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
40                .send(amount, Value::Null, include_invite)
41                .await
42                .map(|ecash| base32::encode_prefixed(FEDIMINT_PREFIX, &ecash))?;
43
44            Ok(json(ecash))
45        }
46        Opts::Receive { ecash } => {
47            let ecash = base32::decode_prefixed(FEDIMINT_PREFIX, &ecash)?;
48
49            let operation_id = mint.receive(ecash, Value::Null).await?;
50
51            let state = mint
52                .await_final_receive_operation_state(operation_id)
53                .await?;
54
55            Ok(json(state))
56        }
57    }
58}
59
60fn json<T: Serialize>(value: T) -> Value {
61    serde_json::to_value(value).expect("JSON serialization failed")
62}