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}