Skip to main content

fedimint_walletv2_client/
cli.rs

1use std::{ffi, iter};
2
3use bitcoin::Address;
4use bitcoin::address::NetworkUnchecked;
5use clap::{Parser, Subcommand};
6use serde::Serialize;
7use serde_json::Value;
8
9use crate::WalletClientModule;
10
11#[derive(Parser, Serialize)]
12enum Opts {
13    /// Subcommands for operator to retrieve information about the wallet state.
14    #[command(subcommand)]
15    Info(InfoOpts),
16    /// Fetch the current fee required to send an on-chain payment.
17    SendFee,
18    /// Send an on-chain payment.
19    Send {
20        address: Address<NetworkUnchecked>,
21        amount: bitcoin::Amount,
22        #[arg(long)]
23        fee: Option<bitcoin::Amount>,
24    },
25    /// Return the next unused deposit address.
26    Receive,
27}
28
29#[derive(Clone, Subcommand, Serialize)]
30enum InfoOpts {
31    /// Fetch the total value of bitcoin controlled by the federation.
32    TotalValue,
33    /// Fetch the consensus block count of the federation.
34    BlockCount,
35    /// Fetch the current consensus feerate.
36    Feerate,
37    /// Display the chain of pending bitcoin transactions.
38    PendingTxChain,
39    /// Display the chain of bitcoin transactions.
40    TxChain { n: usize },
41}
42
43pub(crate) async fn handle_cli_command(
44    wallet: &WalletClientModule,
45    args: &[ffi::OsString],
46) -> anyhow::Result<Value> {
47    let opts = Opts::parse_from(iter::once(&ffi::OsString::from("walletv2")).chain(args.iter()));
48
49    let value = match opts {
50        Opts::Info(subcommand) => match subcommand {
51            InfoOpts::TotalValue => json(wallet.total_value().await?),
52            InfoOpts::BlockCount => json(wallet.block_count().await?),
53            InfoOpts::Feerate => json(wallet.feerate().await?),
54            InfoOpts::PendingTxChain => json(wallet.pending_tx_chain().await?),
55            InfoOpts::TxChain { n } => json(wallet.tx_chain(n).await?),
56        },
57        Opts::SendFee => json(wallet.send_fee().await?),
58        Opts::Send {
59            address,
60            amount,
61            fee,
62        } => json(
63            wallet
64                .await_final_send_operation_state(wallet.send(address, amount, fee).await?)
65                .await,
66        ),
67        Opts::Receive => json(wallet.receive().await),
68    };
69
70    Ok(value)
71}
72
73fn json<T: Serialize>(value: T) -> Value {
74    serde_json::to_value(value).expect("JSON serialization failed")
75}