pull in latest upstream#2
Open
TtheBC01 wants to merge 779 commits into
Open
Conversation
* Create scheme_exact_cardano.md * Update scheme_exact_cardano.md * Update and rename scheme_exact_cardano.md to scheme_exact_cardano-masumi.md * Added Address-To-Address on Cardano Specs * Update scheme_exact_cardano.md * feat: add optional session management to final response * chore: add instructions for script flavor * feat: update cardano schema according to x402 v2 migration guide * chore: update mermaid diagram for x402 v2 * chore: reapply v2 changes that might got lost in the merging process * chore: address x402 schema feedback around nonce, legacy v1 fields, flavor and session tokens * chore: add warning for mempool status, rewrite facilitator verification rules --------- Co-authored-by: Patrick Tobler <129864078+PatrickTobler@users.noreply.github.com>
Generated-By: mintlify-agent Mintlify-Source: dashboard-editor Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* feat(site): make x402.org agent-ready for isitagentready.com Add all 13 isitagentready.com checks: - robots.txt with AI crawler rules and Content Signals - sitemap.xml via Next.js metadata API - Link response headers (api-catalog, service-doc, payment-required) - Markdown content negotiation (Accept: text/markdown) - API catalog at /.well-known/api-catalog (RFC 9727) - OAuth/OIDC discovery at /.well-known/openid-configuration - OAuth Protected Resource at /.well-known/oauth-protected-resource - MCP Server Card at /.well-known/mcp/server-card.json - Agent Skills index at /.well-known/agent-skills/index.json - WebMCP tool registration (get-x402-info, navigate-x402) - x402 demo endpoint returning HTTP 402 with PAYMENT-REQUIRED header Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(site): add JSDoc descriptions to agent-ready route handlers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(site): address PR review feedback - Remove hollow OAuth stubs (openid-configuration, oauth-protected-resource) that declared endpoints which don't exist - Remove redundant /api/x402/demo route, point to /protected instead - Remove non-existent /mcp endpoint from MCP server card - Fix sitemap to use static dates instead of new Date() - Fix SKILL.md to use CAIP-2 network identifiers (eip155:8453) - Change WebMCP script strategy from beforeInteractive to afterInteractive Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ctly (#2109) * feat(ts): allow ResourceServerExtension to assign x402ResourceServer hooks directly * feat: improve enforcement/security of what hooks can and cannot modify * feat: pr review * feat: try/catching hooks * feat: pr feedback
* Update docs/extensions/overview.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/overview.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/overview.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/advanced-concepts/lifecycle-hooks.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* feat(hedera): add @x402/hedera package with exact payment scheme - New @x402/hedera package implementing the x402 v2 exact scheme - Uses @hiero-ledger/sdk for signing and submission - Onchain preflight transfer check before settlement - Settlement receipt validation (USDC + HBAR coverage) - HEDERA_ACCOUNT_ID / HEDERA_PRIVATE_KEY / HEDERA_NETWORK env vars - Integrated with advanced clients (axios, fetch), facilitators, and HTTP adapters (hono, fastify, next) - E2E tests for Hono, Next.js, and Fastify servers - Testnet faucet docs and token association notes Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com> * refactor: use convertToAtomicAmount function from @x402/core/utils Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com> --------- Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…ion (#1902) * feat: add auth-hints extension to streamline scheme-level authentication - Described general auth scheme for x402, mainly on HTTP transports - Initial support for two auth method types: oauth2 (Bearer/DPoP) and sign-in-with-x - Defined scheme and acceptIndex hints. * feat: settle on acceptIndexes, schemeAuth->authRequirements, remove references to scheme-based hints
…DC 6 (#1926) * getDisplayAmount でトークンの decimals を動的取得し USDC ハードコードを修正 * Amount 表示で末尾の0を削除し動的 decimals を適用 * decimals を [0, 100] にクランプし toFixed の RangeError を防ぐ * x402ResourceServer.ts の prettier フォーマットを修正
* checkIfBazaarNeeded を @x402/core に統合し、4パッケージの重複を排除 * 重複した checkIfBazaarNeeded 定義を削除 * 各HTTPパッケージの vi.mock に checkIfBazaarNeeded を追加
* fix(paywall): use dynamic token decimals instead of hardcoding 6
The EVM paywall displays incorrect amounts for any token that does not
use 6 decimal places. An 18-decimal token priced at 0.001 raw units
renders as $1,000,000,000 because the code divides by 10^6 everywhere.
Root cause: the paywall was built assuming USDC (6 decimals) is the
only payment token. This assumption appears in three places:
1. Server-side HTML generation (index.ts) divides the raw amount by
a hardcoded 10^6 to produce the display value injected into the
template.
2. Client-side balance display (EvmPaywall.tsx) calls formatUnits
with a hardcoded 6 and reads the token address from a 3-chain
USDC lookup table that returns 0 for any other chain.
3. The balance utility (utils.ts) only knows USDC addresses on
Ethereum, Base, and Base Sepolia — every other chain silently
shows a zero balance.
Fix:
Server-side (index.ts): look up the token's decimal precision from a
known-decimals map aligned with DEFAULT_STABLECOINS. Only non-6-decimal
chains need entries; everything else falls back to 6. This keeps the
server-side path simple with no RPC calls.
Client-side (EvmPaywall.tsx): read the token contract address from
the payment requirement's `asset` field (which the server already
populates) and query the standard ERC-20 decimals() function on-chain.
This works for any compliant token without maintaining a lookup table.
utils.ts: replace the USDC-specific getUSDCBalance (internal helper,
not part of the public API) with generic getTokenBalance and
getTokenDecimals functions that accept a token address parameter.
The function signature changes from 2 args to 3, but no external
consumer can import it — it is only used by the bundled React
component inside the paywall HTML template.
**Breaking change note:** the internal helper getUSDCBalance in utils.ts
is removed and replaced by getTokenBalance (different signature: takes
an explicit token address instead of looking it up by chain ID). This
function is not exported from the package's public API — it is only
consumed by the bundled EvmPaywall React component inside the paywall
HTML template. No server operator code calls it directly. However,
anyone who has forked the paywall and imports from the file path
(bypassing package exports) would need to update their import and
call site.
Regenerated Go, Python, and TS paywall templates.
**AI disclosure:** This PR was prepared with the assistance of a coding agent and
reviewed by Ryan R. Fox (an actual human) before submission.
* style: ruff format paywall templates
* fix(paywall): use DEFAULT_STABLECOINS lookup + BigInt formatUnits
Removes the parallel KNOWN_DECIMALS map in @x402/paywall/src/evm/index.ts
that mirrored DEFAULT_STABLECOINS from @x402/evm. The paywall now resolves
token decimals through the same registry that scheme implementations and
@x402/core's inline scheme dispatch already read from.
evmPaywall.generateHtml changes:
* getDefaultTokenDecimals helper looks up requirement.network directly in
@x402/evm's DEFAULT_STABLECOINS, with a 6 (USDC default) fallback when
the network is unknown.
* Atomic-to-display conversion uses Number(formatUnits(BigInt(amount),
decimals)) instead of parseFloat(amount) / 10**decimals. parseFloat
silently rounds sub-cent precision on real 18-decimal amounts before
the divide; BigInt + formatUnits preserves precision through the
conversion. BigInt also rejects non-integer atomic strings, which
matches the spec's atomic-integer contract.
@x402/paywall package.json: @x402/evm moves from devDependencies to
dependencies because the new server-side import of DEFAULT_STABLECOINS is
on the runtime path emitted into dist/.
@x402/evm now publicly re-exports DEFAULT_STABLECOINS from
./shared/defaultAssets so consumers can read the canonical default-asset
registry directly. Both @x402/evm and @x402/paywall get a minor bump
for the additive public API.
Adds 6 unit tests:
* getDefaultTokenDecimals returns 18 for Mezo Testnet (registry path)
* getDefaultTokenDecimals returns 6 for Base mainnet, asserted alongside
DEFAULT_STABLECOINS so an empty registry would fail the test
* getDefaultTokenDecimals falls back to 6 for unknown networks
* evmPaywall.generateHtml renders 1e15-atomic Mezo mUSD as
'amount: 0.001,' end-to-end (regression test for the /1e6 bug)
* evmPaywall.generateHtml renders 1e6-atomic Base USDC as 'amount: 1,'
* evmPaywall.generateHtml throws on a non-integer atomic ('1.5'),
pinning the BigInt strictness so a future revert to parseFloat fails
Closes #1979.
* refactor(paywall): generate evm decimals at build time, drop @x402/evm runtime dep
Addresses @phdargen's review: rather than promoting @x402/evm to a
runtime dependency of @x402/paywall, keep it a devDependency and
emit a codegen'd `src/evm/gen/decimals.ts` that mirrors just the
per-network `decimals` field of `DEFAULT_STABLECOINS`.
Pattern-consistent with the existing `src/evm/gen/template.ts` codegen
(HTML bundle) — same build step (`src/evm/build.ts`), same "AUTO-GENERATED
DO NOT EDIT" banner, same commit-the-generated-file workflow. The CI
drift check queued in #2054 (`check_paywall_template.yml`) will pick up
`decimals.ts` under the existing `typescript/packages/http/paywall/**`
trigger glob once that PR merges; in the meantime an in-process drift
invariant test in `network-handlers.test.ts` asserts `NETWORK_DECIMALS`
matches `DEFAULT_STABLECOINS` key-for-key.
Runtime behaviour is unchanged. `getDefaultTokenDecimals` now reads the
generated `NETWORK_DECIMALS` map instead of reading `DEFAULT_STABLECOINS`
at runtime; the same Mezo-18, Base-6, unknown→6 cases still hold, and
the existing 6 regression tests in `network-handlers.test.ts` pass
without modification. A seventh test pins the drift invariant described
above.
package.json: `@x402/evm` moved from `dependencies` to `devDependencies`.
Runtime module graph for `@x402/paywall` no longer pulls `@x402/evm`;
the only surviving `@x402/evm` references in paywall src are:
* `browserAdapter.ts` — `import type { ClientEvmSigner }` (type-only,
erased at build time)
* `EvmPaywall.tsx` — `ExactEvmScheme` (bundled into `gen/template.ts`
by esbuild, not part of the server-side runtime path)
* `build.ts` and `network-handlers.test.ts` — build-time / test-time
consumers; devDep is available in both.
Both the root `typescript/pnpm-lock.yaml` and `examples/typescript/pnpm-lock.yaml`
are updated to reflect the dep move — both workspaces reference the
paywall package manifest via `workspace:~`.
- Add /protected to sitemap so scanners can discover the 402 endpoint - Add X-X402-Supported header on homepage to signal x402 support Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The committed @x402/paywall bundle on main was last generated against an older viem than the lockfile currently pins. pnpm install --frozen-lockfile resolves viem 2.47.12 (via #2013), but the bundled src/evm/gen/template.ts (and its Python + Go siblings) were built against an earlier resolution that pre-dated chain definitions for Mezo, MegaETH, Stable, Radius (each with a testnet variant), and 33 others. EvmPaywall.tsx throws "Unsupported chain ID" at init for any eip155:<id> whose chain isn't in the bundled viem/chains. This PR: 1. Regenerates all nine auto-generated template files (TypeScript, Python, and Go for EVM/SVM/AVM) against the current lockfile. No source changes on any runtime path. 2. Teaches build:paywall to emit output matching the repo's formatters (prettier / ruff), so generated files stay clean under pnpm run format + uvx ruff format. 3. Adds a PR-time drift check (.github/workflows/check_paywall_template.yml) so a future lockfile or @x402/evm change that invalidates the bundle fails loudly instead of shipping silently. Scope is limited to @x402/paywall because it is the only package in this repo that bakes viem chain definitions into a built artifact. Verified on a fork-internal test PR running on ubuntu-latest (Node 24, pnpm 10.7.0): check_format, check_lint, check_go, check_python, check_package_lock, and the new check_paywall_template drift check all pass. Additional local evidence: - Chain-presence in regenerated bundle: Mezo 31612/31611, MegaETH 4326/6343, Stable 988/2201, Radius 723487/72344, Base/Arbitrum/ Polygon all present (mainnet/testnet ordering). - Cross-platform determinism: a clean-slate rebuild on macOS produces byte-identical output to ubuntu-latest CI. - Tarball install into a throwaway consumer: all expected chain IDs present in the published dist/esm/evm/index.js. - Browser smoke test (Chrome, served from a local HTTP server): EvmPaywall mounts without Unsupported-chain throw for eip155:31611 (Mezo Testnet) and eip155:723487 (Radius); DOM renders the expected token/chain labels. Fixes #1971.
…2152) The isitagentready.com scanner cannot detect x402 support through the existing /protected page (tried sitemap inclusion, Link headers, X-X402-Supported header). Add a dedicated API endpoint at /api/x402/demo that returns a clean HTTP 402 with PAYMENT-REQUIRED header using the same payment config as /protected.
* Add codeowners per-network * Update CODEOWNERS
…h, and Python alignment (#2094) * update withBazaar * Fix bazaar MCP discovery parity across TS/Python/Go; tighten e2e validation; update docs/examples. * python format * remove formatting-only changes * remove formatting-only changes * reinstate old comments * clean up response shape * revert pagination to object instead of top level fields * address review comments
* fix #2701 * pr feedback * pr feedback 2
* spec(xrpl): add exact scheme
* spec(xrpl): address exact scheme review
* spec(xrpl): add assetTransferMethod to select sequence or ticketSequence
Per review feedback, account sequencing is now negotiable via
extra.assetTransferMethod ("sequence" | "ticketSequence"), mirroring the
EVM exact scheme pattern. Documents the tradeoffs (ticket reserve and
TicketCreate preflight vs. the sequence settlement race) and splits the
facilitator sequencing checks per method.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Update docs/schemes/exact.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/schemes/exact.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* fix keeta tests * fix fmt
* mcp interop fixes * add changeset
) facilitator.x402.org has no DNS record (NXDOMAIN), so every quickstart that copies these snippets fails at the first request. The rest of the repo (99 references) already uses https://x402.org/facilitator, which is live and serving /supported. Claude-Session: https://claude.ai/code/session_018p8jtKC5g7uUMrjGCWksqu Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… fresh clone (#2791) * examples/go: add missing .env-example for echo server * examples/go: simplify payment response handling in http client The call site duplicated the v2/v1 header lookup that extractPaymentResponse already performs, and parse errors were silently dropped. Use the helper directly and surface parse failures. * examples/go: tidy modules in echo server and http client examples SDK dependency bumps were not propagated to the example modules, so neither example builds from a fresh clone (missing go.sum entries). Regenerated with go mod tidy under go1.24.1, the toolchain pinned in go.mod.
* deprecate website * small fixes * bring back protected * fix fmt
* add ts/go readmes * core + EVM mechanism plumbing * add extension * add examples * fix siwx
* Update docs/sdk-features.md Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/overview.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/builder-code.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/builder-code.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/builder-code.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/builder-code.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…2810) * fix(python/flask): use sync server in payment_middleware_from_config The Flask factory instantiated the async x402ResourceServer and handed it to PaymentMiddleware, which builds x402HTTPResourceServerSync. The sync HTTP server rejects a server whose verify_payment is a coroutine, so the factory raised TypeError('requires a sync server') at construction — it failed 100% of the time and was unusable. Switch to x402ResourceServerSync, mirroring how the FastAPI factory uses the async x402ResourceServer for its async server. Regression test added. * chore(python): changelog fragment for #2810
Add USDC on Igra Network (chain ID 38833) as a default stablecoin across TypeScript, Go, and Python SDKs. Uses Permit2 transfer method (no EIP-3009 or EIP-2612 support on the token contract). Token: 0xA5b8BF902b2844dA17d4506cc827F7F1681735E7 (USDC, 6 decimals)
* docs(specs): add exact scheme spec for Casper Network
Implements PR 1 ("Specification Only") of the "Adding a New Chain
Family" workflow in CONTRIBUTING.md.
The scheme is built on CEP-3009, Casper's CEP-18 + EIP-712 adaptation
of EIP-3009: the payer signs an off-chain EIP-712 authorization for
a single fixed-amount CEP-18 transfer; the facilitator relays it on
chain via transfer_with_authorization and pays the gas. The token
contract enforces signature validity, strict validity window, and
nonce uniqueness. speculative_exec is referenced as an optional
verification step since it is not enabled on most Casper nodes.
No SDK changes; reference implementation will follow in PR 2.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(specs): address review feedback on Casper exact scheme spec
Fix validBefore/maxTimeoutSeconds bound direction, require canonical
low-s secp256k1 signatures, make supported CAIP-2 networks explicit,
rename PAYMENT-RESPONSE section to SettlementResponse, and update the
stale Casper JSON-RPC docs link.
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix flask 3xx response bug * changeset
#2622) * fix(python/fastapi): log + return 402 with PAYMENT-RESPONSE on unexpected settlement errors * style(python/fastapi): satisfy ruff lint - move logger below the extension imports (bazaar imports were E402) - drop unused 'as error' on the settlement catch-all (F841) - ruff format (one-line logger.exception, sorted test imports)
* docs(facilitators): add Solvador to facilitators list * docs(facilitators:solvador): add NEAR support
…t error (#2721) * fix(python/flask): return 500 (and log) on unexpected settlement error * chore(changelog): name flask settlement fragment by PR number * fix(python/flask): surface unexpected settlement error as 402 + PAYMENT-RESPONSE (mirror #2622) * fix(python/flask): use canonical unexpected_settle_error reason (parity with #2622) * style(python): apply ruff format to test_flask.py * chore(python): restore uv.lock to main (no dependency changes in this PR) * chore(python): leave uv.lock untouched (no dependency changes)
* verify aptos sign * verify aptos sign
* feat(xrpl): add exact scheme TypeScript reference implementation Implements specs/schemes/exact/scheme_exact_xrpl.md as @x402/xrpl with client, resource-server, and facilitator schemes for payer-signed XRPL Payment transactions: - sequence and ticketSequence asset transfer methods with the spec's resolution order, per-method verification (current account Sequence, ticket availability), and a createTickets utility - extra.areFeesSponsored=false advertised via facilitator getExtra and enforced in envelope verification - offline signature validation, NetworkID binding, InvoiceID invoice binding (Memos rejected), Delegate/Paths/DeliverMin/partial-payment rejection, fee caps, LastLedgerSequence expiry policy, and simulation (signature fields stripped: the XRPL simulate API only accepts unsigned transactions) - settlement re-verifies, submits, and requires validated tesSUCCESS - XRP drops and issued-currency decimal value amounts compared with exact decimal arithmetic (no extra.decimals field) The server scheme keeps enhancePaymentRequirements deterministic (requirements are rebuilt per request), so invoice binding activates only when the resource configuration provides extra.invoiceId. Adds unit and integration tests, publish workflows, release-script and changeset fixed-group wiring, and the root test:integration filter. * feat(e2e): wire XRPL into the e2e harness and participants Adds the xrpl protocol family to the harness networks/types/env plumbing, registers @x402/xrpl in the axios and fetch clients, the express/fastify/hono/next servers (GET /exact/xrpl routes priced in XRP drops), the TypeScript facilitator (keyless: the payer signs and pays XRPL fees), and the mock facilitator supported response. Verified locally against XRPL Testnet (xrpl:1) with funded faucet accounts: pnpm test --testnet --families=xrpl --versions=2 passes all 10 scenarios (axios/fetch x express/fastify/hono/next incl. withX402). * feat(examples): add XRPL to the advanced all_networks examples Registers @x402/xrpl in the client, server, and facilitator all_networks examples (alphabetical by network prefix), with XRPL_SEED/XRPL_ADDRESS/XRPL_NETWORK/XRPL_WS_URL configuration. * docs(examples): add XRPL setup to the advanced example READMEs Document the XRPL environment variables, testnet faucet steps, and reserve/trust line requirements in the advanced client, server, and facilitator example READMEs, and add the matching .env-local entries. The facilitator README also notes the keyless XRPL scheme (enabled via XRPL_NETWORK), its /supported kind with areFeesSponsored=false, and the xrpl:0 / xrpl:1 network identifiers. * fix(typescript): regenerate pnpm-lock.yaml after rebase onto main The website deprecation (#2794) removed the jiti-suffixed peer-dependency variants that the @x402/xrpl importer entries resolved to. Re-resolve the lockfile against the current workspace so frozen installs succeed. * fix(xrpl): bind signatures to account authorization and harden verification - Verify the embedded SigningPubKey is authorized for Account (master key pair unless disabled, or the configured regular key) via a validated account_info lookup. Offline signature validation only proves the blob was signed by its embedded key, and simulation strips signature fields, so an unauthorized signer previously passed /verify and failed at /settle with tefBAD_AUTH or tefMASTER_DISABLED. - Reject single-signed blobs that carry a Signers array; the single signature does not cover Signers, so hybrid blobs still pass verifySignature. - Fail closed on malformed extra.destinationTag in the facilitator, resource server, and client instead of silently skipping the tx-level binding. - Correct the changeset wording: the server scheme passes through configured invoice ids, it does not generate them. - Cover the new checks and previously untested spec rules in unit tests: envelope mismatches, NetworkID branches, XRP/IOU amount and SendMax variants, LastLedgerSequence bounds, InvoiceID mismatch, sequence 0, settle outcomes, and client-side NetworkID handling. * test(xrpl): add env-gated live settlement integration test Mirror the NEAR exact-near.live.test.ts pattern: when XRPL_PAYER_SEED and XRPL_LIVE_PAYTO (or the e2e CLIENT_XRPL_SEED / SERVER_XRPL_ADDRESS names) are set, drive the reference client, resource server, and keyless facilitator end to end against a real network and assert the payTo XRP balance increases by exactly the requested drops. Skipped when the accounts are not configured, so it stays inert in CI. Verified against XRPL Testnet: settled tx 6AF0A4F630F2B43CA44544D5246B58260A01860A3CCBB331625229CD78696791. * fix(xrpl): mirror rippled signer-key ordering and require canonical signing keys - Authorize the configured regular key before the master-disabled check, matching rippled's fixMasterKeyAsRegularKey ordering so legacy accounts whose RegularKey equals their own address are not wrongly rejected. - Reject non-canonical SigningPubKey encodings (only 33-byte compressed secp256k1 or ed25519 keys) before signature validation; rippled refuses such keys at preflight, so accepting them would let verification pass for a transaction that can never settle. * feat(xrpl): create tickets automatically for ticketSequence payments When a ticketSequence payment finds no available ticket, the client now creates tickets through the ClientXrplSigner abstraction instead of throwing and requiring a manual createTickets() call. The new ticketCreateCount option controls the policy: it defaults to 1, allows up to 250 tickets per TicketCreate, and 0 restores the previous fail-fast behavior for pre-provisioned setups. Available tickets are still reused first and skip the creation transaction entirely. - Widen ClientXrplSigner.sign from Payment to SubmittableTransaction so the same signer can sign TicketCreate; createTickets accepts the signer abstraction instead of an xrpl.js Wallet. - Cover the default, configured, and disabled policies plus invalid counts in unit tests. * fix(xrpl): return a stable reason code for unexpected verification failures The verify() catch-all embedded the raw error message in the invalidReason string (invalid_exact_xrpl_payload_malformed: <message>), so integrators could not match on a stable code. Return invalid_exact_xrpl_facilitator_error and carry the raw diagnostic text separately in invalidMessage. Settlement submission errors keep the existing transaction_failed: <diagnostic> reason. * fix(xrpl): fail closed on missing or invalid IOU issuers Issued-currency requirements and accepted payloads must both carry a valid classic issuer address before the issuer comparison runs. Two absent issuers previously compared equal and passed envelope validation, and a single absent issuer surfaced as a confusing mismatch. Missing or malformed issuers now return invalid_exact_xrpl_iou_issuer_missing. * fix(xrpl): set the custom-network NetworkID when building payments The client validated that prepared transactions carried the correct NetworkID on custom networks (id > 1024) but relied on the preparer to add the field. Insert it while building the payment so the default and custom preparers both start from a correct transaction; validation still rejects preparers that remove or replace it. * refactor(xrpl): reuse parseMoneyString from @x402/core Replace the server scheme's hand-rolled money-string parsing with the shared parseMoneyString helper used by the other mechanism packages, aligning string-price edge-case handling with the rest of the SDK. * test(e2e): cover both XRPL asset-transfer methods on every server Replace the single /exact/xrpl route with explicit sequence and ticketSequence endpoints on Express, Fastify, Hono, and Next (both the proxy middleware and withX402), pinning extra.assetTransferMethod and the issuer for issued-currency pricing in each route config. Teach the harness that asset transfer methods are not EVM-only metadata: xrpl endpoints resolve their declared method and default to sequence, and the server proxy forwards the configured issuer. * test(e2e): add a self-managed XRPL Testnet IOU fixture pnpm xrpl:iou:setup creates or reuses dedicated Testnet issuer, payer, and payee accounts, funds missing ones through the faucet, enables DefaultRipple on the issuer, establishes the trust lines, and issues test USD to the payer, replenishing it on re-runs. Credentials are persisted only in the git-ignored e2e/.env with 0600 permissions, seeds are never logged, and the script refuses to run unless the connected ledger reports Testnet network id 1. Mask seed values alongside private keys in the harness debug output. * fix(xrpl): reject duplicate settlements with a settlement cache Concurrent /settle calls carrying the same signed blob each passed verification, and because XRPL submission is idempotent on the transaction hash, submitAndWait resolved the same validated tesSUCCESS for every caller. The facilitator therefore returned success to all of them, letting a client access the resource N times while paying once. Add an in-memory SettlementCache (mirroring the SVM one) keyed on the signed transaction hash. settle() checks and inserts the key synchronously between re-verification and submission, so concurrent duplicates are serialized: the first proceeds, the rest return a duplicate_settlement error. Unlike Solana's protocol-fixed blockhash lifetime, an XRPL transaction stays landable until its LastLedgerSequence, which the scheme derives from maxTimeoutSeconds. Each entry's retention is sized to that window (plus a margin) rather than a flat interval, so an entry cannot be evicted while a slow-to-validate duplicate could still pass re-verification. Document the mitigation as REQUIRED in the spec, including the per-process scope and the shared-store requirement for horizontally scaled facilitators.
Follow-up to #2801, implementing the maintainer suggestion to add XRPL as an optional network on the x402.org testnet facilitator. Unlike the other optional networks, XRPL is gated on an explicit FACILITATOR_XRPL_ENABLED=true flag rather than a private key: in the XRPL exact scheme the payer signs the transaction and pays its fee, so the facilitator needs no key or funds — it only verifies and submits the pre-signed blob. An optional FACILITATOR_XRPL_TESTNET_WS_URL override is supported for deployments that prefer their own node over the default public testnet endpoint, mirroring the e2e facilitator's XRPL_WS_URL option.
* Update docs/sdk-features.md Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/sdk-features.md Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/schemes/exact.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…2856) * docs: add XRPL to buyer quickstart, network lists, and facilitators Complements #2854 (XRPL Setup in exact.mdx + sdk-features tables) with the remaining pages, mirroring how NEAR was documented in #2771: - quickstart-for-buyers: install line, XRPL signer section, multi-scheme registration example, and the summary package list - schemes/overview: add XRPL to the network implementations sentence - network-and-token-support: add the xrpl:<networkId> CAIP-2 identifier - dev-tools/facilitators: list the T54 XRPL facilitator (mainnet and testnet), which previously appeared on the ecosystem page removed in #2794 * docs: add XRPL to the token support table The Token Support ecosystem table and its intro sentence stopped at Concordium; add the XRPL row (XRP or any issued currency, transferred via a payer-signed Payment transaction) alongside the CAIP-2 identifier added in the previous commit. * docs: add XRPL to the network support summary bullet The Summary list at the bottom of network-and-token-support.mdx parallels the intro sentence updated in the previous commit; bring it in line so both lists end with the same network set.
* Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* SIWX configured-origin fix * py+go * updated docs
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.
Description
Tests
Checklist