drk/
lib.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19use 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
26/// Error codes
27pub mod error;
28use error::{WalletDbError, WalletDbResult};
29
30/// darkfid JSON-RPC related methods
31pub mod rpc;
32use rpc::DarkfidRpcClient;
33
34/// Payment methods
35pub mod transfer;
36
37/// Swap methods
38pub mod swap;
39
40/// Token methods
41pub mod token;
42
43/// CLI utility functions
44pub mod cli_util;
45
46/// Drk interactive shell
47pub mod interactive;
48
49/// Wallet functionality related to Money
50pub mod money;
51
52/// Wallet functionality related to Dao
53pub mod dao;
54
55/// Wallet functionality related to Deployooor
56pub mod deploy;
57
58/// Wallet functionality related to transactions history
59pub mod txs_history;
60
61/// Wallet functionality related to scanned blocks
62pub mod scanned_blocks;
63
64/// Wallet database operations handler
65pub mod walletdb;
66use walletdb::{WalletDb, WalletPtr};
67
68/// Blockchain cache database operations handler
69pub mod cache;
70use cache::Cache;
71
72/// Atomic pointer to a `Drk` structure.
73pub type DrkPtr = Arc<RwLock<Drk>>;
74
75/// CLI-util structure
76pub struct Drk {
77    /// Blockchain cache database operations handler
78    pub cache: Cache,
79    /// Wallet database operations handler
80    pub wallet: WalletPtr,
81    /// JSON-RPC client to execute requests to darkfid daemon
82    pub rpc_client: Option<RwLock<DarkfidRpcClient>>,
83    /// Flag indicating if fun stuff are enabled
84    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        // Initialize blockchain cache database
97        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        // Initialize wallet
104        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        // Initialize rpc client
115        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    /// Initialize wallet with tables for `Drk`.
129    pub async fn initialize_wallet(&self) -> WalletDbResult<()> {
130        // Initialize wallet schema
131        self.wallet.exec_batch_sql(include_str!("../wallet.sql"))?;
132
133        Ok(())
134    }
135
136    /// Auxiliary function to completely reset wallet state.
137    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}