electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

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:
Melectrum/base_wizard.py | 3++-
Melectrum/plugin.py | 3++-
Melectrum/plugins/coldcard/coldcard.py | 17+++++++++++++----
Melectrum/plugins/hw_wallet/plugin.py | 36+++++++++++++++++++++++++++++++++++-
Melectrum/plugins/hw_wallet/qt.py | 6+-----
Melectrum/plugins/safe_t/safe_t.py | 28+++++++++-------------------
Melectrum/plugins/trezor/trezor.py | 28+++++++++-------------------
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]