docs: add Section 7 — Wallet and Payment Processor Requirements#23
Open
refined-element wants to merge 1 commit into
Open
docs: add Section 7 — Wallet and Payment Processor Requirements#23refined-element wants to merge 1 commit into
refined-element wants to merge 1 commit into
Conversation
Add a new top-level Section 7 to protocol-specification.md addressing a
compatibility gap when underlying Lightning settlement bypasses HTLC
routing (e.g. same-custodian internal account transfers).
Three normative requirements:
1. Wallets/processors MUST surface the preimage to the client for any
settled invoice, regardless of settlement path (HTLC routing or
internal accounting).
2. Omitting the preimage on the payment-confirmation response for an
internally-settled invoice SHOULD be considered non-compliant.
3. Wallets/processors MUST NOT release the preimage prior to invoice
settlement; this preserves the implicit binding the server's
stateless H == sha256(r) check relies on.
The section is protocol-agnostic (HTTP and gRPC). Sections 7-11 renumber
to 8-12 to accommodate. No internal cross-references break (existing
references point at Sections 5.x and 6.x, which are unchanged).
There was a problem hiding this comment.
Pull request overview
Adds a new top-level specification section defining normative wallet/payment-processor behavior required for L402 to work when Lightning settlement occurs via internal custodial accounting (i.e., no HTLC route to propagate the preimage). This closes a compatibility gap where an invoice can be paid but the client cannot obtain the preimage needed to form an L402 credential.
Changes:
- Introduces Section 7: Wallet and Payment Processor Requirements, including MUST/MUST NOT requirements around preimage surfacing and settlement ordering.
- Renumbers the existing sections (gRPC flow and onward) from 7–11 to 8–12.
- Updates the affected heading/subheading numbers to match the new section ordering.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+271
to
+275
| 2. A wallet or payment processor that omits `r` from the payment-confirmation | ||
| response for an internally-settled invoice SHOULD be considered | ||
| non-compliant with this specification for L402 authentication purposes, | ||
| since the client cannot construct a valid `Authorization` header without | ||
| `r`. |
|
@refined-element, remember to re-request review from reviewers when ready |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new top-level Section 7, "Wallet and Payment Processor Requirements," to
protocol-specification.md, addressing a compatibility gap when the underlying Lightning settlement bypasses HTLC routing. Renumbers existing Sections 7–11 to 8–12 to accommodate.Motivation
L402's proof-of-payment chain depends on the client obtaining the payment preimage
rafter invoice settlement. In typical Lightning Network routing,rpropagates back to the client's wallet through the HTLC settlement chain — no normative wallet behavior is required for L402 to work.However, when both the payee and payer are hosted by the same custodial Lightning service, that service may settle the payment internally — crediting the payee's account and debiting the payer's account without routing the payment over the Lightning Network. In this scenario:
ris generated at invoice creation by the custodian and sits in their database.ris never propagated to the client through Lightning protocol mechanisms.If the custodian's payer-facing API does not surface
rafter settlement, the client has no preimage to present in the L402Authorizationheader, even though the invoice is fully paid. The proof chain is broken: the merchant has the funds, the buyer can't construct a valid L402 token, and the resource access is denied.This has been observed in production with at least one major custodial Lightning provider whose own developer documentation explicitly describes the optimization (same-currency-region same-app payments executed as internal account transfers, "instant and incurs no routing or on-chain fees") but does not document preimage availability on the payer side. The optimization is intentional and arguably correct from a custodial UX perspective; the L402 incompatibility is collateral damage of a design decision that makes sense in every other respect.
The spec-evolution path is one of several ways to close this gap (others include BOLT12 with blinded paths, which would force real routing by hiding the destination from the payer's wallet, and a vendor opt-in flag forcing real routing per invoice). These approaches are complements, not alternatives. This PR addresses the spec-evolution path: making preimage availability a wallet/processor requirement so the custodian-side fix becomes unambiguous expected behavior rather than a per-integrator request.
What this PR adds
A new Section 7 "Wallet and Payment Processor Requirements" with three normative bullets:
A wallet or payment processor MUST surface the payment preimage
rto the client for any settled invoice, regardless of whether settlement occurred via HTLC routing or via internal accounting on a single custodial service.A wallet or payment processor that omits
rfrom the payment-confirmation response for an internally-settled invoice SHOULD be considered non-compliant with this specification for L402 authentication purposes.A wallet or payment processor MUST NOT release the preimage
rto the client prior to settlement of the corresponding invoice. In standard Lightning routing this is enforced by the HTLC protocol; in internal-settlement implementations it MUST be enforced by the wallet or payment processor's accounting logic. The L402 server's statelessH == sha256(r)check (Section 6.1) assumes that possession ofrby the client implies the invoice has been settled.The third bullet is included to make explicit the implicit binding between preimage possession and settlement that the protocol's stateless verification relies on. In the standard HTLC path this is enforced cryptographically by Lightning itself; in the internal-settlement path it has to be enforced by the wallet or payment processor's accounting logic. Without this requirement, a wallet could naively interpret bullet 1 as "release the preimage at invoice creation" and break the L402 server's stateless verification model.
The section explicitly notes that these requirements apply protocol-agnostically — to the HTTP flow (Section 6) and the gRPC flow (Section 8) equally — and that they impose no requirement on the underlying Lightning settlement path. Only what the wallet or payment processor surfaces to the client after settlement is constrained.
Why a new top-level section
Wallets and payment processors are a third actor in the L402 protocol, alongside the server (Section 6.1) and the client (Section 6.2). Their obligation is protocol-agnostic. Placing the requirement as a subsection under "HTTP Protocol Flow" (Section 6) would imply HTTP-specific scope, which is incorrect. A new top-level section preserves structural parity and makes the wallet/processor obligation discoverable.
If the structural placement is the wrong call, happy to revise — could go as a subsection 6.3 with a one-line cross-reference from the gRPC section.
What this PR does NOT change
Renumbering
Sections 7 through 11 of the prior version shift to 8 through 12 in this PR:
Subsection numbering shifts accordingly (e.g., 9.1 → 10.1). All internal cross-references within the document remain accurate — every existing
Section N.Mreference points to Section 5.x or Section 6.x, both of which are unchanged.Acknowledgments
Thanks to Hannah at Lightning Labs DevRel for the pointer to this repo as the right place to land this contribution and for the framing pushback that sharpened the proposed addition. The "implementation issue, not a protocol break" framing is hers; this PR closes the spec gap so that the implementation expectation is normatively explicit.