sal-vault 0.1.0

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

use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::sync::Mutex;

use super::networks::{self, NetworkConfig};
use super::wallet::EthereumWallet;
use crate::error::CryptoError;

/// Global storage for Ethereum wallets.
static ETH_WALLETS: Lazy<Mutex<HashMap<String, Vec<EthereumWallet>>>> =
    Lazy::new(|| Mutex::new(HashMap::new()));

/// Creates an Ethereum wallet from the currently selected keypair for a specific network.
pub fn create_ethereum_wallet_for_network(
    network: NetworkConfig,
) -> Result<EthereumWallet, CryptoError> {
    // Get the currently selected keypair
    let keypair = crate::keyspace::get_selected_keypair()?;

    // Create an Ethereum wallet from the keypair
    let wallet = EthereumWallet::from_keypair(&keypair, network)?;

    // Store the wallet
    let mut wallets = ETH_WALLETS.lock().unwrap();
    let network_wallets = wallets
        .entry(wallet.network.name.clone())
        .or_insert_with(Vec::new);
    network_wallets.push(wallet.clone());

    Ok(wallet)
}

/// Creates an Ethereum wallet from the currently selected keypair for the Peaq network.
pub fn create_peaq_wallet() -> Result<EthereumWallet, CryptoError> {
    create_ethereum_wallet_for_network(networks::peaq())
}

/// Creates an Ethereum wallet from the currently selected keypair for the Agung testnet.
pub fn create_agung_wallet() -> Result<EthereumWallet, CryptoError> {
    create_ethereum_wallet_for_network(networks::agung())
}

/// Gets the current Ethereum wallet for a specific network.
pub fn get_current_ethereum_wallet_for_network(
    network_name: &str,
) -> Result<EthereumWallet, CryptoError> {
    let wallets = ETH_WALLETS.lock().unwrap();

    let network_wallets = wallets
        .get(network_name)
        .ok_or(CryptoError::NoKeypairSelected)?;

    if network_wallets.is_empty() {
        return Err(CryptoError::NoKeypairSelected);
    }

    Ok(network_wallets.last().unwrap().clone())
}

/// Gets the current Ethereum wallet for the Peaq network.
pub fn get_current_peaq_wallet() -> Result<EthereumWallet, CryptoError> {
    get_current_ethereum_wallet_for_network("Peaq")
}

/// Gets the current Ethereum wallet for the Agung testnet.
pub fn get_current_agung_wallet() -> Result<EthereumWallet, CryptoError> {
    get_current_ethereum_wallet_for_network("Agung")
}

/// Clears all Ethereum wallets.
pub fn clear_ethereum_wallets() {
    let mut wallets = ETH_WALLETS.lock().unwrap();
    wallets.clear();
}

/// Clears Ethereum wallets for a specific network.
pub fn clear_ethereum_wallets_for_network(network_name: &str) {
    let mut wallets = ETH_WALLETS.lock().unwrap();
    wallets.remove(network_name);
}

/// Creates an Ethereum wallet from a name and the currently selected keypair for a specific network.
pub fn create_ethereum_wallet_from_name_for_network(
    name: &str,
    network: NetworkConfig,
) -> Result<EthereumWallet, CryptoError> {
    // Get the currently selected keypair
    let keypair = crate::keyspace::get_selected_keypair()?;

    // Create an Ethereum wallet from the name and keypair
    let wallet = EthereumWallet::from_name_and_keypair(name, &keypair, network)?;

    // Store the wallet
    let mut wallets = ETH_WALLETS.lock().unwrap();
    let network_wallets = wallets
        .entry(wallet.network.name.clone())
        .or_insert_with(Vec::new);
    network_wallets.push(wallet.clone());

    Ok(wallet)
}

/// Creates an Ethereum wallet from a name and the currently selected keypair for the Gnosis network.
pub fn create_ethereum_wallet_from_name(name: &str) -> Result<EthereumWallet, CryptoError> {
    create_ethereum_wallet_from_name_for_network(name, networks::gnosis())
}

/// Creates an Ethereum wallet from a private key for a specific network.
pub fn create_ethereum_wallet_from_private_key_for_network(
    private_key: &str,
    network: NetworkConfig,
) -> Result<EthereumWallet, CryptoError> {
    // Create an Ethereum wallet from the private key
    let wallet = EthereumWallet::from_private_key(private_key, network)?;

    // Store the wallet
    let mut wallets = ETH_WALLETS.lock().unwrap();
    let network_wallets = wallets
        .entry(wallet.network.name.clone())
        .or_insert_with(Vec::new);
    network_wallets.push(wallet.clone());

    Ok(wallet)
}

/// Creates an Ethereum wallet from a private key for the Gnosis network.
pub fn create_ethereum_wallet_from_private_key(
    private_key: &str,
) -> Result<EthereumWallet, CryptoError> {
    create_ethereum_wallet_from_private_key_for_network(private_key, networks::gnosis())
}