1use std::collections::HashMap;
2use std::sync::Arc;
3
4use anyhow::anyhow;
5use axum::extract::{Path, Query, Request};
6use axum::http::{StatusCode, header};
7use axum::middleware::{self, Next};
8use axum::response::IntoResponse;
9use axum::routing::{get, post};
10use axum::{Extension, Json, Router};
11use bitcoin::hashes::sha256;
12use fedimint_core::config::FederationId;
13use fedimint_core::task::TaskGroup;
14use fedimint_core::util::FmtCompact;
15use fedimint_gateway_common::{
16 ADDRESS_ENDPOINT, ADDRESS_RECHECK_ENDPOINT, BACKUP_ENDPOINT, BackupPayload,
17 CLOSE_CHANNELS_WITH_PEER_ENDPOINT, CONFIGURATION_ENDPOINT, CONNECT_FED_ENDPOINT,
18 CREATE_BOLT11_INVOICE_FOR_OPERATOR_ENDPOINT, CREATE_BOLT12_OFFER_FOR_OPERATOR_ENDPOINT,
19 CloseChannelsWithPeerRequest, ConfigPayload, ConnectFedPayload,
20 CreateInvoiceForOperatorPayload, CreateOfferPayload, DepositAddressPayload,
21 DepositAddressRecheckPayload, GATEWAY_INFO_ENDPOINT, GET_BALANCES_ENDPOINT,
22 GET_INVOICE_ENDPOINT, GET_LN_ONCHAIN_ADDRESS_ENDPOINT, GetInvoiceRequest,
23 INVITE_CODES_ENDPOINT, LEAVE_FED_ENDPOINT, LIST_CHANNELS_ENDPOINT, LIST_TRANSACTIONS_ENDPOINT,
24 LeaveFedPayload, ListTransactionsPayload, MNEMONIC_ENDPOINT, OPEN_CHANNEL_ENDPOINT,
25 OPEN_CHANNEL_WITH_PUSH_ENDPOINT, OpenChannelRequest, PAY_INVOICE_FOR_OPERATOR_ENDPOINT,
26 PAY_OFFER_FOR_OPERATOR_ENDPOINT, PAYMENT_LOG_ENDPOINT, PAYMENT_SUMMARY_ENDPOINT,
27 PEGIN_FROM_ONCHAIN_ENDPOINT, PayInvoiceForOperatorPayload, PayOfferPayload, PaymentLogPayload,
28 PaymentSummaryPayload, PeginFromOnchainPayload, RECEIVE_ECASH_ENDPOINT, ReceiveEcashPayload,
29 SEND_ONCHAIN_ENDPOINT, SET_CHANNEL_FEES_ENDPOINT, SET_FEES_ENDPOINT, SPEND_ECASH_ENDPOINT,
30 STOP_ENDPOINT, SendOnchainRequest, SetChannelFeesRequest, SetFeesPayload, SetMnemonicPayload,
31 SpendEcashPayload, V1_API_ENDPOINT, WITHDRAW_ENDPOINT, WITHDRAW_TO_ONCHAIN_ENDPOINT,
32 WithdrawPayload, WithdrawToOnchainPayload,
33};
34use fedimint_gateway_ui::IAdminGateway;
35use fedimint_ln_common::gateway_endpoint_constants::{
36 GET_GATEWAY_ID_ENDPOINT, PAY_INVOICE_ENDPOINT,
37};
38use fedimint_lnurl::LnurlResponse;
39use fedimint_lnv2_common::endpoint_constants::{
40 CREATE_BOLT11_INVOICE_ENDPOINT, ROUTING_INFO_ENDPOINT, SEND_PAYMENT_ENDPOINT,
41};
42use fedimint_lnv2_common::gateway_api::{CreateBolt11InvoicePayload, SendPaymentPayload};
43use fedimint_logging::LOG_GATEWAY;
44use hex::ToHex;
45use serde::de::DeserializeOwned;
46use serde_json::json;
47use tokio::net::TcpListener;
48use tower_http::cors::CorsLayer;
49use tracing::{info, instrument, warn};
50
51use crate::error::{GatewayError, LnurlError};
52use crate::iroh_server::{Handlers, start_iroh_endpoint};
53use crate::{Gateway, GatewayState};
54
55const LIQUIDITY_MANAGER_ROUTES: [&str; 20] = [
58 ADDRESS_ENDPOINT,
59 ADDRESS_RECHECK_ENDPOINT,
60 CLOSE_CHANNELS_WITH_PEER_ENDPOINT,
61 CONFIGURATION_ENDPOINT,
62 CREATE_BOLT11_INVOICE_FOR_OPERATOR_ENDPOINT,
63 CREATE_BOLT12_OFFER_FOR_OPERATOR_ENDPOINT,
64 GATEWAY_INFO_ENDPOINT,
65 GET_BALANCES_ENDPOINT,
66 GET_INVOICE_ENDPOINT,
67 GET_LN_ONCHAIN_ADDRESS_ENDPOINT,
68 INVITE_CODES_ENDPOINT,
69 LIST_CHANNELS_ENDPOINT,
70 LIST_TRANSACTIONS_ENDPOINT,
71 OPEN_CHANNEL_ENDPOINT,
72 PAYMENT_LOG_ENDPOINT,
73 PAYMENT_SUMMARY_ENDPOINT,
74 PEGIN_FROM_ONCHAIN_ENDPOINT,
75 SET_CHANNEL_FEES_ENDPOINT,
76 SET_FEES_ENDPOINT,
77 WITHDRAW_TO_ONCHAIN_ENDPOINT,
78];
79
80pub async fn run_webserver(
82 gateway: Arc<Gateway>,
83 mut mnemonic_receiver: tokio::sync::broadcast::Receiver<()>,
84) -> anyhow::Result<()> {
85 let task_group = gateway.task_group.clone();
86 let mut handlers = Handlers::new();
87
88 let routes = routes(gateway.clone(), task_group.clone(), &mut handlers);
89 let ui_routes = fedimint_gateway_ui::router(gateway.clone());
90 let api_v1 = Router::new()
91 .nest(&format!("/{V1_API_ENDPOINT}"), routes.clone())
92 .merge(routes)
94 .merge(ui_routes);
95
96 let handle = task_group.make_handle();
97 let shutdown_rx = handle.make_shutdown_rx();
98 let listener = TcpListener::bind(&gateway.listen).await?;
99 let serve = axum::serve(listener, api_v1.into_make_service());
100 task_group.spawn("Gateway Webserver", |_| async {
101 let graceful = serve.with_graceful_shutdown(async {
102 shutdown_rx.await;
103 });
104
105 match graceful.await {
106 Err(err) => {
107 warn!(target: LOG_GATEWAY, err = %err.fmt_compact(), "Error shutting down gatewayd webserver");
108 }
109 _ => {
110 info!(target: LOG_GATEWAY, "Successfully shutdown webserver");
111 }
112 }
113 });
114 info!(target: LOG_GATEWAY, listen = %gateway.listen, "Successfully started webserver");
115
116 if let GatewayState::NotConfigured { .. } = gateway.get_state().await {
119 info!(target: LOG_GATEWAY, "Waiting for the mnemonic to be set before starting iroh loop.");
120 let _ = mnemonic_receiver.recv().await;
121 }
122
123 start_iroh_endpoint(&gateway, task_group, Arc::new(handlers)).await?;
124
125 Ok(())
126}
127
128fn extract_bearer_token(request: &Request) -> Result<String, StatusCode> {
130 let headers = request.headers();
131 let auth_header = headers.get(header::AUTHORIZATION);
132 if let Some(header_value) = auth_header {
133 let auth_str = header_value
134 .to_str()
135 .map_err(|_| StatusCode::UNAUTHORIZED)?;
136 let token = auth_str.trim_start_matches("Bearer ").to_string();
137 return Ok(token);
138 }
139
140 Err(StatusCode::UNAUTHORIZED)
141}
142
143async fn not_configured_middleware(
144 Extension(gateway): Extension<Arc<Gateway>>,
145 request: Request,
146 next: Next,
147) -> Result<impl IntoResponse, StatusCode> {
148 if matches!(
149 gateway.get_state().await,
150 GatewayState::NotConfigured { .. }
151 ) {
152 let method = request.method().clone();
153 let path = request.uri().path();
154
155 let is_mnemonic_api = method == axum::http::Method::POST
157 && (path == MNEMONIC_ENDPOINT
158 || path == format!("/{V1_API_ENDPOINT}/{MNEMONIC_ENDPOINT}"));
159
160 let is_setup_route = fedimint_gateway_ui::is_allowed_setup_route(path);
161
162 if !is_mnemonic_api && !is_setup_route {
163 return Err(StatusCode::NOT_FOUND);
164 }
165 }
166
167 Ok(next.run(request).await)
168}
169
170async fn auth_middleware(
174 Extension(gateway): Extension<Arc<Gateway>>,
175 request: Request,
176 next: Next,
177) -> Result<impl IntoResponse, StatusCode> {
178 let token = extract_bearer_token(&request)?;
179 if bcrypt::verify(token.clone(), &gateway.bcrypt_password_hash)
180 .expect("Bcrypt hash is valid since we just stringified it")
181 {
182 return Ok(next.run(request).await);
183 }
184
185 if let Some(liquidity_manager_password_hash) = &gateway.bcrypt_liquidity_manager_password_hash
187 && bcrypt::verify(token, liquidity_manager_password_hash)
188 .expect("Bcrypt hash is valid since we just stringified it")
189 {
190 let path = request.uri().path().to_string();
191
192 if !LIQUIDITY_MANAGER_ROUTES.contains(&path.as_str()) {
193 return Err(StatusCode::UNAUTHORIZED);
194 }
195
196 return Ok(next.run(request).await);
197 }
198
199 Err(StatusCode::UNAUTHORIZED)
200}
201
202fn register_get_handler<F, Fut>(
205 handlers: &mut Handlers,
206 route: &str,
207 func: F,
208 is_authenticated: bool,
209 router: Router,
210) -> Router
211where
212 F: Fn(Extension<Arc<Gateway>>) -> Fut + Clone + Send + Sync + 'static,
213 Fut: Future<Output = Result<Json<serde_json::Value>, GatewayError>> + Send + 'static,
214{
215 handlers.add_handler(route, func.clone(), is_authenticated);
216 router.route(route, get(func))
217}
218
219fn register_post_handler<P, F, Fut>(
222 handlers: &mut Handlers,
223 route: &str,
224 func: F,
225 is_authenticated: bool,
226 router: Router,
227) -> Router
228where
229 P: DeserializeOwned + Send + 'static,
230 F: Fn(Extension<Arc<Gateway>>, Json<P>) -> Fut + Clone + Send + Sync + 'static,
231 Fut: Future<Output = Result<Json<serde_json::Value>, GatewayError>> + Send + 'static,
232{
233 handlers.add_handler_with_payload(route, func.clone(), is_authenticated);
234 router.route(route, post(func))
235}
236
237fn lnv1_routes(handlers: &mut Handlers) -> Router {
239 let router = Router::new();
240 let router = register_post_handler(handlers, PAY_INVOICE_ENDPOINT, pay_invoice, false, router);
241 register_get_handler(
242 handlers,
243 GET_GATEWAY_ID_ENDPOINT,
244 get_gateway_id,
245 false,
246 router,
247 )
248}
249
250fn lnv2_routes(handlers: &mut Handlers) -> Router {
252 let router = Router::new();
253 let router = register_post_handler(
254 handlers,
255 ROUTING_INFO_ENDPOINT,
256 routing_info_v2,
257 false,
258 router,
259 );
260 let router = register_post_handler(
261 handlers,
262 SEND_PAYMENT_ENDPOINT,
263 pay_bolt11_invoice_v2,
264 false,
265 router,
266 );
267 let router = register_post_handler(
268 handlers,
269 CREATE_BOLT11_INVOICE_ENDPOINT,
270 create_bolt11_invoice_v2,
271 false,
272 router,
273 );
274 router.route("/verify/{payment_hash}", get(verify_bolt11_preimage_v2_get))
276}
277
278fn routes(gateway: Arc<Gateway>, task_group: TaskGroup, handlers: &mut Handlers) -> Router {
284 let mut public_routes = register_post_handler(
286 handlers,
287 RECEIVE_ECASH_ENDPOINT,
288 receive_ecash,
289 false,
290 Router::new(),
291 );
292 public_routes = public_routes.merge(lnv1_routes(handlers));
293 public_routes = public_routes.merge(lnv2_routes(handlers));
294
295 let is_authenticated = true;
297 let authenticated_routes = Router::new();
298 let authenticated_routes = register_post_handler(
299 handlers,
300 ADDRESS_ENDPOINT,
301 address,
302 is_authenticated,
303 authenticated_routes,
304 );
305 let authenticated_routes = register_post_handler(
306 handlers,
307 WITHDRAW_ENDPOINT,
308 withdraw,
309 is_authenticated,
310 authenticated_routes,
311 );
312 let authenticated_routes = register_post_handler(
313 handlers,
314 WITHDRAW_TO_ONCHAIN_ENDPOINT,
315 withdraw_to_onchain,
316 is_authenticated,
317 authenticated_routes,
318 );
319 let authenticated_routes = register_post_handler(
320 handlers,
321 PEGIN_FROM_ONCHAIN_ENDPOINT,
322 pegin_from_onchain,
323 is_authenticated,
324 authenticated_routes,
325 );
326 let authenticated_routes = register_post_handler(
327 handlers,
328 CONNECT_FED_ENDPOINT,
329 connect_fed,
330 is_authenticated,
331 authenticated_routes,
332 );
333 let authenticated_routes = register_post_handler(
334 handlers,
335 LEAVE_FED_ENDPOINT,
336 leave_fed,
337 is_authenticated,
338 authenticated_routes,
339 );
340 let authenticated_routes = register_post_handler(
341 handlers,
342 BACKUP_ENDPOINT,
343 backup,
344 is_authenticated,
345 authenticated_routes,
346 );
347 let authenticated_routes = register_post_handler(
348 handlers,
349 CREATE_BOLT11_INVOICE_FOR_OPERATOR_ENDPOINT,
350 create_invoice_for_operator,
351 is_authenticated,
352 authenticated_routes,
353 );
354 let authenticated_routes = register_post_handler(
355 handlers,
356 CREATE_BOLT12_OFFER_FOR_OPERATOR_ENDPOINT,
357 create_offer_for_operator,
358 is_authenticated,
359 authenticated_routes,
360 );
361 let authenticated_routes = register_post_handler(
362 handlers,
363 PAY_INVOICE_FOR_OPERATOR_ENDPOINT,
364 pay_invoice_operator,
365 is_authenticated,
366 authenticated_routes,
367 );
368 let authenticated_routes = register_post_handler(
369 handlers,
370 PAY_OFFER_FOR_OPERATOR_ENDPOINT,
371 pay_offer_operator,
372 is_authenticated,
373 authenticated_routes,
374 );
375 let authenticated_routes = register_post_handler(
376 handlers,
377 GET_INVOICE_ENDPOINT,
378 get_invoice,
379 is_authenticated,
380 authenticated_routes,
381 );
382 let authenticated_routes = register_get_handler(
383 handlers,
384 GET_LN_ONCHAIN_ADDRESS_ENDPOINT,
385 get_ln_onchain_address,
386 is_authenticated,
387 authenticated_routes,
388 );
389 let authenticated_routes = register_post_handler(
390 handlers,
391 OPEN_CHANNEL_ENDPOINT,
392 open_channel,
393 is_authenticated,
394 authenticated_routes,
395 );
396 let authenticated_routes = register_post_handler(
397 handlers,
398 OPEN_CHANNEL_WITH_PUSH_ENDPOINT,
399 open_channel_with_push,
400 is_authenticated,
401 authenticated_routes,
402 );
403 let authenticated_routes = register_post_handler(
404 handlers,
405 CLOSE_CHANNELS_WITH_PEER_ENDPOINT,
406 close_channels_with_peer,
407 is_authenticated,
408 authenticated_routes,
409 );
410 let authenticated_routes = register_get_handler(
411 handlers,
412 LIST_CHANNELS_ENDPOINT,
413 list_channels,
414 is_authenticated,
415 authenticated_routes,
416 );
417 let authenticated_routes = register_post_handler(
418 handlers,
419 SET_CHANNEL_FEES_ENDPOINT,
420 set_channel_fees,
421 is_authenticated,
422 authenticated_routes,
423 );
424 let authenticated_routes = register_post_handler(
425 handlers,
426 LIST_TRANSACTIONS_ENDPOINT,
427 list_transactions,
428 is_authenticated,
429 authenticated_routes,
430 );
431 let authenticated_routes = register_post_handler(
432 handlers,
433 SEND_ONCHAIN_ENDPOINT,
434 send_onchain,
435 is_authenticated,
436 authenticated_routes,
437 );
438 let authenticated_routes = register_post_handler(
439 handlers,
440 ADDRESS_RECHECK_ENDPOINT,
441 recheck_address,
442 is_authenticated,
443 authenticated_routes,
444 );
445 let authenticated_routes = register_get_handler(
446 handlers,
447 GET_BALANCES_ENDPOINT,
448 get_balances,
449 is_authenticated,
450 authenticated_routes,
451 );
452 let authenticated_routes = register_post_handler(
453 handlers,
454 SPEND_ECASH_ENDPOINT,
455 spend_ecash,
456 is_authenticated,
457 authenticated_routes,
458 );
459 let authenticated_routes = register_get_handler(
460 handlers,
461 MNEMONIC_ENDPOINT,
462 mnemonic,
463 is_authenticated,
464 authenticated_routes,
465 );
466 let authenticated_routes = authenticated_routes.route(STOP_ENDPOINT, get(stop));
468 let authenticated_routes = register_post_handler(
469 handlers,
470 PAYMENT_LOG_ENDPOINT,
471 payment_log,
472 is_authenticated,
473 authenticated_routes,
474 );
475 let authenticated_routes = register_post_handler(
476 handlers,
477 PAYMENT_SUMMARY_ENDPOINT,
478 payment_summary,
479 is_authenticated,
480 authenticated_routes,
481 );
482 let authenticated_routes = register_post_handler(
483 handlers,
484 SET_FEES_ENDPOINT,
485 set_fees,
486 is_authenticated,
487 authenticated_routes,
488 );
489 let authenticated_routes = register_post_handler(
490 handlers,
491 CONFIGURATION_ENDPOINT,
492 configuration,
493 is_authenticated,
494 authenticated_routes,
495 );
496 let authenticated_routes = register_get_handler(
497 handlers,
498 GATEWAY_INFO_ENDPOINT,
499 info,
500 is_authenticated,
501 authenticated_routes,
502 );
503 let authenticated_routes = register_post_handler(
504 handlers,
505 MNEMONIC_ENDPOINT,
506 set_mnemonic,
507 is_authenticated,
508 authenticated_routes,
509 );
510 let authenticated_routes = register_get_handler(
511 handlers,
512 INVITE_CODES_ENDPOINT,
513 invite_codes,
514 is_authenticated,
515 authenticated_routes,
516 );
517 let authenticated_routes = authenticated_routes.layer(middleware::from_fn(auth_middleware));
518
519 Router::new()
520 .merge(public_routes)
521 .merge(authenticated_routes)
522 .layer(middleware::from_fn(not_configured_middleware))
523 .layer(Extension(gateway))
524 .layer(Extension(task_group))
525 .layer(CorsLayer::permissive())
526}
527
528#[instrument(target = LOG_GATEWAY, skip_all, err)]
530async fn info(
531 Extension(gateway): Extension<Arc<Gateway>>,
532) -> Result<Json<serde_json::Value>, GatewayError> {
533 let info = gateway.handle_get_info().await?;
534 Ok(Json(json!(info)))
535}
536
537#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
539async fn configuration(
540 Extension(gateway): Extension<Arc<Gateway>>,
541 Json(payload): Json<ConfigPayload>,
542) -> Result<Json<serde_json::Value>, GatewayError> {
543 let gateway_fed_config = gateway
544 .handle_get_federation_config(payload.federation_id)
545 .await?;
546 Ok(Json(json!(gateway_fed_config)))
547}
548
549#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
551async fn address(
552 Extension(gateway): Extension<Arc<Gateway>>,
553 Json(payload): Json<DepositAddressPayload>,
554) -> Result<Json<serde_json::Value>, GatewayError> {
555 let address = gateway.handle_address_msg(payload).await?;
556 Ok(Json(json!(address)))
557}
558
559#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
561async fn pegin_from_onchain(
562 Extension(gateway): Extension<Arc<Gateway>>,
563 Json(payload): Json<PeginFromOnchainPayload>,
564) -> Result<Json<serde_json::Value>, GatewayError> {
565 let address = gateway.handle_pegin_from_onchain_msg(payload).await?;
566 Ok(Json(json!(address)))
567}
568
569#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
571async fn withdraw(
572 Extension(gateway): Extension<Arc<Gateway>>,
573 Json(payload): Json<WithdrawPayload>,
574) -> Result<Json<serde_json::Value>, GatewayError> {
575 let txid = gateway.handle_withdraw_msg(payload).await?;
576 Ok(Json(json!(txid)))
577}
578
579#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
581async fn withdraw_to_onchain(
582 Extension(gateway): Extension<Arc<Gateway>>,
583 Json(payload): Json<WithdrawToOnchainPayload>,
584) -> Result<Json<serde_json::Value>, GatewayError> {
585 let txid = gateway.handle_withdraw_to_onchain_msg(payload).await?;
586 Ok(Json(json!(txid)))
587}
588
589#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
590async fn create_invoice_for_operator(
591 Extension(gateway): Extension<Arc<Gateway>>,
592 Json(payload): Json<CreateInvoiceForOperatorPayload>,
593) -> Result<Json<serde_json::Value>, GatewayError> {
594 let invoice = gateway
595 .handle_create_invoice_for_operator_msg(payload)
596 .await?;
597 Ok(Json(json!(invoice)))
598}
599
600#[instrument(target = LOG_GATEWAY, skip_all, err)]
601async fn pay_invoice_operator(
602 Extension(gateway): Extension<Arc<Gateway>>,
603 Json(payload): Json<PayInvoiceForOperatorPayload>,
604) -> Result<Json<serde_json::Value>, GatewayError> {
605 let preimage = gateway.handle_pay_invoice_for_operator_msg(payload).await?;
606 Ok(Json(json!(preimage.0.encode_hex::<String>())))
607}
608
609#[instrument(target = LOG_GATEWAY, skip_all, err)]
610async fn pay_invoice(
611 Extension(gateway): Extension<Arc<Gateway>>,
612 Json(payload): Json<fedimint_ln_client::pay::PayInvoicePayload>,
613) -> Result<Json<serde_json::Value>, GatewayError> {
614 let preimage = gateway.handle_pay_invoice_msg(payload).await?;
615 Ok(Json(json!(preimage.0.encode_hex::<String>())))
616}
617
618#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
620async fn connect_fed(
621 Extension(gateway): Extension<Arc<Gateway>>,
622 Json(payload): Json<ConnectFedPayload>,
623) -> Result<Json<serde_json::Value>, GatewayError> {
624 let fed = gateway.handle_connect_federation(payload).await?;
625 Ok(Json(json!(fed)))
626}
627
628#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
630async fn leave_fed(
631 Extension(gateway): Extension<Arc<Gateway>>,
632 Json(payload): Json<LeaveFedPayload>,
633) -> Result<Json<serde_json::Value>, GatewayError> {
634 let fed = gateway.handle_leave_federation(payload).await?;
635 Ok(Json(json!(fed)))
636}
637
638#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
640async fn backup(
641 Extension(gateway): Extension<Arc<Gateway>>,
642 Json(payload): Json<BackupPayload>,
643) -> Result<Json<serde_json::Value>, GatewayError> {
644 gateway.handle_backup_msg(payload).await?;
645 Ok(Json(json!(())))
646}
647
648#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
649async fn set_fees(
650 Extension(gateway): Extension<Arc<Gateway>>,
651 Json(payload): Json<SetFeesPayload>,
652) -> Result<Json<serde_json::Value>, GatewayError> {
653 gateway.handle_set_fees_msg(payload).await?;
654 Ok(Json(json!(())))
655}
656
657#[instrument(target = LOG_GATEWAY, skip_all, err)]
658async fn get_ln_onchain_address(
659 Extension(gateway): Extension<Arc<Gateway>>,
660) -> Result<Json<serde_json::Value>, GatewayError> {
661 let address = gateway.handle_get_ln_onchain_address_msg().await?;
662 Ok(Json(json!(address.to_string())))
663}
664
665#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
666async fn open_channel(
667 Extension(gateway): Extension<Arc<Gateway>>,
668 Json(mut payload): Json<OpenChannelRequest>,
669) -> Result<Json<serde_json::Value>, GatewayError> {
670 payload.push_amount_sats = 0;
671 let funding_txid = gateway.handle_open_channel_msg(payload).await?;
672 Ok(Json(json!(funding_txid)))
673}
674
675#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
676async fn open_channel_with_push(
677 Extension(gateway): Extension<Arc<Gateway>>,
678 Json(payload): Json<OpenChannelRequest>,
679) -> Result<Json<serde_json::Value>, GatewayError> {
680 let funding_txid = gateway.handle_open_channel_msg(payload).await?;
681 Ok(Json(json!(funding_txid)))
682}
683
684#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
685async fn close_channels_with_peer(
686 Extension(gateway): Extension<Arc<Gateway>>,
687 Json(payload): Json<CloseChannelsWithPeerRequest>,
688) -> Result<Json<serde_json::Value>, GatewayError> {
689 let response = gateway.handle_close_channels_with_peer_msg(payload).await?;
690 Ok(Json(json!(response)))
691}
692
693#[instrument(target = LOG_GATEWAY, skip_all, err)]
694async fn list_channels(
695 Extension(gateway): Extension<Arc<Gateway>>,
696) -> Result<Json<serde_json::Value>, GatewayError> {
697 let channels = gateway.handle_list_channels_msg().await?;
698 Ok(Json(json!(channels)))
699}
700
701#[instrument(target = LOG_GATEWAY, skip_all, err, fields(?payload))]
702async fn set_channel_fees(
703 Extension(gateway): Extension<Arc<Gateway>>,
704 Json(payload): Json<SetChannelFeesRequest>,
705) -> Result<Json<serde_json::Value>, GatewayError> {
706 gateway.handle_set_channel_fees_msg(payload).await?;
707 Ok(Json(json!(())))
708}
709
710#[instrument(target = LOG_GATEWAY, skip_all, err)]
711async fn send_onchain(
712 Extension(gateway): Extension<Arc<Gateway>>,
713 Json(payload): Json<SendOnchainRequest>,
714) -> Result<Json<serde_json::Value>, GatewayError> {
715 let txid = gateway.handle_send_onchain_msg(payload).await?;
716 Ok(Json(json!(txid)))
717}
718
719#[instrument(target = LOG_GATEWAY, skip_all, err)]
720async fn recheck_address(
721 Extension(gateway): Extension<Arc<Gateway>>,
722 Json(payload): Json<DepositAddressRecheckPayload>,
723) -> Result<Json<serde_json::Value>, GatewayError> {
724 gateway.handle_recheck_address_msg(payload).await?;
725 Ok(Json(json!({})))
726}
727
728#[instrument(target = LOG_GATEWAY, skip_all, err)]
729async fn get_balances(
730 Extension(gateway): Extension<Arc<Gateway>>,
731) -> Result<Json<serde_json::Value>, GatewayError> {
732 let balances = gateway.handle_get_balances_msg().await?;
733 Ok(Json(json!(balances)))
734}
735
736#[instrument(target = LOG_GATEWAY, skip_all, err)]
737async fn get_gateway_id(
738 Extension(gateway): Extension<Arc<Gateway>>,
739) -> Result<Json<serde_json::Value>, GatewayError> {
740 Ok(Json(json!(gateway.http_gateway_id().await)))
741}
742
743#[instrument(target = LOG_GATEWAY, skip_all, err)]
744async fn routing_info_v2(
745 Extension(gateway): Extension<Arc<Gateway>>,
746 Json(federation_id): Json<FederationId>,
747) -> Result<Json<serde_json::Value>, GatewayError> {
748 let routing_info = gateway.routing_info_v2(&federation_id).await?;
749 Ok(Json(json!(routing_info)))
750}
751
752#[instrument(target = LOG_GATEWAY, skip_all, err)]
753async fn pay_bolt11_invoice_v2(
754 Extension(gateway): Extension<Arc<Gateway>>,
755 Json(payload): Json<SendPaymentPayload>,
756) -> Result<Json<serde_json::Value>, GatewayError> {
757 let payment_result = gateway.send_payment_v2(payload).await?;
758 Ok(Json(json!(payment_result)))
759}
760
761#[instrument(target = LOG_GATEWAY, skip_all, err)]
762async fn create_bolt11_invoice_v2(
763 Extension(gateway): Extension<Arc<Gateway>>,
764 Json(payload): Json<CreateBolt11InvoicePayload>,
765) -> Result<Json<serde_json::Value>, GatewayError> {
766 let invoice = gateway.create_bolt11_invoice_v2(payload).await?;
767 Ok(Json(json!(invoice)))
768}
769
770pub(crate) async fn verify_bolt11_preimage_v2_get(
771 Extension(gateway): Extension<Arc<Gateway>>,
772 Path(payment_hash): Path<sha256::Hash>,
773 Query(query): Query<HashMap<String, String>>,
774) -> Result<Json<serde_json::Value>, GatewayError> {
775 let response = gateway
776 .verify_bolt11_preimage_v2(payment_hash, query.contains_key("wait"))
777 .await
778 .map_err(|e| LnurlError::internal(anyhow!(e)))?;
779
780 Ok(Json(json!(LnurlResponse::Ok(response))))
781}
782
783#[instrument(target = LOG_GATEWAY, skip_all, err)]
784async fn spend_ecash(
785 Extension(gateway): Extension<Arc<Gateway>>,
786 Json(payload): Json<SpendEcashPayload>,
787) -> Result<Json<serde_json::Value>, GatewayError> {
788 Ok(Json(json!(gateway.handle_spend_ecash_msg(payload).await?)))
789}
790
791#[instrument(target = LOG_GATEWAY, skip_all, err)]
792async fn receive_ecash(
793 Extension(gateway): Extension<Arc<Gateway>>,
794 Json(payload): Json<ReceiveEcashPayload>,
795) -> Result<Json<serde_json::Value>, GatewayError> {
796 Ok(Json(json!(
797 gateway.handle_receive_ecash_msg(payload).await?
798 )))
799}
800
801#[instrument(target = LOG_GATEWAY, skip_all, err)]
802async fn mnemonic(
803 Extension(gateway): Extension<Arc<Gateway>>,
804) -> Result<Json<serde_json::Value>, GatewayError> {
805 let words = gateway.handle_mnemonic_msg().await?;
806 Ok(Json(json!(words)))
807}
808
809#[instrument(target = LOG_GATEWAY, skip_all, err)]
810async fn set_mnemonic(
811 Extension(gateway): Extension<Arc<Gateway>>,
812 Json(payload): Json<SetMnemonicPayload>,
813) -> Result<Json<serde_json::Value>, GatewayError> {
814 gateway.handle_set_mnemonic_msg(payload).await?;
815 Ok(Json(json!(())))
816}
817
818#[instrument(target = LOG_GATEWAY, skip_all, err)]
819pub(crate) async fn stop(
820 Extension(task_group): Extension<TaskGroup>,
821 Extension(gateway): Extension<Arc<Gateway>>,
822) -> Result<Json<serde_json::Value>, GatewayError> {
823 gateway.handle_shutdown_msg(task_group).await?;
824 Ok(Json(json!(())))
825}
826
827#[instrument(target = LOG_GATEWAY, skip_all, err)]
834async fn payment_log(
835 Extension(gateway): Extension<Arc<Gateway>>,
836 Json(payload): Json<PaymentLogPayload>,
837) -> Result<Json<serde_json::Value>, GatewayError> {
838 let payment_log = gateway.handle_payment_log_msg(payload).await?;
839 Ok(Json(json!(payment_log)))
840}
841
842#[instrument(target = LOG_GATEWAY, skip_all, err)]
843async fn payment_summary(
844 Extension(gateway): Extension<Arc<Gateway>>,
845 Json(payload): Json<PaymentSummaryPayload>,
846) -> Result<Json<serde_json::Value>, GatewayError> {
847 let payment_summary = gateway.handle_payment_summary_msg(payload).await?;
848 Ok(Json(json!(payment_summary)))
849}
850
851#[instrument(target = LOG_GATEWAY, skip_all, err)]
852async fn get_invoice(
853 Extension(gateway): Extension<Arc<Gateway>>,
854 Json(payload): Json<GetInvoiceRequest>,
855) -> Result<Json<serde_json::Value>, GatewayError> {
856 let invoice = gateway.handle_get_invoice_msg(payload).await?;
857 Ok(Json(json!(invoice)))
858}
859
860#[instrument(target = LOG_GATEWAY, skip_all, err)]
861async fn list_transactions(
862 Extension(gateway): Extension<Arc<Gateway>>,
863 Json(payload): Json<ListTransactionsPayload>,
864) -> Result<Json<serde_json::Value>, GatewayError> {
865 let transactions = gateway.handle_list_transactions_msg(payload).await?;
866 Ok(Json(json!(transactions)))
867}
868
869#[instrument(target = LOG_GATEWAY, skip_all, err)]
870async fn create_offer_for_operator(
871 Extension(gateway): Extension<Arc<Gateway>>,
872 Json(payload): Json<CreateOfferPayload>,
873) -> Result<Json<serde_json::Value>, GatewayError> {
874 let offer = gateway
875 .handle_create_offer_for_operator_msg(payload)
876 .await?;
877 Ok(Json(json!(offer)))
878}
879
880#[instrument(target = LOG_GATEWAY, skip_all, err)]
881async fn pay_offer_operator(
882 Extension(gateway): Extension<Arc<Gateway>>,
883 Json(payload): Json<PayOfferPayload>,
884) -> Result<Json<serde_json::Value>, GatewayError> {
885 let response = gateway.handle_pay_offer_for_operator_msg(payload).await?;
886 Ok(Json(json!(response)))
887}
888
889#[instrument(target = LOG_GATEWAY, skip_all, err)]
890async fn invite_codes(
891 Extension(gateway): Extension<Arc<Gateway>>,
892) -> Result<Json<serde_json::Value>, GatewayError> {
893 let invite_codes = gateway.handle_export_invite_codes().await;
894 Ok(Json(json!(invite_codes)))
895}