ethers_wallet_rs/
wallet.rs

1//! ethers-rs wallet facade
2//!
3
4use ethers_types_rs::bytes::bytes_from_str;
5
6use crate::{Result, WalletError};
7
8#[cfg(feature = "pure")]
9mod pure;
10#[cfg(feature = "pure")]
11pub type Wallet = pure::LocalWalletRustCrypto;
12
13#[cfg(feature = "openssl")]
14mod openssl;
15
16/// Private key provider trait
17pub trait KeyProvider {
18    /// Load private key to memory
19    fn load(&self) -> Result<Vec<u8>>;
20}
21
22impl<'a> KeyProvider for &'a str {
23    fn load(&self) -> Result<Vec<u8>> {
24        bytes_from_str(self).map_err(|err| WalletError::LoadKey(format!("{}", err)))
25    }
26}
27
28impl<'a> KeyProvider for &'a [u8] {
29    fn load(&self) -> Result<Vec<u8>> {
30        Ok(self.to_vec())
31    }
32}
33
34impl KeyProvider for Vec<u8> {
35    fn load(&self) -> Result<Vec<u8>> {
36        Ok(self.clone())
37    }
38}
39
40impl<const LEN: usize> KeyProvider for [u8; LEN] {
41    fn load(&self) -> Result<Vec<u8>> {
42        Ok(self.to_vec())
43    }
44}
45
46#[cfg(test)]
47mod tests {
48
49    use ethers_hash_rs::keccak256;
50    use ethers_types_rs::signature::SignatureVRS;
51    use ethers_types_rs::{Address, AddressEx, Eip55};
52
53    use super::Wallet;
54
55    #[test]
56    fn test_public_key() {
57        let _ = pretty_env_logger::try_init();
58
59        let wallet =
60            Wallet::new("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
61                .expect("Create wallet from private key");
62
63        let address =
64            Address::from_pub_key(wallet.public_key(false).expect("Public key").as_slice())
65                .expect("Address from publick key");
66
67        assert_eq!(
68            address.to_checksum_string(),
69            "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
70        );
71    }
72
73    #[test]
74    fn test_sign_and_recover() {
75        let _ = pretty_env_logger::try_init();
76
77        let expected = "0x01f16ea9a3478698f695fd1401bfe27e9e4a7e8e3da94aa72b021125e31fa899cc573c48ea3fe1d4ab61a9db10c19032026e3ed2dbccba5a178235ac27f9450431";
78
79        let data = "hello";
80
81        let hashed = format!("\x19Ethereum Signed Message:\n{}{}", data.len(), data);
82
83        let hashed = keccak256(hashed);
84
85        let wallet =
86            Wallet::new("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
87                .expect("Create wallet from private key");
88
89        let signature = wallet.sign(&hashed).expect("personal_sign");
90
91        assert_eq!(expected, format!("{:#x}", signature));
92
93        assert!(wallet
94            .verify(&hashed, signature.r(), signature.s())
95            .expect("Verify signature"));
96
97        let address =
98            Address::from_pub_key(wallet.public_key(false).expect("Public key").as_slice())
99                .expect("Address from publick key");
100
101        assert_eq!(
102            address.to_checksum_string(),
103            "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
104        );
105
106        let recover_verify = wallet
107            .recover(&hashed, signature, false)
108            .expect("Verify signature");
109
110        let address =
111            Address::from_pub_key(recover_verify.as_slice()).expect("Address from publick key");
112
113        assert_eq!(
114            address.to_checksum_string(),
115            "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
116        );
117    }
118}