forc_wallet/
export.rs

1use crate::utils::display_string_discreetly;
2use anyhow::{Context, Result, anyhow};
3use rpassword::prompt_password;
4use std::path::Path;
5
6/// Decrypts a wallet using provided password
7fn decrypt_mnemonic(wallet_path: &Path, password: &str) -> Result<String> {
8    let phrase_bytes = eth_keystore::decrypt_key(wallet_path, password)
9        .map_err(|e| anyhow!("Failed to decrypt keystore: {}", e))?;
10
11    String::from_utf8(phrase_bytes).context("Invalid UTF-8 in mnemonic phrase")
12}
13
14/// Prints the wallet at the given path as mnemonic phrase as a discrete string
15pub fn export_wallet_cli(wallet_path: &Path) -> Result<()> {
16    let prompt = "Please enter your wallet password to export your wallet: ";
17    let password = prompt_password(prompt)?;
18    let phrase = decrypt_mnemonic(wallet_path, &password)?;
19
20    // Display phrase in alternate screen
21    display_string_discreetly(
22        &phrase,
23        "### Do not share or lose this mnemonic phrase! Press any key to complete. ###",
24    )?;
25
26    Ok(())
27}
28
29#[cfg(test)]
30mod tests {
31    use crate::{
32        export::decrypt_mnemonic,
33        utils::test_utils::{TEST_MNEMONIC, TEST_PASSWORD, with_tmp_dir_and_wallet},
34    };
35
36    #[test]
37    fn decrypt_wallet() {
38        with_tmp_dir_and_wallet(|_dir, wallet_path| {
39            let decrypted_mnemonic = decrypt_mnemonic(wallet_path, TEST_PASSWORD).unwrap();
40            assert_eq!(decrypted_mnemonic, TEST_MNEMONIC)
41        });
42    }
43}