commit 91c369e39288328f24fedc70e36eda67f5ad6dd3
parent 9279f30363d0e01ec0ee501eddd6966cf9a37d7e
Author: SomberNight <somber.night@protonmail.com>
Date: Thu, 23 Aug 2018 18:31:14 +0200
hw wallets: generalise 'minimum_library' for those that provide a version number
Diffstat:
7 files changed, 71 insertions(+), 50 deletions(-)
diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py
@@ -240,7 +240,8 @@ class BaseWizard(object):
u = devmgr.unpaired_device_infos(None, plugin, devices=scanned_devices)
except BaseException as e:
devmgr.print_error('error getting device infos for {}: {}'.format(name, e))
- debug_msg += ' {}:\n {}\n'.format(plugin.name, e)
+ indented_error_msg = ' '.join([''] + str(e).splitlines(keepends=True))
+ debug_msg += ' {}:\n{}\n'.format(plugin.name, indented_error_msg)
continue
devices += list(map(lambda x: (name, x), u))
if not debug_msg:
diff --git a/electrum/plugin.py b/electrum/plugin.py
@@ -457,7 +457,8 @@ class DeviceMgr(ThreadJob, PrintError):
'''Returns a list of DeviceInfo objects: one for each connected,
unpaired device accepted by the plugin.'''
if not plugin.libraries_available:
- raise Exception('Missing libraries for {}'.format(plugin.name))
+ message = plugin.get_library_not_available_message()
+ raise Exception(message)
if devices is None:
devices = self.scan_devices()
devices = [dev for dev in devices if not self.xpub_by_id(dev.id_)]
diff --git a/electrum/plugins/coldcard/coldcard.py b/electrum/plugins/coldcard/coldcard.py
@@ -585,8 +585,8 @@ class Coldcard_KeyStore(Hardware_KeyStore):
class ColdcardPlugin(HW_PluginBase):
- libraries_available = requirements_ok
keystore_class = Coldcard_KeyStore
+ minimum_library = (0, 7, 2)
client = None
DEVICE_IDS = [
@@ -600,10 +600,19 @@ class ColdcardPlugin(HW_PluginBase):
def __init__(self, parent, config, name):
HW_PluginBase.__init__(self, parent, config, name)
- if self.libraries_available:
- self.device_manager().register_devices(self.DEVICE_IDS)
+ self.libraries_available = self.check_libraries_available() and requirements_ok
+ if not self.libraries_available:
+ return
+
+ self.device_manager().register_devices(self.DEVICE_IDS)
+ self.device_manager().register_enumerate_func(self.detect_simulator)
- self.device_manager().register_enumerate_func(self.detect_simulator)
+ def get_library_version(self):
+ import ckcc
+ try:
+ return ckcc.__version__
+ except AttributeError:
+ return 'unknown'
def detect_simulator(self):
# if there is a simulator running on this machine,
diff --git a/electrum/plugins/hw_wallet/plugin.py b/electrum/plugins/hw_wallet/plugin.py
@@ -27,7 +27,7 @@
from electrum.plugin import BasePlugin, hook
from electrum.i18n import _
from electrum.bitcoin import is_address, TYPE_SCRIPT
-from electrum.util import bfh
+from electrum.util import bfh, versiontuple
from electrum.transaction import opcodes, TxOutput
@@ -38,6 +38,8 @@ class HW_PluginBase(BasePlugin):
# libraries_available, libraries_URL, minimum_firmware,
# wallet_class, ckd_public, types, HidTransport
+ minimum_library = (0, )
+
def __init__(self, parent, config, name):
BasePlugin.__init__(self, parent, config, name)
self.device = self.keystore_class.device
@@ -78,6 +80,38 @@ class HW_PluginBase(BasePlugin):
return False
return True
+ def get_library_version(self) -> str:
+ """Returns the version of the 3rd party python library
+ for the hw wallet. For example '0.9.0'
+
+ Returns 'unknown' if library is found but cannot determine version.
+ Raises 'ImportError' if library is not found.
+ """
+ raise NotImplementedError()
+
+ def check_libraries_available(self) -> bool:
+ try:
+ library_version = self.get_library_version()
+ except ImportError:
+ return False
+ if library_version == 'unknown' or \
+ versiontuple(library_version) < self.minimum_library:
+ self.libraries_available_message = (
+ _("Library version for '{}' is too old.").format(self.name)
+ + '\nInstalled: {}, Needed: {}'
+ .format(library_version, self.minimum_library))
+ self.print_stderr(self.libraries_available_message)
+ return False
+ return True
+
+ def get_library_not_available_message(self) -> str:
+ if hasattr(self, 'libraries_available_message'):
+ message = self.libraries_available_message
+ else:
+ message = _("Missing libraries for {}.").format(self.name)
+ message += '\n' + _("Make sure you install it with python3")
+ return message
+
def is_any_tx_output_on_change_branch(tx):
if not hasattr(tx, 'output_info'):
diff --git a/electrum/plugins/hw_wallet/qt.py b/electrum/plugins/hw_wallet/qt.py
@@ -189,11 +189,7 @@ class QtPluginBase(object):
if not isinstance(keystore, self.keystore_class):
continue
if not self.libraries_available:
- if hasattr(self, 'libraries_available_message'):
- message = self.libraries_available_message + '\n'
- else:
- message = _("Cannot find python library for") + " '%s'.\n" % self.name
- message += _("Make sure you install it with python3")
+ message = keystore.plugin.get_library_not_available_message()
window.show_error(message)
return
tooltip = self.device + '\n' + (keystore.label or 'unnamed')
diff --git a/electrum/plugins/safe_t/safe_t.py b/electrum/plugins/safe_t/safe_t.py
@@ -82,25 +82,8 @@ class SafeTPlugin(HW_PluginBase):
def __init__(self, parent, config, name):
HW_PluginBase.__init__(self, parent, config, name)
- try:
- # Minimal test if python-safet is installed
- import safetlib
- try:
- library_version = safetlib.__version__
- except AttributeError:
- # python-safet only introduced __version__ in 0.1.0
- library_version = 'unknown'
- if library_version == 'unknown' or \
- versiontuple(library_version) < self.minimum_library:
- self.libraries_available_message = (
- _("Library version for '{}' is too old.").format(name)
- + '\nInstalled: {}, Needed: {}'
- .format(library_version, self.minimum_library))
- self.print_stderr(self.libraries_available_message)
- raise ImportError()
- self.libraries_available = True
- except ImportError:
- self.libraries_available = False
+ self.libraries_available = self.check_libraries_available()
+ if not self.libraries_available:
return
from . import client
@@ -113,6 +96,13 @@ class SafeTPlugin(HW_PluginBase):
self.transport_handler = transport.SafeTTransport()
self.device_manager().register_enumerate_func(self.enumerate)
+ def get_library_version(self):
+ import safetlib
+ try:
+ return safetlib.__version__
+ except AttributeError:
+ return 'unknown'
+
def enumerate(self):
devices = self.transport_handler.enumerate_devices()
return [Device(d.get_path(), -1, d.get_path(), 'Safe-T mini', 0) for d in devices]
diff --git a/electrum/plugins/trezor/trezor.py b/electrum/plugins/trezor/trezor.py
@@ -83,25 +83,8 @@ class TrezorPlugin(HW_PluginBase):
def __init__(self, parent, config, name):
HW_PluginBase.__init__(self, parent, config, name)
- try:
- # Minimal test if python-trezor is installed
- import trezorlib
- try:
- library_version = trezorlib.__version__
- except AttributeError:
- # python-trezor only introduced __version__ in 0.9.0
- library_version = 'unknown'
- if library_version == 'unknown' or \
- versiontuple(library_version) < self.minimum_library:
- self.libraries_available_message = (
- _("Library version for '{}' is too old.").format(name)
- + '\nInstalled: {}, Needed: {}'
- .format(library_version, self.minimum_library))
- self.print_stderr(self.libraries_available_message)
- raise ImportError()
- self.libraries_available = True
- except ImportError:
- self.libraries_available = False
+ self.libraries_available = self.check_libraries_available()
+ if not self.libraries_available:
return
from . import client
@@ -114,6 +97,13 @@ class TrezorPlugin(HW_PluginBase):
self.transport_handler = transport.TrezorTransport()
self.device_manager().register_enumerate_func(self.enumerate)
+ def get_library_version(self):
+ import trezorlib
+ try:
+ return trezorlib.__version__
+ except AttributeError:
+ return 'unknown'
+
def enumerate(self):
devices = self.transport_handler.enumerate_devices()
return [Device(d.get_path(), -1, d.get_path(), 'TREZOR', 0) for d in devices]