electrum

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

commit 86e23d998900b07b84c716c7cb804646a4232b9b
parent cae635c3e4b0450d64d169910a6e93235f4b1563
Author: ThomasV <thomasv@electrum.org>
Date:   Fri, 26 Aug 2016 11:45:12 +0200

save wallet label in keystore, to facilitate pairing

Diffstat:
Mlib/base_wizard.py | 1+
Mlib/keystore.py | 7++++++-
Mlib/plugins.py | 38++++++++++++++++++++++++--------------
Mlib/wallet.py | 4++++
Mplugins/trezor/plugin.py | 5+----
Mplugins/trezor/qt_generic.py | 2+-
6 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/lib/base_wizard.py b/lib/base_wizard.py @@ -218,6 +218,7 @@ class BaseWizard(object): 'hw_type': name, 'derivation': derivation, 'xpub': xpub, + 'label': device_info.label, } k = hardware_keystore(d) self.on_keystore(k) diff --git a/lib/keystore.py b/lib/keystore.py @@ -49,6 +49,7 @@ class KeyStore(PrintError): def can_import(self): return False + class Software_KeyStore(KeyStore): def __init__(self): @@ -70,7 +71,6 @@ class Software_KeyStore(KeyStore): return decrypted - class Imported_KeyStore(Software_KeyStore): # keystore for imported private keys @@ -459,9 +459,13 @@ class Hardware_KeyStore(KeyStore, Xpub): # handler. The handler is per-window and preserved across # device reconnects self.xpub = d.get('xpub') + self.label = d.get('label') self.derivation = d.get('derivation') self.handler = None + def set_label(self, label): + self.label = label + def may_have_password(self): return False @@ -474,6 +478,7 @@ class Hardware_KeyStore(KeyStore, Xpub): 'hw_type': self.hw_type, 'xpub': self.xpub, 'derivation':self.derivation, + 'label':self.label, } def unpaired(self): diff --git a/lib/plugins.py b/lib/plugins.py @@ -383,8 +383,18 @@ class DeviceMgr(ThreadJob, PrintError): self.scan_devices() return self.client_lookup(id_) - def client_for_xpub(self, plugin, xpub, derivation, handler, force_pair): - devices = self.scan_devices() + def client_for_keystore(self, plugin, keystore, force_pair): + with self.lock: + devices = self.scan_devices() + xpub = keystore.xpub + derivation = keystore.get_derivation() + handler = keystore.handler + client = self.client_by_xpub(plugin, xpub, handler, devices) + if client is None and force_pair: + info = self.select_device(handler, plugin, keystore, devices) + client = self.force_pair_xpub(plugin, handler, info, xpub, derivation, devices) + + def client_by_xpub(self, plugin, xpub, handler, devices): _id = self.xpub_id(xpub) client = self.client_lookup(_id) if client: @@ -397,16 +407,11 @@ class DeviceMgr(ThreadJob, PrintError): if device.id_ == _id: return self.create_client(device, handler, plugin) - if force_pair: - return self.force_pair_xpub(plugin, handler, xpub, derivation, devices) - - return None - def force_pair_xpub(self, plugin, handler, xpub, derivation, devices): + def force_pair_xpub(self, plugin, handler, info, xpub, derivation, devices): # The wallet has not been previously paired, so let the user # choose an unpaired device and compare its first address. - with self.lock: - info = self.select_device(handler, plugin, devices) + client = self.client_lookup(info.device.id_) if client and client.is_pairable(): # See comment above for same code @@ -447,7 +452,7 @@ class DeviceMgr(ThreadJob, PrintError): return infos - def select_device(self, handler, plugin, devices=None): + def select_device(self, handler, plugin, keystore, devices=None): '''Ask the user to select a device to use if there is more than one, and return the DeviceInfo for the device.''' while True: @@ -460,12 +465,17 @@ class DeviceMgr(ThreadJob, PrintError): if not handler.yes_no_question(msg): raise UserCancelled() devices = None - - if len(infos) == 1: - return infos[0] + # select device by label + for info in infos: + if info.label == keystore.label: + return info msg = _("Please select which %s device to use:") % plugin.device descriptions = [info.label + ' (%s)'%(_("initialized") if info.initialized else _("wiped")) for info in infos] - return infos[handler.query_choice(msg, descriptions)] + info = infos[handler.query_choice(msg, descriptions)] + # save new label + keystore.set_label(info.label) + keystore.handler.win.wallet.save_keystore() + return info def scan_devices(self): # All currently supported hardware libraries use hid, so we diff --git a/lib/wallet.py b/lib/wallet.py @@ -1489,6 +1489,10 @@ class Multisig_Wallet(Deterministic_Wallet): self.keystores[name] = load_keystore(self.storage, name) self.keystore = self.keystores['x1/'] + def save_keystore(self): + for name, k in self.keystores.items(): + self.storage.put(name, k.dump()) + def get_keystore(self): return self.keystores.get('x1/') diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py @@ -134,10 +134,7 @@ class TrezorCompatiblePlugin(HW_PluginBase): # All client interaction should not be in the main GUI thread assert self.main_thread != threading.current_thread() devmgr = self.device_manager() - derivation = keystore.get_derivation() - xpub = keystore.xpub - handler = keystore.handler - client = devmgr.client_for_xpub(self, xpub, derivation, handler, force_pair) + client = devmgr.client_for_keystore(self, keystore, force_pair) # returns the client for a given keystore. can use xpub if client: client.used() diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py @@ -219,7 +219,7 @@ def qt_plugin_class(base_plugin_class): forgotten their PIN or it is in bootloader mode.''' device_id = self.device_manager().xpub_id(keystore.xpub) if not device_id: - info = self.device_manager().select_device(keystore.handler, self) + info = self.device_manager().select_device(keystore.handler, self, keystore) device_id = info.device.id_ return device_id