def __init__(self, parent): MyTreeWidget.__init__(self, parent, self.create_menu, [_('Name'), _('Address')], 0, [0]) self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setSortingEnabled(False) self.header().setResizeMode(0, QHeaderView.Fixed) self.setColumnWidth(0, 300)
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): from uwallet.bitcoin import deserialize_xkey, bip32_private_key, regenerate_key, is_compressed _, _, _, c, k = deserialize_xkey(xprv) pk = bip32_private_key([0, 0], k, c) key = regenerate_key(pk) compressed = is_compressed(pk) sig = key.sign_message(message, compressed) return base64.b64encode(sig) 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 seed_input_bip39(self, title, message, is_seed): slayout = SeedInputLayout(self, message, is_seed) vbox = QVBoxLayout() vbox.addLayout(slayout.layout()) if self.opt_ext or self.opt_bip39: vbox.addStretch(1) # vbox.addWidget(QLabel(_('Options') + ':')) if self.opt_ext: cb_pass = QCheckBox(_('Add a passphrase to this seed')) # vbox.addWidget(cb_pass) if self.opt_bip39: def f(b): if b: msg = ' '.join([ '<b>' + _('Warning') + '</b>' + ': ', _('BIP39 seeds may not be supported in the future.'), '<br/><br/>', _('As technology matures, Ulord address generation may change.'), _('However, BIP39 seeds do not include a version number.'), _('As a result, it is not possible to infer your wallet type from a BIP39 seed.'), '<br/><br/>', _('We do not guarantee that BIP39 seeds will be supported in future versions of UWalletLite.'), _('We recommend to use seeds generated by UWalletLite or compatible wallets.'), ]) # self.show_warning(msg) slayout.seed_type_label.setVisible(not b) slayout.is_seed = (lambda x: bool(x)) if b else is_seed slayout.on_edit() cb_bip39 = QCheckBox(_('BIP39 seed')) cb_bip39.toggled.connect(f) f(True) # vbox.addWidget(cb_bip39) self.set_main_layout(vbox, title, next_enabled=False) seed = slayout.get_seed()
def value_str(self, satoshis, rate): if satoshis is None: # Can happen with incomplete history return _("Unknown") if rate: value = Decimal(satoshis) / COIN * Decimal(rate) return "%s" % (self.ccy_amount_str(value, True)) return _("No data")
def toggle_passphrase(self): if self.features.passphrase_protection: self.msg = _("Confirm on your %s device to disable passphrases") else: self.msg = _("Confirm on your %s device to enable passphrases") enabled = not self.features.passphrase_protection self.apply_settings(use_passphrase=enabled)
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 add_cosigner_dialog(self, run_next, index, is_valid): title = _("Cosigner %d root public key")%index message = ' '.join([ _('Please enter the root 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 task(): wallet.wait_until_synchronized() if wallet.is_found(): msg = _("Recovery successful") else: msg = _("No transactions found for this seed") self.emit(QtCore.SIGNAL('synchronized'), msg)
def __init__(self, parent, address): WindowModalDialog.__init__(self, parent, _("Address")) self.address = address self.parent = parent self.config = parent.config self.wallet = parent.wallet self.app = parent.app self.saved = True self.setMinimumWidth(700) vbox = QVBoxLayout() self.setLayout(vbox) self.setTitleBar(vbox) vbox.addWidget(QLabel(_("Address:"))) self.addr_e = ButtonsLineEdit(self.address) self.addr_e.addCopyButton(self.app) # self.addr_e.addButton(":icons/qrcode.png", self.show_qr, _("Show QR Code")) self.addr_e.setReadOnly(True) vbox.addWidget(self.addr_e) vbox.addWidget(QLabel(_("History"))) self.hw = HistoryList(self.parent) self.hw.get_domain = self.get_domain vbox.addWidget(self.hw) vbox.addStretch(1) vbox.addLayout(Buttons(CloseButton(self))) self.format_amount = self.parent.format_amount self.hw.update()
def create_menu(self, position): menu = QMenu() menu.setStyleSheet( "QMenu{background-color: white;color: black;border: 0px solid #000;}QMenu::item::selected{color: black;background-color:rgb(255,251,160);}" ) selected = self.selectedItems() if not selected: menu.addAction(_("New contact"), lambda: self.parent.new_contact_dialog()) else: names = [unicode(item.text(0)) for item in selected] keys = [unicode(item.text(1)) for item in selected] column = self.currentColumn() column_title = self.headerItem().text(column) column_data = '\n'.join( [unicode(item.text(column)) for item in selected]) menu.addAction( _("Copy %s") % column_title, lambda: self.parent.app.clipboard().setText(column_data)) if column in self.editable_columns: menu.addAction( _("Edit %s") % column_title, lambda: self.editItem(item, column)) menu.addAction(_("Pay to"), lambda: self.parent.payto_contacts(keys)) menu.addAction(_("Delete"), lambda: self.parent.delete_contacts(keys)) # URLs = [block_explorer_URL(self.config, 'addr', key) for key in filter(is_address, keys)] # if URLs: # menu.addAction(_("View on block explorer"), lambda: map(webbrowser.open, URLs)) run_hook('create_contact_menu', menu, selected) menu.exec_(self.viewport().mapToGlobal(position))
def set_pin(self, remove): if remove: self.msg = _("Confirm on your %s device to disable PIN protection") elif self.features.pin_protection: self.msg = _("Confirm on your %s device to change your PIN") else: self.msg = _("Confirm on your %s device to set a PIN") self.change_pin(remove)
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() dialogs.remove(self)
def restore_seed_dialog_bip39(self, run_next, test): title = _("Import mnemonic") message = ' '.join([ _("Please enter your backup mnemonic."), # _('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.') ]) return self.seed_input_bip39(title, message, test)
def __init__(self, parent=None): MyTreeWidget.__init__(self, parent, self.create_menu, [ _('Address'), " " + _('Label'), _('Balance') + ' ', _('Tx') ], 1) # self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.headerItem().setTextAlignment(2, Qt.AlignHCenter | Qt.AlignVCenter)
def wipe_device(): 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 bitcoins in it!") if not self.question( msg, title=title, icon=QMessageBox.Critical): return invoke_client('wipe_device', unpair_after=True)
def export_history_dialog(self, window, hbox): wallet = window.wallet history = wallet.get_history() if len(history) > 0: b = QPushButton(_("Preview plot")) hbox.addWidget(b) b.clicked.connect(lambda: self.do_plot(wallet, history)) else: b = QPushButton(_("No history to plot")) hbox.addWidget(b)
def save(self): name = 'signed_%s.txn' % ( self.tx.hash()[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 saved successfully")) self.saved = True
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 = SeedDisplayLayout(xpub, title=msg, icon=False) vbox.addLayout(layout.layout()) self.set_main_layout(vbox, _('Master Public Key')) return None
def __init__(self, wallet, msg, kind, OK_button): self.wallet = wallet self.titles = [_("Enter Password"), _("Change Password"), _("Enter Passphrase")] self.pw = QLineEditEx() self.pw.setEchoMode(2) self.pw.setMaxLength(15) self.new_pw = QLineEditEx() self.new_pw.setEchoMode(2) self.new_pw.setMaxLength(15) self.conf_pw = QLineEditEx() self.conf_pw.setEchoMode(2) self.conf_pw.setMaxLength(15) self.kind = kind self.OK_button = OK_button vbox = QVBoxLayout() label = QLabel(msg + "\n") label.setStyleSheet("color:#999999;") label.setWordWrap(True) if kind == PW_PASSPHRASE: vbox.addWidget(label) msgs = [_('Passphrase:'), _('Confirm Passphrase:')] else: lblayout = QHBoxLayout() lblayout.addWidget(label) vbox.addLayout(lblayout) m1 = _('New Password:'******'Password:'******'Confirm Password:'******'Current Password:'******'') self.new_pw.textChanged.connect(enable_OK) self.conf_pw.textChanged.connect(enable_OK) self.vbox = vbox
def show_seed_dialog(self, run_next, seed_text): vbox = QVBoxLayout() slayout = CreateSeedLayout(seed_text) vbox.addLayout(slayout.layout()) vbox.addStretch(1) # vbox.addWidget(QLabel(_('Option') + ':')) cb_pass = QCheckBox(_('Add a passphrase to this seed')) # vbox.addWidget(cb_pass) title = _("Mnemonic") self.set_main_layout(vbox,title) return cb_pass.isChecked()
def pw_changed(self): password = self.new_pw.text() if password: colors = {_("Weak"):"Red", _("Medium"):"Blue", _("Strong"):"Green", _("Very Strong"):"Green"} strength = check_password_strength(password) label = (_("Password Strength") + ": " + "<font color=" + colors[strength] + ">" + strength + "</font>") else: label = "" self.pw_strength.setText(label)
def callback_PinMatrixRequest(self, msg): if msg.type == 2: msg = _("Enter a new PIN for your %s:") elif msg.type == 3: msg = (_("Re-enter the new PIN for your %s.\n\n" "NOTE: the positions of the numbers have changed!")) else: msg = _("Enter your current %s PIN:") pin = self.handler.get_pin(msg % self.device) if not pin: return self.proto.Cancel() return self.proto.PinMatrixAck(pin=pin)
def build_tray_menu(self): # Avoid immediate GC of old menu when window closed via its action self.old_menu = self.tray.contextMenu() m = QMenu() for window in self.windows: submenu = m.addMenu(window.wallet.basename()) submenu.addAction(_("Show/Hide"), window.show_or_hide) submenu.addAction(_("Close"), window.close) # m.addAction(_("Dark/Light"), self.toggle_tray_icon) m.addSeparator() m.addAction(_("Exit UWalletLite"), self.close) self.tray.setContextMenu(m)
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.') ]) self.opt_ext = True self.opt_bip39 = True seed, is_bip39, is_ext = self.seed_input(title, message, test) return seed
def choose_seed(self, wizard): title = _('Create or restore') message = _( 'Do you want to create a new seed, or to restore a wallet using an existing seed?' ) choices = [ ('create_seed', _('Create a new seed')), ('restore_wallet', _('I already have a seed')), ] wizard.choice_dialog(title=title, message=message, choices=choices, run_next=wizard.run)
def refresh_headers(self): headers = [ '', '', _('Date'), _('Description'), _('Amount') + ' ', _('Balance') + ' ', _(' ') ] run_hook('history_tab_headers', headers) self.update_headers(headers) self.headerItem().setTextAlignment(4, Qt.AlignRight | Qt.AlignVCenter) self.headerItem().setTextAlignment(5, Qt.AlignRight | Qt.AlignVCenter)
def callback_PassphraseRequest(self, req): if self.creating_wallet: msg = _("Enter a passphrase to generate this wallet. Each time " "you use this wallet your %s will prompt you for the " "passphrase. If you forget the passphrase you cannot " "access the bitcoins in the wallet.") % self.device else: msg = _("Enter the passphrase to unlock this wallet:") passphrase = self.handler.get_passphrase(msg, self.creating_wallet) if passphrase is None: return self.proto.Cancel() passphrase = bip39_normalize_passphrase(passphrase) return self.proto.PassphraseAck(passphrase=passphrase)
def choose_server(self, network): title = _("UWalletLite communicates with remote servers to get information about your transactions and addresses.\r\n The servers all fulfil the same purpose only differing in hardware. In most cases you simply want to let Uwallet pick one at random.\r\nHowever if you prefer feel free to select a server manually.") choices = [_("Auto connect"), _("Select server manually")] choices_title = _("How do you want to connect to a server? ") clayout = ChoicesLayout(choices_title, choices) self.set_main_layout(clayout.layout(), title) auto_connect = True if clayout.selected_index() == 1: nlayout = NetworkChoiceLayout(network, self.config, wizard=True) if self.set_main_layout(nlayout.layout(), raise_on_cancel=False): nlayout.accept() auto_connect = False self.config.set_key('auto_connect', auto_connect, True) network.auto_connect = auto_connect
def update(features): self.features = features set_label_enabled() bl_hash = features.bootloader_hash.encode('hex') bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]]) noyes = [_("No"), _("Yes")] endis = [_("Enable Passphrases"), _("Disable Passphrases")] disen = [_("Disabled"), _("Enabled")] setchange = [_("Set a PIN"), _("Change PIN")] version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) coins = ", ".join(coin.coin_name for coin in features.coins) device_label.setText(features.label) pin_set_label.setText(noyes[features.pin_protection]) passphrases_label.setText(disen[features.passphrase_protection]) bl_hash_label.setText(bl_hash) label_edit.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) coins_label.setText(coins) clear_pin_button.setVisible(features.pin_protection) clear_pin_warning.setVisible(features.pin_protection) pin_button.setText(setchange[features.pin_protection]) pin_msg.setVisible(not features.pin_protection) passphrase_button.setText(endis[features.passphrase_protection]) language_label.setText(features.language)
def settings_dialog(self, window): d = WindowModalDialog(window, _("Exchange Rate Settings")) layout = QGridLayout(d) layout.addWidget(QLabel(_('Exchange rate API: ')), 0, 0) layout.addWidget(QLabel(_('Currency: ')), 1, 0) layout.addWidget(QLabel(_('History Rates: ')), 2, 0) # Currency list self.ccy_combo = QComboBox() self.ccy_combo.currentIndexChanged.connect(self.on_ccy_combo_change) self.populate_ccy_combo() def on_change_ex(idx): exchange = str(combo_ex.currentText()) if exchange != self.exchange.name(): self.set_exchange(exchange) self.hist_checkbox_update() def on_change_hist(checked): if checked: self.config.set_key('history_rates', 'checked') self.get_historical_rates() else: self.config.set_key('history_rates', 'unchecked') self.emit(SIGNAL('refresh_headers')) def ok_clicked(): self.timeout = 0 self.ccy_combo = None d.accept() combo_ex = QComboBox() combo_ex.addItems(sorted(self.exchanges.keys())) combo_ex.setCurrentIndex(combo_ex.findText(self.config_exchange())) combo_ex.currentIndexChanged.connect(on_change_ex) self.hist_checkbox = QCheckBox() self.hist_checkbox.stateChanged.connect(on_change_hist) self.hist_checkbox_update() ok_button = QPushButton(_("OK")) ok_button.clicked.connect(lambda: ok_clicked()) layout.addWidget(self.ccy_combo, 1, 1) layout.addWidget(combo_ex, 0, 1) layout.addWidget(self.hist_checkbox, 2, 1) layout.addWidget(ok_button, 3, 1) return d.exec_()