gateway_cli/
ecash_commands.rs

1use bitcoin::Address;
2use bitcoin::address::NetworkUnchecked;
3use clap::Subcommand;
4use fedimint_core::config::FederationId;
5use fedimint_core::{Amount, BitcoinAmountOrAll};
6use fedimint_gateway_client::GatewayRpcClient;
7use fedimint_gateway_common::{
8    BackupPayload, DepositAddressPayload, DepositAddressRecheckPayload, ReceiveEcashPayload,
9    SpendEcashPayload, WithdrawPayload,
10};
11use fedimint_mint_client::OOBNotes;
12
13use crate::print_response;
14
15#[derive(Subcommand)]
16pub enum EcashCommands {
17    /// Make a backup of snapshot of all e-cash.
18    Backup {
19        #[clap(long)]
20        federation_id: FederationId,
21    },
22    /// Generate a new peg-in address to a federation that the gateway can claim
23    /// e-cash for later.
24    Pegin {
25        #[clap(long)]
26        federation_id: FederationId,
27    },
28    /// Trigger a recheck for deposits on a deposit address
29    PeginRecheck {
30        #[clap(long)]
31        address: bitcoin::Address<NetworkUnchecked>,
32        #[clap(long)]
33        federation_id: FederationId,
34    },
35    /// Claim funds from a gateway federation to an on-chain address.
36    Pegout {
37        #[clap(long)]
38        federation_id: FederationId,
39        /// The amount to withdraw
40        #[clap(long)]
41        amount: BitcoinAmountOrAll,
42        /// The address to send the funds to
43        #[clap(long)]
44        address: Address<NetworkUnchecked>,
45    },
46    /// Send e-cash out of band
47    Send {
48        #[clap(long)]
49        federation_id: FederationId,
50        amount: Amount,
51        #[clap(long)]
52        allow_overpay: bool,
53        #[clap(long, default_value_t = 60 * 60 * 24 * 7)]
54        timeout: u64,
55        #[clap(long)]
56        include_invite: bool,
57    },
58    /// Receive e-cash out of band
59    Receive {
60        #[clap(long)]
61        notes: OOBNotes,
62        #[arg(long = "no-wait", action = clap::ArgAction::SetFalse)]
63        wait: bool,
64    },
65}
66
67impl EcashCommands {
68    pub async fn handle(
69        self,
70        create_client: impl Fn() -> GatewayRpcClient + Send + Sync,
71    ) -> anyhow::Result<()> {
72        match self {
73            Self::Backup { federation_id } => {
74                create_client()
75                    .backup(BackupPayload { federation_id })
76                    .await?;
77            }
78            Self::Pegin { federation_id } => {
79                let response = create_client()
80                    .get_deposit_address(DepositAddressPayload { federation_id })
81                    .await?;
82
83                print_response(response);
84            }
85            Self::PeginRecheck {
86                address,
87                federation_id,
88            } => {
89                let response = create_client()
90                    .recheck_address(DepositAddressRecheckPayload {
91                        address,
92                        federation_id,
93                    })
94                    .await?;
95                print_response(response);
96            }
97            Self::Pegout {
98                federation_id,
99                amount,
100                address,
101            } => {
102                let response = create_client()
103                    .withdraw(WithdrawPayload {
104                        federation_id,
105                        amount,
106                        address,
107                    })
108                    .await?;
109
110                print_response(response);
111            }
112            Self::Send {
113                federation_id,
114                amount,
115                allow_overpay,
116                timeout,
117                include_invite,
118            } => {
119                let response = create_client()
120                    .spend_ecash(SpendEcashPayload {
121                        federation_id,
122                        amount,
123                        allow_overpay,
124                        timeout,
125                        include_invite,
126                    })
127                    .await?;
128
129                print_response(response);
130            }
131            Self::Receive { notes, wait } => {
132                let response = create_client()
133                    .receive_ecash(ReceiveEcashPayload { notes, wait })
134                    .await?;
135                print_response(response);
136            }
137        }
138
139        Ok(())
140    }
141}