lens_client/crypto/
mod.rs1use k256::ecdsa::SigningKey;
2use sha3::{Digest, Keccak256};
3use std::io::Read;
4use std::path::Path;
5
6use secp256k1::{PublicKey, Secp256k1, SecretKey};
7
8pub struct Wallet {
9 pub keystore: eth_keystore::EthKeystore,
10 pub private_key: Option<Vec<u8>>,
11 pub public_key: Option<PublicKey>,
12 pub name: String,
13 pub signing_key: SigningKey,
14 pub address: String,
15 pub path: String,
16}
17
18pub fn generate_wallet(
26 path: String,
27 password: String,
28 name: Option<&str>,
29 with_keys: bool,
30) -> Result<Wallet, eth_keystore::KeystoreError> {
31 let mut rng = rand::thread_rng();
32 let dir = Path::new(&path);
33 let (_private_key, name) = eth_keystore::new(dir, &mut rng, password.clone(), name)?;
34
35 let mut file = std::fs::File::open(format!("{}/{}", path, name))?;
36 let mut contents = String::new();
37 file.read_to_string(&mut contents)?;
38
39 let wallet = keystore_to_wallet(contents, &path, &name, &password, with_keys)?;
40
41 return Ok(wallet);
42}
43
44pub fn load_wallet(
45 path: &String,
46 name: &String,
47 password: String,
48) -> Result<Wallet, eth_keystore::KeystoreError> {
49 let mut file = std::fs::File::open(format!("{}/{}", path, name)).unwrap();
50 let mut contents = String::new();
51 file.read_to_string(&mut contents).unwrap();
52
53 let wallet = keystore_to_wallet(contents, path, name, &password, true)?;
54
55 return Ok(wallet);
56}
57
58pub fn keystore_to_wallet(
59 keystore_string: String,
60 path: &String,
61 name: &String,
62 password: &String,
63 with_keys: bool,
64) -> Result<Wallet, eth_keystore::KeystoreError> {
65 let keystore: eth_keystore::EthKeystore = serde_json::from_str(&keystore_string)?;
66
67 let private_key = eth_keystore::decrypt_key(format!("{}/{}", path.clone(), name), password)?;
68
69 let mut k = None;
70 let mut pk = None;
71 let signing_key = k256::ecdsa::SigningKey::from_bytes(&private_key).unwrap();
72
73 let secp = Secp256k1::new();
74 let secret_key = SecretKey::from_slice(&private_key).expect("32 bytes, within curve order");
75 let secp256k1_public_key = PublicKey::from_secret_key(&secp, &secret_key);
76
77 let pub_key_bytes = &secp256k1_public_key.serialize_uncompressed()[1..];
78
79 let mut hasher: Keccak256 = Keccak256::new();
80 hasher.update(pub_key_bytes);
81 let hash = hasher.finalize();
82
83 let hash_hex = hex::encode(hash).to_string();
84
85 let address = eth_checksum::checksum(&format!("0x{}", &hash_hex[24..]));
86
87 if with_keys {
88 k = Some(private_key);
89 pk = Some(secp256k1_public_key);
90 }
91
92 let wallet = Wallet {
93 keystore,
94 private_key: k,
95 public_key: pk,
96 name: name.to_string(),
97 signing_key: signing_key,
98 address: address,
99 path: path.clone(),
100 };
101
102 Ok(wallet)
103}
104
105use ethers_signers::LocalWallet;
106use ethers_signers::Signer as EthSigner;
107
108pub fn sign_message(wallet: &Wallet, message: &[u8]) -> String {
111 let mut signature = String::new();
112 async_std::task::block_on(async {
113 let wallet = hex::encode(&wallet.private_key.as_ref().unwrap())
114 .parse::<LocalWallet>()
115 .unwrap();
116
117 signature = wallet.sign_message(message).await.unwrap().to_string();
118 });
119
120 let hex_signature = signature;
121
122 return format!("{}", hex_signature);
123}