1use bitcoin::Address;
2use bitcoin::address::NetworkUnchecked;
3use clap::Subcommand;
4use fedimint_core::config::FederationId;
5use fedimint_core::util::SafeUrl;
6use fedimint_core::{Amount, BitcoinAmountOrAll};
7use fedimint_gateway_client::{
8 backup, get_deposit_address, pegin_from_onchain, receive_ecash, recheck_address, spend_ecash,
9 withdraw, withdraw_to_onchain,
10};
11use fedimint_gateway_common::{
12 BackupPayload, DepositAddressPayload, DepositAddressRecheckPayload, PeginFromOnchainPayload,
13 ReceiveEcashPayload, SpendEcashPayload, WithdrawPayload, WithdrawToOnchainPayload,
14};
15use fedimint_ln_common::client::GatewayApi;
16
17use crate::{CliOutput, CliOutputResult};
18
19#[derive(Subcommand)]
22pub enum EcashCommands {
23 Backup {
25 #[clap(long)]
26 federation_id: FederationId,
27 },
28 Pegin {
31 #[clap(long)]
32 federation_id: FederationId,
33 },
34 PeginRecheck {
36 #[clap(long)]
37 address: bitcoin::Address<NetworkUnchecked>,
38 #[clap(long)]
39 federation_id: FederationId,
40 },
41 PeginFromOnchain {
44 #[clap(long)]
45 federation_id: FederationId,
46 #[clap(long)]
48 amount: BitcoinAmountOrAll,
49 #[clap(long)]
51 fee_rate_sats_per_vbyte: u64,
52 },
53 Pegout {
55 #[clap(long)]
56 federation_id: FederationId,
57 #[clap(long)]
59 amount: BitcoinAmountOrAll,
60 #[clap(long)]
62 address: Address<NetworkUnchecked>,
63 },
64 PegoutToOnchain {
66 #[clap(long)]
67 federation_id: FederationId,
68 #[clap(long)]
70 amount: BitcoinAmountOrAll,
71 },
72 Send {
74 #[clap(long)]
75 federation_id: FederationId,
76 amount: Amount,
77 },
78 Receive {
80 #[clap(long)]
82 notes: String,
83 #[arg(long = "no-wait", action = clap::ArgAction::SetFalse)]
84 wait: bool,
85 },
86}
87
88impl EcashCommands {
89 pub async fn handle(self, client: &GatewayApi, base_url: &SafeUrl) -> CliOutputResult {
90 match self {
91 Self::Backup { federation_id } => {
92 backup(client, base_url, BackupPayload { federation_id }).await?;
93 Ok(CliOutput::Empty)
94 }
95 Self::Pegin { federation_id } => {
96 let address =
97 get_deposit_address(client, base_url, DepositAddressPayload { federation_id })
98 .await?;
99
100 Ok(CliOutput::DepositAddress { address })
101 }
102 Self::PeginRecheck {
103 address,
104 federation_id,
105 } => {
106 let response = recheck_address(
107 client,
108 base_url,
109 DepositAddressRecheckPayload {
110 address,
111 federation_id,
112 },
113 )
114 .await?;
115 Ok(CliOutput::DepositRecheck(response))
116 }
117 Self::PeginFromOnchain {
118 federation_id,
119 amount,
120 fee_rate_sats_per_vbyte,
121 } => {
122 let txid = pegin_from_onchain(
123 client,
124 base_url,
125 PeginFromOnchainPayload {
126 federation_id,
127 amount,
128 fee_rate_sats_per_vbyte,
129 },
130 )
131 .await?;
132
133 Ok(CliOutput::PeginTxid { txid })
134 }
135 Self::Pegout {
136 federation_id,
137 amount,
138 address,
139 } => {
140 let response = withdraw(
141 client,
142 base_url,
143 WithdrawPayload {
144 federation_id,
145 amount,
146 address,
147 quoted_fees: None,
148 },
149 )
150 .await?;
151
152 Ok(CliOutput::Withdraw(response))
153 }
154 Self::PegoutToOnchain {
155 federation_id,
156 amount,
157 } => {
158 let response = withdraw_to_onchain(
159 client,
160 base_url,
161 WithdrawToOnchainPayload {
162 federation_id,
163 amount,
164 },
165 )
166 .await?;
167
168 Ok(CliOutput::Withdraw(response))
169 }
170 Self::Send {
171 federation_id,
172 amount,
173 } => {
174 let response = spend_ecash(
175 client,
176 base_url,
177 SpendEcashPayload {
178 federation_id,
179 amount,
180 },
181 )
182 .await?;
183
184 Ok(CliOutput::SpendEcash(response))
185 }
186 Self::Receive { notes, wait } => {
187 let response =
188 receive_ecash(client, base_url, ReceiveEcashPayload { notes, wait }).await?;
189 Ok(CliOutput::ReceiveEcash(response))
190 }
191 }
192 }
193}