Skip to main content

polyoxide_clob/account/
wallet.rs

1use alloy::{network::EthereumWallet, primitives::Address, signers::local::PrivateKeySigner};
2
3use crate::error::ClobError;
4
5/// Wallet wrapper for signing operations
6#[derive(Clone)]
7pub struct Wallet {
8    signer: PrivateKeySigner,
9    wallet: EthereumWallet,
10}
11
12impl std::fmt::Debug for Wallet {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        f.debug_struct("Wallet")
15            .field("address", &self.signer.address())
16            .finish()
17    }
18}
19
20impl Wallet {
21    /// Create wallet from private key hex string
22    pub fn from_private_key(private_key: &str) -> Result<Self, ClobError> {
23        let signer = private_key
24            .parse::<PrivateKeySigner>()
25            .map_err(|e| ClobError::Crypto(format!("Failed to parse private key: {}", e)))?;
26        let wallet = EthereumWallet::from(signer.clone());
27
28        Ok(Self { signer, wallet })
29    }
30
31    /// Get the wallet address
32    pub fn address(&self) -> Address {
33        self.signer.address()
34    }
35
36    /// Get reference to the signer
37    pub fn signer(&self) -> &PrivateKeySigner {
38        &self.signer
39    }
40
41    /// Get reference to the Ethereum wallet
42    pub fn ethereum_wallet(&self) -> &EthereumWallet {
43        &self.wallet
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    // Well-known test private key (DO NOT use in production)
52    const TEST_KEY: &str = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
53
54    #[test]
55    fn test_wallet_debug_shows_address_not_key() {
56        let wallet = Wallet::from_private_key(TEST_KEY).unwrap();
57        let debug_output = format!("{:?}", wallet);
58
59        // Should contain "address" field
60        assert!(
61            debug_output.contains("address"),
62            "Debug should show address: {}",
63            debug_output
64        );
65        // Should NOT contain the private key material
66        assert!(
67            !debug_output
68                .contains("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"),
69            "Debug should NOT contain private key: {}",
70            debug_output
71        );
72    }
73}