Skip to main content

fedimint_mintv2_client/
cli.rs

1use std::{ffi, iter};
2
3use clap::Parser;
4use fedimint_core::Amount;
5use fedimint_core::base32::{self, FEDIMINT_PREFIX};
6use serde::Serialize;
7use serde_json::Value;
8
9use crate::MintClientModule;
10
11#[derive(Parser, Serialize)]
12enum Opts {
13    /// Count the `ECash` notes in the client's database by denomination.
14    Count,
15    /// Send `ECash` for the given amount.
16    Send {
17        amount: Amount,
18        /// Embed the federation's invite code in the serialized ecash so a
19        /// recipient that hasn't joined the federation can do so from it.
20        #[clap(long)]
21        include_invite: bool,
22    },
23    /// Receive the `ECash` by reissuing the notes and return the amount.
24    Receive { ecash: String },
25}
26
27pub(crate) async fn handle_cli_command(
28    mint: &MintClientModule,
29    args: &[ffi::OsString],
30) -> anyhow::Result<Value> {
31    let opts = Opts::parse_from(iter::once(&ffi::OsString::from("mintv2")).chain(args.iter()));
32
33    match opts {
34        Opts::Count => Ok(json(mint.get_count_by_denomination().await)),
35        Opts::Send {
36            amount,
37            include_invite,
38        } => {
39            let (_, ecash) = mint.send(amount, Value::Null, include_invite).await?;
40            let ecash = base32::encode_prefixed(FEDIMINT_PREFIX, &ecash);
41
42            Ok(json(ecash))
43        }
44        Opts::Receive { ecash } => {
45            let ecash = base32::decode_prefixed(FEDIMINT_PREFIX, &ecash)?;
46
47            let operation_id = mint.receive(ecash, Value::Null).await?;
48
49            let state = mint
50                .await_final_receive_operation_state(operation_id)
51                .await?;
52
53            Ok(json(state))
54        }
55    }
56}
57
58fn json<T: Serialize>(value: T) -> Value {
59    serde_json::to_value(value).expect("JSON serialization failed")
60}