Skip to content

feat(specs): add diagnostic extension for payment failure signaling#1

Open
jonathanbulkeley wants to merge 133 commits intomainfrom
feat/diagnostic-extension
Open

feat(specs): add diagnostic extension for payment failure signaling#1
jonathanbulkeley wants to merge 133 commits intomainfrom
feat/diagnostic-extension

Conversation

@jonathanbulkeley
Copy link
Copy Markdown
Owner

x402 Diagnostic Extension

PR Description

Adds specs/extensions/diagnostic.md — a machine-readable diagnostic vocabulary for x402 402 responses.

Closes x402-foundation#1860.

This spec was developed from production experience operating a pay-per-query oracle receiving 8,000+ daily failed payment requests from a broken client over 18 days, with no protocol mechanism to signal the issue. It was refined through discussion in x402-foundation#1860 incorporating contributions from @hermesnousagent (receipt trail, correlation_id), @up2itnow0822 / agentwallet-sdk (code-to-behavior mapping, committed to shipping client-side implementation when spec stabilizes), and builds on the implementation foundation laid by @0xAxiom in x402-foundation#1866.

What this adds:

  • 6 standard diagnostic codes with clear retriable/escalate semantics
  • escalate: true flag for broken payment logic detection
  • Client SDK implementation guidance with escalation event schema
  • Server implementation guidance with attempt tracking thresholds
  • Python and TypeScript reference implementations
  • Out-of-band operator contact scoped as a future extension
  • Fully backward compatible — existing clients ignore extensions

cc @hermesnousagent @up2itnow0822 @0xAxiom


gap-editor and others added 30 commits March 1, 2026 12:22
Corrected the spelling of 'convenience' in the README.
* feat: add agently to x402 ecosystem

* chore: update agently url
* Update docs/sdk-features.md

Generated-By: mintlify-agent

* Update docs/extensions/payment-identifier.mdx

Generated-By: mintlify-agent

* Update docs/extensions/payment-identifier.mdx

Generated-By: mintlify-agent

* Update docs/extensions/payment-identifier.mdx

Generated-By: mintlify-agent

* Update docs/extensions/payment-identifier.mdx

Generated-By: mintlify-agent

* fix conflicts

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Co-authored-by: Philippe d'Argent <p.dargent@cern.ch>
* Update docs/extensions/bazaar.mdx

Generated-By: mintlify-agent

* Update docs/sdk-features.md

Generated-By: mintlify-agent

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…terception (x402-foundation#1371)

* feat(go/http): add onProtectedRequest hook for pre-payment request interception

* feat(go/http/gin): add PaymentMiddlewareFromHTTPServer for pre-configured server support
* Update docs/advanced-concepts/lifecycle-hooks.mdx

Generated-By: mintlify-agent

* Update docs/sdk-features.md

Generated-By: mintlify-agent

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…1388)

* fix(exact): enforce strict amount equality per spec

The exact scheme spec states the transferred amount MUST equal
PaymentRequirements.amount exactly. All four facilitators used < instead
of !==, silently accepting overpayments.

Changes:
- SVM V2: amount !== BigInt(requirements.amount), reason: amount_mismatch
- SVM V1: amount !== BigInt(requirementsV1.maxAmountRequired), reason: amount_mismatch
- EVM EIP-3009: authorization.value !== requirements.amount, reason: authorization_value_mismatch
- EVM Permit2: permitted.amount !== requirements.amount, reason: amount_mismatch

Error reasons renamed from _insufficient to _mismatch to cover both
directions (underpayment and overpayment).

Closes x402-foundation#1378

* fix(exact): also enforce strict amount equality in v1 EVM facilitator

Applies the same < to !== comparison change to the v1 EVM facilitator
for consistency with the v2 EVM and SVM facilitators.

* docs(spec): correct exact scheme amount validation description

Two inaccuracies in x402-specification-v2.md relative to the authoritative
scheme contract in specs/schemes/exact/scheme_exact.md:

- §6.1.2 step 3: 'meets or exceeds' -> 'exactly matches'
  The exact scheme requires strict equality (scheme_exact.md L24,
  scheme_exact_svm.md L143). This section describes the EVM implementation
  of the exact scheme, not the upto scheme.

- §9 error table: rename invalid_exact_evm_payload_authorization_value
  to invalid_exact_evm_payload_authorization_value_mismatch and update
  description from 'insufficient' to 'does not exactly match'.
  These error codes are EVM-scheme-layer codes; the table is updated
  to reflect the renamed code in the accompanying implementation change.

* style(evm): wrap long if condition in permit2.ts for prettier compliance
Generated-By: mintlify-agent

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…ody (x402-foundation#1312)

All four SDK implementations (TypeScript, Go, Go legacy, Python) include
x402Version as a top-level field in the facilitator /verify and /settle
request bodies, but neither the v1/v2 specs nor the TypeScript types
document it.

This adds x402Version to:
- v2 spec section 7.1 (POST /verify) request schema
- v1 spec section 7.1 (POST /verify) request schema
- VerifyRequest and SettleRequest types in @x402/core
- VerifyRequestV1 and SettleRequestV1 types in @x402/core

Closes x402-foundation#1176
…agents (x402-foundation#1381)

Co-authored-by: AI Agent Economy <up2itnow0822@users.noreply.github.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
* feat(ecosystem): add Kevros AI governance gateway

* ci: retrigger checks
…02 Gateway (x402-foundation#1403)

* feat(ecosystem): Add Agoragentic - Agent-to-Agent Marketplace with x402 Gateway

* feat(ecosystem): Add Agoragentic logo

---------

Co-authored-by: rhein1 <rhein1@users.noreply.github.com>
* Add upto payment scheme specification for EVM

Introduces the upto scheme which enables usage-based payments where
clients authorize a maximum amount and servers settle for the actual
amount used. This is ideal for variable-cost resources like LLM token
generation, bandwidth metering, or time-based access.

Key features:
- Uses Permit2 exclusively (permitWitnessTransferFrom)
- Client signs for max amount, server settles for actual usage
- Settlement amount can be 0 to amount (inclusive)
- Adds settledAmount field to SettlementResponse
- Reuses existing x402Permit2Proxy contract

* Link to existing x402Permit2Proxy contract instead of duplicating

* Clarify error codes: standard vs scheme-specific

- List standard x402 error codes that apply to upto scheme
- Add scheme-specific error codes following naming convention
- Add missing error codes for recipient mismatch and time validation

* Simplify error codes section and add SettlementResponse link

- Link to base SettlementResponse schema in main spec
- Reference standard error codes instead of duplicating
- Keep only the truly upto-specific error code: settlement_exceeds_amount

* docs(upto): add explicit MUST requirements for cross-network properties

- Add Core Properties (MUST) section with single-use, time-bound,
  recipient binding, and max amount enforcement requirements
- Add Out of Scope section clarifying what upto does NOT support
- Remove invalid use cases: streaming, time-based access, API rate metering
- Clarify remaining use cases as single-request patterns

Addresses PR feedback from @phdargen and @notorious-d-e-v

* docs(upto): rename settledAmount to amount in SettlementResponse

Rename for consistency with planned addition of amount field to base
SettlementResponse schema in x402-specification-v2.md (per PR feedback)

* docs(upto): clarify phase-dependent amount semantics in PaymentRequirements

The amount field in PaymentRequirements has different semantics at verify vs settle time for the upto scheme. At verification, it represents the max authorized amount. At settlement, it represents the actual amount to settle. This was ambiguous in the spec and is now explicitly documented across scheme_upto.md, scheme_upto_evm.md, and the main x402 v2 spec.
* Add @x402/stellar mechanism package with exact scheme

Implement Stellar support for the x402 protocol covering:
- Types, constants (network IDs, USDC contracts), and utility functions
- Ed25519 signer with client/facilitator variants
- Soroban transaction simulation and auth entry handling
- Client: builds transfer calls, signs auth entries, serializes XDR
- Server: parses prices, enhances payment requirements
- Facilitator: verify (structure, amounts, signatures, events) and
  settle (fee sponsorship, multi-signer round-robin, submission)

* Add unit tests for the Stellar mechanism

Cover signer, constants, utils, shared helpers, client/server
scheme logic, and facilitator verify/settle/getExtra flows.
150 tests across 9 test files.

* Add integration tests for Stellar exact scheme

End-to-end flows against Stellar testnet covering both the core
x402Client/Server/Facilitator and the HTTP middleware variants.
Includes resilience to testnet resets via automatic re-funding.

* Add Stellar README and cross-reference from evm/svm

Document the package API, usage examples, fee sponsorship model,
and multi-signer facilitator setup. Link back from evm and svm.

* Wire up Stellar in the advanced examples

Register Stellar client/server/facilitator schemes alongside EVM
and SVM in the all_networks examples. Guarded by env var presence
so existing setups keep working without Stellar credentials.

* Document Stellar setup in the advanced example READMEs

Add STELLAR_PRIVATE_KEY / STELLAR_ADDRESS env vars to .env-local
templates and update the example READMEs with Stellar usage notes.

* Add Stellar to the e2e test suite

Extend the test framework with Stellar network support, add
protected-stellar endpoints to express/hono/next servers, register
Stellar signers in axios/fetch clients and the TS facilitator.
Includes test configs, lockfile, and the Stellar family in the
test runner. All 8 server×client combos pass against testnet.

* Update e2e docs with Stellar setup and trustline instructions

Add STELLAR env vars to .env-local templates, document the Stellar
testnet account setup process (keypair, USDC trustline, faucet),
and update all server/client/facilitator READMEs.

* Add npm publish workflow for @x402/stellar

Manual-dispatch GitHub Actions workflow to publish the Stellar
package to npm with provenance, matching the pattern used by
the other mechanism packages.

* Add CHANGELOG for @x402/stellar v2.5.0
* py fix for 1176

* fix settle response body

* same for go/py

* fix format
…02-foundation#1359)

* set assetTransferMethod for defaultAsset

* mock token fix

* use moneyparser

* py changes

* go changes

* fix get_asset_info

* add SupportsEip2612 flag

* add changelogs

* fix tests
…-foundation#1453)

* fix(stellar): include feeBumpSigner in getSigners response

The /facilitator/supported endpoint was not returning the feeBumpSigner
address alongside regular signer addresses. This meant clients couldn't
discover the fee bump signer via the supported endpoint.

getSigners() now appends the feeBumpSigner address when configured,
with a guard to prevent duplicates if it's also a regular signer.

* refactor(stellar): unify getExtra and getSigners tests into facilitator-accessors

Merge facilitator-getExtra.test.ts and facilitator-getSigners.test.ts
into a single facilitator-accessors.test.ts, eliminating duplicate
imports, mocks, and setup.
* fix: add duplicate settlement mitigation for SVM across all SDKs

Introduce an in-memory SettlementCache to prevent a race condition on
Solana where the same payment transaction could be settled multiple
times before on-chain confirmation. The cache is shared across V1 and
V2 facilitator schemes so that cross-version duplicates are caught.

- Add SettlementCache with 120s TTL in TypeScript, Python, and Go
- Integrate cache check into facilitator settle paths (V1 and V2)
- Add unit tests for duplicate detection in all three languages
- Share cache across V1/V2 in Go facilitator example
- Add duplicate settlement spec to scheme_exact_svm.md
- Document SettlementCache in SVM READMEs for all three SDKs
- Document the race condition in go/FACILITATOR.md Security section
- Add merchant-facing guidance in docs/core-concepts/client-server.md
  and docs/core-concepts/facilitator.md for self-settling servers
- Fix JSDoc lint errors in TypeScript settlement-cache.ts

* refactor: optimize SettlementCache prune with early break on ordered entries

Leverage insertion-order guarantees of Map (TS) and dict (Python) to
break early once a non-expired entry is encountered, avoiding a full
scan of the cache on every isDuplicate call. Go is left unchanged since
map iteration order is not guaranteed.

Also adds prune-specific unit tests for all three SDKs covering:
- mixed expired/fresh entries
- all expired
- none expired
- insertion-order early-break correctness (Python)

* docs: add changelog entries for SVM duplicate settlement fix
* fix stellar e2e config

* fix stellar next e2e
* updated changeset

* chore: version typescript packages

* updated changelogs
JleviEderer and others added 12 commits March 30, 2026 15:07
* fix: randomize facilitator signer selection

* fix: test
* Update docs/getting-started/quickstart-for-sellers.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/getting-started/quickstart-for-sellers.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/getting-started/quickstart-for-sellers.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* Update docs/sdk-features.md

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

* Update docs/getting-started/quickstart-for-sellers.mdx

Generated-By: mintlify-agent

Mintlify-Source: dashboard-editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…foundation#1791)

Add native USDC (0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359) as the
default stablecoin for Polygon mainnet across all three SDKs:

- Go: ChainIDPolygon constant, v2 NetworkConfigs, v1 NetworkConfigs
- TypeScript: v2 stablecoins map in ExactEvmScheme
- Python: v2 NETWORK_CONFIGS with supported_assets

Update Go v1 unit tests that previously used "polygon" as a network
without a default asset config. Replace with "iotex" and add positive
test coverage for Polygon config and asset resolution.

Contract details (verified on-chain via PolygonScan):
- Token: Circle native USDC (FiatTokenV2_2)
- EIP-712 domain: name="USD Coin", version="2"
- EIP-3009: transferWithAuthorization supported
- x402 proxy deployed at canonical CREATE2 address
…foundation#1834)

* fix(mcp): preserve structuredContent in payment wrapper result

createPaymentWrapper was reconstructing the tool result with only
content/isError/_meta, dropping structuredContent. This causes MCP SDK
output schema validation to fail with "Tool has an output schema but
no structured content was provided" for any tool that defines an
outputSchema.

Fix: spread the full handler result instead of cherry-picking fields,
so structuredContent and any future fields are preserved.

Adds test verifying structuredContent survives the payment wrapper.

* fix(mcp): drop result._meta spread to fix TS2698

The index signature on ToolResult makes _meta typed as unknown,
which cannot be spread. The wrapper owns _meta exclusively so
no merge is needed.
…n#1813)

* Fix HTTPFacilitatorClient not following 308 redirects from facilitator

The x402.org/facilitator/supported endpoint returns HTTP 308 before
resolving to 200. HTTPFacilitatorClient did not normalize the base URL
or explicitly request redirect following, causing syncFacilitatorOnStart
to silently fail in some runtimes. When no supported payment kinds are
loaded, the middleware passes all requests through as 200 instead of 402.

- Strip trailing slashes from facilitator URL in constructor to prevent
  unnecessary 308 redirects from trailing-slash normalization
- Explicitly set redirect: "follow" on all fetch calls (verify, settle,
  getSupported) for cross-runtime compatibility
- Add tests for URL normalization and redirect option propagation

Closes x402-foundation#1692

* fix: apply prettier formatting to httpFacilitatorClient test
…dation#1733)

* test(python): add missing sync test scenarios to existing test_server.py

Add edge case coverage for: missing/malformed _meta, no matching
requirements, MCPToolResult direct return, non-dict handler return,
structuredContent preservation, empty accepts validation, verification
failure without reason, and hook context field verification.

* fix: apply ruff format to test_server.py

* fix formatting: match existing test style, inline data construction, fix import order
EmreDincoglu and others added 7 commits March 31, 2026 00:54
* fix: evm contract deploys

* feat: updated constants in SDKs

* feat: added changeset fragments
…oundation#1786)

* feat(evm): add Stable testnet (chain ID 2201) network support

* style(go): fix gofmt alignment for chain ID variable declarations

* fix(python): remove supported_assets from Stable network configs

* style(ts): reorder Stable configs above Polygon/Arbitrum in defaultAssets
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFC: Diagnostic extension for 402 responses — payment failure signaling for agents