def dbb_load_backup(self, show_msg=True): backups = self.hid_send_encrypt(b'{"backup":"list"}') if 'error' in backups: raise Exception(backups['error']['message']) try: f = self.handler.win.query_choice(_("Choose a backup file:"), backups['backup']) except Exception: return False # Back button pushed key = self.backup_password_dialog() if key is None: raise Exception('Canceled by user') key = self.stretch_key(key) if show_msg: self.handler.show_message( _("Loading backup...") + "\n\n" + _("To continue, touch the Digital Bitbox's light for 3 seconds." ) + "\n\n" + _("To cancel, briefly touch the light or wait for the timeout." )) msg = b'{"seed":{"source": "backup", "key": "%s", "filename": "%s"}}' % ( key, backups['backup'][f].encode('utf8')) hid_reply = self.hid_send_encrypt(msg) self.handler.finished() if 'error' in hid_reply: raise Exception(hid_reply['error']['message']) return True
def task(): wallet.wait_until_synchronized() if wallet.is_found(): msg = _("Recovery successful") else: msg = _("No transactions found for this seed") self.synchronized_signal.emit(msg)
def __init__(self, parent): super(CharacterDialog, self).__init__(parent) self.setWindowTitle(_("KeepKey Seed Recovery")) self.character_pos = 0 self.word_pos = 0 self.loop = QEventLoop() self.word_help = QLabel() self.char_buttons = [] vbox = QVBoxLayout(self) vbox.addWidget(WWLabel(CHARACTER_RECOVERY)) hbox = QHBoxLayout() hbox.addWidget(self.word_help) for i in range(4): char_button = CharacterButton('*') char_button.setMaximumWidth(36) self.char_buttons.append(char_button) hbox.addWidget(char_button) self.accept_button = CharacterButton(_("Accept Word")) self.accept_button.clicked.connect(partial(self.process_key, 32)) self.rejected.connect(partial(self.loop.exit, 1)) hbox.addWidget(self.accept_button) hbox.addStretch(1) vbox.addLayout(hbox) self.finished_button = QPushButton(_("Seed Entered")) self.cancel_button = QPushButton(_("Cancel")) self.finished_button.clicked.connect( partial(self.process_key, Qt.Key_Return)) self.cancel_button.clicked.connect(self.rejected) buttons = Buttons(self.finished_button, self.cancel_button) vbox.addSpacing(40) vbox.addLayout(buttons) self.refresh() self.show()
def __init__(self, parent): super(MatrixDialog, self).__init__(parent) self.setWindowTitle(_("Trezor Matrix Recovery")) self.num = 9 self.loop = QEventLoop() vbox = QVBoxLayout(self) vbox.addWidget(WWLabel(MATRIX_RECOVERY)) grid = QGridLayout() grid.setSpacing(0) self.char_buttons = [] for y in range(3): for x in range(3): button = QPushButton('?') button.clicked.connect(partial(self.process_key, ord('1') + y * 3 + x)) grid.addWidget(button, 3 - y, x) self.char_buttons.append(button) vbox.addLayout(grid) self.backspace_button = QPushButton("<=") self.backspace_button.clicked.connect(partial(self.process_key, Qt.Key_Backspace)) self.cancel_button = QPushButton(_("Cancel")) self.cancel_button.clicked.connect(partial(self.process_key, Qt.Key_Escape)) buttons = Buttons(self.backspace_button, self.cancel_button) vbox.addSpacing(40) vbox.addLayout(buttons) self.refresh() self.show()
def load_wallet(self, wallet, window): for keystore in wallet.get_keystores(): if not isinstance(keystore, self.keystore_class): continue if not self.libraries_available: if hasattr(self, 'libraries_available_message'): message = self.libraries_available_message + '\n' else: message = _("Cannot find python library for" ) + " '%s'.\n" % self.name message += _("Make sure you install it with python3") window.show_error(message) return tooltip = self.device + '\n' + (keystore.label or 'unnamed') cb = partial(self.show_settings_dialog, window, keystore) button = StatusBarButton(QIcon(self.icon_unpaired), tooltip, cb) button.icon_paired = self.icon_paired button.icon_unpaired = self.icon_unpaired window.statusBar().addPermanentWidget(button) handler = self.create_handler(window) handler.button = button keystore.handler = handler keystore.thread = TaskThread(window, window.on_error) # Trigger a pairing keystore.thread.add(partial(self.get_client, keystore))
def get_library_not_available_message(self) -> str: if hasattr(self, 'libraries_available_message'): message = self.libraries_available_message else: message = _("Missing libraries for {}.").format(self.name) message += '\n' + _("Make sure you install it with python3") return message
def on_reset_auth(self, wizard, short_id, seed, passphrase, xpub3): xprv1, xpub1, xprv2, xpub2 = self.xkeys_from_seed(seed, passphrase) try: assert xpub1 == wizard.storage.get('x1/')['xpub'] assert xpub2 == wizard.storage.get('x2/')['xpub'] except: wizard.show_message(_('Incorrect seed')) return r = server.get_challenge(short_id) challenge = r.get('challenge') message = 'TRUSTEDCOIN CHALLENGE: ' + challenge def f(xprv): _, _, _, _, c, k = deserialize_xprv(xprv) pk = bip32_private_key([0, 0], k, c) key = regenerate_key(pk) sig = key.sign_message(message, True) return base64.b64encode(sig).decode() signatures = [f(x) for x in [xprv1, xprv2]] r = server.reset_auth(short_id, challenge, signatures) new_secret = r.get('otp_secret') if not new_secret: wizard.show_message(_('Request rejected by server')) return self.check_otp(wizard, short_id, new_secret, xpub3)
def on_password(self, wizard, password, encrypt_storage, k1, k2): k1.update_password(None, password) wizard.storage.set_keystore_encryption(bool(password)) if encrypt_storage: wizard.storage.set_password(password, enc_version=STO_EV_USER_PW) wizard.storage.put('x1/', k1.dump()) wizard.storage.put('x2/', k2.dump()) wizard.storage.write() msg = [ _("Your wallet file is: {}.").format( os.path.abspath(wizard.storage.path)), _("You need to be online in order to complete the creation of " "your wallet. If you generated your seed on an offline " 'computer, click on "{}" to close this window, move your ' "wallet file to an online computer, and reopen it with " "Electrum.").format(_('Cancel')), _('If you are online, click on "{}" to continue.').format( _('Next')) ] msg = '\n\n'.join(msg) wizard.stack = [] wizard.confirm_dialog( title='', message=msg, run_next=lambda x: wizard.run('create_remote_key'))
def toggle_passphrase(self): if self.features.passphrase_protection: self.msg = _("Confirm on your {} device to disable passphrases") else: self.msg = _("Confirm on your {} device to enable passphrases") enabled = not self.features.passphrase_protection self.apply_settings(use_passphrase=enabled)
def add_cosigner_dialog(self, run_next, index, is_valid): title = _("Add Cosigner") + " %d" % index message = ' '.join([ _('Please enter the master public key (xpub) of your cosigner.'), _('Enter their master private key (xprv) if you want to be able to sign for them.' ) ]) return self.text_input(title, message, is_valid)
def __init__(self, text="", allow_multi=False): ButtonsTextEdit.__init__(self, text) self.allow_multi = allow_multi self.setReadOnly(0) self.addButton(":icons/file.png", self.file_input, _("Read file")) icon = ":icons/qrcode_white.png" if ColorScheme.dark_scheme else ":icons/qrcode.png" self.addButton(icon, self.qr_input, _("Read QR code")) run_hook('scan_text_edit', self)
def set_pin(self, remove): if remove: self.msg = _("Confirm on your {} device to disable PIN protection") elif self.features.pin_protection: self.msg = _("Confirm on your {} device to change your PIN") else: self.msg = _("Confirm on your {} device to set a PIN") self.change_pin(remove)
def save_node(self): alias = self.aliasField.text() if not alias: QMessageBox.critical(self, _('Error'), _("Alias missing.")) return addr = self.ipField.text() valid_address = self.validate_addr(addr) if not valid_address: QMessageBox.critical( self, _('Error'), _("Invalid IP-Address\n\nRequired format: xxx.xxx.xxx.xxx or xxx.xxx.xxx.xxx:port" )) return collateralTableSelectedItem = self.collateralTable.selectedItems() if not collateralTableSelectedItem: QMessageBox.critical(self, _('Error'), _("You need to select a collateral.")) return row_index = self.collateralTable.currentRow() tx_addr = self.collateralTable.item(row_index, 0).text() tx_prevout_n = self.collateralTable.item(row_index, 1).text() tx_hash = self.collateralTable.item(row_index, 2).text() tx_value = self.collateralTable.item(row_index, 3).text() tx_collateral_key = self.manager.get_masternode_collateral_key(tx_addr) self.txCollateralKeyLabel.setText(tx_collateral_key) self.addressViewLabel.setText(tx_addr) self.txIndexViewLabel.setText(tx_prevout_n) self.txHashViewLabel.setText(tx_hash) self.txValueViewLabel.setText(tx_value) self.txScriptSigViewLabel.setText('') smartnode_privkey = str(self.smartnodeKeyLabel.text()) if not smartnode_privkey: QMessageBox.warning(self, _('Warning'), _('Smartnode privkey is empty.')) return try: smartnode_pubkey = self.manager.import_masternode_delegate( smartnode_privkey) except Exception: # Show an error if the private key is invalid and not an empty string. if smartnode_privkey: QMessageBox.warning( self, _('Warning'), _('Ignoring invalid smartnode private key.')) smartnode_pubkey = '' # Save Smartnode self.manager.wallet.set_frozen_state([tx_addr], True) self.mapper.submit() self.manager.save() self.accept()
def set_pin(self, remove): if remove: msg = _("Confirm on your {} device to disable PIN protection") elif self.features.pin_protection: msg = _("Confirm on your {} device to change your PIN") else: msg = _("Confirm on your {} device to set a PIN") with self.run_flow(msg): trezorlib.device.change_pin(self.client, remove)
def toggle_passphrase(self): if self.features.passphrase_protection: msg = _("Confirm on your {} device to disable passphrases") else: msg = _("Confirm on your {} device to enable passphrases") enabled = not self.features.passphrase_protection with self.run_flow(msg): trezorlib.device.apply_settings(self.client, use_passphrase=enabled)
def on_update(self): self.wallet = self.parent.wallet item = self.currentItem() current_address = item.data(0, Qt.UserRole) if item else None if self.show_change == 1: addr_list = self.wallet.get_receiving_addresses() elif self.show_change == 2: addr_list = self.wallet.get_change_addresses() else: addr_list = self.wallet.get_addresses() self.clear() for address in addr_list: num = len(self.wallet.get_address_history(address)) is_used = self.wallet.is_used(address) label = self.wallet.labels.get(address, '') c, u, x = self.wallet.get_addr_balance(address) balance = c + u + x if self.show_used == 1 and (balance or is_used): continue if self.show_used == 2 and balance == 0: continue if self.show_used == 3 and not is_used: continue balance_text = self.parent.format_amount(balance, whitespaces=True) fx = self.parent.fx if fx and fx.get_fiat_address_config(): rate = fx.exchange_rate() fiat_balance = fx.value_str(balance, rate) address_item = SortableTreeWidgetItem([ '', address, label, balance_text, fiat_balance, "%d" % num ]) address_item.setTextAlignment(4, Qt.AlignRight) address_item.setFont(4, QFont(MONOSPACE_FONT)) else: address_item = SortableTreeWidgetItem( ['', address, label, balance_text, "%d" % num]) address_item.setFont(3, QFont(MONOSPACE_FONT)) if self.wallet.is_change(address): address_item.setText(0, _('change')) address_item.setBackground(0, ColorScheme.YELLOW.as_color(True)) else: address_item.setText(0, _('receiving')) address_item.setBackground(0, ColorScheme.GREEN.as_color(True)) address_item.setFont(1, QFont(MONOSPACE_FONT)) address_item.setData( 0, Qt.UserRole, address) # column 0; independent from address column if self.wallet.is_frozen(address): address_item.setBackground(1, ColorScheme.BLUE.as_color(True)) if self.wallet.is_beyond_limit(address): address_item.setBackground(1, ColorScheme.RED.as_color(True)) self.addChild(address_item) if address == current_address: self.setCurrentItem(address_item)
def accept_terms_of_use(self, window): vbox = QVBoxLayout() vbox.addWidget(QLabel(_("Terms of Service"))) tos_e = TOS() tos_e.setReadOnly(True) vbox.addWidget(tos_e) tos_received = False vbox.addWidget(QLabel(_("Please enter your e-mail address"))) email_e = QLineEdit() vbox.addWidget(email_e) next_button = window.next_button prior_button_text = next_button.text() next_button.setText(_('Accept')) def request_TOS(): try: tos = server.get_terms_of_service() except Exception as e: import traceback traceback.print_exc(file=sys.stderr) tos_e.error_signal.emit( _('Could not retrieve Terms of Service:') + '\n' + str(e)) return self.TOS = tos tos_e.tos_signal.emit() def on_result(): tos_e.setText(self.TOS) nonlocal tos_received tos_received = True set_enabled() def on_error(msg): window.show_error(str(msg)) window.terminate() def set_enabled(): valid_email = re.match(regexp, email_e.text()) is not None next_button.setEnabled(tos_received and valid_email) tos_e.tos_signal.connect(on_result) tos_e.error_signal.connect(on_error) t = Thread(target=request_TOS) t.setDaemon(True) t.start() regexp = r"[^@]+@[^@]+\.[^@]+" email_e.textChanged.connect(set_enabled) email_e.setFocus(True) window.exec_layout(vbox, next_enabled=False) next_button.setText(prior_button_text) return str(email_e.text())
def create_password_layout(self, wallet, is_encrypted, OK_button): if not is_encrypted: msg = _('Your wallet file is NOT encrypted.') else: msg = _('Your wallet file is encrypted.') msg += '\n' + _( 'Note: If you enable this setting, you will need your hardware device to open your wallet.' ) msg += '\n' + _('Use this dialog to toggle encryption.') self.playout = PasswordLayoutForHW(wallet, msg, PW_CHANGE, OK_button)
def text_ignore_old_fw_and_continue(self) -> str: suffix = (_( "The firmware of your hardware device is too old. " "If possible, you should upgrade it. " "You can ignore this error and try to continue, however things are likely to break." ) + "\n\n" + _("Ignore and continue?")) if str(self): return str(self) + "\n\n" + suffix else: return suffix
def create_toolbar_buttons(self): self.period_combo = QComboBox() self.start_button = QPushButton('-') self.start_button.pressed.connect(self.select_start_date) self.start_button.setEnabled(False) self.end_button = QPushButton('-') self.end_button.pressed.connect(self.select_end_date) self.end_button.setEnabled(False) self.period_combo.addItems([_('All'), _('Custom')]) self.period_combo.activated.connect(self.on_combo)
def wipe_device(): wallet = window.wallet if wallet and sum(wallet.get_balance()): title = _("Confirm Device Wipe") msg = _("Are you SURE you want to wipe the device?\n" "Your wallet still has SmartCash in it!") if not self.question( msg, title=title, icon=QMessageBox.Critical): return invoke_client('wipe_device', unpair_after=True)
def export(self): name = 'signed_%s.txn' % ( self.tx.txid()[0:8]) if self.tx.is_complete() else 'unsigned.txn' fileName = self.main_window.getSaveFileName( _("Select where to save your signed transaction"), name, "*.txn") if fileName: with open(fileName, "w+") as f: f.write(json.dumps(self.tx.as_dict(), indent=4) + '\n') self.show_message(_("Transaction exported successfully")) self.saved = True
def custom_smartnode_key(self): smartnodeKey, ok = QInputDialog.getText(self, 'Custom Smartnode Key', 'Insert your key here...') if ok: if self.validate_smartnode_key(smartnodeKey): self.smartnodeKeyLabel.setText(str(smartnodeKey)) else: QMessageBox.critical(self, _('Error'), _("Invalid Smartnode Key provided\n\n" + smartnodeKey)) else: return
def show_xpub_dialog(self, xpub, run_next): msg = ' '.join([ _("Here is your master public key."), _("Please share it with your cosigners.") ]) vbox = QVBoxLayout() layout = SeedLayout(xpub, title=msg, icon=False) vbox.addLayout(layout.layout()) self.exec_layout(vbox, _('Master Public Key')) return None
def restore_seed_dialog(self, run_next, test): options = [] if self.opt_ext: options.append('ext') if self.opt_bip39: options.append('bip39') title = _('Enter Seed') message = _( 'Please enter your seed phrase in order to restore your wallet.') return self.seed_input(title, message, test, options)
def get_tooltip(self, pos, fee_rate): mempool = self.config.use_mempool_fees() target, estimate = self.config.get_fee_text(pos, self.dyn, mempool, fee_rate) if self.dyn: return _('Target') + ': ' + target + '\n' + _( 'Current rate') + ': ' + estimate else: return _('Fixed rate') + ': ' + target + '\n' + _( 'Estimate') + ': ' + estimate
def closeEvent(self, event): if (self.prompt_if_unsaved and not self.saved and not self.question( _('This transaction is not saved. Close anyway?'), title=_("Warning"))): event.ignore() else: event.accept() try: dialogs.remove(self) except ValueError: pass # was not in list already
def confirm_seed_dialog(self, run_next, test): self.app.clipboard().clear() title = _('Confirm Seed') message = ' '.join([ _('Your seed is important!'), _('If you lose your seed, your money will be permanently lost.'), _('To make sure that you have properly saved your seed, please retype it here.' ) ]) seed, is_bip39, is_ext = self.seed_input(title, message, test, None) return seed
def __init__(self, seed=None, title=None, icon=True, msg=None, options=None, is_seed=None, passphrase=None, parent=None): QVBoxLayout.__init__(self) self.parent = parent self.options = options if title: self.addWidget(WWLabel(title)) self.seed_e = CompletionTextEdit() if seed: self.seed_e.setText(seed) else: self.seed_e.setTabChangesFocus(True) self.is_seed = is_seed self.saved_is_seed = self.is_seed self.seed_e.textChanged.connect(self.on_edit) self.initialize_completer() self.seed_e.setMaximumHeight(75) hbox = QHBoxLayout() if icon: logo = QLabel() logo.setPixmap(QPixmap(":icons/seed.png").scaledToWidth(64)) logo.setMaximumWidth(60) hbox.addWidget(logo) hbox.addWidget(self.seed_e) self.addLayout(hbox) hbox = QHBoxLayout() hbox.addStretch(1) self.seed_type_label = QLabel('') hbox.addWidget(self.seed_type_label) if options: opt_button = EnterButton(_('Options'), self.seed_options) hbox.addWidget(opt_button) self.addLayout(hbox) if passphrase: hbox = QHBoxLayout() passphrase_e = QLineEdit() passphrase_e.setText(passphrase) passphrase_e.setReadOnly(True) hbox.addWidget(QLabel(_("Your seed extension is") + ':')) hbox.addWidget(passphrase_e) self.addLayout(hbox) self.addStretch(1) self.seed_warning = WWLabel('') if msg: self.seed_warning.setText(seed_warning_msg(seed)) self.addWidget(self.seed_warning)
def __init__(self, parent, seed, passphrase): WindowModalDialog.__init__(self, parent, ('Electrum - ' + _('Seed'))) self.setMinimumWidth(400) vbox = QVBoxLayout(self) title = _("Your wallet generation seed is:") slayout = SeedLayout(title=title, seed=seed, msg=True, passphrase=passphrase) vbox.addLayout(slayout) vbox.addLayout(Buttons(CloseButton(self)))