1use std::{fs::create_dir_all, sync::Arc};
20
21use smol::lock::RwLock;
22use url::Url;
23
24use darkfi::{system::ExecutorPtr, util::path::expand_path, Error, Result};
25use darkfi_sdk::crypto::keypair::Network;
26
27pub mod error;
29use error::{WalletDbError, WalletDbResult};
30
31pub mod common;
33
34pub mod rpc;
36use rpc::DarkfidRpcClient;
37
38pub mod transfer;
40
41pub mod swap;
43
44pub mod token;
46
47pub mod cli_util;
49
50pub mod interactive;
52
53pub mod money;
55
56pub mod dao;
58
59pub mod deploy;
61
62pub mod txs_history;
64
65pub mod scanned_blocks;
67
68pub mod walletdb;
70use walletdb::{WalletDb, WalletPtr};
71
72pub mod cache;
74use cache::Cache;
75
76pub type DrkPtr = Arc<RwLock<Drk>>;
78
79pub struct Drk {
81 pub network: Network,
83 pub cache: Cache,
85 pub wallet: WalletPtr,
87 pub rpc_client: Option<RwLock<DarkfidRpcClient>>,
89 pub fun: bool,
91}
92
93impl Drk {
94 pub async fn new(
95 network: Network,
96 cache_path: String,
97 wallet_path: String,
98 wallet_pass: String,
99 endpoint: Option<Url>,
100 ex: &ExecutorPtr,
101 fun: bool,
102 ) -> Result<Self> {
103 let db_path = expand_path(&cache_path)?;
105 let sled_db = sled_overlay::sled::open(&db_path)?;
106 let Ok(cache) = Cache::new(&sled_db) else {
107 return Err(Error::DatabaseError(format!("{}", WalletDbError::InitializationFailed)));
108 };
109
110 let wallet_path = expand_path(&wallet_path)?;
112 if !wallet_path.exists() {
113 if let Some(parent) = wallet_path.parent() {
114 create_dir_all(parent)?;
115 }
116 }
117 let Ok(wallet) = WalletDb::new(Some(wallet_path), Some(&wallet_pass)) else {
118 return Err(Error::DatabaseError(format!("{}", WalletDbError::InitializationFailed)));
119 };
120
121 let rpc_client = if let Some(endpoint) = endpoint {
123 Some(RwLock::new(DarkfidRpcClient::new(endpoint, ex.clone()).await))
124 } else {
125 None
126 };
127
128 Ok(Self { network, cache, wallet, rpc_client, fun })
129 }
130
131 pub fn into_ptr(self) -> DrkPtr {
132 Arc::new(RwLock::new(self))
133 }
134
135 pub async fn initialize_wallet(&self) -> WalletDbResult<()> {
137 self.wallet.exec_batch_sql(include_str!("../wallet.sql"))?;
139
140 Ok(())
141 }
142
143 pub fn reset(&self, output: &mut Vec<String>) -> WalletDbResult<()> {
145 output.push(String::from("Resetting full wallet state"));
146 self.reset_scanned_blocks(output)?;
147 self.reset_money_tree(output)?;
148 self.reset_money_smt(output)?;
149 self.reset_money_coins(output)?;
150 self.reset_mint_authorities(output)?;
151 self.reset_dao_trees(output)?;
152 self.reset_daos(output)?;
153 self.reset_dao_proposals(output)?;
154 self.reset_dao_votes(output)?;
155 self.reset_deploy_authorities(output)?;
156 self.reset_deploy_history(output)?;
157 self.reset_tx_history(output)?;
158 output.push(String::from("Successfully reset full wallet state"));
159 Ok(())
160 }
161}