-
Notifications
You must be signed in to change notification settings - Fork 627
[SDK] Add payment scheme and improve type documentation for x402 #8457
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
[SDK] Add payment scheme and improve type documentation for x402 #8457
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 797573a 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 |
WalkthroughThe PR introduces support for dynamic pricing via an "upto" payment scheme alongside the existing "exact" scheme in the x402 payment system. Changes include new PaymentScheme type definitions, schema updates, payment flow logic modifications to handle scheme-based pricing, comprehensive documentation updates with code examples, and a UI component enhancement for displaying optional descriptions. Changes
Sequence DiagramsequenceDiagram
actor Client
participant API
participant Facilitator
participant Payment System
Note over Client,Payment System: Exact Scheme Flow
Client->>API: verifyPayment(scheme: "exact")
API->>Facilitator: accepts(args with scheme)
Facilitator-->>API: payment requirements
Client->>API: settlePayment(price: fixed)
API-->>Client: settled
Note over Client,Payment System: Upto Scheme Flow
Client->>API: verifyPayment(scheme: "upto")
API->>Facilitator: accepts(args with scheme)
Facilitator-->>API: payment requirements (upto)
Client->>API: expensive operation
Note right of Client: actual usage measured
Client->>API: settlePayment(tokensUsed: actual)
API-->>Client: settled with final price
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (11)
💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (6)
🧰 Additional context used📓 Path-based instructions (4)**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
packages/thirdweb/src/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{js,jsx,ts,tsx,json}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (13)📚 Learning: 2025-06-26T19:46:04.024ZApplied to files:
📚 Learning: 2025-06-03T23:44:40.243ZApplied to files:
📚 Learning: 2025-11-24T22:45:01.202ZApplied to files:
📚 Learning: 2025-11-24T22:43:43.644ZApplied to files:
📚 Learning: 2025-11-24T22:45:01.202ZApplied to files:
📚 Learning: 2025-11-24T22:45:01.202ZApplied to files:
📚 Learning: 2025-11-24T22:45:01.202ZApplied to files:
📚 Learning: 2025-11-24T22:44:20.977ZApplied to files:
📚 Learning: 2025-11-24T22:44:20.977ZApplied to files:
📚 Learning: 2025-11-24T22:45:01.202ZApplied to files:
📚 Learning: 2025-11-24T22:43:43.644ZApplied to files:
📚 Learning: 2025-08-28T20:50:33.170ZApplied to files:
📚 Learning: 2025-11-24T22:43:43.644ZApplied to files:
🧬 Code graph analysis (2)packages/thirdweb/src/x402/common.ts (1)
packages/thirdweb/src/x402/fetchWithPayment.ts (1)
🪛 LanguageToolapps/portal/src/app/x402/server/page.mdx[uncategorized] ~88-~88: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL) ⏰ 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). (3)
🔇 Additional comments (8)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Comment |
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
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: 1
🧹 Nitpick comments (1)
packages/thirdweb/src/x402/types.ts (1)
106-106: Consider adding JSDoc for the new public type.While the type definition is correct, adding TSDoc would improve discoverability and understanding for consumers of this public API. Consider documenting what "exact" vs "upto" means in the payment context.
Example documentation:
+/** + * Specifies how payment amounts should be interpreted in the X402 protocol. + * - "exact": Payment must match the specified amount exactly + * - "upto": Payment can be up to the specified amount (inclusive) + * + * @public + */ export type PaymentScheme = "exact" | "upto";
📜 Review details
Configuration used: CodeRabbit 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 (2)
.changeset/chilly-taxis-search.md(1 hunks)packages/thirdweb/src/x402/types.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/types.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/types.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/types.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/x402/types.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Use `patch` version bump for changes that don't impact the public API
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to packages/**/.changeset/*.md : Each change in packages/* should contain a changeset for the appropriate package with the appropriate version bump: patch for changes that don't impact the public API, minor for any new/modified public API
Applied to files:
.changeset/chilly-taxis-search.md
📚 Learning: 2025-06-26T19:46:04.024Z
Learnt from: gregfromstl
Repo: thirdweb-dev/js PR: 7450
File: packages/thirdweb/src/bridge/Webhook.ts:57-81
Timestamp: 2025-06-26T19:46:04.024Z
Learning: In the onramp webhook schema (`packages/thirdweb/src/bridge/Webhook.ts`), the `currencyAmount` field is intentionally typed as `z.number()` while other amount fields use `z.string()` because `currencyAmount` represents fiat currency amounts in decimals (like $10.50), whereas other amount fields represent token amounts in wei (very large integers that benefit from bigint representation). The different naming convention (`currencyAmount` vs `amount`) reflects this intentional distinction.
Applied to files:
packages/thirdweb/src/x402/types.ts
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to packages/thirdweb/src/exports/**/*.{ts,tsx} : Export everything in packages/thirdweb via the exports/ directory, grouped by feature. Every public symbol must have comprehensive TSDoc including at least one example block that compiles and one custom annotation (beta, internal, experimental, etc.)
Applied to files:
packages/thirdweb/src/x402/types.ts
🧬 Code graph analysis (1)
packages/thirdweb/src/x402/types.ts (2)
packages/thirdweb/src/x402/schemas.ts (1)
RequestedPaymentPayload(22-24)packages/thirdweb/src/exports/x402.ts (1)
ERC20TokenAmount(17-17)
⏰ 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: Size
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
packages/thirdweb/src/x402/types.ts (2)
94-97: LGTM! Clear documentation for new verification result fields.The added fields properly extend the verification result with decoded payment information and selected requirements, with appropriate type references.
108-126: LGTM! Well-structured type extension with clear documentation.The additions properly extend
ERC20TokenAmountwith:
- Optional
schemefield for payment flexibility (backward compatible)- Enhanced
assetdocumentation explaining inference behavior- Optional
eip712metadata for explicit EIP-712 typingThe optional fields and default behavior ("exact" scheme) ensure backward compatibility while enabling the new "upto" payment scheme.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8457 +/- ##
=======================================
Coverage 54.82% 54.82%
=======================================
Files 919 919
Lines 60875 60875
Branches 4142 4141 -1
=======================================
Hits 33374 33374
Misses 27399 27399
Partials 102 102
🚀 New features to boost your workflow:
|
size-limit report 📦
|
4930f63 to
de7e2eb
Compare
de7e2eb to
35273ba
Compare
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: 3
🧹 Nitpick comments (1)
packages/thirdweb/src/x402/common.ts (1)
38-41: Type mismatch: passing fullargstofacilitator.accepts.The
facilitator.acceptsmethod expectsOmit<PaymentArgs, "facilitator">, butargsis of typePaymentArgswhich includes thefacilitatorproperty. While this may work at runtime (the extra property is ignored), it's a type inconsistency.Consider spreading without the facilitator:
- const paymentRequirementsResult = await facilitator.accepts(args); + const { facilitator: _, ...acceptsArgs } = args; + const paymentRequirementsResult = await facilitator.accepts(acceptsArgs);Or alternatively:
- const { facilitator, routeConfig = {}, paymentData } = args; + const { facilitator, routeConfig = {}, paymentData, ...acceptsArgs } = args; - const paymentRequirementsResult = await facilitator.accepts(args); + const paymentRequirementsResult = await facilitator.accepts({ ...acceptsArgs, routeConfig });
📜 Review details
Configuration used: CodeRabbit 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 (10)
.changeset/chilly-taxis-search.md(1 hunks)apps/portal/src/app/x402/page.mdx(0 hunks)apps/portal/src/app/x402/server/page.mdx(8 hunks)packages/thirdweb/src/x402/common.ts(1 hunks)packages/thirdweb/src/x402/facilitator.ts(1 hunks)packages/thirdweb/src/x402/fetchWithPayment.ts(2 hunks)packages/thirdweb/src/x402/schemas.ts(3 hunks)packages/thirdweb/src/x402/settle-payment.ts(1 hunks)packages/thirdweb/src/x402/types.ts(4 hunks)packages/thirdweb/src/x402/verify-payment.ts(1 hunks)
💤 Files with no reviewable changes (1)
- apps/portal/src/app/x402/page.mdx
✅ Files skipped from review due to trivial changes (1)
- packages/thirdweb/src/x402/settle-payment.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- .changeset/chilly-taxis-search.md
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/facilitator.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/verify-payment.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.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/facilitator.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/verify-payment.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.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/facilitator.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/verify-payment.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/x402/facilitator.tspackages/thirdweb/src/x402/common.tspackages/thirdweb/src/x402/verify-payment.tspackages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.ts
🧠 Learnings (9)
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Import UI primitives from @/components/ui/_ (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in Dashboard and Playground apps
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Use NavLink for internal navigation so active states are handled automatically
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Client Components: Begin files with 'use client'; before imports, handle interactive UI relying on React hooks (useState, useEffect, React Query, wallet hooks), access browser APIs (localStorage, window, IntersectionObserver, etc.), and support fast transitions with client-side data prefetching
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:44:20.977Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-11-24T22:44:20.977Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Always import from the central UI library under `@/components/ui/*` for reusable core UI components like `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:44:20.977Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-11-24T22:44:20.977Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use `NavLink` from `@/components/ui/NavLink` for internal navigation to ensure active states are handled automatically
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-08-28T20:50:33.170Z
Learnt from: joaquim-verges
Repo: thirdweb-dev/js PR: 7922
File: apps/playground-web/src/app/ai/ai-sdk/components/chat-container.tsx:167-181
Timestamp: 2025-08-28T20:50:33.170Z
Learning: The thirdweb-dev/ai-sdk-provider schemas use snake_case field naming convention (e.g., chain_id, transaction_hash) rather than camelCase, as defined in the zod schemas in packages/ai-sdk-provider/src/tools.ts.
Applied to files:
packages/thirdweb/src/x402/schemas.ts
📚 Learning: 2025-06-26T19:46:04.024Z
Learnt from: gregfromstl
Repo: thirdweb-dev/js PR: 7450
File: packages/thirdweb/src/bridge/Webhook.ts:57-81
Timestamp: 2025-06-26T19:46:04.024Z
Learning: In the onramp webhook schema (`packages/thirdweb/src/bridge/Webhook.ts`), the `currencyAmount` field is intentionally typed as `z.number()` while other amount fields use `z.string()` because `currencyAmount` represents fiat currency amounts in decimals (like $10.50), whereas other amount fields represent token amounts in wei (very large integers that benefit from bigint representation). The different naming convention (`currencyAmount` vs `amount`) reflects this intentional distinction.
Applied to files:
packages/thirdweb/src/x402/schemas.tspackages/thirdweb/src/x402/types.ts
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to packages/thirdweb/src/exports/**/*.{ts,tsx} : Export everything in packages/thirdweb via the exports/ directory, grouped by feature. Every public symbol must have comprehensive TSDoc including at least one example block that compiles and one custom annotation (beta, internal, experimental, etc.)
Applied to files:
packages/thirdweb/src/x402/schemas.ts
📚 Learning: 2025-06-03T23:44:40.243Z
Learnt from: joaquim-verges
Repo: thirdweb-dev/js PR: 7268
File: packages/thirdweb/src/wallets/in-app/core/wallet/in-app-core.ts:210-216
Timestamp: 2025-06-03T23:44:40.243Z
Learning: EIP7702 wallets do not need special handling for switching chains, unlike EIP4337 wallets which require reconnection when switching chains. In the switchChain method condition, EIP7702 should be intentionally excluded from the reconnection logic.
Applied to files:
packages/thirdweb/src/x402/fetchWithPayment.ts
🧬 Code graph analysis (3)
packages/thirdweb/src/x402/common.ts (1)
packages/thirdweb/src/x402/facilitator.ts (1)
facilitator(112-305)
packages/thirdweb/src/x402/schemas.ts (1)
packages/thirdweb/src/x402/types.ts (1)
PaymentSchemeSchema(108-111)
packages/thirdweb/src/x402/types.ts (2)
packages/thirdweb/src/x402/schemas.ts (1)
RequestedPaymentPayload(24-26)packages/thirdweb/src/exports/x402.ts (1)
ERC20TokenAmount(17-17)
⏰ 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). (1)
- GitHub Check: Size
🔇 Additional comments (11)
packages/thirdweb/src/x402/types.ts (2)
108-112: LGTM! Well-defined payment scheme type.The
PaymentSchemeSchemausing Zod'sz.unionwith literals ensures type safety and runtime validation. The inferredPaymentSchemetype properly derives from the schema.
114-129: The JSDoc comment forERC20TokenAmountis misleading, but the type definition itself is correct.The
schemefield is correctly defined at thePaymentArgslevel (line 35:scheme?: PaymentScheme;), not withinERC20TokenAmount. The JSDoc comment at line 115 stating "The asset, scheme and amount for the payment in base units" should be corrected to only reference "The asset and amount" since theschemebelongs to the broader payment configuration, not the token amount specification itself.The type definition is structurally correct and requires no field additions. Only the documentation comment needs fixing.
packages/thirdweb/src/x402/schemas.ts (3)
19-22: LGTM! Schema extensions properly include payment scheme.The
RequestedPaymentPayloadSchemacorrectly extends the base schema with bothnetworkandschemefields.
34-38: LGTM! Payment requirements schema updated consistently.The
RequestedPaymentRequirementsSchemamirrors the payload schema extension, ensuring consistency across the payment flow.
77-94: LGTM! Facilitator response schema updated to support multiple schemes.The
FacilitatorSupportedResponseSchemanow usesPaymentSchemeSchemainstead of a hardcoded literal, enabling support for both "exact" and "upto" schemes in the facilitator's supported kinds response.packages/thirdweb/src/x402/facilitator.ts (1)
276-286: LGTM! Scheme field properly passed to facilitator.The
schemefield is correctly included in theacceptsrequest payload. Since it's optional inPaymentArgs, undefined values will be serialized and the server should handle the default case appropriately.packages/thirdweb/src/x402/common.ts (1)
71-76: LGTM! Payment requirement matching includes scheme.The selection logic correctly matches both
schemeandnetworkfrom the decoded payment against the available requirements, ensuring the correct payment requirement is selected for the given scheme.packages/thirdweb/src/x402/fetchWithPayment.ts (1)
74-76: LGTM! Simplified payment requirements parsing.Removing the scheme-based filtering is appropriate since the server now handles scheme-aware responses. All requirements are parsed and the selection logic handles choosing the appropriate one.
apps/portal/src/app/x402/server/page.mdx (3)
1-20: LGTM!Metadata restructuring with nested image object is clean and properly formatted.
112-144: LGTM!Price and token configuration section is clear and comprehensive, with good examples for all supported formats.
184-189: I'll help you verify this review comment about inconsistentmaxTimeoutSecondshandling across the examples. Let me start by examining the actual file content.
<function_calls>
#!/bin/bashFirst, get the file and check its line count
wc -l apps/portal/src/app/x402/server/page.mdx
</function_calls>
<function_calls>
#!/bin/bashRead the sections mentioned in the review comment
Lines 180-310 to cover all dedicated endpoint examples
sed -n '180,310p' apps/portal/src/app/x402/server/page.mdx | cat -n
</function_calls>
<function_calls>
#!/bin/bashRead the middleware section
Lines 312-494
sed -n '312,494p' apps/portal/src/app/x402/server/page.mdx | cat -n
</function_calls>Let me search for all occurrences of
maxTimeoutSecondsin this file to get a complete picture:
<function_calls>
#!/bin/bashSearch for all maxTimeoutSeconds occurrences with context
rg -n 'maxTimeoutSeconds' apps/portal/src/app/x402/server/page.mdx -B 3 -A 3
</function_calls>Now let me examine the specific line ranges mentioned in the review comment:
<function_calls>
#!/bin/bashCheck lines 184-189 (Next.js dedicated endpoint - claimed to be missing maxTimeoutSeconds)
echo "=== Lines 184-189 (Next.js dedicated - should be missing maxTimeoutSeconds) ==="
sed -n '184,189p' apps/portal/src/app/x402/server/page.mdx | cat -necho ""
echo "=== Lines 233-237 (Express dedicated - should have maxTimeoutSeconds) ==="
sed -n '233,237p' apps/portal/src/app/x402/server/page.mdx | cat -necho ""
echo "=== Lines 286-290 (Hono dedicated - should have maxTimeoutSeconds) ==="
sed -n '286,290p' apps/portal/src/app/x402/server/page.mdx | cat -necho ""
echo "=== Lines 353-357 (Next.js middleware - should have maxTimeoutSeconds) ==="
sed -n '353,357p' apps/portal/src/app/x402/server/page.mdx | cat -necho ""
echo "=== Lines 411-415 (Express middleware - should have maxTimeoutSeconds) ==="
sed -n '411,415p' apps/portal/src/app/x402/server/page.mdx | cat -necho ""
echo "=== Lines 466-470 (Hono middleware - should have maxTimeoutSeconds) ==="
sed -n '466,470p' apps/portal/src/app/x402/server/page.mdx | cat -n
</function_calls><shell_result>
=== Lines 184-189 (Next.js dedicated - should be missing maxTimeoutSeconds) ===
1 184 routeConfig: {
2 185 description: "Access to premium API content",
3 186 mimeType: "application/json",
4 187 },
5 188 });
6 189
7
=== Lines 233-237 (Express dedicated - should have maxTimeoutSeconds) ===
1 233 routeConfig: {
2 234 description: "Access to premium API content",
3 235 mimeType: "application/json",
4 236 },
5 237 });
6
=== Lines 286-290 (Hono dedicated - should have maxTimeoutSeconds) ===
1 286 routeConfig: {
2 287 description: "Access to purple API content",
3 288 mimeType: "application/json",
4 289 },
10 291 });
11 292=== Lines 353-357 (Next.js middleware - should have maxTimeoutSeconds) ===
1 353 routeConfig: {
2 354 description: "Check if user is premium",
3 mimeType: "application/json",
4 },
5 357 });
6=== Lines 411-415 (Express middleware - should have maxTimeoutSeconds) ===
1 411 routeConfig: {
2 412 description: "Check if user is premium",
3 413 mimeType: "application/json",
4 414 },
5 415 });
6=== Lines 466-470 (Hono middleware - should have maxTimeoutSeconds) ===
1 466 routeConfig: {
2 467 description: "Check if user is purple",
3 mimeType: "application/json",
4 },
5 470 });
</function_calls>Perfect! I now have clear verification. The review comment is incorrect. Let me verify the search results one more time to be absolutely certain:
<function_calls>
#!/bin/bashComprehensive verification: search entire file for maxTimeoutSeconds
echo "Total occurrences of 'maxTimeoutSeconds' in the file:"
rg 'maxTimeoutSeconds' apps/portal/src/app/x402/server/page.mdx | wc -lecho ""
echo "Any matches found:"
rg 'maxTimeoutSeconds' apps/portal/src/app/x402/server/page.mdx
</function_calls><shell_result>
Total occurrences of 'maxTimeoutSeconds' in the file:
0
</shell_resultBased on my thorough verification of the file, the review comment is factually incorrect.
The review comment incorrectly identifies an inconsistency that does not exist. All six examples (Next.js dedicated, Express dedicated, Hono dedicated, Next.js middleware, Express middleware, and Hono middleware) are consistently missing
maxTimeoutSeconds. There are zero occurrences ofmaxTimeoutSecondsanywhere in the file. The review comment claims that only the Next.js dedicated endpoint omits it while all others includemaxTimeoutSeconds: 300, but this is contradicted by the actual file content.Likely an incorrect or invalid review comment.
35273ba to
2a22c08
Compare
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: 2
♻️ Duplicate comments (1)
packages/thirdweb/src/x402/fetchWithPayment.ts (1)
167-179: Default selector still ignores scheme - already flagged.The past review comment correctly identified that
defaultPaymentRequirementsSelectormatches only bychainId(line 169) and doesn't consider scheme. This could be problematic if a server returns multiple payment requirements with different schemes for the same chain.However, this may be intentional for client-side usage where the client doesn't necessarily have a scheme preference. The server-side matching in
common.ts(lines 71-75) properly matches by bothschemeandnetwork.
📜 Review details
Configuration used: CodeRabbit 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 (10)
.changeset/chilly-taxis-search.md(1 hunks)apps/portal/src/app/x402/page.mdx(0 hunks)apps/portal/src/app/x402/server/page.mdx(8 hunks)packages/thirdweb/src/x402/common.ts(1 hunks)packages/thirdweb/src/x402/facilitator.ts(1 hunks)packages/thirdweb/src/x402/fetchWithPayment.ts(2 hunks)packages/thirdweb/src/x402/schemas.ts(3 hunks)packages/thirdweb/src/x402/settle-payment.ts(1 hunks)packages/thirdweb/src/x402/types.ts(4 hunks)packages/thirdweb/src/x402/verify-payment.ts(1 hunks)
💤 Files with no reviewable changes (1)
- apps/portal/src/app/x402/page.mdx
✅ Files skipped from review due to trivial changes (2)
- packages/thirdweb/src/x402/verify-payment.ts
- packages/thirdweb/src/x402/settle-payment.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/thirdweb/src/x402/schemas.ts
- .changeset/chilly-taxis-search.md
- packages/thirdweb/src/x402/facilitator.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/types.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/common.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/types.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/common.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/types.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/common.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Lazy-import optional features; avoid top-level side-effects
Files:
packages/thirdweb/src/x402/types.tspackages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/common.ts
🧠 Learnings (8)
📚 Learning: 2025-06-26T19:46:04.024Z
Learnt from: gregfromstl
Repo: thirdweb-dev/js PR: 7450
File: packages/thirdweb/src/bridge/Webhook.ts:57-81
Timestamp: 2025-06-26T19:46:04.024Z
Learning: In the onramp webhook schema (`packages/thirdweb/src/bridge/Webhook.ts`), the `currencyAmount` field is intentionally typed as `z.number()` while other amount fields use `z.string()` because `currencyAmount` represents fiat currency amounts in decimals (like $10.50), whereas other amount fields represent token amounts in wei (very large integers that benefit from bigint representation). The different naming convention (`currencyAmount` vs `amount`) reflects this intentional distinction.
Applied to files:
packages/thirdweb/src/x402/types.tspackages/thirdweb/src/x402/fetchWithPayment.ts
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Applies to packages/thirdweb/src/**/*.{ts,tsx} : Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Import UI primitives from @/components/ui/_ (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in Dashboard and Playground apps
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Use NavLink for internal navigation so active states are handled automatically
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Client Components: Begin files with 'use client'; before imports, handle interactive UI relying on React hooks (useState, useEffect, React Query, wallet hooks), access browser APIs (localStorage, window, IntersectionObserver, etc.), and support fast transitions with client-side data prefetching
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:44:20.977Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-11-24T22:44:20.977Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Always import from the central UI library under `@/components/ui/*` for reusable core UI components like `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:44:20.977Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-11-24T22:44:20.977Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use `NavLink` from `@/components/ui/NavLink` for internal navigation to ensure active states are handled automatically
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-06-03T23:44:40.243Z
Learnt from: joaquim-verges
Repo: thirdweb-dev/js PR: 7268
File: packages/thirdweb/src/wallets/in-app/core/wallet/in-app-core.ts:210-216
Timestamp: 2025-06-03T23:44:40.243Z
Learning: EIP7702 wallets do not need special handling for switching chains, unlike EIP4337 wallets which require reconnection when switching chains. In the switchChain method condition, EIP7702 should be intentionally excluded from the reconnection logic.
Applied to files:
packages/thirdweb/src/x402/fetchWithPayment.ts
🧬 Code graph analysis (2)
packages/thirdweb/src/x402/types.ts (2)
packages/thirdweb/src/x402/schemas.ts (1)
RequestedPaymentPayload(24-26)packages/thirdweb/src/exports/x402.ts (1)
ERC20TokenAmount(17-17)
packages/thirdweb/src/x402/common.ts (1)
packages/thirdweb/src/x402/facilitator.ts (1)
facilitator(112-305)
⏰ 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). (8)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Size
- GitHub Check: Unit Tests
- GitHub Check: Lint Packages
- GitHub Check: Build Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (6)
packages/thirdweb/src/x402/common.ts (1)
38-41: Clean refactor to pass full args object.The simplification from explicit field extraction to passing the entire
argsobject tofacilitator.accepts()is appropriate. Per the relevant code snippet fromfacilitator.ts, theaccepts()function handles extracting required fields including the newschemeproperty.packages/thirdweb/src/x402/types.ts (1)
114-129: Improved documentation forERC20TokenAmount.The JSDoc comments clearly document the purpose of fields. The optional
eip712metadata allows explicit specification of token signing capabilities when needed.packages/thirdweb/src/x402/fetchWithPayment.ts (1)
74-76: Formatting adjustment only.The parsing logic is unchanged; this is just a line-break adjustment in the map call.
apps/portal/src/app/x402/server/page.mdx (3)
69-111: Good documentation for the "upto" scheme with dynamic pricing.The example clearly demonstrates the verify-then-settle pattern for usage-based pricing. The inline calculation
tokensUsed * pricePerTokenUsedis clearer than a separate placeholder function.The past review concern about
calculateDynamicPricebeing a placeholder has been addressed by using inline math with clearly named variables.
39-67: Clear explanation of exact vs upto schemes.The documentation effectively explains when to use each scheme and provides a concise example for the default "exact" flow.
113-145: Helpful price configuration examples.The three pricing methods (USD string, ERC20 token, native token) are clearly documented with practical examples.
2a22c08 to
023f93b
Compare
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: 1
♻️ Duplicate comments (4)
packages/thirdweb/src/x402/fetchWithPayment.ts (1)
167-179: Default selector ignores scheme in multi-requirement scenarios.The
defaultPaymentRequirementsSelectorfilters bychainIdonly (line 169) and doesn't account for scheme. When servers return multiple payment requirements with different schemes on the same chain, the first match is selected regardless of scheme type.This is mitigated by the
paymentRequirementsSelectoroption, but consider documenting this behavior or adding scheme preference logic to the default selector.packages/thirdweb/src/x402/types.ts (1)
108-112: AddexporttoPaymentSchemetype for API consistency.
PaymentSchemeSchemais exported (line 108) butPaymentSchemeis not (line 112), creating an asymmetry. SincePaymentSchemeis used in the exportedPaymentArgstype, external consumers may need to reference this type explicitly.export const PaymentSchemeSchema = z.union([ z.literal("exact"), z.literal("upto"), ]); -type PaymentScheme = z.infer<typeof PaymentSchemeSchema>; +export type PaymentScheme = z.infer<typeof PaymentSchemeSchema>;apps/portal/src/app/x402/server/page.mdx (2)
117-122: Bug: Undefined variableresultshould besettleResult.Line 122 references
resultwhich is not defined in this scope. The settle result is stored insettleResulton line 117.const settleResult = await settlePayment({ ...paymentArgs, price: tokensUsed * pricePerTokenUsed, // adjust final price based on usage }); -return Response.json(result); +return Response.json(settleResult);
113-113: Clarify thatcallExpensiveAIModelis a user-provided placeholder.The function
callExpensiveAIModel()is used in the example but not defined. Consider adding a brief comment indicating this is placeholder code that developers must implement based on their use case.// Do the expensive work that requires payment -const { tokensUsed } = await callExpensiveAIModel(); +const { tokensUsed } = await callExpensiveAIModel(); // your custom function
📜 Review details
Configuration used: CodeRabbit 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 (11)
.changeset/chilly-taxis-search.md(1 hunks)apps/portal/src/app/x402/page.mdx(0 hunks)apps/portal/src/app/x402/server/page.mdx(8 hunks)apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx(1 hunks)packages/thirdweb/src/x402/common.ts(1 hunks)packages/thirdweb/src/x402/facilitator.ts(1 hunks)packages/thirdweb/src/x402/fetchWithPayment.ts(2 hunks)packages/thirdweb/src/x402/schemas.ts(3 hunks)packages/thirdweb/src/x402/settle-payment.ts(1 hunks)packages/thirdweb/src/x402/types.ts(4 hunks)packages/thirdweb/src/x402/verify-payment.ts(1 hunks)
💤 Files with no reviewable changes (1)
- apps/portal/src/app/x402/page.mdx
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/thirdweb/src/x402/schemas.ts
- packages/thirdweb/src/x402/verify-payment.ts
- packages/thirdweb/src/x402/facilitator.ts
- packages/thirdweb/src/x402/common.ts
- packages/thirdweb/src/x402/settle-payment.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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.tsapps/portal/src/components/Document/Cards/GithubTemplateCard.tsxpackages/thirdweb/src/x402/types.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.tspackages/thirdweb/src/x402/types.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.tsapps/portal/src/components/Document/Cards/GithubTemplateCard.tsxpackages/thirdweb/src/x402/types.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.tsapps/portal/src/components/Document/Cards/GithubTemplateCard.tsxpackages/thirdweb/src/x402/types.ts
🧠 Learnings (17)
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to packages/**/.changeset/*.md : Each change in packages/* should contain a changeset for the appropriate package with the appropriate version bump: patch for changes that don't impact the public API, minor for any new/modified public API
Applied to files:
.changeset/chilly-taxis-search.md
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Use `minor` version bump for any new/modified public API
Applied to files:
.changeset/chilly-taxis-search.md
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Use `patch` version bump for changes that don't impact the public API
Applied to files:
.changeset/chilly-taxis-search.md
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Use `major` version bump for breaking changes and surface prominently in PR descriptions
Applied to files:
.changeset/chilly-taxis-search.md
📚 Learning: 2025-06-26T19:46:04.024Z
Learnt from: gregfromstl
Repo: thirdweb-dev/js PR: 7450
File: packages/thirdweb/src/bridge/Webhook.ts:57-81
Timestamp: 2025-06-26T19:46:04.024Z
Learning: In the onramp webhook schema (`packages/thirdweb/src/bridge/Webhook.ts`), the `currencyAmount` field is intentionally typed as `z.number()` while other amount fields use `z.string()` because `currencyAmount` represents fiat currency amounts in decimals (like $10.50), whereas other amount fields represent token amounts in wei (very large integers that benefit from bigint representation). The different naming convention (`currencyAmount` vs `amount`) reflects this intentional distinction.
Applied to files:
packages/thirdweb/src/x402/fetchWithPayment.tspackages/thirdweb/src/x402/types.ts
📚 Learning: 2025-06-03T23:44:40.243Z
Learnt from: joaquim-verges
Repo: thirdweb-dev/js PR: 7268
File: packages/thirdweb/src/wallets/in-app/core/wallet/in-app-core.ts:210-216
Timestamp: 2025-06-03T23:44:40.243Z
Learning: EIP7702 wallets do not need special handling for switching chains, unlike EIP4337 wallets which require reconnection when switching chains. In the switchChain method condition, EIP7702 should be intentionally excluded from the reconnection logic.
Applied to files:
packages/thirdweb/src/x402/fetchWithPayment.ts
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Surface breaking changes prominently in PR descriptions
Applied to files:
apps/portal/src/components/Document/Cards/GithubTemplateCard.tsxapps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to packages/thirdweb/src/exports/**/*.{ts,tsx} : Export everything in packages/thirdweb via the exports/ directory, grouped by feature. Every public symbol must have comprehensive TSDoc including at least one example block that compiles and one custom annotation (beta, internal, experimental, etc.)
Applied to files:
packages/thirdweb/src/x402/types.ts
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Applies to packages/thirdweb/src/**/*.{ts,tsx} : Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Applied to files:
packages/thirdweb/src/x402/types.tsapps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-08-28T20:50:33.170Z
Learnt from: joaquim-verges
Repo: thirdweb-dev/js PR: 7922
File: apps/playground-web/src/app/ai/ai-sdk/components/chat-container.tsx:167-181
Timestamp: 2025-08-28T20:50:33.170Z
Learning: The thirdweb-dev/ai-sdk-provider schemas use snake_case field naming convention (e.g., chain_id, transaction_hash) rather than camelCase, as defined in the zod schemas in packages/ai-sdk-provider/src/tools.ts.
Applied to files:
packages/thirdweb/src/x402/types.ts
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Applies to packages/thirdweb/src/exports/**/*.{ts,tsx} : Every public symbol must have comprehensive TSDoc with at least one `example` block that compiles and custom annotation tags (`beta`, `internal`, `experimental`)
Applied to files:
packages/thirdweb/src/x402/types.ts
📚 Learning: 2025-11-24T22:43:43.644Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T22:43:43.644Z
Learning: Applies to packages/thirdweb/src/exports/**/*.{ts,tsx} : Export everything via `exports/` directory, grouped by feature in SDK development
Applied to files:
packages/thirdweb/src/x402/types.ts
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Import UI primitives from @/components/ui/_ (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in Dashboard and Playground apps
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Use NavLink for internal navigation so active states are handled automatically
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:45:01.202Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T22:45:01.202Z
Learning: Applies to apps/{dashboard,playground}/**/*.{tsx,ts} : Client Components: Begin files with 'use client'; before imports, handle interactive UI relying on React hooks (useState, useEffect, React Query, wallet hooks), access browser APIs (localStorage, window, IntersectionObserver, etc.), and support fast transitions with client-side data prefetching
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:44:20.977Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-11-24T22:44:20.977Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Always import from the central UI library under `@/components/ui/*` for reusable core UI components like `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`
Applied to files:
apps/portal/src/app/x402/server/page.mdx
📚 Learning: 2025-11-24T22:44:20.977Z
Learnt from: CR
Repo: thirdweb-dev/js PR: 0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-11-24T22:44:20.977Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use `NavLink` from `@/components/ui/NavLink` for internal navigation to ensure active states are handled automatically
Applied to files:
apps/portal/src/app/x402/server/page.mdx
🧬 Code graph analysis (3)
packages/thirdweb/src/x402/fetchWithPayment.ts (1)
packages/thirdweb/src/x402/schemas.ts (3)
RequestedPaymentRequirementsSchema(34-38)extractEvmChainId(107-114)networkToCaip2ChainId(186-191)
apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx (1)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
Link(46-64)
packages/thirdweb/src/x402/types.ts (2)
packages/thirdweb/src/x402/schemas.ts (1)
RequestedPaymentPayload(24-26)packages/thirdweb/src/exports/x402.ts (1)
ERC20TokenAmount(17-17)
🪛 LanguageTool
apps/portal/src/app/x402/server/page.mdx
[grammar] ~88-~88: Use a hyphen to join words.
Context: ...ai-inference" /> Here's a high level example of how to use the upto p...
(QB_NEW_EN_HYPHEN)
⏰ 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). (2)
- GitHub Check: Size
- GitHub Check: Analyze (javascript)
🔇 Additional comments (7)
.changeset/chilly-taxis-search.md (1)
1-38: LGTM!The changeset correctly uses a "minor" version bump for this public API change (new
PaymentSchemetype and extended types). The example demonstrates the newuptoscheme workflow well.apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx (1)
4-20: LGTM!Clean enhancement to support optional description text. The conditional rendering and flex layout wrapper are well-structured.
packages/thirdweb/src/x402/fetchWithPayment.ts (1)
74-76: LGTM - Scheme filtering removed to support both "exact" and "upto".The change to parse all payment requirements without filtering by scheme aligns with the PR's goal of supporting both payment schemes.
packages/thirdweb/src/x402/types.ts (2)
2-2: LGTM - Import style change.The zod import change from named to default import is valid and aligns with common usage patterns.
92-102: LGTM - Enhanced VerifyPaymentResult type.The addition of
decodedPaymentandselectedPaymentRequirementsfields with proper JSDoc provides useful context for consumers handling verification results.apps/portal/src/app/x402/server/page.mdx (2)
1-10: LGTM - Updated imports.Clean addition of
StackandGithubTemplateCardimports for the new example card.
41-69: LGTM - Clear explanation of payment schemes.The documentation clearly explains the difference between
exactanduptoschemes with a practical example.
| /> | ||
| </Stack> | ||
|
|
||
| Here's a high level example of how to use the `upto` payment scheme with a dynamic price based on the token usage. First we verify the payment is valid for the max payable amount and then settle the payment based on the actual usage. |
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.
Minor: Hyphenate "high-level".
Per grammar conventions, compound adjectives before a noun should be hyphenated.
-Here's a high level example of how to use the `upto` payment scheme
+Here's a high-level example of how to use the `upto` payment scheme🧰 Tools
🪛 LanguageTool
[grammar] ~88-~88: Use a hyphen to join words.
Context: ...ai-inference" /> Here's a high level example of how to use the upto p...
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents
In apps/portal/src/app/x402/server/page.mdx around line 88, the phrase "high
level example" should be hyphenated as "high-level" when used as a compound
adjective before the noun; update the sentence to use "high-level example" to
conform to grammar conventions.
023f93b to
797573a
Compare

PR-Codex overview
This PR introduces the
uptopayment scheme for the x402 payment process, allowing dynamic pricing based on usage. It enhances payment verification and settlement procedures while updating relevant documentation to reflect these changes.Detailed summary
scheme: args.schemeto thefacilitator.ts.uptopayment scheme insettle-payment.tsandverify-payment.ts.PaymentArgsto include an optionalscheme.uptopayment scheme and provide usage examples.GithubTemplateCardto include an optionaldescription.maxTimeoutSecondsfrom route configuration in multiple files.Summary by CodeRabbit
Release Notes
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.