sal-vault 0.1.0

SAL Vault - Cryptographic functionality including key management, digital signatures, symmetric encryption, Ethereum wallets, and encrypted key-value store
Documentation
//! Tests for Ethereum wallet functionality.

use crate::vault::ethereum::*;
use crate::vault::keypair::implementation::KeyPair;
use ethers::utils::hex;

#[test]
fn test_ethereum_wallet_from_keypair() {
    let keypair = KeyPair::new("test_keypair");
    let network = networks::gnosis();
    
    let wallet = EthereumWallet::from_keypair(&keypair, network.clone()).unwrap();
    
    assert_eq!(wallet.network.name, "Gnosis");
    assert_eq!(wallet.network.chain_id, 100);
    
    // The address should be a valid Ethereum address
    assert!(wallet.address_string().starts_with("0x"));
}

#[test]
fn test_ethereum_wallet_from_name_and_keypair() {
    let keypair = KeyPair::new("test_keypair2");
    let network = networks::gnosis();
    
    let wallet = EthereumWallet::from_name_and_keypair("test", &keypair, network.clone()).unwrap();
    
    assert_eq!(wallet.network.name, "Gnosis");
    assert_eq!(wallet.network.chain_id, 100);
    
    // The address should be a valid Ethereum address
    assert!(wallet.address_string().starts_with("0x"));
    
    // Creating another wallet with the same name and keypair should yield the same address
    let wallet2 = EthereumWallet::from_name_and_keypair("test", &keypair, network.clone()).unwrap();
    assert_eq!(wallet.address, wallet2.address);
    
    // Creating a wallet with a different name should yield a different address
    let wallet3 = EthereumWallet::from_name_and_keypair("test2", &keypair, network.clone()).unwrap();
    assert_ne!(wallet.address, wallet3.address);
}

#[test]
fn test_ethereum_wallet_from_private_key() {
    let private_key = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
    let network = networks::gnosis();
    
    let wallet = EthereumWallet::from_private_key(private_key, network.clone()).unwrap();
    
    assert_eq!(wallet.network.name, "Gnosis");
    assert_eq!(wallet.network.chain_id, 100);
    
    // The address should be a valid Ethereum address
    assert!(wallet.address_string().starts_with("0x"));
    
    // The address should be deterministic based on the private key
    let wallet2 = EthereumWallet::from_private_key(private_key, network.clone()).unwrap();
    assert_eq!(wallet.address, wallet2.address);
}

#[test]
fn test_wallet_management() {
    // Clear any existing wallets
    clear_ethereum_wallets();
    
    // Create a key space and keypair
    crate::vault::keypair::session_manager::create_space("test_space").unwrap();
    crate::vault::keypair::create_keypair("test_keypair3").unwrap();
    
    // Create wallets for different networks
    let gnosis_wallet = create_ethereum_wallet_for_network(networks::gnosis()).unwrap();
    let peaq_wallet = create_ethereum_wallet_for_network(networks::peaq()).unwrap();
    let agung_wallet = create_ethereum_wallet_for_network(networks::agung()).unwrap();
    
    // Get the current wallets
    let current_gnosis = get_current_ethereum_wallet_for_network("Gnosis").unwrap();
    let current_peaq = get_current_ethereum_wallet_for_network("Peaq").unwrap();
    let current_agung = get_current_ethereum_wallet_for_network("Agung").unwrap();
    
    // Check that they match
    assert_eq!(gnosis_wallet.address, current_gnosis.address);
    assert_eq!(peaq_wallet.address, current_peaq.address);
    assert_eq!(agung_wallet.address, current_agung.address);
    
    // Clear wallets for a specific network
    clear_ethereum_wallets_for_network("Gnosis");
    
    // Check that the wallet is gone
    let result = get_current_ethereum_wallet_for_network("Gnosis");
    assert!(result.is_err());
    
    // But the others should still be there
    let current_peaq = get_current_ethereum_wallet_for_network("Peaq").unwrap();
    let current_agung = get_current_ethereum_wallet_for_network("Agung").unwrap();
    assert_eq!(peaq_wallet.address, current_peaq.address);
    assert_eq!(agung_wallet.address, current_agung.address);
    
    // Clear all wallets
    clear_ethereum_wallets();
    
    // Check that all wallets are gone
    let result1 = get_current_ethereum_wallet_for_network("Gnosis");
    let result2 = get_current_ethereum_wallet_for_network("Peaq");
    let result3 = get_current_ethereum_wallet_for_network("Agung");
    assert!(result1.is_err());
    assert!(result2.is_err());
    assert!(result3.is_err());
}

#[test]
fn test_sign_message() {
    let keypair = KeyPair::new("test_keypair4");
    let network = networks::gnosis();
    
    let wallet = EthereumWallet::from_keypair(&keypair, network.clone()).unwrap();
    
    // Create a tokio runtime for the async test
    let rt = tokio::runtime::Runtime::new().unwrap();
    
    // Sign a message
    let message = b"Hello, world!";
    let signature = rt.block_on(wallet.sign_message(message)).unwrap();
    
    // The signature should be a non-empty string
    assert!(!signature.is_empty());
}

#[test]
fn test_private_key_hex() {
    let keypair = KeyPair::new("test_keypair5");
    let network = networks::gnosis();
    
    let wallet = EthereumWallet::from_keypair(&keypair, network.clone()).unwrap();
    
    // Get the private key as hex
    let private_key_hex = wallet.private_key_hex();
    
    // The private key should be a 64-character hex string (32 bytes)
    assert_eq!(private_key_hex.len(), 64);
    
    // It should be possible to parse it as hex
    let _bytes = hex::decode(private_key_hex).unwrap();
}