Browse Source

hardware wallets: better handle label collision when selecting device

related: #5759
master
SomberNight 6 years ago
parent
commit
56c3de0e1e
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 26
      electrum/plugin.py
  2. 7
      electrum/plugins/hw_wallet/plugin.py

26
electrum/plugin.py

@ -314,6 +314,9 @@ class HardwarePluginToScan(NamedTuple):
exception: Optional[Exception]
PLACEHOLDER_HW_CLIENT_LABELS = {"", " "}
class DeviceMgr(ThreadJob):
'''Manages hardware clients. A client communicates over a hardware
channel with the device.
@ -507,7 +510,7 @@ class DeviceMgr(ThreadJob):
'its seed (and passphrase, if any). Otherwise all bitcoins you '
'receive will be unspendable.').format(plugin.device))
def unpaired_device_infos(self, handler, plugin: 'HW_PluginBase', devices=None,
def unpaired_device_infos(self, handler, plugin: 'HW_PluginBase', devices: List['Device'] = None,
include_failing_clients=False):
'''Returns a list of DeviceInfo objects: one for each connected,
unpaired device accepted by the plugin.'''
@ -537,7 +540,7 @@ class DeviceMgr(ThreadJob):
return infos
def select_device(self, plugin: 'HW_PluginBase', handler,
keystore: 'Hardware_KeyStore', devices=None) -> 'DeviceInfo':
keystore: 'Hardware_KeyStore', devices: List['Device'] = 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:
@ -557,12 +560,21 @@ class DeviceMgr(ThreadJob):
devices = None
if len(infos) == 1:
return infos[0]
# select device by label
for info in infos:
if info.label == keystore.label:
return info
# select device by label automatically;
# but only if not a placeholder label and only if there is no collision
device_labels = [info.label for info in infos]
if (keystore.label not in PLACEHOLDER_HW_CLIENT_LABELS
and device_labels.count(keystore.label) == 1):
for info in infos:
if info.label == keystore.label:
return info
# ask user to select device
msg = _("Please select which {} device to use:").format(plugin.device)
descriptions = [str(info.label) + ' (%s)'%(_("initialized") if info.initialized else _("wiped")) for info in infos]
descriptions = ["{label} ({init}, {transport})"
.format(label=info.label,
init=(_("initialized") if info.initialized else _("wiped")),
transport=info.device.transport_ui_string)
for info in infos]
c = handler.query_choice(msg, descriptions)
if c is None:
raise UserCancelled()

7
electrum/plugins/hw_wallet/plugin.py

@ -160,7 +160,12 @@ class HardwareClientBase:
raise NotImplementedError()
def label(self) -> str:
"""The name given by the user to the device."""
"""The name given by the user to the device.
Note: labels are shown to the user to help distinguish their devices,
and they are also used as a fallback to distinguish devices programmatically.
So ideally, different devices would have different labels.
"""
raise NotImplementedError()
def has_usable_connection_with_device(self) -> bool:

Loading…
Cancel
Save