diff --git a/.github/ci-groups.yml b/.github/ci-groups.yml index 03f114508..e996ce208 100644 --- a/.github/ci-groups.yml +++ b/.github/ci-groups.yml @@ -12,6 +12,7 @@ groups: wallet: - key-wallet + - key-wallet-manager ffi: - dash-spv-ffi diff --git a/Cargo.toml b/Cargo.toml index e899d83f4..7be8607fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["dash", "hashes", "internals", "fuzz", "rpc-client", "rpc-json", "rpc-integration-test", "key-wallet", "key-wallet-ffi", "dash-spv", "dash-spv-ffi"] +members = ["dash", "hashes", "internals", "fuzz", "rpc-client", "rpc-json", "rpc-integration-test", "key-wallet", "key-wallet-manager", "key-wallet-ffi", "dash-spv", "dash-spv-ffi"] resolver = "2" [workspace.package] diff --git a/dash-spv-ffi/Cargo.toml b/dash-spv-ffi/Cargo.toml index 17c2687b2..da11bea58 100644 --- a/dash-spv-ffi/Cargo.toml +++ b/dash-spv-ffi/Cargo.toml @@ -28,6 +28,7 @@ tracing = "0.1" key-wallet-ffi = { path = "../key-wallet-ffi" } # Still need these for SPV client internals (not for FFI types) key-wallet = { path = "../key-wallet" } +key-wallet-manager = { path = "../key-wallet-manager" } rand = "0.8" clap = { version = "4.5", features = ["derive"] } diff --git a/dash-spv-ffi/src/callbacks.rs b/dash-spv-ffi/src/callbacks.rs index 6422463e3..cbff4419e 100644 --- a/dash-spv-ffi/src/callbacks.rs +++ b/dash-spv-ffi/src/callbacks.rs @@ -11,8 +11,8 @@ use dash_spv::network::NetworkEvent; use dash_spv::sync::{SyncEvent, SyncProgress}; use dash_spv::EventHandler; use dashcore::hashes::Hash; -use key_wallet::manager::WalletEvent; use key_wallet_ffi::types::FFITransactionContext; +use key_wallet_manager::WalletEvent; use std::ffi::CString; use std::os::raw::{c_char, c_void}; diff --git a/dash-spv-ffi/src/client.rs b/dash-spv-ffi/src/client.rs index 02a60515b..b588a5bb7 100644 --- a/dash-spv-ffi/src/client.rs +++ b/dash-spv-ffi/src/client.rs @@ -17,7 +17,7 @@ use tokio_util::sync::CancellationToken; /// FFI wrapper around `DashSpvClient`. type InnerClient = DashSpvClient< - key_wallet::manager::WalletManager, + key_wallet_manager::WalletManager, dash_spv::network::PeerNetworkManager, DiskStorageManager, FFIEventCallbacks, @@ -78,7 +78,7 @@ pub unsafe extern "C" fn dash_spv_ffi_client_new( // Construct concrete implementations for generics let network = dash_spv::network::PeerNetworkManager::new(&client_config).await; let storage = DiskStorageManager::new(&client_config).await; - let wallet = key_wallet::manager::WalletManager::< + let wallet = key_wallet_manager::WalletManager::< key_wallet::wallet::managed_wallet_info::ManagedWalletInfo, >::new(client_config.network); let wallet = std::sync::Arc::new(tokio::sync::RwLock::new(wallet)); diff --git a/dash-spv-ffi/tests/test_wallet_manager.rs b/dash-spv-ffi/tests/test_wallet_manager.rs index 15f5df2fd..5c4d6710f 100644 --- a/dash-spv-ffi/tests/test_wallet_manager.rs +++ b/dash-spv-ffi/tests/test_wallet_manager.rs @@ -1,7 +1,6 @@ #[cfg(test)] mod tests { use dash_spv_ffi::*; - use key_wallet::manager::WalletManager; use key_wallet::wallet::initialization::WalletAccountCreationOptions; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; use key_wallet_ffi::{ @@ -11,6 +10,7 @@ mod tests { }, FFIError, FFINetwork, FFIWalletManager, }; + use key_wallet_manager::WalletManager; use std::ffi::{CStr, CString}; use tempfile::TempDir; diff --git a/dash-spv/Cargo.toml b/dash-spv/Cargo.toml index c05f46999..5a468b02c 100644 --- a/dash-spv/Cargo.toml +++ b/dash-spv/Cargo.toml @@ -12,7 +12,8 @@ rust-version = "1.89" # Core Dash libraries dashcore = { path = "../dash", features = ["serde", "core-block-hash-use-x11", "message_verification", "bls", "quorum_validation"] } dashcore_hashes = { path = "../hashes" } -key-wallet = { path = "../key-wallet", features = ["parallel-filters"] } +key-wallet = { path = "../key-wallet" } +key-wallet-manager = { path = "../key-wallet-manager", features = ["parallel-filters"] } # BLS signatures blsful = { git = "https://github.com/dashpay/agora-blsful", rev = "0c34a7a488a0bd1c9a9a2196e793b303ad35c900" } @@ -64,6 +65,7 @@ log = "0.4" dash-spv = { path = ".", features = ["test-utils"] } dashcore = { path = "../dash", features = ["test-utils"] } key-wallet = { path = "../key-wallet", features = ["test-utils"] } +key-wallet-manager = { path = "../key-wallet-manager", features = ["test-utils"] } criterion = { version = "0.8.1", features = ["async_tokio"] } tempfile = "3.0" tokio-test = "0.4" diff --git a/dash-spv/examples/filter_sync.rs b/dash-spv/examples/filter_sync.rs index 07e0840e9..22a78b418 100644 --- a/dash-spv/examples/filter_sync.rs +++ b/dash-spv/examples/filter_sync.rs @@ -4,8 +4,8 @@ use dash_spv::network::PeerNetworkManager; use dash_spv::storage::DiskStorageManager; use dash_spv::{init_console_logging, ClientConfig, DashSpvClient, LevelFilter}; use dashcore::Address; -use key_wallet::manager::WalletManager; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletManager; use std::str::FromStr; use std::sync::Arc; use tokio::sync::RwLock; diff --git a/dash-spv/examples/simple_sync.rs b/dash-spv/examples/simple_sync.rs index 33344a824..2f162dc15 100644 --- a/dash-spv/examples/simple_sync.rs +++ b/dash-spv/examples/simple_sync.rs @@ -5,7 +5,7 @@ use dash_spv::storage::DiskStorageManager; use dash_spv::{init_console_logging, ClientConfig, DashSpvClient, LevelFilter}; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; -use key_wallet::manager::WalletManager; +use key_wallet_manager::WalletManager; use std::sync::Arc; use tokio::sync::RwLock; use tokio_util::sync::CancellationToken; diff --git a/dash-spv/examples/spv_with_wallet.rs b/dash-spv/examples/spv_with_wallet.rs index 5c21534a3..d8f913089 100644 --- a/dash-spv/examples/spv_with_wallet.rs +++ b/dash-spv/examples/spv_with_wallet.rs @@ -5,8 +5,8 @@ use dash_spv::network::PeerNetworkManager; use dash_spv::storage::DiskStorageManager; use dash_spv::{ClientConfig, DashSpvClient, LevelFilter}; -use key_wallet::manager::WalletManager; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletManager; use std::sync::Arc; use tokio::sync::RwLock; use tokio_util::sync::CancellationToken; diff --git a/dash-spv/src/client/core.rs b/dash-spv/src/client/core.rs index 746ffd5f1..9a046b4c4 100644 --- a/dash-spv/src/client/core.rs +++ b/dash-spv/src/client/core.rs @@ -23,7 +23,7 @@ use crate::storage::{ }; use crate::sync::SyncCoordinator; use crate::types::MempoolState; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; pub(super) type PersistentSyncCoordinator = SyncCoordinator< PersistentBlockHeaderStorage, diff --git a/dash-spv/src/client/event_handler.rs b/dash-spv/src/client/event_handler.rs index b3c3026df..b2b42c3c3 100644 --- a/dash-spv/src/client/event_handler.rs +++ b/dash-spv/src/client/event_handler.rs @@ -12,7 +12,7 @@ use tokio_util::sync::CancellationToken; use crate::network::NetworkEvent; use crate::sync::{SyncEvent, SyncProgress}; -use key_wallet::manager::WalletEvent; +use key_wallet_manager::WalletEvent; /// Trait for receiving SPV client events. /// @@ -105,7 +105,7 @@ mod tests { use super::{spawn_broadcast_monitor, spawn_progress_monitor, EventHandler}; use crate::network::NetworkEvent; use crate::sync::{ManagerIdentifier, SyncEvent, SyncProgress}; - use key_wallet::manager::WalletEvent; + use key_wallet_manager::WalletEvent; struct RecordingHandler { sync_count: AtomicUsize, diff --git a/dash-spv/src/client/events.rs b/dash-spv/src/client/events.rs index 073d3dfef..62881860c 100644 --- a/dash-spv/src/client/events.rs +++ b/dash-spv/src/client/events.rs @@ -9,7 +9,7 @@ use tokio::sync::watch; use crate::network::{NetworkEvent, NetworkManager}; use crate::storage::StorageManager; use crate::sync::{SyncEvent, SyncProgress}; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; use tokio::sync::broadcast; use super::{DashSpvClient, EventHandler}; diff --git a/dash-spv/src/client/lifecycle.rs b/dash-spv/src/client/lifecycle.rs index 5eade3316..739ca8a43 100644 --- a/dash-spv/src/client/lifecycle.rs +++ b/dash-spv/src/client/lifecycle.rs @@ -28,7 +28,7 @@ use crate::sync::{ use crate::types::MempoolState; use dashcore::sml::masternode_list_engine::MasternodeListEngine; use dashcore_hashes::Hash; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; impl DashSpvClient diff --git a/dash-spv/src/client/mempool.rs b/dash-spv/src/client/mempool.rs index 694930152..d15a9e67e 100644 --- a/dash-spv/src/client/mempool.rs +++ b/dash-spv/src/client/mempool.rs @@ -13,7 +13,7 @@ use crate::error::Result; use crate::mempool_filter::MempoolFilter; use crate::network::NetworkManager; use crate::storage::StorageManager; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; use super::{DashSpvClient, EventHandler}; diff --git a/dash-spv/src/client/mod.rs b/dash-spv/src/client/mod.rs index 53d857023..aac6deed3 100644 --- a/dash-spv/src/client/mod.rs +++ b/dash-spv/src/client/mod.rs @@ -52,8 +52,8 @@ mod tests { use crate::storage::DiskStorageManager; use crate::{test_utils::MockNetworkManager, types::UnconfirmedTransaction}; use dashcore::{Address, Amount, Transaction, TxOut}; - use key_wallet::manager::WalletManager; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; + use key_wallet_manager::WalletManager; use std::sync::Arc; use tempfile::TempDir; use tokio::sync::RwLock; diff --git a/dash-spv/src/client/queries.rs b/dash-spv/src/client/queries.rs index 7f8749260..c89fc86e9 100644 --- a/dash-spv/src/client/queries.rs +++ b/dash-spv/src/client/queries.rs @@ -13,7 +13,7 @@ use dashcore::sml::llmq_type::LLMQType; use dashcore::sml::masternode_list_engine::MasternodeListEngine; use dashcore::sml::quorum_entry::qualified_quorum_entry::QualifiedQuorumEntry; use dashcore::QuorumHash; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; use std::sync::Arc; use tokio::sync::RwLock; diff --git a/dash-spv/src/client/sync_coordinator.rs b/dash-spv/src/client/sync_coordinator.rs index 8a99fb840..b4257a943 100644 --- a/dash-spv/src/client/sync_coordinator.rs +++ b/dash-spv/src/client/sync_coordinator.rs @@ -11,7 +11,7 @@ use crate::network::NetworkManager; use crate::storage::StorageManager; use crate::sync::SyncProgress; use crate::SpvError; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; const SYNC_COORDINATOR_TICK_MS: Duration = Duration::from_millis(100); diff --git a/dash-spv/src/client/transactions.rs b/dash-spv/src/client/transactions.rs index 3fbf68b8a..6b7d363c6 100644 --- a/dash-spv/src/client/transactions.rs +++ b/dash-spv/src/client/transactions.rs @@ -4,7 +4,7 @@ use crate::error::{Result, SpvError}; use crate::network::NetworkManager; use crate::storage::StorageManager; use dashcore::network::message::NetworkMessage; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; use super::{DashSpvClient, EventHandler}; diff --git a/dash-spv/src/lib.rs b/dash-spv/src/lib.rs index 5fb3d392a..17644bc08 100644 --- a/dash-spv/src/lib.rs +++ b/dash-spv/src/lib.rs @@ -17,7 +17,7 @@ //! use dash_spv::storage::DiskStorageManager; //! use dashcore::Network; //! use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; -//! use key_wallet::manager::WalletManager; +//! use key_wallet_manager::WalletManager; //! use std::sync::Arc; //! use tokio::sync::RwLock; //! use tokio_util::sync::CancellationToken; diff --git a/dash-spv/src/main.rs b/dash-spv/src/main.rs index ec01c3002..1d3ca097d 100644 --- a/dash-spv/src/main.rs +++ b/dash-spv/src/main.rs @@ -9,8 +9,8 @@ use clap::{Arg, Command}; use dash_spv::network::NetworkEvent; use dash_spv::sync::{SyncEvent, SyncProgress}; use dash_spv::{ClientConfig, DashSpvClient, EventHandler, LevelFilter, MempoolStrategy, Network}; -use key_wallet::manager::{WalletEvent, WalletManager}; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::{WalletEvent, WalletManager}; use tokio_util::sync::CancellationToken; /// Logs all SPV client events via tracing. diff --git a/dash-spv/src/sync/blocks/manager.rs b/dash-spv/src/sync/blocks/manager.rs index bf289057b..8ea4e2f59 100644 --- a/dash-spv/src/sync/blocks/manager.rs +++ b/dash-spv/src/sync/blocks/manager.rs @@ -12,7 +12,7 @@ use crate::error::SyncResult; use crate::network::RequestSender; use crate::storage::{BlockHeaderStorage, BlockStorage}; use crate::sync::{BlocksProgress, SyncEvent, SyncManager, SyncState}; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; /// Blocks manager for downloading and processing matching blocks. /// @@ -168,8 +168,8 @@ mod tests { }; use crate::sync::{ManagerIdentifier, SyncEvent, SyncManagerProgress}; use crate::test_utils::MockNetworkManager; - use key_wallet::manager::FilterMatchKey; - use key_wallet::test_utils::MockWallet; + use key_wallet_manager::test_utils::MockWallet; + use key_wallet_manager::FilterMatchKey; use std::collections::BTreeSet; type TestBlocksManager = diff --git a/dash-spv/src/sync/blocks/pipeline.rs b/dash-spv/src/sync/blocks/pipeline.rs index a431f1032..5daf0962e 100644 --- a/dash-spv/src/sync/blocks/pipeline.rs +++ b/dash-spv/src/sync/blocks/pipeline.rs @@ -11,7 +11,7 @@ use crate::network::RequestSender; use crate::sync::download_coordinator::{DownloadConfig, DownloadCoordinator}; use dashcore::blockdata::block::Block; use dashcore::BlockHash; -use key_wallet::manager::FilterMatchKey; +use key_wallet_manager::FilterMatchKey; /// Maximum number of concurrent block downloads. const MAX_CONCURRENT_BLOCK_DOWNLOADS: usize = 20; diff --git a/dash-spv/src/sync/blocks/sync_manager.rs b/dash-spv/src/sync/blocks/sync_manager.rs index beeeb279a..faf8ce9b0 100644 --- a/dash-spv/src/sync/blocks/sync_manager.rs +++ b/dash-spv/src/sync/blocks/sync_manager.rs @@ -10,7 +10,7 @@ use crate::types::HashedBlock; use crate::SyncError; use async_trait::async_trait; use dashcore::network::message::NetworkMessage; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; #[async_trait] impl SyncManager diff --git a/dash-spv/src/sync/events.rs b/dash-spv/src/sync/events.rs index a7f55a50c..a5ed9734d 100644 --- a/dash-spv/src/sync/events.rs +++ b/dash-spv/src/sync/events.rs @@ -2,7 +2,7 @@ use crate::sync::ManagerIdentifier; use dashcore::ephemerealdata::chain_lock::ChainLock; use dashcore::ephemerealdata::instant_lock::InstantLock; use dashcore::{Address, BlockHash, Txid}; -use key_wallet::manager::FilterMatchKey; +use key_wallet_manager::FilterMatchKey; use std::collections::BTreeSet; /// Events that managers can emit and subscribe to. diff --git a/dash-spv/src/sync/filters/batch.rs b/dash-spv/src/sync/filters/batch.rs index 202d169d9..75ed22025 100644 --- a/dash-spv/src/sync/filters/batch.rs +++ b/dash-spv/src/sync/filters/batch.rs @@ -1,6 +1,6 @@ use dashcore::bip158::BlockFilter; use dashcore::Address; -use key_wallet::manager::FilterMatchKey; +use key_wallet_manager::FilterMatchKey; use std::collections::{HashMap, HashSet}; /// A completed batch of compact block filters ready for verification. @@ -134,7 +134,7 @@ mod tests { use crate::sync::filters::batch::FiltersBatch; use dashcore::bip158::BlockFilter; use dashcore::Header; - use key_wallet::manager::FilterMatchKey; + use key_wallet_manager::FilterMatchKey; use std::collections::{BTreeSet, HashMap}; #[test] diff --git a/dash-spv/src/sync/filters/batch_tracker.rs b/dash-spv/src/sync/filters/batch_tracker.rs index ceae6b731..d67a74653 100644 --- a/dash-spv/src/sync/filters/batch_tracker.rs +++ b/dash-spv/src/sync/filters/batch_tracker.rs @@ -1,6 +1,6 @@ use dashcore::bip158::BlockFilter; use dashcore::BlockHash; -use key_wallet::manager::FilterMatchKey; +use key_wallet_manager::FilterMatchKey; use std::collections::{HashMap, HashSet}; /// Tracks individual filters within a batch. diff --git a/dash-spv/src/sync/filters/manager.rs b/dash-spv/src/sync/filters/manager.rs index 5080af045..06bf440e4 100644 --- a/dash-spv/src/sync/filters/manager.rs +++ b/dash-spv/src/sync/filters/manager.rs @@ -21,8 +21,8 @@ use crate::validation::{FilterValidationInput, FilterValidator, Validator}; use crate::sync::progress::ProgressPercentage; use dashcore::hash_types::FilterHeader; -use key_wallet::manager::WalletInterface; -use key_wallet::manager::{check_compact_filters_for_addresses, FilterMatchKey}; +use key_wallet_manager::WalletInterface; +use key_wallet_manager::{check_compact_filters_for_addresses, FilterMatchKey}; use tokio::sync::RwLock; /// Batch size for processing filters. @@ -771,7 +771,7 @@ mod tests { PersistentFilterStorage, StorageManager, }; use crate::sync::{ManagerIdentifier, SyncManagerProgress}; - use key_wallet::test_utils::MockWallet; + use key_wallet_manager::test_utils::MockWallet; use tokio::sync::mpsc::unbounded_channel; type TestFiltersManager = FiltersManager< diff --git a/dash-spv/src/sync/filters/pipeline.rs b/dash-spv/src/sync/filters/pipeline.rs index 6f2ca8025..8029fd54d 100644 --- a/dash-spv/src/sync/filters/pipeline.rs +++ b/dash-spv/src/sync/filters/pipeline.rs @@ -279,7 +279,7 @@ mod tests { use dashcore::block::Header; use dashcore::network::message::NetworkMessage; use dashcore_hashes::Hash; - use key_wallet::manager::FilterMatchKey; + use key_wallet_manager::FilterMatchKey; use std::time::Duration; use tempfile::TempDir; use tokio::sync::mpsc::unbounded_channel; diff --git a/dash-spv/src/sync/filters/sync_manager.rs b/dash-spv/src/sync/filters/sync_manager.rs index a9423ee1b..e49df3405 100644 --- a/dash-spv/src/sync/filters/sync_manager.rs +++ b/dash-spv/src/sync/filters/sync_manager.rs @@ -9,7 +9,7 @@ use crate::sync::{ }; use async_trait::async_trait; use dashcore::network::message::NetworkMessage; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; #[async_trait] impl< diff --git a/dash-spv/src/sync/mempool/manager.rs b/dash-spv/src/sync/mempool/manager.rs index 4250672af..27d3e4681 100644 --- a/dash-spv/src/sync/mempool/manager.rs +++ b/dash-spv/src/sync/mempool/manager.rs @@ -23,7 +23,7 @@ use crate::network::RequestSender; use crate::sync::mempool::MempoolProgress; use crate::sync::SyncEvent; use crate::types::{MempoolState, UnconfirmedTransaction}; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; /// Timeout for pruning expired mempool transactions (24 hours). pub(super) const MEMPOOL_TX_EXPIRY: Duration = Duration::from_secs(24 * 3600); @@ -497,8 +497,8 @@ mod tests { use dashcore::hashes::Hash; use dashcore::network::message::NetworkMessage; use dashcore::{Address, BlockHash, Network, ScriptBuf, Transaction}; - use key_wallet::test_utils::MockWallet; use key_wallet::transaction_checking::TransactionContext; + use key_wallet_manager::test_utils::MockWallet; use crate::sync::SyncState; use crate::test_utils::test_socket_address; diff --git a/dash-spv/src/sync/mempool/sync_manager.rs b/dash-spv/src/sync/mempool/sync_manager.rs index 33cf41bd4..3292ae770 100644 --- a/dash-spv/src/sync/mempool/sync_manager.rs +++ b/dash-spv/src/sync/mempool/sync_manager.rs @@ -6,7 +6,7 @@ use crate::sync::{ }; use async_trait::async_trait; use dashcore::network::message::NetworkMessage; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; #[async_trait] impl SyncManager for MempoolManager { @@ -191,7 +191,7 @@ mod tests { use crate::test_utils::test_socket_address; use crate::types::MempoolState; use dashcore::hashes::Hash; - use key_wallet::test_utils::MockWallet; + use key_wallet_manager::test_utils::MockWallet; use std::sync::Arc; use tokio::sync::{mpsc, RwLock}; diff --git a/dash-spv/src/sync/sync_coordinator.rs b/dash-spv/src/sync/sync_coordinator.rs index 889aea4c0..7f9bc245d 100644 --- a/dash-spv/src/sync/sync_coordinator.rs +++ b/dash-spv/src/sync/sync_coordinator.rs @@ -24,7 +24,7 @@ use crate::sync::{ SyncManager, SyncManagerProgress, SyncManagerTaskContext, SyncProgress, }; use crate::SyncError; -use key_wallet::manager::WalletInterface; +use key_wallet_manager::WalletInterface; const TASK_JOIN_TIMEOUT: Duration = Duration::from_secs(5); const DEFAULT_SYNC_EVENT_CAPACITY: usize = 10000; diff --git a/dash-spv/src/test_utils/event_handler.rs b/dash-spv/src/test_utils/event_handler.rs index 7d7f21f98..25d9f6b19 100644 --- a/dash-spv/src/test_utils/event_handler.rs +++ b/dash-spv/src/test_utils/event_handler.rs @@ -8,7 +8,7 @@ use tokio::sync::{broadcast, watch}; use crate::client::EventHandler; use crate::network::NetworkEvent; use crate::sync::{SyncEvent, SyncProgress}; -use key_wallet::manager::WalletEvent; +use key_wallet_manager::WalletEvent; /// Event handler that forwards all events to internal channels. /// diff --git a/dash-spv/src/validation/filter.rs b/dash-spv/src/validation/filter.rs index 45b3dd6c1..d9a0f8f3f 100644 --- a/dash-spv/src/validation/filter.rs +++ b/dash-spv/src/validation/filter.rs @@ -7,7 +7,7 @@ use std::collections::HashMap; use dashcore::bip158::BlockFilter; use dashcore::hash_types::FilterHeader; -use key_wallet::manager::FilterMatchKey; +use key_wallet_manager::FilterMatchKey; use rayon::prelude::*; use crate::error::{ValidationError, ValidationResult}; @@ -132,7 +132,7 @@ mod tests { use dashcore::bip158::BlockFilter; use dashcore::BlockHash; use dashcore_hashes::Hash; - use key_wallet::manager::FilterMatchKey; + use key_wallet_manager::FilterMatchKey; use super::*; diff --git a/dash-spv/tests/dashd_sync/helpers.rs b/dash-spv/tests/dashd_sync/helpers.rs index 2a27e51aa..a9eb92481 100644 --- a/dash-spv/tests/dashd_sync/helpers.rs +++ b/dash-spv/tests/dashd_sync/helpers.rs @@ -2,11 +2,11 @@ use dash_spv::network::NetworkEvent; use dash_spv::sync::{ProgressPercentage, SyncEvent, SyncProgress, SyncState}; use dash_spv::test_utils::DashCoreNode; use dashcore::Txid; -use key_wallet::manager::WalletEvent; -use key_wallet::manager::{WalletId, WalletManager}; use key_wallet::transaction_checking::TransactionContext; use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletEvent; +use key_wallet_manager::{WalletId, WalletManager}; use std::collections::HashSet; use std::sync::Arc; use std::time::Duration; diff --git a/dash-spv/tests/dashd_sync/setup.rs b/dash-spv/tests/dashd_sync/setup.rs index 002663a5b..6608a3c58 100644 --- a/dash-spv/tests/dashd_sync/setup.rs +++ b/dash-spv/tests/dashd_sync/setup.rs @@ -13,11 +13,11 @@ use dashcore::network::address::AddrV2Message; use dashcore::network::constants::ServiceFlags; use dashcore::Txid; use key_wallet::managed_account::managed_account_type::ManagedAccountType; -use key_wallet::manager::WalletEvent; -use key_wallet::manager::{WalletId, WalletManager}; use key_wallet::wallet::initialization::WalletAccountCreationOptions; use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletEvent; +use key_wallet_manager::{WalletId, WalletManager}; use std::collections::{BTreeSet, HashSet}; use std::path::PathBuf; use std::sync::Arc; diff --git a/dash-spv/tests/dashd_sync/tests_basic.rs b/dash-spv/tests/dashd_sync/tests_basic.rs index 0ad906d09..3cae9b907 100644 --- a/dash-spv/tests/dashd_sync/tests_basic.rs +++ b/dash-spv/tests/dashd_sync/tests_basic.rs @@ -1,5 +1,5 @@ -use key_wallet::manager::WalletManager; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletManager; use std::sync::Arc; use tokio::sync::RwLock; diff --git a/dash-spv/tests/peer_test.rs b/dash-spv/tests/peer_test.rs index 519dd5fe4..c69d0786c 100644 --- a/dash-spv/tests/peer_test.rs +++ b/dash-spv/tests/peer_test.rs @@ -13,8 +13,8 @@ use dash_spv::network::PeerNetworkManager; use dash_spv::storage::DiskStorageManager; use dash_spv::types::ValidationMode; use dashcore::Network; -use key_wallet::manager::WalletManager; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletManager; /// Create a test configuration with the given network fn create_test_config(network: Network) -> ClientConfig { let mut config = ClientConfig::new(network); diff --git a/dash-spv/tests/wallet_integration_test.rs b/dash-spv/tests/wallet_integration_test.rs index 4aaeb3be9..f518b5343 100644 --- a/dash-spv/tests/wallet_integration_test.rs +++ b/dash-spv/tests/wallet_integration_test.rs @@ -12,8 +12,8 @@ use dash_spv::network::PeerNetworkManager; use dash_spv::storage::DiskStorageManager; use dash_spv::{ClientConfig, DashSpvClient}; use dashcore::Network; -use key_wallet::manager::WalletManager; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletManager; /// Create a test SPV client with memory storage for integration testing. async fn create_test_client( ) -> DashSpvClient, PeerNetworkManager, DiskStorageManager> { diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index f93bdf390..2aa8a704f 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -15,7 +15,7 @@ cargo-fuzz = true [dependencies] honggfuzz = { version = "0.5", default-features = false } dashcore = { path = "../dash", features = [ "serde" ] } -key-wallet = { path = "../key-wallet" } +key-wallet = { path = "../key-wallet", default-features = false, features = ["getrandom"] } serde = { version = "1.0.219", features = [ "derive" ] } serde_json = "1.0" diff --git a/key-wallet-ffi/Cargo.toml b/key-wallet-ffi/Cargo.toml index fea901453..e787a170d 100644 --- a/key-wallet-ffi/Cargo.toml +++ b/key-wallet-ffi/Cargo.toml @@ -15,12 +15,13 @@ crate-type = ["cdylib", "staticlib", "lib"] [features] default = ["bincode", "eddsa", "bls", "bip38"] bip38 = ["key-wallet/bip38"] -bincode = ["key-wallet/bincode"] +bincode = ["key-wallet/bincode", "key-wallet-manager/bincode"] eddsa = ["dashcore/eddsa", "key-wallet/eddsa"] bls = ["dashcore/bls", "key-wallet/bls"] [dependencies] -key-wallet = { path = "../key-wallet", features = ["manager"] } +key-wallet = { path = "../key-wallet" } +key-wallet-manager = { path = "../key-wallet-manager" } dashcore = { path = "../dash" } secp256k1 = { version = "0.30.0", features = ["global-context"] } tokio = { version = "1.32", features = ["rt-multi-thread", "sync"] } @@ -31,6 +32,7 @@ hex = "0.4" cbindgen = "0.29" [dev-dependencies] -key-wallet = { path = "../key-wallet", features = ["manager", "test-utils"] } +key-wallet = { path = "../key-wallet", features = ["test-utils"] } +key-wallet-manager = { path = "../key-wallet-manager", features = ["test-utils"] } tempfile = "3.0" hex = "0.4" diff --git a/key-wallet-ffi/src/error.rs b/key-wallet-ffi/src/error.rs index 3654e163c..cc942f619 100644 --- a/key-wallet-ffi/src/error.rs +++ b/key-wallet-ffi/src/error.rs @@ -191,9 +191,9 @@ impl From for FFIError { } } -impl From for FFIError { - fn from(err: key_wallet::manager::WalletError) -> Self { - use key_wallet::manager::WalletError; +impl From for FFIError { + fn from(err: key_wallet_manager::WalletError) -> Self { + use key_wallet_manager::WalletError; let (code, msg) = match &err { WalletError::WalletCreation(msg) => { diff --git a/key-wallet-ffi/src/wallet_manager.rs b/key-wallet-ffi/src/wallet_manager.rs index ccb844f51..b607b1b68 100644 --- a/key-wallet-ffi/src/wallet_manager.rs +++ b/key-wallet-ffi/src/wallet_manager.rs @@ -16,9 +16,9 @@ use tokio::sync::RwLock; use crate::error::{FFIError, FFIErrorCode}; use crate::FFINetwork; -use key_wallet::manager::WalletInterface; -use key_wallet::manager::WalletManager; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet_manager::WalletInterface; +use key_wallet_manager::WalletManager; /// FFI wrapper for WalletManager /// @@ -470,14 +470,14 @@ pub unsafe extern "C" fn wallet_manager_import_wallet_from_bytes( Err(e) => { // Convert the error to FFI error match e { - key_wallet::manager::WalletError::WalletExists(_) => { + key_wallet_manager::WalletError::WalletExists(_) => { FFIError::set_error( error, FFIErrorCode::InvalidState, "Wallet already exists in the manager".to_string(), ); } - key_wallet::manager::WalletError::InvalidParameter(msg) => { + key_wallet_manager::WalletError::InvalidParameter(msg) => { FFIError::set_error( error, FFIErrorCode::SerializationError, diff --git a/key-wallet-ffi/src/wallet_manager_tests.rs b/key-wallet-ffi/src/wallet_manager_tests.rs index 6997c237f..d7afd4e8a 100644 --- a/key-wallet-ffi/src/wallet_manager_tests.rs +++ b/key-wallet-ffi/src/wallet_manager_tests.rs @@ -5,7 +5,7 @@ mod tests { use crate::error::{FFIError, FFIErrorCode}; use crate::{wallet, wallet_manager, FFINetwork}; - use key_wallet::manager::WalletInterface; + use key_wallet_manager::WalletInterface; use std::ffi::{CStr, CString}; use std::ptr; use std::slice; diff --git a/key-wallet-ffi/tests/test_error_conversions.rs b/key-wallet-ffi/tests/test_error_conversions.rs index dbeefcd97..d9af8a761 100644 --- a/key-wallet-ffi/tests/test_error_conversions.rs +++ b/key-wallet-ffi/tests/test_error_conversions.rs @@ -55,7 +55,7 @@ fn test_key_wallet_error_to_ffi_error() { #[test] fn test_wallet_manager_error_to_ffi_error() { - use key_wallet::manager::WalletError; + use key_wallet_manager::WalletError; // Test WalletNotFound conversion let wallet_id = [0u8; 32]; @@ -105,8 +105,8 @@ fn test_wallet_manager_error_to_ffi_error() { #[test] fn test_key_wallet_error_to_wallet_manager_error() { - use key_wallet::manager::WalletError; use key_wallet::Error as KeyWalletError; + use key_wallet_manager::WalletError; // Test InvalidMnemonic conversion let err = KeyWalletError::InvalidMnemonic("bad mnemonic".to_string()); @@ -172,8 +172,8 @@ fn test_key_wallet_error_to_wallet_manager_error() { #[test] fn test_error_message_consistency() { - use key_wallet::manager::WalletError; use key_wallet::Error as KeyWalletError; + use key_wallet_manager::WalletError; // Test that error messages are preserved through conversions let original_msg = "This is a test error message"; diff --git a/key-wallet-manager/Cargo.toml b/key-wallet-manager/Cargo.toml new file mode 100644 index 000000000..169c444b1 --- /dev/null +++ b/key-wallet-manager/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "key-wallet-manager" +version = { workspace = true } +authors = ["The Dash Core Developers"] +edition = "2021" +description = "High-level wallet management for Dash (WalletManager, WalletInterface, events, compact filters)" +keywords = ["dash", "wallet", "manager", "spv"] +license = "CC0-1.0" + +[features] +default = [] +parallel-filters = ["dep:rayon"] +bincode = ["key-wallet/bincode", "dep:bincode"] +test-utils = ["key-wallet/test-utils"] + +[dependencies] +key-wallet = { path = "../key-wallet" } +dashcore = { path = "../dash" } +tokio = { version = "1", features = ["macros", "rt", "sync"] } +async-trait = "0.1" +rayon = { version = "1.11", optional = true } +zeroize = { version = "1.8", features = ["derive"] } +bincode = { version = "2.0.1", optional = true } + +[dev-dependencies] +key-wallet = { path = "../key-wallet", features = ["test-utils"] } +tokio = { version = "1", features = ["macros", "rt-multi-thread"] } diff --git a/key-wallet-manager/src/accessors.rs b/key-wallet-manager/src/accessors.rs new file mode 100644 index 000000000..1f72d4616 --- /dev/null +++ b/key-wallet-manager/src/accessors.rs @@ -0,0 +1,213 @@ +//! Accessor and query methods for WalletManager. + +use crate::{ + current_timestamp, WalletCoreBalance, WalletError, WalletEvent, WalletId, WalletManager, +}; +use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; +use key_wallet::wallet::managed_wallet_info::TransactionRecord; +use key_wallet::{Account, Address, Network, Utxo, Wallet}; +use std::collections::{BTreeMap, BTreeSet}; +use tokio::sync::broadcast; + +impl WalletManager { + /// Get a wallet by ID + pub fn get_wallet(&self, wallet_id: &WalletId) -> Option<&Wallet> { + self.wallets.get(wallet_id) + } + + /// Get wallet info by ID + pub fn get_wallet_info(&self, wallet_id: &WalletId) -> Option<&T> { + self.wallet_infos.get(wallet_id) + } + + /// Get mutable wallet info by ID + pub fn get_wallet_info_mut(&mut self, wallet_id: &WalletId) -> Option<&mut T> { + self.wallet_infos.get_mut(wallet_id) + } + + /// Get both wallet and info by ID + pub fn get_wallet_and_info(&self, wallet_id: &WalletId) -> Option<(&Wallet, &T)> { + match (self.wallets.get(wallet_id), self.wallet_infos.get(wallet_id)) { + (Some(wallet), Some(info)) => Some((wallet, info)), + _ => None, + } + } + + /// Remove a wallet + pub fn remove_wallet(&mut self, wallet_id: &WalletId) -> Result<(Wallet, T), WalletError> { + let wallet = + self.wallets.remove(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + let info = + self.wallet_infos.remove(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + // Absorb the removed wallet's account-level revision so the total + // stays monotonically increasing even though we lost a contributor. + self.structural_revision += info.monitor_revision() + 1; + Ok((wallet, info)) + } + + /// List all wallet IDs + pub fn list_wallets(&self) -> Vec<&WalletId> { + self.wallets.keys().collect() + } + + /// Get all wallets + pub fn get_all_wallets(&self) -> &BTreeMap { + &self.wallets + } + + /// Get all wallet infos + pub fn get_all_wallet_infos(&self) -> &BTreeMap { + &self.wallet_infos + } + + /// Get wallet count + pub fn wallet_count(&self) -> usize { + self.wallets.len() + } + + /// Get all accounts in a specific wallet + pub fn get_accounts(&self, wallet_id: &WalletId) -> Result, WalletError> { + let wallet = self.wallets.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + Ok(wallet.all_accounts()) + } + + /// Get account by index in a specific wallet + pub fn get_account( + &self, + wallet_id: &WalletId, + index: u32, + ) -> Result, WalletError> { + let wallet = self.wallets.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + Ok(wallet.get_bip44_account(index)) + } + + /// Get transaction history for a specific wallet + pub fn wallet_transaction_history( + &self, + wallet_id: &WalletId, + ) -> Result, WalletError> { + let managed_info = + self.wallet_infos.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + Ok(managed_info.transaction_history()) + } + + /// Get UTXOs for all wallets across all networks + pub fn get_all_utxos(&self) -> Vec<&Utxo> { + let mut all_utxos = Vec::new(); + for info in self.wallet_infos.values() { + all_utxos.extend(info.utxos().iter()); + } + all_utxos + } + + /// Get UTXOs for a specific wallet + pub fn wallet_utxos(&self, wallet_id: &WalletId) -> Result, WalletError> { + let wallet_info = + self.wallet_infos.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + Ok(wallet_info.utxos()) + } + + /// Get total balance across all wallets and networks + pub fn get_total_balance(&self) -> u64 { + self.wallet_infos.values().map(|info| info.balance().total()).sum() + } + + /// Get balance for a specific wallet + pub fn get_wallet_balance( + &self, + wallet_id: &WalletId, + ) -> Result { + let wallet_info = + self.wallet_infos.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + Ok(wallet_info.balance()) + } + + /// Update wallet metadata + pub fn update_wallet_metadata( + &mut self, + wallet_id: &WalletId, + name: Option, + description: Option, + ) -> Result<(), WalletError> { + let managed_info = + self.wallet_infos.get_mut(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; + + if let Some(new_name) = name { + managed_info.set_name(new_name); + } + + if let Some(desc) = description { + managed_info.set_description(Some(desc)); + } + + managed_info.update_last_synced(current_timestamp()); + + Ok(()) + } + + /// Get the network this manager is configured for + pub fn network(&self) -> Network { + self.network + } + + /// Get monitored addresses for all wallets + pub fn monitored_addresses(&self) -> Vec
{ + let mut addresses = Vec::new(); + for info in self.wallet_infos.values() { + addresses.extend(info.monitored_addresses()); + } + addresses + } + + /// Subscribe to wallet events. + /// + /// Returns a receiver that will receive all wallet events emitted by this manager. + pub fn subscribe_events(&self) -> broadcast::Receiver { + self.event_sender.subscribe() + } + + /// Get a reference to the event sender for emitting events. + pub fn event_sender(&self) -> &broadcast::Sender { + &self.event_sender + } + + /// Return the total monitor revision (structural + per-wallet account revisions). + pub fn monitor_revision(&self) -> u64 { + self.structural_revision + + self.wallet_infos.values().map(|w| w.monitor_revision()).sum::() + } + + /// Snapshot the current balance of every managed wallet. + pub(crate) fn snapshot_balances(&self) -> Vec<(WalletId, WalletCoreBalance)> { + self.wallet_infos.iter().map(|(id, info)| (*id, info.balance())).collect() + } + + /// Emit `BalanceUpdated` events for wallets whose balance differs from the snapshot. + pub(crate) fn emit_balance_changes(&self, old_balances: &[(WalletId, WalletCoreBalance)]) { + for (wallet_id, old_balance) in old_balances { + if let Some(info) = self.wallet_infos.get(wallet_id) { + let new_balance = info.balance(); + if *old_balance != new_balance { + let event = WalletEvent::BalanceUpdated { + wallet_id: *wallet_id, + spendable: new_balance.spendable(), + unconfirmed: new_balance.unconfirmed(), + immature: new_balance.immature(), + locked: new_balance.locked(), + }; + let _ = self.event_sender.send(event); + } + } + } + } + + /// Get all outpoints from wallet UTXOs across all managed wallets. + /// Used for bloom filter construction to detect spends of our UTXOs. + pub fn watched_outpoints(&self) -> Vec { + let mut outpoints = Vec::new(); + for info in self.wallet_infos.values() { + outpoints.extend(info.utxos().into_iter().map(|u| u.outpoint)); + } + outpoints + } +} diff --git a/key-wallet-manager/src/error.rs b/key-wallet-manager/src/error.rs new file mode 100644 index 000000000..9f96b7e2c --- /dev/null +++ b/key-wallet-manager/src/error.rs @@ -0,0 +1,99 @@ +//! Error types for the wallet manager. + +use crate::WalletId; + +/// Wallet manager errors +#[derive(Debug)] +pub enum WalletError { + /// Wallet creation failed + WalletCreation(String), + /// Wallet not found + WalletNotFound(WalletId), + /// Wallet already exists + WalletExists(WalletId), + /// Invalid mnemonic + InvalidMnemonic(String), + /// Account creation failed + AccountCreation(String), + /// Account not found + AccountNotFound(u32), + /// Address generation failed + AddressGeneration(String), + /// Invalid network + InvalidNetwork, + /// Invalid parameter + InvalidParameter(String), + /// Transaction building failed + TransactionBuild(String), + /// Insufficient funds + InsufficientFunds, +} + +impl core::fmt::Display for WalletError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + WalletError::WalletCreation(msg) => write!(f, "Wallet creation failed: {}", msg), + WalletError::WalletNotFound(id) => { + write!(f, "Wallet not found: ")?; + for byte in id.iter() { + write!(f, "{:02x}", byte)?; + } + Ok(()) + } + WalletError::WalletExists(id) => { + write!(f, "Wallet already exists: ")?; + for byte in id.iter() { + write!(f, "{:02x}", byte)?; + } + Ok(()) + } + WalletError::InvalidMnemonic(msg) => write!(f, "Invalid mnemonic: {}", msg), + WalletError::AccountCreation(msg) => write!(f, "Account creation failed: {}", msg), + WalletError::AccountNotFound(idx) => write!(f, "Account not found: {}", idx), + WalletError::AddressGeneration(msg) => write!(f, "Address generation failed: {}", msg), + WalletError::InvalidNetwork => write!(f, "Invalid network"), + WalletError::InvalidParameter(msg) => write!(f, "Invalid parameter: {}", msg), + WalletError::TransactionBuild(err) => write!(f, "Transaction build failed: {}", err), + WalletError::InsufficientFunds => write!(f, "Insufficient funds"), + } + } +} + +impl std::error::Error for WalletError {} + +/// Conversion from key_wallet::Error to WalletError +impl From for WalletError { + fn from(err: key_wallet::Error) -> Self { + use key_wallet::Error; + + match err { + Error::InvalidMnemonic(msg) => WalletError::InvalidMnemonic(msg), + Error::InvalidDerivationPath(msg) => { + WalletError::InvalidParameter(format!("Invalid derivation path: {}", msg)) + } + Error::InvalidAddress(msg) => { + WalletError::AddressGeneration(format!("Invalid address: {}", msg)) + } + Error::InvalidNetwork => WalletError::InvalidNetwork, + Error::InvalidParameter(msg) => WalletError::InvalidParameter(msg), + Error::WatchOnly => WalletError::InvalidParameter( + "Operation not supported on watch-only wallet".to_string(), + ), + Error::CoinJoinNotEnabled => { + WalletError::InvalidParameter("CoinJoin not enabled".to_string()) + } + Error::KeyError(msg) => WalletError::AccountCreation(format!("Key error: {}", msg)), + Error::Serialization(msg) => { + WalletError::InvalidParameter(format!("Serialization error: {}", msg)) + } + Error::Bip32(e) => WalletError::AccountCreation(format!("BIP32 error: {}", e)), + Error::Secp256k1(e) => WalletError::AccountCreation(format!("Secp256k1 error: {}", e)), + Error::Base58 => WalletError::InvalidParameter("Base58 decoding error".to_string()), + Error::NoKeySource => { + WalletError::InvalidParameter("No key source available".to_string()) + } + #[allow(unreachable_patterns)] + _ => WalletError::InvalidParameter(format!("Key wallet error: {}", err)), + } + } +} diff --git a/key-wallet/src/manager/event_tests.rs b/key-wallet-manager/src/event_tests.rs similarity index 99% rename from key-wallet/src/manager/event_tests.rs rename to key-wallet-manager/src/event_tests.rs index afc02f604..a22237861 100644 --- a/key-wallet/src/manager/event_tests.rs +++ b/key-wallet-manager/src/event_tests.rs @@ -1,9 +1,9 @@ use super::test_helpers::*; use super::*; -use crate::manager::wallet_interface::WalletInterface; -use crate::transaction_checking::BlockInfo; +use crate::wallet_interface::WalletInterface; use dashcore::hashes::Hash; use dashcore::BlockHash; +use key_wallet::transaction_checking::BlockInfo; // --------------------------------------------------------------------------- // Lifecycle flow tests diff --git a/key-wallet/src/manager/events.rs b/key-wallet-manager/src/events.rs similarity index 97% rename from key-wallet/src/manager/events.rs rename to key-wallet-manager/src/events.rs index 1049294a6..7fc63ceab 100644 --- a/key-wallet/src/manager/events.rs +++ b/key-wallet-manager/src/events.rs @@ -3,9 +3,9 @@ //! These events are emitted by the WalletManager when significant wallet //! operations occur, allowing consumers to receive push-based notifications. -use crate::manager::WalletId; -use crate::transaction_checking::TransactionContext; +use crate::WalletId; use dashcore::{Address, Amount, SignedAmount, Txid}; +use key_wallet::transaction_checking::TransactionContext; /// Events emitted by the wallet manager. /// diff --git a/key-wallet/src/manager/mod.rs b/key-wallet-manager/src/lib.rs similarity index 74% rename from key-wallet/src/manager/mod.rs rename to key-wallet-manager/src/lib.rs index 138ac463a..493acb58d 100644 --- a/key-wallet/src/manager/mod.rs +++ b/key-wallet-manager/src/lib.rs @@ -1,3 +1,6 @@ +/// Re-export key-wallet so consumers can access wallet primitives through this crate. +pub use key_wallet; + /// High-level wallet management for Dash /// /// This module provides high-level wallet functionality that builds on top of @@ -9,26 +12,28 @@ /// - BIP 157/158 compact block filter support /// - Address generation and gap limit handling /// - Blockchain synchronization +mod accessors; +mod error; mod events; mod matching; mod process_block; mod wallet_interface; +pub use error::WalletError; pub use events::WalletEvent; pub use matching::{check_compact_filters_for_addresses, FilterMatchKey}; pub use wallet_interface::{BlockProcessingResult, MempoolTransactionResult, WalletInterface}; -use crate::account::AccountCollection; -use crate::transaction_checking::TransactionContext; -use crate::wallet::managed_wallet_info::transaction_building::AccountTypePreference; -use crate::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; -use crate::wallet::managed_wallet_info::{ManagedWalletInfo, TransactionRecord}; -use crate::Utxo; -use crate::{Account, AccountType, Address, ExtendedPrivKey, Mnemonic, Network, Wallet}; -use crate::{ExtendedPubKey, WalletCoreBalance}; use dashcore::blockdata::transaction::Transaction; use dashcore::prelude::CoreBlockHeight; -use std::collections::{BTreeMap, BTreeSet}; +use key_wallet::account::AccountCollection; +use key_wallet::transaction_checking::TransactionContext; +use key_wallet::wallet::managed_wallet_info::transaction_building::AccountTypePreference; +use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; +use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet::{AccountType, Address, ExtendedPrivKey, Mnemonic, Network, Wallet}; +use key_wallet::{ExtendedPubKey, WalletCoreBalance}; +use std::collections::BTreeMap; use std::str::FromStr; use tokio::sync::broadcast; @@ -115,24 +120,6 @@ impl WalletManager { } } - /// Subscribe to wallet events. - /// - /// Returns a receiver that will receive all wallet events emitted by this manager. - pub fn subscribe_events(&self) -> broadcast::Receiver { - self.event_sender.subscribe() - } - - /// Get a reference to the event sender for emitting events. - pub fn event_sender(&self) -> &broadcast::Sender { - &self.event_sender - } - - /// Return the total monitor revision (structural + per-wallet account revisions). - pub fn monitor_revision(&self) -> u64 { - self.structural_revision - + self.wallet_infos.values().map(|w| w.monitor_revision()).sum::() - } - /// Increment the structural revision for wallet/account additions or removals. fn bump_structural_revision(&mut self) { self.structural_revision += 1; @@ -145,9 +132,9 @@ impl WalletManager { mnemonic: &str, passphrase: &str, birth_height: CoreBlockHeight, - account_creation_options: crate::wallet::initialization::WalletAccountCreationOptions, + account_creation_options: key_wallet::wallet::initialization::WalletAccountCreationOptions, ) -> Result { - let mnemonic_obj = Mnemonic::from_phrase(mnemonic, crate::mnemonic::Language::English) + let mnemonic_obj = Mnemonic::from_phrase(mnemonic, key_wallet::mnemonic::Language::English) .map_err(|e| WalletError::InvalidMnemonic(e.to_string()))?; // Use appropriate wallet creation method based on whether a passphrase is provided @@ -221,14 +208,14 @@ impl WalletManager { mnemonic: &str, passphrase: &str, birth_height: CoreBlockHeight, - account_creation_options: crate::wallet::initialization::WalletAccountCreationOptions, + account_creation_options: key_wallet::wallet::initialization::WalletAccountCreationOptions, downgrade_to_pubkey_wallet: bool, allow_external_signing: bool, ) -> Result<(Vec, WalletId), WalletError> { - use crate::wallet::WalletType; + use key_wallet::wallet::WalletType; use zeroize::Zeroize; - let mnemonic_obj = Mnemonic::from_phrase(mnemonic, crate::mnemonic::Language::English) + let mnemonic_obj = Mnemonic::from_phrase(mnemonic, key_wallet::mnemonic::Language::English) .map_err(|e| WalletError::InvalidMnemonic(e.to_string()))?; // Create the initial wallet from mnemonic @@ -305,12 +292,13 @@ impl WalletManager { /// Returns the generated wallet ID pub fn create_wallet_with_random_mnemonic( &mut self, - account_creation_options: crate::wallet::initialization::WalletAccountCreationOptions, + account_creation_options: key_wallet::wallet::initialization::WalletAccountCreationOptions, ) -> Result { // Generate a random mnemonic (24 words for maximum security) - let mnemonic = Mnemonic::generate(24, crate::mnemonic::Language::English).map_err(|e| { - WalletError::WalletCreation(format!("Failed to generate mnemonic: {}", e)) - })?; + let mnemonic = + Mnemonic::generate(24, key_wallet::mnemonic::Language::English).map_err(|e| { + WalletError::WalletCreation(format!("Failed to generate mnemonic: {}", e)) + })?; let wallet = Wallet::from_mnemonic(mnemonic, self.network, account_creation_options) .map_err(|e| WalletError::WalletCreation(e.to_string()))?; @@ -334,61 +322,6 @@ impl WalletManager { Ok(wallet_id) } - /// Get a wallet by ID - pub fn get_wallet(&self, wallet_id: &WalletId) -> Option<&Wallet> { - self.wallets.get(wallet_id) - } - - /// Get wallet info by ID - pub fn get_wallet_info(&self, wallet_id: &WalletId) -> Option<&T> { - self.wallet_infos.get(wallet_id) - } - - /// Get mutable wallet info by ID - pub fn get_wallet_info_mut(&mut self, wallet_id: &WalletId) -> Option<&mut T> { - self.wallet_infos.get_mut(wallet_id) - } - - /// Get both wallet and info by ID - pub fn get_wallet_and_info(&self, wallet_id: &WalletId) -> Option<(&Wallet, &T)> { - match (self.wallets.get(wallet_id), self.wallet_infos.get(wallet_id)) { - (Some(wallet), Some(info)) => Some((wallet, info)), - _ => None, - } - } - - /// Remove a wallet - pub fn remove_wallet(&mut self, wallet_id: &WalletId) -> Result<(Wallet, T), WalletError> { - let wallet = - self.wallets.remove(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - let info = - self.wallet_infos.remove(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - // Absorb the removed wallet's account-level revision so the total - // stays monotonically increasing even though we lost a contributor. - self.structural_revision += info.monitor_revision() + 1; - Ok((wallet, info)) - } - - /// List all wallet IDs - pub fn list_wallets(&self) -> Vec<&WalletId> { - self.wallets.keys().collect() - } - - /// Get all wallets - pub fn get_all_wallets(&self) -> &BTreeMap { - &self.wallets - } - - /// Get all wallet infos - pub fn get_all_wallet_infos(&self) -> &BTreeMap { - &self.wallet_infos - } - - /// Get wallet count - pub fn wallet_count(&self) -> usize { - self.wallets.len() - } - /// Import a wallet from an extended private key and add it to the manager /// /// # Arguments @@ -401,7 +334,7 @@ impl WalletManager { pub fn import_wallet_from_extended_priv_key( &mut self, xprv: &str, - account_creation_options: crate::wallet::initialization::WalletAccountCreationOptions, + account_creation_options: key_wallet::wallet::initialization::WalletAccountCreationOptions, ) -> Result { // Parse the extended private key let extended_priv_key = ExtendedPrivKey::from_str(xprv) @@ -635,24 +568,6 @@ impl WalletManager { Ok(()) } - /// Get all accounts in a specific wallet - pub fn get_accounts(&self, wallet_id: &WalletId) -> Result, WalletError> { - let wallet = self.wallets.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - - Ok(wallet.all_accounts()) - } - - /// Get account by index in a specific wallet - pub fn get_account( - &self, - wallet_id: &WalletId, - index: u32, - ) -> Result, WalletError> { - let wallet = self.wallets.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - - Ok(wallet.get_bip44_account(index)) - } - /// Get receive address from a specific wallet and account pub fn get_receive_address( &mut self, @@ -981,184 +896,6 @@ impl WalletManager { account_type_used, }) } - - /// Get transaction history for a specific wallet - pub fn wallet_transaction_history( - &self, - wallet_id: &WalletId, - ) -> Result, WalletError> { - let managed_info = - self.wallet_infos.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - - Ok(managed_info.transaction_history()) - } - - /// Get UTXOs for all wallets across all networks - pub fn get_all_utxos(&self) -> Vec<&Utxo> { - let mut all_utxos = Vec::new(); - for info in self.wallet_infos.values() { - all_utxos.extend(info.utxos().iter()); - } - all_utxos - } - - /// Get UTXOs for a specific wallet - pub fn wallet_utxos(&self, wallet_id: &WalletId) -> Result, WalletError> { - // Get the wallet info - let wallet_info = - self.wallet_infos.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - - // Get UTXOs from the wallet info and clone them - let utxos = wallet_info.utxos(); - - Ok(utxos) - } - - /// Get total balance across all wallets and networks - pub fn get_total_balance(&self) -> u64 { - self.wallet_infos.values().map(|info| info.balance().total()).sum() - } - - /// Get balance for a specific wallet - pub fn get_wallet_balance( - &self, - wallet_id: &WalletId, - ) -> Result { - // Get the wallet info - let wallet_info = - self.wallet_infos.get(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - - // Get balance from the wallet info - Ok(wallet_info.balance()) - } - - /// Update wallet metadata - pub fn update_wallet_metadata( - &mut self, - wallet_id: &WalletId, - name: Option, - description: Option, - ) -> Result<(), WalletError> { - let managed_info = - self.wallet_infos.get_mut(wallet_id).ok_or(WalletError::WalletNotFound(*wallet_id))?; - - if let Some(new_name) = name { - managed_info.set_name(new_name); - } - - if let Some(desc) = description { - managed_info.set_description(Some(desc)); - } - - managed_info.update_last_synced(current_timestamp()); - - Ok(()) - } - - /// Get the network this manager is configured for - pub fn network(&self) -> Network { - self.network - } - - /// Get monitored addresses for all wallets for a specific network - pub fn monitored_addresses(&self) -> Vec
{ - let mut addresses = Vec::new(); - for info in self.wallet_infos.values() { - addresses.extend(info.monitored_addresses()); - } - addresses - } - - /// Snapshot the current balance of every managed wallet. - pub(crate) fn snapshot_balances(&self) -> Vec<(WalletId, WalletCoreBalance)> { - self.wallet_infos.iter().map(|(id, info)| (*id, info.balance())).collect() - } - - /// Emit `BalanceUpdated` events for wallets whose balance differs from the snapshot. - pub(crate) fn emit_balance_changes(&self, old_balances: &[(WalletId, WalletCoreBalance)]) { - for (wallet_id, old_balance) in old_balances { - if let Some(info) = self.wallet_infos.get(wallet_id) { - let new_balance = info.balance(); - if *old_balance != new_balance { - let event = WalletEvent::BalanceUpdated { - wallet_id: *wallet_id, - spendable: new_balance.spendable(), - unconfirmed: new_balance.unconfirmed(), - immature: new_balance.immature(), - locked: new_balance.locked(), - }; - let _ = self.event_sender.send(event); - } - } - } - } - - /// Get all outpoints from wallet UTXOs across all managed wallets. - /// Used for bloom filter construction to detect spends of our UTXOs. - pub fn watched_outpoints(&self) -> Vec { - let mut outpoints = Vec::new(); - for info in self.wallet_infos.values() { - outpoints.extend(info.utxos().into_iter().map(|u| u.outpoint)); - } - outpoints - } -} - -/// Wallet manager errors -#[derive(Debug)] -pub enum WalletError { - /// Wallet creation failed - WalletCreation(String), - /// Wallet not found - WalletNotFound(WalletId), - /// Wallet already exists - WalletExists(WalletId), - /// Invalid mnemonic - InvalidMnemonic(String), - /// Account creation failed - AccountCreation(String), - /// Account not found - AccountNotFound(u32), - /// Address generation failed - AddressGeneration(String), - /// Invalid network - InvalidNetwork, - /// Invalid parameter - InvalidParameter(String), - /// Transaction building failed - TransactionBuild(String), - /// Insufficient funds - InsufficientFunds, -} - -impl core::fmt::Display for WalletError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - WalletError::WalletCreation(msg) => write!(f, "Wallet creation failed: {}", msg), - WalletError::WalletNotFound(id) => { - write!(f, "Wallet not found: ")?; - for byte in id.iter() { - write!(f, "{:02x}", byte)?; - } - Ok(()) - } - WalletError::WalletExists(id) => { - write!(f, "Wallet already exists: ")?; - for byte in id.iter() { - write!(f, "{:02x}", byte)?; - } - Ok(()) - } - WalletError::InvalidMnemonic(msg) => write!(f, "Invalid mnemonic: {}", msg), - WalletError::AccountCreation(msg) => write!(f, "Account creation failed: {}", msg), - WalletError::AccountNotFound(idx) => write!(f, "Account not found: {}", idx), - WalletError::AddressGeneration(msg) => write!(f, "Address generation failed: {}", msg), - WalletError::InvalidNetwork => write!(f, "Invalid network"), - WalletError::InvalidParameter(msg) => write!(f, "Invalid parameter: {}", msg), - WalletError::TransactionBuild(err) => write!(f, "Transaction build failed: {}", err), - WalletError::InsufficientFunds => write!(f, "Insufficient funds"), - } - } } /// Helper function for getting current timestamp @@ -1166,46 +903,10 @@ fn current_timestamp() -> u64 { std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_secs() } -impl std::error::Error for WalletError {} - #[cfg(test)] mod event_tests; #[cfg(test)] mod test_helpers; -/// Conversion from crate::Error to WalletError -impl From for WalletError { - fn from(err: crate::Error) -> Self { - use crate::Error; - - match err { - Error::InvalidMnemonic(msg) => WalletError::InvalidMnemonic(msg), - Error::InvalidDerivationPath(msg) => { - WalletError::InvalidParameter(format!("Invalid derivation path: {}", msg)) - } - Error::InvalidAddress(msg) => { - WalletError::AddressGeneration(format!("Invalid address: {}", msg)) - } - Error::InvalidNetwork => WalletError::InvalidNetwork, - Error::InvalidParameter(msg) => WalletError::InvalidParameter(msg), - Error::WatchOnly => WalletError::InvalidParameter( - "Operation not supported on watch-only wallet".to_string(), - ), - Error::CoinJoinNotEnabled => { - WalletError::InvalidParameter("CoinJoin not enabled".to_string()) - } - Error::KeyError(msg) => WalletError::AccountCreation(format!("Key error: {}", msg)), - Error::Serialization(msg) => { - WalletError::InvalidParameter(format!("Serialization error: {}", msg)) - } - Error::Bip32(e) => WalletError::AccountCreation(format!("BIP32 error: {}", e)), - Error::Secp256k1(e) => WalletError::AccountCreation(format!("Secp256k1 error: {}", e)), - Error::Base58 => WalletError::InvalidParameter("Base58 decoding error".to_string()), - Error::NoKeySource => { - WalletError::InvalidParameter("No key source available".to_string()) - } - #[allow(unreachable_patterns)] - _ => WalletError::InvalidParameter(format!("Key wallet error: {}", err)), - } - } -} +#[cfg(any(test, feature = "test-utils"))] +pub mod test_utils; diff --git a/key-wallet/src/manager/matching.rs b/key-wallet-manager/src/matching.rs similarity index 99% rename from key-wallet/src/manager/matching.rs rename to key-wallet-manager/src/matching.rs index f976cd269..0b61289f8 100644 --- a/key-wallet/src/manager/matching.rs +++ b/key-wallet-manager/src/matching.rs @@ -55,8 +55,8 @@ pub fn check_compact_filters_for_addresses( #[cfg(test)] mod tests { use super::*; - use crate::Network; use dashcore::{Block, Transaction}; + use key_wallet::Network; #[test] fn test_empty_input_returns_empty() { diff --git a/key-wallet/src/manager/process_block.rs b/key-wallet-manager/src/process_block.rs similarity index 95% rename from key-wallet/src/manager/process_block.rs rename to key-wallet-manager/src/process_block.rs index bfb9848a1..7b7e0d3d1 100644 --- a/key-wallet/src/manager/process_block.rs +++ b/key-wallet-manager/src/process_block.rs @@ -1,14 +1,12 @@ -use crate::manager::wallet_interface::{ - BlockProcessingResult, MempoolTransactionResult, WalletInterface, -}; -use crate::manager::{WalletEvent, WalletManager}; -use crate::transaction_checking::transaction_router::TransactionRouter; -use crate::transaction_checking::{BlockInfo, TransactionContext}; -use crate::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; +use crate::wallet_interface::{BlockProcessingResult, MempoolTransactionResult, WalletInterface}; +use crate::{WalletEvent, WalletManager}; use async_trait::async_trait; use core::fmt::Write as _; use dashcore::prelude::CoreBlockHeight; use dashcore::{Address, Block, Transaction, Txid}; +use key_wallet::transaction_checking::transaction_router::TransactionRouter; +use key_wallet::transaction_checking::{BlockInfo, TransactionContext}; +use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; use std::collections::BTreeSet; use tokio::sync::broadcast; @@ -228,18 +226,18 @@ impl WalletInterface for WalletM #[cfg(test)] mod tests { use super::*; - use crate::account::StandardAccountType; - use crate::manager::test_helpers::*; - use crate::wallet::initialization::WalletAccountCreationOptions; - use crate::wallet::managed_wallet_info::transaction_building::AccountTypePreference; - use crate::wallet::managed_wallet_info::ManagedWalletInfo; - use crate::AccountType; + use crate::test_helpers::*; use dashcore::block::{Header, Version}; use dashcore::hashes::Hash; use dashcore::pow::CompactTarget; use dashcore::{ BlockHash, Network, OutPoint, ScriptBuf, TxIn, TxMerkleNode, TxOut, Txid, Witness, }; + use key_wallet::account::StandardAccountType; + use key_wallet::wallet::initialization::WalletAccountCreationOptions; + use key_wallet::wallet::managed_wallet_info::transaction_building::AccountTypePreference; + use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; + use key_wallet::AccountType; fn make_block(txdata: Vec) -> Block { Block { diff --git a/key-wallet/src/manager/test_helpers.rs b/key-wallet-manager/src/test_helpers.rs similarity index 96% rename from key-wallet/src/manager/test_helpers.rs rename to key-wallet-manager/src/test_helpers.rs index ebd882c04..268bf6a47 100644 --- a/key-wallet/src/manager/test_helpers.rs +++ b/key-wallet-manager/src/test_helpers.rs @@ -1,9 +1,9 @@ use super::*; -use crate::wallet::initialization::WalletAccountCreationOptions; -use crate::wallet::managed_wallet_info::ManagedWalletInfo; -use crate::Network; use dashcore::hashes::Hash; use dashcore::{OutPoint, ScriptBuf, TxIn, TxOut, Txid, Witness}; +use key_wallet::wallet::initialization::WalletAccountCreationOptions; +use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use key_wallet::Network; use tokio::sync::broadcast; pub(crate) const TEST_MNEMONIC: &str = diff --git a/key-wallet/src/test_utils/mock_wallet.rs b/key-wallet-manager/src/test_utils/mock_wallet.rs similarity index 97% rename from key-wallet/src/test_utils/mock_wallet.rs rename to key-wallet-manager/src/test_utils/mock_wallet.rs index 856dc31e0..9c19472ce 100644 --- a/key-wallet/src/test_utils/mock_wallet.rs +++ b/key-wallet-manager/src/test_utils/mock_wallet.rs @@ -1,9 +1,9 @@ -use crate::manager::MempoolTransactionResult; -use crate::manager::{BlockProcessingResult, WalletEvent, WalletInterface}; -use crate::transaction_checking::TransactionContext; +use crate::MempoolTransactionResult; +use crate::{BlockProcessingResult, WalletEvent, WalletInterface}; use dashcore::address::NetworkUnchecked; use dashcore::prelude::CoreBlockHeight; use dashcore::{Address, Block, OutPoint, Transaction, Txid}; +use key_wallet::transaction_checking::TransactionContext; use std::collections::BTreeMap; use std::str::FromStr; use std::sync::Arc; diff --git a/key-wallet-manager/src/test_utils/mod.rs b/key-wallet-manager/src/test_utils/mod.rs new file mode 100644 index 000000000..108a02fd5 --- /dev/null +++ b/key-wallet-manager/src/test_utils/mod.rs @@ -0,0 +1,4 @@ +mod mock_wallet; + +pub use mock_wallet::MockWallet; +pub use mock_wallet::NonMatchingMockWallet; diff --git a/key-wallet/src/manager/wallet_interface.rs b/key-wallet-manager/src/wallet_interface.rs similarity index 99% rename from key-wallet/src/manager/wallet_interface.rs rename to key-wallet-manager/src/wallet_interface.rs index fd2e69023..cdd5dbb39 100644 --- a/key-wallet/src/manager/wallet_interface.rs +++ b/key-wallet-manager/src/wallet_interface.rs @@ -2,7 +2,7 @@ //! //! This module defines the trait that SPV clients use to interact with wallets. -use crate::manager::WalletEvent; +use crate::WalletEvent; use async_trait::async_trait; use dashcore::prelude::CoreBlockHeight; use dashcore::{Address, Block, OutPoint, Transaction, Txid}; diff --git a/key-wallet/Cargo.toml b/key-wallet/Cargo.toml index 336f5cae2..653724bd4 100644 --- a/key-wallet/Cargo.toml +++ b/key-wallet/Cargo.toml @@ -9,9 +9,7 @@ readme = "README.md" license = "CC0-1.0" [features] -default = ["getrandom", "manager"] -manager = ["dep:tokio"] -parallel-filters = ["manager", "dep:rayon"] +default = ["getrandom"] serde = ["dep:serde", "dep:serde_json", "dashcore_hashes/serde", "secp256k1/serde", "dashcore/serde"] bincode = ["serde", "dep:bincode", "dep:bincode_derive", "dashcore_hashes/bincode", "dashcore/bincode"] bip38 = ["scrypt", "aes", "bs58", "rand"] @@ -44,12 +42,12 @@ hex = { version = "0.4"} zeroize = { version = "1.8", features = ["derive"] } tracing = "0.1" async-trait = "0.1" -tokio = { version = "1", features = ["macros", "rt", "sync"], optional = true } -rayon = { version = "1.11", optional = true } [dev-dependencies] dashcore = { path="../dash", features = ["test-utils"] } hex = "0.4" key-wallet = { path = ".", features = ["test-utils", "bip38", "serde", "bincode", "eddsa", "bls"] } +key-wallet-manager = { path = "../key-wallet-manager", features = ["test-utils", "bincode"] } +tokio = { version = "1", features = ["macros", "rt"] } rand = { version = "0.8", features = ["std", "std_rng"] } test-case = "3.3" diff --git a/key-wallet/examples/wallet_creation.rs b/key-wallet/examples/wallet_creation.rs index 5d0943cf0..4529f5bb7 100644 --- a/key-wallet/examples/wallet_creation.rs +++ b/key-wallet/examples/wallet_creation.rs @@ -6,12 +6,12 @@ //! - Managing wallet accounts and addresses use key_wallet::account::StandardAccountType; -use key_wallet::manager::WalletInterface; -use key_wallet::manager::WalletManager; use key_wallet::wallet::initialization::WalletAccountCreationOptions; use key_wallet::wallet::managed_wallet_info::transaction_building::AccountTypePreference; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; use key_wallet::{AccountType, Network}; +use key_wallet_manager::WalletInterface; +use key_wallet_manager::WalletManager; fn main() { println!("=== Wallet Creation Example ===\n"); diff --git a/key-wallet/src/lib.rs b/key-wallet/src/lib.rs index d6c8a81a5..e12224ae4 100644 --- a/key-wallet/src/lib.rs +++ b/key-wallet/src/lib.rs @@ -35,8 +35,6 @@ pub mod dip9; pub mod error; pub mod gap_limit; pub mod managed_account; -#[cfg(feature = "manager")] -pub mod manager; pub mod mnemonic; pub mod psbt; pub mod seed; diff --git a/key-wallet/src/test_utils/mod.rs b/key-wallet/src/test_utils/mod.rs index bb5390835..d9de8de38 100644 --- a/key-wallet/src/test_utils/mod.rs +++ b/key-wallet/src/test_utils/mod.rs @@ -1,11 +1,5 @@ mod account; -#[cfg(feature = "manager")] -mod mock_wallet; mod utxo; mod wallet; -#[cfg(feature = "manager")] -pub use mock_wallet::MockWallet; -#[cfg(feature = "manager")] -pub use mock_wallet::NonMatchingMockWallet; pub use wallet::TestWalletContext; diff --git a/key-wallet/tests/integration_test.rs b/key-wallet/tests/integration_test.rs index 37d7580c8..e48674469 100644 --- a/key-wallet/tests/integration_test.rs +++ b/key-wallet/tests/integration_test.rs @@ -3,13 +3,13 @@ //! These tests verify that the high-level wallet management functionality //! works correctly with the low-level key-wallet primitives. -use key_wallet::manager::WalletInterface; -use key_wallet::manager::{WalletError, WalletManager}; use key_wallet::wallet::initialization::WalletAccountCreationOptions; use key_wallet::wallet::managed_wallet_info::transaction_building::AccountTypePreference; use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; use key_wallet::{mnemonic::Language, Mnemonic, Network}; +use key_wallet_manager::WalletInterface; +use key_wallet_manager::{WalletError, WalletManager}; #[test] fn test_wallet_manager_creation() { diff --git a/key-wallet/tests/spv_integration_tests.rs b/key-wallet/tests/spv_integration_tests.rs index d3fd99655..ddcffc29a 100644 --- a/key-wallet/tests/spv_integration_tests.rs +++ b/key-wallet/tests/spv_integration_tests.rs @@ -4,12 +4,12 @@ use dashcore::blockdata::block::Block; use dashcore::blockdata::transaction::Transaction; use dashcore::constants::COINBASE_MATURITY; use dashcore::Address; -use key_wallet::manager::WalletInterface; -use key_wallet::manager::WalletManager; use key_wallet::wallet::initialization::WalletAccountCreationOptions; use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; use key_wallet::Network; +use key_wallet_manager::WalletInterface; +use key_wallet_manager::WalletManager; #[tokio::test] async fn test_block_processing() { diff --git a/key-wallet/tests/test_serialized_wallets.rs b/key-wallet/tests/test_serialized_wallets.rs index 0dd9b8f44..015f19c7c 100644 --- a/key-wallet/tests/test_serialized_wallets.rs +++ b/key-wallet/tests/test_serialized_wallets.rs @@ -1,10 +1,10 @@ #[cfg(feature = "bincode")] #[cfg(test)] mod tests { - use key_wallet::manager::WalletManager; use key_wallet::wallet::initialization::WalletAccountCreationOptions; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; use key_wallet::Network; + use key_wallet_manager::WalletManager; #[test] fn test_create_wallet_return_serialized_bytes() {