-
Notifications
You must be signed in to change notification settings - Fork 637
support x402 v2 headers #8623
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
support x402 v2 headers #8623
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 845889c The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughAdds X402 v2 support: introduces versioned header constants and lookup helpers, expands types and schemas for v2, and makes payment header selection and x402Version assignment dynamic across decode, fetch, verify, and settle flows. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Server
participant Facilitator
Client->>Server: Request (no payment)
Server->>Client: 402 + payment header (name from getPaymentRequestHeader(x402Version))
Client->>Facilitator: Pay (uses PAYMENT-SIGNATURE / X-PAYMENT header variant per version)
Facilitator->>Server: Payment confirmation (includes x402Version and payment data)
Server->>Server: decodePaymentRequest (preserve client x402Version if present)
Server->>Client: Retry original request with payment response header (name from getPaymentResponseHeader)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/thirdweb/src/x402/headers.ts (1)
8-10: Consider stricter version validation to avoid silent fallback.The
resolveVersionfunction silently converts any non-1 value (including 0, 3, or other invalid numbers) to version 2. While the type signature acceptsnumber | X402Version, invalid inputs are masked rather than caught.Consider throwing for unsupported versions or validating against
supportedX402Versions:♻️ Suggested stricter validation
+import { type X402Version, x402Version, supportedX402Versions } from "./types.js"; + function resolveVersion(version?: number | X402Version): X402Version { - return version === 1 ? 1 : 2; + if (version === undefined) { + return x402Version; + } + if (!supportedX402Versions.includes(version as X402Version)) { + throw new Error(`Unsupported x402 version: ${version}`); + } + return version as X402Version; }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (8)
packages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/fetchWithPayment.test.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/headers.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/settle-payment.tspackages/thirdweb/src/x402/types.tspackages/thirdweb/src/x402/verify-payment.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoidanyandunknownin TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.) in TypeScript
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose
Files:
packages/thirdweb/src/x402/fetchWithPayment.test.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.tspackages/thirdweb/src/x402/headers.tspackages/thirdweb/src/x402/settle-payment.tspackages/thirdweb/src/x402/verify-payment.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Place tests alongside code:foo.ts↔foo.test.tsin the same directory
Use real function invocations with stub data in tests; avoid brittle mocks
Use Mock Service Worker (MSW) for fetch/HTTP call interception in tests
Keep tests deterministic and side-effect free
Use predefined test accounts fromtest/src/test-wallets.tsin tests
UseFORKED_ETHEREUM_CHAINfor mainnet interactions andANVIL_CHAINfor isolated tests
**/*.test.{ts,tsx}: Co-locate tests with source files using the pattern foo.ts ↔ foo.test.ts
Use real function invocations with stub data in tests; avoid brittle mocks
For network interactions in tests, use Mock Service Worker (MSW) to intercept fetch/HTTP calls, mocking only scenarios that are hard to reproduce
Keep tests deterministic and side-effect free; Vitest is pre-configured
Files:
packages/thirdweb/src/x402/fetchWithPayment.test.ts
packages/thirdweb/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g.const { jsPDF } = await import("jspdf");)Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)
Files:
packages/thirdweb/src/x402/fetchWithPayment.test.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.tspackages/thirdweb/src/x402/headers.tspackages/thirdweb/src/x402/settle-payment.tspackages/thirdweb/src/x402/verify-payment.ts
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Biome governs formatting and linting; its rules live in biome.json. Run
pnpm fix&pnpm lintbefore committing, ensure there are no linting errors
Files:
packages/thirdweb/src/x402/fetchWithPayment.test.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.tspackages/thirdweb/src/x402/headers.tspackages/thirdweb/src/x402/settle-payment.tspackages/thirdweb/src/x402/verify-payment.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/x402/fetchWithPayment.test.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.tspackages/thirdweb/src/x402/headers.tspackages/thirdweb/src/x402/settle-payment.tspackages/thirdweb/src/x402/verify-payment.ts
🧬 Code graph analysis (6)
packages/thirdweb/src/x402/fetchWithPayment.test.ts (1)
packages/thirdweb/src/x402/headers.ts (1)
getPaymentRequestHeader(12-17)
packages/thirdweb/src/x402/common.ts (1)
packages/thirdweb/src/x402/types.ts (1)
x402Version(16-16)
packages/thirdweb/src/x402/fetchWithPayment.ts (2)
packages/thirdweb/src/x402/types.ts (1)
x402Version(16-16)packages/thirdweb/src/x402/headers.ts (2)
getPaymentRequestHeader(12-17)getPaymentResponseHeader(19-26)
packages/thirdweb/src/x402/headers.ts (1)
packages/thirdweb/src/x402/types.ts (2)
X402Version(15-15)x402Version(16-16)
packages/thirdweb/src/x402/settle-payment.ts (2)
packages/thirdweb/src/x402/headers.ts (1)
getPaymentResponseHeader(19-26)packages/thirdweb/src/x402/types.ts (1)
x402Version(16-16)
packages/thirdweb/src/x402/verify-payment.ts (1)
packages/thirdweb/src/x402/types.ts (1)
x402Version(16-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (17)
packages/thirdweb/src/x402/headers.ts (1)
12-26: LGTM!The header resolution functions are well-structured with clear return types. The default fallback to
x402Versionwhen no version is provided ensures backward compatibility.packages/thirdweb/src/x402/types.ts (2)
14-16: LGTM!The versioning implementation using
as constwith a derived type provides type safety while keeping the supported versions maintainable. The default version set to 2 aligns with the PR objective of supporting x402 v2 headers.
28-31: LGTM!The JSDoc update accurately documents both header names (PAYMENT-SIGNATURE for v2, X-PAYMENT for v1), which improves discoverability for developers.
packages/thirdweb/src/x402/common.ts (1)
54-55: LGTM!The nullish coalescing assignment (
??=) correctly preserves the client-provided version while defaulting to the current protocol version when missing. This is essential for proper multi-version support where clients may send either v1 or v2 payments.packages/thirdweb/src/x402/fetchWithPayment.test.ts (3)
4-4: LGTM!Good addition of the
getPaymentRequestHeaderimport to enable dynamic header validation in tests.
113-117: LGTM!The assertion now properly validates that the payment header name is dynamically determined based on the
x402Versionfrom the mock response. This ensures the implementation correctly handles version-specific headers.
307-311: Good backward compatibility test coverage.This test validates that v1 payloads (with
x402Version: 1in the base64-encoded header) correctly use the v1 header name (X-PAYMENT). This ensures backward compatibility with existing v1 servers.packages/thirdweb/src/x402/verify-payment.ts (2)
32-34: LGTM!The JSDoc example correctly demonstrates the header fallback pattern (v2
payment-signaturefirst, then v1x-payment), providing clear guidance for implementers.
126-126: LGTM!Using
decodedPayment.x402Version ?? x402Versionin error responses ensures the 402 response uses the same protocol version as the client's request. This maintains consistency and allows clients to properly interpret error responses.Also applies to: 142-142
packages/thirdweb/src/x402/schemas.ts (1)
85-85: LGTM!The schema correctly expands to accept both X402 protocol versions using a union of literals, maintaining strict type validation while enabling v2 support.
packages/thirdweb/src/x402/settle-payment.ts (4)
4-4: LGTM!Import correctly added for dynamic header name resolution.
41-43: LGTM!Example code correctly demonstrates reading payment data from both v2 (
payment-signature) and v1 (x-payment) headers with appropriate fallback for backward compatibility.Also applies to: 110-111
158-173: LGTM!The dynamic header name resolution correctly uses the client's provided
x402Versionfrom the decoded payment, ensuring the response header matches the version the client used in their request.
184-184: Verify the default version fallback behavior in error responses.The nullish coalescing
decodedPayment.x402Version ?? x402Versionfalls back to the default version (v2) whenx402Versionis missing from the decoded payment. This means error responses may advertise v2 even if the client originally used v1 but didn't include the version field.If this is intentional (to encourage clients to upgrade), the current implementation is fine. Otherwise, consider preserving the version from the original 402 response requirements if available.
Also applies to: 200-200
packages/thirdweb/src/x402/fetchWithPayment.ts (3)
8-11: LGTM!Clean imports with appropriate aliasing. Renaming to
defaultX402Versionclearly distinguishes the module-level default from the locally-scopedx402Versionvariable parsed from responses.Also applies to: 20-20
104-104: LGTM!Fallback to
defaultX402Versionensures backward compatibility with servers that don't includex402Versionin their 402 responses. This correctly defaults to v2 for such cases.Also applies to: 122-122
188-202: LGTM!Dynamic header name resolution correctly uses the version from the server's 402 response, ensuring the payment request and expected response headers match the protocol version the server indicated.
size-limit report 📦
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8623 +/- ##
==========================================
+ Coverage 53.00% 53.02% +0.02%
==========================================
Files 929 930 +1
Lines 62109 62136 +27
Branches 4077 4088 +11
==========================================
+ Hits 32921 32949 +28
+ Misses 29089 29088 -1
Partials 99 99
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
.changeset/eight-pants-drum.md (1)
1-5: Consider a more descriptive changeset message.The current description "Support x402 v2" is minimal. Consider expanding it to briefly explain what x402 v2 support includes (e.g., "Add support for x402 v2 protocol with backward compatibility for v1, including versioned headers and dynamic header selection").
Additionally, verify whether this should be a
minorversion bump rather thanpatch, as adding support for a new protocol version typically constitutes a feature addition rather than a bug fix.📝 More descriptive changeset example
--- "thirdweb": patch --- -Support x402 v2 +Add x402 v2 protocol support with backward compatibility for v1, including versioned headers and dynamic version detection
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.changeset/eight-pants-drum.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Build Packages
- GitHub Check: Size
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
PR-Codex overview
This PR focuses on updating the
x402payment protocol to support version 2, enhancing payment header management, and ensuring backward compatibility with version 1. It modifies schemas, types, and payment handling functions to accommodate the new version.Detailed summary
x402Versionto support both version 1 and 2.decodedPayment.x402Versionassignment to preserve client-provided version.X-PAYMENT) and version 2 (PAYMENT-SIGNATURE).Summary by CodeRabbit
New Features
Improvements
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.