Skip to content

integration(x402): buyer-funnel stack + v2 PAYMENT-SIGNATURE (supersedes #686–689) - #690

Merged
OisinKyne merged 7 commits into
mainfrom
integration/x402-buyer-funnel
Jul 2, 2026
Merged

integration(x402): buyer-funnel stack + v2 PAYMENT-SIGNATURE (supersedes #686–689)#690
OisinKyne merged 7 commits into
mainfrom
integration/x402-buyer-funnel

Conversation

@bussyjd

@bussyjd bussyjd commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What

One PR superseding #686, #687, #688, #689 — the buyer-funnel stack plus the x402 v2 PAYMENT-SIGNATURE fix, integrated with the forwardauth.go conflict resolved and two emergent defects fixed.

Contents

Commit PR
26c058d #686 go auto-dispatch front door + buyer UX hardening
cfaf3e9 #687 single-source buyer prompts, docs deep links, Scalar, ServiceCard
c5a2c57 #688 tolerant chat-path gateway, structured payment errors, funnel metrics
#689 #689 accept x402 v2 PAYMENT-SIGNATURE header — already validated live on-chain
merge #689 into the stack; forwardauth.go conflicts resolved keep-both
fix meter v2 (PAYMENT-SIGNATURE) payments in the funnel (emergent defect)

forwardauth.go conflict resolution (keep-both)

Emergent defect fixed

verifier.go gated the funnel metrics on hadPayment := Get("X-PAYMENT") != "". After #689, a spec-compliant v2 payment arrives under PAYMENT-SIGNATURE, so every successful v2 payment — exactly the cohort #689 unblocked — incremented none of the success/charge/upstream counters. hadPayment now checks both headers.

Validation

Supersedes #686, #687, #688, #689.

OisinKyne and others added 6 commits July 2, 2026 02:38
…metadata

- new internal/buyprompts package is the one authoring point for how-to-buy
  copy; the 402 page, /api/services.json ('buy' block with callShape +
  prompts per buyer-software kind), the storefront, and 'obol sell info'
  all render it, so instructions can no longer drift between surfaces
  (the storefront was still advertising the removed --no-verify-identity flag)
- catalog entries gain openapiPath + docsPath (Scalar deep-link anchor);
  storefront shows API-docs links for every offer type, skill.md service
  details link the anchored docs
- x-payment-info always emits accepts[] with payTo, CAIP-2 network, atomic
  amount, and the asset's EIP-712 signing domain, so an OpenAPI-only client
  can construct a valid X-PAYMENT without a second fetch
- @scalar/api-reference bumped 1.34.0 -> 1.62.1; renovate custom manager +
  postUpgradeTasks now keep it current, with scripts/update-scalar-sri.sh
  refreshing the SRI hash inside the same renovate PR

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nnel metrics

- HandleProxy rewrites bare POST /services/<name> (and /chat/completions,
  /v1) to /v1/chat/completions for agent/inference offers, so the most
  common wrong-path mistake from external buyers succeeds instead of
  paying into a 404; the 402 page's agent copy taught exactly that bare
  form until this change
- terminal payment failures return structured JSON {error, reason, hint,
  retriable}; the facilitator's invalidReason (previously discarded) now
  rides the re-issued 402 challenge in error + extensions.paymentFailure,
  and signature rejections state the expected EIP-712 domain
- legacy error phrases kept verbatim (flows/lib.sh greps for them)
- new funnel metrics: payment_failure_reasons_total{reason} (bounded
  6-value set) and upstream_failed_after_verify_total, so first-try buyer
  success is measurable per stage; docs/observability.md updated

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The ForwardAuth verifier advertises x402Version 2 in its 402 challenge but only
read the payment from the legacy v1 X-PAYMENT header. Spec-compliant x402 v2
buyers (agentcash, poncho, coinbase SDK >= v2) attach the payment under
PAYMENT-SIGNATURE, so their valid payment was silently ignored and the caller
re-challenged — no verify, no settle, no log. This blocked every third-party v2
client from paying obol endpoints; only the in-tree buyer (which sends X-PAYMENT)
worked.

- Read the payment from X-PAYMENT (v1) OR PAYMENT-SIGNATURE (v2).
- Decode via the canonical x402types.ToPaymentPayload helper instead of a local
  json.Unmarshal, keeping the envelope in lockstep with the SDK.
- Mirror the settlement receipt onto both X-PAYMENT-RESPONSE and PAYMENT-RESPONSE.
- Tests for the v2 header accept + settle + dual response header.

Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
Post-#689 a spec-compliant x402 v2 payment arrives under PAYMENT-SIGNATURE, but
the funnel gate hadPayment only checked X-PAYMENT — so every successful v2
payment (exactly the cohort #689 unblocked) incremented none of the
success/charge/upstream counters. Gate on both headers.

Emergent defect of integrating #688 (X-PAYMENT-gated metrics) with #689
(v2 via PAYMENT-SIGNATURE).
@OisinKyne
OisinKyne merged commit f0f519d into main Jul 2, 2026
8 checks passed
@OisinKyne
OisinKyne deleted the integration/x402-buyer-funnel branch July 2, 2026 19:41
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.

2 participants