use clap::{Args, Subcommand};
use kobe::{DerivedAccount, Wallet};
use crate::output::{self, HdWalletOutput};
pub(crate) type CliResult<T = ()> = Result<T, Box<dyn std::error::Error>>;
#[derive(Args, Debug, Clone)]
pub(crate) struct SimpleArgs {
#[arg(short, long, default_value_t = 12)]
pub words: usize,
#[arg(short, long)]
pub passphrase: Option<String>,
#[arg(short, long, default_value_t = 1)]
pub count: u32,
#[arg(long)]
pub qr: bool,
}
#[derive(Subcommand, Debug)]
pub(crate) enum SimpleSubcommand {
New {
#[command(flatten)]
args: SimpleArgs,
},
Import {
#[arg(short, long)]
mnemonic: String,
#[command(flatten)]
args: SimpleArgs,
},
}
impl SimpleSubcommand {
pub(crate) fn execute<F>(self, chain: &'static str, json: bool, derive_fn: F) -> CliResult
where
F: FnOnce(&Wallet, u32) -> CliResult<Vec<DerivedAccount>>,
{
let (wallet, args) = match self {
Self::New { args } => {
let wallet = Wallet::generate(args.words, args.passphrase.as_deref())?;
(wallet, args)
}
Self::Import { mnemonic, args } => {
let expanded = kobe::mnemonic::expand(&mnemonic)?;
let wallet = Wallet::from_mnemonic(&expanded, args.passphrase.as_deref())?;
(wallet, args)
}
};
let accounts = derive_fn(&wallet, args.count)?;
let out = HdWalletOutput::simple(chain, &wallet, &accounts);
output::render_hd_wallet(&out, json, args.qr)?;
Ok(())
}
}