def func_wrapper(*args, **kwargs):
     run_next = kwargs['run_next']
     wizard = args[0]
     wizard.back_button.setText(_('Back') if wizard.can_go_back() else _('Cancel'))
     try:
         out = func(*args, **kwargs)
     except GoBack:
         wizard.go_back() if wizard.can_go_back() else wizard.close()
         return
     except UserCancelled:
         return
     #if out is None:
     #    out = ()
     if type(out) is not tuple:
         out = (out,)
     run_next(*out)
Example #2
0
 def password_dialog(self, pw, grid, pos):
     vkb_button = QPushButton(_("+"))
     vkb_button.setFixedWidth(20)
     vkb_button.clicked.connect(lambda: self.toggle_vkb(grid, pw))
     grid.addWidget(vkb_button, pos, 2)
     self.kb_pos = 2
     self.vkb = None
Example #3
0
    def __init__(self, parent, config, name):
        HW_PluginBase.__init__(self, parent, config, name)
        try:
            # Minimal test if python-trezor is installed
            import trezorlib
            try:
                library_version = trezorlib.__version__
            except AttributeError:
                # python-trezor only introduced __version__ in 0.9.0
                library_version = 'unknown'
            if library_version == 'unknown' or \
                    versiontuple(library_version) < self.minimum_library:
                self.libraries_available_message = (
                    _("Library version for '{}' is too old.").format(name) +
                    '\nInstalled: {}, Needed: {}'.format(
                        library_version, self.minimum_library))
                self.print_stderr(self.libraries_available_message)
                raise ImportError()
            self.libraries_available = True
        except ImportError:
            self.libraries_available = False
            return

        from . import client
        from . import transport
        import trezorlib.ckd_public
        import trezorlib.messages
        self.client_class = client.TrezorClient
        self.ckd_public = trezorlib.ckd_public
        self.types = trezorlib.messages
        self.DEVICE_IDS = ('TREZOR', )

        self.transport_handler = transport.TrezorTransport()
        self.device_manager().register_enumerate_func(self.enumerate)
 def seed_device_dialog(self):
     msg = _("Choose how to initialize your Digital Bitbox:\n")
     choices = [
         (_("Generate a new random wallet")),
         (_("Load a wallet from the micro SD card"))
     ]
     try:
         reply = self.handler.win.query_choice(msg, choices)
     except Exception:
         return # Back button pushed
     if reply == 0:
         self.dbb_generate_wallet()
     else:
         if not self.dbb_load_backup(show_msg=False):
             return
     self.isInitialized = True
Example #5
0
 def message_dialog(self, msg):
     self.clear_dialog()
     self.dialog = dialog = WindowModalDialog(self.top_level_window(),
                                              _("Ledger Status"))
     l = QLabel(msg)
     vbox = QVBoxLayout(dialog)
     vbox.addWidget(l)
     dialog.show()
Example #6
0
 def __init__(self, parent, contract=None):
     QDialog.__init__(self, parent=parent)
     self.setWindowTitle(_('Smart Contract'))
     self.setMinimumSize(700, 400)
     self.main_window = parent
     run_hook('contract_edit_dialog', self)
     layout = ContractInfoLayout(self, contract, callback=self.save)
     self.setLayout(layout)
Example #7
0
    def __init__(self, data, parent=None, title="", show_text=False):
        WindowModalDialog.__init__(self, parent, title)

        vbox = QVBoxLayout()
        qrw = QRCodeWidget(data)
        qscreen = QApplication.primaryScreen()
        vbox.addWidget(qrw, 1)
        if show_text:
            text = QTextEdit()
            text.setText(data)
            text.setReadOnly(True)
            vbox.addWidget(text)
        hbox = QHBoxLayout()
        hbox.addStretch(1)

        config = electrum.get_config()
        if config:
            filename = os.path.join(config.path, "qrcode.png")

            def print_qr():
                p = qscreen.grabWindow(qrw.winId())
                p.save(filename, 'png')
                self.show_message(_("QR code saved to file") + " " + filename)

            def copy_to_clipboard():
                p = qscreen.grabWindow(qrw.winId())
                QApplication.clipboard().setPixmap(p)
                # p.save(filename, 'png')
                # QApplication.clipboard().setImage(QImage(filename))
                self.show_message(_("QR code copied to clipboard"))

            b = QPushButton(_("Copy"))
            hbox.addWidget(b)
            b.clicked.connect(copy_to_clipboard)

            b = QPushButton(_("Save"))
            hbox.addWidget(b)
            b.clicked.connect(print_qr)

        b = QPushButton(_("Close"))
        hbox.addWidget(b)
        b.clicked.connect(self.accept)
        b.setDefault(True)

        vbox.addLayout(hbox)
        self.setLayout(vbox)
Example #8
0
 def on_new_window(self, window):
     wallet = window.wallet
     if not isinstance(wallet, self.wallet_class):
         return
     if wallet.can_sign_without_server():
         msg = ' '.join([
             _('This wallet was restored from seed, and it contains two master private keys.'
               ),
             _('Therefore, two-factor authentication is disabled.')
         ])
         action = lambda: window.show_message(msg)
     else:
         action = partial(self.settings_dialog, window)
     button = StatusBarButton(QIcon(":icons/trustedcoin-status.png"),
                              _("TrustedCoin"), action)
     window.statusBar().addPermanentWidget(button)
     self.start_request_thread(window.wallet)
Example #9
0
 def catch_exception(self, *args, **kwargs):
     try:
         return func(self, *args, **kwargs)
     except BTChipException as e:
         if e.sw == 0x6982:
             raise Exception(_('Your Ledger is locked. Please unlock it.'))
         else:
             raise
Example #10
0
    def request_otp_dialog(self, window, _id, otp_secret):
        vbox = QVBoxLayout()
        if otp_secret is not None:
            uri = "otpauth://totp/%s?secret=%s" % ('trustedcoin.com',
                                                   otp_secret)
            l = QLabel(
                "Please scan the following QR code in Google Authenticator. You may as well use the following key: %s"
                % otp_secret)
            l.setWordWrap(True)
            vbox.addWidget(l)
            qrw = QRCodeWidget(uri)
            vbox.addWidget(qrw, 1)
            msg = _('Then, enter your Google Authenticator code:')
        else:
            label = QLabel(
                "This wallet is already registered with Trustedcoin. "
                "To finalize wallet creation, please enter your Google Authenticator Code. "
            )
            label.setWordWrap(1)
            vbox.addWidget(label)
            msg = _('Google Authenticator code:')

        hbox = QHBoxLayout()
        hbox.addWidget(WWLabel(msg))
        pw = AmountEdit(None, is_int=True)
        pw.setFocus(True)
        pw.setMaximumWidth(50)
        hbox.addWidget(pw)
        vbox.addLayout(hbox)

        cb_lost = QCheckBox(_("I have lost my Google Authenticator account"))
        cb_lost.setToolTip(
            _("Check this box to request a new secret. You will need to retype your seed."
              ))
        vbox.addWidget(cb_lost)
        cb_lost.setVisible(otp_secret is None)

        def set_enabled():
            b = True if cb_lost.isChecked() else len(pw.text()) == 6
            window.next_button.setEnabled(b)

        pw.textChanged.connect(set_enabled)
        cb_lost.toggled.connect(set_enabled)

        window.exec_layout(vbox, next_enabled=False, raise_on_cancel=False)
        return pw.get_amount(), cb_lost.isChecked()
 def create_menu(self, position):
     item = self.currentItem()
     if not item:
         return
     menu = QMenu()
     server = item.data(1, Qt.UserRole)
     menu.addAction(_("Use as server"), lambda: self.set_server(server))
     menu.exec_(self.viewport().mapToGlobal(position))
Example #12
0
 def on_filename(filename):
     path = os.path.join(wallet_folder, filename)
     wallet_from_memory = get_wallet_from_daemon(path)
     try:
         if wallet_from_memory:
             self.storage = wallet_from_memory.storage
         else:
             self.storage = WalletStorage(path)
         self.next_button.setEnabled(True)
     except BaseException:
         traceback.print_exc(file=sys.stderr)
         self.storage = None
         self.next_button.setEnabled(False)
     if self.storage:
         if not self.storage.file_exists():
             msg =_("This file does not exist.") + '\n' \
                   + _("Press 'Next' to create this wallet, or choose another file.")
             pw = False
         elif not wallet_from_memory:
             if self.storage.is_encrypted_with_user_pw():
                 msg = _("This file is encrypted with a password.") + '\n' \
                       + _('Enter your password or choose another file.')
                 pw = True
             elif self.storage.is_encrypted_with_hw_device():
                 msg = _("This file is encrypted using a hardware device.") + '\n' \
                       + _("Press 'Next' to choose device to decrypt.")
                 pw = False
             else:
                 msg = _("Press 'Next' to open this wallet.")
                 pw = False
         else:
             msg = _("This file is already open in memory.") + "\n" \
                   + _("Press 'Next' to create/focus window.")
             pw = False
     else:
         msg = _('Cannot read file')
         pw = False
     self.msg_label.setText(msg)
     if pw:
         self.pw_label.show()
         self.pw_e.show()
         self.pw_e.setFocus()
     else:
         self.pw_label.hide()
         self.pw_e.hide()
 def create_menu(self, position):
     menu = QMenu()
     selected = self.selectedItems()
     multi_select = len(selected) > 1
     if not selected:
         menu.addAction(_("Add contract"),
                        lambda: self.parent.contract_add_dialog())
         menu.addAction(_("Create contract"),
                        lambda: self.parent.contract_create_dialog())
     elif not multi_select:
         item = selected[0]
         name = item.text(0)
         address = item.text(1)
         column = self.currentColumn()
         column_title = self.headerItem().text(column)
         column_data = '\n'.join([item.text(column) for item in selected])
         menu.addAction(
             _("Copy %s") % column_title,
             lambda: self.parent.app.clipboard().setText(column_data))
         menu.addAction(_("Edit"),
                        lambda: self.parent.contract_edit_dialog(address))
         menu.addAction(_("Function"),
                        lambda: self.parent.contract_func_dialog(address))
         menu.addAction(_("Delete"),
                        lambda: self.parent.delete_samart_contact(address))
         URL = block_explorer_URL(self.config, {'contract': address})
         if URL:
             menu.addAction(_("View on block explorer"),
                            lambda: open_browser(URL))
     run_hook('create_smart_contract_menu', menu, selected)
     menu.exec_(self.viewport().mapToGlobal(position))
Example #14
0
    def __init__(self, dialog, callback):
        """
        :type dialog: QDialog
        :type callback: func
        """
        QGridLayout.__init__(self)
        self.setSpacing(8)
        self.setColumnStretch(3, 1)
        self.callback = callback
        self.dialog = dialog

        if isinstance(self.dialog.parent().wallet.keystore, TrezorKeyStore):
            self.dialog.show_message(
                'Trezor does not support QRC20 Token for now')
            self.dialog.reject()
            return

        self.addresses = self.dialog.parent(
        ).wallet.get_addresses_sort_by_balance()

        addr_type, __ = b58_address_to_hash160(self.addresses[0])
        if not addr_type == constants.net.ADDRTYPE_P2PKH:
            self.dialog.show_message('only P2PKH address supports QRC20 Token')
            self.dialog.reject()
            return

        address_lb = QLabel(_("Contract Address:"))
        self.contract_addr_e = ButtonsLineEdit()
        self.addWidget(address_lb, 1, 0)
        self.addWidget(self.contract_addr_e, 1, 1, 1, -1)

        address_lb = QLabel(_("My Address:"))
        self.address_combo = QComboBox()
        self.address_combo.setMinimumWidth(300)
        self.address_combo.addItems(self.addresses)
        self.addWidget(address_lb, 2, 0)
        self.addWidget(self.address_combo, 2, 1, 1, -1)

        self.cancel_btn = CancelButton(dialog)
        self.save_btn = QPushButton(_('Save'))
        self.save_btn.setDefault(True)
        self.save_btn.clicked.connect(self.save_input)
        buttons = Buttons(*[self.cancel_btn, self.save_btn])
        buttons.addStretch()
        self.addLayout(buttons, 3, 2, 2, -1)
Example #15
0
    def create_menu(self, position):
        self.selectedIndexes()
        item = self.currentItem()
        if not item:
            return
        column = self.currentColumn()
        tx_hash = item.data(0, Qt.UserRole)
        if not tx_hash:
            return
        if column is 0:
            column_title = "ID"
            column_data = tx_hash
        else:
            column_title = self.headerItem().text(column)
            column_data = item.text(column)

        tx_URL = block_explorer_URL(self.config, {'tx': tx_hash})
        height, conf, timestamp = self.wallet.get_tx_height(tx_hash)
        tx = self.wallet.transactions.get(tx_hash)
        is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
        is_unconfirmed = height <= 0
        pr_key = self.wallet.invoices.paid.get(tx_hash)

        menu = QMenu()
        if height == TX_HEIGHT_LOCAL:
            menu.addAction(_("Remove"), lambda: self.remove_local_tx(tx_hash))

        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(_("Details"), lambda: self.parent.show_transaction(tx))
        if is_unconfirmed and tx:
            # note: the current implementation of RBF *needs* the old tx fee
            rbf = is_mine and not tx.is_final() and fee is not None
            if rbf:
                menu.addAction(_("Increase fee"),
                               lambda: self.parent.bump_fee_dialog(tx))
            else:
                child_tx = self.wallet.cpfp(tx, 0)
                if child_tx:
                    menu.addAction(_("Child pays for parent"),
                                   lambda: self.parent.cpfp(tx, child_tx))
        if pr_key:
            menu.addAction(self.icon_cache.get(":icons/seal"),
                           _("View invoice"),
                           lambda: self.parent.show_invoice(pr_key))
        if tx_URL:
            menu.addAction(_("View on block explorer"),
                           lambda: open_browser(tx_URL))
        menu.exec_(self.viewport().mapToGlobal(position))
Example #16
0
 def create_menu(self, position):
     menu = QMenu()
     item = self.itemAt(position)
     if not item:
         return
     key = item.data(0, Qt.UserRole)
     column = self.currentColumn()
     column_title = self.headerItem().text(column)
     column_data = item.text(column)
     pr = self.parent.invoices.get(key)
     status = self.parent.invoices.get_status(key)
     if column_data:
         menu.addAction(_("Copy %s")%column_title, lambda: self.parent.app.clipboard().setText(column_data))
     menu.addAction(_("Details"), lambda: self.parent.show_invoice(key))
     if status == PR_UNPAID:
         menu.addAction(_("Pay Now"), lambda: self.parent.do_pay_invoice(key))
     menu.addAction(_("Delete"), lambda: self.parent.delete_invoice(key))
     menu.exec_(self.viewport().mapToGlobal(position))
Example #17
0
 def __init__(self, parent):
     QDialog.__init__(self, parent=parent)
     self.setWindowTitle(_('Create Smart Contract'))
     self.setMinimumSize(700, 400)
     self.setMaximumSize(780, 500)
     self.main_window = parent
     run_hook('contract_create_dialog', self)
     layout = ContractCreateLayout(self)
     self.setLayout(layout)
Example #18
0
 def update_dlg(self):
     self.modes.setCurrentIndex(self.cfg['mode'])
     self.modebox.setVisible(True)
     self.addPair.setText(
         _("Pair") if not self.cfg['pair'] else _("Re-Pair"))
     self.addPair.setVisible(self.txdata['confirmationType'] > 2)
     self.helpmsg.setText(
         helpTxt[self.cfg['mode'] if self.cfg['mode'] < 2 else 2 if self.
                 cfg['pair'] else 4])
     self.helpmsg.setMinimumHeight(180 if self.txdata['confirmationType'] ==
                                   1 else 100)
     self.pairbox.setVisible(False)
     self.helpmsg.setVisible(True)
     self.pinbox.setVisible(self.cfg['mode'] == 0)
     self.cardbox.setVisible(self.cfg['mode'] == 1)
     self.pintxt.setFocus(
         True) if self.cfg['mode'] == 0 else self.cardtxt.setFocus(True)
     self.setMaximumHeight(200)
Example #19
0
 def remove_local_tx(self, delete_tx):
     to_delete = {delete_tx}
     to_delete |= self.wallet.get_depending_transactions(delete_tx)
     question = _("Are you sure you want to remove this transaction?")
     if len(to_delete) > 1:
         question = _(
             "Are you sure you want to remove this transaction and {} child transactions?"
             .format(len(to_delete) - 1))
     answer = QMessageBox.question(self.parent, _("Please confirm"),
                                   question, QMessageBox.Yes,
                                   QMessageBox.No)
     if answer == QMessageBox.No:
         return
     for tx in to_delete:
         self.wallet.remove_transaction(tx)
     self.wallet.save_transactions(write=True)
     # need to update at least: history_list, utxo_list, address_list
     self.parent.need_update.set()
Example #20
0
def filename_field(parent, config, defaultname, select_msg):

    vbox = QVBoxLayout()
    vbox.addWidget(QLabel(_("Format")))
    gb = QGroupBox("format", parent)
    b1 = QRadioButton(gb)
    b1.setText(_("CSV"))
    b1.setChecked(True)
    b2 = QRadioButton(gb)
    b2.setText(_("json"))
    vbox.addWidget(b1)
    vbox.addWidget(b2)

    hbox = QHBoxLayout()

    directory = config.get('io_dir', os.path.expanduser('~'))
    path = os.path.join(directory, defaultname)
    filename_e = QLineEdit()
    filename_e.setText(path)

    def func():
        text = filename_e.text()
        _filter = "*.csv" if text.endswith(
            ".csv") else "*.json" if text.endswith(".json") else None
        p, __ = QFileDialog.getSaveFileName(None, select_msg, text, _filter)
        if p:
            filename_e.setText(p)

    button = QPushButton(_('File'))
    button.clicked.connect(func)
    hbox.addWidget(button)
    hbox.addWidget(filename_e)
    vbox.addLayout(hbox)

    def set_csv(v):
        text = filename_e.text()
        text = text.replace(".json", ".csv") if v else text.replace(
            ".csv", ".json")
        filename_e.setText(text)

    b1.clicked.connect(lambda: set_csv(True))
    b2.clicked.connect(lambda: set_csv(False))

    return vbox, filename_e, b1
Example #21
0
    def sign_message(self, sequence, message, password):
        sig = None
        try:
            message = message.encode('utf8')
            inputPath = self.get_derivation() + "/%d/%d" % sequence
            msg_hash = Hash(msg_magic(message))
            inputHash = to_hexstr(msg_hash)
            hasharray = []
            hasharray.append({'hash': inputHash, 'keypath': inputPath})
            hasharray = json.dumps(hasharray)

            msg = b'{"sign":{"meta":"sign message", "data":%s}}' % hasharray.encode('utf8')

            dbb_client = self.plugin.get_client(self)

            if not dbb_client.is_paired():
                raise Exception("Could not sign message.")

            reply = dbb_client.hid_send_encrypt(msg)
            self.handler.show_message(_("Signing message ...\r\n\r\n" \
                                        "To continue, touch the Digital Bitbox's blinking light for 3 seconds.\r\n\r\n" \
                                        "To cancel, briefly touch the blinking light or wait for the timeout."))
            reply = dbb_client.hid_send_encrypt(msg) # Send twice, first returns an echo for smart verification (not implemented)
            self.handler.clear_dialog()

            if 'error' in reply:
                raise Exception(reply['error']['message'])

            if 'sign' not in reply:
                raise Exception("Could not sign message.")

            if 'recid' in reply['sign'][0]:
                # firmware > v2.1.1
                sig = bytes([27 + int(reply['sign'][0]['recid'], 16) + 4]) + binascii.unhexlify(reply['sign'][0]['sig'])
                pk, compressed = pubkey_from_signature(sig, msg_hash)
                pk = point_to_ser(pk.pubkey.point, compressed)
                addr = public_key_to_p2pkh(pk)
                if verify_message(addr, sig, message) is False:
                    raise Exception("Could not sign message")
            elif 'pubkey' in reply['sign'][0]:
                # firmware <= v2.1.1
                for i in range(4):
                    sig = bytes([27 + i + 4]) + binascii.unhexlify(reply['sign'][0]['sig'])
                    try:
                        addr = public_key_to_p2pkh(binascii.unhexlify(reply['sign'][0]['pubkey']))
                        if verify_message(addr, sig, message):
                            break
                    except Exception:
                        continue
                else:
                    raise Exception("Could not sign message")


        except BaseException as e:
            self.give_error(e)
        return sig
Example #22
0
 def toggle_passphrase():
     title = _("Confirm Toggle Passphrase Protection")
     currently_enabled = self.features.passphrase_protection
     if currently_enabled:
         msg = _("After disabling passphrases, you can only pair this "
                 "Electrum wallet if it had an empty passphrase.  "
                 "If its passphrase was not empty, you will need to "
                 "create a new wallet with the install wizard.  You "
                 "can use this wallet again at any time by re-enabling "
                 "passphrases and entering its passphrase.")
     else:
         msg = _("Your current Electrum wallet can only be used with "
                 "an empty passphrase.  You must create a separate "
                 "wallet with the install wizard for other passphrases "
                 "as each one generates a new set of addresses.")
     msg += "\n\n" + _("Are you sure you want to proceed?")
     if not self.question(msg, title=title):
         return
     invoke_client('toggle_passphrase', unpair_after=currently_enabled)
Example #23
0
 def checkDevice(self):
     if not self.preflightDone:
         try:
             self.perform_hw1_preflight()
         except BTChipException as e:
             print_error('checkDevice', e)
             if (e.sw == 0x6d00 or e.sw == 0x6700):
                 raise Exception(_("Device not in Btn mode")) from e
             raise e
         self.preflightDone = True
Example #24
0
 def f(b):
     self.is_seed = (lambda x: bool(x)) if b else self.saved_is_seed
     self.on_edit()
     self.is_bip39 = b
     if b:
         msg = ' '.join([
             '<b>' + _('Warning') + ':</b>  ',
             _('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'
               ),
             _('However, we do not generate BIP39 seeds, because they do not meet our safety standard.'
               ),
             _('BIP39 seeds do not include a version number, which compromises compatibility with future software.'
               ),
             _('We do not guarantee that BIP39 imports will always be supported in Electrum.'
               ),
         ])
     else:
         msg = ''
     self.seed_warning.setText(msg)
Example #25
0
 def __init__(self, parent):
     """
     :type parent: ElectrumWindow
     :type token: Token
     """
     QDialog.__init__(self, parent=parent)
     self.setMinimumSize(500, 100)
     self.setWindowTitle(_('Add Token'))
     layout = TokenAddLayout(self, callback=self.save)
     self.setLayout(layout)
Example #26
0
 def pin_changed(s):
     if len(s) < len(self.idxs):
         i = self.idxs[len(s)]
         addr = self.txdata['address']
         addr = addr[:i] + '<u><b>' + addr[i:i +
                                           1] + '</u></b>' + addr[i +
                                                                  1:]
         self.addrtext.setHtml(str(addr))
     else:
         self.addrtext.setHtml(_("Press Enter"))
Example #27
0
    def check_device_dialog(self):
        # Set password if fresh device
        if self.password is None and not self.dbb_has_password():
            if not self.setupRunning:
                return False # A fresh device cannot connect to an existing wallet
            msg = _("An uninitialized Digital Bitbox is detected. " \
                    "Enter a new password below.\r\n\r\n REMEMBER THE PASSWORD!\r\n\r\n" \
                    "You cannot access your coins or a backup without the password.\r\n" \
                    "A backup is saved automatically when generating a new wallet.")
            if self.password_dialog(msg):
                reply = self.hid_send_plain(b'{"password":"******"}')
            else:
                return False

        # Get password from user if not yet set
        msg = _("Enter your Digital Bitbox password:"******"led":"blink"}')
            if 'error' in reply:
                self.password = None
                if reply['error']['code'] == 109:
                    msg = _("Incorrect password entered.\r\n\r\n"  \
                            + reply['error']['message'] + "\r\n\r\n" \
                            "Enter your Digital Bitbox password:"******"Unexpected error occurred.\r\n\r\n"  \
                            + reply['error']['message'] + "\r\n\r\n" \
                            "Enter your Digital Bitbox password:"******"device":"info"}')
            if reply['device']['id'] != "":
                self.recover_or_erase_dialog() # Already seeded
            else:
                self.seed_device_dialog() # Seed if not initialized
            self.mobile_pairing_dialog()
        return self.isInitialized
Example #28
0
    def receive_menu(self, menu, addrs, wallet):
        if type(wallet) is not Standard_Wallet:
            return
        keystore = wallet.get_keystore()
        if type(keystore) == self.keystore_class and len(addrs) == 1:

            def show_address():
                keystore.thread.add(
                    partial(self.show_address, wallet, addrs[0]))

            menu.addAction(_("Show on Ledger"), show_address)
Example #29
0
 def get_tooltip(self, pos, fee_rate):
     from btn_electrum.util import fee_levels
     rate_str = self.window.format_amount(fee_rate) + ' ' + self.window.base_unit() + '/kB'
     if self.dyn:
         tooltip = fee_levels[pos] + '\n' + rate_str
     else:
         tooltip = 'Fixed rate: ' + rate_str
         if self.config.has_fee_estimates():
             i = self.config.reverse_dynfee(fee_rate)
             tooltip += '\n' + (_('Low fee') if i < 0 else 'Within %d blocks'%i)
     return tooltip
Example #30
0
 def get_xpub(self, device_id, derivation, xtype, wizard):
     if xtype not in self.SUPPORTED_XTYPES:
         raise ScriptTypeNotSupported(
             _('This type of script is not supported with {}.').format(
                 self.device))
     devmgr = self.device_manager()
     client = devmgr.client_by_id(device_id)
     client.handler = wizard
     xpub = client.get_xpub(derivation, xtype)
     client.used()
     return xpub