gateway_cli/
lightning_commands.rs
1use bitcoin::hashes::sha256;
2use chrono::{DateTime, Utc};
3use clap::Subcommand;
4use fedimint_core::Amount;
5use fedimint_gateway_client::GatewayRpcClient;
6use fedimint_gateway_common::{
7 CloseChannelsWithPeerRequest, CreateInvoiceForOperatorPayload, CreateOfferPayload,
8 GetInvoiceRequest, ListTransactionsPayload, OpenChannelRequest, PayInvoiceForOperatorPayload,
9 PayOfferPayload,
10};
11use lightning_invoice::Bolt11Invoice;
12
13use crate::print_response;
14
15#[derive(Subcommand)]
19pub enum LightningCommands {
20 CreateInvoice {
22 amount_msats: u64,
23
24 #[clap(long)]
25 expiry_secs: Option<u32>,
26
27 #[clap(long)]
28 description: Option<String>,
29 },
30 PayInvoice { invoice: Bolt11Invoice },
32 OpenChannel {
34 #[clap(long)]
36 pubkey: bitcoin::secp256k1::PublicKey,
37
38 #[clap(long)]
39 host: String,
40
41 #[clap(long)]
43 channel_size_sats: u64,
44
45 #[clap(long)]
47 push_amount_sats: Option<u64>,
48 },
49 CloseChannelsWithPeer {
52 #[clap(long)]
54 pubkey: bitcoin::secp256k1::PublicKey,
55 },
56 ListActiveChannels,
58 ListTransactions {
61 #[arg(long, value_parser = parse_datetime)]
64 start_time: DateTime<Utc>,
65
66 #[arg(long, value_parser = parse_datetime)]
69 end_time: DateTime<Utc>,
70 },
71 GetInvoice {
73 #[clap(long)]
75 payment_hash: sha256::Hash,
76 },
77 CreateOffer {
78 #[clap(long)]
79 amount_msat: Option<u64>,
80
81 #[clap(long)]
82 description: Option<String>,
83
84 #[clap(long)]
85 expiry_secs: Option<u32>,
86
87 #[clap(long)]
88 quantity: Option<u64>,
89 },
90 PayOffer {
91 #[clap(long)]
92 offer: String,
93
94 #[clap(long)]
95 amount_msat: Option<u64>,
96
97 #[clap(long)]
98 quantity: Option<u64>,
99
100 #[clap(long)]
101 payer_note: Option<String>,
102 },
103}
104
105fn parse_datetime(s: &str) -> Result<DateTime<Utc>, chrono::ParseError> {
106 s.parse::<DateTime<Utc>>()
107}
108
109impl LightningCommands {
110 #![allow(clippy::too_many_lines)]
111 pub async fn handle(
112 self,
113 create_client: impl Fn() -> GatewayRpcClient + Send + Sync,
114 ) -> anyhow::Result<()> {
115 match self {
116 Self::CreateInvoice {
117 amount_msats,
118 expiry_secs,
119 description,
120 } => {
121 let response = create_client()
122 .create_invoice_for_self(CreateInvoiceForOperatorPayload {
123 amount_msats,
124 expiry_secs,
125 description,
126 })
127 .await?;
128 println!("{response}");
129 }
130 Self::PayInvoice { invoice } => {
131 let response = create_client()
132 .pay_invoice(PayInvoiceForOperatorPayload { invoice })
133 .await?;
134 println!("{response}");
135 }
136 Self::OpenChannel {
137 pubkey,
138 host,
139 channel_size_sats,
140 push_amount_sats,
141 } => {
142 let funding_txid = create_client()
143 .open_channel(OpenChannelRequest {
144 pubkey,
145 host,
146 channel_size_sats,
147 push_amount_sats: push_amount_sats.unwrap_or(0),
148 })
149 .await?;
150 println!("{funding_txid}");
151 }
152 Self::CloseChannelsWithPeer { pubkey } => {
153 let response = create_client()
154 .close_channels_with_peer(CloseChannelsWithPeerRequest { pubkey })
155 .await?;
156 print_response(response);
157 }
158 Self::ListActiveChannels => {
159 let response = create_client().list_active_channels().await?;
160 print_response(response);
161 }
162 Self::GetInvoice { payment_hash } => {
163 let response = create_client()
164 .get_invoice(GetInvoiceRequest { payment_hash })
165 .await?;
166 print_response(response);
167 }
168 Self::ListTransactions {
169 start_time,
170 end_time,
171 } => {
172 let start_secs = start_time.timestamp().try_into()?;
173 let end_secs = end_time.timestamp().try_into()?;
174 let response = create_client()
175 .list_transactions(ListTransactionsPayload {
176 start_secs,
177 end_secs,
178 })
179 .await?;
180 print_response(response);
181 }
182 Self::CreateOffer {
183 amount_msat,
184 description,
185 expiry_secs,
186 quantity,
187 } => {
188 let response = create_client()
189 .create_offer(CreateOfferPayload {
190 amount: amount_msat.map(Amount::from_msats),
191 description,
192 expiry_secs,
193 quantity,
194 })
195 .await?;
196 print_response(response);
197 }
198 Self::PayOffer {
199 offer,
200 amount_msat,
201 quantity,
202 payer_note,
203 } => {
204 let response = create_client()
205 .pay_offer(PayOfferPayload {
206 offer,
207 amount: amount_msat.map(Amount::from_msats),
208 quantity,
209 payer_note,
210 })
211 .await?;
212 print_response(response);
213 }
214 };
215
216 Ok(())
217 }
218}