aptos_network_sdk/
wallet.rs

1use ring::signature::Ed25519KeyPair;
2use serde::{Deserialize, Serialize};
3use sha3::{Digest, Sha3_256};
4
5use ring::signature::KeyPair;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Wallet {
9    keypair: Vec<u8>,
10}
11
12impl Wallet {
13    /// create new wallet
14    pub fn new() -> Result<Self, String> {
15        let rng = ring::rand::SystemRandom::new();
16        let pkcs8_bytes = Ed25519KeyPair::generate_pkcs8(&rng)
17            .map_err(|e| format!("Failed to generate keypair: {}", e))?;
18
19        Ok(Wallet {
20            keypair: pkcs8_bytes.as_ref().to_vec(),
21        })
22    }
23
24    pub fn from_pkcs8_bytes(pkcs8_bytes: &[u8]) -> Result<Self, String> {
25        let _ = Ed25519KeyPair::from_pkcs8(pkcs8_bytes)
26            .map_err(|e| format!("Invalid PKCS8 format: {}", e))?;
27
28        Ok(Wallet {
29            keypair: pkcs8_bytes.to_vec(),
30        })
31    }
32
33    /// create wallet from private key
34    pub fn from_private_key_hex(private_key_hex: &str) -> Result<Self, String> {
35        let pkcs8_bytes =
36            hex::decode(private_key_hex).map_err(|e| format!("Invalid hex: {}", e))?;
37        Self::from_pkcs8_bytes(&pkcs8_bytes)
38    }
39
40    /// get keypair
41    fn keypair(&self) -> Result<Ed25519KeyPair, String> {
42        Ed25519KeyPair::from_pkcs8(&self.keypair)
43            .map_err(|e| format!("Failed to load keypair: {}", e))
44    }
45
46    /// get wallet from base private key
47    pub fn from_private_key_base64(private_key_base64: &str) -> Result<Self, String> {
48        use base64::Engine as _;
49        let pkcs8_bytes = base64::engine::general_purpose::STANDARD
50            .decode(private_key_base64)
51            .map_err(|e| format!("Invalid base64: {}", e))?;
52        Self::from_pkcs8_bytes(&pkcs8_bytes)
53    }
54
55    /// get public key bytes
56    pub fn public_key_bytes(&self) -> Result<Vec<u8>, String> {
57        let keypair = self.keypair()?;
58        Ok(keypair.public_key().as_ref().to_vec())
59    }
60
61    /// get public key hex
62    pub fn public_key_hex(&self) -> Result<String, String> {
63        let public_key = self.public_key_bytes()?;
64        Ok(hex::encode(public_key))
65    }
66
67    /// get public key address
68    pub fn address(&self) -> Result<String, String> {
69        let public_key = self.public_key_bytes()?;
70        let mut hasher = Sha3_256::new();
71        hasher.update(&public_key);
72        hasher.update(&[0u8]);
73        let result = hasher.finalize();
74        Ok(format!("0x{}", hex::encode(result)))
75    }
76
77    /// sign
78    pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, String> {
79        let keypair = self.keypair()?;
80        let signature = keypair.sign(message);
81        Ok(signature.as_ref().to_vec())
82    }
83
84    /// verify message
85    pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool, String> {
86        let public_key = self.public_key_bytes()?;
87        let peer_public_key =
88            ring::signature::UnparsedPublicKey::new(&ring::signature::ED25519, &public_key);
89        match peer_public_key.verify(message, signature) {
90            Ok(()) => Ok(true),
91            Err(_) => Ok(false),
92        }
93    }
94
95    /// get private key hex
96    pub fn private_key_hex(&self) -> String {
97        hex::encode(&self.keypair)
98    }
99
100    /// get private key base4
101    pub fn private_key_base64(&self) -> String {
102        use base64::Engine as _;
103        base64::engine::general_purpose::STANDARD.encode(&self.keypair)
104    }
105
106    /// export keypair
107    pub fn export_keypair(&self) -> Vec<u8> {
108        self.keypair.clone()
109    }
110
111    /// clear wallet
112    pub fn clear(mut self) {
113        for byte in self.keypair.iter_mut() {
114            *byte = 0;
115        }
116    }
117}