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:
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'/"))