wallet_rs_cli/metamask/
mod.rs1use clap::Parser;
6use eth_keystore::encrypt_key;
7use ethers_signers::{coins_bip39::English, MnemonicBuilder};
8use tracing::{debug, error, info};
9use wallet_metamask::{
10 interactive::{extract_all_vaults, get_password},
11 vault::decrypt_vault,
12};
13
14#[derive(Debug, Parser)]
16pub struct Command {
17 #[arg(short, long)]
19 output: bool,
20
21 #[arg(short, long)]
23 keystore: Option<String>,
24
25 #[arg(short, long)]
27 test: bool,
28}
29
30impl Command {
31 pub async fn run(&self) -> eyre::Result<()> {
32 let vaults = extract_all_vaults();
34
35 if let Err(e) = vaults {
37 error!("Failed to extract vaults: {:?}", e);
38 return Ok(());
39 }
40
41 if self.test {
43 info!("Cargo test, exiting");
44 return Ok(());
45 }
46
47 let vaults = vaults.unwrap();
49
50 info!("Found {} vaults", vaults.len());
52
53 if vaults.is_empty() {
55 error!("No vaults found");
56 return Ok(());
57 }
58
59 let vault = vaults[0].clone();
61 let pwd = get_password().unwrap();
62
63 let res = decrypt_vault(&vault, &pwd);
65
66 if res.is_ok() {
68 debug!("Decrypted vault");
69
70 if self.output {
72 print!("{}", &res.unwrap().data.mnemonic);
73 return Ok(());
74 }
75
76 if self.keystore.is_some() {
77 let index = 0u32;
79 let phrase = &res.unwrap().data.mnemonic.to_string();
80
81 let wallet = MnemonicBuilder::<English>::default()
83 .phrase(phrase.as_str())
84 .index(index)
85 .unwrap()
86 .build()
87 .unwrap();
88
89 let pk = wallet.signer();
91 let mut rng = rand::thread_rng();
92 let _ =
93 encrypt_key(self.keystore.clone().unwrap(), &mut rng, pk.to_bytes(), pwd, None);
94 }
95 } else {
96 error!("Failed to decrypt vault: {:?}", res);
97 }
98 Ok(())
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105 use tracing_test::traced_test;
106
107 #[traced_test]
108 #[tokio::test]
109 async fn test_metamask_run() {
110 let command = Command { output: false, keystore: None, test: true };
112
113 let res = command.run().await;
115
116 assert!(res.is_ok());
118
119 assert!(logs_contain("Failed to extract") || logs_contain("Cargo test, exiting"));
121 }
122}