Skip to content

Commit

Permalink
feat(cast): add json flag in cast wallet new-mnemonic (foundry-rs…
Browse files Browse the repository at this point in the history
…#9139)

* feat(cast): add `json` flag in `cast wallet new-mnemonic`

* Update crates/cast/bin/cmd/wallet/mod.rs

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>

* Update crates/cast/tests/cli/main.rs

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>

* chore: adjust `wallet_mnemonic_from_entropy` to generate three accounts instead of one

* Update crates/cast/bin/cmd/wallet/mod.rs

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>

* fix: preserve check-summed format for addresses

* chore: simplify code

* fix: rustfmt

---------

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
  • Loading branch information
2 people authored and rplusq committed Nov 29, 2024
1 parent e9675e4 commit a7f608c
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 11 deletions.
43 changes: 35 additions & 8 deletions crates/cast/bin/cmd/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ pub enum WalletSubcommands {
/// Entropy to use for the mnemonic
#[arg(long, short, conflicts_with = "words")]
entropy: Option<String>,

/// Output generated mnemonic phrase and accounts as JSON.
#[arg(long, short, default_value = "false")]
json: bool,
},

/// Generate a vanity address.
Expand Down Expand Up @@ -290,16 +294,19 @@ impl WalletSubcommands {
}
}
}
Self::NewMnemonic { words, accounts, entropy } => {
Self::NewMnemonic { words, accounts, entropy, json } => {
let phrase = if let Some(entropy) = entropy {
let entropy = Entropy::from_slice(hex::decode(entropy)?)?;
println!("{}", "Generating mnemonic from provided entropy...".yellow());
Mnemonic::<English>::new_from_entropy(entropy).to_phrase()
} else {
let mut rng = thread_rng();
Mnemonic::<English>::new_with_count(&mut rng, words)?.to_phrase()
};

if !json {
println!("{}", "Generating mnemonic from provided entropy...".yellow());
}

let builder = MnemonicBuilder::<English>::default().phrase(phrase.as_str());
let derivation_path = "m/44'/60'/0'/0/";
let wallets = (0..accounts)
Expand All @@ -308,13 +315,33 @@ impl WalletSubcommands {
let wallets =
wallets.into_iter().map(|b| b.build()).collect::<Result<Vec<_>, _>>()?;

println!("{}", "Successfully generated a new mnemonic.".green());
println!("Phrase:\n{phrase}");
println!("\nAccounts:");
if !json {
println!("{}", "Successfully generated a new mnemonic.".green());
println!("Phrase:\n{phrase}");
println!("\nAccounts:");
}

let mut accounts = json!([]);
for (i, wallet) in wallets.iter().enumerate() {
println!("- Account {i}:");
println!("Address: {}", wallet.address());
println!("Private key: 0x{}\n", hex::encode(wallet.credential().to_bytes()));
let private_key = hex::encode(wallet.credential().to_bytes());
if json {
accounts.as_array_mut().unwrap().push(json!({
"address": format!("{}", wallet.address()),
"private_key": format!("0x{}", private_key),
}));
} else {
println!("- Account {i}:");
println!("Address: {}", wallet.address());
println!("Private key: 0x{private_key}\n");
}
}

if json {
let obj = json!({
"mnemonic": phrase,
"accounts": accounts,
});
println!("{}", serde_json::to_string_pretty(&obj)?);
}
}
Self::Vanity(cmd) => {
Expand Down
55 changes: 52 additions & 3 deletions crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,16 @@ Created new encrypted keystore file: [..]

// tests that `cast wallet new-mnemonic --entropy` outputs the expected mnemonic
casttest!(wallet_mnemonic_from_entropy, |_prj, cmd| {
cmd.args(["wallet", "new-mnemonic", "--entropy", "0xdf9bf37e6fcdf9bf37e6fcdf9bf37e3c"])
.assert_success()
.stdout_eq(str![[r#"
cmd.args([
"wallet",
"new-mnemonic",
"--accounts",
"3",
"--entropy",
"0xdf9bf37e6fcdf9bf37e6fcdf9bf37e3c",
])
.assert_success()
.stdout_eq(str![[r#"
Generating mnemonic from provided entropy...
Successfully generated a new mnemonic.
Phrase:
Expand All @@ -298,6 +305,48 @@ Accounts:
Address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Private key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
- Account 1:
Address: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
Private key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
- Account 2:
Address: 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
Private key: 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
"#]]);
});

// tests that `cast wallet new-mnemonic --json` outputs the expected mnemonic
casttest!(wallet_mnemonic_from_entropy_json, |_prj, cmd| {
cmd.args([
"wallet",
"new-mnemonic",
"--accounts",
"3",
"--entropy",
"0xdf9bf37e6fcdf9bf37e6fcdf9bf37e3c",
"--json",
])
.assert_success()
.stdout_eq(str![[r#"
{
"mnemonic": "test test test test test test test test test test test junk",
"accounts": [
{
"address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"private_key": "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
},
{
"address": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"private_key": "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
},
{
"address": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
"private_key": "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"
}
]
}
"#]]);
});
Expand Down

0 comments on commit a7f608c

Please sign in to comment.