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};
25
26pub mod error;
28use error::{WalletDbError, WalletDbResult};
29
30pub mod rpc;
32use rpc::DarkfidRpcClient;
33
34pub mod transfer;
36
37pub mod swap;
39
40pub mod token;
42
43pub mod cli_util;
45
46pub mod interactive;
48
49pub mod money;
51
52pub mod dao;
54
55pub mod deploy;
57
58pub mod txs_history;
60
61pub mod scanned_blocks;
63
64pub mod walletdb;
66use walletdb::{WalletDb, WalletPtr};
67
68pub mod cache;
70use cache::Cache;
71
72pub type DrkPtr = Arc<RwLock<Drk>>;
74
75pub struct Drk {
77 pub cache: Cache,
79 pub wallet: WalletPtr,
81 pub rpc_client: Option<RwLock<DarkfidRpcClient>>,
83 pub fun: bool,
85}
86
87impl Drk {
88 pub async fn new(
89 cache_path: String,
90 wallet_path: String,
91 wallet_pass: String,
92 endpoint: Option<Url>,
93 ex: &ExecutorPtr,
94 fun: bool,
95 ) -> Result<Self> {
96 let db_path = expand_path(&cache_path)?;
98 let sled_db = sled_overlay::sled::open(&db_path)?;
99 let Ok(cache) = Cache::new(&sled_db) else {
100 return Err(Error::DatabaseError(format!("{}", WalletDbError::InitializationFailed)));
101 };
102
103 let wallet_path = expand_path(&wallet_path)?;
105 if !wallet_path.exists() {
106 if let Some(parent) = wallet_path.parent() {
107 create_dir_all(parent)?;
108 }
109 }
110 let Ok(wallet) = WalletDb::new(Some(wallet_path), Some(&wallet_pass)) else {
111 return Err(Error::DatabaseError(format!("{}", WalletDbError::InitializationFailed)));
112 };
113
114 let rpc_client = if let Some(endpoint) = endpoint {
116 Some(RwLock::new(DarkfidRpcClient::new(endpoint, ex.clone()).await))
117 } else {
118 None
119 };
120
121 Ok(Self { cache, wallet, rpc_client, fun })
122 }
123
124 pub fn into_ptr(self) -> DrkPtr {
125 Arc::new(RwLock::new(self))
126 }
127
128 pub async fn initialize_wallet(&self) -> WalletDbResult<()> {
130 self.wallet.exec_batch_sql(include_str!("../wallet.sql"))?;
132
133 Ok(())
134 }
135
136 pub fn reset(&self, output: &mut Vec<String>) -> WalletDbResult<()> {
138 output.push(String::from("Resetting full wallet state"));
139 self.reset_scanned_blocks(output)?;
140 self.reset_money_tree(output)?;
141 self.reset_money_smt(output)?;
142 self.reset_money_coins(output)?;
143 self.reset_mint_authorities(output)?;
144 self.reset_dao_trees(output)?;
145 self.reset_daos(output)?;
146 self.reset_dao_proposals(output)?;
147 self.reset_dao_votes(output)?;
148 self.reset_deploy_authorities(output)?;
149 self.reset_deploy_history(output)?;
150 self.reset_tx_history(output)?;
151 output.push(String::from("Successfully reset full wallet state"));
152 Ok(())
153 }
154}