Ejemplo n.º 1
0
    def get_xpub(self, device_id, derivation, xtype, wizard):
        # this seems to be part of the pairing process only, not during normal ops?
        # base_wizard:on_hw_derivation
        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 = self.create_handler(wizard)
        client.ping_check()

        xpub = client.get_xpub(derivation, xtype)
        return xpub
Ejemplo n.º 2
0
 def create_menu(self, position):
     idx = self.indexAt(position)
     item = self.model().itemFromIndex(idx)
     item_col0 = self.model().itemFromIndex(
         idx.sibling(idx.row(), self.Columns.DATE))
     if not item or not item_col0:
         return
     key = item_col0.data(Qt.UserRole)
     column = idx.column()
     column_title = self.model().horizontalHeaderItem(column).text()
     column_data = item.text()
     status = self.parent.invoices.get_status(key)
     menu = QMenu(self)
     if column_data:
         menu.addAction(
             _("Copy {}").format(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))
Ejemplo n.º 3
0
 def get_xpub(self, bip32_path, xtype):
     assert xtype in ColdcardPlugin.SUPPORTED_XTYPES
     print_error('[coldcard]', 'Derive xtype = %r' % xtype)
     xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path), timeout=5000)
     # TODO handle timeout?
     # change type of xpub to the requested type
     try:
         __, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub)
     except InvalidMasterKeyVersionBytes:
         raise Exception(_('Invalid xpub magic. Make sure your {} device is set to the correct chain.')
                         .format(self.device)) from None
     if xtype != 'standard':
         xpub = serialize_xpub(xtype, c, cK, depth, fingerprint, child_number)
     return xpub
Ejemplo n.º 4
0
 def pin_changed(s):
     if len(s) < len(self.idxs):
         i = self.idxs[len(s)]
         addr = self.txdata['address']
         if not constants.net.TESTNET:
             text = addr[:i] + '<u><b>' + addr[i:i+1] + '</u></b>' + addr[i+1:]
         else:
             # pin needs to be created from mainnet address
             addr_mainnet = bitcoin.script_to_address(bitcoin.address_to_script(addr), net=constants.BitcoinMainnet)
             addr_mainnet = addr_mainnet[:i] + '<u><b>' + addr_mainnet[i:i+1] + '</u></b>' + addr_mainnet[i+1:]
             text = str(addr) + '\n' + str(addr_mainnet)
         self.addrtext.setHtml(str(text))
     else:
         self.addrtext.setHtml(_("Press Enter"))
Ejemplo n.º 5
0
    def callback_PassphraseRequest(self, req):
        if req and hasattr(req, 'on_device') and req.on_device is True:
            return self.proto.PassphraseAck()

        if self.creating_wallet:
            msg = _("Enter a passphrase to generate this wallet.  Each time "
                    "you use this wallet your {} will prompt you for the "
                    "passphrase.  If you forget the passphrase you cannot "
                    "access the namecoins in the wallet.").format(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)

        ack = self.proto.PassphraseAck(passphrase=passphrase)
        length = len(ack.passphrase)
        if length > 50:
            self.handler.show_error(
                _("Too long passphrase ({} > 50 chars).").format(length))
            return self.proto.Cancel()
        return ack
Ejemplo n.º 6
0
    def show_address(self, wallet, address, keystore=None):
        if keystore is None:
            keystore = wallet.get_keystore()
        if not self.show_address_helper(wallet, address, keystore):
            return

        # Standard_Wallet => not multisig, must be bip32
        if type(wallet) is not Standard_Wallet:
            keystore.handler.show_error(_('This function is only available for standard wallets when using {}.').format(self.device))
            return

        sequence = wallet.get_address_index(address)
        txin_type = wallet.get_txin_type(address)
        keystore.show_address(sequence, txin_type)
Ejemplo n.º 7
0
 def waiting_dialog_for_billing_info(self, window, *, on_finished=None):
     def task():
         return self.request_billing_info(window.wallet, suppress_connection_error=False)
     def on_error(exc_info):
         e = exc_info[1]
         window.show_error("{header}\n{exc}\n\n{tor}"
                           .format(header=_('Error getting TrustedCoin account info.'),
                                   exc=str(e),
                                   tor=_('If you keep experiencing network problems, try using a Tor proxy.')))
     return WaitingDialog(parent=window,
                          message=_('Requesting account info from TrustedCoin server...'),
                          task=task,
                          on_success=on_finished,
                          on_error=on_error)
Ejemplo n.º 8
0
    def initialize_device(self, device_id, wizard, handler):
        # Initialization method
        msg = _("Choose how you want to initialize your {}.\n\n"
                "The first two methods are secure as no secret information "
                "is entered into your computer.\n\n"
                "For the last two methods you input secrets on your keyboard "
                "and upload them to your {}, and so you should "
                "only do those on a computer you know to be trustworthy "
                "and free of malware.").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)
Ejemplo n.º 9
0
    def waiting_dialog(
        self,
        task,
        msg=_("Electrum-NMC is generating your addresses, please wait.")):
        def target():
            task()
            self.emit(QtCore.SIGNAL('accept'))

        vbox = QVBoxLayout()
        self.waiting_label = QLabel(msg)
        vbox.addWidget(self.waiting_label)
        self.set_layout(vbox)
        t = threading.Thread(target=target)
        t.start()
        self.exec_()
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
 def request_otp_dialog(self, window, short_id, otp_secret, xpub3):
     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)
     self.check_otp(window, short_id, otp_secret, xpub3, pw.get_amount(), cb_lost.isChecked())
Ejemplo n.º 12
0
    def export_psbt(self, dia):
        # Called from hook in transaction dialog
        tx = dia.tx

        if tx.is_complete():
            # if they sign while dialog is open, it can transition from unsigned to signed,
            # which we don't support here, so do nothing
            return

        # can only expect Coldcard wallets to work with these files (right now)
        keystore = dia.wallet.get_keystore()
        assert type(keystore) == self.keystore_class

        # convert to PSBT
        raw_psbt = keystore.build_psbt(tx, wallet=dia.wallet)

        name = (dia.wallet.basename() + time.strftime('-%y%m%d-%H%M.psbt')).replace(' ', '-')
        fileName = dia.main_window.getSaveFileName(_("Select where to save the PSBT file"),
                                                        name, "*.psbt")
        if fileName:
            with open(fileName, "wb+") as f:
                f.write(raw_psbt)
            dia.show_message(_("Transaction exported successfully"))
            dia.saved = True
Ejemplo n.º 13
0
    def context_menu(self):
        view_menu = QMenu()
        themes_menu = view_menu.addMenu(_("&Themes"))
        selected_theme = self.actuator.selected_theme()
        theme_group = QActionGroup(self)
        for theme_name in self.actuator.theme_names():
            theme_action = themes_menu.addAction(theme_name)
            theme_action.setCheckable(True)
            if selected_theme == theme_name:
                theme_action.setChecked(True)

            class SelectThemeFunctor:
                def __init__(self, theme_name, toggle_theme):
                    self.theme_name = theme_name
                    self.toggle_theme = toggle_theme

                def __call__(self, checked):
                    if checked:
                        self.toggle_theme(self.theme_name)

            delegate = SelectThemeFunctor(theme_name, self.toggle_theme)
            theme_action.toggled.connect(delegate)
            theme_group.addAction(theme_action)
        view_menu.addSeparator()

        show_receiving = view_menu.addAction(_("Show Receiving addresses"))
        show_receiving.setCheckable(True)
        show_receiving.toggled.connect(self.toggle_receiving_layout)
        show_receiving.setChecked(self.config.get("gui_show_receiving", False))

        show_history = view_menu.addAction(_("Show History"))
        show_history.setCheckable(True)
        show_history.toggled.connect(self.show_history)
        show_history.setChecked(self.config.get("gui_show_history", False))

        return view_menu
Ejemplo n.º 14
0
    def __init__(self, prompt='>> ', startup_message='', parent=None):
        QtWidgets.QPlainTextEdit.__init__(self, parent)

        self.prompt = prompt
        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.showMessage(startup_message)

        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)
Ejemplo n.º 15
0
    def on_reset_auth(self, wizard, short_id, seed, passphrase, xpub3):
        xprv1, xpub1, xprv2, xpub2 = self.xkeys_from_seed(seed, passphrase)
        if (wizard.storage.get('x1/')['xpub'] != xpub1
                or wizard.storage.get('x2/')['xpub'] != xpub2):
            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 = ecc.ECPrivkey(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.request_otp_dialog(wizard, short_id, new_secret, xpub3)
Ejemplo n.º 16
0
 def restore_choice(self, wizard, seed, passphrase):
     wizard.set_icon(':icons/trustedcoin-wizard.png')
     wizard.stack = []
     title = _('Restore 2FA wallet')
     msg = ' '.join([
         'You are going to restore a wallet protected with two-factor authentication.',
         'Do you want to keep using two-factor authentication with this wallet,',
         'or do you want to disable it, and have two master private keys in your wallet?'
     ])
     choices = [('keep', 'Keep'), ('disable', 'Disable')]
     f = lambda x: self.on_choice(wizard, seed, passphrase, x)
     wizard.choice_dialog(choices=choices,
                          message=msg,
                          title=title,
                          run_next=f)
Ejemplo n.º 17
0
def seed_warning_msg(seed):
    return ''.join([
        "<p>",
        _("Please save these {0} words on paper (order is important). "),
        _("This seed will allow you to recover your wallet in case "
          "of computer failure."), "</p>", "<b>" + _("WARNING") + ":</b>",
        "<ul>", "<li>" + _("Never disclose your seed.") + "</li>",
        "<li>" + _("Never type it on a website.") + "</li>",
        "<li>" + _("Do not store it electronically.") + "</li>", "</ul>"
    ]).format(len(seed.split()))
Ejemplo n.º 18
0
    def callback_WordRequest(self, msg):
        if (msg.type is not None
            and msg.type in (self.types.WordRequestType.Matrix9,
                             self.types.WordRequestType.Matrix6)):
            num = 9 if msg.type == self.types.WordRequestType.Matrix9 else 6
            char = self.handler.get_matrix(num)
            if char == 'x':
                return self.proto.Cancel()
            return self.proto.WordAck(word=char)

        self.step += 1
        msg = _("Step {}/24.  Enter seed word as explained on "
                "your {}:").format(self.step, self.device)
        word = self.handler.get_word(msg)
        # Unfortunately the device can't handle self.proto.Cancel()
        return self.proto.WordAck(word=word)
Ejemplo n.º 19
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
     tx = self.wallet.transactions.get(tx_hash)
     if not tx:
         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 = self.wallet.get_tx_height(tx_hash).height
     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 {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data))
     for c in self.editable_columns:
         menu.addAction(_("Edit {}").format(self.headerItem().text(c)),
                        lambda bound_c=c: self.editItem(item, bound_c))
     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: webbrowser.open(tx_URL))
     menu.exec_(self.viewport().mapToGlobal(position))
Ejemplo n.º 20
0
 def get_xpub(self, bip32_path, xtype):
     assert xtype in ColdcardPlugin.SUPPORTED_XTYPES
     print_error('[coldcard]', 'Derive xtype = %r' % xtype)
     xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path),
                               timeout=5000)
     # TODO handle timeout?
     # change type of xpub to the requested type
     try:
         node = BIP32Node.from_xkey(xpub)
     except InvalidMasterKeyVersionBytes:
         raise UserFacingException(
             _('Invalid xpub magic. Make sure your {} device is set to the correct chain.'
               ).format(self.device)) from None
     if xtype != 'standard':
         xpub = node._replace(xtype=xtype).to_xpub()
     return xpub
Ejemplo n.º 21
0
def address_field(addresses):
    hbox = QHBoxLayout()
    address_e = QLineEdit()
    if addresses:
        address_e.setText(addresses[0])

    def func():
        i = addresses.index(str(address_e.text())) + 1
        i = i % len(addresses)
        address_e.setText(addresses[i])

    button = QPushButton(_('Address'))
    button.clicked.connect(func)
    hbox.addWidget(button)
    hbox.addWidget(address_e)
    return hbox, address_e
Ejemplo n.º 22
0
    def transaction_dialog(self, dia):
        # see gui/qt/transaction_dialog.py

        keystore = dia.wallet.get_keystore()
        if type(keystore) != self.keystore_class:
            # not a Coldcard wallet, hide feature
            return

        # - add a new button, near "export"
        btn = QPushButton(_("Save PSBT"))
        btn.clicked.connect(lambda unused: self.export_psbt(dia))
        if dia.tx.is_complete():
            # but disable it for signed transactions (nothing to do if already signed)
            btn.setDisabled(True)

        dia.sharing_buttons.append(btn)
Ejemplo n.º 23
0
    def _initialize_device(self, settings, method, device_id, wizard, handler):
        item, label, pin_protection, passphrase_protection, recovery_type = settings

        if method == TIM_RECOVER and recovery_type == RECOVERY_TYPE_SCRAMBLED_WORDS:
            handler.show_error(_(
                "You will be asked to enter 24 words regardless of your "
                "seed's actual length.  If you enter a word incorrectly or "
                "misspell it, you cannot change it or go back - you will need "
                "to start again from the beginning.\n\nSo please enter "
                "the words carefully!"),
                               blocking=True)

        language = 'english'
        devmgr = self.device_manager()
        client = devmgr.client_by_id(device_id)

        if method == TIM_NEW:
            strength = 64 * (item + 2)  # 128, 192 or 256
            u2f_counter = 0
            skip_backup = False
            client.reset_device(True, strength, passphrase_protection,
                                pin_protection, label, language, u2f_counter,
                                skip_backup)
        elif method == TIM_RECOVER:
            word_count = 6 * (item + 2)  # 12, 18 or 24
            client.step = 0
            if recovery_type == RECOVERY_TYPE_SCRAMBLED_WORDS:
                recovery_type_trezor = self.types.RecoveryDeviceType.ScrambledWords
            else:
                recovery_type_trezor = self.types.RecoveryDeviceType.Matrix
            client.recovery_device(word_count,
                                   passphrase_protection,
                                   pin_protection,
                                   label,
                                   language,
                                   type=recovery_type_trezor)
            if recovery_type == RECOVERY_TYPE_MATRIX:
                handler.close_matrix_dialog()
        elif method == TIM_MNEMONIC:
            pin = pin_protection  # It's the pin, not a boolean
            client.load_device_by_mnemonic(str(item), pin,
                                           passphrase_protection, label,
                                           language)
        else:
            pin = pin_protection  # It's the pin, not a boolean
            client.load_device_by_xprv(item, pin, passphrase_protection, label,
                                       language)
Ejemplo n.º 24
0
    def show_settings_dialog(self, window, success):
        if not success:
            window.show_message(_('Server not reachable.'))
            return

        wallet = window.wallet
        d = WindowModalDialog(window, _("TrustedCoin Information"))
        d.setMinimumSize(500, 200)
        vbox = QVBoxLayout(d)
        hbox = QHBoxLayout()

        logo = QLabel()
        logo.setPixmap(QPixmap(":icons/trustedcoin-status.png"))
        msg = _('This wallet is protected by TrustedCoin\'s two-factor authentication.') + '<br/>'\
              + _("For more information, visit") + " <a href=\"https://api.trustedcoin.com/#/electrum-help\">https://api.trustedcoin.com/#/electrum-help</a>"
        label = QLabel(msg)
        label.setOpenExternalLinks(1)

        hbox.addStretch(10)
        hbox.addWidget(logo)
        hbox.addStretch(10)
        hbox.addWidget(label)
        hbox.addStretch(10)

        vbox.addLayout(hbox)
        vbox.addStretch(10)

        msg = _('TrustedCoin charges a small fee to co-sign transactions. The fee depends on how many prepaid transactions you buy. An extra output is added to your transaction every time you run out of prepaid transactions.') + '<br/>'
        label = QLabel(msg)
        label.setWordWrap(1)
        vbox.addWidget(label)

        vbox.addStretch(10)
        grid = QGridLayout()
        vbox.addLayout(grid)

        price_per_tx = wallet.price_per_tx
        n_prepay = wallet.num_prepay(self.config)
        i = 0
        for k, v in sorted(price_per_tx.items()):
            if k == 1:
                continue
            grid.addWidget(QLabel("Pay every %d transactions:"%k), i, 0)
            grid.addWidget(QLabel(window.format_amount(v/k) + ' ' + window.base_unit() + "/tx"), i, 1)
            b = QRadioButton()
            b.setChecked(k == n_prepay)
            b.clicked.connect(lambda b, k=k: self.config.set_key('trustedcoin_prepay', k, True))
            grid.addWidget(b, i, 2)
            i += 1

        n = wallet.billing_info.get('tx_remaining', 0)
        grid.addWidget(QLabel(_("Your wallet has {} prepaid transactions.").format(n)), i, 0)
        vbox.addLayout(Buttons(CloseButton(d)))
        d.exec_()
Ejemplo n.º 25
0
 def __init__(self, parent=None):
     MyTreeWidget.__init__(self, parent, self.create_menu, [], 2)
     self.refresh_headers()
     self.setSelectionMode(QAbstractItemView.ExtendedSelection)
     self.setSortingEnabled(True)
     self.show_change = 0
     self.show_used = 0
     self.change_button = QComboBox(self)
     self.change_button.currentIndexChanged.connect(self.toggle_change)
     for t in [_('All'), _('Receiving'), _('Change')]:
         self.change_button.addItem(t)
     self.used_button = QComboBox(self)
     self.used_button.currentIndexChanged.connect(self.toggle_used)
     for t in [_('All'), _('Unused'), _('Funded'), _('Used')]:
         self.used_button.addItem(t)
Ejemplo n.º 26
0
 def refresh_headers(self):
     fx = self.parent.fx
     if fx and fx.get_fiat_address_config():
         ccy = fx.get_currency()
     else:
         ccy = _('Fiat')
     headers = {
         self.Columns.TYPE: _('Type'),
         self.Columns.ADDRESS: _('Address'),
         self.Columns.LABEL: _('Label'),
         self.Columns.COIN_BALANCE: _('Balance'),
         self.Columns.FIAT_BALANCE: ccy + ' ' + _('Balance'),
         self.Columns.NUM_TXS: _('Tx'),
     }
     self.update_headers(headers)
Ejemplo n.º 27
0
 def change_homescreen():
     from PIL import Image  # FIXME
     dialog = QFileDialog(self, _("Choose Homescreen"))
     filename, __ = dialog.getOpenFileName()
     if filename:
         im = Image.open(str(filename))
         if im.size != (hs_cols, hs_rows):
             raise Exception('Image must be 64 x 128 pixels')
         im = im.convert('1')
         pix = im.load()
         img = ''
         for j in range(hs_rows):
             for i in range(hs_cols):
                 img += '1' if pix[i, j] else '0'
         img = ''.join(
             chr(int(img[i:i + 8], 2)) for i in range(0, len(img), 8))
         invoke_client('change_homescreen', img)
Ejemplo n.º 28
0
    def on_update(self):
        self.wallet = self.parent.wallet
        self.network = self.parent.network
        item = self.currentItem()
        self.clear()
        self.utxos = self.wallet.get_utxos()
        for x in self.utxos:
            txid = x['prevout_hash']
            vout = x['prevout_n']
            name_op = self.wallet.transactions[txid].outputs()[vout].name_op
            if name_op is None:
                continue

            # TODO: Support name_new
            if 'name' in name_op:
                name = name_op['name']
                formatted_name = format_name_identifier(name)
                value = name_op['value']
                formatted_value = format_name_value(value)
            else:
                name = None
                formatted_name = ''
                value = None
                formatted_value = ''

            height = x.get('height')
            chain_height = self.network.blockchain().height()
            expires_in = name_expires_in(height, chain_height)
            formatted_expires_in = '%d' % expires_in if expires_in is not None else ''

            status = '' if expires_in is not None else _('Update Pending')

            utxo_item = SortableTreeWidgetItem([
                formatted_name, formatted_value, formatted_expires_in, status
            ])
            utxo_item.setFont(0, QFont(MONOSPACE_FONT))
            utxo_item.setFont(1, QFont(MONOSPACE_FONT))

            utxo_item.setData(0, Qt.UserRole, self.get_name(x))
            utxo_item.setData(0, Qt.UserRole + USER_ROLE_NAME, name)
            utxo_item.setData(0, Qt.UserRole + USER_ROLE_VALUE, value)

            address = x.get('address')
            if self.wallet.is_frozen(address):
                utxo_item.setBackground(0, ColorScheme.BLUE.as_color(True))
            self.addChild(utxo_item)
Ejemplo n.º 29
0
    def __init__(self, main_window, exctype, value, tb):
        BaseCrashReporter.__init__(self, exctype, value, tb)
        self.main_window = main_window

        QWidget.__init__(self)
        self.setWindowTitle('Electrum-NMC - ' + _('An Error Occurred'))
        self.setMinimumSize(600, 300)

        main_box = QVBoxLayout()

        heading = QLabel('<h2>' + BaseCrashReporter.CRASH_TITLE + '</h2>')
        main_box.addWidget(heading)
        main_box.addWidget(QLabel(BaseCrashReporter.CRASH_MESSAGE))

        main_box.addWidget(QLabel(BaseCrashReporter.REQUEST_HELP_MESSAGE))

        collapse_info = QPushButton(_("Show report contents"))
        collapse_info.clicked.connect(
            lambda: self.msg_box(QMessageBox.NoIcon,
                                 self,
                                 _("Report contents"),
                                 self.get_report_string(),
                                 rich_text=True))

        main_box.addWidget(collapse_info)

        main_box.addWidget(QLabel(BaseCrashReporter.DESCRIBE_ERROR_MESSAGE))

        self.description_textfield = QTextEdit()
        self.description_textfield.setFixedHeight(50)
        main_box.addWidget(self.description_textfield)

        main_box.addWidget(QLabel(BaseCrashReporter.ASK_CONFIRM_SEND))

        buttons = QHBoxLayout()

        report_button = QPushButton(_('Send Bug Report'))
        report_button.clicked.connect(self.send_report)
        report_button.setIcon(read_QIcon("tab_send.png"))
        buttons.addWidget(report_button)

        never_button = QPushButton(_('Never'))
        never_button.clicked.connect(self.show_never)
        buttons.addWidget(never_button)

        close_button = QPushButton(_('Not Now'))
        close_button.clicked.connect(self.close)
        buttons.addWidget(close_button)

        main_box.addLayout(buttons)

        self.setLayout(main_box)
        self.show()
Ejemplo n.º 30
0
    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)

        vbox.addWidget(QLabel(_("Address:")))
        self.addr_e = ButtonsLineEdit(self.address)
        self.addr_e.addCopyButton(self.app)
        icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png"
        self.addr_e.addButton(icon, self.show_qr, _("Show QR Code"))
        self.addr_e.setReadOnly(True)
        vbox.addWidget(self.addr_e)

        try:
            pubkeys = self.wallet.get_public_keys(address)
        except BaseException as e:
            pubkeys = None
        if pubkeys:
            vbox.addWidget(QLabel(_("Public keys") + ':'))
            for pubkey in pubkeys:
                pubkey_e = ButtonsLineEdit(pubkey)
                pubkey_e.addCopyButton(self.app)
                pubkey_e.setReadOnly(True)
                vbox.addWidget(pubkey_e)

        try:
            redeem_script = self.wallet.pubkeys_to_redeem_script(pubkeys)
        except BaseException as e:
            redeem_script = None
        if redeem_script:
            vbox.addWidget(QLabel(_("Redeem Script") + ':'))
            redeem_e = ShowQRTextEdit(text=redeem_script)
            redeem_e.addCopyButton(self.app)
            vbox.addWidget(redeem_e)

        vbox.addWidget(QLabel(_("History")))
        addr_hist_model = AddressHistoryModel(self.parent, self.address)
        self.hw = HistoryList(self.parent, addr_hist_model)
        addr_hist_model.set_view(self.hw)
        vbox.addWidget(self.hw)

        vbox.addLayout(Buttons(CloseButton(self)))
        self.format_amount = self.parent.format_amount
        addr_hist_model.refresh('address dialog constructor')