electrum

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

commit f36024e216f96ec2c73aaa67e45c2751378bde03
parent 1ecfcea8dcfe37df4c6dceeaf071f19c7660c44b
Author: ThomasV <thomasv@electrum.org>
Date:   Tue, 31 Oct 2017 11:45:25 +0100

hardware wallets: pass xtype to get_xpub

Diffstat:
Mlib/base_wizard.py | 3++-
Mlib/bitcoin.py | 1-
Mlib/plugins.py | 5+++--
Mlib/wallet.py | 4++--
Mplugins/digitalbitbox/digitalbitbox.py | 9+++++----
Mplugins/ledger/ledger.py | 24+++++++++---------------
Mplugins/trezor/clientbase.py | 8++------
Mplugins/trezor/plugin.py | 6+++---
8 files changed, 26 insertions(+), 34 deletions(-)

diff --git a/lib/base_wizard.py b/lib/base_wizard.py @@ -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 diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -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) diff --git a/lib/plugins.py b/lib/plugins.py @@ -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() @@ -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 diff --git a/lib/wallet.py b/lib/wallet.py @@ -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 @@ -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): diff --git a/plugins/digitalbitbox/digitalbitbox.py b/plugins/digitalbitbox/digitalbitbox.py @@ -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'] @@ -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): @@ -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 diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py @@ -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 @@ -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:] @@ -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): diff --git a/plugins/trezor/clientbase.py b/plugins/trezor/clientbase.py @@ -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") diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py @@ -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