rustywallet_taproot/
lib.rs1pub mod control_block;
63pub mod error;
64pub mod schnorr;
65pub mod sighash;
66pub mod tagged_hash;
67pub mod taproot;
68pub mod taptree;
69pub mod tweak;
70pub mod xonly;
71
72pub use control_block::ControlBlock;
74pub use error::TaprootError;
75pub use schnorr::SchnorrSignature;
76pub use sighash::{taproot_key_path_sighash, taproot_script_path_sighash, TaprootSighashType};
77pub use tagged_hash::{tagged_hash, TapLeafHash, TapNodeHash, TapTweakHash};
78pub use taproot::{create_address, is_p2tr_address, parse_address, Network, TaprootOutput};
79pub use taptree::{LeafVersion, TapLeaf, TapNode, TapTree, TapTreeBuilder};
80pub use tweak::{compute_output_key, compute_tweak, tweak_private_key, tweak_public_key};
81pub use xonly::{Parity, XOnlyPublicKey};
82
83pub mod prelude {
85 pub use crate::control_block::ControlBlock;
86 pub use crate::error::TaprootError;
87 pub use crate::schnorr::SchnorrSignature;
88 pub use crate::sighash::TaprootSighashType;
89 pub use crate::tagged_hash::{TapLeafHash, TapNodeHash, TapTweakHash};
90 pub use crate::taproot::{Network, TaprootOutput};
91 pub use crate::taptree::{LeafVersion, TapLeaf, TapTree, TapTreeBuilder};
92 pub use crate::xonly::{Parity, XOnlyPublicKey};
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 use secp256k1::{Secp256k1, SecretKey};
99
100 fn get_test_keypair() -> ([u8; 32], XOnlyPublicKey) {
101 let secp = Secp256k1::new();
102 let secret = [1u8; 32];
103 let sk = SecretKey::from_slice(&secret).unwrap();
104 let pk = sk.public_key(&secp);
105 let (xonly, _) = pk.x_only_public_key();
106 (secret, XOnlyPublicKey::from_inner(xonly))
107 }
108
109 #[test]
110 fn test_key_path_workflow() {
111 let (secret, internal_key) = get_test_keypair();
112
113 let output = TaprootOutput::key_path_only(internal_key).unwrap();
115
116 let address = output.address(Network::Mainnet).unwrap();
118 assert!(address.starts_with("bc1p"));
119
120 let parsed = parse_address(&address).unwrap();
122 assert_eq!(output.output_key, parsed);
123 }
124
125 #[test]
126 fn test_script_path_workflow() {
127 let (_, internal_key) = get_test_keypair();
128
129 let tree = TapTreeBuilder::new()
131 .add_leaf(1, vec![0x51])
132 .add_leaf(1, vec![0x52])
133 .build()
134 .unwrap();
135
136 let output = TaprootOutput::with_script_tree(internal_key, &tree).unwrap();
138 assert!(!output.is_key_path_only());
139
140 let leaf = TapLeaf::new(vec![0x51]);
142 let cb = ControlBlock::for_leaf(&tree, &leaf, internal_key, output.parity).unwrap();
143
144 assert!(cb.verify(&output.output_key, &leaf.script).unwrap());
146 }
147
148 #[test]
149 fn test_schnorr_signing() {
150 let (secret, pubkey) = get_test_keypair();
151 let message = [0x42u8; 32];
152
153 let sig = SchnorrSignature::sign(&message, &secret).unwrap();
154 assert!(sig.verify(&message, &pubkey));
155 }
156}