-
Notifications
You must be signed in to change notification settings - Fork 619
Add successUrl support to payment page #8341
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
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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. |
WalkthroughAdds a new packages/nexus-fetch package with a fetch wrapper implementing PKCE OAuth, token caching/refresh, and 402 payment handling; adds config, build, and test files. Refactors dashboard pay page validators to module scope and adds successUrl parsing and onSuccess redirect behavior. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant App
participant WrappedFetch as Nexus Fetch Wrapper
participant OAuth as Authorization Endpoint
participant Nexus as Nexus Proxy/API
App->>WrappedFetch: invoke wrapped fetch(input, init)
alt Valid cached token
WrappedFetch->>WrappedFetch: attach Authorization header
else Token expired -> refresh available
WrappedFetch->>Nexus: POST /oauth/token (refresh)
Nexus-->>WrappedFetch: new tokens
WrappedFetch->>WrappedFetch: persist tokens
else No token
WrappedFetch->>OAuth: Redirect to /authorize (PKCE + state)
OAuth-->>User: user authenticates & redirects back with code
User->>App: returns with code
App->>WrappedFetch: complete OAuth flow (exchange code)
WrappedFetch->>Nexus: POST /oauth/token (code exchange)
Nexus-->>WrappedFetch: tokens
WrappedFetch->>WrappedFetch: persist tokens
end
WrappedFetch->>Nexus: forward original request (with auth)
alt 200 OK
Nexus-->>WrappedFetch: response -> App
else 401 Unauthorized
WrappedFetch->>WrappedFetch: attempt refresh or restart OAuth
else 402 Payment Required
rect rgb(255, 249, 230)
note right of WrappedFetch: build proxy payment request and derive funding URL
WrappedFetch->>User: redirect to wallet-funding/payment URL
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8341 +/- ##
=======================================
Coverage 54.87% 54.87%
=======================================
Files 919 919
Lines 60653 60653
Branches 4117 4117
=======================================
Hits 33283 33283
Misses 27268 27268
Partials 102 102
🚀 New features to boost your workflow:
|
size-limit report 📦
|
49ad057 to
77a4a07
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: 5
📜 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 ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
apps/dashboard/src/app/pay/page.tsx(2 hunks)packages/nexus-fetch/.size-limit.json(1 hunks)packages/nexus-fetch/biome.json(1 hunks)packages/nexus-fetch/knip.json(1 hunks)packages/nexus-fetch/package.json(1 hunks)packages/nexus-fetch/src/exports/nexus-fetch.ts(1 hunks)packages/nexus-fetch/src/fetch.ts(1 hunks)packages/nexus-fetch/testing/test.html(1 hunks)packages/nexus-fetch/tsconfig.base.json(1 hunks)packages/nexus-fetch/tsconfig.build.json(1 hunks)packages/nexus-fetch/tsconfig.json(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each 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
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
packages/nexus-fetch/src/exports/nexus-fetch.tsapps/dashboard/src/app/pay/page.tsxpackages/nexus-fetch/src/fetch.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
packages/nexus-fetch/src/exports/nexus-fetch.tsapps/dashboard/src/app/pay/page.tsxpackages/nexus-fetch/src/fetch.ts
apps/{dashboard,playground-web}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/*(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
UseNavLinkfor internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()from@/lib/utilsfor conditional class logic
Use design system tokens (e.g.,bg-card,border-border,text-muted-foreground)
Server Components (Node edge): Start files withimport "server-only";
Client Components (browser): Begin files with'use client';
Always callgetAuthToken()to retrieve JWT from cookies on server side
UseAuthorization: Bearerheader – never embed tokens in URLs
Return typed results (e.g.,Project[],User[]) – avoidany
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stablequeryKeysfor React Query cache hits
ConfigurestaleTime/cacheTimein React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never importposthog-jsin server components
Files:
apps/dashboard/src/app/pay/page.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/_(e.g., Button, Input, Tabs, Card)
UseNavLinkfor internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names withcn()from@/lib/utilsfor conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start withimport "server-only"; usenext/headers, server‑only env, heavy data fetching, andredirect()where appropriate
Client Components must start with'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: callgetAuthToken()from cookies, sendAuthorization: Bearer <token>header, and return typed results (avoidany)
Client-side data fetching: wrap calls in React Query with descriptive, stablequeryKeysand set sensiblestaleTime/cacheTime(≥ 60s default); keep tokens secret via internal routes or server actions
Do not importposthog-jsin server components (client-side only)
Files:
apps/dashboard/src/app/pay/page.tsx
apps/{dashboard,playground}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Expose a
classNameprop on the root element of every component
Files:
apps/dashboard/src/app/pay/page.tsx
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Track bundle budgets via
package.json#size-limit
Files:
packages/nexus-fetch/package.json
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Create light wrappers (e.g. `fetchJson`) that automatically attach the JWT from cookies/session when calling internal API routes.
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.test.{ts,tsx} : Use MSW to intercept HTTP calls for network interactions; mock only hard‑to‑reproduce scenarios
Applied to files:
packages/nexus-fetch/testing/test.htmlpackages/nexus-fetch/tsconfig.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Re‑use shared types from `@/types` where applicable
Applied to files:
packages/nexus-fetch/tsconfig.jsonpackages/nexus-fetch/tsconfig.base.jsonpackages/nexus-fetch/tsconfig.build.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx} : Re-use shared types from `@/types` or local `types.ts` barrels
Applied to files:
packages/nexus-fetch/tsconfig.jsonpackages/nexus-fetch/tsconfig.base.jsonpackages/nexus-fetch/tsconfig.build.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/**/*.{ts,tsx} : Comment only ambiguous logic; avoid restating TypeScript in prose
Applied to files:
packages/nexus-fetch/tsconfig.jsonpackages/nexus-fetch/tsconfig.base.jsonpackages/nexus-fetch/tsconfig.build.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Use explicit function declarations and explicit return types in TypeScript
Applied to files:
packages/nexus-fetch/tsconfig.jsonpackages/nexus-fetch/tsconfig.base.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/types.ts : Provide and re‑use local type barrels in a `types.ts` file
Applied to files:
packages/nexus-fetch/tsconfig.jsonpackages/nexus-fetch/tsconfig.base.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx} : Write idiomatic TypeScript with explicit function declarations and return types
Applied to files:
packages/nexus-fetch/tsconfig.jsonpackages/nexus-fetch/tsconfig.base.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.test.{ts,tsx} : Use Mock Service Worker (MSW) for fetch/HTTP call interception in tests
Applied to files:
packages/nexus-fetch/tsconfig.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.test.{ts,tsx} : Place tests alongside code: `foo.ts` ↔ `foo.test.ts`
Applied to files:
packages/nexus-fetch/tsconfig.jsonpackages/nexus-fetch/tsconfig.build.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.test.{ts,tsx} : Co‑locate tests as `foo.test.ts(x)` next to the implementation
Applied to files:
packages/nexus-fetch/tsconfig.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Applied to files:
packages/nexus-fetch/tsconfig.base.jsonpackages/nexus-fetch/tsconfig.build.jsonpackages/nexus-fetch/.size-limit.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx} : Comment only ambiguous logic; avoid restating TypeScript in prose
Applied to files:
packages/nexus-fetch/tsconfig.base.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Avoid `any` and `unknown` unless unavoidable; narrow generics when possible
Applied to files:
packages/nexus-fetch/tsconfig.base.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx} : Choose composition over inheritance; leverage utility types (`Partial`, `Pick`, etc.)
Applied to files:
packages/nexus-fetch/tsconfig.base.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to {.vscode/**,.idea/**} : Avoid editor‑specific configs; rely on shared settings
Applied to files:
packages/nexus-fetch/tsconfig.base.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Applied to files:
packages/nexus-fetch/tsconfig.base.jsonpackages/nexus-fetch/.size-limit.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/exports/** : Export all public API via `packages/thirdweb/exports/`, grouped by feature
Applied to files:
packages/nexus-fetch/src/exports/nexus-fetch.tspackages/nexus-fetch/.size-limit.jsonpackages/nexus-fetch/package.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to packages/thirdweb/src/exports/** : Export everything via `exports/` directory, grouped by feature in the SDK public API
Applied to files:
packages/nexus-fetch/src/exports/nexus-fetch.tspackages/nexus-fetch/.size-limit.jsonpackages/nexus-fetch/package.json
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Create light wrappers (e.g. `fetchJson`) that automatically attach the JWT from cookies/session when calling internal API routes.
Applied to files:
packages/nexus-fetch/src/exports/nexus-fetch.tspackages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to biome.json : Biome governs formatting and linting; project rules live in biome.json
Applied to files:
packages/nexus-fetch/biome.jsonpackages/nexus-fetch/knip.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to biome.json : Biome is the primary linter/formatter; rules are defined in `biome.json`
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Run `pnpm biome check --apply` before committing
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Run `pnpm biome check --apply` before committing (pre-commit hook)
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-08-20T10:35:18.543Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/page.tsx:77-81
Timestamp: 2025-08-20T10:35:18.543Z
Learning: The webhooks/payments route exists at apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/payments/page.tsx and was added as part of the unified project layout changes.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-08-20T10:35:18.543Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/page.tsx:77-81
Timestamp: 2025-08-20T10:35:18.543Z
Learning: The webhooks/payments route exists at apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/payments/page.tsx and was added as part of the unified project layout PR #7888.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Client-side data fetching: wrap calls in React Query with descriptive, stable `queryKeys` and set sensible `staleTime/cacheTime` (≥ 60s default); keep tokens secret via internal routes or server actions
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/package.json : Track bundle budgets via `package.json#size-limit`
Applied to files:
packages/nexus-fetch/.size-limit.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to package.json : Track bundle budgets via `package.json#size-limit`
Applied to files:
packages/nexus-fetch/.size-limit.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/**/*.{ts,tsx} : Lazy‑load heavy dependencies inside async paths (e.g., `const { jsPDF } = await import("jspdf")`)
Applied to files:
packages/nexus-fetch/.size-limit.jsonpackages/nexus-fetch/package.json
📚 Learning: 2025-06-17T18:30:52.976Z
Learnt from: MananTank
PR: thirdweb-dev/js#7356
File: apps/nebula/src/app/not-found.tsx:1-1
Timestamp: 2025-06-17T18:30:52.976Z
Learning: In the thirdweb/js project, the React namespace is available for type annotations (like React.FC) without needing to explicitly import React. This is project-specific configuration that differs from typical TypeScript/React setups.
Applied to files:
packages/nexus-fetch/package.json
🧬 Code graph analysis (2)
apps/dashboard/src/app/pay/page.tsx (1)
apps/dashboard/src/app/pay/[id]/page.tsx (1)
PayPage(27-93)
packages/nexus-fetch/src/fetch.ts (1)
packages/nexus-fetch/src/exports/nexus-fetch.ts (1)
wrap(1-1)
🪛 Gitleaks (8.28.0)
packages/nexus-fetch/src/fetch.ts
[high] 8-8: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
⏰ 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 (2)
packages/nexus-fetch/package.json (1)
56-56: The original review comment is incorrect. The--noCheckflag skips full type-checking of input files so tsc performs only parsing/emit-critical checks (faster emit/declaration generation), and it is properly supported in the project's TypeScript 5.8.3. This is an intentional optimization for faster builds, commonly used to separate emit from a later full type-check pass. The code requires no changes.Likely an incorrect or invalid review comment.
packages/nexus-fetch/src/exports/nexus-fetch.ts (1)
1-1: Re-export wiring looks good.The barrel cleanly surfaces
wrapwithout extra weight.
77a4a07 to
fa1757f
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 (5)
apps/dashboard/src/app/pay/page.tsx (1)
33-50: Implement server-side URL validation and domain allowlist to prevent open redirects.The
successUrlparameter accepts any valid URL without domain restrictions, creating an open redirect vulnerability. An attacker can supply?successUrl=https://attacker.comand users will be redirected there after payment, enabling phishing or credential theft.Verification confirms:
- No server-side validation exists (only client-side
onlyUrlcheck)- No domain allowlist or redirect restrictions found in the codebase
- Only validation is protocol check and hostname existence
Recommended fixes:
- Define allowed redirect domains: Create a whitelist of trusted domains (e.g., your app, known partners)
- Server-side validation: Add a server action or API route that validates
successUrlagainst the allowlist before returning it to the client- Alternative approach: Accept a redirect token/identifier instead of full URLs, mapping tokens to pre-configured destinations server-side
Example minimal fix:
const ALLOWED_REDIRECT_DOMAINS = ["yourdomain.com", "partner.com"]; const isAllowedRedirect = (url: string): boolean => { try { const parsed = new URL(url); return ALLOWED_REDIRECT_DOMAINS.includes(parsed.hostname); } catch { return false; } };packages/nexus-fetch/package.json (2)
57-57: Fix the invalid--noCheckflag.Same issue as build:cjs -
--noCheckis not a valid TypeScript flag.Apply this diff:
- "build:esm": "tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json", + "build:esm": "tsc --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json",
61-62: Fix the invalid--noCheckflag in dev scripts.Both dev:cjs and dev:esm use the invalid
--noCheckflag.Apply this diff:
- "dev:cjs": "printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json && tsc --noCheck --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false --watch", - "dev:esm": "printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json && tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm --watch", + "dev:cjs": "printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json && tsc --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false --watch", + "dev:esm": "printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json && tsc --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm --watch",packages/nexus-fetch/src/fetch.ts (1)
114-119: Fix header serialization bug (duplicate from previous review).As noted in the previous review,
request.headersorinit?.headerscan be aHeadersobject or tuple array, whichJSON.stringifyconverts to{}, losing critical headers likeContent-TypeandAuthorization.The fix from the previous review should be applied - add a
normalizeHeadershelper that convertsHeadersobjects and arrays to plain objects before serialization.packages/nexus-fetch/testing/test.html (1)
4-4: Fix TypeScript import (duplicate from previous review).As noted in the previous review, browsers cannot load
.tsfiles directly. The script tag must be changed totype="module"and import the built JavaScript output.Apply the fix from the previous review to load the compiled module.
🧹 Nitpick comments (4)
apps/dashboard/src/app/pay/page.tsx (1)
79-94: Consider adding user-visible feedback on redirect failure.The try-catch error handling addresses the previous review concern about potential URL construction errors. However, the catch block only logs to the console without providing user feedback. If the redirect fails after a successful payment, users may be confused about what happened or where to go next.
Consider adding a user-visible error message or fallback behavior in the catch block, such as displaying a toast notification or redirecting to a default success page.
Example enhancement:
} catch (error) { // Log URL construction error for debugging console.error( "Failed to construct redirect URL:", successUrl, error, ); + // Show user feedback or fallback to a default success page + // e.g., toast.error("Redirect failed. Payment completed successfully."); }packages/nexus-fetch/package.json (1)
75-75: Update version before publishing.The placeholder version
0.0.0should be updated to a proper semver before the package is published to npm.packages/nexus-fetch/src/fetch.ts (1)
7-8: Consider making the base URL and client ID configurable.While hardcoded values work for production, consider accepting these as optional parameters to the
wrapfunction or via environment variables to support testing, staging, and local development environments.packages/nexus-fetch/testing/test.html (1)
8-19: Enhance the test harness with feedback and error handling.The current test lacks visibility into results. Consider adding:
- Console logging or UI display of the response
- Error handling to show failures
- Content-Type header on the POST request
Example enhancement:
<script> const testButton = document.getElementById("test-button"); testButton.addEventListener("click", () => { - fetch("https://q1qkkomp.nx.link/kindle", { + fetch("https://q1qkkomp.nx.link/kindle", { method: "POST", + headers: { "Content-Type": "application/json" }, body: JSON.stringify({ recipient: "0x0890C23024089675D072E984f28A93bb391a35Ab", }) + }).then(res => { + console.log("Response:", res.status, res.statusText); + return res.text(); + }).then(body => { + console.log("Body:", body); + }).catch(err => { + console.error("Error:", err); }); }); testButton.click(); </script>
📜 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 ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
apps/dashboard/src/app/pay/page.tsx(2 hunks)packages/nexus-fetch/.size-limit.json(1 hunks)packages/nexus-fetch/biome.json(1 hunks)packages/nexus-fetch/knip.json(1 hunks)packages/nexus-fetch/package.json(1 hunks)packages/nexus-fetch/src/exports/nexus-fetch.ts(1 hunks)packages/nexus-fetch/src/fetch.ts(1 hunks)packages/nexus-fetch/testing/test.html(1 hunks)packages/nexus-fetch/tsconfig.base.json(1 hunks)packages/nexus-fetch/tsconfig.build.json(1 hunks)packages/nexus-fetch/tsconfig.json(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/nexus-fetch/src/exports/nexus-fetch.ts
- packages/nexus-fetch/tsconfig.base.json
- packages/nexus-fetch/knip.json
- packages/nexus-fetch/tsconfig.json
- packages/nexus-fetch/.size-limit.json
- packages/nexus-fetch/tsconfig.build.json
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each 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
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
packages/nexus-fetch/src/fetch.tsapps/dashboard/src/app/pay/page.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
packages/nexus-fetch/src/fetch.tsapps/dashboard/src/app/pay/page.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/*(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
UseNavLinkfor internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()from@/lib/utilsfor conditional class logic
Use design system tokens (e.g.,bg-card,border-border,text-muted-foreground)
Server Components (Node edge): Start files withimport "server-only";
Client Components (browser): Begin files with'use client';
Always callgetAuthToken()to retrieve JWT from cookies on server side
UseAuthorization: Bearerheader – never embed tokens in URLs
Return typed results (e.g.,Project[],User[]) – avoidany
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stablequeryKeysfor React Query cache hits
ConfigurestaleTime/cacheTimein React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never importposthog-jsin server components
Files:
apps/dashboard/src/app/pay/page.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/_(e.g., Button, Input, Tabs, Card)
UseNavLinkfor internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names withcn()from@/lib/utilsfor conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start withimport "server-only"; usenext/headers, server‑only env, heavy data fetching, andredirect()where appropriate
Client Components must start with'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: callgetAuthToken()from cookies, sendAuthorization: Bearer <token>header, and return typed results (avoidany)
Client-side data fetching: wrap calls in React Query with descriptive, stablequeryKeysand set sensiblestaleTime/cacheTime(≥ 60s default); keep tokens secret via internal routes or server actions
Do not importposthog-jsin server components (client-side only)
Files:
apps/dashboard/src/app/pay/page.tsx
apps/{dashboard,playground}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Expose a
classNameprop on the root element of every component
Files:
apps/dashboard/src/app/pay/page.tsx
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Track bundle budgets via
package.json#size-limit
Files:
packages/nexus-fetch/package.json
🧠 Learnings (27)
📓 Common learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/page.tsx:77-81
Timestamp: 2025-08-20T10:35:18.543Z
Learning: The webhooks/payments route exists at apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/payments/page.tsx and was added as part of the unified project layout PR #7888.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Create light wrappers (e.g. `fetchJson`) that automatically attach the JWT from cookies/session when calling internal API routes.
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.test.{ts,tsx} : Use MSW to intercept HTTP calls for network interactions; mock only hard‑to‑reproduce scenarios
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.test.{ts,tsx} : Use Mock Service Worker (MSW) for fetch/HTTP call interception in tests
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.test.{ts,tsx} : Keep tests deterministic and side-effect free
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/**/*.{ts,tsx} : Lazy‑load heavy dependencies inside async paths (e.g., `const { jsPDF } = await import("jspdf")`)
Applied to files:
packages/nexus-fetch/testing/test.htmlpackages/nexus-fetch/package.json
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{ts,tsx} : Export default async functions without `'use client';` – they run on the Node edge.
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.test.{ts,tsx} : Keep tests deterministic and side‑effect free; use Vitest
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Server Components (Node edge): Start files with `import "server-only";`
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.test.{ts,tsx} : Use real function invocations with stub data; avoid brittle mocks
Applied to files:
packages/nexus-fetch/testing/test.html
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Create light wrappers (e.g. `fetchJson`) that automatically attach the JWT from cookies/session when calling internal API routes.
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Client-side data fetching: wrap calls in React Query with descriptive, stable `queryKeys` and set sensible `staleTime/cacheTime` (≥ 60s default); keep tokens secret via internal routes or server actions
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Server-side data fetching: call `getAuthToken()` from cookies, send `Authorization: Bearer <token>` header, and return typed results (avoid `any`)
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to biome.json : Biome governs formatting and linting; project rules live in biome.json
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to biome.json : Biome is the primary linter/formatter; rules are defined in `biome.json`
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Run `pnpm biome check --apply` before committing
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-08-20T10:35:18.543Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/page.tsx:77-81
Timestamp: 2025-08-20T10:35:18.543Z
Learning: The webhooks/payments route exists at apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/payments/page.tsx and was added as part of the unified project layout changes.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-08-20T10:35:18.543Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/page.tsx:77-81
Timestamp: 2025-08-20T10:35:18.543Z
Learning: The webhooks/payments route exists at apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/payments/page.tsx and was added as part of the unified project layout PR #7888.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-08-07T20:43:21.864Z
Learnt from: MananTank
PR: thirdweb-dev/js#7812
File: apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/token-banner.tsx:48-60
Timestamp: 2025-08-07T20:43:21.864Z
Learning: In the TokenBanner component at apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/token-banner.tsx, the Link components use target="_blank" with internal application routes (starting with "/") to open pages in new tabs within the same application. These internal links do not require rel="noopener noreferrer" security attributes, which are only needed for external URLs.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-06-05T13:59:49.886Z
Learnt from: MananTank
PR: thirdweb-dev/js#7285
File: apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx:57-57
Timestamp: 2025-06-05T13:59:49.886Z
Learning: In the thirdweb dashboard Next.js app, when using loginRedirect() in server components, ensure to add a return statement after the redirect call to prevent further code execution and potential security issues.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Prefer API routes or server actions to keep tokens secret; the browser only sees relative paths.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{ts,tsx} : Redirect logic using `redirect()` from `next/navigation`.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-05-26T16:31:02.480Z
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx:43-49
Timestamp: 2025-05-26T16:31:02.480Z
Learning: In the thirdweb dashboard codebase, when `redirectToContractLandingPage()` is called, an explicit return statement is not required afterward because the function internally calls Next.js's `redirect()` which throws an error to halt execution.
Applied to files:
apps/dashboard/src/app/pay/page.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/exports/** : Export all public API via `packages/thirdweb/exports/`, grouped by feature
Applied to files:
packages/nexus-fetch/package.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to packages/thirdweb/src/exports/** : Export everything via `exports/` directory, grouped by feature in the SDK public API
Applied to files:
packages/nexus-fetch/package.json
📚 Learning: 2025-06-17T18:30:52.976Z
Learnt from: MananTank
PR: thirdweb-dev/js#7356
File: apps/nebula/src/app/not-found.tsx:1-1
Timestamp: 2025-06-17T18:30:52.976Z
Learning: In the thirdweb/js project, the React namespace is available for type annotations (like React.FC) without needing to explicitly import React. This is project-specific configuration that differs from typical TypeScript/React setups.
Applied to files:
packages/nexus-fetch/package.json
🧬 Code graph analysis (2)
packages/nexus-fetch/src/fetch.ts (1)
packages/nexus-fetch/src/exports/nexus-fetch.ts (1)
wrap(1-1)
apps/dashboard/src/app/pay/page.tsx (1)
apps/dashboard/src/app/pay/[id]/page.tsx (1)
PayPage(27-93)
🪛 Gitleaks (8.28.0)
packages/nexus-fetch/src/fetch.ts
[high] 8-8: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
⏰ 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). (6)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: Size
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (11)
apps/dashboard/src/app/pay/page.tsx (1)
61-61: LGTM!The
successUrlparameter parsing is consistent with the pattern used for other parameters and correctly applies theonlyUrlvalidator.packages/nexus-fetch/package.json (4)
3-5: LGTM!The browser field correctly disables Node's crypto module, ensuring bundlers use the native Web Crypto API (
crypto.getRandomValues,crypto.subtle) available in browsers.
17-19: Verify the Node >=22 requirement.This package appears to be browser-focused (uses Web Crypto API), so a strict Node >=22 engine requirement may unnecessarily limit adoption. Please confirm if Node 22-specific features are actually required for the build/dev tooling, or if this can be lowered to a more common LTS version like Node 18 or 20.
20-26: LGTM!The exports configuration follows best practices with proper ESM/CJS dual output, types-first ordering, and aligned paths.
69-69: Clarify thetest:uicommand.Running
bun ./testing/test.html --watchis unusual - Bun doesn't natively execute HTML files. Please verify this command works as intended, or consider using a local dev server (e.g.,vite,http-server) to serve the HTML test harness.packages/nexus-fetch/src/fetch.ts (5)
168-179: LGTM with noted limitation.The 402 handling correctly redirects to the payment URL with
successUrlset. The TODO comment appropriately flags the future enhancement to usewindow.postMessagefor a better UX (avoiding full page navigation). The current approach is acceptable for an MVP.
219-236: LGTM!Token management is well-implemented with dual in-memory/localStorage persistence, proper expiry calculation, and defensive checks against malformed token values.
273-308: LGTM!Token refresh logic correctly implements the OAuth refresh token flow with proper error handling and token cleanup on failure.
337-362: LGTM!PKCE implementation is secure and follows OAuth 2.0 RFC 7636 standards with proper code verifier generation (256-bit entropy) and SHA-256 challenge.
370-459: LGTM!OAuth flow correctly implements PKCE authorization code flow with proper CSRF protection (state validation), one-time-use enforcement (state/verifier cleanup), and secure token exchange.
packages/nexus-fetch/biome.json (1)
1-16: LGTM!The Biome configuration appropriately disables key sorting for
package.jsonto preserve intentional field ordering. Theextends: "//"likely references the monorepo root config.
Merge activity
|
<!--
## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"
If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):
## Notes for the reviewer
Anything important to call out? Be sure to also clarify these in your comments.
## How to test
Unit tests, playground, etc.
-->
<!-- start pr-codex -->
---
## PR-Codex overview
This PR introduces various configuration files, updates the `PayPage` component with URL validation, and enhances the fetch functionality with OAuth support. It also includes the addition of testing HTML and size limits for the package.
### Detailed summary
- Added `wrap` export in `nexus-fetch.ts`.
- Introduced `biome.json`, `.size-limit.json`, `tsconfig.json`, `tsconfig.build.json`, and `knip.json` for configuration.
- Enhanced `PayPage` with `onlyUrl` validation and success URL handling.
- Added testing HTML file for `nexus-fetch`.
- Updated `package.json` with author and dependencies.
- Improved fetch functionality with OAuth and error handling.
> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
<!-- end pr-codex -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- **New Features**
- Payment page now supports redirecting to a provided success URL after payment completes.
- New nexus-fetch library adds automatic OAuth token management, PKCE-backed sign-in flow, automatic token refresh, and integrated handling of proxy payment flows for web requests.
- **Chores**
- Added build/configuration and size-limit files for the new nexus-fetch package.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
fa1757f to
b88f75b
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 (3)
packages/nexus-fetch/src/fetch.ts (2)
48-59: Export an explicit initializer instead of auto-wrapping on import.This repeats the earlier feedback: the top-level IIFE still wraps
globalThis.fetchduring module evaluation, violating the “avoid top-level side effects” guidance and making integration/testing brittle. Please move this logic into an exported initializer so callers opt in. As per coding guidelines.
114-119: Normalize forwarded request headers before encoding.Reiterating the unresolved blocker: the payload still serializes
init?.headers/input.headersdirectly. When callers pass aHeadersobject or tuple array,JSON.stringifyreduces it to{}, so the proxy loses crucial metadata (Content-Type, auth, etc.). Additionally, wheninputis aURLinstance you now dropinit?.headersentirely. Normalize to a plain record first and reuse it for both string/URL andRequestinputs.+function normalizeHeaders( + headers: RequestInit["headers"] | undefined, +): Record<string, string> { + if (!headers) { + return {}; + } + if (headers instanceof Headers) { + return Object.fromEntries(headers.entries()); + } + if (Array.isArray(headers)) { + return Object.fromEntries(headers); + } + return { ...headers }; +} @@ - headers: - typeof input === "string" - ? init?.headers - : input instanceof Request - ? input.headers - : {}, + headers: + typeof input === "string" || input instanceof URL + ? normalizeHeaders(init?.headers) + : input instanceof Request + ? normalizeHeaders(input.headers) + : {},packages/nexus-fetch/package.json (1)
56-63: Remove the unsupported--noCheckflag from TypeScript scripts.
tsc(even 5.8.x) does not recognize--noCheck, so every script using it fails with “Unknown compiler option '--noCheck'”, breakingbuild,dev:*, etc. Drop the flag everywhere it appears (or replace with a valid option) so the build and watch commands succeed.- "build:cjs": "tsc --noCheck --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json", - "build:esm": "tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json", + "build:cjs": "tsc --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json", + "build:esm": "tsc --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json", @@ - "dev:cjs": "printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json && tsc --noCheck --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false --watch", - "dev:esm": "printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json && tsc --noCheck --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm --watch", + "dev:cjs": "printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json && tsc --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false --watch", + "dev:esm": "printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json && tsc --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm --watch",
📜 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 ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
apps/dashboard/src/app/pay/page.tsx(2 hunks)packages/nexus-fetch/.size-limit.json(1 hunks)packages/nexus-fetch/biome.json(1 hunks)packages/nexus-fetch/knip.json(1 hunks)packages/nexus-fetch/package.json(1 hunks)packages/nexus-fetch/src/exports/nexus-fetch.ts(1 hunks)packages/nexus-fetch/src/fetch.ts(1 hunks)packages/nexus-fetch/testing/test.html(1 hunks)packages/nexus-fetch/tsconfig.base.json(1 hunks)packages/nexus-fetch/tsconfig.build.json(1 hunks)packages/nexus-fetch/tsconfig.json(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
- packages/nexus-fetch/tsconfig.json
- apps/dashboard/src/app/pay/page.tsx
- packages/nexus-fetch/knip.json
- packages/nexus-fetch/src/exports/nexus-fetch.ts
- packages/nexus-fetch/testing/test.html
- packages/nexus-fetch/.size-limit.json
- packages/nexus-fetch/tsconfig.build.json
- packages/nexus-fetch/tsconfig.base.json
🧰 Additional context used
📓 Path-based instructions (3)
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Track bundle budgets via
package.json#size-limit
Files:
packages/nexus-fetch/package.json
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each 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
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
packages/nexus-fetch/src/fetch.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
packages/nexus-fetch/src/fetch.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/page.tsx:77-81
Timestamp: 2025-08-20T10:35:18.543Z
Learning: The webhooks/payments route exists at apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/payments/page.tsx and was added as part of the unified project layout PR #7888.
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to biome.json : Biome governs formatting and linting; project rules live in biome.json
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to biome.json : Biome is the primary linter/formatter; rules are defined in `biome.json`
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Run `pnpm biome check --apply` before committing
Applied to files:
packages/nexus-fetch/biome.json
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/**/*.{ts,tsx} : Lazy‑load heavy dependencies inside async paths (e.g., `const { jsPDF } = await import("jspdf")`)
Applied to files:
packages/nexus-fetch/package.jsonpackages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/exports/** : Export all public API via `packages/thirdweb/exports/`, grouped by feature
Applied to files:
packages/nexus-fetch/package.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to packages/thirdweb/src/exports/** : Export everything via `exports/` directory, grouped by feature in the SDK public API
Applied to files:
packages/nexus-fetch/package.json
📚 Learning: 2025-06-17T18:30:52.976Z
Learnt from: MananTank
PR: thirdweb-dev/js#7356
File: apps/nebula/src/app/not-found.tsx:1-1
Timestamp: 2025-06-17T18:30:52.976Z
Learning: In the thirdweb/js project, the React namespace is available for type annotations (like React.FC) without needing to explicitly import React. This is project-specific configuration that differs from typical TypeScript/React setups.
Applied to files:
packages/nexus-fetch/package.json
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Create light wrappers (e.g. `fetchJson`) that automatically attach the JWT from cookies/session when calling internal API routes.
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Client-side data fetching: wrap calls in React Query with descriptive, stable `queryKeys` and set sensible `staleTime/cacheTime` (≥ 60s default); keep tokens secret via internal routes or server actions
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Server-side data fetching: call `getAuthToken()` from cookies, send `Authorization: Bearer <token>` header, and return typed results (avoid `any`)
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Applied to files:
packages/nexus-fetch/src/fetch.ts
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Applied to files:
packages/nexus-fetch/src/fetch.ts
🧬 Code graph analysis (1)
packages/nexus-fetch/src/fetch.ts (1)
packages/nexus-fetch/src/exports/nexus-fetch.ts (1)
wrap(1-1)
⏰ 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). (4)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Size
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
| @@ -0,0 +1,16 @@ | |||
| { | |||
| "$schema": "https://biomejs.dev/schemas/2.0.6/schema.json", | |||
| "extends": "//", | |||
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.
Fix the invalid Biome extends entry.
extends must resolve to an actual Biome config or shareable preset. The literal string "//" has no meaning here, so pnpm biome check fails while trying to load that path. Point it at the real base config (e.g. ../../biome.json) or drop the property altogether so biome can run.
🤖 Prompt for AI Agents
In packages/nexus-fetch/biome.json around line 3, the "extends" entry is invalid
("//"); replace it with a real Biome config path (for example
"../../biome.json") or remove the "extends" property entirely so Biome can
resolve a base config and pnpm biome check will succeed.

PR-Codex overview
This PR introduces several updates, including new configuration files, enhancements to the
PayPagecomponent, and updates to the fetch wrapper. It focuses on improving type safety, adding URL validation, and ensuring proper OAuth flow handling.Detailed summary
wrapexport fromfetch.js.biome.json,.size-limit.json,knip.json,tsconfig.json, andtsconfig.build.json.PayPagewith URL validation and handling success redirects.fetch.tswith OAuth flow and token management improvements.package.jsonwith new dependencies and scripts.Summary by CodeRabbit
New Features
Chores