1use config::Config;
2use getset::Getters;
3use serde::{Deserialize, Serialize};
4use tracing::info;
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7use crate::{
8 client::client_setting::ClientSetting,
9 covered_descriptors::CoveredDescriptors,
10 data::{
11 defaults::{
12 DEFAULT_BITCOINCORE_RPC_PORT, DEFAULT_BITCOINCORE_RPC_TIMEOUT_SECONDS,
13 DEFAULT_BITCOINCORE_RPC_URL, DEFAULT_EXPLORATION_DEPTH, DEFAULT_EXPLORATION_PATH,
14 DEFAULT_NETWORK, DEFAULT_SWEEP,
15 },
16 wallets_info::WalletsInfo,
17 },
18 error::RetrieverError,
19 explorer::explorer_setting::ExplorerSetting,
20};
21
22#[derive(Debug, Serialize, Deserialize, Getters, Clone)]
23#[get = "pub with_prefix"]
24pub struct RetrieverSetting {
25 bitcoincore_rpc_url: Option<String>,
26 bitcoincore_rpc_port: Option<String>,
27 bitcoincore_rpc_cookie_path: String,
29 bitcoincore_rpc_timeout_seconds: Option<u64>,
30 mnemonic: String,
32 passphrase: String,
34 base_derivation_paths: Option<Vec<String>>,
35 exploration_path: Option<String>,
36 selected_descriptors: Option<Vec<CoveredDescriptors>>,
37 sweep: Option<bool>,
38 exploration_depth: Option<u32>,
39 network: Option<bitcoin::Network>,
40 data_dir: String,
41}
42
43impl Zeroize for RetrieverSetting {
44 fn zeroize(&mut self) {
45 info!("Zeroizing retriever setting initialized.");
46 self.bitcoincore_rpc_url.zeroize();
47 self.bitcoincore_rpc_port.zeroize();
48 self.bitcoincore_rpc_cookie_path.zeroize();
49 self.bitcoincore_rpc_timeout_seconds.zeroize();
50 self.mnemonic.zeroize();
51 self.passphrase.zeroize();
52 self.base_derivation_paths.zeroize();
53 self.exploration_path.zeroize();
54 self.sweep.zeroize();
55 self.exploration_depth.zeroize();
56 self.network = Some(bitcoin::Network::Signet);
57 info!("Zeroizing retriever setting finished.");
58 }
59}
60
61impl ZeroizeOnDrop for RetrieverSetting {}
62
63impl RetrieverSetting {
64 pub fn new(
65 bitcoincore_rpc_url: Option<String>,
66 bitcoincore_rpc_port: Option<String>,
67 bitcoincore_rpc_cookie_path: String,
69 bitcoincore_rpc_timeout_seconds: Option<u64>,
70 mnemonic: String,
72 passphrase: String,
74 base_derivation_paths: Option<Vec<String>>,
75 exploration_path: Option<String>,
76 selected_descriptors: Option<Vec<CoveredDescriptors>>,
77 sweep: Option<bool>,
78 exploration_depth: Option<u32>,
79 network: Option<bitcoin::Network>,
80 data_dir: String,
81 ) -> Self {
82 RetrieverSetting {
83 bitcoincore_rpc_url,
84 bitcoincore_rpc_port,
85 bitcoincore_rpc_cookie_path,
86 bitcoincore_rpc_timeout_seconds,
87 mnemonic,
88 passphrase,
89 base_derivation_paths,
90 exploration_path,
91 selected_descriptors,
92 sweep,
93 exploration_depth,
94 network,
95 data_dir,
96 }
97 }
98
99 pub fn from_config_file(config_file_path: &str) -> Result<Self, RetrieverError> {
100 Ok(Config::builder()
101 .add_source(config::File::with_name(config_file_path))
102 .build()?
103 .try_deserialize::<RetrieverSetting>()?)
104 }
105
106 pub fn get_client_setting(&self) -> ClientSetting {
107 let rpc_url = match self.get_bitcoincore_rpc_url() {
108 Some(rpc_url) => rpc_url,
109 None => DEFAULT_BITCOINCORE_RPC_URL,
110 };
111 let rpc_port = match self.get_bitcoincore_rpc_port() {
112 Some(rpc_port) => rpc_port,
113 None => DEFAULT_BITCOINCORE_RPC_PORT,
114 };
115 let cookie_path = self.get_bitcoincore_rpc_cookie_path();
116 let timeout_seconds = match self.get_bitcoincore_rpc_timeout_seconds() {
117 Some(timeout_seconds) => *timeout_seconds,
118 None => DEFAULT_BITCOINCORE_RPC_TIMEOUT_SECONDS,
119 };
120 ClientSetting::new(rpc_url, rpc_port, cookie_path, timeout_seconds)
121 }
122
123 pub fn get_explorer_setting(&self) -> ExplorerSetting {
124 let mnemonic = self.get_mnemonic().to_owned();
125 let passphrase = self.get_passphrase().to_owned();
126 let base_derivation_paths = match self.get_base_derivation_paths() {
127 Some(base_derivation_paths) => base_derivation_paths.to_owned(),
128 None => WalletsInfo::get_all_unique_preset_wallet_base_paths().to_owned(),
129 };
130
131 let exploration_path = match self.get_exploration_path() {
132 Some(exploration_path) => exploration_path.to_owned(),
133 None => DEFAULT_EXPLORATION_PATH.to_string(),
134 };
135
136 let exploration_depth = match self.get_exploration_depth() {
137 Some(exploration_depth) => *exploration_depth,
138 None => DEFAULT_EXPLORATION_DEPTH,
139 };
140
141 let network = match self.get_network() {
142 Some(network) => *network,
143 None => DEFAULT_NETWORK,
144 };
145 let sweep = match self.get_sweep() {
146 Some(sweep) => *sweep,
147 None => DEFAULT_SWEEP,
148 };
149 ExplorerSetting::new(
150 mnemonic,
151 passphrase,
152 base_derivation_paths,
153 exploration_path,
154 exploration_depth,
155 network,
156 sweep,
157 )
158 }
159}