Skip to content

Commit b952472

Browse files
finalize_psbt.py
1 parent d29e3bc commit b952472

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

examples/finalize_psbt.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Finalize a PSBT (Partially Signed Bitcoin Transaction) to produce a broadcastable Bitcoin transaction.
4+
5+
This script serves as the finalizer step (as defined in BIP-174), assembling signatures and scripts
6+
into a complete transaction ready for broadcast.
7+
8+
Features:
9+
- Loads a base64-encoded PSBT from string or file
10+
- Finalizes all inputs by constructing scriptSig/scriptWitness
11+
- Optionally validates that all inputs are fully signed before finalization
12+
- Outputs the raw hex-encoded Bitcoin transaction
13+
14+
Usage:
15+
python finalize_psbt.py <psbt_base64_string>
16+
python finalize_psbt.py --file <psbt_file.txt>
17+
python finalize_psbt.py --file <psbt_file.txt> --validate
18+
19+
Arguments:
20+
<psbt_base64_string> PSBT data as a base64-encoded string
21+
--file <psbt_file.txt> Load PSBT from a file
22+
--validate (Optional) Enforce validation before finalizing
23+
24+
Returns:
25+
Hex-encoded, fully signed Bitcoin transaction ready for broadcast
26+
"""
27+
28+
29+
import argparse
30+
import base64
31+
import sys
32+
from bitcoinutils.setup import setup
33+
from bitcoinutils.psbt import PSBT
34+
35+
36+
def main():
37+
"""
38+
Main function for PSBT finalization.
39+
40+
Usage:
41+
python finalize_psbt.py <psbt_base64_string>
42+
python finalize_psbt.py --file <psbt_file.txt>
43+
python finalize_psbt.py --file <psbt_file.txt> --validate
44+
"""
45+
parser = argparse.ArgumentParser(description='Finalize a PSBT and create a transaction.')
46+
parser.add_argument('psbt', nargs='?', help='Base64-encoded PSBT string')
47+
parser.add_argument('--file', help='Text file containing base64 PSBT')
48+
parser.add_argument('--validate', action='store_true', help='Validate finalized transaction')
49+
parser.add_argument('--network', choices=['mainnet', 'testnet'], default='testnet',
50+
help='Bitcoin network (default: testnet)')
51+
52+
args = parser.parse_args()
53+
54+
# Setup the library for specified network
55+
setup(args.network)
56+
57+
try:
58+
# Load PSBT from input
59+
if args.file:
60+
with open(args.file, 'r') as f:
61+
psbt_b64 = f.read().strip()
62+
elif args.psbt:
63+
psbt_b64 = args.psbt
64+
else:
65+
print("Error: Provide either base64 string or --file option.")
66+
print("Use --help for usage information.")
67+
return 1
68+
69+
# Create PSBT object
70+
psbt = PSBT.from_base64(psbt_b64)
71+
72+
# Finalize the PSBT
73+
if args.validate:
74+
final_tx, validation = psbt.finalize(validate=True)
75+
76+
print("Finalized Transaction (Hex):")
77+
print(final_tx.serialize())
78+
79+
print("\nValidation Report:")
80+
print(f"Valid: {validation['valid']}")
81+
print(f"Transaction ID: {validation['txid']}")
82+
print(f"Size: {validation['size']} bytes")
83+
print(f"Virtual Size: {validation['vsize']} vbytes")
84+
85+
if validation['errors']:
86+
print("Errors:")
87+
for error in validation['errors']:
88+
print(f" - {error}")
89+
90+
if validation['warnings']:
91+
print("Warnings:")
92+
for warning in validation['warnings']:
93+
print(f" - {warning}")
94+
95+
else:
96+
final_tx = psbt.finalize(validate=False)
97+
print("Finalized Transaction (Hex):")
98+
print(final_tx.serialize())
99+
100+
print(f"\nTransaction ready to broadcast!")
101+
print(f"Use 'bitcoin-cli sendrawtransaction {final_tx.serialize()}' to broadcast")
102+
103+
return 0
104+
105+
except Exception as e:
106+
print(f"Error: {str(e)}")
107+
return 1
108+
109+
110+
if __name__ == "__main__":
111+
sys.exit(main())

0 commit comments

Comments
 (0)