hardware wallets: create base class for HW Clients. add some type hints
This commit is contained in:
@@ -28,7 +28,8 @@ import importlib.util
|
||||
import time
|
||||
import threading
|
||||
import sys
|
||||
from typing import NamedTuple, Any, Union, TYPE_CHECKING, Optional
|
||||
from typing import (NamedTuple, Any, Union, TYPE_CHECKING, Optional, Tuple,
|
||||
Dict, Iterable, List)
|
||||
|
||||
from .i18n import _
|
||||
from .util import (profiler, DaemonThread, UserCancelled, ThreadJob, UserFacingException)
|
||||
@@ -38,7 +39,7 @@ from .simple_config import SimpleConfig
|
||||
from .logging import get_logger, Logger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .plugins.hw_wallet import HW_PluginBase
|
||||
from .plugins.hw_wallet import HW_PluginBase, HardwareClientBase
|
||||
from .keystore import Hardware_KeyStore
|
||||
|
||||
|
||||
@@ -234,7 +235,7 @@ def run_hook(name, *args):
|
||||
class BasePlugin(Logger):
|
||||
|
||||
def __init__(self, parent, config, name):
|
||||
self.parent = parent # The plugins object
|
||||
self.parent = parent # type: Plugins # The plugins object
|
||||
self.name = name
|
||||
self.config = config
|
||||
self.wallet = None
|
||||
@@ -351,7 +352,7 @@ class DeviceMgr(ThreadJob):
|
||||
self.xpub_ids = {}
|
||||
# A list of clients. The key is the client, the value is
|
||||
# a (path, id_) pair.
|
||||
self.clients = {}
|
||||
self.clients = {} # type: Dict[HardwareClientBase, Tuple[Union[str, bytes], str]]
|
||||
# What we recognise. Each entry is a (vendor_id, product_id)
|
||||
# pair.
|
||||
self.recognised_hardware = set()
|
||||
@@ -382,7 +383,7 @@ class DeviceMgr(ThreadJob):
|
||||
def register_enumerate_func(self, func):
|
||||
self.enumerate_func.add(func)
|
||||
|
||||
def create_client(self, device, handler, plugin):
|
||||
def create_client(self, device: 'Device', handler, plugin: 'HW_PluginBase') -> Optional['HardwareClientBase']:
|
||||
# Get from cache first
|
||||
client = self.client_lookup(device.id_)
|
||||
if client:
|
||||
@@ -429,21 +430,22 @@ class DeviceMgr(ThreadJob):
|
||||
with self.lock:
|
||||
self.xpub_ids[xpub] = id_
|
||||
|
||||
def client_lookup(self, id_):
|
||||
def client_lookup(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_):
|
||||
def client_by_id(self, id_) -> 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_)
|
||||
|
||||
def client_for_keystore(self, plugin, handler, keystore: 'Hardware_KeyStore', force_pair):
|
||||
def client_for_keystore(self, plugin: 'HW_PluginBase', handler, keystore: 'Hardware_KeyStore',
|
||||
force_pair: bool) -> Optional['HardwareClientBase']:
|
||||
self.logger.info("getting client for keystore")
|
||||
if handler is None:
|
||||
raise Exception(_("Handler not found for") + ' ' + plugin.name + '\n' + _("A library is probably missing."))
|
||||
@@ -455,7 +457,7 @@ class DeviceMgr(ThreadJob):
|
||||
client = self.client_by_xpub(plugin, xpub, handler, devices)
|
||||
if client is None and force_pair:
|
||||
info = self.select_device(plugin, handler, keystore, devices)
|
||||
client = self.force_pair_xpub(plugin, handler, info, xpub, derivation, devices)
|
||||
client = self.force_pair_xpub(plugin, handler, info, xpub, derivation)
|
||||
if client:
|
||||
handler.update_status(True)
|
||||
if client:
|
||||
@@ -463,7 +465,8 @@ class DeviceMgr(ThreadJob):
|
||||
self.logger.info("end client for keystore")
|
||||
return client
|
||||
|
||||
def client_by_xpub(self, plugin, xpub, handler, devices):
|
||||
def client_by_xpub(self, plugin: 'HW_PluginBase', xpub, handler,
|
||||
devices: Iterable['Device']) -> Optional['HardwareClientBase']:
|
||||
_id = self.xpub_id(xpub)
|
||||
client = self.client_lookup(_id)
|
||||
if client:
|
||||
@@ -476,8 +479,8 @@ class DeviceMgr(ThreadJob):
|
||||
if device.id_ == _id:
|
||||
return self.create_client(device, handler, plugin)
|
||||
|
||||
|
||||
def force_pair_xpub(self, plugin, handler, info, xpub, derivation, devices):
|
||||
def force_pair_xpub(self, plugin: 'HW_PluginBase', handler,
|
||||
info: 'DeviceInfo', xpub, derivation) -> Optional['HardwareClientBase']:
|
||||
# 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)
|
||||
@@ -533,7 +536,8 @@ class DeviceMgr(ThreadJob):
|
||||
|
||||
return infos
|
||||
|
||||
def select_device(self, plugin, handler, keystore, devices=None):
|
||||
def select_device(self, plugin: 'HW_PluginBase', handler,
|
||||
keystore: 'Hardware_KeyStore', devices=None) -> 'DeviceInfo':
|
||||
'''Ask the user to select a device to use if there is more than one,
|
||||
and return the DeviceInfo for the device.'''
|
||||
while True:
|
||||
@@ -569,7 +573,7 @@ class DeviceMgr(ThreadJob):
|
||||
handler.win.wallet.save_keystore()
|
||||
return info
|
||||
|
||||
def _scan_devices_with_hid(self):
|
||||
def _scan_devices_with_hid(self) -> List['Device']:
|
||||
try:
|
||||
import hid
|
||||
except ImportError:
|
||||
@@ -597,7 +601,7 @@ class DeviceMgr(ThreadJob):
|
||||
transport_ui_string='hid'))
|
||||
return devices
|
||||
|
||||
def scan_devices(self):
|
||||
def scan_devices(self) -> List['Device']:
|
||||
self.logger.info("scanning devices...")
|
||||
|
||||
# First see what's connected that we know about
|
||||
|
||||
Reference in New Issue
Block a user