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 },
84}
85
86impl EcashCommands {
87 pub async fn handle(self, client: &GatewayApi, base_url: &SafeUrl) -> CliOutputResult {
88 match self {
89 Self::Backup { federation_id } => {
90 backup(client, base_url, BackupPayload { federation_id }).await?;
91 Ok(CliOutput::Empty)
92 }
93 Self::Pegin { federation_id } => {
94 let address =
95 get_deposit_address(client, base_url, DepositAddressPayload { federation_id })
96 .await?;
97
98 Ok(CliOutput::DepositAddress { address })
99 }
100 Self::PeginRecheck {
101 address,
102 federation_id,
103 } => {
104 let response = recheck_address(
105 client,
106 base_url,
107 DepositAddressRecheckPayload {
108 address,
109 federation_id,
110 },
111 )
112 .await?;
113 Ok(CliOutput::DepositRecheck(response))
114 }
115 Self::PeginFromOnchain {
116 federation_id,
117 amount,
118 fee_rate_sats_per_vbyte,
119 } => {
120 let txid = pegin_from_onchain(
121 client,
122 base_url,
123 PeginFromOnchainPayload {
124 federation_id,
125 amount,
126 fee_rate_sats_per_vbyte,
127 },
128 )
129 .await?;
130
131 Ok(CliOutput::PeginTxid { txid })
132 }
133 Self::Pegout {
134 federation_id,
135 amount,
136 address,
137 } => {
138 let response = withdraw(
139 client,
140 base_url,
141 WithdrawPayload {
142 federation_id,
143 amount,
144 address,
145 quoted_fees: None,
146 },
147 )
148 .await?;
149
150 Ok(CliOutput::Withdraw(response))
151 }
152 Self::PegoutToOnchain {
153 federation_id,
154 amount,
155 } => {
156 let response = withdraw_to_onchain(
157 client,
158 base_url,
159 WithdrawToOnchainPayload {
160 federation_id,
161 amount,
162 },
163 )
164 .await?;
165
166 Ok(CliOutput::Withdraw(response))
167 }
168 Self::Send {
169 federation_id,
170 amount,
171 } => {
172 let response = spend_ecash(
173 client,
174 base_url,
175 SpendEcashPayload {
176 federation_id,
177 amount,
178 },
179 )
180 .await?;
181
182 Ok(CliOutput::SpendEcash(response))
183 }
184 Self::Receive { notes } => {
185 let response =
186 receive_ecash(client, base_url, ReceiveEcashPayload { notes }).await?;
187 Ok(CliOutput::ReceiveEcash(response))
188 }
189 }
190 }
191}