Skip to content

Async Payments

Async payments let an often-offline node — typically a mobile wallet — receive Lightning payments without keeping an app open in the foreground, without trusting a third party to custody funds, and without anyone encumbering network capacity with long-lived HTLCs.

Beta

Async payments are still under active development and are not yet recommended for production use. In particular, the sender-side HTLC hold — extending CLTVs so the sender's LSP can hold the payment until the recipient comes online (step 2, "Lock the payment on hold") — has not yet been merged. The flow currently works LDK-to-LDK only; interoperability with other Lightning implementations is not yet guaranteed, and the APIs described below may change before the feature is complete.

This guide covers how to enable async payments in your application. For the protocol background, the existing approaches it improves on, and the design rationale, see the blog post Async Payments: Getting Paid While Your Node Is Offline.

Sequence diagram of an async Lightning payment from sender to an often-offline recipient via their LSPs.Sequence diagram of an async Lightning payment from sender to an often-offline recipient via their LSPs.
How an async payment flows from sender to an often-offline recipient via their LSPs.

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.

Always-Online Sender or Receiver

If your node is reliably online, no special configuration is required. Pay an offer with ChannelManager::pay_for_offer; async offers are handled transparently.

Often-Offline Sender or Receiver

For a node that is frequently offline, such as a mobile wallet:

  1. Set UserConfig::enable_htlc_hold to true.
  2. Obtain blinded paths to your static invoice server out-of-band from the LSP (see Acting as an LSP 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; async offers are handled transparently.

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:

  1. Set UserConfig::enable_htlc_hold to true.
  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 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. For details on configuring and constructing the ChannelManager, see Setting up a ChannelManager.