Skip to content

Bump @x402 dev set to 2.29.0 and exempt it from the release-age soak - #164

Merged
vvillait88 merged 3 commits into
mainfrom
x402-2.29.0
Oct 28, 2026
Merged

vvillait88 merged 3 commits into
mainfrom
x402-2.29.0

Conversation

@vvillait88

@vvillait88 vvillait88 commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Moves the @x402/core, @x402/evm and @x402/extensions dev pins from 2.28.0 to 2.29.0, so the suite runs against the version the storefronts ship, and adds the @x402 set to minimumReleaseAgeExcludes. The set is exact-pinned, so the pin is the gate for the version, the same as for viem and mppx.

2.29.0 changes on the paths this package uses (the resource server and the EVM exact and upto server schemes):

  • core: network ids are validated against a strict pattern, a settlement override above the authorized amount now throws, accepts is capped at 1024 entries, and facilitator response bodies are capped at 1 MiB.
  • core: afterSettle hooks can fail a settle closed with the new AfterSettleAbortError. Other hook errors are still logged and ignored.
  • evm: the exact and upto server schemes are unchanged.
  • core now depends on zod 4.

Also refreshes qs (dev only, through express) from 6.16.0 to 6.17.0 in the lockfile. The dependency scan failed this branch on GHSA-6pq8-jhm2-2vcw, a medium advisory on 6.16.0 fixed in 6.16.1 and published after main last scanned.

Also pins @x402/core to 2.29.0 in overrides. @coinbase/x402 requires @x402/core ^2.0.0 and kept its own 2.26.0 copy, so the name-matched release-age exemption would otherwise let a lock regeneration resolve that caret range to an hours-old core.

Type of change

  • Bug fix (no breaking change)
  • New feature (no breaking change)
  • Breaking change (existing callers must update)
  • Docs, tests, or internal maintenance only

Public API

None. The @x402 packages are dev dependencies loaded through optional dynamic imports; the published manifest's dependencies and peer ranges are unchanged.

Test plan

On this branch: bun install resolves 2.29.0 for every @x402 package. bun run lint, typecheck, test (109 files, 1637 tests passed, 4 skipped) and knip all exit 0.

Checklist

  • Tests cover the new behavior, and the suite passes locally
  • Lint, format, and type checks pass
  • Docs and README examples updated if the public surface changed (no public surface change)
  • No secrets, credentials, or personal data in the diff or the tests

2.29.0 moves @x402/core to zod 4, dropping the nested zod 3.25.76 copies
under @x402/* that carry CVE-2023-54404. The set is exact-pinned, so the
pin plus a read of the dist diff is the gate and the 24h soak is lifted
for it, matching viem and mppx.
qs 6.16.0, pulled in through the express dev dependency, carries a
medium advisory fixed in 6.16.1; the dependency scan fails on it.
@vvillait88

Copy link
Copy Markdown
Contributor Author

Review: x402 2.29.0 dev pins plus the qs refresh

Verdict: nothing blocks this PR. This comment is the approval. Reviewed at head d75ab32, which includes both commits.

Upstream diff, 2.28.0 vs 2.29.0 (npm pack of both, dist read directly; tarball integrity matches the lock for all five packages):

  • @x402/hono: dist byte-identical; only package.json moves (deps to ~2.29.0, peer hono >=4.13.7 <5, satisfied by our ^4.13.14).
  • @x402/evm: exact/server and upto/server dist unchanged (0 diff lines). Client side adds a one-time console.warn when gas sponsoring is advertised and the signer has no readContract; changes elsewhere are facilitator-only (EIP-6492 code-lookup handling, auth-capture/batch-settlement shapes).
  • @x402/core: (a) NetworkSchemaV2 is now /^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$/; every network id we emit passes (eip155:8453, eip155:84532, eip155:4217, eip155:42431, both Solana CAIP-2 refs at 32 chars), probed with node. Only a wildcard like eip155:* fails, and none of our repos put one on the wire. (b) accepts capped at 1024. (c) Facilitator responses read through a 1 MiB cap. (d) A settlement override above requirements.amount now throws. (e) HTTP route matching: HEAD falls back to GET routes and * no longer matches OPTIONS. (f) An unpaid 402 from x402HTTPResourceServer now carries {error} when no custom body is set. (g) afterSettle gains an opt-in AfterSettleAbortError. (h) The resource-server verify hook code is unchanged; only its doc comments changed. The isValid:false re-route from onVerifyFailure to onAfterVerify is in x402Facilitator only.
  • @x402/extensions bazaar: enrichDeclaration now forces the declared method to the body set (POST/PUT/PATCH) when info.input.bodyType is set, and to GET/HEAD/DELETE otherwise.
  • @x402/fetch: 402 bodies are read through the same 1 MiB cap, and a 402 returned after payment is re-wrapped as a fresh Response.

Effect on this library's paths: the @x402/* packages are dev-only here; consumers install their own, and they are not peers. createX402Server uses only constructors that are unchanged in 2.29.0 (x402ResourceServer, HTTPFacilitatorClient, ExactEvmScheme/UptoEvmScheme from the unchanged server dists, bazaarResourceServerExtension). processX402Settle calls settlePayment without the settlement-override argument, so the new override cap can't fire from our helper; settlementOverrideHeader only formats a header. Nothing in src uses x402HTTPResourceServer route matching or imports zod. One semantic change does reach enrichBazaarDiscoveryExtensions: a declaration with no bodyType on a POST request now enriches to GET. In 2.28.0 it enriched to POST, which upstream's own validator rejects anyway, so 2.29.0 is the consistent result. All three hosted storefronts declare bodyType: 'json', so their discovery output does not change.

Lockfile: @x402/core, @x402/evm and @x402/extensions all resolve to 2.29.0, with 0 occurrences of 2.28.0. Each now nests zod 4.6.7 because this repo's top-level zod is 3.25.76; that accounts for the 843 to 846 package count. The @coinbase/x402/@x402/core@2.26.0 nested copy is unchanged from main.

qs commit (d75ab32): the lock diff is +1 -3. Top-level qs moves from 6.16.0 to 6.17.0, and the nested body-parser/qs@6.16.1 collapses into it. 6.17.0 was published 2026-10-27 06:23 UTC, more than 24h before this review, so the soak covers it and it needs no exclude (it has none). Dependency Scan passes on this head.

bunfig: identical to the three storefronts; pay has the same list plus incur. Every name in the list is exact-pinned here or is not installed at all.

CI at d75ab32: 9 of 9 rows pass (ci, node-compat 22/24/26, Dependency Scan, CodeQL, three Analyze jobs).

Non-blocking, on main before this PR: BazaarDiscoveryConfig in src/discovery/bazaar.ts types bodyType as 'json' | 'form'. Upstream's VALID_BODY_TYPES is json, form-data, text in both 2.28.0 and 2.29.0, so a merchant following our type with 'form' gets a declaration that fails validation. This is worth a separate fix to 'json' | 'form-data' | 'text'.

@coinbase/x402 requires @x402/core ^2.0.0 and kept its own 2.26.0 copy.
With the set exempt from the release-age soak by name, a lock regeneration
could resolve that caret range to an hours-old core; the override holds
every copy at the exact pin and leaves one core on the rail.
@vvillait88

Copy link
Copy Markdown
Contributor Author

Round 2 re-check (head 7313543)

The finding is closed. Nothing blocks this PR, and the approval stands.

  • Override: overrides now pins "@x402/core": "2.29.0", mirrored in the lock's overrides block. There is one @x402/core entry (2.29.0), and the nested @coinbase/x402/@x402/core@2.26.0 is gone. The only reference @coinbase/x402@2.1.0 makes to core is a type import (FacilitatorConfig from @x402/core/http, which 2.29.0 still exports), so nothing changes at runtime. This repo is a library, so the override governs only its own dev install and never reaches consumers. That's the intended scope.
  • Lock: the qs 6.17.0 change from the previous commit is still in place. The package count goes from 846 to 844 (the nested core and its zod 3 copy are gone).
  • CI on this head: 9 of 9 rows pass.
  • Merge order with Type Bazaar bodyType as json, form-data or text #165: Type Bazaar bodyType as json, form-data or text #165 is cut from main, and its Dependency Scan currently fails on the same qs 6.16.0 advisory that this PR fixes (OSV GHSA-6pq8-jhm2-2vcw, read from that run's log). Merge this PR first, then update Type Bazaar bodyType as json, form-data or text #165 from main and confirm its scan is green.

@vvillait88
vvillait88 merged commit 42827d7 into main Oct 28, 2026
9 checks passed
@vvillait88
vvillait88 deleted the x402-2.29.0 branch October 28, 2026 22:10
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