Browse Source

hww: factor out part of hid scan code to HW_PluginBase

so that bitbox02 can override it
hard-fail-on-bad-server-string
SomberNight 5 years ago
committed by TheCharlatan
parent
commit
e830ef309f
No known key found for this signature in database GPG Key ID: 9B79B45691DB4173
  1. 31
      electrum/plugin.py
  2. 9
      electrum/plugins/bitbox02/bitbox02.py
  3. 2
      electrum/plugins/coldcard/coldcard.py
  4. 2
      electrum/plugins/digitalbitbox/digitalbitbox.py
  5. 16
      electrum/plugins/hw_wallet/plugin.py
  6. 2
      electrum/plugins/keepkey/keepkey.py
  7. 2
      electrum/plugins/ledger/ledger.py

31
electrum/plugin.py

@ -360,9 +360,8 @@ class DeviceMgr(ThreadJob):
# A list of clients. The key is the client, the value is # A list of clients. The key is the client, the value is
# a (path, id_) pair. Needs self.lock. # a (path, id_) pair. Needs self.lock.
self.clients = {} # type: Dict[HardwareClientBase, Tuple[Union[str, bytes], str]] self.clients = {} # type: Dict[HardwareClientBase, Tuple[Union[str, bytes], str]]
# What we recognise. Each entry is a (vendor_id, product_id) # What we recognise. (vendor_id, product_id) -> Plugin
# pair. self._recognised_hardware = {} # type: Dict[Tuple[int, int], HW_PluginBase]
self.recognised_hardware = set()
# Custom enumerate functions for devices we don't know about. # Custom enumerate functions for devices we don't know about.
self._enumerate_func = set() # Needs self.lock. self._enumerate_func = set() # Needs self.lock.
# locks: if you need to take multiple ones, acquire them in the order they are defined here! # locks: if you need to take multiple ones, acquire them in the order they are defined here!
@ -390,9 +389,9 @@ class DeviceMgr(ThreadJob):
for client in clients: for client in clients:
client.timeout(cutoff) client.timeout(cutoff)
def register_devices(self, device_pairs): def register_devices(self, device_pairs, *, plugin: 'HW_PluginBase'):
for pair in device_pairs: for pair in device_pairs:
self.recognised_hardware.add(pair) self._recognised_hardware[pair] = plugin
def register_enumerate_func(self, func): def register_enumerate_func(self, func):
with self.lock: with self.lock:
@ -642,24 +641,10 @@ class DeviceMgr(ThreadJob):
devices = [] devices = []
for d in hid_list: for d in hid_list:
product_key = (d['vendor_id'], d['product_id']) product_key = (d['vendor_id'], d['product_id'])
if product_key in self.recognised_hardware: if product_key in self._recognised_hardware:
# Older versions of hid don't provide interface_number plugin = self._recognised_hardware[product_key]
interface_number = d.get('interface_number', -1) device = plugin.create_device_from_hid_enumeration(d, product_key=product_key)
usage_page = d['usage_page'] devices.append(device)
id_ = d['serial_number']
if len(id_) == 0:
id_ = str(d['path'])
id_ += str(interface_number) + str(usage_page)
# The BitBox02's product_id is not unique per device, thus use the path instead to
# distinguish devices.
if d["product_id"] == 0x2403:
id_ = d['path']
devices.append(Device(path=d['path'],
interface_number=interface_number,
id_=id_,
product_key=product_key,
usage_page=usage_page,
transport_ui_string='hid'))
return devices return devices
@with_scan_lock @with_scan_lock

9
electrum/plugins/bitbox02/bitbox02.py

@ -546,7 +546,7 @@ class BitBox02Plugin(HW_PluginBase):
self.libraries_available = self.check_libraries_available() self.libraries_available = self.check_libraries_available()
if not self.libraries_available: if not self.libraries_available:
return return
self.device_manager().register_devices(self.DEVICE_IDS) self.device_manager().register_devices(self.DEVICE_IDS, plugin=self)
def get_library_version(self): def get_library_version(self):
try: try:
@ -617,3 +617,10 @@ class BitBox02Plugin(HW_PluginBase):
derivation = keystore.get_derivation_prefix() derivation = keystore.get_derivation_prefix()
xtype = keystore.get_bip32_node_for_xpub().xtype xtype = keystore.get_bip32_node_for_xpub().xtype
client.get_xpub(derivation, xtype, display=True) client.get_xpub(derivation, xtype, display=True)
def create_device_from_hid_enumeration(self, d: dict, *, product_key) -> 'Device':
device = super().create_device_from_hid_enumeration(d, product_key=product_key)
# The BitBox02's product_id is not unique per device, thus use the path instead to
# distinguish devices.
id_ = str(d['path'])
return device._replace(id_=id_)

2
electrum/plugins/coldcard/coldcard.py

@ -477,7 +477,7 @@ class ColdcardPlugin(HW_PluginBase):
if not self.libraries_available: if not self.libraries_available:
return return
self.device_manager().register_devices(self.DEVICE_IDS) self.device_manager().register_devices(self.DEVICE_IDS, plugin=self)
self.device_manager().register_enumerate_func(self.detect_simulator) self.device_manager().register_enumerate_func(self.detect_simulator)
def get_library_version(self): def get_library_version(self):

2
electrum/plugins/digitalbitbox/digitalbitbox.py

@ -675,7 +675,7 @@ class DigitalBitboxPlugin(HW_PluginBase):
def __init__(self, parent, config, name): def __init__(self, parent, config, name):
HW_PluginBase.__init__(self, parent, config, name) HW_PluginBase.__init__(self, parent, config, name)
if self.libraries_available: if self.libraries_available:
self.device_manager().register_devices(self.DEVICE_IDS) self.device_manager().register_devices(self.DEVICE_IDS, plugin=self)
self.digitalbitbox_config = self.config.get('digitalbitbox', {}) self.digitalbitbox_config = self.config.get('digitalbitbox', {})

16
electrum/plugins/hw_wallet/plugin.py

@ -60,6 +60,22 @@ class HW_PluginBase(BasePlugin):
def device_manager(self) -> 'DeviceMgr': def device_manager(self) -> 'DeviceMgr':
return self.parent.device_manager return self.parent.device_manager
def create_device_from_hid_enumeration(self, d: dict, *, product_key) -> 'Device':
# Older versions of hid don't provide interface_number
interface_number = d.get('interface_number', -1)
usage_page = d['usage_page']
id_ = d['serial_number']
if len(id_) == 0:
id_ = str(d['path'])
id_ += str(interface_number) + str(usage_page)
device = Device(path=d['path'],
interface_number=interface_number,
id_=id_,
product_key=product_key,
usage_page=usage_page,
transport_ui_string='hid')
return device
@hook @hook
def close_wallet(self, wallet: 'Abstract_Wallet'): def close_wallet(self, wallet: 'Abstract_Wallet'):
for keystore in wallet.get_keystores(): for keystore in wallet.get_keystores():

2
electrum/plugins/keepkey/keepkey.py

@ -88,7 +88,7 @@ class KeepKeyPlugin(HW_PluginBase):
self.DEVICE_IDS = (keepkeylib.transport_hid.DEVICE_IDS + self.DEVICE_IDS = (keepkeylib.transport_hid.DEVICE_IDS +
keepkeylib.transport_webusb.DEVICE_IDS) keepkeylib.transport_webusb.DEVICE_IDS)
# only "register" hid device id: # only "register" hid device id:
self.device_manager().register_devices(keepkeylib.transport_hid.DEVICE_IDS) self.device_manager().register_devices(keepkeylib.transport_hid.DEVICE_IDS, plugin=self)
# for webusb transport, use custom enumerate function: # for webusb transport, use custom enumerate function:
self.device_manager().register_enumerate_func(self.enumerate) self.device_manager().register_enumerate_func(self.enumerate)
self.libraries_available = True self.libraries_available = True

2
electrum/plugins/ledger/ledger.py

@ -578,7 +578,7 @@ class LedgerPlugin(HW_PluginBase):
self.segwit = config.get("segwit") self.segwit = config.get("segwit")
HW_PluginBase.__init__(self, parent, config, name) HW_PluginBase.__init__(self, parent, config, name)
if self.libraries_available: if self.libraries_available:
self.device_manager().register_devices(self.DEVICE_IDS) self.device_manager().register_devices(self.DEVICE_IDS, plugin=self)
def get_btchip_device(self, device): def get_btchip_device(self, device):
ledger = False ledger = False

Loading…
Cancel
Save