rustywallet_psbt/lib.rs
1//! # rustywallet-psbt
2//!
3//! PSBT (Partially Signed Bitcoin Transaction) implementation for Bitcoin wallet development.
4//!
5//! This crate implements BIP174 (PSBT v0) and BIP370 (PSBT v2) for hardware wallet
6//! interoperability and multi-party signing workflows.
7//!
8//! ## Features
9//!
10//! - Parse and create PSBTs
11//! - Sign PSBTs with private keys
12//! - Combine PSBTs from multiple signers
13//! - Finalize PSBTs and extract signed transactions
14//! - Support for P2PKH, P2WPKH, P2SH, P2WSH, and P2TR inputs
15//! - PSBT v2 (BIP370) support
16//!
17//! ## Example
18//!
19//! ```rust,no_run
20//! use rustywallet_psbt::{Psbt, PsbtError};
21//!
22//! // Parse PSBT from base64
23//! let psbt_base64 = "cHNidP8BAH...";
24//! let mut psbt = Psbt::from_base64(psbt_base64)?;
25//!
26//! // Sign with private key
27//! // let signed = psbt.sign(&private_key)?;
28//!
29//! // Finalize
30//! psbt.finalize()?;
31//!
32//! // Extract signed transaction
33//! let tx = psbt.extract_tx()?;
34//! # Ok::<(), PsbtError>(())
35//! ```
36//!
37//! ## BIP174 Roles
38//!
39//! This crate implements all BIP174 roles:
40//!
41//! - **Creator**: Create PSBT from unsigned transaction
42//! - **Updater**: Add UTXO info, scripts, derivation paths
43//! - **Signer**: Add partial signatures
44//! - **Combiner**: Merge PSBTs from multiple signers
45//! - **Finalizer**: Construct final scriptSig/witness
46//! - **Extractor**: Extract signed transaction
47
48pub mod error;
49pub mod global;
50pub mod input;
51pub mod output;
52pub mod psbt;
53pub mod serialize;
54pub mod types;
55
56mod combiner;
57mod finalizer;
58mod signer;
59
60// Re-exports
61pub use error::PsbtError;
62pub use global::GlobalMap;
63pub use input::{InputMap, TxOut, Witness};
64pub use output::OutputMap;
65pub use psbt::Psbt;
66pub use types::{KeySource, PsbtSighashType};
67
68/// Prelude module for convenient imports
69pub mod prelude {
70 pub use crate::error::PsbtError;
71 pub use crate::global::GlobalMap;
72 pub use crate::input::{InputMap, TxOut, Witness};
73 pub use crate::output::OutputMap;
74 pub use crate::psbt::Psbt;
75 pub use crate::types::{KeySource, PsbtSighashType};
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_psbt_magic() {
84 let magic = types::PSBT_MAGIC;
85 assert_eq!(magic, [0x70, 0x73, 0x62, 0x74, 0xff]);
86 assert_eq!(&magic[0..4], b"psbt");
87 }
88
89 #[test]
90 fn test_create_psbt() {
91 // Minimal unsigned transaction
92 let tx = vec![
93 0x02, 0x00, 0x00, 0x00, // version
94 0x00, // no inputs
95 0x00, // no outputs
96 0x00, 0x00, 0x00, 0x00, // locktime
97 ];
98
99 let psbt = Psbt::from_unsigned_tx(tx).unwrap();
100 assert_eq!(psbt.version(), 0);
101 assert_eq!(psbt.input_count(), 0);
102 assert_eq!(psbt.output_count(), 0);
103 }
104
105 #[test]
106 fn test_psbt_serialization() {
107 let tx = vec![
108 0x02, 0x00, 0x00, 0x00, // version
109 0x00, // no inputs
110 0x00, // no outputs
111 0x00, 0x00, 0x00, 0x00, // locktime
112 ];
113
114 let psbt = Psbt::from_unsigned_tx(tx).unwrap();
115 let bytes = psbt.to_bytes();
116
117 // Check magic
118 assert_eq!(&bytes[0..5], &types::PSBT_MAGIC);
119
120 // Roundtrip
121 let parsed = Psbt::from_bytes(&bytes).unwrap();
122 assert_eq!(psbt.to_bytes(), parsed.to_bytes());
123 }
124}