1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use clap::Parser;
use eth_keystore::encrypt_key;
use ethers_signers::{coins_bip39::English, MnemonicBuilder};
use tracing::{debug, info};
use wallet_metamask::{
    interactive::{extract_all_vaults, get_password},
    vault::decrypt_vault,
};

/// Start the metamask command
#[derive(Debug, Parser)]
pub struct Command {
    /// Output the decrypted mnemonic to stdout
    #[arg(short, long)]
    output: bool,

    /// The path to the keystore file, if you want to export the encrypted keystore
    #[arg(short, long)]
    keystore: Option<String>,
}

impl Command {
    pub async fn run(&self) -> eyre::Result<()> {
        // Get the vaults and the password
        let vaults = extract_all_vaults().unwrap();
        let vault = vaults[0].clone();
        let pwd = get_password().unwrap();

        // Attempt to decrypt the vault
        let res = decrypt_vault(&vault, &pwd);

        // Print the result
        if res.is_ok() {
            debug!("Decrypted vault");

            // Print the mnemonic
            if self.output {
                println!("{}", &res.unwrap().data.mnemonic);
                return Ok(());
            }

            if self.keystore.is_some() {
                let index = 0u32;
                let phrase = &res.unwrap().data.mnemonic.to_string();

                let wallet = MnemonicBuilder::<English>::default()
                    .phrase(phrase.as_str())
                    .index(index)
                    .unwrap()
                    .build()
                    .unwrap();

                let pk = wallet.signer();
                let mut rng = rand::thread_rng();
                let _ =
                    encrypt_key(self.keystore.clone().unwrap(), &mut rng, pk.to_bytes(), pwd, None);
            }

            // let a = Wallet::<SigningKey>::new_keystore("", &mut rng, "randpsswd", None).unwrap();
        } else {
            info!("Failed to decrypt vault: {:?}", res);
        }
        Ok(())
    }
}