Skip to content

Conversation

@joaquim-verges
Copy link
Member

@joaquim-verges joaquim-verges commented Nov 25, 2025


PR-Codex overview

This PR introduces the upto payment 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

  • Added scheme: args.scheme to the facilitator.ts.
  • Introduced the upto payment scheme in settle-payment.ts and verify-payment.ts.
  • Updated PaymentArgs to include an optional scheme.
  • Modified schemas to support the new payment scheme.
  • Enhanced documentation to describe the upto payment scheme and provide usage examples.
  • Updated GithubTemplateCard to include an optional description.
  • Removed fixed maxTimeoutSeconds from route configuration in multiple files.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for dynamic pricing (upto) payment scheme as an alternative to exact pricing for payment verification and settlement flows
    • Enhanced component descriptions for improved flexibility
  • Documentation

    • Expanded payment scheme documentation with detailed examples for exact and dynamic pricing configurations
    • Added comprehensive guides comparing payment scheme options and pricing strategies across multiple frameworks

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Nov 25, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
docs-v2 Ready Ready Preview Comment Nov 26, 2025 0:57am
nebula Ready Ready Preview Comment Nov 26, 2025 0:57am
thirdweb_playground Ready Ready Preview Comment Nov 26, 2025 0:57am
thirdweb-www Ready Ready Preview Comment Nov 26, 2025 0:57am
wallet-ui Ready Ready Preview Comment Nov 26, 2025 0:57am

@changeset-bot
Copy link

changeset-bot bot commented Nov 25, 2025

🦋 Changeset detected

Latest commit: 797573a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
thirdweb Minor
@thirdweb-dev/nebula Patch
@thirdweb-dev/wagmi-adapter Patch
wagmi-inapp Patch

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

Walkthrough

The 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

Cohort / File(s) Summary
Type & Schema Definitions
packages/thirdweb/src/x402/types.ts, packages/thirdweb/src/x402/schemas.ts
Added PaymentScheme union type (exact | upto); extended PaymentArgs with optional scheme field; updated VerifyPaymentResult to include decodedPayment and selectedPaymentRequirements; extended RequestedPaymentPayload and RequestedPaymentRequirements schemas with scheme field; updated FacilitatorSupportedResponseSchema scheme type to use PaymentSchemeSchema.
Payment Flow Logic
packages/thirdweb/src/x402/common.ts, packages/thirdweb/src/x402/facilitator.ts, packages/thirdweb/src/x402/fetchWithPayment.ts
Modified decodePaymentRequest to pass full args object to facilitator.accepts; updated facilitator.accepts to include scheme in request payload; removed scheme-based filtering in payment requirements selection; updated defaultPaymentRequirementsSelector signature to remove scheme parameter.
Documentation & Examples
packages/thirdweb/src/x402/verify-payment.ts, packages/thirdweb/src/x402/settle-payment.ts
Removed maxTimeoutSeconds from routeConfig examples; added new "Upto Payment Scheme" documentation sections with dynamic pricing usage examples.
Portal Documentation
apps/portal/src/app/x402/page.mdx, apps/portal/src/app/x402/server/page.mdx
Removed routeConfig object from settlePayment call in basic example; restructured documentation with "Exact vs Upto Payment Schemes" section; expanded code examples across Next.js, Express, and Hono tabs; added new "Price and Token Configuration" section with USD, ERC20, and native token details.
Changesets & UI
.changeset/chilly-taxis-search.md, apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx
Added changeset entry for thirdweb minor update; enhanced GithubTemplateCard component with optional description prop and conditional rendering.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Payment flow logic updates: The removal of scheme-based filtering in fetchWithPayment.ts and changes to how the full args object is passed through common.ts to facilitator.ts requires careful verification of backward compatibility and correct scheme propagation.
  • Schema consistency: Verify that PaymentScheme is correctly integrated across all schema definitions (RequestedPaymentPayload, RequestedPaymentRequirements, FacilitatorSupportedResponseSchema) and that validation aligns with implementation.
  • Documentation accuracy: Portal examples span multiple frameworks (Next.js, Express, Hono) with dynamic pricing explanations that should align with actual implementation behavior.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete; it lacks required template sections like 'Notes for the reviewer' and 'How to test' from the repository template. Add 'Notes for the reviewer' section highlighting important changes and 'How to test' section with testing instructions or validation steps.
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main objectives: introducing a payment scheme and improving type documentation for x402.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch _SDK_Add_payment_scheme_and_improve_type_documentation_for_x402

📜 Recent 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 023f93b and 797573a.

📒 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 (6)
  • packages/thirdweb/src/x402/facilitator.ts
  • .changeset/chilly-taxis-search.md
  • apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx
  • packages/thirdweb/src/x402/schemas.ts
  • packages/thirdweb/src/x402/verify-payment.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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in 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/common.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • 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/common.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • 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 lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/x402/common.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • 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/common.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • packages/thirdweb/src/x402/types.ts
🧠 Learnings (13)
📚 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.ts
  • packages/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: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: Surface breaking changes prominently in PR descriptions

Applied to files:

  • apps/portal/src/app/x402/server/page.mdx
📚 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
  • 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
📚 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/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-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} : Export everything via `exports/` directory, grouped by feature in SDK development

Applied to files:

  • packages/thirdweb/src/x402/types.ts
🧬 Code graph analysis (2)
packages/thirdweb/src/x402/common.ts (1)
packages/thirdweb/src/x402/facilitator.ts (1)
  • facilitator (112-305)
packages/thirdweb/src/x402/fetchWithPayment.ts (1)
packages/thirdweb/src/x402/schemas.ts (3)
  • RequestedPaymentRequirementsSchema (34-38)
  • extractEvmChainId (107-114)
  • networkToCaip2ChainId (186-191)
🪛 LanguageTool
apps/portal/src/app/x402/server/page.mdx

[uncategorized] ~88-~88: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...402-ai-inference" /> Here's a high level example of how to use the upto paymen...

(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)
  • GitHub Check: Size
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (8)
apps/portal/src/app/x402/server/page.mdx (2)

80-86: Good use of GithubTemplateCard for linking AI inference example.

The Stack and GithubTemplateCard integration provides a clear, discoverable link to a working reference implementation. This improves developer experience and reduces friction for learning the upto scheme.


1-10: Imports well-organized for added documentation components.

The new imports (Stack, GithubTemplateCard) are cleanly added and support the expanded documentation structure.

packages/thirdweb/src/x402/common.ts (1)

38-41: LGTM! Clean refactor to pass full args.

The refactor correctly passes the entire args object to facilitator.accepts(), enabling it to access the new scheme field and other payment configuration. The narrowed destructuring is cleaner since individual fields are no longer needed at this level.

packages/thirdweb/src/x402/types.ts (4)

2-2: LGTM! Import change enables runtime schema validation.

The switch from type-only import to value import for zod is necessary to support the runtime usage of PaymentSchemeSchema introduced in this PR.


34-35: LGTM! Scheme field added to PaymentArgs.

The optional scheme field properly supports the new "exact" vs "upto" payment model with clear documentation.


96-99: LGTM! Enhanced transparency in VerifyPaymentResult.

The addition of decodedPayment and selectedPaymentRequirements to the success response provides callers with valuable context about which payment was decoded and which requirements were matched, improving debuggability and enabling downstream logic to act on scheme-specific information.


114-119: LGTM! Improved documentation clarity.

The updated JSDoc comments provide clearer guidance on the purpose and usage of the amount and asset fields.

packages/thirdweb/src/x402/fetchWithPayment.ts (1)

74-76: LGTM! Simplified parsing logic.

The straightforward mapping and parsing of payment requirements is correct and delegates scheme-based selection to the selector function.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added packages SDK Involves changes to the thirdweb SDK labels Nov 25, 2025
Copy link
Member Author


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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.

📥 Commits

Reviewing files that changed from the base of the PR and between ad2d175 and 4930f63.

📒 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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in 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 lint before 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 ERC20TokenAmount with:

  • Optional scheme field for payment flexibility (backward compatible)
  • Enhanced asset documentation explaining inference behavior
  • Optional eip712 metadata for explicit EIP-712 typing

The optional fields and default behavior ("exact" scheme) ensure backward compatibility while enabling the new "upto" payment scheme.

@codecov
Copy link

codecov bot commented Nov 25, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 54.82%. Comparing base (ad2d175) to head (797573a).
⚠️ Report is 1 commits behind head on main.

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           
Flag Coverage Δ
packages 54.82% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 25, 2025

size-limit report 📦

Path Size
@thirdweb-dev/nexus (esm) 104.88 KB (0%)
@thirdweb-dev/nexus (cjs) 316.6 KB (0%)

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 full args to facilitator.accepts.

The facilitator.accepts method expects Omit<PaymentArgs, "facilitator">, but args is of type PaymentArgs which includes the facilitator property. 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 4930f63 and 35273ba.

📒 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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in 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.ts
  • packages/thirdweb/src/x402/common.ts
  • packages/thirdweb/src/x402/verify-payment.ts
  • packages/thirdweb/src/x402/schemas.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • 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/facilitator.ts
  • packages/thirdweb/src/x402/common.ts
  • packages/thirdweb/src/x402/verify-payment.ts
  • packages/thirdweb/src/x402/schemas.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • 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 lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/x402/facilitator.ts
  • packages/thirdweb/src/x402/common.ts
  • packages/thirdweb/src/x402/verify-payment.ts
  • packages/thirdweb/src/x402/schemas.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • 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/facilitator.ts
  • packages/thirdweb/src/x402/common.ts
  • packages/thirdweb/src/x402/verify-payment.ts
  • packages/thirdweb/src/x402/schemas.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • packages/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.ts
  • 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/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 PaymentSchemeSchema using Zod's z.union with literals ensures type safety and runtime validation. The inferred PaymentScheme type properly derives from the schema.


114-129: The JSDoc comment for ERC20TokenAmount is misleading, but the type definition itself is correct.

The scheme field is correctly defined at the PaymentArgs level (line 35: scheme?: PaymentScheme;), not within ERC20TokenAmount. 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 the scheme belongs 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 RequestedPaymentPayloadSchema correctly extends the base schema with both network and scheme fields.


34-38: LGTM! Payment requirements schema updated consistently.

The RequestedPaymentRequirementsSchema mirrors the payload schema extension, ensuring consistency across the payment flow.


77-94: LGTM! Facilitator response schema updated to support multiple schemes.

The FacilitatorSupportedResponseSchema now uses PaymentSchemeSchema instead 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 scheme field is correctly included in the accepts request payload. Since it's optional in PaymentArgs, 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 scheme and network from 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 inconsistent maxTimeoutSeconds handling across the examples. Let me start by examining the actual file content.
<function_calls>

#!/bin/bash

First, get the file and check its line count

wc -l apps/portal/src/app/x402/server/page.mdx


</function_calls>
<function_calls>

#!/bin/bash

Read 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/bash

Read 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 maxTimeoutSeconds in this file to get a complete picture:
<function_calls>

#!/bin/bash

Search 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/bash

Check 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 -n

echo ""
echo "=== Lines 233-237 (Express dedicated - should have maxTimeoutSeconds) ==="
sed -n '233,237p' apps/portal/src/app/x402/server/page.mdx | cat -n

echo ""
echo "=== Lines 286-290 (Hono dedicated - should have maxTimeoutSeconds) ==="
sed -n '286,290p' apps/portal/src/app/x402/server/page.mdx | cat -n

echo ""
echo "=== Lines 353-357 (Next.js middleware - should have maxTimeoutSeconds) ==="
sed -n '353,357p' apps/portal/src/app/x402/server/page.mdx | cat -n

echo ""
echo "=== Lines 411-415 (Express middleware - should have maxTimeoutSeconds) ==="
sed -n '411,415p' apps/portal/src/app/x402/server/page.mdx | cat -n

echo ""
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/bash

Comprehensive 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 -l

echo ""
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_result

Based 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 of maxTimeoutSeconds anywhere in the file. The review comment claims that only the Next.js dedicated endpoint omits it while all others include maxTimeoutSeconds: 300, but this is contradicted by the actual file content.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 defaultPaymentRequirementsSelector matches only by chainId (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 both scheme and network.

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 35273ba and 2a22c08.

📒 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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in 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/x402/fetchWithPayment.ts
  • packages/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.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • packages/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 lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/x402/types.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • packages/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.ts
  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • packages/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.ts
  • 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: 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 args object to facilitator.accepts() is appropriate. Per the relevant code snippet from facilitator.ts, the accepts() function handles extracting required fields including the new scheme property.

packages/thirdweb/src/x402/types.ts (1)

114-129: Improved documentation for ERC20TokenAmount.

The JSDoc comments clearly document the purpose of fields. The optional eip712 metadata 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 * pricePerTokenUsed is clearer than a separate placeholder function.

The past review concern about calculateDynamicPrice being 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 defaultPaymentRequirementsSelector filters by chainId only (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 paymentRequirementsSelector option, but consider documenting this behavior or adding scheme preference logic to the default selector.

packages/thirdweb/src/x402/types.ts (1)

108-112: Add export to PaymentScheme type for API consistency.

PaymentSchemeSchema is exported (line 108) but PaymentScheme is not (line 112), creating an asymmetry. Since PaymentScheme is used in the exported PaymentArgs type, 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 variable result should be settleResult.

Line 122 references result which is not defined in this scope. The settle result is stored in settleResult on 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 that callExpensiveAIModel is 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 2a22c08 and 023f93b.

📒 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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in 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.ts
  • apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx
  • 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/fetchWithPayment.ts
  • 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 lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/x402/fetchWithPayment.ts
  • apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx
  • 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/fetchWithPayment.ts
  • apps/portal/src/components/Document/Cards/GithubTemplateCard.tsx
  • packages/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.ts
  • packages/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.tsx
  • 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 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.ts
  • 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/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 PaymentScheme type and extended types). The example demonstrates the new upto scheme 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 decodedPayment and selectedPaymentRequirements fields 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 Stack and GithubTemplateCard imports for the new example card.


41-69: LGTM - Clear explanation of payment schemes.

The documentation clearly explains the difference between exact and upto schemes 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packages Portal Involves changes to the Portal (docs) codebase. SDK Involves changes to the thirdweb SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants