Browse Source

qt: jade for new wizard

master
Sander van Grieken 2 years ago
parent
commit
b2a41b6363
  1. 20
      electrum/plugins/jade/jade.py
  2. 108
      electrum/plugins/jade/qt.py
  3. 6
      electrum/plugins/trezor/qt.py

20
electrum/plugins/jade/jade.py

@ -476,3 +476,23 @@ class JadePlugin(HW_PluginBase):
if hw_address != address: if hw_address != address:
keystore.handler.show_error(_('The address generated by {} does not match!').format(self.device)) keystore.handler.show_error(_('The address generated by {} does not match!').format(self.device))
# new wizard
def wizard_entry_for_device(self, device_info: 'DeviceInfo') -> str:
return 'jade_start' if device_info.initialized else 'jade_not_initialized'
# insert trezor pages in new wallet wizard
def extend_wizard(self, wizard: 'NewWalletWizard'):
views = {
'jade_start': {
'next': 'jade_xpub',
},
'jade_xpub': {
'next': lambda d: wizard.wallet_password_view(d) if wizard.last_cosigner(d) else 'multisig_cosigner_keystore',
'accept': wizard.maybe_master_pubkey,
'last': lambda d: wizard.is_single_password() and wizard.last_cosigner(d)
},
'jade_not_initialized': {}
}
wizard.navmap_merge(views)

108
electrum/plugins/jade/qt.py

@ -1,16 +1,20 @@
import threading
from functools import partial from functools import partial
from PyQt5.QtCore import pyqtSignal from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtWidgets import QLabel, QVBoxLayout
from electrum.i18n import _ from electrum.i18n import _
from electrum.plugin import hook from electrum.plugin import hook
from electrum.wallet import Standard_Wallet from electrum.wallet import Standard_Wallet
from electrum.gui.qt.util import WindowModalDialog from electrum.logging import Logger
from electrum.plugins.hw_wallet.qt import QtHandlerBase, QtPluginBase
from electrum.plugins.hw_wallet import plugin
from electrum.gui.qt.util import WWLabel
from electrum.gui.qt.wizard.wallet import WCScriptAndDerivation
from electrum.gui.qt.wizard.wizard import WizardComponent
from .jade import JadePlugin from .jade import JadePlugin
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
from ..hw_wallet.plugin import only_hook_if_libraries_available
class Plugin(JadePlugin, QtPluginBase): class Plugin(JadePlugin, QtPluginBase):
@ -20,7 +24,7 @@ class Plugin(JadePlugin, QtPluginBase):
def create_handler(self, window): def create_handler(self, window):
return Jade_Handler(window) return Jade_Handler(window)
@only_hook_if_libraries_available @plugin.only_hook_if_libraries_available
@hook @hook
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
if type(wallet) is not Standard_Wallet: if type(wallet) is not Standard_Wallet:
@ -31,6 +35,21 @@ class Plugin(JadePlugin, QtPluginBase):
keystore.thread.add(partial(self.show_address, wallet, addrs[0])) keystore.thread.add(partial(self.show_address, wallet, addrs[0]))
menu.addAction(_("Show on Jade"), show_address) menu.addAction(_("Show on Jade"), show_address)
@hook
def init_wallet_wizard(self, wizard: 'QEWalletWizard'):
self.extend_wizard(wizard)
# insert trezor pages in new wallet wizard
def extend_wizard(self, wizard: 'NewWalletWizard'):
super().extend_wizard(wizard)
views = {
'jade_start': { 'gui': WCScriptAndDerivation },
'jade_xpub': { 'gui': WCJadeXPub },
'jade_not_initialized': {'gui': WCJadeNope},
}
wizard.navmap_merge(views)
class Jade_Handler(QtHandlerBase): class Jade_Handler(QtHandlerBase):
setup_signal = pyqtSignal() setup_signal = pyqtSignal()
auth_signal = pyqtSignal(object, object) auth_signal = pyqtSignal(object, object)
@ -39,3 +58,80 @@ class Jade_Handler(QtHandlerBase):
def __init__(self, win): def __init__(self, win):
super(Jade_Handler, self).__init__(win, 'Jade') super(Jade_Handler, self).__init__(win, 'Jade')
class WCJadeXPub(WizardComponent, Logger): # TODO: almost verbatim copy of trezor WCTrezorXPub, generalize!
def __init__(self, parent, wizard):
WizardComponent.__init__(self, parent, wizard, title=_('Hardware wallet information'))
Logger.__init__(self)
self.plugins = wizard.plugins
self.plugin = self.plugins.get_plugin('jade')
self.busy_msg = _('Unlock your Jade')
self._busy = True
self.xpub = None
self.root_fingerprint = None
self.label = None
self.soft_device_id = None
self.ok_l = WWLabel(_('Hardware keystore added to wallet'))
self.ok_l.setAlignment(Qt.AlignCenter)
self.layout().addWidget(self.ok_l)
def on_ready(self):
_name, _info = self.wizard_data['hardware_device']
device_id = _info.device.id_
client = self.plugins.device_manager.client_by_id(device_id, scan_now=False)
if not client.handler:
client.handler = self.plugin.create_handler(self.wizard)
cosigner = self.wizard.current_cosigner(self.wizard_data)
xtype = cosigner['script_type']
derivation = cosigner['derivation_path']
def get_xpub_task(client, derivation, xtype):
try:
self.xpub = client.get_xpub(derivation, xtype)
self.root_fingerprint = client.request_root_fingerprint_from_device()
self.label = client.label()
self.soft_device_id = client.get_soft_device_id()
except Exception as e:
# TODO: handle user interaction exceptions (e.g. invalid pin) more gracefully
self.error = repr(e)
self.logger.error(repr(e))
self.xpub_done()
t = threading.Thread(target=get_xpub_task, args=(client, derivation, xtype), daemon=True)
t.start()
def xpub_done(self):
self.logger.debug(f'Done retrieve xpub: {self.xpub}')
self.busy = False
self.validate()
def validate(self):
if self.xpub and not self.error:
self.apply()
valid, error = self.wizard.check_multisig_constraints(self.wizard_data)
if not valid:
self.error = '\n'.join([
_('Could not add hardware keystore to wallet'),
error
])
self.valid = valid
else:
self.valid = False
def apply(self):
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
cosigner_data['hw_type'] = 'jade'
cosigner_data['master_key'] = self.xpub
cosigner_data['root_fingerprint'] = self.root_fingerprint
cosigner_data['label'] = self.label
cosigner_data['soft_device_id'] = self.soft_device_id
class WCJadeNope(WizardComponent):
def __init__(self, parent, wizard):
WizardComponent.__init__(self, parent, wizard, title=_('Jade not initialized'))
self.layout().addWidget(WWLabel(_('This Jade is not initialized. Cannot continue')))

6
electrum/plugins/trezor/qt.py

@ -826,7 +826,7 @@ class WCTrezorXPub(WizardComponent, Logger):
def get_xpub_task(client, derivation, xtype): def get_xpub_task(client, derivation, xtype):
try: try:
self.xpub = client.get_xpub(derivation, xtype) self.xpub = client.get_xpub(derivation, xtype, True)
self.root_fingerprint = client.request_root_fingerprint_from_device() self.root_fingerprint = client.request_root_fingerprint_from_device()
self.label = client.label() self.label = client.label()
self.soft_device_id = client.get_soft_device_id() self.soft_device_id = client.get_soft_device_id()
@ -914,6 +914,9 @@ class WCTrezorInit(WizardComponent, Logger):
Logger.__init__(self) Logger.__init__(self)
self.plugins = wizard.plugins self.plugins = wizard.plugins
self.plugin = self.plugins.get_plugin('trezor') self.plugin = self.plugins.get_plugin('trezor')
self.layout().addWidget(WWLabel('Done'))
self._busy = True self._busy = True
def on_ready(self): def on_ready(self):
@ -937,7 +940,6 @@ class WCTrezorInit(WizardComponent, Logger):
def init_done(self): def init_done(self):
self.logger.info('Done initialize device') self.logger.info('Done initialize device')
self.busy = False self.busy = False
self.layout().addWidget(WWLabel('Done'))
def apply(self): def apply(self):
pass pass

Loading…
Cancel
Save