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