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};
25use darkfi_sdk::crypto::keypair::Network;
26
27/// Error codes
28pub mod error;
29use error::{WalletDbError, WalletDbResult};
30
31/// Common shared functions
32pub mod common;
33
34/// darkfid JSON-RPC related methods
35pub mod rpc;
36use rpc::DarkfidRpcClient;
37
38/// Payment methods
39pub mod transfer;
40
41/// Swap methods
42pub mod swap;
43
44/// Token methods
45pub mod token;
46
47/// CLI utility functions
48pub mod cli_util;
49
50/// Drk interactive shell
51pub mod interactive;
52
53/// Wallet functionality related to Money
54pub mod money;
55
56/// Wallet functionality related to Dao
57pub mod dao;
58
59/// Wallet functionality related to Deployooor
60pub mod deploy;
61
62/// Wallet functionality related to transactions history
63pub mod txs_history;
64
65/// Wallet functionality related to scanned blocks
66pub mod scanned_blocks;
67
68/// Wallet database operations handler
69pub mod walletdb;
70use walletdb::{WalletDb, WalletPtr};
71
72/// Blockchain cache database operations handler
73pub mod cache;
74use cache::Cache;
75
76/// Atomic pointer to a `Drk` structure.
77pub type DrkPtr = Arc<RwLock<Drk>>;
78
79/// CLI-util structure
80pub struct Drk {
81    /// Blockchain network
82    pub network: Network,
83    /// Blockchain cache database operations handler
84    pub cache: Cache,
85    /// Wallet database operations handler
86    pub wallet: WalletPtr,
87    /// JSON-RPC client to execute requests to darkfid daemon
88    pub rpc_client: Option<RwLock<DarkfidRpcClient>>,
89    /// Flag indicating if fun stuff are enabled
90    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        // Initialize blockchain cache database
104        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        // Initialize wallet
111        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        // Initialize rpc client
122        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    /// Initialize wallet with tables for `Drk`.
136    pub async fn initialize_wallet(&self) -> WalletDbResult<()> {
137        // Initialize wallet schema
138        self.wallet.exec_batch_sql(include_str!("../wallet.sql"))?;
139
140        Ok(())
141    }
142
143    /// Auxiliary function to completely reset wallet state.
144    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}