bitceptron_retriever/
path_pairs.rs1use std::str::FromStr;
2
3use bitcoin::{
4 bip32::DerivationPath, key::Secp256k1, secp256k1::SecretKey, Amount, BlockHash, ScriptBuf, Txid,
5};
6use bitcoincore_rpc::json::{ScanTxOutRequest, ScanTxOutResult, Utxo};
7use miniscript::{bitcoin::secp256k1::PublicKey, Descriptor};
8use tracing::info;
9use zeroize::{Zeroize, ZeroizeOnDrop};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct PathScriptPubKeyBytesPair(DerivationPath, Vec<u8>);
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct PathDescriptorPair(pub(crate) DerivationPath, pub(crate) Descriptor<PublicKey>);
16
17impl PathDescriptorPair {
18 pub fn new(path: DerivationPath, descriptor: Descriptor<PublicKey>) -> Self {
19 PathDescriptorPair(path, descriptor)
20 }
21
22 pub fn to_path_scan_request_descriptor_trio(&self) -> PathScanRequestDescriptorTrio {
23 let scan_request = ScanTxOutRequest::Single(self.1.to_string());
24 PathScanRequestDescriptorTrio(self.0.clone(), scan_request, self.1.clone())
25 }
26}
27
28impl Zeroize for PathDescriptorPair {
29 fn zeroize(&mut self) {
30 let paths = vec!["0".to_string(); self.0.len()].join::<&str>("/");
31 self.0 = DerivationPath::from_str(format!("m/{}", paths).as_str()).unwrap();
32 self.1 = Descriptor::new_pkh(
33 SecretKey::from_slice(&[0u8; 32])
34 .unwrap()
35 .public_key(&Secp256k1::new()),
36 )
37 .unwrap();
38 }
39}
40
41impl ZeroizeOnDrop for PathDescriptorPair {}
42
43#[derive(Debug, Clone, PartialEq, Eq)]
44pub struct PathScanRequestDescriptorTrio(
45 pub(crate) DerivationPath,
46 pub(crate) ScanTxOutRequest,
47 pub(crate) Descriptor<PublicKey>,
48);
49
50impl PathScanRequestDescriptorTrio {
51 pub fn new(
52 path: DerivationPath,
53 scan_request: ScanTxOutRequest,
54 descriptor: Descriptor<PublicKey>,
55 ) -> Self {
56 PathScanRequestDescriptorTrio(path, scan_request, descriptor)
57 }
58
59 pub fn from_path_descriptor_pair(path_descriptor_pair: PathDescriptorPair) -> Self {
60 let scan_request = ScanTxOutRequest::Single(path_descriptor_pair.1.to_string());
61 PathScanRequestDescriptorTrio(path_descriptor_pair.0, scan_request, path_descriptor_pair.1)
62 }
63}
64
65impl Zeroize for PathScanRequestDescriptorTrio {
66 fn zeroize(&mut self) {
67 let paths = vec!["0".to_string(); self.0.len()].join::<&str>("/");
68 self.0 = DerivationPath::from_str(format!("m/{}", paths).as_str()).unwrap();
69 self.1 = ScanTxOutRequest::Single("00000000000000000".to_string());
70 }
71}
72
73impl ZeroizeOnDrop for PathScanRequestDescriptorTrio {}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub struct PathScanResultDescriptorTrio(
77 pub DerivationPath,
78 pub ScanTxOutResult,
79 pub Descriptor<PublicKey>,
80);
81
82impl PathScanResultDescriptorTrio {
83 pub fn new(
84 path: DerivationPath,
85 scan_result: ScanTxOutResult,
86 descriptor: Descriptor<PublicKey>,
87 ) -> Self {
88 PathScanResultDescriptorTrio(path, scan_result, descriptor)
89 }
90
91 pub fn get_derivation_path(&self) -> DerivationPath {
92 self.0.clone()
93 }
94
95 pub fn get_scan_result(&self) -> ScanTxOutResult {
96 self.1.clone()
97 }
98
99 pub fn get_descriptor(&self) -> Descriptor<PublicKey> {
100 self.2.clone()
101 }
102}
103
104impl Zeroize for PathScanResultDescriptorTrio {
105 fn zeroize(&mut self) {
106 info!("Zeroizing path-scan result pairs initialized.");
107 let paths = vec!["0".to_string(); self.0.len()].join::<&str>("/");
108 self.0 = DerivationPath::from_str(format!("m/{}", paths).as_str()).unwrap();
109 self.1 = ScanTxOutResult {
110 success: Some(false),
111 tx_outs: Some(42),
112 height: Some(5326),
113 best_block_hash: Some(
114 BlockHash::from_str(
115 "00000000000000000002ac885fab3cd598f5ae4092fc92b3d4c7096ef0f0caae",
116 )
117 .unwrap(),
118 ),
119 unspents: vec![Utxo {
120 txid: Txid::from_str(
121 "f3aa99937337582a105c90e0595847177d8ab99d50201e318634a5d2db4f9d85",
122 )
123 .unwrap(),
124 vout: 21,
125 script_pub_key: ScriptBuf::from_hex(
126 "a91442402a28dd61f2718a4b27ae72a4791d5bbdade787",
127 )
128 .unwrap(),
129 descriptor: "none".to_string(),
130 amount: Amount::from_sat(2100000000000000),
131 height: 42,
132 }],
133 total_amount: Amount::from_sat(2100000000000000),
134 };
135 info!("Zeroizing path-scan result pairs finished.");
136 }
137}
138
139impl ZeroizeOnDrop for PathScanResultDescriptorTrio {}