Skip to content

Add L402 discovery awareness - #25

Open
Roasbeef wants to merge 4 commits into
mainfrom
l402-discovery
Open

Add L402 discovery awareness#25
Roasbeef wants to merge 4 commits into
mainfrom
l402-discovery

Conversation

@Roasbeef

Copy link
Copy Markdown
Member

In this PR, we teach lnget about L402 discovery, the client side of the layer
specified in lightninglabs/L402#27
and served by aperture#241.
Until now lnget only learned what a resource cost by hitting it and getting a 402
back. Now it can fetch a provider's manifest, see the catalog and prices ahead of
time, and request a quote for a specific bundle, all without paying.

The new discovery package fetches the manifest from the well-known path,
falling back to a Link: rel="l402-manifest" header, and parses both profiles:
the bespoke JSON and the self-describing OpenAPI document with its x-l402-*
extensions, into one common shape. A formula price can be computed locally from
the manifest.

Verify before you pay

The interesting part is the quote path. A quote response is an ordinary L402
challenge minted for a bundle the client chose, and lnget verifies it before
paying. We decode the returned BOLT 11 invoice in-process with zpay32, no node
round trip, and confirm the macaroon commits to the invoice's payment hash, that
its caveats grant at least the bundle we asked for, that the amount is within the
configured max cost, and that it pays the provider's advertised node. A quote
that fails any of these is rejected, so a buggy or hostile provider can't take
payment for a credential that doesn't grant what we requested.

Surfaces

Discovery lives in the shared service layer (Discover and Quote), so the CLI
and MCP server expose it through one code path. The CLI gains a discover
command with manifest and quote subcommands, both with JSON output for
agents. The MCP server gains discover and quote tools. Paying a quote still
goes through the existing flow; this PR is about awareness and verification.

The discovery package ships with unit tests covering both manifest profiles,
the well-known and Link-header fetch paths, the quote request and error
handling, in-process invoice decoding, and the full pre-pay verification against
a generated invoice whose payment hash we control.

OpenAPI parsing here is JSON-only (the common case for a served openapi.json);
both the bespoke and OpenAPI profiles are covered.

Roasbeef added 4 commits June 9, 2026 19:32
In this commit, we add the client side of the L402 discovery layer. The new
package fetches a provider's manifest from the well-known path (falling back to
a Link header), and parses both profiles: the bespoke JSON and the
self-describing OpenAPI document with its x-l402-* extensions, into one common
shape. A formula price can be computed locally from the manifest.

It also requests quotes and, crucially, verifies them before the client pays.
We decode the returned BOLT 11 invoice in-process with zpay32 (no node round
trip) and confirm the macaroon commits to the invoice's payment hash, that its
caveats grant at least the requested bundle, that the amount fits the budget,
and that it pays the expected node. A quote that fails any check is rejected, so
a buggy or hostile provider cannot take payment for a credential that does not
grant what was asked.
In this commit, we add Discover and Quote to the shared service layer so the
CLI and MCP server expose discovery through one code path. Discover fetches and
parses the manifest; Quote resolves the quote endpoint, posts the bundle, and
runs the pre-pay verification using the client's configured max cost and the
provider's advertised node pubkey.
In this commit, we add the discover command with manifest and quote
subcommands. "lnget discover manifest <url>" shows what a provider offers and
how it prices things; "lnget discover quote <url> --service ..." proposes a
bundle and returns a verified, ready-to-pay challenge. Both work without paying,
and support JSON output for agents.
In this commit, we expose discovery to agents as two MCP tools. discover returns
a provider's manifest; quote proposes a bundle and returns a challenge that is
verified before it is handed back. Both delegate to the shared service layer.
@claude

claude Bot commented Jun 10, 2026

Copy link
Copy Markdown

test

@claude

claude Bot commented Jun 10, 2026

Copy link
Copy Markdown

Code Review

Found 4 CLAUDE.md compliance issues, 0 bugs.


1. Exported struct fields missing GoDoc — discovery/manifest.go

Line 40 and throughout the file.

Exported struct fields in Provider, Manifest, ServiceEntry, Tier, ResourceEntry, Pricing, FormulaComponent, Constraint, and CaveatSpec are missing GoDoc comments. Per CLAUDE.md L57-L58:

Exported struct fields must have a GoDoc comment (GoDoc style, starting with the field name) and wrapped to 80 columns.

Other structs in this PR (DecodedInvoice, VerifyOptions, QuoteResult) follow the expected pattern. These structs should be updated to match.


2. Exported struct fields missing GoDoc — discovery/quote.go

Line 13

Exported struct fields in QuoteRequest, QuoteResponse, and QuoteError are missing GoDoc comments. Only QuoteError.Status has a comment. All other exported fields need GoDoc comments starting with their name.

Same rule: CLAUDE.md L57-L58.


3. Missing spacing between switch cases — discovery/verify.go

Lines 244-258

The switch cases in stringifyValue have no blank lines between them. Per CLAUDE.md L70-L71:

Spacing between switch/select cases

Add blank lines between each case/default clause.


4. Missing function comment — discovery/discovery_test.go

Line 293

makeMacaroon is missing a function comment. Per CLAUDE.md L47-L48:

Every function and method (including unexported ones) must have a comment starting with the function/method name

Compare with makeInvoice (line 257) and hexEncode (line 406) which both have proper comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant