Ejemplo n.º 1
0
    def create_menu(self, position):
        from electrum_grlc.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))
Ejemplo n.º 2
0
 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_())
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 def dbb_load_backup(self, show_msg=True):
     backups = self.hid_send_encrypt(b'{"backup":"list"}')
     if 'error' in backups:
         raise UserFacingException(backups['error']['message'])
     f = self.handler.query_choice(_("Choose a backup file:"),
                                   backups['backup'])
     if f is None:
         return False  # user cancelled
     key = self.backup_password_dialog()
     if key is None:
         raise Exception('Canceled by user')
     key = self.stretch_key(key)
     if show_msg:
         self.handler.show_message(
             _("Loading backup...") + "\n\n" +
             _("To continue, touch the Digital Bitbox's light for 3 seconds."
               ) + "\n\n" +
             _("To cancel, briefly touch the light or wait for the timeout."
               ))
     msg = ('{"seed":{"source": "backup", "key": "%s", "filename": "%s"}}' %
            (key, backups['backup'][f])).encode('utf8')
     hid_reply = self.hid_send_encrypt(msg)
     self.handler.finished()
     if 'error' in hid_reply:
         raise UserFacingException(hid_reply['error']['message'])
     return True
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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()
Ejemplo n.º 8
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
     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
     if not self.is_mobile_paired():
         keystore.handler.show_error(
             _('This function is only available after pairing your {} with a mobile device.'
               ).format(self.device))
         return
     if wallet.get_txin_type(address) != 'p2pkh':
         keystore.handler.show_error(
             _('This function is only available for p2pkh keystores when using {}.'
               ).format(self.device))
         return
     change, index = wallet.get_address_index(address)
     keypath = '%s/%d/%d' % (keystore.get_derivation_prefix(), change,
                             index)
     xpub = self.get_client(keystore)._get_xpub(keypath)
     verify_request_payload = {
         "type": 'p2pkh',
         "echo": xpub['echo'],
     }
     self.comserver_post_notification(verify_request_payload)
Ejemplo n.º 9
0
 def show_address(self, sequence, txin_type):
     client = self.get_client()
     address_path = self.get_derivation_prefix()[2:] + "/%d/%d" % sequence
     self.handler.show_message(_("Showing address ..."))
     segwit = is_segwit_script_type(txin_type)
     segwitNative = txin_type == 'p2wpkh'
     try:
         client.getWalletPublicKey(address_path,
                                   showOnScreen=True,
                                   segwit=segwit,
                                   segwitNative=segwitNative)
     except BTChipException as e:
         if e.sw == 0x6985:  # cancelled by user
             pass
         elif e.sw == 0x6982:
             raise  # pin lock. decorator will catch it
         elif e.sw == 0x6b00:  # hw.1 raises this
             self.handler.show_error('{}\n{}\n{}'.format(
                 _('Error showing address') + ':', e,
                 _('Your device might not have support for this functionality.'
                   )))
         else:
             self.logger.exception('')
             self.handler.show_error(e)
     except BaseException as e:
         self.logger.exception('')
         self.handler.show_error(e)
     finally:
         self.handler.finished()
Ejemplo n.º 10
0
 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
Ejemplo n.º 11
0
 def update_can_send(self, lnworker: LNWallet):
     msg = _('Can send') + ' ' + self.parent.format_amount(lnworker.num_sats_can_send())\
           + ' ' + self.parent.base_unit() + '; '\
           + _('can receive') + ' ' + self.parent.format_amount(lnworker.num_sats_can_receive())\
           + ' ' + self.parent.base_unit()
     self.can_send_label.setText(msg)
     self.update_swap_button(lnworker)
Ejemplo n.º 12
0
 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.'))
Ejemplo n.º 13
0
 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)
Ejemplo n.º 14
0
    def make_model(
            self, htlcs: Sequence[HTLCWithStatus]) -> 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 htlc_with_status in htlcs:
                if htlc_with_status.status != keyname:
                    continue
                htlc = htlc_with_status.htlc
                it = self.make_htlc_item(htlc, htlc_with_status.direction)
                self.folders[keyname].appendRow(it)
                mapping[htlc.payment_hash] = num
                num += 1
            self.keyname_rows[keyname] = mapping
        return model
Ejemplo n.º 15
0
    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))
            cypherseed.save(self.get_path_to_revealer_file('.png'))
            self.bcrypt(self.c_dialog)
        return cypherseed
Ejemplo n.º 16
0
 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)
Ejemplo n.º 17
0
 def show_tx(self, link_text: str):
     funding_tx = self.wallet.db.get_transaction(
         self.chan.funding_outpoint.txid)
     if not funding_tx:
         self.show_error(_("Funding transaction not found."))
         return
     self.window.show_transaction(funding_tx,
                                  tx_desc=_('Funding Transaction'))
Ejemplo n.º 18
0
 def ui_text(self) -> str:
     return {
         self.ALL: _('All'),
         self.UNUSED: _('Unused'),
         self.FUNDED: _('Funded'),
         self.USED_AND_EMPTY: _('Used'),
         self.FUNDED_OR_UNUSED: _('Funded or Unused'),
     }[self]
Ejemplo n.º 19
0
 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)
Ejemplo n.º 20
0
 def export_channel_backup(self, channel_id):
     msg = ' '.join([
         _("Channel backups can be imported in another instance of the same wallet, by scanning this QR code."),
         _("Please note that channel backups cannot be used to restore your channels."),
         _("If you lose your wallet file, the only thing you can do with a backup is to request your channel to be closed, so that your funds will be sent on-chain."),
     ])
     data = self.lnworker.export_channel_backup(channel_id)
     self.main_window.show_qrcode(data, 'channel backup', help_text=msg,
                                  show_copy_text_btn=True)
Ejemplo n.º 21
0
 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)
Ejemplo n.º 22
0
 def on_failure(exc_info):
     e = exc_info[1]
     self.logger.error('There was a problem with the automatic reporting', exc_info=exc_info)
     self.show_critical(parent=self,
                        msg=(_('There was a problem with the automatic reporting:') + '<br/>' +
                             repr(e)[:120] + '<br/><br/>' +
                             _("Please report this issue manually") +
                             f' <a href="{constants.GIT_REPO_ISSUES_URL}">on GitHub</a>.'),
                        rich_text=True)
Ejemplo n.º 23
0
 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()
Ejemplo n.º 24
0
    def setup_dialog(self, window):
        self.wallet = window.parent().wallet
        self.update_wallet_name(self.wallet)
        self.user_input = False

        self.d = WindowModalDialog(window, "Setup Dialog")
        self.d.setMinimumWidth(500)
        self.d.setMinimumHeight(210)
        self.d.setMaximumHeight(320)
        self.d.setContentsMargins(11, 11, 1, 1)

        self.hbox = QHBoxLayout(self.d)
        vbox = QVBoxLayout()
        logo = QLabel()
        self.hbox.addWidget(logo)
        logo.setPixmap(QPixmap(icon_path('revealer.png')))
        logo.setAlignment(Qt.AlignLeft)
        self.hbox.addSpacing(16)
        vbox.addWidget(
            WWLabel("<b>" + _("Revealer Visual Cryptography Plugin") +
                    "</b><br><br>" +
                    _("To encrypt a secret, first create or load noise.") +
                    "<br/>"))
        vbox.addSpacing(7)
        bcreate = QPushButton(_("Create a new Revealer"))
        bcreate.setMaximumWidth(181)
        bcreate.setDefault(True)
        vbox.addWidget(bcreate, Qt.AlignCenter)
        self.load_noise = ScanQRTextEdit(config=self.config)
        self.load_noise.setTabChangesFocus(True)
        self.load_noise.textChanged.connect(self.on_edit)
        self.load_noise.setMaximumHeight(33)
        self.hbox.addLayout(vbox)
        vbox.addWidget(
            WWLabel(
                _("or type an existing revealer code below and click 'next':"))
        )
        vbox.addWidget(self.load_noise)
        vbox.addSpacing(3)
        self.next_button = QPushButton(_("Next"), self.d)
        self.next_button.setEnabled(False)
        vbox.addLayout(Buttons(self.next_button))
        self.next_button.clicked.connect(self.d.close)
        self.next_button.clicked.connect(
            partial(self.cypherseed_dialog, window))

        def mk_digital():
            try:
                self.make_digital(self.d)
            except Exception:
                self.logger.exception('')
            else:
                self.cypherseed_dialog(window)

        bcreate.clicked.connect(mk_digital)
        return bool(self.d.exec_())
Ejemplo n.º 25
0
 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)
Ejemplo n.º 26
0
 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 garlicoins in it!")
         if not self.question(
                 msg, title=title, icon=QMessageBox.Critical):
             return
     invoke_client('wipe_device', unpair_after=True)
Ejemplo n.º 27
0
 def __init__(self, text="", allow_multi=False, *, config: SimpleConfig):
     ButtonsTextEdit.__init__(self, text)
     Logger.__init__(self)
     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)
Ejemplo n.º 28
0
 def new_channel_with_warning(self):
     lnworker = self.parent.wallet.lnworker
     if not lnworker.channels and not lnworker.channel_backups:
         warning = _(messages.MSG_LIGHTNING_WARNING)
         answer = self.parent.question(
             _('Do you want to create your first channel?') + '\n\n' + warning)
         if answer:
             self.new_channel_dialog()
     else:
         self.new_channel_dialog()
Ejemplo n.º 29
0
 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
Ejemplo n.º 30
0
 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)