Skip to content

Commit fee44fd

Browse files
author
example-user
committed
fix: added quiet mode
1 parent e2cae85 commit fee44fd

2 files changed

Lines changed: 139 additions & 25 deletions

File tree

benches/bip39_bench.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn bench_generate_mnemonic(c: &mut Criterion) {
88
for &word_count in &[12, 15, 18, 21, 24] {
99
let entropy_bytes = word_count * 32 / 24; // Convert word count to entropy bytes
1010

11-
group.bench_function(format!("{}_words", word_count), |b| {
11+
group.bench_function(format!("{word_count}_words"), |b| {
1212
b.iter(|| {
1313
let mut entropy = vec![0u8; entropy_bytes];
1414
OsRng.fill_bytes(&mut entropy);
@@ -101,8 +101,8 @@ fn bench_languages(c: &mut Criterion) {
101101
let mut group = c.benchmark_group("languages");
102102

103103
for language in &languages {
104-
let lang_name = format!("{:?}", language).to_lowercase();
105-
group.bench_function(format!("generate_{}", lang_name), |b| {
104+
let lang_name = format!("{language:?}").to_lowercase();
105+
group.bench_function(format!("generate_{lang_name}"), |b| {
106106
b.iter(|| {
107107
black_box(Mnemonic::from_entropy_in(*language, &entropy).unwrap());
108108
})

src/main.rs

Lines changed: 136 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ enum Commands {
4242
/// Passphrase for seed derivation (only used with --show-seed)
4343
#[arg(long, default_value = "")]
4444
passphrase: String,
45+
46+
/// Output only raw data without headers (useful for piping)
47+
#[arg(short, long)]
48+
quiet: bool,
4549
},
4650

4751
/// Validate a mnemonic phrase
@@ -52,6 +56,10 @@ enum Commands {
5256
/// Language of the mnemonic
5357
#[arg(short, long, default_value = "english")]
5458
language: LanguageOption,
59+
60+
/// Output only raw data without headers (useful for piping)
61+
#[arg(short, long)]
62+
quiet: bool,
5563
},
5664

5765
/// Convert mnemonic to seed
@@ -66,6 +74,10 @@ enum Commands {
6674
/// Language of the mnemonic
6775
#[arg(short, long, default_value = "english")]
6876
language: LanguageOption,
77+
78+
/// Output only raw data without headers (useful for piping)
79+
#[arg(short, long)]
80+
quiet: bool,
6981
},
7082

7183
/// Generate mnemonic from provided entropy
@@ -76,6 +88,10 @@ enum Commands {
7688
/// Language for the mnemonic
7789
#[arg(short, long, default_value = "english")]
7890
language: LanguageOption,
91+
92+
/// Output only raw data without headers (useful for piping)
93+
#[arg(short, long)]
94+
quiet: bool,
7995
},
8096

8197
/// Get entropy from a mnemonic
@@ -86,6 +102,10 @@ enum Commands {
86102
/// Language of the mnemonic
87103
#[arg(short, long, default_value = "english")]
88104
language: LanguageOption,
105+
106+
/// Output only raw data without headers (useful for piping)
107+
#[arg(short, long)]
108+
quiet: bool,
89109
},
90110
}
91111

@@ -119,7 +139,7 @@ impl WordCount {
119139
}
120140
}
121141

122-
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
142+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
123143
enum LanguageOption {
124144
English,
125145
Japanese,
@@ -259,6 +279,7 @@ fn run_command(command: Commands) -> Result<(), CliError> {
259279
show_entropy,
260280
show_seed,
261281
passphrase,
282+
quiet,
262283
} => {
263284
let mut entropy = vec![0u8; words.to_entropy_bytes()];
264285
OsRng.fill_bytes(&mut entropy);
@@ -272,27 +293,85 @@ fn run_command(command: Commands) -> Result<(), CliError> {
272293
WordCount::TwentyOne => 21,
273294
WordCount::TwentyFour => 24,
274295
};
275-
println!("Mnemonic ({word_count} words):");
296+
if !quiet {
297+
let bits = words.to_entropy_bits();
298+
println!("Generated Mnemonic");
299+
println!("═══════════════════");
300+
println!("Words: {word_count}");
301+
println!("Entropy: {bits} bits");
302+
println!();
303+
}
276304
println!("{mnemonic}");
277305

278306
if show_entropy {
279-
println!("\nEntropy ({} bits):", words.to_entropy_bits());
280-
println!("{}", hex::encode(&entropy));
307+
let bits = words.to_entropy_bits();
308+
if !quiet {
309+
println!();
310+
println!("Raw Entropy");
311+
println!("═══════════");
312+
println!("Bits: {bits}");
313+
println!("Bytes: {}", entropy.len());
314+
println!();
315+
} else {
316+
println!();
317+
}
318+
let encoded = hex::encode(&entropy);
319+
println!("{encoded}");
281320
}
282321

283322
if show_seed {
284323
let seed = mnemonic.to_seed(&passphrase);
285-
println!("\nSeed (512 bits):");
286-
println!("{}", hex::encode(seed));
324+
if !quiet {
325+
if !show_entropy {
326+
println!();
327+
}
328+
println!("Derived Seed");
329+
println!("════════════");
330+
println!("Length: 512 bits (64 bytes)");
331+
if !passphrase.is_empty() {
332+
println!("Passphrase: Used");
333+
} else {
334+
println!("Passphrase: None");
335+
}
336+
println!();
337+
} else if show_entropy {
338+
println!();
339+
}
340+
let encoded_seed = hex::encode(seed);
341+
println!("{encoded_seed}");
287342
}
288343
}
289344

290-
Commands::Validate { mnemonic, language } => {
345+
Commands::Validate { mnemonic, language, quiet } => {
291346
validate_mnemonic_word_count(&mnemonic)?;
292347
match Mnemonic::parse_in_normalized(language.into(), &mnemonic) {
293-
Ok(_) => println!("✓ Valid BIP39 mnemonic"),
348+
Ok(parsed_mnemonic) => {
349+
if quiet {
350+
println!("valid");
351+
} else {
352+
let entropy = parsed_mnemonic.to_entropy();
353+
let word_count = mnemonic.split_whitespace().count();
354+
let bits = entropy.len() * 8;
355+
println!("Mnemonic Validation");
356+
println!("═══════════════════");
357+
println!("✓ Status: Valid BIP39 mnemonic");
358+
println!("Words: {word_count}");
359+
println!("Entropy: {bits} bits");
360+
println!("Language: {:?}", language);
361+
}
362+
}
294363
Err(e) => {
295-
println!("✗ Invalid BIP39 mnemonic: {e}");
364+
if quiet {
365+
println!("invalid");
366+
} else {
367+
let word_count = mnemonic.split_whitespace().count();
368+
println!("Mnemonic Validation");
369+
println!("═══════════════════");
370+
println!("✗ Status: Invalid BIP39 mnemonic");
371+
println!("Words: {word_count}");
372+
println!("Error: {e}");
373+
println!("Language: {:?}", language);
374+
}
296375
std::process::exit(1);
297376
}
298377
}
@@ -302,16 +381,33 @@ fn run_command(command: Commands) -> Result<(), CliError> {
302381
mnemonic,
303382
passphrase,
304383
language,
384+
quiet,
305385
} => {
306386
validate_mnemonic_word_count(&mnemonic)?;
307-
let mnemonic = Mnemonic::parse_in_normalized(language.into(), &mnemonic)?;
308-
let seed = mnemonic.to_seed(&passphrase);
309-
310-
println!("Seed (512 bits):");
311-
println!("{}", hex::encode(seed));
387+
let mnemonic_obj = Mnemonic::parse_in_normalized(language.into(), &mnemonic)?;
388+
let seed = mnemonic_obj.to_seed(&passphrase);
389+
390+
if !quiet {
391+
let entropy = mnemonic_obj.to_entropy();
392+
let word_count = mnemonic.split_whitespace().count();
393+
let entropy_bits = entropy.len() * 8;
394+
println!("Seed Generation");
395+
println!("════════════════");
396+
println!("Input words: {word_count}");
397+
println!("Input entropy: {entropy_bits} bits");
398+
println!("Output: 512 bits (64 bytes)");
399+
if !passphrase.is_empty() {
400+
println!("Passphrase: Used");
401+
} else {
402+
println!("Passphrase: None");
403+
}
404+
println!();
405+
}
406+
let encoded_seed = hex::encode(seed);
407+
println!("{encoded_seed}");
312408
}
313409

314-
Commands::FromEntropy { entropy, language } => {
410+
Commands::FromEntropy { entropy, language, quiet } => {
315411
validate_entropy_hex(&entropy)?;
316412
let entropy_bytes = hex::decode(&entropy)?;
317413
let mnemonic = Mnemonic::from_entropy_in(language.into(), &entropy_bytes)?;
@@ -329,17 +425,35 @@ fn run_command(command: Commands) -> Result<(), CliError> {
329425
});
330426
}
331427
};
332-
println!("Mnemonic ({word_count} words):");
428+
if !quiet {
429+
let bits = entropy_bytes.len() * 8;
430+
println!("Mnemonic from Entropy");
431+
println!("══════════════════════");
432+
println!("Input entropy: {bits} bits ({} bytes)", entropy_bytes.len());
433+
println!("Output words: {word_count}");
434+
println!("Language: {:?}", language);
435+
println!();
436+
}
333437
println!("{mnemonic}");
334438
}
335439

336-
Commands::Entropy { mnemonic, language } => {
440+
Commands::Entropy { mnemonic, language, quiet } => {
337441
validate_mnemonic_word_count(&mnemonic)?;
338-
let mnemonic = Mnemonic::parse_in_normalized(language.into(), &mnemonic)?;
339-
let entropy = mnemonic.to_entropy();
340-
341-
println!("Entropy ({} bits):", entropy.len() * 8);
342-
println!("{}", hex::encode(&entropy));
442+
let mnemonic_obj = Mnemonic::parse_in_normalized(language.into(), &mnemonic)?;
443+
let entropy = mnemonic_obj.to_entropy();
444+
445+
let bits = entropy.len() * 8;
446+
if !quiet {
447+
let word_count = mnemonic.split_whitespace().count();
448+
println!("Entropy Extraction");
449+
println!("═══════════════════");
450+
println!("Input words: {word_count}");
451+
println!("Output entropy: {bits} bits ({} bytes)", entropy.len());
452+
println!("Language: {:?}", language);
453+
println!();
454+
}
455+
let encoded_entropy = hex::encode(&entropy);
456+
println!("{encoded_entropy}");
343457
}
344458
}
345459

0 commit comments

Comments
 (0)