Browse Source

Trezor/KeepKey: force watching only improvements

Only warn about watching only once given a chance to pair.
Failure to pair makes watching-only and warns.
In error message to user, distinguish between failure to connect
and failure to pair.
master
Neil Booth 10 years ago
parent
commit
e61fffab55
  1. 1
      gui/qt/main_window.py
  2. 22
      lib/plugins.py
  3. 13
      plugins/hw_wallet/hw_wallet.py
  4. 13
      plugins/trezor/plugin.py

1
gui/qt/main_window.py

@ -311,6 +311,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
title = 'Electrum %s - %s' % (self.wallet.electrum_version, title = 'Electrum %s - %s' % (self.wallet.electrum_version,
self.wallet.basename()) self.wallet.basename())
if self.wallet.is_watching_only(): if self.wallet.is_watching_only():
self.warn_if_watching_only()
title += ' [%s]' % (_('watching only')) title += ' [%s]' % (_('watching only'))
self.setWindowTitle(title) self.setWindowTitle(title)
self.password_menu.setEnabled(self.wallet.can_change_password()) self.password_menu.setEnabled(self.wallet.can_change_password())

22
lib/plugins.py

@ -234,6 +234,13 @@ class BasePlugin(PrintError):
def settings_dialog(self): def settings_dialog(self):
pass pass
class DeviceNotFoundError(Exception):
pass
class DeviceUnpairableError(Exception):
pass
Device = namedtuple("Device", "path interface_number id_ product_key") Device = namedtuple("Device", "path interface_number id_ product_key")
DeviceInfo = namedtuple("DeviceInfo", "device description initialized") DeviceInfo = namedtuple("DeviceInfo", "device description initialized")
@ -368,6 +375,11 @@ class DeviceMgr(PrintError):
return self.create_client(device, wallet.handler, plugin) return self.create_client(device, wallet.handler, plugin)
if force_pair: if force_pair:
return self.force_pair_wallet(plugin, wallet, devices)
return None
def force_pair_wallet(self, plugin, wallet, devices):
first_address, derivation = wallet.first_address() first_address, derivation = wallet.first_address()
assert first_address assert first_address
@ -385,7 +397,15 @@ class DeviceMgr(PrintError):
self.pair_wallet(wallet, info.device.id_) self.pair_wallet(wallet, info.device.id_)
return client return client
return None if info and client:
# The user input has wrong PIN or passphrase
raise DeviceUnpairableError(
_('Unable to pair with your %s.') % plugin.device)
raise DeviceNotFoundError(
_('Could not connect to your %s. Verify the cable is '
'connected and that no other application is using it.')
% plugin.device)
def unpaired_device_infos(self, handler, plugin, devices=None): def unpaired_device_infos(self, handler, plugin, devices=None):
'''Returns a list of DeviceInfo objects: one for each connected, '''Returns a list of DeviceInfo objects: one for each connected,

13
plugins/hw_wallet/hw_wallet.py

@ -39,26 +39,29 @@ class BIP44_HW_Wallet(BIP44_Wallet):
# handler. The handler is per-window and preserved across # handler. The handler is per-window and preserved across
# device reconnects # device reconnects
self.handler = None self.handler = None
self.force_watching_only = True self.force_watching_only = False
def set_session_timeout(self, seconds): def set_session_timeout(self, seconds):
self.print_error("setting session timeout to %d seconds" % seconds) self.print_error("setting session timeout to %d seconds" % seconds)
self.session_timeout = seconds self.session_timeout = seconds
self.storage.put('session_timeout', seconds) self.storage.put('session_timeout', seconds)
def set_force_watching_only(self, value):
if value != self.force_watching_only:
self.force_watching_only = value
self.handler.watching_only_changed()
def unpaired(self): def unpaired(self):
'''A device paired with the wallet was diconnected. This can be '''A device paired with the wallet was diconnected. This can be
called in any thread context.''' called in any thread context.'''
self.print_error("unpaired") self.print_error("unpaired")
self.force_watching_only = True self.set_force_watching_only(True)
self.handler.watching_only_changed()
def paired(self): def paired(self):
'''A device paired with the wallet was (re-)connected. This can be '''A device paired with the wallet was (re-)connected. This can be
called in any thread context.''' called in any thread context.'''
self.print_error("paired") self.print_error("paired")
self.force_watching_only = False self.set_force_watching_only(False)
self.handler.watching_only_changed()
def timeout(self): def timeout(self):
'''Called when the wallet session times out. Note this is called from '''Called when the wallet session times out. Note this is called from

13
plugins/trezor/plugin.py

@ -20,9 +20,6 @@ from ..hw_wallet import BIP44_HW_Wallet, HW_PluginBase
# TREZOR initialization methods # TREZOR initialization methods
TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY = range(0, 4) TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY = range(0, 4)
class DeviceDisconnectedError(Exception):
pass
class TrezorCompatibleWallet(BIP44_HW_Wallet): class TrezorCompatibleWallet(BIP44_HW_Wallet):
def get_public_key(self, bip32_path): def get_public_key(self, bip32_path):
@ -137,17 +134,15 @@ class TrezorCompatiblePlugin(HW_PluginBase):
assert self.main_thread != threading.current_thread() assert self.main_thread != threading.current_thread()
devmgr = self.device_manager() devmgr = self.device_manager()
try:
client = devmgr.client_for_wallet(self, wallet, force_pair) client = devmgr.client_for_wallet(self, wallet, force_pair)
except:
wallet.set_force_watching_only(True)
raise
if client: if client:
self.print_error("set last_operation") self.print_error("set last_operation")
wallet.last_operation = time.time() wallet.last_operation = time.time()
elif force_pair:
msg = (_('Could not connect to your %s. Verify the '
'cable is connected and that no other app is '
'using it.\nContinuing in watching-only mode '
'until the device is re-connected.') % self.device)
raise DeviceDisconnectedError(msg)
return client return client

Loading…
Cancel
Save