Skip to main content

fedimint_gateway_server/
rpc_server.rs

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
54// Routes that the liquidity manager is allowed to access. Any authenticated
55// route NOT in this list requires the admin password.
56const 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
78/// Creates the webserver's routes and spawns the webserver in a separate task.
79pub 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        // Backwards compatibility: Continue supporting gateway APIs without versioning
91        .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    // Don't start the Iroh endpoint until the mnemonic has been set via HTTP or the
115    // UI
116    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
126/// Extracts the Bearer token from the Authorization header of the request.
127fn 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        // Allow the API mnemonic endpoint (for CLI usage)
154        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
168/// Middleware to authenticate an incoming request. Routes that are
169/// authenticated with this middleware always require a Bearer token to be
170/// supplied in the Authorization header.
171async 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    // Check the liquidity manager
184    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
200/// Registers a GET API handler for both the HTTP server and the Iroh
201/// `Endpoint`.
202fn 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
217/// Registers a POST API handler for both the HTTP server and the Iroh
218/// `Endpoint`.
219fn 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
235/// Public routes that are used in the LNv1 protocol
236fn 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
248/// Public routes that are used in the LNv2 protocol
249fn 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    // Verify endpoint does not have the same signature, it is handled separately
273    router.route("/verify/{payment_hash}", get(verify_bolt11_preimage_v2_get))
274}
275
276/// Gateway Webserver Routes. The gateway supports two types of routes
277/// - Always Authenticated: these routes always require a Bearer token. Used by
278///   gateway administrators.
279/// - Un-authenticated: anyone can request these routes. Used by fedimint
280///   clients.
281fn routes(gateway: Arc<Gateway>, task_group: TaskGroup, handlers: &mut Handlers) -> Router {
282    // Public routes on gateway webserver
283    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    // Authenticated routes used for gateway administration
294    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    // Stop does not have the same function signature, it is handled separately
458    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/// Display high-level information about the Gateway
520#[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/// Display high-level information about the Gateway config
529#[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/// Generate deposit address
541#[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/// Pegs in funds from the gateway's onchain wallet
551#[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/// Withdraw from a gateway federation.
561#[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/// Withdraw from a gateway federation.
571#[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/// Connect a new federation
610#[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/// Leave a federation
620#[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/// Backup a gateway actor state
630#[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}