hw wallets: generalise 'minimum_library' for those that provide a version number

This commit is contained in:
SomberNight 2018-08-23 18:31:14 +02:00
parent 9279f30363
commit 91c369e392
No known key found for this signature in database
GPG key ID: B33B5F232C6271E9
7 changed files with 71 additions and 50 deletions

View file

@ -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:

View file

@ -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_)]

View file

@ -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_enumerate_func(self.detect_simulator)
self.device_manager().register_devices(self.DEVICE_IDS)
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,

View file

@ -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'):

View file

@ -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')

View file

@ -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]

View file

@ -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]