def fill_psbt(self, tx): for scope in tx.inputs + tx.outputs: # fill derivation paths wallet_key = b"\xfc\xca\x01" + self.fingerprint if wallet_key not in scope.unknown: continue der = scope.unknown[wallet_key] wallet_derivation = [] for i in range(len(der) // 4): idx = int.from_bytes(der[4 * i:4 * i + 4], 'little') wallet_derivation.append(idx) for arg in self.args: # check if it is DerivedKey try: fingerprint = arg.fingerprint except: continue pub = arg.key.derive(wallet_derivation).key scope.bip32_derivations[pub] = DerivationPath( fingerprint, arg.parent_derivation + wallet_derivation) # fill script if len(wallet_derivation) != 2: raise ValueError( "Only 2-index derivation is allowed: change/index") if wallet_derivation[0] > 1: raise ValueError("Change index can be only 0 or 1") args = self.get_derived_args(wallet_derivation[1], wallet_derivation[0]) scope.witness_script = self.witness_script(args=args) scope.redeem_script = self.redeem_script(args=args)
def find_wallet_from_address(self, addr: str, paths=None, index=None): if index is not None: for w in self.wallets: a, _ = w.get_address(index, self.network) print(a) if a == addr: return w, (0, index) if paths is not None: # we can detect the wallet from just one path p = paths[0] if not p.startswith("m"): fingerprint = unhexlify(p[:8]) derivation = bip32.parse_path("m" + p[8:]) else: fingerprint = self.keystore.fingerprint derivation = bip32.parse_path(p) derivation_path = DerivationPath(fingerprint, derivation) for w in self.wallets: der = w.descriptor.check_derivation(derivation_path) if der is not None: branch_idx, idx = der a, _ = w.get_address(idx, self.network, branch_idx) if a == addr: return w, (branch_idx, idx) raise WalletError("Can't find wallet owning address %s" % addr)
def fill_psbt(self, psbt, fingerprint): """Fills derivation paths in inputs""" for scope in psbt.inputs: # fill derivation paths wallet_key = b"\xfc\xca\x01" + self.fingerprint if wallet_key not in scope.unknown: continue der = scope.unknown[wallet_key] wallet_derivation = [] for i in range(len(der) // 4): idx = int.from_bytes(der[4 * i:4 * i + 4], 'little') wallet_derivation.append(idx) # find keys with our fingerprint for key in self.script.get_keys(): if key.fingerprint == fingerprint: pub = key.derive(wallet_derivation).get_public_key() # fill our derivations scope.bip32_derivations[pub] = DerivationPath( fingerprint, key.derivation + wallet_derivation) # fill script scope.witness_script = self.script.witness_script( wallet_derivation) if self.wrapped: scope.redeem_script = self.script.scriptpubkey( wallet_derivation) return psbt
def fill_scope(self, scope, fingerprint): """Fills derivation paths in inputs""" if not self.owns(scope): return False der = self.get_derivation(scope.bip32_derivations) if der is None: return False idx, branch_idx = der desc = self.descriptor.derive(idx, branch_index=branch_idx) # find keys with our fingerprint for key in desc.keys: if key.fingerprint == fingerprint: pub = key.get_public_key() # fill our derivations scope.bip32_derivations[pub] = DerivationPath( fingerprint, key.derivation) # fill script scope.witness_script = desc.witness_script() scope.redeem_script = desc.redeem_script() return True