gateway_cli/
lightning_commands.rs1use 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 #[clap(long)]
57 force: bool,
58 },
59 ListChannels,
61 ListTransactions {
64 #[arg(long, value_parser = parse_datetime)]
67 start_time: DateTime<Utc>,
68
69 #[arg(long, value_parser = parse_datetime)]
72 end_time: DateTime<Utc>,
73 },
74 GetInvoice {
76 #[clap(long)]
78 payment_hash: sha256::Hash,
79 },
80 CreateOffer {
81 #[clap(long)]
82 amount_msat: Option<u64>,
83
84 #[clap(long)]
85 description: Option<String>,
86
87 #[clap(long)]
88 expiry_secs: Option<u32>,
89
90 #[clap(long)]
91 quantity: Option<u64>,
92 },
93 PayOffer {
94 #[clap(long)]
95 offer: String,
96
97 #[clap(long)]
98 amount_msat: Option<u64>,
99
100 #[clap(long)]
101 quantity: Option<u64>,
102
103 #[clap(long)]
104 payer_note: Option<String>,
105 },
106}
107
108fn parse_datetime(s: &str) -> Result<DateTime<Utc>, chrono::ParseError> {
109 s.parse::<DateTime<Utc>>()
110}
111
112impl LightningCommands {
113 #![allow(clippy::too_many_lines)]
114 pub async fn handle(
115 self,
116 create_client: impl Fn() -> GatewayRpcClient + Send + Sync,
117 ) -> anyhow::Result<()> {
118 match self {
119 Self::CreateInvoice {
120 amount_msats,
121 expiry_secs,
122 description,
123 } => {
124 let response = create_client()
125 .create_invoice_for_self(CreateInvoiceForOperatorPayload {
126 amount_msats,
127 expiry_secs,
128 description,
129 })
130 .await?;
131 println!("{response}");
132 }
133 Self::PayInvoice { invoice } => {
134 let response = create_client()
135 .pay_invoice(PayInvoiceForOperatorPayload { invoice })
136 .await?;
137 println!("{response}");
138 }
139 Self::OpenChannel {
140 pubkey,
141 host,
142 channel_size_sats,
143 push_amount_sats,
144 } => {
145 let funding_txid = create_client()
146 .open_channel(OpenChannelRequest {
147 pubkey,
148 host,
149 channel_size_sats,
150 push_amount_sats: push_amount_sats.unwrap_or(0),
151 })
152 .await?;
153 println!("{funding_txid}");
154 }
155 Self::CloseChannelsWithPeer { pubkey, force } => {
156 let response = create_client()
157 .close_channels_with_peer(CloseChannelsWithPeerRequest { pubkey, force })
158 .await?;
159 print_response(response);
160 }
161 Self::ListChannels => {
162 let response = create_client().list_channels().await?;
163 print_response(response);
164 }
165 Self::GetInvoice { payment_hash } => {
166 let response = create_client()
167 .get_invoice(GetInvoiceRequest { payment_hash })
168 .await?;
169 print_response(response);
170 }
171 Self::ListTransactions {
172 start_time,
173 end_time,
174 } => {
175 let start_secs = start_time.timestamp().try_into()?;
176 let end_secs = end_time.timestamp().try_into()?;
177 let response = create_client()
178 .list_transactions(ListTransactionsPayload {
179 start_secs,
180 end_secs,
181 })
182 .await?;
183 print_response(response);
184 }
185 Self::CreateOffer {
186 amount_msat,
187 description,
188 expiry_secs,
189 quantity,
190 } => {
191 let response = create_client()
192 .create_offer(CreateOfferPayload {
193 amount: amount_msat.map(Amount::from_msats),
194 description,
195 expiry_secs,
196 quantity,
197 })
198 .await?;
199 print_response(response);
200 }
201 Self::PayOffer {
202 offer,
203 amount_msat,
204 quantity,
205 payer_note,
206 } => {
207 let response = create_client()
208 .pay_offer(PayOfferPayload {
209 offer,
210 amount: amount_msat.map(Amount::from_msats),
211 quantity,
212 payer_note,
213 })
214 .await?;
215 print_response(response);
216 }
217 }
218
219 Ok(())
220 }
221}