Skip to content

Commit 9f48e21

Browse files
sign_psbt.py
1 parent 3cc1586 commit 9f48e21

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

examples/sign_psbt.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Copyright (C) 2025 The python-bitcoin-utils developers
2+
#
3+
# This file is part of python-bitcoin-utils
4+
#
5+
# It is subject to the license terms in the LICENSE file found in the top-level
6+
# directory of this distribution.
7+
#
8+
# No part of python-bitcoin-utils, including this file, may be copied,
9+
# modified, propagated, or distributed except according to the terms contained
10+
# in the LICENSE file.
11+
12+
"""
13+
Sign a specific input of a PSBT (Partially Signed Bitcoin Transaction) using a WIF private key.
14+
15+
This script allows targeted signing of one input in a PSBT, which is useful for multisig setups,
16+
hardware wallet integrations, or step-by-step signing processes.
17+
18+
Features:
19+
- Loads a PSBT from a base64-encoded string
20+
- Signs a specified input using a provided WIF-formatted private key
21+
- Supports multiple script types: P2PKH, P2SH, P2WPKH, P2WSH, P2TR
22+
- Allows optional SIGHASH type customization (default: SIGHASH_ALL)
23+
24+
Usage:
25+
python sign_psbt.py <psbt_base64> <private_key_wif> <input_index> [sighash_type]
26+
27+
Arguments:
28+
psbt_base64 The PSBT in base64 encoding
29+
private_key_wif The private key in Wallet Import Format (WIF)
30+
input_index Index of the input to sign (0-based)
31+
sighash_type (Optional) Bitcoin SIGHASH flag (e.g., SIGHASH_ALL, SIGHASH_SINGLE)
32+
33+
Returns:
34+
Updated PSBT with the input partially signed and printed as base64
35+
"""
36+
37+
38+
import sys
39+
from bitcoinutils.setup import setup
40+
from bitcoinutils.keys import PrivateKey
41+
from bitcoinutils.psbt import PSBT
42+
from bitcoinutils.constants import SIGHASH_ALL
43+
44+
45+
def main():
46+
"""Main function for signing PSBT example."""
47+
# Always call setup() first
48+
setup('testnet')
49+
50+
# Parse command line arguments
51+
if len(sys.argv) < 4:
52+
print("Usage: python sign_psbt.py <psbt_base64> <private_key_wif> <input_index> [sighash_type]")
53+
print("\nExample:")
54+
print("python sign_psbt.py <psbt> cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo 0")
55+
sys.exit(1)
56+
57+
psbt_base64 = sys.argv[1]
58+
private_key_wif = sys.argv[2]
59+
input_index = int(sys.argv[3])
60+
sighash_type = int(sys.argv[4]) if len(sys.argv) > 4 else SIGHASH_ALL
61+
62+
try:
63+
# Load PSBT from base64
64+
psbt = PSBT.from_base64(psbt_base64)
65+
66+
# Load private key
67+
private_key = PrivateKey.from_wif(private_key_wif)
68+
69+
# Sign the specified input
70+
success = psbt.sign_input(input_index, private_key, sighash_type)
71+
72+
if success:
73+
# Output the updated PSBT
74+
print(psbt.to_base64())
75+
else:
76+
print("Failed to sign input", file=sys.stderr)
77+
sys.exit(1)
78+
79+
except Exception as e:
80+
print(f"Error: {str(e)}", file=sys.stderr)
81+
sys.exit(1)
82+
83+
84+
if __name__ == "__main__":
85+
main()

0 commit comments

Comments
 (0)