Exemplo n.º 1
0
    def genContractWallet(self, nickname=None):
        path = os.path.join(self.topDir, 'wallets')
        if not os.path.isdir(path):
            os.mkdir(path)
        if nickname:
            for i, c in enumerate(self.contracts):
                if c["nickname"] == nickname:
                    print_msg("{} contract exists.".format(nickname))
                    return self.getContractWallet(i), c
        #print(type(self.contracts))
        #this next loop generates a wallet name that isn't in use yet.
        if self.contracts == []:
            walletFile = os.path.join(self.topDir, 'wallets',
                                      'contract0.wallet')
        else:
            walletNames = []
            for c in self.contracts:
                #print(c)
                walletNames.append(c['walletFile'])
            for i in range(len(walletNames) + 1):
                walletFile = os.path.join(self.topDir, 'wallets',
                                          'contract' + str(i) + '.wallet')
                if walletFile not in walletNames:
                    break
        storage = WalletStorage(walletFile)
        seed_type = 'standard'
        seed = Mnemonic('en').make_seed(seed_type)
        k = keystore.from_seed(seed, '', False)
        storage.put('keystore', k.dump())
        storage.put('wallet_type', 'standard')
        wallet = Wallet(storage)
        wallet.set_schnorr_enabled(False)
        wallet.update_password(None, '', True)
        wallet.synchronize()
        print_msg("Your wallet generation seed is:\n\"%s\"" % seed)
        print_msg(
            "Please keep it in a safe place; if you lose it, you will not be able to restore your wallet."
        )

        wallet.storage.write()
        print_msg("Wallet saved in '%s'" % wallet.storage.path)

        my_addr = wallet.get_unused_address()
        my_addr_index = wallet.receiving_addresses.index(my_addr)
        #my_addr_index is always going to be 0 if the wallet is unused, so maybe previous line unnecessary
        my_pubkey = wallet.derive_pubkeys(False, my_addr_index)
        my_x_pubkey = self.get_x_pubkey(my_addr_index, wallet)
        self.contracts.append({
            'walletFile': wallet.storage.path,
            "my_addr": my_addr.to_ui_string(),
            "my_pubkey": my_pubkey,
            "my_x_pubkey": my_x_pubkey,
            "nickname": nickname,
            "label": ""
        })
        #print(self.contracts)
        self.updateContracts()
        self.multiWallets.append(None)
        return wallet, self.contracts[-1]
Exemplo n.º 2
0
	def write_if_dirty(self, storage: WalletStorage):
		if self.dirty:
			try:
				d = {
					"version": PersistentTipList.STORAGE_VERSION,
					"tips": self.to_dict()
				}
				storage.put(PersistentTipList.KEY, d)
				self.dirty = False
			except RuntimeError as e: # looking for "RuntimeError: dictionary changed size during iteration"
				pass
Exemplo n.º 3
0
    def test_write_dictionnary_to_file(self):

        storage = WalletStorage(self.wallet_path)

        some_dict = {
            u"a": u"b",
            u"c": u"d",
            u"seed_version": FINAL_SEED_VERSION
        }

        for key, value in some_dict.items():
            storage.put(key, value)
        storage.write()

        contents = ""
        with open(self.wallet_path, "r") as f:
            contents = f.read()
        self.assertEqual(some_dict, json.loads(contents))
Exemplo n.º 4
0
    def create(self, name, password, seed=None, addresses=None, privkeys=None):
        """Create or restore a new wallet"""
        path = self._wallet_path(name)
        if exists(path):
            raise FileExistsError(path)
        storage = WalletStorage(path)

        if addresses:
            wallet = ImportedAddressWallet.from_text(storage, addresses)
        elif privkeys:
            wallet = ImportedPrivkeyWallet.from_text(storage, privkeys)
        else:
            if seed is None:
                seed = self.make_seed()
                print("Your wallet generation seed is:\n\"%s\"" % seed)
            storage.put('keystore', keystore.from_seed(seed, "", False).dump())
            wallet = Standard_Wallet(storage)

        wallet.update_password(None, password, True)
    def create(self, name, password=None, seed=None):
        """Create or restore a new wallet"""
        path = self._wallet_path(name)
        if exists(path):
            raise FileExistsError(path)
        storage = WalletStorage(path)

        if seed is None:
            seed = self.make_seed()
            print("Your wallet generation seed is:\n\"%s\"" % seed)
        storage.put('keystore', keystore.from_seed(seed, "", False).dump())
        storage.put('wallet_type', 'standard')
        wallet = Wallet(storage)

        if password is None:
            password = main.prompt_password(
                "Password (hit return if you do not wish to encrypt your wallet):"
            )
        wallet.update_password(None, password, True)
        storage.write()
class LoadRWallet(MessageBoxMixin, PrintError, QWidget):
    def __init__(self,
                 parent,
                 plugin,
                 wallet_name,
                 recipient_wallet=None,
                 time=None,
                 password=None):
        QWidget.__init__(self, parent)
        self.password = password
        self.wallet = parent.wallet
        self.utxos = self.wallet.get_spendable_coins(None, parent.config)
        random.shuffle(self.utxos)  # randomize the coins' order
        for x in range(10):
            name = 'tmp_wo_wallet' + ''.join(
                random.choices(string.ascii_letters + string.digits, k=10))
            self.file = os.path.join(tempfile.gettempdir(), name)
            if not os.path.exists(self.file):
                break
        else:
            raise RuntimeError(
                'Could not find a unique temp file in tmp directory',
                tempfile.gettempdir())
        self.tmp_pass = ''.join(
            random.choices(string.ascii_uppercase + string.digits, k=10))
        self.storage = None
        self.recipient_wallet = None
        self.keystore = None
        self.plugin = plugin
        self.network = parent.network
        self.wallet_name = wallet_name
        self.keystore = None
        vbox = QVBoxLayout()
        self.setLayout(vbox)
        self.local_xpub = self.wallet.get_master_public_keys()
        l = QLabel(
            _("Master Public Key") +
            _(" of this wallet (used to generate all of your addresses): "))
        l2 = QLabel((self.local_xpub and self.local_xpub[0]) or _(
            "This wallet is <b>non-deterministic</b> and cannot be used as a transfer destination."
        ))
        vbox.addWidget(l)
        vbox.addWidget(l2)
        l2.setTextInteractionFlags(Qt.TextSelectableByMouse)
        l = QLabel(
            _("Master Public Key") +
            " of the wallet you want to transfer your funds to:")
        disabled = False
        if self.wallet.is_watching_only():
            l.setText(
                _("This wallet is <b>watching-only</b> and cannot be used as a transfer source."
                  ))
            disabled = True
        elif any([
                isinstance(k, Hardware_KeyStore)
                for k in self.wallet.get_keystores()
        ]):
            l.setText(
                _("This wallet is a <b>hardware wallet</b> and cannot be used as a transfer source."
                  ))
            disabled = True
        vbox.addWidget(l)
        self.xpubkey = None
        self.xpubkey_wid = QLineEdit()
        self.xpubkey_wid.textEdited.connect(self.transfer_changed)
        self.xpubkey_wid.setDisabled(disabled)
        vbox.addWidget(self.xpubkey_wid)
        l = QLabel(_("How long the transfer should take (in whole hours): "))
        vbox.addWidget(l)
        l.setDisabled(disabled)
        self.time_e = QLineEdit()
        self.time_e.setMaximumWidth(70)
        self.time_e.textEdited.connect(self.transfer_changed)
        self.time_e.setDisabled(disabled)
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        hbox.addWidget(self.time_e)
        self.speed = QLabel()
        hbox.addWidget(self.speed)
        hbox.addStretch(1)
        self.transfer_button = QPushButton(_("Transfer"))
        self.transfer_button.clicked.connect(self.transfer)
        vbox.addWidget(self.transfer_button)
        self.transfer_button.setDisabled(True)

        vbox.addStretch(1)

    def filter(self, *args):
        ''' This is here because searchable_list must define a filter method '''

    def showEvent(self, e):
        super().showEvent(e)
        if not self.network and self.isEnabled():
            self.show_warning(
                _("The Inter-Wallet Transfer plugin cannot function in offline mode. Restart Electron Cash in online mode to proceed."
                  ))
            self.setDisabled(True)

    @staticmethod
    def delete_temp_wallet_file(file):
        ''' deletes the wallet file '''
        if file and os.path.exists(file):
            try:
                os.remove(file)
                print_error("[InterWalletTransfer] Removed temp file", file)
            except Exception as e:
                print_error("[InterWalletTransfer] Failed to remove temp file",
                            file, "error: ", repr(e))

    def transfer(self):
        self.show_message(
            _("You should not use either wallet during the transfer. Leave Electron Cash active. "
              "The plugin ceases operation and will have to be re-activated if Electron Cash "
              "is stopped during the operation."))
        self.storage = WalletStorage(self.file)
        self.storage.set_password(self.tmp_pass, encrypt=True)
        self.storage.put('keystore', self.keystore.dump())
        self.recipient_wallet = Standard_Wallet(self.storage)
        self.recipient_wallet.start_threads(self.network)
        # comment the below out if you want to disable auto-clean of temp file
        # otherwise the temp file will be auto-cleaned on app exit or
        # on the recepient_wallet object's destruction (when refct drops to 0)
        Weak.finalize(self.recipient_wallet, self.delete_temp_wallet_file,
                      self.file)
        self.plugin.switch_to(Transfer,
                              self.wallet_name, self.recipient_wallet,
                              float(self.time_e.text()), self.password)

    def transfer_changed(self):
        try:
            assert float(self.time_e.text()) > 0
            self.xpubkey = self.xpubkey_wid.text()
            self.keystore = keystore.from_master_key(self.xpubkey)
        except:
            self.speed.setText('')
            self.transfer_button.setDisabled(True)
        else:
            self.transfer_button.setDisabled(False)
            v = len(self.utxos) / float(self.time_e.text())
            self.speed.setText('{0:.2f}'.format(v) + ' tx/h on average')
Exemplo n.º 7
0
class NewBatchDialog(QDialog, MessageBoxMixin, PrintError):
    settings_updated_signal = pyqtSignal()

    def __init__(self, parent, plugin, wallet_name, password=None):
        QDialog.__init__(self, parent)
        self.main_window = parent
        self.password = password
        self.wallet = parent.wallet
        self.plugin = plugin
        self.network = parent.network
        self.wallet_name = wallet_name
        self.batch_label = "BitcoinBiletoj1"
        self.template_file = ''
        self.working_directory = self.wallet.storage.get("bileto_path")
        if self.working_directory:
            if not os.path.exists(self.working_directory):
                self.working_directory = None
        self.number = 0
        self.times = 1
        self.public_key = ''
        for x in range(10):
            name = 'tmp_wo_wallet' + ''.join(
                random.choices(string.ascii_letters + string.digits, k=10))
            self.file = os.path.join(tempfile.gettempdir(), name)
            if not os.path.exists(self.file):
                break
        else:
            raise RuntimeError(
                'Could not find a unique temp file in tmp directory',
                tempfile.gettempdir())
        self.tmp_pass = ''.join(
            random.choices(string.ascii_uppercase + string.digits, k=10))

        from electroncash import mnemonic
        seed = mnemonic.Mnemonic('en').make_seed('standard')
        self.keystore = keystore.from_seed(seed, self.tmp_pass, False)
        self.storage = WalletStorage(self.file)
        self.storage.set_password(self.tmp_pass, encrypt=True)
        self.storage.put('keystore', self.keystore.dump())
        self.recipient_wallet = Standard_Wallet(self.storage)
        self.recipient_wallet.start_threads(self.network)
        Weak.finalize(self.recipient_wallet, self.delete_temp_wallet_file,
                      self.file)
        vbox = QVBoxLayout()
        self.setLayout(vbox)
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        l = QLabel("<b>%s</b>" % (_("Bitcoin Bileto")))
        hbox.addStretch(1)
        hbox.addWidget(l)
        hbox.addStretch(1)
        vbox.addWidget(QLabel("Working directory:"))
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        self.wd_label = QLabel(self.working_directory)
        hbox.addWidget(self.wd_label)
        b = QPushButton("Set")
        b.clicked.connect(lambda: self.plugin.settings_dialog(
            self, self.settings_updated_signal))
        self.settings_updated_signal.connect(self.on_settings_updated)
        hbox.addWidget(b)
        data = "prywatny klucz do portfela"
        self.qrw_priv = QRCodeWidget(data)
        self.qrw_add = QRCodeWidget(data)

        self.batch_label_wid = QLineEdit()
        self.batch_label_wid.setPlaceholderText(
            _("Bitcoin biletoj batch label"))
        self.batch_label_wid.textEdited.connect(self.batch_info_changed)
        vbox.addWidget(self.batch_label_wid)

        grid = QGridLayout()
        vbox.addLayout(grid)
        self.number_wid = QLineEdit()
        self.number_wid.setPlaceholderText(_("Number of biletoj"))
        self.number_wid.textEdited.connect(self.batch_info_changed)
        self.times_wid = QLineEdit()
        self.times_wid.textEdited.connect(self.batch_info_changed)
        self.times_wid.setText("1")
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)
        hbox.addWidget(self.number_wid)
        #hbox.addWidget(QLabel("x"))
        #hbox.addWidget(self.times_wid)
        hbox.addStretch(1)
        self.times_wid.setMaximumWidth(120)
        self.number_wid.setMaximumWidth(140)
        self.only_qrcodes_checkbox = QCheckBox("Only make QR codes.")
        self.only_qrcodes_checkbox.stateChanged.connect(
            self.batch_info_changed)
        self.encrypt_checkbox = QCheckBox("Encrypt Batch.")
        vbox.addWidget(self.encrypt_checkbox)
        vbox.addWidget(self.only_qrcodes_checkbox)
        #b = QPushButton(_("Load .tex template"))
        #b.clicked.connect(self.load_template)
        #b.setMaximumWidth(130)
        #grid.addWidget(b, 0, 0)
        #self.template_path_label_wid = QLabel('set path')
        #grid.addWidget(self.template_path_label_wid, 0, 1)
        self.public_key_wid = QLineEdit()
        self.public_key_wid.setPlaceholderText(
            _("Public Key") + _(" for encryption"))
        self.public_key_wid.textEdited.connect(self.batch_info_changed)
        #vbox.addWidget(self.public_key_wid)
        self.b = QPushButton(_("Generate biletoj"))
        self.b.clicked.connect(self.generate_biletoj)
        self.prog_bar = QProgressBar()
        self.prog_bar.setVisible(False)
        vbox.addWidget(self.b)
        vbox.addWidget(self.prog_bar)
        self.b.setDisabled(True)
        vbox.addStretch(1)

    def on_settings_updated(self):
        self.working_directory = self.wallet.storage.get("bileto_path")
        self.wd_label.setText(self.working_directory)

    def save_qrcode(self, qrw, name):
        p = qrw and qrw.grab()
        filename = os.path.join(self.working_directory, name)
        if p and not p.isNull():
            if filename:
                print_error("saving")
                p.save(filename, 'png')

    def batch_info_changed(self):
        # string = self.recipient_wallet.get_unused_address().to_ui_string()
        try:
            self.batch_label = str(self.batch_label_wid.text())
            self.number = int(self.number_wid.text())
            self.times = int(self.times_wid.text())
            assert self.times > 0
            # self.public_key = str(self.public_key_wid.text())
            self.public_key = self.wallet.get_pubkey(False, 0)
            assert os.path.exists(self.working_directory)
            #if not self.only_qrcodes_checkbox.isChecked():
            #assert os.path.isfile(self.template_file)
        except AssertionError:
            self.times_wid.setText("1")
            self.b.setDisabled(True)
        except:
            self.b.setDisabled(True)
        else:
            self.b.setDisabled(False)

    def load_template(self):
        self.template_file = self.main_window.getOpenFileName(
            "Load Latex template", "*.tex")
        self.template_path_label_wid.setText(self.template_file)
        self.batch_info_changed()

    def generate_biletoj(self):
        self.b.setDisabled(True)
        self.b.setText("In progress...")
        self.prog_bar.setRange(0, self.number)
        self.prog_bar.setVisible(True)
        QCoreApplication.processEvents()
        try:
            path_to_latex = check_output(["which", "pdflatex"],
                                         shell=False).strip()
        except:
            path_to_latex = '/Library/Tex/texbin/pdflatex'
        batch_privs = self.batch_label + '\n'
        os.mkdir(
            os.path.join(self.working_directory,
                         self.batch_label + "_qrcodes"))
        for i in range(self.number):
            add = self.recipient_wallet.create_new_address()
            privkey = self.recipient_wallet.export_private_key(add, None)
            batch_privs += privkey + '\n'
            self.qrw_priv.number_label.setText('  ' + str(i + 1))
            self.qrw_priv.setData(privkey)
            self.save_qrcode(
                self.qrw_priv,
                self.batch_label + "_qrcodes/priv_key_" + str(i + 1) + ".png")
            self.qrw_add.number_label.setText('  ' + str(i + 1))
            self.qrw_priv.setData("bitcoincash:" + add.to_ui_string())
            self.save_qrcode(
                self.qrw_add,
                self.batch_label + "_qrcodes/address_" + str(i + 1) + ".png")
            self.prog_bar.setValue(i + 1)
        if not self.only_qrcodes_checkbox.isChecked():
            self.scripts()
            call(['chmod', 'u+x', "compile.sh"],
                 cwd=self.working_directory,
                 shell=False)
            call([
                "./compile.sh", '-l', self.batch_label, '-n',
                str(self.number)
            ],
                 cwd=self.working_directory,
                 shell=False)
        filename = os.path.join(self.working_directory,
                                self.batch_label + '_encrypted_private_keys')

        save_private_keys(batch_privs, self.public_key, filename,
                          self.encrypt_checkbox.isChecked())
        self.prog_bar.setVisible(False)
        self.main_window.show_message("Done!")
        self.b.setDisabled(False)
        self.b.setText(_("Generate biletoj"))

    def filter(self, *args):
        ''' This is here because searchable_list must define a filter method '''

    def scripts(self):
        for name, scr in script_dict.items():
            path = os.path.join(self.working_directory, name)
            if not os.path.isfile(path):
                with open(path, 'w') as file:
                    file.write(scr)

    @staticmethod
    def delete_temp_wallet_file(file):
        ''' deletes the wallet file '''
        if file and os.path.exists(file):
            try:
                os.remove(file)
                print_error("[BitcoinBileto] Removed temp file", file)
            except Exception as e:
                print_error("[BitcoinBileto] Failed to remove temp file", file,
                            "error: ", repr(e))

    def closeEvent(self, event):
        #self.plugin.on_create_dialog_closed(self.wallet_name)
        event.accept()