diff --git a/key-wallet-ffi/Cargo.toml b/key-wallet-ffi/Cargo.toml index 23edb7c31..804cbf930 100644 --- a/key-wallet-ffi/Cargo.toml +++ b/key-wallet-ffi/Cargo.toml @@ -13,9 +13,9 @@ name = "key_wallet_ffi" crate-type = ["cdylib", "staticlib", "lib"] [features] -default = ["bincode", "eddsa", "bls", "bip38"] +default = ["serde", "eddsa", "bls", "bip38"] bip38 = ["key-wallet/bip38"] -bincode = ["key-wallet-manager/bincode", "key-wallet/bincode"] +serde = ["key-wallet/serde", "key-wallet-manager/serde"] eddsa = ["dashcore/eddsa", "key-wallet/eddsa"] bls = ["dashcore/bls", "key-wallet/bls"] diff --git a/key-wallet-ffi/src/wallet_manager.rs b/key-wallet-ffi/src/wallet_manager.rs index e209af61f..8ecc1af24 100644 --- a/key-wallet-ffi/src/wallet_manager.rs +++ b/key-wallet-ffi/src/wallet_manager.rs @@ -277,7 +277,7 @@ pub unsafe extern "C" fn wallet_manager_add_wallet_from_mnemonic( /// - `error` must be a valid pointer to an FFIError structure or null /// - The caller must ensure all pointers remain valid for the duration of this call /// - The caller must free the returned wallet_bytes using wallet_manager_free_wallet_bytes() -#[cfg(feature = "bincode")] +#[cfg(feature = "serde")] #[no_mangle] pub unsafe extern "C" fn wallet_manager_add_wallet_from_mnemonic_return_serialized_bytes( manager: *mut FFIWalletManager, @@ -397,7 +397,7 @@ pub unsafe extern "C" fn wallet_manager_add_wallet_from_mnemonic_return_serializ /// - `bytes_len` must match the original allocation size /// - The pointer must not be used after calling this function /// - This function must only be called once per buffer -#[cfg(feature = "bincode")] +#[cfg(feature = "serde")] #[no_mangle] pub unsafe extern "C" fn wallet_manager_free_wallet_bytes(wallet_bytes: *mut u8, bytes_len: usize) { if !wallet_bytes.is_null() && bytes_len > 0 { @@ -422,7 +422,7 @@ pub unsafe extern "C" fn wallet_manager_free_wallet_bytes(wallet_bytes: *mut u8, /// - `wallet_id_out` must be a valid pointer to a 32-byte array that will receive the wallet ID /// - `error` must be a valid pointer to an FFIError structure or null /// - The caller must ensure all pointers remain valid for the duration of this call -#[cfg(feature = "bincode")] +#[cfg(feature = "serde")] #[no_mangle] pub unsafe extern "C" fn wallet_manager_import_wallet_from_bytes( manager: *mut FFIWalletManager, diff --git a/key-wallet-ffi/src/wallet_manager_serialization_tests.rs b/key-wallet-ffi/src/wallet_manager_serialization_tests.rs index 7b5f33f6e..c418ab719 100644 --- a/key-wallet-ffi/src/wallet_manager_serialization_tests.rs +++ b/key-wallet-ffi/src/wallet_manager_serialization_tests.rs @@ -1,6 +1,6 @@ //! Tests for wallet serialization FFI functions -#[cfg(all(test, feature = "bincode"))] +#[cfg(all(test, feature = "serde"))] mod tests { use crate::error::{FFIError, FFIErrorCode}; use crate::types::FFIWalletAccountCreationOptions; diff --git a/key-wallet-ffi/src/wallet_manager_tests.rs b/key-wallet-ffi/src/wallet_manager_tests.rs index d1f9720e5..95fd1068a 100644 --- a/key-wallet-ffi/src/wallet_manager_tests.rs +++ b/key-wallet-ffi/src/wallet_manager_tests.rs @@ -864,7 +864,7 @@ mod tests { } } - #[cfg(feature = "bincode")] + #[cfg(feature = "serde")] #[test] fn test_create_wallet_from_mnemonic_return_serialized_bytes() { let mut error = FFIError::success(); @@ -1062,7 +1062,7 @@ mod tests { } } - #[cfg(feature = "bincode")] + #[cfg(feature = "serde")] #[test] fn test_serialized_wallet_across_managers() { let mut error = FFIError::success(); diff --git a/key-wallet-ffi/tests/test_import_wallet.rs b/key-wallet-ffi/tests/test_import_wallet.rs index ddf0f4042..c71bbac02 100644 --- a/key-wallet-ffi/tests/test_import_wallet.rs +++ b/key-wallet-ffi/tests/test_import_wallet.rs @@ -1,6 +1,6 @@ //! Test for wallet import from bytes via FFI -#[cfg(feature = "bincode")] +#[cfg(feature = "serde")] #[cfg(test)] mod tests { use key_wallet_ffi::error::{FFIError, FFIErrorCode}; diff --git a/key-wallet-manager/Cargo.toml b/key-wallet-manager/Cargo.toml index 78e7bbe6c..79f793b0d 100644 --- a/key-wallet-manager/Cargo.toml +++ b/key-wallet-manager/Cargo.toml @@ -9,11 +9,10 @@ readme = "README.md" license = "CC0-1.0" [features] -default = ["std", "bincode"] +default = ["std", "serde", "bincode"] std = ["key-wallet/std", "dashcore/std", "dashcore_hashes/std", "secp256k1/std"] serde = ["dep:serde", "key-wallet/serde", "dashcore/serde"] getrandom = ["key-wallet/getrandom"] -bincode = ["dep:bincode", "key-wallet/bincode"] test-utils = [] [dependencies] @@ -22,8 +21,8 @@ dashcore = { path = "../dash", default-features = false } dashcore_hashes = { path = "../hashes", default-features = false } secp256k1 = { version = "0.30.0", default-features = false, features = ["recovery"] } serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } +bincode = { version = "2.0.1", optional = true, features = ["serde"] } async-trait = "0.1" -bincode = { version = "2.0.1", optional = true } zeroize = { version = "1.8", features = ["derive"] } rayon = "1.11" tokio = { version = "1.32", features = ["full"] } diff --git a/key-wallet-manager/src/wallet_manager/mod.rs b/key-wallet-manager/src/wallet_manager/mod.rs index 944a16b0c..80405e805 100644 --- a/key-wallet-manager/src/wallet_manager/mod.rs +++ b/key-wallet-manager/src/wallet_manager/mod.rs @@ -193,7 +193,7 @@ impl WalletManager { /// # Security Note /// When `downgrade_to_pubkey_wallet` is true, the returned wallet contains NO private key material, /// making it safe to use on potentially compromised systems or for creating watch-only wallets. - #[cfg(feature = "bincode")] + #[cfg(feature = "serde")] #[allow(clippy::too_many_arguments)] pub fn create_wallet_from_mnemonic_return_serialized_bytes( &mut self, @@ -260,10 +260,10 @@ impl WalletManager { } // Serialize the wallet to bytes - let serialized_bytes = bincode::encode_to_vec(&final_wallet, bincode::config::standard()) - .map_err(|e| { - WalletError::InvalidParameter(format!("Failed to serialize wallet: {}", e)) - })?; + let serialized_bytes = + bincode::serde::encode_to_vec(&final_wallet, bincode::config::standard()).map_err( + |e| WalletError::InvalidParameter(format!("Failed to serialize wallet: {}", e)), + )?; // Add the wallet to the manager let mut managed_info = T::from_wallet(&final_wallet); @@ -460,17 +460,18 @@ impl WalletManager { /// # Returns /// * `Ok(WalletId)` - The computed wallet ID of the imported wallet /// * `Err(WalletError)` - If deserialization fails or the wallet already exists - #[cfg(feature = "bincode")] + #[cfg(feature = "serde")] pub fn import_wallet_from_bytes( &mut self, wallet_bytes: &[u8], ) -> Result { // Deserialize the wallet from bincode - let wallet: Wallet = bincode::decode_from_slice(wallet_bytes, bincode::config::standard()) - .map_err(|e| { - WalletError::InvalidParameter(format!("Failed to deserialize wallet: {}", e)) - })? - .0; + let wallet: Wallet = + bincode::serde::decode_from_slice(wallet_bytes, bincode::config::standard()) + .map_err(|e| { + WalletError::InvalidParameter(format!("Failed to deserialize wallet: {}", e)) + })? + .0; // Compute wallet ID from the wallet's root public key let wallet_id = wallet.compute_wallet_id(); diff --git a/key-wallet/Cargo.toml b/key-wallet/Cargo.toml index 606b40223..5dffe33da 100644 --- a/key-wallet/Cargo.toml +++ b/key-wallet/Cargo.toml @@ -11,8 +11,7 @@ license = "CC0-1.0" [features] default = ["std"] std = ["dashcore_hashes/std", "secp256k1/std", "bip39/std", "getrandom", "dash-network/std", "rand"] -serde = ["dep:serde", "dep:serde_json", "dashcore_hashes/serde", "secp256k1/serde", "dash-network/serde", "dashcore/serde"] -bincode = ["serde", "dep:bincode", "dep:bincode_derive", "dash-network/bincode", "dashcore_hashes/bincode", "dashcore/bincode"] +serde = ["dep:serde", "dashcore_hashes/serde", "secp256k1/serde", "dash-network/serde", "dashcore/serde"] bip38 = ["scrypt", "aes", "bs58", "rand"] eddsa = ["dashcore/eddsa"] bls = ["dashcore/bls"] @@ -36,10 +35,7 @@ sha2 = { version = "0.10", default-features = false } bs58 = { version = "0.5", default-features = false, features = ["check", "alloc"], optional = true } rand = { version = "0.8", default-features = false, features = ["std", "std_rng"], optional = true } # Serialization -bincode = { version = "2.0.1", optional = true } -bincode_derive = { version = "2.0.1", optional = true } base64 = { version = "0.22", optional = true } -serde_json = { version = "1.0", optional = true } hex = { version = "0.4"} hkdf = { version = "0.12", default-features = false } zeroize = { version = "1.8", features = ["derive"] } @@ -49,6 +45,6 @@ async-trait = "0.1" [dev-dependencies] dashcore = { path="../dash", features = ["test-utils"] } hex = "0.4" -key-wallet = { path = ".", features = ["test-utils", "bip38", "serde", "bincode", "eddsa", "bls"] } +key-wallet = { path = ".", features = ["test-utils", "bip38", "serde", "eddsa", "bls"] } tokio = { version = "1", features = ["macros", "rt"] } test-case = "3.3" diff --git a/key-wallet/src/account/account_collection.rs b/key-wallet/src/account/account_collection.rs index 5a2a2c566..09eea4dff 100644 --- a/key-wallet/src/account/account_collection.rs +++ b/key-wallet/src/account/account_collection.rs @@ -4,8 +4,6 @@ use alloc::collections::BTreeMap; use alloc::vec::Vec; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -21,7 +19,6 @@ pub type DashpayContactIdentityId = [u8; 32]; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct DashpayAccountKey { pub index: u32, pub user_identity_id: DashpayOurUserIdentityId, @@ -31,7 +28,6 @@ pub struct DashpayAccountKey { /// Key for Platform Payment accounts (DIP-17) #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct PlatformPaymentAccountKey { /// Account index (hardened) pub account: u32, @@ -42,7 +38,6 @@ pub struct PlatformPaymentAccountKey { /// Collection of accounts organized by type #[derive(Debug, Clone, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct AccountCollection { /// Standard BIP44 accounts by index pub standard_bip44_accounts: BTreeMap, diff --git a/key-wallet/src/account/account_type.rs b/key-wallet/src/account/account_type.rs index cd318ff88..f6da6c8e5 100644 --- a/key-wallet/src/account/account_type.rs +++ b/key-wallet/src/account/account_type.rs @@ -8,15 +8,12 @@ use crate::transaction_checking::transaction_router::{ AccountTypeToCheck, PlatformAccountConversionError, }; use crate::Network; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; /// Account types supported by the wallet #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum StandardAccountType { /// Standard BIP44 account for regular transactions m/44'/coin_type'/account'/x/x #[default] @@ -28,7 +25,6 @@ pub enum StandardAccountType { /// Account types supported by the wallet #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum AccountType { /// Standard BIP44 account for regular transactions Standard { diff --git a/key-wallet/src/account/bls_account.rs b/key-wallet/src/account/bls_account.rs index 94c4d188b..0385bd993 100644 --- a/key-wallet/src/account/bls_account.rs +++ b/key-wallet/src/account/bls_account.rs @@ -17,8 +17,6 @@ use dashcore::Address; use serde::{Deserialize, Serialize}; use crate::bip32::{ChainCode, Fingerprint}; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use dashcore::blsful::{Bls12381G2Impl, SerializationFormat}; use crate::account::derivation::AccountDerivation; @@ -28,7 +26,6 @@ pub use dashcore::blsful::SecretKey; /// BLS account structure for Platform and masternode operations #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct BLSAccount { /// Wallet id (stored as Vec for serialization) pub parent_wallet_id: Option>, @@ -164,21 +161,6 @@ impl BLSAccount { watch_only.is_watch_only = true; watch_only } - - /// Serialize account to bytes - #[cfg(feature = "bincode")] - pub fn serialize(&self) -> Result> { - bincode::encode_to_vec(self, bincode::config::standard()) - .map_err(|e| Error::Serialization(e.to_string())) - } - - /// Deserialize account from bytes - #[cfg(feature = "bincode")] - pub fn deserialize(data: &[u8]) -> Result { - bincode::decode_from_slice(data, bincode::config::standard()) - .map(|(account, _)| account) - .map_err(|e| Error::Serialization(e.to_string())) - } } impl AccountTrait for BLSAccount { diff --git a/key-wallet/src/account/coinjoin.rs b/key-wallet/src/account/coinjoin.rs index 25d187712..d49f799b4 100644 --- a/key-wallet/src/account/coinjoin.rs +++ b/key-wallet/src/account/coinjoin.rs @@ -3,15 +3,12 @@ //! This module contains structures for managing CoinJoin address pools. use crate::managed_account::address_pool::AddressPool; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; /// CoinJoin-specific address pools #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct CoinJoinPools { /// CoinJoin receive addresses pub external: AddressPool, diff --git a/key-wallet/src/account/eddsa_account.rs b/key-wallet/src/account/eddsa_account.rs index efbf40ff4..3c3895a0c 100644 --- a/key-wallet/src/account/eddsa_account.rs +++ b/key-wallet/src/account/eddsa_account.rs @@ -18,13 +18,10 @@ use serde::{Deserialize, Serialize}; use crate::account::derivation::AccountDerivation; use crate::bip32::{ChainCode, Fingerprint}; use crate::managed_account::address_pool::AddressPoolType; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; /// EdDSA (Ed25519) account structure for Platform identity operations #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct EdDSAAccount { /// Wallet id (stored as Vec for serialization) pub parent_wallet_id: Option>, @@ -156,21 +153,6 @@ impl EdDSAAccount { watch_only } - /// Serialize account to bytes - #[cfg(feature = "bincode")] - pub fn serialize(&self) -> Result> { - bincode::encode_to_vec(self, bincode::config::standard()) - .map_err(|e| Error::Serialization(e.to_string())) - } - - /// Deserialize account from bytes - #[cfg(feature = "bincode")] - pub fn deserialize(data: &[u8]) -> Result { - bincode::decode_from_slice(data, bincode::config::standard()) - .map(|(account, _)| account) - .map_err(|e| Error::Serialization(e.to_string())) - } - /// Derive a Platform identity key at index pub fn derive_identity_key(&self, index: u32) -> Result { self.derive_ed25519_key_at_index(index) diff --git a/key-wallet/src/account/mod.rs b/key-wallet/src/account/mod.rs index 704a2cd3a..d7d50229f 100644 --- a/key-wallet/src/account/mod.rs +++ b/key-wallet/src/account/mod.rs @@ -14,12 +14,9 @@ pub mod eddsa_account; // pub mod scan; pub mod account_type; pub mod derivation; -mod serialization; use core::fmt; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use secp256k1::Secp256k1; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -53,7 +50,6 @@ pub use eddsa_account::EdDSAAccount; /// identity information that doesn't change during normal operation. #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct Account { /// Wallet id pub parent_wallet_id: Option<[u8; 32]>, diff --git a/key-wallet/src/account/serialization.rs b/key-wallet/src/account/serialization.rs deleted file mode 100644 index 493a6b198..000000000 --- a/key-wallet/src/account/serialization.rs +++ /dev/null @@ -1,149 +0,0 @@ -#[cfg(feature = "bls")] -use crate::account::BLSAccount; -#[cfg(feature = "eddsa")] -use crate::account::EdDSAAccount; -use crate::Account; - -impl Account { - /// Serialize account to bytes - #[cfg(feature = "bincode")] - pub fn to_bytes(&self) -> crate::Result> { - bincode::encode_to_vec(self, bincode::config::standard()) - .map_err(|e| crate::error::Error::Serialization(e.to_string())) - } - - /// Deserialize account from bytes - #[cfg(feature = "bincode")] - pub fn from_bytes(data: &[u8]) -> crate::Result { - bincode::decode_from_slice(data, bincode::config::standard()) - .map(|(account, _)| account) - .map_err(|e| crate::error::Error::Serialization(e.to_string())) - } -} - -#[cfg(feature = "bls")] -impl BLSAccount { - /// Serialize BLS account to bytes - #[cfg(feature = "bincode")] - pub fn to_bytes(&self) -> crate::Result> { - bincode::encode_to_vec(self, bincode::config::standard()) - .map_err(|e| crate::error::Error::Serialization(e.to_string())) - } - - /// Deserialize BLS account from bytes - #[cfg(feature = "bincode")] - pub fn from_bytes(data: &[u8]) -> crate::Result { - bincode::decode_from_slice(data, bincode::config::standard()) - .map(|(account, _)| account) - .map_err(|e| crate::error::Error::Serialization(e.to_string())) - } -} - -#[cfg(feature = "eddsa")] -impl EdDSAAccount { - /// Serialize EdDSA account to bytes - #[cfg(feature = "bincode")] - pub fn to_bytes(&self) -> crate::Result> { - bincode::encode_to_vec(self, bincode::config::standard()) - .map_err(|e| crate::error::Error::Serialization(e.to_string())) - } - - /// Deserialize EdDSA account from bytes - #[cfg(feature = "bincode")] - pub fn from_bytes(data: &[u8]) -> crate::Result { - bincode::decode_from_slice(data, bincode::config::standard()) - .map(|(account, _)| account) - .map_err(|e| crate::error::Error::Serialization(e.to_string())) - } -} - -#[cfg(test)] -mod tests { - #[cfg(feature = "bls")] - use crate::account::BLSAccount; - #[cfg(feature = "eddsa")] - use crate::account::EdDSAAccount; - use crate::Account; - - #[test] - #[cfg(feature = "bincode")] - fn test_serialization() { - let account = crate::account::tests::test_account(); - let serialized = account.to_bytes().unwrap(); - let deserialized = Account::from_bytes(&serialized).unwrap(); - - assert_eq!(account.index(), deserialized.index()); - assert_eq!(account.account_type, deserialized.account_type); - } - - #[test] - #[cfg(all(feature = "bincode", feature = "bls"))] - fn test_bls_serialization() { - use crate::account::{account_type::StandardAccountType, AccountTrait, AccountType}; - use crate::derivation_bls_bip32::{ExtendedBLSPrivKey, ExtendedBLSPubKey}; - use crate::Network; - - // Create a valid BLS public key - let seed = [42u8; 32]; - let bls_private = ExtendedBLSPrivKey::new_master(Network::Testnet, &seed) - .expect("Failed to create BLS private key from seed"); - let bls_public = ExtendedBLSPubKey::from_private_key(&bls_private); - let public_key_bytes = bls_public.to_bytes(); - - let account = BLSAccount::from_public_key_bytes( - None, - AccountType::Standard { - index: 0, - standard_account_type: StandardAccountType::BIP44Account, - }, - public_key_bytes, - Network::Testnet, - ) - .expect("Failed to create BLS account from public key bytes"); - - let serialized = account.to_bytes().expect("Failed to serialize BLS account"); - let deserialized = - BLSAccount::from_bytes(&serialized).expect("Failed to deserialize BLS account"); - - assert_eq!(account.index(), deserialized.index()); - assert_eq!(account.account_type, deserialized.account_type); - assert_eq!(account.network, deserialized.network); - assert_eq!(account.is_watch_only, deserialized.is_watch_only); - } - - #[test] - #[cfg(all(feature = "bincode", feature = "eddsa"))] - fn test_eddsa_serialization() { - use crate::account::{account_type::StandardAccountType, AccountTrait, AccountType}; - use crate::derivation_slip10::{ExtendedEd25519PrivKey, ExtendedEd25519PubKey}; - use crate::Network; - - // Create a valid Ed25519 public key - let seed = [42u8; 32]; - let ed25519_private = ExtendedEd25519PrivKey::new_master(Network::Testnet, &seed) - .expect("Failed to create Ed25519 private key from seed"); - let ed25519_public = ExtendedEd25519PubKey::from_priv(&ed25519_private) - .expect("Failed to derive Ed25519 public key from private key"); - let public_key_bytes = ed25519_public.public_key.to_bytes(); - - let account = EdDSAAccount::from_public_key_bytes( - None, - AccountType::Standard { - index: 0, - standard_account_type: StandardAccountType::BIP44Account, - }, - public_key_bytes, - Network::Testnet, - ) - .expect("Failed to create EdDSA account from public key bytes"); - - let serialized = account.to_bytes().expect("Failed to serialize EdDSA account"); - let deserialized = - EdDSAAccount::from_bytes(&serialized).expect("Failed to deserialize EdDSA account"); - - assert_eq!(account.index(), deserialized.index()); - assert_eq!(account.account_type, deserialized.account_type); - assert_eq!(account.network, deserialized.network); - assert_eq!(account.is_watch_only, deserialized.is_watch_only); - } -} diff --git a/key-wallet/src/bip32.rs b/key-wallet/src/bip32.rs index 9c597587a..2eb807371 100644 --- a/key-wallet/src/bip32.rs +++ b/key-wallet/src/bip32.rs @@ -44,8 +44,6 @@ use crate::dip9::{ }; use alloc::{string::String, vec::Vec}; use base58ck; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use dash_network::Network; /// XpubIdentifier as a hash160 result @@ -58,7 +56,6 @@ pub use secp256k1::SecretKey as PrivateKey; /// A chain code #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct ChainCode([u8; 32]); impl ChainCode { @@ -203,7 +200,6 @@ impl<'de> serde::Deserialize<'de> for ChainCode { /// A fingerprint #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct Fingerprint([u8; 4]); impl Fingerprint { @@ -359,77 +355,6 @@ pub struct ExtendedPrivKey { pub chain_code: ChainCode, } -#[cfg(feature = "bincode")] -impl bincode::Encode for ExtendedPrivKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - self.network.encode(encoder)?; - self.depth.encode(encoder)?; - self.parent_fingerprint.encode(encoder)?; - self.child_number.encode(encoder)?; - // Encode the private key as bytes - self.private_key.secret_bytes().encode(encoder)?; - self.chain_code.encode(encoder)?; - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for ExtendedPrivKey { - fn decode>( - decoder: &mut D, - ) -> Result { - let network = Network::decode(decoder)?; - let depth = u8::decode(decoder)?; - let parent_fingerprint = Fingerprint::decode(decoder)?; - let child_number = ChildNumber::decode(decoder)?; - // Decode the private key from bytes - let private_key_bytes: [u8; 32] = <[u8; 32]>::decode(decoder)?; - let private_key = secp256k1::SecretKey::from_slice(&private_key_bytes).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid private key: {}", e)) - })?; - let chain_code = ChainCode::decode(decoder)?; - - Ok(ExtendedPrivKey { - network, - depth, - parent_fingerprint, - child_number, - private_key, - chain_code, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for ExtendedPrivKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - let network = Network::borrow_decode(decoder)?; - let depth = u8::borrow_decode(decoder)?; - let parent_fingerprint = Fingerprint::borrow_decode(decoder)?; - let child_number = ChildNumber::borrow_decode(decoder)?; - // Decode the private key from bytes - let private_key_bytes: [u8; 32] = <[u8; 32]>::borrow_decode(decoder)?; - let private_key = secp256k1::SecretKey::from_slice(&private_key_bytes).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid private key: {}", e)) - })?; - let chain_code = ChainCode::borrow_decode(decoder)?; - - Ok(ExtendedPrivKey { - network, - depth, - parent_fingerprint, - child_number, - private_key, - chain_code, - }) - } -} - #[cfg(feature = "serde")] impl serde::Serialize for ExtendedPrivKey { fn serialize(&self, serializer: S) -> Result @@ -482,77 +407,6 @@ pub struct ExtendedPubKey { pub chain_code: ChainCode, } -#[cfg(feature = "bincode")] -impl bincode::Encode for ExtendedPubKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - self.network.encode(encoder)?; - self.depth.encode(encoder)?; - self.parent_fingerprint.encode(encoder)?; - self.child_number.encode(encoder)?; - // Encode the public key as bytes (33 bytes for compressed) - self.public_key.serialize().encode(encoder)?; - self.chain_code.encode(encoder)?; - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for ExtendedPubKey { - fn decode>( - decoder: &mut D, - ) -> Result { - let network = Network::decode(decoder)?; - let depth = u8::decode(decoder)?; - let parent_fingerprint = Fingerprint::decode(decoder)?; - let child_number = ChildNumber::decode(decoder)?; - // Decode the public key from bytes (33 bytes for compressed) - let public_key_bytes: [u8; 33] = <[u8; 33]>::decode(decoder)?; - let public_key = secp256k1::PublicKey::from_slice(&public_key_bytes).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid public key: {}", e)) - })?; - let chain_code = ChainCode::decode(decoder)?; - - Ok(ExtendedPubKey { - network, - depth, - parent_fingerprint, - child_number, - public_key, - chain_code, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for ExtendedPubKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - let network = Network::borrow_decode(decoder)?; - let depth = u8::borrow_decode(decoder)?; - let parent_fingerprint = Fingerprint::borrow_decode(decoder)?; - let child_number = ChildNumber::borrow_decode(decoder)?; - // Decode the public key from bytes (33 bytes for compressed) - let public_key_bytes: [u8; 33] = <[u8; 33]>::borrow_decode(decoder)?; - let public_key = secp256k1::PublicKey::from_slice(&public_key_bytes).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid public key: {}", e)) - })?; - let chain_code = ChainCode::borrow_decode(decoder)?; - - Ok(ExtendedPubKey { - network, - depth, - parent_fingerprint, - child_number, - public_key, - chain_code, - }) - } -} - #[cfg(feature = "serde")] impl serde::Serialize for ExtendedPubKey { fn serialize(&self, serializer: S) -> Result @@ -576,7 +430,6 @@ impl<'de> serde::Deserialize<'de> for ExtendedPubKey { /// A child number for a derived key #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum ChildNumber { /// Non-hardened key Normal { @@ -947,34 +800,6 @@ pub trait IntoDerivationPath { #[derive(Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub struct DerivationPath(Vec); -#[cfg(feature = "bincode")] -impl bincode::Encode for DerivationPath { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - self.0.encode(encoder) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for DerivationPath { - fn decode>( - decoder: &mut D, - ) -> Result { - Ok(DerivationPath(Vec::::decode(decoder)?)) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for DerivationPath { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - Ok(DerivationPath(Vec::::borrow_decode(decoder)?)) - } -} - #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] #[repr(u32)] pub enum KeyDerivationType { @@ -2442,42 +2267,6 @@ mod tests { ); } - #[test] - #[cfg(feature = "serde")] - pub fn encode_decode_childnumber() { - serde_round_trip!(ChildNumber::from_normal_idx(0).unwrap()); - serde_round_trip!(ChildNumber::from_normal_idx(1).unwrap()); - serde_round_trip!(ChildNumber::from_normal_idx((1 << 31) - 1).unwrap()); - serde_round_trip!(ChildNumber::from_hardened_idx(0).unwrap()); - serde_round_trip!(ChildNumber::from_hardened_idx(1).unwrap()); - serde_round_trip!(ChildNumber::from_hardened_idx((1 << 31) - 1).unwrap()); - } - - #[test] - #[cfg(feature = "serde")] - pub fn encode_fingerprint_chaincode() { - use serde_json; - let fp = Fingerprint::from([1u8, 2, 3, 42]); - let cc = ChainCode::from([ - 1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 0, 1, 2, - ]); - - serde_round_trip!(fp); - serde_round_trip!(cc); - - assert_eq!("\"0102032a\"", serde_json::to_string(&fp).unwrap()); - assert_eq!( - "\"0102030405060708090001020304050607080900010203040506070809000102\"", - serde_json::to_string(&cc).unwrap() - ); - assert_eq!("0102032a", fp.to_string()); - assert_eq!( - "0102030405060708090001020304050607080900010203040506070809000102", - cc.to_string() - ); - } - #[test] fn fmt_child_number() { assert_eq!("000005h", &format!("{:#06}", ChildNumber::from_hardened_idx(5).unwrap())); diff --git a/key-wallet/src/derivation_bls_bip32.rs b/key-wallet/src/derivation_bls_bip32.rs index 6f980ed04..75fbc1fff 100644 --- a/key-wallet/src/derivation_bls_bip32.rs +++ b/key-wallet/src/derivation_bls_bip32.rs @@ -508,120 +508,6 @@ impl<'de> serde::Deserialize<'de> for ExtendedBLSPubKey { } } -// Manual bincode implementations for ExtendedBLSPrivKey -#[cfg(feature = "bincode")] -impl bincode::Encode for ExtendedBLSPrivKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - self.network.encode(encoder)?; - self.depth.encode(encoder)?; - self.parent_fingerprint.encode(encoder)?; - self.child_number.encode(encoder)?; - // Encode private key as bytes - let private_key_bytes = self.private_key.to_be_bytes(); - private_key_bytes.encode(encoder)?; - self.chain_code.encode(encoder)?; - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for ExtendedBLSPrivKey { - fn decode>( - decoder: &mut D, - ) -> Result { - let network = Network::decode(decoder)?; - let depth = u8::decode(decoder)?; - let parent_fingerprint = Fingerprint::decode(decoder)?; - let child_number = ChildNumber::decode(decoder)?; - let private_key_bytes: [u8; 32] = <[u8; 32]>::decode(decoder)?; - let private_key = BlsSecretKey::::from_be_bytes(&private_key_bytes) - .into_option() - .ok_or_else(|| { - bincode::error::DecodeError::OtherString("Invalid BLS private key".to_string()) - })?; - let chain_code = ChainCode::decode(decoder)?; - - Ok(ExtendedBLSPrivKey { - network, - depth, - parent_fingerprint, - child_number, - private_key, - chain_code, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for ExtendedBLSPrivKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - >::decode(decoder) - } -} - -// Manual bincode implementations for ExtendedBLSPubKey -#[cfg(feature = "bincode")] -impl bincode::Encode for ExtendedBLSPubKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - self.network.encode(encoder)?; - self.depth.encode(encoder)?; - self.parent_fingerprint.encode(encoder)?; - self.child_number.encode(encoder)?; - // Encode public key as bytes - let public_key_bytes = self.public_key.to_bytes(); - public_key_bytes.encode(encoder)?; - self.chain_code.encode(encoder)?; - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for ExtendedBLSPubKey { - fn decode>( - decoder: &mut D, - ) -> Result { - let network = Network::decode(decoder)?; - let depth = u8::decode(decoder)?; - let parent_fingerprint = Fingerprint::decode(decoder)?; - let child_number = ChildNumber::decode(decoder)?; - let public_key_bytes: Vec = Vec::::decode(decoder)?; - let public_key = BlsPublicKey::::from_bytes_with_mode( - &public_key_bytes, - SerializationFormat::Modern, - ) - .map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid BLS public key: {}", e)) - })?; - let chain_code = ChainCode::decode(decoder)?; - - Ok(ExtendedBLSPubKey { - network, - depth, - parent_fingerprint, - child_number, - public_key, - chain_code, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for ExtendedBLSPubKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - >::decode(decoder) - } -} - #[cfg(test)] mod tests { use super::*; @@ -890,73 +776,6 @@ mod tests { assert_eq!(child.depth, 7); } - #[test] - fn test_serialization_roundtrip() { - // Test serialization and deserialization of extended keys - let seed = vec![1u8, 50, 6, 244, 25, 199, 1, 25]; // C++ test vector - - let master_priv = ExtendedBLSPrivKey::new_master(Network::Testnet, &seed).unwrap(); - let master_pub = master_priv.to_extended_pub_key(); - - // Test private key serialization with serde - #[cfg(feature = "serde")] - { - // Serialize to JSON - let serialized = serde_json::to_string(&master_priv).unwrap(); - // Deserialize back - let deserialized: ExtendedBLSPrivKey = serde_json::from_str(&serialized).unwrap(); - - // Verify they match - assert_eq!(master_priv.depth, deserialized.depth); - assert_eq!(master_priv.parent_fingerprint, deserialized.parent_fingerprint); - assert_eq!(master_priv.child_number, deserialized.child_number); - assert_eq!(master_priv.chain_code, deserialized.chain_code); - assert_eq!( - master_priv.private_key.to_be_bytes(), - deserialized.private_key.to_be_bytes() - ); - - // Test public key serialization - let pub_serialized = serde_json::to_string(&master_pub).unwrap(); - let pub_deserialized: ExtendedBLSPubKey = - serde_json::from_str(&pub_serialized).unwrap(); - - assert_eq!(master_pub.depth, pub_deserialized.depth); - assert_eq!(master_pub.parent_fingerprint, pub_deserialized.parent_fingerprint); - assert_eq!(master_pub.child_number, pub_deserialized.child_number); - assert_eq!(master_pub.chain_code, pub_deserialized.chain_code); - assert_eq!(master_pub.public_key.to_bytes(), pub_deserialized.public_key.to_bytes()); - } - - // Test bincode serialization - #[cfg(feature = "bincode")] - { - // Test private key - let encoded = - bincode::encode_to_vec(&master_priv, bincode::config::standard()).unwrap(); - let decoded: ExtendedBLSPrivKey = - bincode::decode_from_slice(&encoded, bincode::config::standard()).unwrap().0; - - assert_eq!(master_priv.depth, decoded.depth); - assert_eq!(master_priv.parent_fingerprint, decoded.parent_fingerprint); - assert_eq!(master_priv.child_number, decoded.child_number); - assert_eq!(master_priv.chain_code, decoded.chain_code); - assert_eq!(master_priv.private_key.to_be_bytes(), decoded.private_key.to_be_bytes()); - - // Test public key - let pub_encoded = - bincode::encode_to_vec(&master_pub, bincode::config::standard()).unwrap(); - let pub_decoded: ExtendedBLSPubKey = - bincode::decode_from_slice(&pub_encoded, bincode::config::standard()).unwrap().0; - - assert_eq!(master_pub.depth, pub_decoded.depth); - assert_eq!(master_pub.parent_fingerprint, pub_decoded.parent_fingerprint); - assert_eq!(master_pub.child_number, pub_decoded.child_number); - assert_eq!(master_pub.chain_code, pub_decoded.chain_code); - assert_eq!(master_pub.public_key.to_bytes(), pub_decoded.public_key.to_bytes()); - } - } - #[test] fn test_serialization_and_derivation() { // Test that serialized keys can be used for derivation (matching C++ test) diff --git a/key-wallet/src/derivation_slip10.rs b/key-wallet/src/derivation_slip10.rs index c8eaddd61..550013e9c 100644 --- a/key-wallet/src/derivation_slip10.rs +++ b/key-wallet/src/derivation_slip10.rs @@ -506,97 +506,6 @@ impl<'de> serde::Deserialize<'de> for ExtendedEd25519PubKey { } } -#[cfg(feature = "bincode")] -impl bincode::Encode for ExtendedEd25519PrivKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - self.network.encode(encoder)?; - self.depth.encode(encoder)?; - self.parent_fingerprint.encode(encoder)?; - self.child_number.encode(encoder)?; - self.private_key.encode(encoder)?; - self.chain_code.encode(encoder)?; - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for ExtendedEd25519PrivKey { - fn decode>( - decoder: &mut D, - ) -> Result { - Ok(ExtendedEd25519PrivKey { - network: Network::decode(decoder)?, - depth: u8::decode(decoder)?, - parent_fingerprint: Fingerprint::decode(decoder)?, - child_number: ChildNumber::decode(decoder)?, - private_key: <[u8; 32]>::decode(decoder)?, - chain_code: ChainCode::decode(decoder)?, - }) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Encode for ExtendedEd25519PubKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - self.network.encode(encoder)?; - self.depth.encode(encoder)?; - self.parent_fingerprint.encode(encoder)?; - self.child_number.encode(encoder)?; - self.public_key.as_bytes().encode(encoder)?; - self.chain_code.encode(encoder)?; - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for ExtendedEd25519PubKey { - fn decode>( - decoder: &mut D, - ) -> Result { - let network = Network::decode(decoder)?; - let depth = u8::decode(decoder)?; - let parent_fingerprint = Fingerprint::decode(decoder)?; - let child_number = ChildNumber::decode(decoder)?; - let public_key_bytes = <[u8; 32]>::decode(decoder)?; - let public_key = VerifyingKey::from_bytes(&public_key_bytes) - .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; - let chain_code = ChainCode::decode(decoder)?; - - Ok(ExtendedEd25519PubKey { - network, - depth, - parent_fingerprint, - child_number, - public_key, - chain_code, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for ExtendedEd25519PrivKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - >::decode(decoder) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for ExtendedEd25519PubKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - >::decode(decoder) - } -} - /// Test cases from SLIP-0010 https://github.com/satoshilabs/slips/blob/master/slip-0010.md /// Just relevant cases, Ed25519, private key #[cfg(test)] diff --git a/key-wallet/src/dip9.rs b/key-wallet/src/dip9.rs index d4b094fc9..2542e5f09 100644 --- a/key-wallet/src/dip9.rs +++ b/key-wallet/src/dip9.rs @@ -1,6 +1,4 @@ use crate::bip32::{ChildNumber, DerivationPath, Error, ExtendedPrivKey, ExtendedPubKey}; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use bitflags::bitflags; use dash_network::Network; use secp256k1::Secp256k1; @@ -9,7 +7,6 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum DerivationPathReference { Unknown = 0, BIP32 = 1, diff --git a/key-wallet/src/gap_limit.rs b/key-wallet/src/gap_limit.rs index 9d4d5b088..bcf418811 100644 --- a/key-wallet/src/gap_limit.rs +++ b/key-wallet/src/gap_limit.rs @@ -3,8 +3,6 @@ //! Implements BIP44 gap limit tracking to determine when to stop generating //! addresses during wallet recovery and discovery. -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use core::cmp; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -31,7 +29,6 @@ pub const MAX_GAP_LIMIT: u32 = 1000; /// Stages of gap limit processing #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum GapLimitStage { /// Initial address generation Initial, @@ -46,7 +43,6 @@ pub enum GapLimitStage { /// Gap limit tracker for a single chain (external or internal) #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct GapLimit { /// The gap limit value pub limit: u32, @@ -232,7 +228,6 @@ impl GapLimit { /// Statistics about gap limit state #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct GapLimitStats { pub limit: u32, pub stage: GapLimitStage, @@ -247,7 +242,6 @@ pub struct GapLimitStats { /// Manager for multiple gap limits (external, internal, CoinJoin) #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct GapLimitManager { /// External (receive) address gap limit pub external: GapLimit, @@ -325,7 +319,6 @@ impl GapLimitManager { /// Combined statistics for all gap limits #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct GapLimitManagerStats { pub external: GapLimitStats, pub internal: GapLimitStats, diff --git a/key-wallet/src/lib.rs b/key-wallet/src/lib.rs index 38b4e3cd8..6afa37418 100644 --- a/key-wallet/src/lib.rs +++ b/key-wallet/src/lib.rs @@ -15,10 +15,6 @@ extern crate std; #[cfg(any(test, feature = "test-utils"))] pub mod test_utils; -#[cfg(test)] -#[macro_use] -mod test_macros; - #[cfg(test)] mod address_metadata_tests; #[cfg(all(test, feature = "bip38"))] diff --git a/key-wallet/src/managed_account/address_pool.rs b/key-wallet/src/managed_account/address_pool.rs index 3762918b4..42213c3c0 100644 --- a/key-wallet/src/managed_account/address_pool.rs +++ b/key-wallet/src/managed_account/address_pool.rs @@ -5,8 +5,6 @@ use alloc::string::String; use alloc::vec::Vec; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use core::fmt; use secp256k1::Secp256k1; #[cfg(feature = "serde")] @@ -21,7 +19,6 @@ use dashcore::{Address, AddressType, ScriptBuf}; /// Types of public keys used in the address pool #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] #[allow(clippy::upper_case_acronyms)] pub enum PublicKeyType { /// ECDSA public key (standard Bitcoin/Dash addresses) - stored as `Vec` for serialization @@ -35,7 +32,6 @@ pub enum PublicKeyType { /// Type of address pool (external, internal, or absent/single-pool) #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum AddressPoolType { /// External (receive) addresses - used for receiving funds External, @@ -94,7 +90,6 @@ impl<'de> Deserialize<'de> for PublicKeyType { /// Key source for address derivation #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum KeySource { /// ECDSA private key for full wallet Private(ExtendedPrivKey), @@ -212,7 +207,6 @@ impl KeySource { /// Information about a single address in the pool #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct AddressInfo { /// The address pub address: Address, @@ -324,7 +318,6 @@ impl AddressInfo { /// Address pool for managing HD wallet addresses #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct AddressPool { /// Base derivation path for this pool pub base_path: DerivationPath, diff --git a/key-wallet/src/managed_account/managed_account_type.rs b/key-wallet/src/managed_account/managed_account_type.rs index d86c6812f..e403aadf9 100644 --- a/key-wallet/src/managed_account/managed_account_type.rs +++ b/key-wallet/src/managed_account/managed_account_type.rs @@ -6,8 +6,6 @@ use crate::gap_limit::{ }; use crate::{AccountType, AddressPool, DerivationPath}; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use dashcore::ScriptBuf; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -15,7 +13,6 @@ use serde::{Deserialize, Serialize}; /// Managed account type with embedded address pools #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] #[allow(clippy::large_enum_variant)] pub enum ManagedAccountType { /// Standard BIP44 account for regular transactions diff --git a/key-wallet/src/managed_account/managed_platform_account.rs b/key-wallet/src/managed_account/managed_platform_account.rs index a803feb0e..0321491ed 100644 --- a/key-wallet/src/managed_account/managed_platform_account.rs +++ b/key-wallet/src/managed_account/managed_platform_account.rs @@ -336,73 +336,6 @@ impl ManagedPlatformAccount { } } -#[cfg(feature = "bincode")] -impl bincode::Encode for ManagedPlatformAccount { - fn encode( - &self, - encoder: &mut E, - ) -> core::result::Result<(), bincode::error::EncodeError> { - // Encode each field - bincode::Encode::encode(&self.account, encoder)?; - bincode::Encode::encode(&self.key_class, encoder)?; - bincode::Encode::encode(&self.network, encoder)?; - bincode::Encode::encode(&self.credit_balance, encoder)?; - - // Encode address_balances as a vec of tuples - let address_balances_vec: Vec<(PlatformP2PKHAddress, u64)> = - self.address_balances.iter().map(|(k, v)| (*k, *v)).collect(); - bincode::Encode::encode(&address_balances_vec, encoder)?; - - bincode::Encode::encode(&self.addresses, encoder)?; - bincode::Encode::encode(&self.metadata, encoder)?; - bincode::Encode::encode(&self.is_watch_only, encoder)?; - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for ManagedPlatformAccount { - fn decode>( - decoder: &mut D, - ) -> core::result::Result { - let account = bincode::Decode::decode(decoder)?; - let key_class = bincode::Decode::decode(decoder)?; - let network = bincode::Decode::decode(decoder)?; - let credit_balance = bincode::Decode::decode(decoder)?; - - // Decode address_balances from vec of tuples - let address_balances_vec: Vec<(PlatformP2PKHAddress, u64)> = - bincode::Decode::decode(decoder)?; - let address_balances: BTreeMap = - address_balances_vec.into_iter().collect(); - - let addresses = bincode::Decode::decode(decoder)?; - let metadata = bincode::Decode::decode(decoder)?; - let is_watch_only = bincode::Decode::decode(decoder)?; - - Ok(Self { - account, - key_class, - network, - credit_balance, - address_balances, - addresses, - metadata, - is_watch_only, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, Context> bincode::BorrowDecode<'de, Context> for ManagedPlatformAccount { - fn borrow_decode>( - decoder: &mut D, - ) -> core::result::Result { - // Use the regular decode implementation - >::decode(decoder) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/key-wallet/src/managed_account/metadata.rs b/key-wallet/src/managed_account/metadata.rs index ccdd63ca6..e890d973b 100644 --- a/key-wallet/src/managed_account/metadata.rs +++ b/key-wallet/src/managed_account/metadata.rs @@ -4,15 +4,12 @@ use alloc::string::String; use alloc::vec::Vec; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; /// Account metadata for organization and tracking #[derive(Debug, Clone, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct AccountMetadata { /// Human-readable account name pub name: Option, diff --git a/key-wallet/src/managed_account/platform_address.rs b/key-wallet/src/managed_account/platform_address.rs index 31c15dc1c..fa8420ecd 100644 --- a/key-wallet/src/managed_account/platform_address.rs +++ b/key-wallet/src/managed_account/platform_address.rs @@ -124,34 +124,6 @@ impl AsRef<[u8]> for PlatformP2PKHAddress { } } -#[cfg(feature = "bincode")] -impl bincode::Encode for PlatformP2PKHAddress { - fn encode( - &self, - encoder: &mut E, - ) -> core::result::Result<(), bincode::error::EncodeError> { - bincode::Encode::encode(&self.0, encoder) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for PlatformP2PKHAddress { - fn decode>( - decoder: &mut D, - ) -> core::result::Result { - Ok(Self(<[u8; 20]>::decode(decoder)?)) - } -} - -#[cfg(feature = "bincode")] -impl<'de, Context> bincode::BorrowDecode<'de, Context> for PlatformP2PKHAddress { - fn borrow_decode>( - decoder: &mut D, - ) -> core::result::Result { - Ok(Self(<[u8; 20]>::borrow_decode(decoder)?)) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/key-wallet/src/mnemonic.rs b/key-wallet/src/mnemonic.rs index 554779cce..f75bc8472 100644 --- a/key-wallet/src/mnemonic.rs +++ b/key-wallet/src/mnemonic.rs @@ -7,8 +7,6 @@ use core::str::FromStr; use crate::bip32::ExtendedPrivKey; use crate::error::{Error, Result}; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use bip39 as bip39_crate; #[cfg(feature = "std")] use rand::{RngCore, SeedableRng}; @@ -19,7 +17,6 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; /// Language for mnemonic generation #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum Language { English, ChineseSimplified, @@ -57,49 +54,6 @@ pub struct Mnemonic { inner: bip39_crate::Mnemonic, } -#[cfg(feature = "bincode")] -impl bincode::Encode for Mnemonic { - fn encode( - &self, - encoder: &mut E, - ) -> core::result::Result<(), bincode::error::EncodeError> { - // Store mnemonic as its phrase string - let phrase = self.phrase(); - phrase.encode(encoder) - } -} - -#[cfg(feature = "bincode")] -impl bincode::Decode for Mnemonic { - fn decode>( - decoder: &mut D, - ) -> core::result::Result { - let phrase: String = bincode::Decode::decode(decoder)?; - // Parse back from phrase - default to English - let inner = bip39_crate::Mnemonic::parse(&phrase).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid mnemonic: {}", e)) - })?; - Ok(Self { - inner, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> bincode::BorrowDecode<'de, C> for Mnemonic { - fn borrow_decode>( - decoder: &mut D, - ) -> core::result::Result { - let phrase: String = bincode::BorrowDecode::borrow_decode(decoder)?; - let inner = bip39_crate::Mnemonic::parse(&phrase).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid mnemonic: {}", e)) - })?; - Ok(Self { - inner, - }) - } -} - impl Mnemonic { /// Generate a new mnemonic with the specified word count #[cfg(feature = "getrandom")] diff --git a/key-wallet/src/psbt/mod.rs b/key-wallet/src/psbt/mod.rs index 5529f8383..707af61bf 100644 --- a/key-wallet/src/psbt/mod.rs +++ b/key-wallet/src/psbt/mod.rs @@ -1006,125 +1006,6 @@ mod tests { assert_eq!(hex, psbt.serialize_hex()); } - #[cfg(feature = "serde")] - #[test] - fn test_serde_psbt() { - //! Create a full PSBT value with various fields filled and make sure it can be JSONized. - use dashcore_hashes::sha256d; - - use crate::psbt::map::Input; - - // create some values to use in the PSBT - let tx = Transaction { - version: 1, - lock_time: 0, - input: vec![TxIn { - previous_output: OutPoint { - txid: "e567952fb6cc33857f392efa3a46c995a28f69cca4bb1b37e0204dab1ec7a389" - .parse() - .unwrap(), - vout: 1, - }, - script_sig: ScriptBuf::from_hex("160014be18d152a9b012039daf3da7de4f53349eecb985") - .unwrap(), - sequence: u32::MAX, - witness: Witness::from_slice(&[hex!( - "03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105" - )]), - }], - output: vec![TxOut { - value: 190303501938, - script_pubkey: ScriptBuf::from_hex( - "a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587", - ) - .unwrap(), - }], - special_transaction_payload: None, - }; - let unknown: BTreeMap> = vec![( - raw::Key { - type_value: 1, - key: vec![0, 1], - }, - vec![3, 4, 5], - )] - .into_iter() - .collect(); - let key_source = ("deadbeef".parse().unwrap(), "m/0'/1".parse().unwrap()); - let keypaths: BTreeMap = vec![( - "0339880dc92394b7355e3d0439fa283c31de7590812ea011c4245c0674a685e883".parse().unwrap(), - key_source.clone(), - )] - .into_iter() - .collect(); - - let proprietary: BTreeMap> = vec![( - raw::ProprietaryKey { - prefix: "prefx".as_bytes().to_vec(), - subtype: 42, - key: "test_key".as_bytes().to_vec(), - }, - vec![5, 6, 7], - )] - .into_iter() - .collect(); - - let psbt = PartiallySignedTransaction { - version: 0, - xpub: { - let xpub: ExtendedPubKey = - "xpub661MyMwAqRbcGoRVtwfvzZsq2VBJR1LAHfQstHUoxqDorV89vRoMxUZ27kLrraAj6MPi\ - QfrDb27gigC1VS1dBXi5jGpxmMeBXEkKkcXUTg4".parse().unwrap(); - vec![(xpub, key_source)].into_iter().collect() - }, - unsigned_tx: { - let mut unsigned = tx.clone(); - unsigned.input[0].script_sig = ScriptBuf::new(); - unsigned.input[0].witness = Witness::default(); - unsigned - }, - proprietary: proprietary.clone(), - unknown: unknown.clone(), - - inputs: vec![ - Input { - non_witness_utxo: Some(tx), - witness_utxo: Some(TxOut { - value: 190303501938, - script_pubkey: ScriptBuf::from_hex("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587").unwrap(), - }), - sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::().unwrap()), - redeem_script: Some(vec![0x51].into()), - witness_script: None, - partial_sigs: vec![( - "0339880dc92394b7355e3d0439fa283c31de7590812ea011c4245c0674a685e883".parse().unwrap(), - "304402204f67e2afb76142d44fae58a2495d33a3419daa26cd0db8d04f3452b63289ac0f022010762a9fb67e94cc5cad9026f6dc99ff7f070f4278d30fbc7d0c869dd38c7fe701".parse().unwrap(), - )].into_iter().collect(), - bip32_derivation: keypaths.clone(), - final_script_witness: Some(Witness::from_slice(&[vec![1, 3], vec![5]])), - ripemd160_preimages: vec![(ripemd160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), - sha256_preimages: vec![(sha256::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), - hash160_preimages: vec![(hash160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), - hash256_preimages: vec![(sha256d::Hash::hash(&[]), vec![1, 2])].into_iter().collect(), - proprietary: proprietary.clone(), - unknown: unknown.clone(), - ..Default::default() - } - ], - outputs: vec![ - Output { - bip32_derivation: keypaths, - proprietary, - unknown, - ..Default::default() - } - ], - }; - let encoded = serde_json::to_string(&psbt).unwrap(); - let decoded: PartiallySignedTransaction = serde_json::from_str(&encoded).unwrap(); - assert_eq!(psbt, decoded); - } - mod bip_vectors { use std::collections::BTreeMap; #[cfg(feature = "base64")] diff --git a/key-wallet/src/seed.rs b/key-wallet/src/seed.rs index 9c4ccda52..cdfe6181f 100644 --- a/key-wallet/src/seed.rs +++ b/key-wallet/src/seed.rs @@ -5,8 +5,6 @@ use crate::error::{Error, Result}; use alloc::string::String; use alloc::vec::Vec; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use core::fmt; use core::str::FromStr; use dashcore_hashes::hex::FromHex; @@ -16,7 +14,6 @@ use zeroize::Zeroize; /// A BIP32 seed (512 bits / 64 bytes) #[derive(Clone, Copy, PartialEq, Eq, Hash, Zeroize)] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct Seed([u8; 64]); impl Seed { diff --git a/key-wallet/src/test_macros.rs b/key-wallet/src/test_macros.rs deleted file mode 100644 index 5337ac004..000000000 --- a/key-wallet/src/test_macros.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Test macros for key-wallet. - -#[cfg(all(test, feature = "serde"))] -macro_rules! serde_round_trip { - ($var:expr) => {{ - use serde_json; - - let encoded = serde_json::to_value(&$var).unwrap(); - let decoded = serde_json::from_value(encoded).unwrap(); - assert_eq!($var, decoded); - }}; -} diff --git a/key-wallet/src/tests/mod.rs b/key-wallet/src/tests/mod.rs index 811240960..339ff67db 100644 --- a/key-wallet/src/tests/mod.rs +++ b/key-wallet/src/tests/mod.rs @@ -24,6 +24,4 @@ mod special_transaction_tests; mod transaction_tests; -mod spent_outpoints_tests; - mod wallet_tests; diff --git a/key-wallet/src/tests/spent_outpoints_tests.rs b/key-wallet/src/tests/spent_outpoints_tests.rs deleted file mode 100644 index a9e941b26..000000000 --- a/key-wallet/src/tests/spent_outpoints_tests.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! Tests for spent_outpoints deserialization and tracking. - -use dashcore::blockdata::transaction::{OutPoint, Transaction}; -use dashcore::{TxIn, Txid}; - -use crate::account::TransactionRecord; -use crate::managed_account::ManagedCoreAccount; - -/// Create a transaction that spends the given outpoints. -fn spending_tx(spent: &[OutPoint]) -> Transaction { - Transaction { - version: 1, - lock_time: 0, - input: spent - .iter() - .map(|op| TxIn { - previous_output: *op, - ..Default::default() - }) - .collect(), - output: Vec::new(), - special_transaction_payload: None, - } -} - -/// Create a receive-only transaction (no meaningful inputs). -fn receive_only_tx() -> Transaction { - Transaction { - version: 1, - lock_time: 0, - input: vec![TxIn::default()], - output: Vec::new(), - special_transaction_payload: None, - } -} - -fn record_from_tx(tx: &Transaction) -> TransactionRecord { - TransactionRecord::new(tx.clone(), 0, 0, false) -} - -#[test] -fn fresh_account_has_empty_spent_outpoints() { - let account = ManagedCoreAccount::dummy_bip44(); - assert!(account.transactions.is_empty()); - - let probe = OutPoint::new(Txid::from([0xAA; 32]), 0); - // Accessing spent_outpoints on a fresh account should not panic or misbehave. - // We verify indirectly via serde round-trip (spent_outpoints is private). - let json = serde_json::to_string(&account).unwrap(); - let deserialized: ManagedCoreAccount = serde_json::from_str(&json).unwrap(); - // No transactions, so spent_outpoints stays empty after round-trip. - assert!(deserialized.transactions.is_empty()); - // Confirm the serialized form does not contain spent_outpoints. - assert!(!json.contains("spent_outpoints")); - let _ = probe; // used only for clarity of intent -} - -#[test] -fn serde_round_trip_rebuilds_spent_outpoints() { - let mut account = ManagedCoreAccount::dummy_bip44(); - - let outpoint_a = OutPoint::new(Txid::from([0x01; 32]), 0); - let outpoint_b = OutPoint::new(Txid::from([0x02; 32]), 1); - let tx = spending_tx(&[outpoint_a, outpoint_b]); - let txid = tx.txid(); - account.transactions.insert(txid, record_from_tx(&tx)); - - // Serialize (spent_outpoints is skipped) - let json = serde_json::to_string(&account).unwrap(); - assert!(!json.contains("spent_outpoints")); - - // Deserialize: spent_outpoints should be rebuilt from transactions - let deserialized: ManagedCoreAccount = serde_json::from_str(&json).unwrap(); - assert_eq!(deserialized.transactions.len(), 1); - - // Verify the rebuilt set by serializing again and comparing transactions - // (spent_outpoints is private, so we test behavior through a second round-trip - // to confirm stability) - let json2 = serde_json::to_string(&deserialized).unwrap(); - let deserialized2: ManagedCoreAccount = serde_json::from_str(&json2).unwrap(); - assert_eq!(deserialized2.transactions.len(), 1); -} - -#[test] -fn receive_only_account_round_trips_correctly() { - let mut account = ManagedCoreAccount::dummy_bip44(); - - // Add a receive-only transaction (coinbase-like, no real spent outpoints) - let tx = receive_only_tx(); - let txid = tx.txid(); - account.transactions.insert(txid, record_from_tx(&tx)); - - assert_eq!(account.transactions.len(), 1); - - // Round-trip should work without issues (no rebuild loop) - let json = serde_json::to_string(&account).unwrap(); - let deserialized: ManagedCoreAccount = serde_json::from_str(&json).unwrap(); - assert_eq!(deserialized.transactions.len(), 1); - - // A second round-trip should be stable - let json2 = serde_json::to_string(&deserialized).unwrap(); - let deserialized2: ManagedCoreAccount = serde_json::from_str(&json2).unwrap(); - assert_eq!(deserialized2.transactions.len(), 1); -} - -#[test] -fn multiple_transactions_all_inputs_tracked_after_round_trip() { - let mut account = ManagedCoreAccount::dummy_bip44(); - - let outpoint_1 = OutPoint::new(Txid::from([0x10; 32]), 0); - let outpoint_2 = OutPoint::new(Txid::from([0x20; 32]), 0); - let outpoint_3 = OutPoint::new(Txid::from([0x30; 32]), 2); - - let tx1 = spending_tx(&[outpoint_1]); - let tx2 = spending_tx(&[outpoint_2, outpoint_3]); - - account.transactions.insert(tx1.txid(), record_from_tx(&tx1)); - account.transactions.insert(tx2.txid(), record_from_tx(&tx2)); - - let json = serde_json::to_string(&account).unwrap(); - let deserialized: ManagedCoreAccount = serde_json::from_str(&json).unwrap(); - - // All three outpoints should be in the rebuilt spent set. - // We verify by confirming the transaction inputs survived the round-trip. - let all_spent: Vec = deserialized - .transactions - .values() - .flat_map(|r| &r.transaction.input) - .map(|inp| inp.previous_output) - .collect(); - assert!(all_spent.contains(&outpoint_1)); - assert!(all_spent.contains(&outpoint_2)); - assert!(all_spent.contains(&outpoint_3)); - assert_eq!(all_spent.len(), 3); -} diff --git a/key-wallet/src/wallet/backup.rs b/key-wallet/src/wallet/backup.rs deleted file mode 100644 index f87886dbe..000000000 --- a/key-wallet/src/wallet/backup.rs +++ /dev/null @@ -1,97 +0,0 @@ -//! Wallet backup and restore functionality -//! -//! This module provides serialization and deserialization methods for wallets -//! using bincode for efficient binary storage. - -use crate::wallet::Wallet; -#[cfg(feature = "bincode")] -use crate::Error; - -impl Wallet { - /// Create a backup of this wallet - /// - /// # Returns - /// A `Vec` containing the serialized wallet data - /// - /// # Examples - /// ```no_run - /// use key_wallet::wallet::Wallet; - /// - /// let wallet = Wallet::new_random( - /// key_wallet::Network::Testnet, - /// key_wallet::wallet::initialization::WalletAccountCreationOptions::Default, - /// ).unwrap(); - /// - /// let backup_data = wallet.backup().unwrap(); - /// // Store backup_data securely... - /// ``` - #[cfg(feature = "bincode")] - pub fn backup(&self) -> Result, Error> { - bincode::encode_to_vec(self, bincode::config::standard()) - .map_err(|e| Error::Serialization(format!("Failed to backup wallet: {}", e))) - } - - /// Restore a wallet from a backup - /// - /// # Arguments - /// * `backup_data` - The serialized wallet data - /// - /// # Returns - /// The restored `Wallet` - /// - /// # Examples - /// ```no_run - /// use key_wallet::wallet::Wallet; - /// - /// let backup_data: Vec = vec![]; // Load from storage - /// let restored_wallet = Wallet::restore(&backup_data).unwrap(); - /// ``` - #[cfg(feature = "bincode")] - pub fn restore(backup_data: &[u8]) -> Result { - bincode::decode_from_slice(backup_data, bincode::config::standard()) - .map(|(wallet, _)| wallet) - .map_err(|e| Error::Serialization(format!("Failed to restore wallet: {}", e))) - } -} - -#[cfg(all(test, feature = "bincode"))] -mod tests { - use super::*; - use crate::mnemonic::{Language, Mnemonic}; - use crate::wallet::initialization::WalletAccountCreationOptions; - use crate::Network; - - #[test] - fn test_backup_restore() { - // Create a wallet - let mnemonic = Mnemonic::from_phrase( - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", - Language::English, - ).unwrap(); - - let original = Wallet::from_mnemonic( - mnemonic, - Network::Testnet, - WalletAccountCreationOptions::Default, - ) - .unwrap(); - - // Create backup - let backup_data = original.backup().unwrap(); - assert!(!backup_data.is_empty()); - - // Restore from backup - let restored = Wallet::restore(&backup_data).unwrap(); - - // Verify the restored wallet matches the original - assert_eq!(original.wallet_id, restored.wallet_id); - assert_eq!(original.accounts.count(), restored.accounts.count()); - } - - #[test] - fn test_restore_invalid_data() { - let invalid_data = vec![0xFF, 0xFF, 0xFF, 0xFF]; - let result = Wallet::restore(&invalid_data); - assert!(result.is_err()); - } -} diff --git a/key-wallet/src/wallet/mod.rs b/key-wallet/src/wallet/mod.rs index f7a30e81e..0e6325e56 100644 --- a/key-wallet/src/wallet/mod.rs +++ b/key-wallet/src/wallet/mod.rs @@ -4,7 +4,6 @@ //! multiple accounts, seed management, and transaction coordination. pub mod accounts; -pub mod backup; pub mod balance; #[cfg(feature = "bip38")] pub mod bip38; @@ -23,8 +22,6 @@ use crate::mnemonic::Mnemonic; use crate::seed::Seed; use crate::Network; use alloc::vec::Vec; -#[cfg(feature = "bincode")] -use bincode_derive::{Decode, Encode}; use core::fmt; use dashcore_hashes::{sha256, Hash}; #[cfg(feature = "serde")] @@ -34,7 +31,6 @@ use zeroize::Zeroize; /// Type of wallet based on how it was created #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub enum WalletType { /// Standard mnemonic wallet without passphrase Mnemonic { @@ -67,7 +63,6 @@ pub enum WalletType { /// in ManagedWalletInfo. #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "bincode", derive(Encode, Decode))] pub struct Wallet { /// Network this wallet is associated with pub network: Network, diff --git a/key-wallet/src/wallet/root_extended_keys.rs b/key-wallet/src/wallet/root_extended_keys.rs index 5e2122e52..af03796e8 100644 --- a/key-wallet/src/wallet/root_extended_keys.rs +++ b/key-wallet/src/wallet/root_extended_keys.rs @@ -4,8 +4,6 @@ use crate::derivation_bls_bip32::ExtendedBLSPrivKey; use crate::wallet::WalletType; use crate::{Error, Network, Wallet}; use alloc::borrow::Cow; -#[cfg(feature = "bincode")] -use bincode::{BorrowDecode, Decode, Encode}; #[cfg(feature = "bls")] use dashcore::blsful::Bls12381G2Impl; use dashcore_hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine}; @@ -152,56 +150,6 @@ impl RootExtendedPrivKey { } } -#[cfg(feature = "bincode")] -impl Encode for RootExtendedPrivKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - // Encode the private key as 32 bytes - let private_key_bytes = self.root_private_key.secret_bytes(); - bincode::Encode::encode(&private_key_bytes, encoder)?; - - // Encode the chain code - bincode::Encode::encode(&self.root_chain_code, encoder)?; - - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl Decode for RootExtendedPrivKey { - fn decode>( - decoder: &mut D, - ) -> Result { - // Decode the private key bytes - let private_key_bytes: [u8; 32] = bincode::Decode::decode(decoder)?; - let root_private_key = - secp256k1::SecretKey::from_byte_array(&private_key_bytes).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid private key: {}", e)) - })?; - - // Decode the chain code - let root_chain_code: ChainCode = bincode::Decode::decode(decoder)?; - - Ok(Self { - root_private_key, - root_chain_code, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> BorrowDecode<'de, C> for RootExtendedPrivKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - // For borrowed decode, we still need to copy the data since secp256k1::SecretKey - // doesn't support borrowing from the decoder - >::decode(decoder) - } -} - pub trait FromOnNetwork: Sized { /// Converts to this type from the input type. fn from_on_network(value: T, network: Network) -> Self; @@ -288,55 +236,6 @@ impl RootExtendedPubKey { } } -#[cfg(feature = "bincode")] -impl Encode for RootExtendedPubKey { - fn encode( - &self, - encoder: &mut E, - ) -> Result<(), bincode::error::EncodeError> { - // Encode the public key as serialized bytes (33 bytes compressed) - let public_key_bytes = self.root_public_key.serialize(); - bincode::Encode::encode(&public_key_bytes, encoder)?; - - // Encode the chain code - bincode::Encode::encode(&self.root_chain_code, encoder)?; - - Ok(()) - } -} - -#[cfg(feature = "bincode")] -impl Decode for RootExtendedPubKey { - fn decode>( - decoder: &mut D, - ) -> Result { - // Decode the public key bytes - let public_key_bytes: [u8; 33] = bincode::Decode::decode(decoder)?; - let root_public_key = secp256k1::PublicKey::from_slice(&public_key_bytes).map_err(|e| { - bincode::error::DecodeError::OtherString(format!("Invalid public key: {}", e)) - })?; - - // Decode the chain code - let root_chain_code: ChainCode = bincode::Decode::decode(decoder)?; - - Ok(Self { - root_public_key, - root_chain_code, - }) - } -} - -#[cfg(feature = "bincode")] -impl<'de, C> BorrowDecode<'de, C> for RootExtendedPubKey { - fn borrow_decode>( - decoder: &mut D, - ) -> Result { - // For borrowed decode, we still need to copy the data since secp256k1::PublicKey - // doesn't support borrowing from the decoder - >::decode(decoder) - } -} - impl FromOnNetwork for ExtendedPubKey { fn from_on_network(value: RootExtendedPubKey, network: Network) -> Self { ExtendedPubKey {