![]()
@@ -141,6 +158,9 @@ const alt =
padding: 4vmin;
background: rgba(0, 0, 0, 0.8);
cursor: zoom-out;
+ /* Programmatically focused on open for keyboard/SR users; the full-screen
+ backdrop outline would look like a bug, so suppress it. */
+ outline: none;
}
.async-payments-lightbox img {
diff --git a/docs/async-payments.md b/docs/async-payments.md
index 9377d669..e94da8bd 100644
--- a/docs/async-payments.md
+++ b/docs/async-payments.md
@@ -12,23 +12,23 @@ This guide covers how to enable async payments in your application. For the prot
## Integrating Async Payments
-LDK handles the async offer machinery transparently once your node is configured for the appropriate role. The configuration differs depending on whether your node is an always-online participant, an often-offline sender or receiver, or the always-online LSP and static-invoice server that supports offline recipients.
+LDK handles the async offer machinery transparently once your node is configured for the appropriate role. The configuration differs depending on whether your node is an always-online participant, an often-offline sender or receiver, or the always-online LSP and static invoice server that supports offline recipients.
-### Always-online sender or receiver
+### Always-Online Sender or Receiver
If your node is reliably online, no special configuration is required. Pay an offer with [`ChannelManager::pay_for_offer`](https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManager.html#method.pay_for_offer); async offers are handled transparently.
-### Often-offline sender or receiver
+### Often-Offline Sender or Receiver
For a node that is frequently offline, such as a mobile wallet:
1. Set [`UserConfig::enable_htlc_hold`](https://docs.rs/lightning/*/lightning/util/config/struct.UserConfig.html) to `true`.
-2. Obtain blinded paths to your static-invoice server out-of-band from the LSP (see [Acting as an LSP](#acting-as-an-lsp-static-invoice-server) below).
+2. Obtain blinded paths to your static invoice server out-of-band from the LSP (see [Acting as an LSP](#acting-as-an-lsp-static-invoice-server) below).
3. Register those paths with `ChannelManager::set_paths_to_static_invoice_server`.
4. When sharing an offer with a sender, obtain it from `ChannelManager::get_async_receive_offer`.
5. Pay offers with [`ChannelManager::pay_for_offer`](https://docs.rs/lightning/*/lightning/ln/channelmanager/struct.ChannelManager.html#method.pay_for_offer); async offers are handled transparently.
-### Acting as an LSP / static-invoice server
+### Acting as an LSP / Static Invoice Server
An always-online node that serves offline recipients acts as both an onion message mailbox and a store for static invoices:
@@ -36,7 +36,7 @@ An always-online node that serves offline recipients acts as both an onion messa
2. Initialize the onion messenger with `OnionMessenger::new_with_offline_peer_interception` so that messages destined for offline peers can be held.
3. Generate blinded paths for each recipient with `ChannelManager::blinded_paths_for_async_recipient` and deliver them to the recipient out-of-band.
4. Act as an onion message mailbox by handling `Event::OnionMessageIntercepted` and `Event::OnionMessagePeerConnected`: buffer messages for offline peers, and flush them when the peer reconnects.
-5. Persist static invoices by handling `Event::PersistStaticInvoice`. Store the provided invoice and blinded path keyed by `(recipient_id, invoice_slot)`, then call `ChannelManager::static_invoice_persisted` with the supplied path.
+5. Persist static invoices by handling `Event::PersistStaticInvoice`. Store the provided invoice and its `invoice_request_path` keyed by `(recipient_id, invoice_slot)`, then call `ChannelManager::static_invoice_persisted` with the supplied `invoice_persisted_path`.
6. Serve invoice requests by handling `Event::StaticInvoiceRequested`. Look up the persisted invoice and reply with `ChannelManager::respond_to_static_invoice_request`.
For a complete reference on the events referenced above, see the [`Event` documentation](https://docs.rs/lightning/*/lightning/events/enum.Event.html). For details on configuring and constructing the `ChannelManager`, see [Setting up a ChannelManager](/building-a-node-with-ldk/setting-up-a-channel-manager).
diff --git a/docs/blog/async-payments-receiving-while-offline.md b/docs/blog/async-payments-receiving-while-offline.md
index 80acc994..36bd3a7d 100644
--- a/docs/blog/async-payments-receiving-while-offline.md
+++ b/docs/blog/async-payments-receiving-while-offline.md
@@ -1,10 +1,10 @@
---
title: "Async Payments: Getting Paid While Your Node Is Offline"
description: "Async payments let an often-offline node receive Lightning payments without trusting a custodian and without locking up network capacity with long-lived HTLCs."
-date: "2026-06-23"
+date: "2026-06-26"
authors:
- - Matt Corallo
- Valentine Wallace
+ - Conor Okus
tags:
- async payments
- offers
@@ -17,6 +17,10 @@ That assumption breaks down for one of the most common things people want to do
This post describes the async payments protocol, which LDK implements to allow an often-offline node to receive payments without trusting a third party to custody funds, and without anyone encumbering network capacity with long-lived HTLCs.
+::: warning Beta
+Async payments are still under active development and not yet recommended for production use. Parts of the sender-side flow described below have not yet been merged, and the flow currently works LDK-to-LDK only. See the [implementation guide](/async-payments) for the current status.
+:::
+
## Existing Approaches and Their Limitations
Before async payments, several techniques made partial progress toward offline receiving. Each is useful in its own context, but none fully solves the problem:
@@ -37,13 +41,13 @@ A payment then proceeds roughly as follows:
1. **The sender fetches a static invoice.** The sender requests a static invoice from the recipient's invoice server. The absence of a payment hash signals that the recipient sits behind an LSP and is rarely online, so the sender knows to use the async flow.
-2. **The sender locks in the HTLC with its own LSP.** The sender forwards an HTLC with a long CLTV timeout to its own LSP, with instructions to hold it: "when you receive an onion message containing secret B, release this HTLC; until then, hold it." The sender's LSP accepts the HTLC but does not forward it. The long CLTV is acceptable here because these are the sender's own funds; if the sender chooses to encumber their own balance, no one else is affected. A sender that is reliably online can skip this step.
+2. **The sender locks in the HTLC with its own LSP.** The sender forwards an HTLC with a long CLTV timeout to its own LSP, with instructions to hold it: "when you receive an onion message containing the release secret, release this HTLC; until then, hold it." The sender's LSP accepts the HTLC but does not forward it. The long CLTV is acceptable here because these are the sender's own funds; if the sender chooses to encumber their own balance, no one else is affected. A sender that is reliably online can skip this step.
-3. **The sender notifies the recipient.** The sender transmits an onion message to the recipient: "when you next come online, use the included reply path to send secret B to my LSP." The recipient's LSP holds this message until the recipient connects. At this point the sender can safely go offline.
+3. **The sender notifies the recipient.** The sender transmits an onion message to the recipient: "when you next come online, use the included reply path to send the release secret to my LSP." The recipient's LSP holds this message until the recipient connects. At this point the sender can safely go offline.
-4. **The recipient comes online and replies.** When the recipient reconnects, their LSP delivers the held onion message. The recipient follows the reply path and sends secret B to the sender's LSP.
+4. **The recipient comes online and replies.** When the recipient reconnects, their LSP delivers the held onion message. The recipient follows the reply path and sends the release secret to the sender's LSP.
-5. **The HTLC is released.** Receiving secret B prompts the sender's LSP to forward the original HTLC, which travels the route and is received by the recipient.
+5. **The HTLC is released.** Receiving the release secret prompts the sender's LSP to forward the original HTLC, which travels the route and is received by the recipient.
@@ -57,6 +61,6 @@ When the route the sender originally selected has gone stale by the time the rec
- **Stale routes.** If the route the sender used when locking in the HTLC is no longer viable by the time the recipient returns, the sender's LSP finds a new route. This is what makes step 2 safe to perform immediately rather than waiting for the recipient.
- **The recipient never returns.** This behaves exactly as a normal Lightning payment does today. If any node on the route is offline long enough that the payment approaches its expiry, the HTLC is failed backwards to the sender.
-## Integrating it into your app
+## Integrating It Into Your App
-LDK handles the async offer machinery transparently once your node is configured for the appropriate role, whether it is an always-online participant, an often-offline sender or receiver, or the always-online LSP and static-invoice server that supports offline recipients. For step-by-step configuration, see the [Async Payments guide](/async-payments).
+LDK handles the async offer machinery transparently once your node is configured for the appropriate role, whether it is an always-online participant, an often-offline sender or receiver, or the always-online LSP and static invoice server that supports offline recipients. For step-by-step configuration, see the [Async Payments guide](/async-payments).