diff --git a/docs/api/transaction.md b/docs/api/transaction.md index 55ca5a3..c2ec3cf 100644 --- a/docs/api/transaction.md +++ b/docs/api/transaction.md @@ -305,7 +305,7 @@ TransactionInput(txid, vout, script_sig=None, sequence=0xFFFFFFFF, witness=None) - `txid: bytes` - `32` bytes, txid of the transaction this input is spending. - `vout: int` - index of the output this input is spending. - `script_sig: script.Script` - input script sig, if `None` (default) - it will create an empty script sig. -- `sequence = 0xFFFFFFFF` - sequence number. For Replace-by-fee set it to lower value for example `0xfffffffe`. Also used by timelocked transaction, see [BIP-68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki). +- `sequence = 0xFFFFFFFF` - sequence number. For Replace-by-fee set it to lower value for example `0xfffffffd`. Also used by timelocked transaction, see [BIP-68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki). - `witness: script.Witness` - input witness, if `None` (default) - set to empty witness. Serialization and parsing is done as usual - `from_string(hex)`, `to_string()`, `parse(bytes)`, `serialize()`, `read_from(stream)`, `write_to(stream)`. diff --git a/src/embit/psbt.py b/src/embit/psbt.py index 7b27114..69ca98b 100644 --- a/src/embit/psbt.py +++ b/src/embit/psbt.py @@ -679,8 +679,27 @@ class PSBT(EmbitBase): so if PSBT is asking to sign with a different sighash this function won't sign. If you want to sign with sighashes provided in the PSBT - set sighash=None. """ + # check if it's a descriptor + if hasattr(root, "keys"): + counter = 0 + for k in root.keys: + if hasattr(k, "is_private") and k.is_private: + counter += self.sign_with(k, sighash) + return counter + # if WIF - fingerprint is None - fingerprint = None if not hasattr(root, "child") else root.child(0).fingerprint + fingerprint = None + # if descriptor key + if hasattr(root, "origin"): + if not root.is_private: # pubkey can't sign + return 0 + if root.is_extended: # use fingerprint only for HDKey + fingerprint = root.fingerprint + else: + root = root.key # WIF key + # if HDKey + if not fingerprint and hasattr(root, "my_fingerprint"): + fingerprint = root.my_fingerprint if not fingerprint: pub = root.get_public_key() sec = pub.sec() @@ -726,7 +745,16 @@ class PSBT(EmbitBase): for pub in inp.bip32_derivations: # check if it is root key if inp.bip32_derivations[pub].fingerprint == fingerprint: - hdkey = root.derive(inp.bip32_derivations[pub].derivation) + der = inp.bip32_derivations[pub].derivation + if hasattr(root, "origin"): + # for descriptor key remove origin part + if root.origin: + if root.origin.derivation != der[:len(root.origin.derivation)]: + continue + der = der[len(root.origin.derivation):] + hdkey = root.key.derive(der) + else: + hdkey = root.derive(der) mypub = hdkey.key.get_public_key() if mypub != pub: raise PSBTError("Derivation path doesn't look right") @@ -755,7 +783,16 @@ class PSBT(EmbitBase): for pub in inp.bip32_derivations: # check if it is root key if inp.bip32_derivations[pub].fingerprint == fingerprint: - hdkey = root.derive(inp.bip32_derivations[pub].derivation) + der = inp.bip32_derivations[pub].derivation + if hasattr(root, "origin"): + # for descriptor key remove origin part + if root.origin: + if root.origin.derivation != der[:len(root.origin.derivation)]: + continue + der = der[len(root.origin.derivation):] + hdkey = root.key.derive(der) + else: + hdkey = root.derive(der) mypub = hdkey.key.get_public_key() if mypub != pub: raise PSBTError("Derivation path doesn't look right")