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