Skip to main content

lexe_api_core/
def.rs

1//! # API Definitions
2//!
3//! This module, as closely as possible, defines the various APIs exposed by
4//! different services to different clients. Although we do not have
5//! compile-time guarantees that the services exposed exactly match the
6//! definitions below, it is straightforward to compare the Axum routers and
7//! handlers with the definitions below to ensure consistency.
8//!
9//! ## Guidelines
10//!
11//! All API requests and responses should return structs for upgradeability,
12//! e.g. [`UserPkStruct`] instead of [`UserPk`].
13//!
14//! If an API method takes or returns nothing, make the type [`Empty`] and NOT
15//! `()` (unit type). Using `()` makes it impossible to add optional fields in a
16//! backwards-compatible way.
17//!
18//! Each endpoint should be documented with:
19//! - 1) HTTP method e.g. `GET`
20//! - 2) Endpoint e.g. `/v1/file`
21//! - 3) Data used to make the request e.g. `VfsFileId`
22//! - 4) The return type e.g. `MaybeVfsFile`
23//!
24//! The methods below should resemble the data actually sent across the wire.
25//!
26//! [`Empty`]: crate::types::Empty
27//! [`UserPk`]: lexe_common::api::user::UserPk
28//! [`UserPkStruct`]: lexe_common::api::user::UserPkStruct
29
30#![deny(missing_docs)]
31// We don't export our traits currently so auto trait stability is not relevant.
32#![allow(async_fn_in_trait)]
33
34use std::collections::HashSet;
35
36use async_trait::async_trait;
37use bytes::Bytes;
38use lexe_common::api::{
39    MegaId,
40    auth::{
41        BearerAuthRequestWire, BearerAuthResponse, BearerAuthToken,
42        UserSignupRequestWire, UserSignupRequestWireV1,
43    },
44    fiat_rates::FiatRates,
45    models::{
46        SignMsgRequest, SignMsgResponse, Status, VerifyMsgRequest,
47        VerifyMsgResponse,
48    },
49    provision::NodeProvisionRequest,
50    revocable_clients::{
51        CreateRevocableClientRequest, CreateRevocableClientResponse,
52        GetRevocableClients, RevocableClients, UpdateClientRequest,
53        UpdateClientResponse,
54    },
55    test_event::TestEventOp,
56    user::{GetNewScidsRequest, MaybeScid, MaybeUser, Scids, UserPk},
57    version::{CurrentEnclaves, EnclavesToProvision, NodeEnclave},
58};
59#[cfg(doc)]
60use lexe_common::{
61    api::MegaIdStruct,
62    api::models::BroadcastedTxInfo,
63    api::user::NodePkStruct,
64    api::user::{UserPkSet, UserPkStruct},
65    api::version::MeasurementStruct,
66};
67use lexe_crypto::ed25519;
68use lexe_enclave::enclave::Measurement;
69use lightning::events::Event;
70
71#[cfg(doc)]
72use crate::types::payments::{PaymentCreatedIndex, PaymentId};
73use crate::{
74    error::{
75        BackendApiError, GatewayApiError, LspApiError, MegaApiError,
76        NodeApiError, RunnerApiError,
77    },
78    models::{
79        command::{
80            BackupInfo, ClaimGeneratedHumanBitcoinAddress, CloseChannelRequest,
81            CreateInvoiceRequest, CreateInvoiceResponse, CreateOfferRequest,
82            CreateOfferResponse, DebugInfo, EnclavesToProvisionRequest,
83            GetAddressResponse, GetGeneratedUsernameResponse,
84            GetHumanBitcoinAddressResponse, GetNewPayments,
85            GetUpdatedPaymentMetadata, GetUpdatedPayments,
86            HumanBitcoinAddressV1, ListChannelsResponse, NodeInfo, NodeInfoV1,
87            OpenChannelRequest, OpenChannelResponse, PayInvoiceRequest,
88            PayInvoiceResponse, PayOfferRequest, PayOfferResponse,
89            PayOnchainRequest, PayOnchainResponse, PaymentCreatedIndexStruct,
90            PaymentCreatedIndexes, PaymentIdStruct,
91            PreflightCloseChannelRequest, PreflightCloseChannelResponse,
92            PreflightOpenChannelRequest, PreflightOpenChannelResponse,
93            PreflightPayInvoiceRequest, PreflightPayInvoiceResponse,
94            PreflightPayOfferRequest, PreflightPayOfferResponse,
95            PreflightPayOnchainRequest, PreflightPayOnchainResponse,
96            ResyncRequest, SetupGDrive, UpdatePersonalNote,
97            UpsertCustomHumanBitcoinAddress, UpsertHumanBitcoinAddressResponse,
98            VecPaymentId,
99        },
100        nwc::{
101            CreateNwcClientRequest, CreateNwcClientResponse, DbNwcClient,
102            DbNwcClientFields, GetNwcClients, ListNwcClientResponse,
103            NostrPkStruct, NostrSignedEvent, NwcRequest,
104            UpdateNwcClientRequest, UpdateNwcClientResponse, VecDbNwcClient,
105        },
106        runner::{
107            MegaNodeApiUserEvictRequest, MegaNodeApiUserRunRequest,
108            MegaNodeApiUserRunResponse, UserFinishedRequest,
109            UserLeaseRenewalRequest,
110        },
111    },
112    types::{
113        Empty,
114        lnurl::{
115            LnurlCallbackRequest, LnurlCallbackResponse, LnurlError,
116            LnurlPayRequestWire,
117        },
118        payments::{
119            DbPaymentMetadata, DbPaymentV1, DbPaymentV2, MaybeBasicPaymentV2,
120            MaybeDbPaymentMetadata, MaybeDbPaymentV1, MaybeDbPaymentV2,
121            VecBasicPaymentV1, VecBasicPaymentV2, VecDbPaymentMetadata,
122            VecDbPaymentV1, VecDbPaymentV2,
123        },
124        ports::MegaPorts,
125        sealed_seed::{MaybeSealedSeed, SealedSeed, SealedSeedId},
126        username::UsernameStruct,
127    },
128    vfs::{
129        MaybeVfsFile, VecVfsFile, VfsDirectory, VfsDirectoryList, VfsFile,
130        VfsFileId,
131    },
132};
133
134// TODO(max): To make clear that only upgradeable structs are being serialized,
135// these methods should take e.g. `&UserPkStruct` instead of `UserPk`.
136
137/// Defines the api that the backend exposes to the app (via the gateway).
138pub trait AppBackendApi {
139    /// POST /app/v2/signup [`ed25519::Signed<UserSignupRequestWire>`] ->
140    /// [`Empty`]
141    async fn signup_v2(
142        &self,
143        signed_req: &ed25519::Signed<&UserSignupRequestWire>,
144    ) -> Result<Empty, BackendApiError>;
145
146    /// POST /app/v1/signup [`ed25519::Signed<UserSignupRequestWireV1>`] ->
147    /// [`Empty`]
148    // TODO(phlip9): remove once all installed mobile clients above `app-v0.7.6`
149    #[deprecated = "Use the `signup_v2` API instead"]
150    async fn signup_v1(
151        &self,
152        signed_req: &ed25519::Signed<&UserSignupRequestWireV1>,
153    ) -> Result<Empty, BackendApiError>;
154}
155
156/// Defines the api that the gateway directly exposes to the app.
157pub trait AppGatewayApi {
158    /// GET /app/v1/fiat_rates [`Empty`] -> [`FiatRates`]
159    async fn get_fiat_rates(&self) -> Result<FiatRates, GatewayApiError>;
160
161    /// Query which node enclaves the user needs to provision to.
162    ///
163    /// POST /app/v1/enclaves_to_provision
164    /// [`EnclavesToProvisionRequest`] -> [`EnclavesToProvision`]
165    async fn enclaves_to_provision(
166        &self,
167        req: &EnclavesToProvisionRequest,
168        auth: BearerAuthToken,
169    ) -> Result<EnclavesToProvision, GatewayApiError>;
170
171    /// Get the measurement and semver version of the latest node release.
172    ///
173    /// GET /app/v1/latest_release [`Empty`] -> [`NodeEnclave`]
174    #[deprecated(note = "since app-v0.8.1: Use current_releases() instead")]
175    async fn latest_release(&self) -> Result<NodeEnclave, GatewayApiError>;
176
177    /// Get the measurements, enclave machine id and versions of all
178    /// current node enclaves.
179    ///
180    /// GET /app/v1/current_releases [`Empty`] -> [`CurrentEnclaves`]
181    #[deprecated(note = "since app-v0.8.8: Use current_enclaves() instead")]
182    async fn current_releases(
183        &self,
184    ) -> Result<CurrentEnclaves, GatewayApiError>;
185
186    /// Get the measurements, enclave machine id and versions of all
187    /// current node enclaves.
188    ///
189    /// GET /app/v1/current_enclaves [`Empty`] -> [`CurrentEnclaves`]
190    async fn current_enclaves(
191        &self,
192    ) -> Result<CurrentEnclaves, GatewayApiError>;
193}
194
195/// Defines the api that the node exposes to the app during provisioning.
196pub trait AppNodeProvisionApi {
197    /// Provision a node with the given [`Measurement`]. The provisioning node's
198    /// remote attestation will be checked against the given [`Measurement`].
199    ///
200    /// POST /app/provision [`NodeProvisionRequest`] -> [`Empty`]
201    async fn provision(
202        &self,
203        measurement: Measurement,
204        data: NodeProvisionRequest,
205    ) -> Result<Empty, NodeApiError>;
206}
207
208/// Defines the api that the node exposes to the app during normal operation.
209pub trait AppNodeRunApi {
210    /// GET /app/v2/node_info [`Empty`] -> [`NodeInfo`]
211    async fn node_info(&self) -> Result<NodeInfo, NodeApiError>;
212
213    /// GET /app/node_info [`Empty`] -> [`NodeInfoV1`]
214    #[deprecated(note = "since node-v0.9.4: Use node_info instead")]
215    async fn node_info_v1(&self) -> Result<NodeInfoV1, NodeApiError>;
216
217    /// GET /app/debug_info [`Empty`] -> [`DebugInfo`]
218    async fn debug_info(&self) -> Result<DebugInfo, NodeApiError>;
219
220    /// GET /app/list_channels [`Empty`] -> [`ListChannelsResponse`]
221    async fn list_channels(&self)
222    -> Result<ListChannelsResponse, NodeApiError>;
223
224    /// POST /app/sign_message [`SignMsgRequest`] -> [`SignMsgResponse`]
225    ///
226    /// Introduced in `node-v0.6.5`.
227    async fn sign_message(
228        &self,
229        req: SignMsgRequest,
230    ) -> Result<SignMsgResponse, NodeApiError>;
231
232    /// POST /app/verify_message [`VerifyMsgRequest`] -> [`VerifyMsgResponse`]
233    ///
234    /// Introduced in `node-v0.6.5`.
235    async fn verify_message(
236        &self,
237        req: VerifyMsgRequest,
238    ) -> Result<VerifyMsgResponse, NodeApiError>;
239
240    /// POST /app/open_channel [`OpenChannelRequest`] -> [`OpenChannelResponse`]
241    ///
242    /// Opens a channel to the LSP.
243    async fn open_channel(
244        &self,
245        req: OpenChannelRequest,
246    ) -> Result<OpenChannelResponse, NodeApiError>;
247
248    /// POST /app/preflight_open_channel [`PreflightOpenChannelRequest`]
249    ///                                  -> [`PreflightOpenChannelResponse`]
250    ///
251    /// Estimate on-chain fees required for an [`open_channel`] to the LSP.
252    ///
253    /// [`open_channel`]: AppNodeRunApi::open_channel
254    async fn preflight_open_channel(
255        &self,
256        req: PreflightOpenChannelRequest,
257    ) -> Result<PreflightOpenChannelResponse, NodeApiError>;
258
259    /// POST /app/close_channel [`CloseChannelRequest`] -> [`Empty`]
260    ///
261    /// Closes a channel to the LSP.
262    async fn close_channel(
263        &self,
264        req: CloseChannelRequest,
265    ) -> Result<Empty, NodeApiError>;
266
267    /// POST /app/preflight_close_channel [`PreflightCloseChannelRequest`]
268    ///                                   -> [`PreflightCloseChannelResponse`]
269    ///
270    /// Estimate the on-chain fees required for a [`close_channel`].
271    ///
272    /// [`close_channel`]: AppNodeRunApi::close_channel
273    async fn preflight_close_channel(
274        &self,
275        req: PreflightCloseChannelRequest,
276    ) -> Result<PreflightCloseChannelResponse, NodeApiError>;
277
278    /// POST /app/create_invoice [`CreateInvoiceRequest`]
279    ///                          -> [`CreateInvoiceResponse`]
280    async fn create_invoice(
281        &self,
282        req: CreateInvoiceRequest,
283    ) -> Result<CreateInvoiceResponse, NodeApiError>;
284
285    /// POST /app/pay_invoice [`PayInvoiceRequest`] -> [`PayInvoiceResponse`]
286    async fn pay_invoice(
287        &self,
288        req: PayInvoiceRequest,
289    ) -> Result<PayInvoiceResponse, NodeApiError>;
290
291    /// POST /app/preflight_pay_invoice [`PreflightPayInvoiceRequest`]
292    ///                                 -> [`PreflightPayInvoiceResponse`]
293    ///
294    /// This endpoint lets the app ask its node to "pre-flight" a BOLT11 invoice
295    /// payment without going through with the actual payment. We verify as much
296    /// as we can, find a route, and get the fee estimates.
297    async fn preflight_pay_invoice(
298        &self,
299        req: PreflightPayInvoiceRequest,
300    ) -> Result<PreflightPayInvoiceResponse, NodeApiError>;
301
302    /// POST /app/create_offer [`CreateOfferRequest`] -> [`CreateOfferResponse`]
303    ///
304    /// Create a new Lightning offer (BOLT12).
305    //
306    // Added in `node-v0.7.3`.
307    async fn create_offer(
308        &self,
309        req: CreateOfferRequest,
310    ) -> Result<CreateOfferResponse, NodeApiError>;
311
312    /// POST /app/pay_offer [`PayOfferRequest`] -> [`PayOfferResponse`]
313    ///
314    /// Pay a Lightning offer (BOLT12).
315    //
316    // Added in `node-v0.7.4`.
317    async fn pay_offer(
318        &self,
319        req: PayOfferRequest,
320    ) -> Result<PayOfferResponse, NodeApiError>;
321
322    /// POST /app/preflight_pay_offer [`PreflightPayOfferRequest`]
323    ///                               -> [`PreflightPayOfferResponse`]
324    ///
325    /// This endpoint lets the app ask its node to "pre-flight" a Lightning
326    /// offer (BOLT12) payment without going through with the actual payment. We
327    /// verify as much as we can, find a route, and get the fee estimates.
328    //
329    // Added in `node-v0.7.4`.
330    async fn preflight_pay_offer(
331        &self,
332        req: PreflightPayOfferRequest,
333    ) -> Result<PreflightPayOfferResponse, NodeApiError>;
334
335    // TODO(phlip9): BOLT12: /app/request_refund
336
337    /// POST /app/get_address [`Empty`] -> [`GetAddressResponse`]
338    ///
339    /// Returns an address which can be used to receive funds. It is unused
340    /// unless there is an incoming tx and BDK hasn't detected it yet.
341    async fn get_address(&self) -> Result<GetAddressResponse, NodeApiError>;
342
343    /// POST /app/pay_onchain [`PayOnchainRequest`] -> [`PayOnchainResponse`]
344    ///
345    /// Pay bitcoin onchain. If the address is valid and we have sufficient
346    /// onchain funds, this will broadcast a new transaction to the bitcoin
347    /// mempool.
348    async fn pay_onchain(
349        &self,
350        req: PayOnchainRequest,
351    ) -> Result<PayOnchainResponse, NodeApiError>;
352
353    /// POST /app/preflight_pay_onchain [`PreflightPayOnchainRequest`]
354    ///                              -> [`PreflightPayOnchainResponse`]
355    ///
356    /// Returns estimated network fees for a potential onchain payment.
357    async fn preflight_pay_onchain(
358        &self,
359        req: PreflightPayOnchainRequest,
360    ) -> Result<PreflightPayOnchainResponse, NodeApiError>;
361
362    /// GET /app/v1/payments/id [`PaymentIdStruct`] -> [`MaybeBasicPaymentV2`]
363    //
364    // Added in `node-v0.8.10`.
365    async fn get_payment_by_id(
366        &self,
367        req: PaymentIdStruct,
368    ) -> Result<MaybeBasicPaymentV2, NodeApiError>;
369
370    /// POST /app/payments/indexes [`PaymentCreatedIndexes`]
371    ///                         -> [`VecDbPaymentV1`]
372    ///
373    /// Fetch a batch of payments by their [`PaymentCreatedIndex`]s. This is
374    /// typically used by a mobile client to poll for updates on payments
375    /// which it currently has stored locally as "pending"; the intention is
376    /// to check if any of these payments have been updated.
377    //
378    // We use POST because there may be a lot of idxs, which might be too large
379    // to fit inside query parameters.
380    #[deprecated(note = "since app-v0.8.9+29 and sdk-sidecar-v0.3.1: \
381                         Use get_payments_by_ids instead")]
382    async fn get_payments_by_indexes(
383        &self,
384        req: PaymentCreatedIndexes,
385    ) -> Result<VecBasicPaymentV1, NodeApiError>;
386
387    /// GET /app/payments/new [`GetNewPayments`] -> [`VecBasicPaymentV1`]
388    #[deprecated(note = "since app-v0.8.9+29 and sdk-sidecar-v0.3.1: \
389                         Use get_updated_payments instead")]
390    async fn get_new_payments(
391        &self,
392        req: GetNewPayments,
393    ) -> Result<VecBasicPaymentV1, NodeApiError>;
394
395    /// GET /app/payments/updated [`GetUpdatedPayments`]
396    ///                        -> [`VecBasicPaymentV2`]
397    async fn get_updated_payments(
398        &self,
399        req: GetUpdatedPayments,
400    ) -> Result<VecBasicPaymentV2, NodeApiError>;
401
402    /// PUT /app/payments/note [`UpdatePersonalNote`] -> [`Empty`]
403    async fn update_personal_note(
404        &self,
405        req: UpdatePersonalNote,
406    ) -> Result<Empty, NodeApiError>;
407
408    /// Lists all revocable clients.
409    ///
410    /// GET /app/clients [`GetRevocableClients`] -> [`RevocableClients`]
411    // Added in `node-0.7.9`
412    async fn get_revocable_clients(
413        &self,
414        req: GetRevocableClients,
415    ) -> Result<RevocableClients, NodeApiError>;
416
417    /// Creates a new revocable client. Returns the newly issued client cert.
418    ///
419    /// POST /app/clients [`CreateRevocableClientRequest`]
420    ///                   -> [`CreateRevocableClientResponse`]
421    // Added in `node-0.7.9`
422    async fn create_revocable_client(
423        &self,
424        req: CreateRevocableClientRequest,
425    ) -> Result<CreateRevocableClientResponse, NodeApiError>;
426
427    /// Updates this revocable client. Returns the updated client.
428    ///
429    /// PUT /app/clients [`UpdateClientRequest`] -> [`UpdateClientResponse`]
430    // Added in `node-0.7.9`
431    async fn update_revocable_client(
432        &self,
433        req: UpdateClientRequest,
434    ) -> Result<UpdateClientResponse, NodeApiError>;
435
436    /// List all broadcasted transactions.
437    ///
438    /// GET /app/list_broadcasted_txs [`Empty`] -> [`Vec<BroadcastedTxInfo>`]
439    async fn list_broadcasted_txs(
440        &self,
441    ) -> Result<serde_json::Value, NodeApiError>;
442
443    /// Get the current status of Node backup.
444    ///
445    /// GET /app/backup [`Empty`] -> [`BackupInfo`]
446    async fn backup_info(&self) -> Result<BackupInfo, NodeApiError>;
447
448    /// Setup GDrive backup.
449    ///
450    /// POST /app/backup/gdrive [`SetupGDrive`] -> [`Empty`]
451    async fn setup_gdrive(
452        &self,
453        req: SetupGDrive,
454    ) -> Result<Empty, NodeApiError>;
455
456    /// GET /app/v2/human_bitcoin_address [`Empty`]
457    ///                                -> [`GetHumanBitcoinAddressResponse`]
458    async fn get_human_bitcoin_address(
459        &self,
460    ) -> Result<GetHumanBitcoinAddressResponse, NodeApiError>;
461
462    /// GET /app/human_bitcoin_address [`Empty`] -> [`HumanBitcoinAddressV1`]
463    #[deprecated(note = "since app-v0.9.7 and sdk-sidecar-v0.4.7: \
464                         Use get_human_bitcoin_address instead")]
465    async fn get_human_bitcoin_address_v1(
466        &self,
467    ) -> Result<HumanBitcoinAddressV1, NodeApiError>;
468
469    /// PUT /app/v2/human_bitcoin_address [`UsernameStruct`]
470    ///                                -> [`UpsertHumanBitcoinAddressResponse`]
471    async fn upsert_custom_human_bitcoin_address(
472        &self,
473        req: UsernameStruct,
474    ) -> Result<UpsertHumanBitcoinAddressResponse, NodeApiError>;
475
476    /// PUT /app/human_bitcoin_address [`UsernameStruct`]
477    ///                             -> [`HumanBitcoinAddressV1`]
478    #[deprecated(note = "since app-v0.9.7 and sdk-sidecar-v0.4.7: \
479                         Use upsert_custom_human_bitcoin_address instead")]
480    async fn update_human_bitcoin_address_v1(
481        &self,
482        req: UsernameStruct,
483    ) -> Result<HumanBitcoinAddressV1, NodeApiError>;
484
485    /// GET /app/payment_address [`Empty`] -> [`HumanBitcoinAddressV1`]
486    #[deprecated(note = "since app-v0.9.3 and sdk-sidecar-v0.4.2: \
487                         Use get_human_bitcoin_address_v1 instead")]
488    async fn get_payment_address_v1(
489        &self,
490    ) -> Result<HumanBitcoinAddressV1, NodeApiError>;
491
492    /// PUT /app/payment_address [`UsernameStruct`] -> [`HumanBitcoinAddressV1`]
493    #[deprecated(note = "since app-v0.9.3 and sdk-sidecar-v0.4.2: \
494                         Use update_human_bitcoin_address_v1 instead")]
495    async fn update_payment_address_v1(
496        &self,
497        req: UsernameStruct,
498    ) -> Result<HumanBitcoinAddressV1, NodeApiError>;
499
500    /// List NWC clients for the current user.
501    /// Returns client info without sensitive data (no connection strings).
502    ///
503    /// GET /app/nwc_clients [`Empty`] -> [`ListNwcClientResponse`]
504    async fn list_nwc_clients(
505        &self,
506    ) -> Result<ListNwcClientResponse, NodeApiError>;
507
508    /// Create a new NWC client.
509    /// Generates new keys and returns the connection string.
510    ///
511    /// POST /app/nwc_clients [`CreateNwcClientRequest`]
512    ///                    -> [`CreateNwcClientResponse`]
513    async fn create_nwc_client(
514        &self,
515        req: CreateNwcClientRequest,
516    ) -> Result<CreateNwcClientResponse, NodeApiError>;
517
518    /// Update an existing NWC client's label.
519    ///
520    /// PUT /app/nwc_clients [`UpdateNwcClientRequest`]
521    ///                   -> [`UpdateNwcClientResponse`]
522    async fn update_nwc_client(
523        &self,
524        req: UpdateNwcClientRequest,
525    ) -> Result<UpdateNwcClientResponse, NodeApiError>;
526
527    /// Delete an NWC client given its nostr client public key.
528    ///
529    /// DELETE /app/nwc_clients [`NostrPkStruct`] -> [`Empty`]
530    async fn delete_nwc_client(
531        &self,
532        req: NostrPkStruct,
533    ) -> Result<Empty, NodeApiError>;
534}
535
536/// The bearer auth API exposed by the backend (sometimes via the gateway) to
537/// various consumers. This trait is defined separately from the
538/// usual `ConsumerServiceApi` traits because `BearerAuthenticator` needs to
539/// abstract over a generic implementor of [`BearerAuthBackendApi`].
540#[async_trait]
541pub trait BearerAuthBackendApi {
542    /// POST /CONSUMER/bearer_auth [`ed25519::Signed<BearerAuthRequest>`]
543    ///                         -> [`BearerAuthResponse`]
544    ///
545    /// Valid values for `CONSUMER` are: "app", "node" and "lsp".
546    async fn bearer_auth(
547        &self,
548        signed_req: &ed25519::Signed<&BearerAuthRequestWire>,
549    ) -> Result<BearerAuthResponse, BackendApiError>;
550}
551
552/// Defines the API the mega node exposes to the Lexe operators.
553///
554/// NOTE: For performance, this API does not use TLS! This API should only
555/// contain methods for limited operational and lifecycle management endpoints.
556pub trait LexeMegaApi {
557    /// POST /lexe/run_user [`MegaNodeApiUserRunRequest`]
558    ///                  -> [`MegaNodeApiUserRunResponse`]
559    async fn run_user(
560        &self,
561        req: MegaNodeApiUserRunRequest,
562    ) -> Result<MegaNodeApiUserRunResponse, MegaApiError>;
563
564    /// POST /lexe/evict_user [`MegaNodeApiUserEvictRequest`] -> [`Empty`]
565    async fn evict_user(
566        &self,
567        req: MegaNodeApiUserEvictRequest,
568    ) -> Result<Empty, MegaApiError>;
569
570    /// GET /lexe/status [`MegaIdStruct`] -> [`Status`]
571    async fn status_mega(
572        &self,
573        mega_id: MegaId,
574    ) -> Result<Status, MegaApiError>;
575
576    /// POST /lexe/shutdown [`Empty`] -> [`Empty`]
577    async fn shutdown_mega(&self) -> Result<Empty, MegaApiError>;
578}
579
580/// Defines the API the node exposes to the Lexe operators at run time.
581///
582/// NOTE: For performance, this API does not use TLS! This API should only
583/// contain methods for limited operational and lifecycle management endpoints.
584pub trait LexeNodeRunApi {
585    /// GET /lexe/status [`UserPkStruct`] -> [`Status`]
586    async fn status_run(&self, user_pk: UserPk)
587    -> Result<Status, NodeApiError>;
588
589    /// POST /lexe/resync [`ResyncRequest`] -> [`Empty`]
590    ///
591    /// Triggers an immediate resync of BDK and LDK. Optionally full sync the
592    /// BDK wallet. Returns only once sync has either completed or timed out.
593    async fn resync(&self, req: ResyncRequest) -> Result<Empty, NodeApiError>;
594
595    /// POST /lexe/test_event [`TestEventOp`] -> [`Empty`]
596    ///
597    /// Calls the corresponding `TestEventReceiver` method.
598    /// This endpoint can only be called by one caller at any one time.
599    /// Does nothing and returns an error if called in prod.
600    async fn test_event(&self, op: &TestEventOp)
601    -> Result<Empty, NodeApiError>;
602
603    /// GET /lexe/shutdown [`UserPkStruct`] -> [`Empty`]
604    ///
605    /// Not to be confused with [`LexeMegaApi::shutdown_mega`].
606    async fn shutdown_run(
607        &self,
608        user_pk: UserPk,
609    ) -> Result<Empty, NodeApiError>;
610
611    /// POST /lexe/create_invoice [`CreateInvoiceRequest`] ->
612    /// [`CreateInvoiceResponse`]
613    async fn create_invoice(
614        &self,
615        req: CreateInvoiceRequest,
616    ) -> Result<CreateInvoiceResponse, NodeApiError>;
617
618    /// POST /lexe/nwc_request [`NwcRequest`] -> [`NostrSignedEvent`]
619    ///
620    /// Processes an encrypted NWC request from the nostr-bridge.
621    /// The node will decrypt the request, execute the command, and return
622    /// an encrypted response.
623    async fn nwc_request(
624        &self,
625        req: NwcRequest,
626    ) -> Result<NostrSignedEvent, NodeApiError>;
627}
628
629/// Defines the API the runner exposes to mega nodes.
630pub trait MegaRunnerApi {
631    /// POST /mega/ready [`MegaPorts`] -> [`Empty`]
632    ///
633    /// Indicates this mega node is initialized and ready to load user nodes.
634    async fn mega_ready(
635        &self,
636        ports: &MegaPorts,
637    ) -> Result<Empty, RunnerApiError>;
638
639    /// POST /mega/activity [`UserPkSet`] -> [`Empty`]
640    ///
641    /// Indicates the meganode received some activity from its users.
642    async fn activity(
643        &self,
644        user_pks: HashSet<UserPk>,
645    ) -> Result<Empty, RunnerApiError>;
646
647    /// POST /mega/user_finished [`UserFinishedRequest`] -> [`Empty`]
648    ///
649    /// Notifies the runner that a user has shut down,
650    /// and that the user's lease can be terminated.
651    async fn user_finished(
652        &self,
653        req: &UserFinishedRequest,
654    ) -> Result<Empty, RunnerApiError>;
655}
656
657/// Defines the api that the backend exposes to the node.
658pub trait NodeBackendApi {
659    // --- Unauthenticated --- //
660
661    /// GET /node/v1/user [`UserPkStruct`] -> [`MaybeUser`]
662    async fn get_user(
663        &self,
664        user_pk: UserPk,
665    ) -> Result<MaybeUser, BackendApiError>;
666
667    /// GET /node/v1/sealed_seed [`SealedSeedId`] -> [`MaybeSealedSeed`]
668    async fn get_sealed_seed(
669        &self,
670        data: &SealedSeedId,
671    ) -> Result<MaybeSealedSeed, BackendApiError>;
672
673    // --- Bearer authentication required --- //
674
675    /// PUT /node/v1/sealed_seed [`SealedSeed`] -> [`Empty`]
676    ///
677    /// Idempotent: does nothing if the [`SealedSeedId`] already exists.
678    async fn create_sealed_seed(
679        &self,
680        data: &SealedSeed,
681        auth: BearerAuthToken,
682    ) -> Result<Empty, BackendApiError>;
683
684    /// Delete all sealed seeds which have the given measurement and the user_pk
685    /// of the authenticated user.
686    ///
687    /// DELETE /node/v1/sealed_seed [`MeasurementStruct`] -> [`Empty`]
688    async fn delete_sealed_seeds(
689        &self,
690        measurement: Measurement,
691        auth: BearerAuthToken,
692    ) -> Result<Empty, BackendApiError>;
693
694    /// GET /node/v1/scids [`Empty`] -> [`Scids`]
695    async fn get_scids(
696        &self,
697        auth: BearerAuthToken,
698    ) -> Result<Scids, BackendApiError>;
699
700    /// GET /node/v1/scid [`Empty`] -> [`MaybeScid`]
701    // NOTE: Keep this def around until we can remove the backend handler.
702    #[deprecated(note = "since lsp-v0.7.3: Use multi scid version instead")]
703    async fn get_scid(
704        &self,
705        auth: BearerAuthToken,
706    ) -> Result<MaybeScid, BackendApiError>;
707
708    /// GET /node/v1/file [`VfsFileId`] -> [`MaybeVfsFile`]
709    #[deprecated(note = "since node-v0.8.5: Use get_file instead")]
710    async fn get_file_v1(
711        &self,
712        file_id: &VfsFileId,
713        auth: BearerAuthToken,
714    ) -> Result<MaybeVfsFile, BackendApiError>;
715
716    /// GET /node/v2/file [`VfsFileId`] -> [`Bytes`] ([`VfsFile::data`])
717    async fn get_file(
718        &self,
719        file_id: &VfsFileId,
720        token: BearerAuthToken,
721    ) -> Result<Bytes, BackendApiError>;
722
723    /// POST /node/v1/file [`VfsFile`] -> [`Empty`]
724    #[deprecated(note = "since node-v0.8.5: Use create_file instead")]
725    async fn create_file_v1(
726        &self,
727        file: &VfsFile,
728        auth: BearerAuthToken,
729    ) -> Result<Empty, BackendApiError>;
730
731    /// POST /node/v2/file [`VfsFileId`] (query) + [`Bytes`] (body) -> [`Empty`]
732    async fn create_file(
733        &self,
734        file_id: &VfsFileId,
735        data: bytes::Bytes,
736        auth: BearerAuthToken,
737    ) -> Result<Empty, BackendApiError>;
738
739    /// PUT /node/v1/file [`VfsFile`] -> [`Empty`]
740    #[deprecated(note = "since node-v0.8.5: Use upsert_file instead")]
741    async fn upsert_file_v1(
742        &self,
743        file: &VfsFile,
744        auth: BearerAuthToken,
745    ) -> Result<Empty, BackendApiError>;
746
747    /// PUT /node/v2/file [`VfsFileId`] (query) + [`Bytes`] (body) -> [`Empty`]
748    async fn upsert_file(
749        &self,
750        file_id: &VfsFileId,
751        data: bytes::Bytes,
752        auth: BearerAuthToken,
753    ) -> Result<Empty, BackendApiError>;
754
755    /// DELETE /node/v1/file [`VfsFileId`] -> [`Empty`]
756    ///
757    /// Returns [`Ok`] only if exactly one row was deleted.
758    async fn delete_file(
759        &self,
760        file_id: &VfsFileId,
761        auth: BearerAuthToken,
762    ) -> Result<Empty, BackendApiError>;
763
764    /// GET /node/v1/directory [`VfsDirectory`] -> [`VecVfsFile`]
765    #[deprecated(note = "since node-v0.8.5: Use list_directory instead")]
766    async fn get_directory_v1(
767        &self,
768        dir: &VfsDirectory,
769        auth: BearerAuthToken,
770    ) -> Result<VecVfsFile, BackendApiError>;
771
772    /// GET /node/v2/directory [`VfsDirectory`] -> [`VecVfsFile`]
773    async fn list_directory(
774        &self,
775        dir: &VfsDirectory,
776        auth: BearerAuthToken,
777    ) -> Result<VfsDirectoryList, BackendApiError>;
778
779    /// GET /node/v1/payments [`PaymentCreatedIndexStruct`]
780    ///                    -> [`MaybeDbPaymentV1`]
781    #[deprecated(note = "since node-v0.8.8: Use get_payment_by_index instead")]
782    async fn get_payment_by_index_v1(
783        &self,
784        req: PaymentCreatedIndexStruct,
785        auth: BearerAuthToken,
786    ) -> Result<MaybeDbPaymentV1, BackendApiError>;
787
788    /// POST /node/v1/payments [`DbPaymentV1`] -> [`Empty`]
789    #[deprecated(note = "since node-v0.8.10: Use upsert_payment instead")]
790    async fn create_payment(
791        &self,
792        payment: DbPaymentV1,
793        auth: BearerAuthToken,
794    ) -> Result<Empty, BackendApiError>;
795
796    /// PUT /node/v1/payments [`DbPaymentV1`] -> [`Empty`]
797    #[deprecated(note = "since node-v0.8.8: Use upsert_payment instead")]
798    async fn upsert_payment_v1(
799        &self,
800        payment: DbPaymentV1,
801        auth: BearerAuthToken,
802    ) -> Result<Empty, BackendApiError>;
803
804    /// PUT /node/v2/payments [`DbPaymentV2`] -> [`Empty`]
805    async fn upsert_payment(
806        &self,
807        payment: DbPaymentV2,
808        auth: BearerAuthToken,
809    ) -> Result<Empty, BackendApiError>;
810
811    /// GET /node/v1/payments/id [`PaymentIdStruct`] -> [`MaybeDbPaymentV1`]
812    #[deprecated(note = "since node-v0.8.10: Use get_payment_by_id instead")]
813    async fn get_payment_by_id_v1(
814        &self,
815        req: PaymentIdStruct,
816        auth: BearerAuthToken,
817    ) -> Result<MaybeDbPaymentV1, BackendApiError>;
818
819    /// GET /node/v2/payments/id [`PaymentIdStruct`] -> [`MaybeDbPaymentV2`]
820    async fn get_payment_by_id(
821        &self,
822        req: PaymentIdStruct,
823        auth: BearerAuthToken,
824    ) -> Result<MaybeDbPaymentV2, BackendApiError>;
825
826    /// GET /node/v1/payments/index [`PaymentCreatedIndexStruct`]
827    ///                          -> [`MaybeDbPaymentV1`]
828    #[deprecated(note = "since node-v0.8.10: Use get_payment_by_id instead")]
829    async fn get_payment_by_index(
830        &self,
831        req: PaymentCreatedIndexStruct,
832        auth: BearerAuthToken,
833    ) -> Result<MaybeDbPaymentV1, BackendApiError>;
834
835    /// PUT /node/v1/payments/batch [`VecDbPaymentV1`] -> [`Empty`]
836    ///
837    /// ACID endpoint for upserting a batch of payments.
838    #[deprecated(note = "since node-v0.8.8: Use upsert_payment_batch instead")]
839    async fn upsert_payment_batch_v1(
840        &self,
841        payments: VecDbPaymentV1,
842        auth: BearerAuthToken,
843    ) -> Result<Empty, BackendApiError>;
844
845    /// PUT /node/v2/payments/batch [`VecDbPaymentV2`] -> [`Empty`]
846    ///
847    /// ACID endpoint for upserting a batch of payments.
848    async fn upsert_payment_batch(
849        &self,
850        payments: VecDbPaymentV2,
851        auth: BearerAuthToken,
852    ) -> Result<Empty, BackendApiError>;
853
854    /// POST /node/v1/payments/indexes [`PaymentCreatedIndexes`]
855    ///                             -> [`VecDbPaymentV1`]
856    ///
857    /// Fetch a batch of payments by their [`PaymentCreatedIndex`]s. This is
858    /// typically used by a mobile client to poll for updates on payments
859    /// which it currently has stored locally as "pending"; the intention is
860    /// to check if any of these payments have been updated.
861    //
862    // We use POST because there may be a lot of idxs, which might be too large
863    // to fit inside query parameters.
864    #[deprecated(note = "since node-v0.8.10: Use get_payments_by_ids instead")]
865    async fn get_payments_by_indexes(
866        &self,
867        req: PaymentCreatedIndexes,
868        auth: BearerAuthToken,
869    ) -> Result<VecDbPaymentV1, BackendApiError>;
870
871    /// POST /node/v1/payments/ids [`VecPaymentId`]
872    ///                         -> [`VecDbPaymentV2`]
873    ///
874    /// Fetch a batch of payments by their [`PaymentId`]s.
875    //
876    // We use POST because there may be a lot of ids,
877    // which might be too large to fit inside query params.
878    async fn get_payments_by_ids(
879        &self,
880        req: VecPaymentId,
881        auth: BearerAuthToken,
882    ) -> Result<VecDbPaymentV2, BackendApiError>;
883
884    /// GET /node/v1/payments/new [`GetNewPayments`] -> [`VecDbPaymentV1`]
885    ///
886    /// Sync a batch of new payments to local storage, optionally starting from
887    /// a known [`PaymentCreatedIndex`] (exclusive).
888    /// Results are in ascending order, by `(created_at, payment_id)`.
889    /// See [`GetNewPayments`] for more info.
890    #[deprecated(note = "since app-v0.8.9+29 and sdk-sidecar-v0.3.1: \
891                         Use get_updated_payments instead")]
892    // NOTE: This fn is used in the app->node handler for /app/payments/new, so
893    // the node->backend client code must remain until all app and sdk-sidecar
894    // clients have been updated.
895    async fn get_new_payments(
896        &self,
897        req: GetNewPayments,
898        auth: BearerAuthToken,
899    ) -> Result<VecDbPaymentV1, BackendApiError>;
900
901    /// GET /node/v1/payments/updated [`GetUpdatedPayments`]
902    ///                            -> [`VecDbPaymentV2`]
903    async fn get_updated_payments(
904        &self,
905        req: GetUpdatedPayments,
906        auth: BearerAuthToken,
907    ) -> Result<VecDbPaymentV2, BackendApiError>;
908
909    /// GET /node/v1/payments/pending -> [`VecDbPaymentV1`]
910    ///
911    /// Fetches all pending payments.
912    #[deprecated(note = "since node-v0.8.10: Use get_pending_payments instead")]
913    async fn get_pending_payments_v1(
914        &self,
915        auth: BearerAuthToken,
916    ) -> Result<VecDbPaymentV1, BackendApiError>;
917
918    /// GET /node/v2/payments/pending -> [`VecDbPaymentV2`]
919    ///
920    /// Fetches all pending payments.
921    async fn get_pending_payments(
922        &self,
923        auth: BearerAuthToken,
924    ) -> Result<VecDbPaymentV2, BackendApiError>;
925
926    /// GET /node/v1/payments/final -> [`VecPaymentId`]
927    ///
928    /// Fetches the IDs of all finalized payments.
929    #[deprecated(note = "since node-v0.8.8")]
930    async fn get_finalized_payment_ids(
931        &self,
932        auth: BearerAuthToken,
933    ) -> Result<VecPaymentId, BackendApiError>;
934
935    /// PUT /node/v1/payments/metadata [`DbPaymentMetadata`] -> [`Empty`]
936    async fn upsert_payment_metadata(
937        &self,
938        metadata: DbPaymentMetadata,
939        auth: BearerAuthToken,
940    ) -> Result<Empty, BackendApiError>;
941
942    /// PUT /node/v1/payments/metadata/batch [`VecDbPaymentMetadata`]
943    ///                                   -> [`Empty`]
944    ///
945    /// ACID endpoint for upserting a batch of payments metadata.
946    async fn upsert_payment_metadata_batch(
947        &self,
948        payments: VecDbPaymentMetadata,
949        auth: BearerAuthToken,
950    ) -> Result<Empty, BackendApiError>;
951
952    /// GET /node/v1/payments/metadata/id [`PaymentIdStruct`]
953    ///                                -> [`MaybeDbPaymentMetadata`]
954    ///
955    /// Fetch a payment metadata by its [`PaymentId`].
956    async fn get_payment_metadata_by_id(
957        &self,
958        req: PaymentIdStruct,
959        token: BearerAuthToken,
960    ) -> Result<MaybeDbPaymentMetadata, BackendApiError>;
961
962    /// POST /node/v1/payments/metadata/ids [`VecPaymentId`]
963    ///                                  -> [`VecDbPaymentMetadata`]
964    ///
965    /// Fetch a batch of payment metadata by their [`PaymentId`]s.
966    //
967    // We use POST because there may be a lot of ids,
968    // which might be too large to fit inside query params.
969    async fn get_payment_metadata_by_ids(
970        &self,
971        req: VecPaymentId,
972        token: BearerAuthToken,
973    ) -> Result<VecDbPaymentMetadata, BackendApiError>;
974
975    /// GET /node/v1/payments/metadata/updated [`GetUpdatedPaymentMetadata`]
976    ///                                     -> [`VecDbPaymentMetadata`]
977    ///
978    /// Get a batch of payment metadata in asc `(updated_at, payment_id)` order.
979    async fn get_updated_payment_metadata(
980        &self,
981        req: GetUpdatedPaymentMetadata,
982        auth: BearerAuthToken,
983    ) -> Result<VecDbPaymentMetadata, BackendApiError>;
984
985    /// GET /node/v2/human_bitcoin_address [`Empty`]
986    ///                                 -> [`GetHumanBitcoinAddressResponse`]
987    ///
988    /// Fetches the node's **active** Human Bitcoin Address: their primary
989    /// custom HBA if present, otherwise generated fallback, otherwise None.
990    async fn get_human_bitcoin_address(
991        &self,
992        auth: BearerAuthToken,
993    ) -> Result<GetHumanBitcoinAddressResponse, BackendApiError>;
994
995    /// GET /node/v1/human_bitcoin_address [`Empty`]
996    ///                                 -> [`HumanBitcoinAddressV1`]
997    #[deprecated(note = "since node-v0.9.7: \
998                         Use get_human_bitcoin_address instead")]
999    async fn get_human_bitcoin_address_v1(
1000        &self,
1001        auth: BearerAuthToken,
1002    ) -> Result<HumanBitcoinAddressV1, BackendApiError>;
1003
1004    /// GET /node/v1/payment_address [`Empty`] -> [`HumanBitcoinAddressV1`]
1005    #[deprecated(note = "since node-v0.9.3: \
1006                         Use get_human_bitcoin_address_v1 instead")]
1007    async fn get_payment_address_v1(
1008        &self,
1009        auth: BearerAuthToken,
1010    ) -> Result<HumanBitcoinAddressV1, BackendApiError>;
1011
1012    /// PUT /node/v2/human_bitcoin_address [`UpsertCustomHumanBitcoinAddress`]
1013    ///                                 -> [`UpsertHumanBitcoinAddressResponse`]
1014    ///
1015    /// Upserts the user's custom human Bitcoin address (username and offer).
1016    async fn upsert_custom_human_bitcoin_address(
1017        &self,
1018        req: UpsertCustomHumanBitcoinAddress,
1019        auth: BearerAuthToken,
1020    ) -> Result<UpsertHumanBitcoinAddressResponse, BackendApiError>;
1021
1022    /// PUT /node/v1/human_bitcoin_address [`UpsertCustomHumanBitcoinAddress`]
1023    ///                                 -> [`HumanBitcoinAddressV1`]
1024    #[deprecated(note = "since node-v0.9.7: \
1025                         Use upsert_custom_human_bitcoin_address instead")]
1026    async fn update_human_bitcoin_address_v1(
1027        &self,
1028        req: UpsertCustomHumanBitcoinAddress,
1029        auth: BearerAuthToken,
1030    ) -> Result<HumanBitcoinAddressV1, BackendApiError>;
1031
1032    /// PUT /node/v1/payment_address [`UpsertCustomHumanBitcoinAddress`]
1033    ///                           -> [`HumanBitcoinAddressV1`]
1034    #[deprecated(note = "since node-v0.9.3: \
1035                         Use update_human_bitcoin_address_v1 instead")]
1036    async fn update_payment_address_v1(
1037        &self,
1038        req: UpsertCustomHumanBitcoinAddress,
1039        auth: BearerAuthToken,
1040    ) -> Result<HumanBitcoinAddressV1, BackendApiError>;
1041
1042    /// POST /node/v1/claim_generated_human_bitcoin_address
1043    ///   [`ClaimGeneratedHumanBitcoinAddress`] -> [`Empty`]
1044    ///
1045    /// Claims a generated human Bitcoin address for the given node.
1046    async fn claim_generated_human_bitcoin_address(
1047        &self,
1048        req: ClaimGeneratedHumanBitcoinAddress,
1049        auth: BearerAuthToken,
1050    ) -> Result<Empty, BackendApiError>;
1051
1052    /// POST /node/v1/claim_generated_payment_address
1053    ///   [`ClaimGeneratedHumanBitcoinAddress`] -> [`Empty`]
1054    #[deprecated(note = "since node-v0.9.3: \
1055                         Use claim_generated_human_bitcoin_address instead")]
1056    async fn claim_generated_payment_address(
1057        &self,
1058        req: ClaimGeneratedHumanBitcoinAddress,
1059        auth: BearerAuthToken,
1060    ) -> Result<Empty, BackendApiError> {
1061        self.claim_generated_human_bitcoin_address(req, auth).await
1062    }
1063
1064    /// GET /node/v1/generated_username [`Empty`]
1065    ///                              -> [`GetGeneratedUsernameResponse`]
1066    ///
1067    /// Generates an available username for the authenticated user without
1068    /// storing it. The username is derived deterministically from the
1069    /// user's `user_pk`, with collision handling via numeric suffixes.
1070    async fn get_generated_username(
1071        &self,
1072        auth: BearerAuthToken,
1073    ) -> Result<GetGeneratedUsernameResponse, BackendApiError>;
1074
1075    /// GET /node/v1/nwc_clients [`Empty`] -> [`VecDbNwcClient`]
1076    ///
1077    /// Fetches the node's NWC clients and optionally filters by
1078    /// client_nostr_pk.
1079    async fn get_nwc_clients(
1080        &self,
1081        req: GetNwcClients,
1082        auth: BearerAuthToken,
1083    ) -> Result<VecDbNwcClient, BackendApiError>;
1084
1085    /// PUT /node/v1/nwc_clients [`DbNwcClientFields`] -> [`DbNwcClient`]
1086    ///
1087    /// Upserts a NWC client in the database.
1088    async fn upsert_nwc_client(
1089        &self,
1090        req: DbNwcClientFields,
1091        auth: BearerAuthToken,
1092    ) -> Result<DbNwcClient, BackendApiError>;
1093
1094    /// DELETE /node/v1/nwc_clients [`NostrPkStruct`] -> [`Empty`]
1095    ///
1096    /// Deletes a NWC client given its nostr client public key.
1097    async fn delete_nwc_client(
1098        &self,
1099        req: NostrPkStruct,
1100        auth: BearerAuthToken,
1101    ) -> Result<Empty, BackendApiError>;
1102}
1103
1104/// Defines the api that the LSP exposes to user nodes.
1105pub trait NodeLspApi {
1106    /// GET /node/v1/scids [`GetNewScidsRequest`] -> [`Scids`]
1107    async fn get_new_scids(
1108        &self,
1109        req: &GetNewScidsRequest,
1110    ) -> Result<Scids, LspApiError>;
1111
1112    /// GET /node/v1/network_graph [`Empty`] -> [`Bytes`] (LDK-serialized graph)
1113    ///
1114    /// Introduced in node-v0.6.8 and lsp-v0.6.29.
1115    async fn get_network_graph(&self) -> Result<Bytes, LspApiError>;
1116
1117    /// GET /node/v1/prob_scorer [`Empty`]
1118    ///                       -> [`Bytes`] (LDK-serialized probabilistic scorer)
1119    ///
1120    /// Introduced in node-v0.6.17 and lsp-v0.6.33.
1121    async fn get_prob_scorer(&self) -> Result<Bytes, LspApiError>;
1122
1123    /// POST /node/v2/payment_path [`Bytes`] (LDK-serialized [`Event`])
1124    ///                         -> [`Empty`]
1125    ///
1126    /// Sends an anonymized successful or failed payment path to the LSP to
1127    /// update Lexe's shared network graph and improve payment reliability.
1128    ///
1129    /// Originally introduced in node-v0.6.17 and lsp-v0.6.33. All node-v0.9.5
1130    /// and older have a subtle bug in how they anonymize payment paths, so
1131    /// we now ignore all payment path feedback from <=node-v0.9.5
1132    async fn payment_path(&self, event: &Event) -> Result<Empty, LspApiError>;
1133}
1134
1135/// Defines the api that the runner exposes to the user node.
1136pub trait NodeRunnerApi {
1137    /// POST /node/renew_lease [`UserLeaseRenewalRequest`] -> [`Empty`]
1138    ///
1139    /// Renew's a user node's lease with the megarunner.
1140    async fn renew_lease(
1141        &self,
1142        req: &UserLeaseRenewalRequest,
1143    ) -> Result<Empty, RunnerApiError>;
1144
1145    /// POST /node/sync_success [`UserPkStruct`] -> [`Empty`]
1146    ///
1147    /// Indicates the node successfully completed sync.
1148    async fn sync_succ(&self, user_pk: UserPk)
1149    -> Result<Empty, RunnerApiError>;
1150}
1151
1152/// Defines the api that the gateway exposes to the internet.
1153pub trait PublicGatewayApi {
1154    /// Get the LNURL pay request message, if any username has been set.
1155    /// Uses lnurl_callback endpoint as the callback.
1156    ///
1157    /// GET /.well-known/lnurlp/{username}
1158    async fn get_lnurl_pay_request(
1159        &self,
1160    ) -> Result<LnurlPayRequestWire, LnurlError>;
1161
1162    /// Resolves the invoice given a LNURL pay request previously generated.
1163    /// Ciphertext is a base64 encoded string of the username and
1164    /// other metadata information.
1165    ///
1166    /// GET /public/v1/lnurl_callback/{encoded_params}
1167    async fn lnurl_callback(
1168        &self,
1169        req: LnurlCallbackRequest,
1170    ) -> Result<LnurlCallbackResponse, LnurlError>;
1171}