Skip to content

Commit 22d1021

Browse files
Add API to retrieve cached async receive offers
Over the past several commits we've implemented interactively building an async receive offer with a static invoice server that will service invoice requests on our behalf as an async recipient. Here we add an API to retrieve the resulting offers so we can receive payments when we're offline.
1 parent 5010109 commit 22d1021

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10749,9 +10749,23 @@ where
1074910749
#[cfg(c_bindings)]
1075010750
create_refund_builder!(self, RefundMaybeWithDerivedMetadataBuilder);
1075110751

10752+
/// Retrieve our cached [`Offer`]s for receiving async payments as an often-offline recipient.
10753+
/// Will only be set if [`UserConfig::paths_to_static_invoice_server`] is set and we succeeded in
10754+
/// interactively building a [`StaticInvoice`] with the static invoice server.
10755+
///
10756+
/// Useful for posting offers to receive payments later, such as posting an offer on a website.
10757+
#[cfg(async_payments)]
10758+
pub fn get_cached_async_receive_offers(&self) -> Vec<Offer> {
10759+
self.flow.get_cached_async_receive_offers()
10760+
}
10761+
1075210762
/// Create an offer for receiving async payments as an often-offline recipient.
1075310763
///
10754-
/// Because we may be offline when the payer attempts to request an invoice, you MUST:
10764+
/// Instead of using this method, it is preferable to set
10765+
/// [`UserConfig::paths_to_static_invoice_server`] and retrieve the automatically built offer via
10766+
/// [`Self::get_cached_async_receive_offers`].
10767+
///
10768+
/// If you want to build the [`StaticInvoice`] manually using this method instead, you MUST:
1075510769
/// 1. Provide at least 1 [`BlindedMessagePath`] terminating at an always-online node that will
1075610770
/// serve the [`StaticInvoice`] created from this offer on our behalf.
1075710771
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
@@ -10768,6 +10782,10 @@ where
1076810782
/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
1076910783
/// created via [`Self::create_async_receive_offer_builder`]. If `relative_expiry` is unset, the
1077010784
/// invoice's expiry will default to [`STATIC_INVOICE_DEFAULT_RELATIVE_EXPIRY`].
10785+
///
10786+
/// Instead of using this method to manually build the invoice, it is preferable to set
10787+
/// [`UserConfig::paths_to_static_invoice_server`] and retrieve the automatically built offer via
10788+
/// [`Self::get_cached_async_receive_offers`].
1077110789
#[cfg(async_payments)]
1077210790
pub fn create_static_invoice_builder<'a>(
1077310791
&self, offer: &'a Offer, offer_nonce: Nonce, relative_expiry: Option<Duration>,

lightning/src/offers/async_receive_offer_cache.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,26 @@ const MIN_OFFER_PATHS_RELATIVE_EXPIRY_SECS: u64 = 3 * 30 * 24 * 60 * 60;
176176

177177
#[cfg(async_payments)]
178178
impl AsyncReceiveOfferCache {
179+
/// Retrieve our cached [`Offer`]s for receiving async payments as an often-offline recipient.
180+
pub fn offers(&self, duration_since_epoch: Duration) -> Vec<Offer> {
181+
const NEVER_EXPIRES: Duration = Duration::from_secs(u64::MAX);
182+
183+
self.offers
184+
.iter()
185+
.filter_map(|offer| {
186+
if offer.static_invoice_absolute_expiry < duration_since_epoch {
187+
None
188+
} else if offer.offer.absolute_expiry().unwrap_or(NEVER_EXPIRES)
189+
< duration_since_epoch
190+
{
191+
None
192+
} else {
193+
Some(offer.offer.clone())
194+
}
195+
})
196+
.collect()
197+
}
198+
179199
/// Remove expired offers from the cache, returning whether new offers are needed.
180200
pub(super) fn prune_expired_offers(
181201
&mut self, duration_since_epoch: Duration, timer_tick_occurred: bool,

lightning/src/offers/flow.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,14 @@ where
11281128
core::mem::take(&mut self.pending_dns_onion_messages.lock().unwrap())
11291129
}
11301130

1131+
/// Retrieve our cached [`Offer`]s for receiving async payments as an often-offline recipient.
1132+
/// Will only be set if [`UserConfig::paths_to_static_invoice_server`] is set and we succeeded in
1133+
/// interactively building a [`StaticInvoice`] with the static invoice server.
1134+
#[cfg(async_payments)]
1135+
pub(crate) fn get_cached_async_receive_offers(&self) -> Vec<Offer> {
1136+
self.async_receive_offer_cache.lock().unwrap().offers(self.duration_since_epoch())
1137+
}
1138+
11311139
/// Sends out [`OfferPathsRequest`] and [`ServeStaticInvoice`] onion messages if we are an
11321140
/// often-offline recipient and are configured to interactively build offers and static invoices
11331141
/// with a static invoice server.

0 commit comments

Comments
 (0)