diff --git a/README.md b/README.md index fb6562c..363e20d 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ A minimalistic implementation of [BIP 32](https://github.com/bitcoin/bips/blob/m # You can also use "h" or "H" to signal for hardened derivation >>> bip32.get_xpub_from_path("m/0h/42") 'xpub69uEaVYoN1mZyMon8qwRP41YjYyevp3YxJ68ymBGV7qmXZ9rsbMy9kBZnLNPg3TLjKd2EnMw5BtUFQCGrTVDjQok859LowMV2SEooseLCt1' +>>> bip32.get_key_origin_xkey_from_path("xpub", "m/0h/42") +'[b2b1f0cf/0h/42]xpub69uEaVYoN1mZyMon8qwRP41YjYyevp3YxJ68ymBGV7qmXZ9rsbMy9kBZnLNPg3TLjKd2EnMw5BtUFQCGrTVDjQok859LowMV2SEooseLCt1' # You can use pubkey-only derivation >>> bip32 = BIP32.from_xpub("xpub6AKC3u8URPxDojLnFtNdEPFkNsXxHfgRhySvVfEJy9SVvQAn14XQjAoFY48mpjgutJNfA54GbYYRpR26tFEJHTHhfiiZZ2wdBBzydVp12yU") >>> bip32.get_xpub_from_path([42, 43]) diff --git a/bip32/bip32.py b/bip32/bip32.py index e8df204..3429a96 100644 --- a/bip32/bip32.py +++ b/bip32/bip32.py @@ -89,8 +89,6 @@ def __init__( ) if index != 0: raise InvalidInputError("Index must be 0 if depth is 0 (master xpub)") - if network not in ["main", "test"]: - raise InvalidInputError("Unknown network") self.chaincode = chaincode self.privkey = privkey @@ -179,7 +177,7 @@ def get_pubkey_from_path(self, path): :param path: A list of integers (index of each depth) or a string with m/x/x'/x notation. (e.g. m/0'/1/2'/2 or m/0H/1/2H/2). - :return: privkey (bytes) + :return: pubkey (bytes) """ return self.get_extended_pubkey_from_path(path)[1] @@ -198,7 +196,7 @@ def get_xpriv_from_path(self, path): if len(path) == 0: return self.get_xpriv() - elif len(path) == 1: + if len(path) == 1: parent_pubkey = self.pubkey else: parent_pubkey = self.get_pubkey_from_path(path[:-1]) @@ -229,7 +227,7 @@ def get_xpub_from_path(self, path): if len(path) == 0: return self.get_xpub() - elif len(path) == 1: + if len(path) == 1: parent_pubkey = self.pubkey else: parent_pubkey = self.get_pubkey_from_path(path[:-1]) @@ -245,6 +243,19 @@ def get_xpub_from_path(self, path): return b58encode_check(extended_key).decode() + def get_key_origin_xkey_from_path(self, key_type, path): + """Get encoded extended key with origin info from a derivation path. + :param key_type: 'xpub' for pubkeys or 'xpriv' for privkeys. + :param path: a string with m/x/x'/x notation. (e.g. m/0'/1/2'/2 + or m/0H/1/2H/2). + :return: BIP380 key origin followed by the encoded extended key as str + """ + assert key_type in ["xpub", "xpriv"] + if not isinstance(path, str): + raise InvalidInputError("'path' must be string") + key = getattr(self, f"get_{key_type}_from_path")(path) + return f"[{self.get_fingerprint().hex()}{path[1:]}]{key}" + def get_xpriv(self): """Get the base58 encoded extended private key.""" return b58encode_check(self.get_xpriv_bytes()).decode()