URI: 
       tsave wallet label in keystore, to facilitate pairing - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 86e23d998900b07b84c716c7cb804646a4232b9b
   DIR parent cae635c3e4b0450d64d169910a6e93235f4b1563
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Fri, 26 Aug 2016 11:45:12 +0200
       
       save wallet label in keystore, to facilitate pairing
       
       Diffstat:
         M lib/base_wizard.py                  |       1 +
         M lib/keystore.py                     |       7 ++++++-
         M lib/plugins.py                      |      38 +++++++++++++++++++------------
         M lib/wallet.py                       |       4 ++++
         M plugins/trezor/plugin.py            |       5 +----
         M plugins/trezor/qt_generic.py        |       2 +-
       
       6 files changed, 37 insertions(+), 20 deletions(-)
       ---
   DIR diff --git a/lib/base_wizard.py b/lib/base_wizard.py
       t@@ -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)
   DIR diff --git a/lib/keystore.py b/lib/keystore.py
       t@@ -49,6 +49,7 @@ class KeyStore(PrintError):
            def can_import(self):
                return False
        
       +
        class Software_KeyStore(KeyStore):
        
            def __init__(self):
       t@@ -70,7 +71,6 @@ class Software_KeyStore(KeyStore):
                return decrypted
        
        
       -
        class Imported_KeyStore(Software_KeyStore):
            # keystore for imported private keys
        
       t@@ -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
        
       t@@ -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):
   DIR diff --git a/lib/plugins.py b/lib/plugins.py
       t@@ -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:
       t@@ -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
       t@@ -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:
       t@@ -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
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -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/')
        
   DIR diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py
       t@@ -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()
   DIR diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py
       t@@ -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