use clap::{Args, Subcommand, ValueEnum};
use kobe::spark::{Deriver, Network};
use kobe::{DeriveExt, DerivedAccount, Wallet};
use crate::commands::simple::SimpleArgs;
use crate::output::{self, AccountOutput, HdWalletOutput};
#[derive(Args, Debug)]
pub(crate) struct SparkCommand {
#[command(subcommand)]
command: SparkSubcommand,
}
#[derive(Subcommand, Debug)]
enum SparkSubcommand {
New {
#[command(flatten)]
args: SparkArgs,
},
Import {
#[arg(short, long)]
mnemonic: String,
#[command(flatten)]
args: SparkArgs,
},
}
#[derive(Debug, Clone, Copy, Default, ValueEnum)]
enum CliNetwork {
#[default]
Mainnet,
Testnet,
Signet,
Regtest,
Local,
}
impl From<CliNetwork> for Network {
fn from(value: CliNetwork) -> Self {
match value {
CliNetwork::Mainnet => Self::Mainnet,
CliNetwork::Testnet => Self::Testnet,
CliNetwork::Signet => Self::Signet,
CliNetwork::Regtest => Self::Regtest,
CliNetwork::Local => Self::Local,
}
}
}
#[derive(Args, Debug, Clone)]
struct SparkArgs {
#[arg(short, long, value_enum, default_value_t = CliNetwork::Mainnet)]
network: CliNetwork,
#[command(flatten)]
common: SimpleArgs,
}
impl SparkCommand {
pub(crate) fn execute(self, json: bool) -> Result<(), Box<dyn std::error::Error>> {
let (mnemonic, args) = match self.command {
SparkSubcommand::New { args } => (None, args),
SparkSubcommand::Import { mnemonic, args } => (Some(mnemonic), args),
};
let wallet = args.common.build_wallet(mnemonic.as_deref())?;
let network = Network::from(args.network);
let deriver = Deriver::with_network(&wallet, network);
let accounts = deriver.derive_many(0, args.common.count)?;
let out = build_hd(&wallet, network, &accounts);
output::render_hd_wallet(&out, json, args.common.qr)?;
Ok(())
}
}
fn build_hd(wallet: &Wallet, network: Network, accounts: &[DerivedAccount]) -> HdWalletOutput {
HdWalletOutput {
chain: "spark",
network: Some(network.name()),
address_type: None,
mnemonic: wallet.mnemonic().to_owned(),
passphrase_protected: wallet.has_passphrase(),
derivation_style: None,
accounts: accounts
.iter()
.enumerate()
.map(|(i, a)| AccountOutput::from_derived(i, a))
.collect(),
}
}