electrum

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

commit b4b1de088ab88fe0e01b9f19ff48da9d71eac334
parent 52a4810752c37312aeb7cb4739b5462dfdde2c58
Author: SomberNight <somber.night@protonmail.com>
Date:   Tue, 14 Aug 2018 18:19:16 +0200

move TrezorClient.expand_path to bitcoin.py

and allow its input to end with a '/' slash

Diffstat:
Melectrum/base_wizard.py | 1+
Melectrum/bitcoin.py | 20+++++++++++++++++++-
Melectrum/plugins/keepkey/clientbase.py | 18++----------------
Melectrum/plugins/safe_t/clientbase.py | 18++----------------
Melectrum/plugins/trezor/clientbase.py | 18++----------------
Melectrum/tests/test_bitcoin.py | 7++++++-
6 files changed, 32 insertions(+), 50 deletions(-)

diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py @@ -346,6 +346,7 @@ class BaseWizard(object): except ScriptTypeNotSupported: raise # this is handled in derivation_dialog except BaseException as e: + traceback.print_exc(file=sys.stderr) self.show_error(e) return d = { diff --git a/electrum/bitcoin.py b/electrum/bitcoin.py @@ -24,7 +24,7 @@ # SOFTWARE. import hashlib -import hmac +from typing import List from .util import bfh, bh2u, BitcoinException, print_error, assert_bytes, to_bytes, inv_dict from . import version @@ -708,6 +708,24 @@ def bip32_derivation(s): i = int(n[:-1]) + BIP32_PRIME if n[-1] == "'" else int(n) yield i +def convert_bip32_path_to_list_of_uint32(n: str) -> List[int]: + """Convert bip32 path to list of uint32 integers with prime flags + m/0/-1/1' -> [0, 0x80000001, 0x80000001] + + based on code in trezorlib + """ + path = [] + for x in n.split('/')[1:]: + if x == '': continue + prime = 0 + if x.endswith("'"): + x = x.replace('\'', '') + prime = BIP32_PRIME + if x.startswith('-'): + prime = BIP32_PRIME + path.append(abs(int(x)) | prime) + return path + def is_bip32_derivation(x): try: [ i for i in bip32_derivation(x)] diff --git a/electrum/plugins/keepkey/clientbase.py b/electrum/plugins/keepkey/clientbase.py @@ -4,7 +4,7 @@ from struct import pack from electrum.i18n import _ from electrum.util import PrintError, UserCancelled from electrum.keystore import bip39_normalize_passphrase -from electrum.bitcoin import serialize_xpub +from electrum.bitcoin import serialize_xpub, convert_bip32_path_to_list_of_uint32 class GuiMixin(object): @@ -141,21 +141,7 @@ class KeepKeyClientBase(GuiMixin, PrintError): @staticmethod def expand_path(n): - '''Convert bip32 path to list of uint32 integers with prime flags - 0/-1/1' -> [0, 0x80000001, 0x80000001]''' - # This code is similar to code in trezorlib where it unfortunately - # is not declared as a staticmethod. Our n has an extra element. - PRIME_DERIVATION_FLAG = 0x80000000 - path = [] - for x in n.split('/')[1:]: - prime = 0 - if x.endswith("'"): - x = x.replace('\'', '') - prime = PRIME_DERIVATION_FLAG - if x.startswith('-'): - prime = PRIME_DERIVATION_FLAG - path.append(abs(int(x)) | prime) - return path + return convert_bip32_path_to_list_of_uint32(n) def cancel(self): '''Provided here as in keepkeylib but not trezorlib.''' diff --git a/electrum/plugins/safe_t/clientbase.py b/electrum/plugins/safe_t/clientbase.py @@ -4,7 +4,7 @@ from struct import pack from electrum.i18n import _ from electrum.util import PrintError, UserCancelled from electrum.keystore import bip39_normalize_passphrase -from electrum.bitcoin import serialize_xpub +from electrum.bitcoin import serialize_xpub, convert_bip32_path_to_list_of_uint32 class GuiMixin(object): @@ -143,21 +143,7 @@ class SafeTClientBase(GuiMixin, PrintError): @staticmethod def expand_path(n): - '''Convert bip32 path to list of uint32 integers with prime flags - 0/-1/1' -> [0, 0x80000001, 0x80000001]''' - # This code is similar to code in safetlib where it unfortunately - # is not declared as a staticmethod. Our n has an extra element. - PRIME_DERIVATION_FLAG = 0x80000000 - path = [] - for x in n.split('/')[1:]: - prime = 0 - if x.endswith("'"): - x = x.replace('\'', '') - prime = PRIME_DERIVATION_FLAG - if x.startswith('-'): - prime = PRIME_DERIVATION_FLAG - path.append(abs(int(x)) | prime) - return path + return convert_bip32_path_to_list_of_uint32(n) def cancel(self): '''Provided here as in keepkeylib but not safetlib.''' diff --git a/electrum/plugins/trezor/clientbase.py b/electrum/plugins/trezor/clientbase.py @@ -4,7 +4,7 @@ from struct import pack from electrum.i18n import _ from electrum.util import PrintError, UserCancelled from electrum.keystore import bip39_normalize_passphrase -from electrum.bitcoin import serialize_xpub +from electrum.bitcoin import serialize_xpub, convert_bip32_path_to_list_of_uint32 class GuiMixin(object): @@ -152,21 +152,7 @@ class TrezorClientBase(GuiMixin, PrintError): @staticmethod def expand_path(n): - '''Convert bip32 path to list of uint32 integers with prime flags - 0/-1/1' -> [0, 0x80000001, 0x80000001]''' - # This code is similar to code in trezorlib where it unfortunately - # is not declared as a staticmethod. Our n has an extra element. - PRIME_DERIVATION_FLAG = 0x80000000 - path = [] - for x in n.split('/')[1:]: - prime = 0 - if x.endswith("'"): - x = x.replace('\'', '') - prime = PRIME_DERIVATION_FLAG - if x.startswith('-'): - prime = PRIME_DERIVATION_FLAG - path.append(abs(int(x)) | prime) - return path + return convert_bip32_path_to_list_of_uint32(n) def cancel(self): '''Provided here as in keepkeylib but not trezorlib.''' diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py @@ -11,7 +11,7 @@ from electrum.bitcoin import ( deserialize_privkey, serialize_privkey, is_segwit_address, is_b58_address, address_to_scripthash, is_minikey, is_compressed, is_xpub, xpub_type, is_xprv, is_bip32_derivation, seed_type, EncodeBase58Check, - script_num_to_hex, push_script, add_number_to_script, int_to_hex) + script_num_to_hex, push_script, add_number_to_script, int_to_hex, convert_bip32_path_to_list_of_uint32) from electrum import ecc, crypto, constants from electrum.ecc import number_to_string, string_to_number from electrum.transaction import opcodes @@ -470,6 +470,11 @@ class Test_xprv_xpub(SequentialTestCase): self.assertFalse(is_bip32_derivation("")) self.assertFalse(is_bip32_derivation("m/q8462")) + def test_convert_bip32_path_to_list_of_uint32(self): + self.assertEqual([0, 0x80000001, 0x80000001], convert_bip32_path_to_list_of_uint32("m/0/-1/1'")) + self.assertEqual([], convert_bip32_path_to_list_of_uint32("m/")) + self.assertEqual([2147483692, 2147488889, 221], convert_bip32_path_to_list_of_uint32("m/44'/5241'/221")) + def test_xtype_from_derivation(self): self.assertEqual('standard', xtype_from_derivation("m/44'")) self.assertEqual('standard', xtype_from_derivation("m/44'/"))