kobe_sol/
standard_wallet.rs1#[cfg(feature = "rand")]
7use rand_core::OsRng;
8
9use alloc::string::String;
10use ed25519_dalek::{SigningKey, VerifyingKey};
11use zeroize::Zeroizing;
12
13use crate::Error;
14
15#[derive(Debug)]
30pub struct StandardWallet {
31 signing_key: SigningKey,
33}
34
35impl StandardWallet {
36 #[cfg(feature = "rand")]
40 #[must_use]
41 pub fn generate() -> Self {
42 let signing_key = SigningKey::generate(&mut OsRng);
43 Self { signing_key }
44 }
45
46 #[must_use]
48 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
49 let signing_key = SigningKey::from_bytes(bytes);
50 Self { signing_key }
51 }
52
53 pub fn from_hex(hex_key: &str) -> Result<Self, Error> {
59 let bytes = hex::decode(hex_key).map_err(|_| Error::InvalidHex)?;
60
61 if bytes.len() != 32 {
62 return Err(Error::Derivation(alloc::format!(
63 "expected 32 bytes, got {}",
64 bytes.len()
65 )));
66 }
67
68 let mut key_bytes = [0u8; 32];
69 key_bytes.copy_from_slice(&bytes);
70 Ok(Self::from_bytes(&key_bytes))
71 }
72
73 #[inline]
75 #[must_use]
76 pub fn address(&self) -> String {
77 let verifying_key: VerifyingKey = self.signing_key.verifying_key();
78 bs58::encode(verifying_key.as_bytes()).into_string()
79 }
80
81 #[inline]
83 #[must_use]
84 pub fn secret_bytes(&self) -> Zeroizing<[u8; 32]> {
85 Zeroizing::new(*self.signing_key.as_bytes())
86 }
87
88 #[inline]
90 #[must_use]
91 pub fn secret_hex(&self) -> Zeroizing<String> {
92 Zeroizing::new(hex::encode(self.signing_key.as_bytes()))
93 }
94
95 #[inline]
97 #[must_use]
98 pub fn pubkey_hex(&self) -> String {
99 let verifying_key: VerifyingKey = self.signing_key.verifying_key();
100 hex::encode(verifying_key.as_bytes())
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[cfg(feature = "rand")]
109 #[test]
110 fn test_generate() {
111 let wallet = StandardWallet::generate();
112 let address = wallet.address();
113
114 assert!(address.len() >= 32 && address.len() <= 44);
116 }
117
118 #[test]
119 fn test_from_bytes() {
120 let key = [1u8; 32];
121 let wallet = StandardWallet::from_bytes(&key);
122 let address = wallet.address();
123
124 assert!(address.len() >= 32 && address.len() <= 44);
125 }
126
127 #[test]
128 fn test_from_hex() {
129 let hex_key = "0101010101010101010101010101010101010101010101010101010101010101";
130 let wallet = StandardWallet::from_hex(hex_key).unwrap();
131 let address = wallet.address();
132
133 assert!(address.len() >= 32 && address.len() <= 44);
134 }
135
136 #[test]
137 fn test_deterministic() {
138 let key = [42u8; 32];
139 let wallet1 = StandardWallet::from_bytes(&key);
140 let wallet2 = StandardWallet::from_bytes(&key);
141
142 assert_eq!(wallet1.address(), wallet2.address());
143 }
144}