def gait_paths_from_seed(seed): """Get the paths for deriving the GreenAddress xpubs from a hex seed, rather than mnemonic This is an alternative derivation path used with hardware wallets where the mnemonic may not be available. It is based on a hardened public key derived from the backed up hw wallet seed. Returns two possible paths corresponding to two different client implementations. """ assert len(seed) == wally.BIP39_SEED_LEN_512 # Passing version=BIP32_VER_MAIN_PRIVATE here although it may be either MAIN or TEST # This version indicator only matters if you serialize the key version = wally.BIP32_VER_MAIN_PRIVATE root_key = wally.bip32_key_from_seed(seed, version, wally.BIP32_FLAG_SKIP_HASH) # path = m/18241' # 18241 = 0x4741 = 'GA' flags = wally.BIP32_FLAG_KEY_PUBLIC | wally.BIP32_FLAG_SKIP_HASH path = [gaconstants.HARDENED | 18241] derived_public_key = wally.bip32_key_from_parent_path(root_key, path, flags) chain_code = wally.bip32_key_get_chain_code(derived_public_key) pub_key = wally.bip32_key_get_pub_key(derived_public_key) # For historic reasons some old clients use a hexlified input path here - generate both path_input = chain_code + pub_key path_input_hex = bytearray(wally.hex_from_bytes(chain_code + pub_key), 'ascii') return [get_gait_path(path_input) for path_input in [path_input, path_input_hex]]
def derive_ga_xpub(gait_path, subaccount, network): """Derive a GreenAddress extended public key""" ga_root_key = get_ga_root_key(network) if subaccount is not None: branch = 3 ga_path = [branch] + gait_path + [subaccount] else: branch = 1 ga_path = [branch] + gait_path flags = wally.BIP32_FLAG_KEY_PUBLIC | wally.BIP32_FLAG_SKIP_HASH return wally.bip32_key_from_parent_path(ga_root_key, ga_path, flags)
def derive(self, path: List[int]): # TODO: investigate if it's worth to skip hash, for now remove so we # can use bip32 test vectors # flags |= wally.BIP32_FLAG_SKIP_HASH flags = self.bip32_flag try: derived = wally.bip32_key_from_parent_path(self.extkey, path, flags) except ValueError: raise InvalidBip32Path return self.__class__(derived)
def derive_hd_key(root, path, flags=0): return wally.bip32_key_from_parent_path(root, path, flags | wally.BIP32_FLAG_SKIP_HASH)
def derive_key(self, path: List[int]): if not path: return self.master_key else: return wally.bip32_key_from_parent_path(self.master_key, path, wally.BIP32_FLAG_KEY_PRIVATE)
def _derive(self, path, flags): derived = wally.bip32_key_from_parent_path( self.extkey, path, flags | wally.BIP32_FLAG_SKIP_HASH) return Bip32Key(derived)
# calculate master key master_key = wally.bip32_key_from_seed(seed, master_key_flags, wally.BIP32_FLAG_SKIP_HASH) if args.verbose > 1: print('::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::') print('Seed: {}'.format(seed.hex())) print('Mnemonic: {}'.format(mnemonic)) print('Master key: {}'.format(wally.bip32_key_to_base58(master_key, 0))) print('::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::') # derive a children found = False for x in range(0, args.children + 1): child = x if args.hardened == True: child = child + 0x80000000 derived = wally.bip32_key_from_parent_path(master_key, path + [child], wally.BIP32_FLAG_KEY_PRIVATE); if args.verbose > 1: print('Derivation: {}/{}{}'.format(args.derivation, x, hardened_notation)) if args.address == 'native_segwit': # calculate native segwit address native_segwit = wally.bip32_key_to_addr_segwit(derived, native_segwit_address_flags, 0); if args.verbose > 1: print('Native segwit address: {}'.format(native_segwit)) if pattern.match(native_segwit): found = True if args.address == 'nested_segwit': # calculate nested segwit address - base_58 nested_segwit = wally.bip32_key_to_address(derived, wally.WALLY_ADDRESS_TYPE_P2SH_P2WPKH, nested_segwit_address_flags); if args.verbose > 1: