mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-31 17:31:36 +00:00
wizard hww: scan devices fewer times and move away from GUI thread
This commit is contained in:
parent
01dac92e19
commit
4b1d835304
9 changed files with 22 additions and 14 deletions
|
@ -348,7 +348,7 @@ class BaseWizard(Logger):
|
|||
assert isinstance(self.plugin, HW_PluginBase)
|
||||
devmgr = self.plugins.device_manager
|
||||
try:
|
||||
self.plugin.setup_device(device_info, self, purpose)
|
||||
client = self.plugin.setup_device(device_info, self, purpose)
|
||||
except OSError as e:
|
||||
self.show_error(_('We encountered an error while connecting to your device:')
|
||||
+ '\n' + str(e) + '\n'
|
||||
|
@ -376,19 +376,18 @@ class BaseWizard(Logger):
|
|||
self.show_error(str(e))
|
||||
self.choose_hw_device(purpose, storage=storage)
|
||||
return
|
||||
|
||||
if purpose == HWD_SETUP_NEW_WALLET:
|
||||
def f(derivation, script_type):
|
||||
derivation = normalize_bip32_derivation(derivation)
|
||||
self.run('on_hw_derivation', name, device_info, derivation, script_type)
|
||||
self.derivation_and_script_type_dialog(f)
|
||||
elif purpose == HWD_SETUP_DECRYPT_WALLET:
|
||||
client = devmgr.client_by_id(device_info.device.id_)
|
||||
password = client.get_password_for_storage_encryption()
|
||||
try:
|
||||
storage.decrypt(password)
|
||||
except InvalidPassword:
|
||||
# try to clear session so that user can type another passphrase
|
||||
client = devmgr.client_by_id(device_info.device.id_)
|
||||
if hasattr(client, 'clear_session'): # FIXME not all hw wallet plugins have this
|
||||
client.clear_session()
|
||||
raise
|
||||
|
@ -435,7 +434,7 @@ class BaseWizard(Logger):
|
|||
assert isinstance(self.plugin, HW_PluginBase)
|
||||
try:
|
||||
xpub = self.plugin.get_xpub(device_info.device.id_, derivation, xtype, self)
|
||||
client = devmgr.client_by_id(device_info.device.id_)
|
||||
client = devmgr.client_by_id(device_info.device.id_, scan_now=False)
|
||||
if not client: raise Exception("failed to find client for device id")
|
||||
root_fingerprint = client.request_root_fingerprint_from_device()
|
||||
label = client.label() # use this as device_info.label might be outdated!
|
||||
|
|
|
@ -401,7 +401,7 @@ class DeviceMgr(ThreadJob):
|
|||
def create_client(self, device: 'Device', handler: Optional['HardwareHandlerBase'],
|
||||
plugin: 'HW_PluginBase') -> Optional['HardwareClientBase']:
|
||||
# Get from cache first
|
||||
client = self.client_lookup(device.id_)
|
||||
client = self._client_by_id(device.id_)
|
||||
if client:
|
||||
return client
|
||||
client = plugin.create_client(device, handler)
|
||||
|
@ -437,7 +437,7 @@ class DeviceMgr(ThreadJob):
|
|||
self._close_client(id_)
|
||||
|
||||
def _close_client(self, id_):
|
||||
client = self.client_lookup(id_)
|
||||
client = self._client_by_id(id_)
|
||||
self.clients.pop(client, None)
|
||||
if client:
|
||||
client.close()
|
||||
|
@ -446,19 +446,20 @@ class DeviceMgr(ThreadJob):
|
|||
with self.lock:
|
||||
self.xpub_ids[xpub] = id_
|
||||
|
||||
def client_lookup(self, id_) -> Optional['HardwareClientBase']:
|
||||
def _client_by_id(self, id_) -> Optional['HardwareClientBase']:
|
||||
with self.lock:
|
||||
for client, (path, client_id) in self.clients.items():
|
||||
if client_id == id_:
|
||||
return client
|
||||
return None
|
||||
|
||||
def client_by_id(self, id_) -> Optional['HardwareClientBase']:
|
||||
def client_by_id(self, id_, *, scan_now: bool = True) -> Optional['HardwareClientBase']:
|
||||
'''Returns a client for the device ID if one is registered. If
|
||||
a device is wiped or in bootloader mode pairing is impossible;
|
||||
in such cases we communicate by device ID and not wallet.'''
|
||||
self.scan_devices()
|
||||
return self.client_lookup(id_)
|
||||
if scan_now:
|
||||
self.scan_devices()
|
||||
return self._client_by_id(id_)
|
||||
|
||||
@with_scan_lock
|
||||
def client_for_keystore(self, plugin: 'HW_PluginBase', handler: Optional['HardwareHandlerBase'],
|
||||
|
@ -495,7 +496,7 @@ class DeviceMgr(ThreadJob):
|
|||
def client_by_xpub(self, plugin: 'HW_PluginBase', xpub, handler: 'HardwareHandlerBase',
|
||||
devices: Sequence['Device']) -> Optional['HardwareClientBase']:
|
||||
_id = self.xpub_id(xpub)
|
||||
client = self.client_lookup(_id)
|
||||
client = self._client_by_id(_id)
|
||||
if client:
|
||||
# An unpaired client might have another wallet's handler
|
||||
# from a prior scan. Replace to fix dialog parenting.
|
||||
|
@ -511,7 +512,7 @@ class DeviceMgr(ThreadJob):
|
|||
# The wallet has not been previously paired, so let the user
|
||||
# choose an unpaired device and compare its first address.
|
||||
xtype = bip32.xpub_type(xpub)
|
||||
client = self.client_lookup(info.device.id_)
|
||||
client = self._client_by_id(info.device.id_)
|
||||
if client and client.is_pairable():
|
||||
# See comment above for same code
|
||||
client.handler = handler
|
||||
|
|
|
@ -524,6 +524,7 @@ class ColdcardPlugin(HW_PluginBase):
|
|||
def setup_device(self, device_info, wizard, purpose):
|
||||
device_id = device_info.device.id_
|
||||
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
|
||||
return client
|
||||
|
||||
def get_xpub(self, device_id, derivation, xtype, wizard):
|
||||
# this seems to be part of the pairing process only, not during normal ops?
|
||||
|
|
|
@ -705,6 +705,7 @@ class DigitalBitboxPlugin(HW_PluginBase):
|
|||
client.setupRunning = True
|
||||
wizard.run_task_without_blocking_gui(
|
||||
task=lambda: client.get_xpub("m/44'/0'", 'standard'))
|
||||
return client
|
||||
|
||||
|
||||
def is_mobile_paired(self):
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
# SOFTWARE.
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, List, Union, Tuple, Sequence, Optional, Type
|
||||
from functools import partial
|
||||
|
||||
from electrum.plugin import BasePlugin, hook, Device, DeviceMgr, DeviceInfo
|
||||
from electrum.i18n import _
|
||||
|
@ -67,14 +68,15 @@ class HW_PluginBase(BasePlugin):
|
|||
|
||||
def scan_and_create_client_for_device(self, *, device_id: str, wizard: 'BaseWizard') -> 'HardwareClientBase':
|
||||
devmgr = self.device_manager()
|
||||
client = devmgr.client_by_id(device_id)
|
||||
client = wizard.run_task_without_blocking_gui(
|
||||
task=partial(devmgr.client_by_id, device_id))
|
||||
if client is None:
|
||||
raise UserFacingException(_('Failed to create a client for this device.') + '\n' +
|
||||
_('Make sure it is in the correct state.'))
|
||||
client.handler = self.create_handler(wizard)
|
||||
return client
|
||||
|
||||
def setup_device(self, device_info: DeviceInfo, wizard: 'BaseWizard', purpose):
|
||||
def setup_device(self, device_info: DeviceInfo, wizard: 'BaseWizard', purpose) -> 'HardwareClientBase':
|
||||
"""Called when creating a new wallet or when using the device to decrypt
|
||||
an existing wallet. Select the device to use. If the device is
|
||||
uninitialized, go through the initialization process.
|
||||
|
|
|
@ -283,6 +283,7 @@ class KeepKeyPlugin(HW_PluginBase):
|
|||
wizard.run_task_without_blocking_gui(
|
||||
task=lambda: client.get_xpub("m", 'standard'))
|
||||
client.used()
|
||||
return client
|
||||
|
||||
def get_xpub(self, device_id, derivation, xtype, wizard):
|
||||
if xtype not in self.SUPPORTED_XTYPES:
|
||||
|
|
|
@ -610,6 +610,7 @@ class LedgerPlugin(HW_PluginBase):
|
|||
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
|
||||
wizard.run_task_without_blocking_gui(
|
||||
task=lambda: client.get_xpub("m/44'/0'", 'standard')) # TODO replace by direct derivation once Nano S > 1.1
|
||||
return client
|
||||
|
||||
def get_xpub(self, device_id, derivation, xtype, wizard):
|
||||
if xtype not in self.SUPPORTED_XTYPES:
|
||||
|
|
|
@ -257,6 +257,7 @@ class SafeTPlugin(HW_PluginBase):
|
|||
wizard.run_task_without_blocking_gui(
|
||||
task=lambda: client.get_xpub("m", 'standard'))
|
||||
client.used()
|
||||
return client
|
||||
|
||||
def get_xpub(self, device_id, derivation, xtype, wizard):
|
||||
if xtype not in self.SUPPORTED_XTYPES:
|
||||
|
|
|
@ -288,6 +288,7 @@ class TrezorPlugin(HW_PluginBase):
|
|||
wizard.run_task_without_blocking_gui(
|
||||
task=lambda: client.get_xpub('m', 'standard', creating=is_creating_wallet))
|
||||
client.used()
|
||||
return client
|
||||
|
||||
def get_xpub(self, device_id, derivation, xtype, wizard):
|
||||
if xtype not in self.SUPPORTED_XTYPES:
|
||||
|
|
Loading…
Add table
Reference in a new issue