/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2020-2026 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use std::{fs::create_dir_all, sync::Arc}; use smol::lock::RwLock; use url::Url; use darkfi::{system::ExecutorPtr, util::path::expand_path, Error, Result}; use darkfi_sdk::crypto::keypair::Network; /// Error codes pub mod error; use error::{WalletDbError, WalletDbResult}; /// Common shared functions pub mod common; /// darkfid JSON-RPC related methods pub mod rpc; use rpc::DarkfidRpcClient; /// Payment methods pub mod transfer; /// Swap methods pub mod swap; /// Token methods pub mod token; /// CLI utility functions pub mod cli_util; /// Drk interactive shell pub mod interactive; /// Wallet functionality related to Money pub mod money; /// Wallet functionality related to Dao pub mod dao; /// Wallet functionality related to Deployooor pub mod deploy; /// Wallet functionality related to transactions history pub mod txs_history; /// Wallet functionality related to scanned blocks pub mod scanned_blocks; /// Wallet database operations handler pub mod walletdb; use walletdb::{WalletDb, WalletPtr}; /// Blockchain cache database operations handler pub mod cache; use cache::Cache; /// Atomic pointer to a `Drk` structure. pub type DrkPtr = Arc>; /// CLI-util structure pub struct Drk { /// Blockchain network pub network: Network, /// Blockchain cache database operations handler pub cache: Cache, /// Wallet database operations handler pub wallet: WalletPtr, /// JSON-RPC client to execute requests to darkfid daemon pub rpc_client: Option>, /// Flag indicating if fun stuff are enabled pub fun: bool, } impl Drk { pub async fn new( network: Network, cache_path: String, wallet_path: String, wallet_pass: String, endpoint: Option, ex: &ExecutorPtr, fun: bool, ) -> Result { // Initialize blockchain cache database let db_path = expand_path(&cache_path)?; let sled_db = sled_overlay::sled::open(&db_path)?; let Ok(cache) = Cache::new(&sled_db) else { return Err(Error::DatabaseError(format!("{}", WalletDbError::InitializationFailed))); }; // Initialize wallet let wallet_path = expand_path(&wallet_path)?; if !wallet_path.exists() { if let Some(parent) = wallet_path.parent() { create_dir_all(parent)?; } } let Ok(wallet) = WalletDb::new(Some(wallet_path), Some(&wallet_pass)).await else { return Err(Error::DatabaseError(format!("{}", WalletDbError::InitializationFailed))); }; // Initialize rpc client let rpc_client = if let Some(endpoint) = endpoint { Some(RwLock::new(DarkfidRpcClient::new(endpoint, ex.clone()).await)) } else { None }; Ok(Self { network, cache, wallet, rpc_client, fun }) } pub fn into_ptr(self) -> DrkPtr { Arc::new(RwLock::new(self)) } /// Initialize wallet with tables for `Drk`. pub async fn initialize_wallet(&self) -> WalletDbResult<()> { // Initialize wallet schema self.wallet.exec_batch_sql(include_str!("../wallet.sql")).await?; Ok(()) } /// Auxiliary function to completely reset wallet state. pub async fn reset(&self, output: &mut Vec) -> WalletDbResult<()> { output.push(String::from("Resetting full wallet state")); self.reset_scanned_blocks(output)?; self.reset_money_tree(output)?; self.reset_money_smt(output)?; self.reset_money_coins(output).await?; self.reset_mint_authorities(output).await?; self.reset_dao_trees(output)?; self.reset_daos(output).await?; self.reset_dao_proposals(output).await?; self.reset_dao_votes(output).await?; self.reset_deploy_authorities(output).await?; self.reset_deploy_history(output).await?; self.reset_tx_history(output).await?; output.push(String::from("Successfully reset full wallet state")); Ok(()) } }