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 populate_modes(self): self.modes.blockSignals(True) self.modes.clear() self.modes.addItem(_("Summary Text PIN (requires dongle replugging)") if self.txdata['confirmationType'] == 1 else _("Summary Text PIN is Disabled")) if self.txdata['confirmationType'] > 1: self.modes.addItem(_("Security Card Challenge")) self.modes.blockSignals(False)
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 make_model(self, htlcs) -> QtGui.QStandardItemModel: model = QtGui.QStandardItemModel(0, 2) model.setHorizontalHeaderLabels(['HTLC', 'Property value']) parentItem = model.invisibleRootItem() folder_types = { 'settled': _('Fulfilled HTLCs'), 'inflight': _('HTLCs in current commitment transaction'), 'failed': _('Failed HTLCs'), } self.folders = {} self.keyname_rows = {} for keyname, i in folder_types.items(): myFont=QtGui.QFont() myFont.setBold(True) folder = HTLCItem(i) folder.setFont(myFont) parentItem.appendRow(folder) self.folders[keyname] = folder mapping = {} num = 0 for item in htlcs: pay_hash, chan_id, i, direction, status = item if status != keyname: continue it = self.make_htlc_item(i, direction) self.folders[keyname].appendRow(it) mapping[i.payment_hash] = num num += 1 self.keyname_rows[keyname] = mapping return model
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 initialize_device(self, device_id, wizard, handler): # Initialization method msg = _("Choose how you want to initialize your {}.").format( self.device, self.device) choices = [ # Must be short as QT doesn't word-wrap radio button text (TIM_NEW, _("Let the device generate a completely new seed randomly")), (TIM_RECOVER, _("Recover from a seed you have previously written down")), ] def f(method): import threading settings = self.request_trezor_init_settings( wizard, method, device_id) t = threading.Thread(target=self._initialize_device_safe, args=(settings, method, device_id, wizard, handler)) t.setDaemon(True) t.start() exit_code = wizard.loop.exec_() if exit_code != 0: # this method (initialize_device) was called with the expectation # of leaving the device in an initialized state when finishing. # signal that this is not the case: raise UserCancelled() wizard.choice_dialog(title=_('Initialize Device'), message=msg, choices=choices, run_next=f)
def ui_text(self) -> str: return { self.ALL: _('All'), self.UNUSED: _('Unused'), self.FUNDED: _('Funded'), self.USED_AND_EMPTY: _('Used'), }[self]
def __init__(self, gui_object: 'ElectrumGui'): QDialog.__init__(self) self.gui_object = gui_object self.config = gui_object.config self.network = gui_object.daemon.network assert self.network self.setWindowTitle(_('Lightning Network')) self.setMinimumWidth(600) vbox = QVBoxLayout(self) self.num_peers = QLabel('') vbox.addWidget(self.num_peers) self.num_nodes = QLabel('') vbox.addWidget(self.num_nodes) self.num_channels = QLabel('') vbox.addWidget(self.num_channels) self.status = QLabel('') vbox.addWidget(self.status) vbox.addStretch(1) b = QPushButton(_('Close')) b.clicked.connect(self.close) vbox.addLayout(Buttons(b)) util.register_callback(self.on_channel_db, ['channel_db']) util.register_callback(self.set_num_peers, ['gossip_peers']) util.register_callback(self.set_unknown_channels, ['unknown_channels']) self.network.channel_db.update_counts() # trigger callback if self.network.lngossip: self.set_num_peers('', self.network.lngossip.num_peers()) self.set_unknown_channels('', len(self.network.lngossip.unknown_ids)) else: self.num_peers.setText(_('Lightning gossip not active.'))
def settings_dialog(self, window: WindowModalDialog): wallet = window.parent().wallet if not wallet.get_fingerprint(): window.show_error( _("{} plugin does not support this type of wallet.").format( "Label Sync")) return d = WindowModalDialog(window, _("Label Settings")) hbox = QHBoxLayout() hbox.addWidget(QLabel("Label sync options:")) upload = ThreadedButton("Force upload", partial(self.push, wallet), partial(self.done_processing_success, d), partial(self.done_processing_error, d)) download = ThreadedButton("Force download", partial(self.pull, wallet, True), partial(self.done_processing_success, d), partial(self.done_processing_error, d)) vbox = QVBoxLayout() vbox.addWidget(upload) vbox.addWidget(download) hbox.addLayout(vbox) vbox = QVBoxLayout(d) vbox.addLayout(hbox) vbox.addSpacing(20) vbox.addLayout(Buttons(OkButton(d))) return bool(d.exec_())
def create_menu(self, position): from electrum_dsv.wallet import Multisig_Wallet is_multisig = isinstance(self.wallet, Multisig_Wallet) can_delete = self.wallet.can_delete_address() selected = self.selected_in_column(self.Columns.ADDRESS) if not selected: return multi_select = len(selected) > 1 addrs = [self.item_from_index(item).text() for item in selected] menu = QMenu() if not multi_select: idx = self.indexAt(position) if not idx.isValid(): return item = self.item_from_index(idx) if not item: return addr = addrs[0] addr_column_title = self.std_model.horizontalHeaderItem( self.Columns.LABEL).text() addr_idx = idx.sibling(idx.row(), self.Columns.LABEL) self.add_copy_menu(menu, idx) menu.addAction(_('Details'), lambda: self.parent.show_address(addr)) persistent = QPersistentModelIndex(addr_idx) menu.addAction(_("Edit {}").format(addr_column_title), lambda p=persistent: self.edit(QModelIndex(p))) #menu.addAction(_("Request payment"), lambda: self.parent.receive_at(addr)) if self.wallet.can_export(): menu.addAction(_("Private key"), lambda: self.parent.show_private_key(addr)) if not is_multisig and not self.wallet.is_watching_only(): menu.addAction(_("Sign/verify message"), lambda: self.parent.sign_verify_message(addr)) menu.addAction(_("Encrypt/decrypt message"), lambda: self.parent.encrypt_message(addr)) if can_delete: menu.addAction(_("Remove from wallet"), lambda: self.parent.remove_address(addr)) addr_URL = block_explorer_URL(self.config, 'addr', addr) if addr_URL: menu.addAction(_("View on block explorer"), lambda: webopen(addr_URL)) if not self.wallet.is_frozen_address(addr): menu.addAction( _("Freeze"), lambda: self.parent. set_frozen_state_of_addresses([addr], True)) else: menu.addAction( _("Unfreeze"), lambda: self.parent. set_frozen_state_of_addresses([addr], False)) coins = self.wallet.get_spendable_coins(addrs) if coins: menu.addAction(_("Spend from"), lambda: self.parent.utxo_list.set_spend_list(coins)) run_hook('receive_menu', menu, addrs, self.wallet) menu.exec_(self.viewport().mapToGlobal(position))
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 create_menu(self, position): item = self.currentItem() if not item: return item_type = item.data(0, self.ITEMTYPE_ROLE) menu = QMenu() if item_type == self.ItemType.CONNECTED_SERVER: server = item.data(0, self.SERVER_ADDR_ROLE) # type: ServerAddr menu.addAction(_("Use as server"), lambda: self.parent.follow_server(server)) elif item_type == self.ItemType.DISCONNECTED_SERVER: server = item.data(0, self.SERVER_ADDR_ROLE) # type: ServerAddr def func(): self.parent.server_e.setText(server.net_addr_str()) self.parent.set_server() menu.addAction(_("Use as server"), func) elif item_type == self.ItemType.CHAIN: chain_id = item.data(0, self.CHAIN_ID_ROLE) menu.addAction(_("Follow this branch"), lambda: self.parent.follow_branch(chain_id)) else: return menu.exec_(self.viewport().mapToGlobal(position))
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 __init__(self, parent=None): QtWidgets.QPlainTextEdit.__init__(self, parent) self.history = [] self.namespace = {} self.construct = [] self.setGeometry(50, 75, 600, 400) self.setWordWrapMode(QtGui.QTextOption.WrapAnywhere) self.setUndoRedoEnabled(False) self.document().setDefaultFont( QtGui.QFont(MONOSPACE_FONT, 10, QtGui.QFont.Normal)) self.newPrompt( "" ) # make sure there is always a prompt, even before first server.banner self.updateNamespace({'run': self.run_script}) self.set_json(False) warning_text = "<h1>{}</h1><br>{}<br><br>{}".format( _("Warning!"), _("Do not paste code here that you don't understand. Executing the wrong code could lead " "to your coins being irreversibly lost."), _("Click here to hide this message.")) self.messageOverlay = OverlayLabel(warning_text, self)
def make_cypherseed(self, img, rawnoise, calibration=False, is_seed=True): img = img.convertToFormat(QImage.Format_Mono) p = QPainter() p.begin(img) p.setCompositionMode(26) #xor p.drawImage(0, 0, rawnoise) p.end() cypherseed = self.pixelcode_2x2(img) cypherseed = QBitmap.fromImage(cypherseed) cypherseed = cypherseed.scaled(self.f_size, Qt.KeepAspectRatio) cypherseed = self.overlay_marks(cypherseed, True, calibration) if not is_seed: self.filename_prefix = 'custom_secret_' self.was = _('Custom secret') else: self.filename_prefix = self.wallet_name + '_seed_' self.was = self.wallet_name + ' ' + _('seed') if self.extension: self.ext_warning(self.c_dialog) if not calibration: self.toPdf(QImage(cypherseed)) QDesktopServices.openUrl( QUrl.fromLocalFile(self.get_path_to_revealer_file('.pdf'))) cypherseed.save(self.get_path_to_revealer_file('.png')) self.bcrypt(self.c_dialog) return cypherseed
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 ext_warning(self, dialog): dialog.show_message(''.join([ "<b>", _("Warning"), ": </b>", _("your seed extension will <b>not</b> be included in the encrypted backup." ) ]), rich_text=True) dialog.close()
def __init__(self, text="", allow_multi=False, *, config: SimpleConfig): ButtonsTextEdit.__init__(self, text) self.allow_multi = allow_multi self.config = config self.setReadOnly(False) self.addButton("file.png", self.file_input, _("Read file")) icon = "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png" self.addButton(icon, self.qr_input, _("Read QR code")) run_hook('scan_text_edit', self)
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 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 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 doriancoins in it!") if not self.question( msg, title=title, icon=QMessageBox.Critical): return invoke_client('wipe_device', unpair_after=True)
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(msg)
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 confirm_seed_dialog(self, run_next, seed, 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 dbb_erase(self): self.handler.show_message(_("Are you sure you want to erase the Digital Bitbox?") + "\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.")) hid_reply = self.hid_send_encrypt(b'{"reset":"__ERASE__"}') self.handler.finished() if 'error' in hid_reply: raise UserFacingException(hid_reply['error']['message']) else: self.password = None raise UserFacingException('Device erased')
def bcrypt(self, dialog): self.rawnoise = False version = self.versioned_seed.version code_id = self.versioned_seed.checksum dialog.show_message(''.join([ _("{} encrypted for Revealer {}_{} saved as PNG and PDF at: "). format(self.was, version, code_id), "<b>", self.get_path_to_revealer_file(), "</b>", "<br/>", "<br/>", "<b>", _("Always check your backups.") ]), rich_text=True) dialog.close()
def manipulate_keystore_dict_during_wizard_setup(self, d: dict): master_xpub = self.dev.master_xpub if master_xpub is not None: try: node = BIP32Node.from_xkey(master_xpub) except InvalidMasterKeyVersionBytes: raise UserFacingException( _('Invalid xpub magic. Make sure your {} device is set to the correct chain.' ).format(self.device) + ' ' + _('You might have to unplug and plug it in again.') ) from None d['ckcc_xpub'] = master_xpub
def plot_history_dialog(self): if plot_history is None: self.parent.show_message( _("Can't plot history.") + '\n' + _("Perhaps some dependencies are missing...") + " (matplotlib?)") return try: plt = plot_history(list(self.hm.transactions.values())) plt.show() except NothingToPlotException as e: self.parent.show_message(str(e))