URI: 
       thardware wallets: pass xtype to get_xpub - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit f36024e216f96ec2c73aaa67e45c2751378bde03
   DIR parent 1ecfcea8dcfe37df4c6dceeaf071f19c7660c44b
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Tue, 31 Oct 2017 11:45:25 +0100
       
       hardware wallets: pass xtype to get_xpub
       
       Diffstat:
         M lib/base_wizard.py                  |       3 ++-
         M lib/bitcoin.py                      |       1 -
         M lib/plugins.py                      |       5 +++--
         M lib/wallet.py                       |       4 ++--
         M plugins/digitalbitbox/digitalbitbo… |       9 +++++----
         M plugins/ledger/ledger.py            |      24 +++++++++---------------
         M plugins/trezor/clientbase.py        |       8 ++------
         M plugins/trezor/plugin.py            |       6 +++---
       
       8 files changed, 26 insertions(+), 34 deletions(-)
       ---
   DIR diff --git a/lib/base_wizard.py b/lib/base_wizard.py
       t@@ -241,7 +241,8 @@ class BaseWizard(object):
        
            def on_hw_derivation(self, name, device_info, derivation):
                from .keystore import hardware_keystore
       -        xpub = self.plugin.get_xpub(device_info.device.id_, derivation, self)
       +        xtype = 'p2wpkh-p2sh' if derivation.startswith("m/49'/") else 'standard'
       +        xpub = self.plugin.get_xpub(device_info.device.id_, derivation, xtype, self)
                if xpub is None:
                    self.show_error('Cannot read xpub from device')
                    return
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -927,7 +927,6 @@ def deserialize_xkey(xkey, prv):
        def deserialize_xpub(xkey):
            return deserialize_xkey(xkey, False)
        
       -
        def deserialize_xprv(xkey):
            return deserialize_xkey(xkey, True)
        
   DIR diff --git a/lib/plugins.py b/lib/plugins.py
       t@@ -34,6 +34,7 @@ import threading
        from .util import *
        from .i18n import _
        from .util import profiler, PrintError, DaemonThread, UserCancelled, ThreadJob
       +from . import bitcoin
        
        plugin_loaders = {}
        hook_names = set()
       t@@ -421,14 +422,14 @@ class DeviceMgr(ThreadJob, PrintError):
            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.
       -
       +        xtype = bitcoin.xpub_type(xpub)
                client = self.client_lookup(info.device.id_)
                if client and client.is_pairable():
                    # See comment above for same code
                    client.handler = handler
                    # This will trigger a PIN/passphrase entry request
                    try:
       -                client_xpub = client.get_xpub(derivation)
       +                client_xpub = client.get_xpub(derivation, xtype)
                    except (UserCancelled, RuntimeError):
                         # Bad / cancelled PIN / passphrase
                        client_xpub = None
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -1673,7 +1673,7 @@ class Simple_Deterministic_Wallet(Simple_Wallet, Deterministic_Wallet):
            def load_keystore(self):
                self.keystore = load_keystore(self.storage, 'keystore')
                try:
       -            xtype = deserialize_xpub(self.keystore.xpub)[0]
       +            xtype = bitcoin.xpub_type(self.keystore.xpub)
                except:
                    xtype = 'standard'
                self.txin_type = 'p2pkh' if xtype == 'standard' else xtype
       t@@ -1737,7 +1737,7 @@ class Multisig_Wallet(Deterministic_Wallet):
                    name = 'x%d/'%(i+1)
                    self.keystores[name] = load_keystore(self.storage, name)
                self.keystore = self.keystores['x1/']
       -        xtype = deserialize_xpub(self.keystore.xpub)[0]
       +        xtype = bitcoin.xpub_type(self.keystore.xpub)
                self.txin_type = 'p2sh' if xtype == 'standard' else xtype
        
            def save_keystore(self):
   DIR diff --git a/plugins/digitalbitbox/digitalbitbox.py b/plugins/digitalbitbox/digitalbitbox.py
       t@@ -84,7 +84,8 @@ class DigitalBitbox_Client():
                    return self.hid_send_encrypt(b'{"xpub": "%s"}' % bip32_path.encode('utf8'))
        
        
       -    def get_xpub(self, bip32_path):
       +    def get_xpub(self, bip32_path, xtype):
       +        assert xpub == 'standard'
                reply = self._get_xpub(bip32_path)
                if reply:
                    return reply['xpub']
       t@@ -646,7 +647,7 @@ class DigitalBitboxPlugin(HW_PluginBase):
                client = devmgr.client_by_id(device_id)
                client.handler = self.create_handler(wizard)
                client.setupRunning = True
       -        client.get_xpub("m/44'/0'")
       +        client.get_xpub("m/44'/0'", 'standard')
        
        
            def is_mobile_paired(self):
       t@@ -667,12 +668,12 @@ class DigitalBitboxPlugin(HW_PluginBase):
                    self.handler.show_error(str(e))
        
        
       -    def get_xpub(self, device_id, derivation, wizard):
       +    def get_xpub(self, device_id, derivation, xtype, wizard):
                devmgr = self.device_manager()
                client = devmgr.client_by_id(device_id)
                client.handler = self.create_handler(wizard)
                client.check_device_dialog()
       -        xpub = client.get_xpub(derivation)
       +        xpub = client.get_xpub(derivation, xtype)
                return xpub
        
        
   DIR diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py
       t@@ -51,7 +51,7 @@ class Ledger_Client():
            def i4b(self, x):
                return pack('>I', x)        
        
       -    def get_xpub(self, bip32_path):
       +    def get_xpub(self, bip32_path, xtype):
                self.checkDevice()
                # bip32_path is of the form 44'/0'/1'
                # S-L-O-W - we don't handle the fingerprint directly, so compute
       t@@ -60,14 +60,11 @@ class Ledger_Client():
                #self.get_client() # prompt for the PIN before displaying the dialog if necessary
                #self.handler.show_message("Computing master public key")
                try:
       -            if (os.getenv("LEDGER_NATIVE_SEGWIT") is not None) and self.supports_native_segwit():
       -                xtype = 'p2wpkh'
       -            elif bip32_path.startswith("m/49'/"):
       -                if not self.supports_segwit():
       -                    raise Exception("Firmware version too old for Segwit support. Please update at https://www.ledgerwallet.com")
       -                xtype = 'p2wpkh-p2sh'
       -            else:
       -                xtype = 'standard'
       +            if xtype in ['p2wpkh', 'p2wsh'] and not nelf.supports_native_segwit():
       +                raise Exception("Firmware version too old for Segwit support. Please update at https://www.ledgerwallet.com")
       +            if xtype in ['p2wpkh-p2sh', 'p2wsh-p2sh'] and not self.supports_segwit():
       +                raise Exception("Firmware version too old for Segwit support. Please update at https://www.ledgerwallet.com")
       +
                    splitPath = bip32_path.split('/')
                    if splitPath[0] == 'm':
                        splitPath = splitPath[1:]
       t@@ -493,18 +490,15 @@ class LedgerPlugin(HW_PluginBase):
                devmgr = self.device_manager()
                device_id = device_info.device.id_
                client = devmgr.client_by_id(device_id)
       -        #client.handler = wizard
                client.handler = self.create_handler(wizard)
       -        #client.get_xpub('m')
       -        client.get_xpub("m/44'/0'") # TODO replace by direct derivation once Nano S > 1.1
       +        client.get_xpub("m/44'/0'", 'standard') # TODO replace by direct derivation once Nano S > 1.1
        
       -    def get_xpub(self, device_id, derivation, wizard):
       +    def get_xpub(self, device_id, derivation, xtype, wizard):
                devmgr = self.device_manager()
                client = devmgr.client_by_id(device_id)
       -        #client.handler = wizard
                client.handler = self.create_handler(wizard)
                client.checkDevice()
       -        xpub = client.get_xpub(derivation)
       +        xpub = client.get_xpub(derivation, xtype)
                return xpub
        
            def get_client(self, keystore, force_pair=True):
   DIR diff --git a/plugins/trezor/clientbase.py b/plugins/trezor/clientbase.py
       t@@ -147,16 +147,12 @@ class TrezorClientBase(GuiMixin, PrintError):
            def i4b(self, x):
                return pack('>I', x)
        
       -    def get_xpub(self, bip32_path):
       +    def get_xpub(self, bip32_path, xtype):
                address_n = self.expand_path(bip32_path)
       -        creating = False #self.next_account_number() == 0
       +        creating = False
                node = self.get_public_node(address_n, creating).node
       -        xtype = 'p2wpkh-p2sh' if bip32_path.startswith("m/49'/") else 'standard'
                return serialize_xpub(xtype, node.chain_code, node.public_key, node.depth, self.i4b(node.fingerprint), self.i4b(node.child_num))
        
       -    #def address_from_derivation(self, derivation):
       -    #    return self.get_address('Bitcoin', self.expand_path(derivation))
       -
            def toggle_passphrase(self):
                if self.features.passphrase_protection:
                    self.msg = _("Confirm on your %s device to disable passphrases")
   DIR diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py
       t@@ -220,14 +220,14 @@ class TrezorCompatiblePlugin(HW_PluginBase):
                client.handler = self.create_handler(wizard)
                if not device_info.initialized:
                    self.initialize_device(device_id, wizard, client.handler)
       -        client.get_xpub('m')
       +        client.get_xpub('m', 'standard')
                client.used()
        
       -    def get_xpub(self, device_id, derivation, wizard):
       +    def get_xpub(self, device_id, derivation, xtype, wizard):
                devmgr = self.device_manager()
                client = devmgr.client_by_id(device_id)
                client.handler = wizard
       -        xpub = client.get_xpub(derivation)
       +        xpub = client.get_xpub(derivation, xtype)
                client.used()
                return xpub