Skip to content

Conversation

@0xFirekeeper
Copy link
Member

@0xFirekeeper 0xFirekeeper commented Sep 4, 2025

Migrates dashboard wallet user queries from manual fetch calls to the new @thirdweb-dev/api client, updating search, listing, and transformation logic in searchUsers.ts and useEmbeddedWallets.ts. Updates API client usage and types in sdk.gen.ts to match new endpoints and naming conventions. Adds @thirdweb-dev/api as a dependency in package.json.

Closes BLD-243


PR-Codex overview

This PR focuses on updating the API integration in the dashboard application, enhancing wallet functionalities, and improving the handling of user data through the new API endpoints.

Detailed summary

  • Updated THIRDWEB_API_HOST in urls.ts.
  • Integrated listUserWallets API for user wallet retrieval.
  • Replaced old API calls with new API client configuration.
  • Added error handling for API responses.
  • Modified wallet-related functions and types for better compatibility with the new API.
  • Refactored authentication methods for improved security.
  • Updated package dependencies in package.json and pnpm-lock.yaml.

The following files were skipped due to too many changes: packages/api/src/client/sdk.gen.ts, packages/api/src/client/types.gen.ts

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

Summary by CodeRabbit

  • New Features

    • Expanded public API: new wallet- and auth-focused endpoints plus payments, token/NFT listing, bridge swaps, chat, contract metadata/signatures, transaction/history access, and an AI-facing llms.txt resource.
  • Refactor

    • Dashboard embedded wallet user search/listing migrated to the generated API client with improved transformation and error handling.
    • Dashboard now reads API host from environment configuration (updated default API host).
  • Chores

    • Added the new API client dependency to the dashboard and excluded it from dependency checks.

Migrates dashboard wallet user queries from manual fetch calls to the new @thirdweb-dev/api client, updating search, listing, and transformation logic in searchUsers.ts and useEmbeddedWallets.ts. Updates API client usage and types in sdk.gen.ts to match new endpoints and naming conventions. Adds @thirdweb-dev/api as a dependency in package.json.

Closes BLD-243
@0xFirekeeper 0xFirekeeper requested review from a team as code owners September 4, 2025 21:33
@linear
Copy link

linear bot commented Sep 4, 2025

@changeset-bot
Copy link

changeset-bot bot commented Sep 4, 2025

⚠️ No Changeset found

Latest commit: f937095

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 4, 2025

Warning

Rate limit exceeded

@0xFirekeeper has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 0 minutes and 27 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 229aeb2 and f937095.

📒 Files selected for processing (1)
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (4 hunks)

Walkthrough

Adds @thirdweb-dev/api to the dashboard workspace, migrates in-app wallet user listing and search to use the generated API client (listUserWallets) with environment-configured base URL and headers, implements data transformers/helpers and error handling, replaces legacy EWS REST calls, updates the exported URL constant, and regenerates the API SDK to an auth/wallet-centric surface (including listUserWallets).

Changes

Cohort / File(s) Summary
Dashboard dependency
apps/dashboard/package.json
Adds @thirdweb-dev/api as a workspace dependency.
Dashboard: URL constant
apps/dashboard/src/@/constants/urls.ts
Renames THIRDWEB_EWS_API_HOSTTHIRDWEB_API_HOST and switches env var to NEXT_PUBLIC_THIRDWEB_API_HOST with default https://api.thirdweb-dev.com.
Dashboard wallet users: search + hooks
apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts, apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
Replaces EWS fetches with listUserWallets from @thirdweb-dev/api; configures client baseUrl from THIRDWEB_API_HOST; composes headers (Authorization, x-thirdweb-team-id, optional x-client-id, optional x-ecosystem-id); adds API type aliases, transformToWalletUser, getProfileId; builds typed queries; adds try/catch and logging; maps API response to existing WalletUser shape and supports paging.
Dashboard knip ignore
apps/dashboard/knip.json
Adds @thirdweb-dev/api to ignoreDependencies.
Generated API SDK
packages/api/src/client/sdk.gen.ts
Regenerates SDK to an auth/wallet-focused surface: adds listUserWallets and many new endpoints/types (auth, wallets, payments, tokens, bridge, chat, llmsTxt, mcpServer, etc.), removes/renames legacy types/endpoints, and shifts many endpoints to Bearer-style auth.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Dashboard UI
  participant Hook as useEmbeddedWallets / searchUsers
  participant API as @thirdweb-dev/api client
  participant Svc as Thirdweb API

  UI->>Hook: request users (filters, pagination)
  Hook->>API: configure({ override: { baseUrl } })
  Hook->>API: listUserWallets(query, { headers })
  API->>Svc: GET /v1/wallets/user
  Svc-->>API: 200 JSON or error
  API-->>Hook: response
  alt success
    Hook->>Hook: transformToWalletUser(response.data)
    Hook-->>UI: WalletUser[]
  else error
    Hook->>Hook: console.error(...)
    Hook-->>UI: []
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Assessment against linked issues

Objective Addressed Explanation
Migrate EWS to API for Wallets->UserList (BLD-243)
Fix edge cases where users can't load (BLD-243) Error handling and ID-extraction helpers were added, but specific edge cases from the issue are not explicitly documented or tested in the diff.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Large SDK regeneration (packages/api/src/client/sdk.gen.ts) The linked issue targets migration to listUserWallets; the SDK regen introduces many unrelated endpoints/types (payments, bridge, chat, tokens, llmsTxt, mcpServer, etc.) that exceed the stated objective.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch firekeeper/fix-wallet-list

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@vercel
Copy link

vercel bot commented Sep 4, 2025

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

Project Deployment Preview Comments Updated (UTC)
thirdweb-www Ready Ready Preview Comment Sep 4, 2025 10:22pm
4 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
docs-v2 Skipped Skipped Sep 4, 2025 10:22pm
nebula Skipped Skipped Sep 4, 2025 10:22pm
thirdweb_playground Skipped Skipped Sep 4, 2025 10:22pm
wallet-ui Skipped Skipped Sep 4, 2025 10:22pm

@graphite-app
Copy link
Contributor

graphite-app bot commented Sep 4, 2025

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.

@github-actions github-actions bot added Dashboard Involves changes to the Dashboard. packages labels Sep 4, 2025
@codecov
Copy link

codecov bot commented Sep 4, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.53%. Comparing base (17d40af) to head (f937095).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7987   +/-   ##
=======================================
  Coverage   56.53%   56.53%           
=======================================
  Files         904      904           
  Lines       58626    58626           
  Branches     4146     4146           
=======================================
  Hits        33145    33145           
  Misses      25375    25375           
  Partials      106      106           
Flag Coverage Δ
packages 56.53% <ø> (ø)
🚀 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 Sep 4, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.01 KB (0%) 1.3 s (0%) 141 ms (+60.99% 🔺) 1.5 s
thirdweb (cjs) 357.32 KB (0%) 7.2 s (0%) 600 ms (-3.46% 🔽) 7.8 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 61 ms (+1313.82% 🔺) 175 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 37 ms (+2390.37% 🔺) 47 ms
thirdweb/react (minimal + tree-shaking) 19.15 KB (0%) 383 ms (0%) 43 ms (+178.66% 🔺) 426 ms

Moved THIRDWEB_API_HOST definition to a shared constants file and updated imports in searchUsers and useEmbeddedWallets to use the centralized constant. This improves maintainability and consistency across the codebase.
@vercel vercel bot temporarily deployed to Preview – nebula September 4, 2025 21:42 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 4, 2025 21:42 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 4, 2025 21:42 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 September 4, 2025 21:42 Inactive
Changed the fallback THIRDWEB_API_HOST from 'https://api.thirdweb.com' to 'https://api.thirdweb-dev.com' to reflect the new API endpoint.
@vercel vercel bot temporarily deployed to Preview – docs-v2 September 4, 2025 21:43 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 4, 2025 21:43 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula September 4, 2025 21:43 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 4, 2025 21:43 Inactive
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: 5

🧹 Nitpick comments (8)
packages/api/src/client/sdk.gen.ts (1)

459-461: Typo: “signle” → “single” (public docs)

Minor doc polish for Get Balance description.

- * Get native or ERC20 token balance for a wallet address. Can retrieve live balances for any ERC20 token on a signle chain, or native token balances across multiple chains.
+ * Get native or ERC20 token balance for a wallet address. Can retrieve live balances for any ERC20 token on a single chain, or native token balances across multiple chains.
apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts (2)

22-26: Stable user id: fallback to wallet address when profiles are empty

An empty id breaks keys and selection. Prefer wallet address as a stable fallback.

-    id: getProfileId(apiWallet.profiles[0]) || "",
+    id: getProfileId(apiWallet.profiles[0]) || apiWallet.address || "",

51-58: createdAt fallback can mislead; avoid “now” as synthetic creation time

Using the current time skews sorting and UX. Omit the field or set null when missing.

-            createdAt: apiWallet.createdAt || new Date().toISOString(),
+            ...(apiWallet.createdAt ? { createdAt: apiWallet.createdAt } : {}),

If WalletUser requires createdAt, consider making it optional in the type used by this view.

apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (5)

2-6: Prefer lazy-loading the API client to keep bundles lean and avoid module side-effects

Defer importing @thirdweb-dev/api (and running configuration) until inside the fetch path. This reduces initial dashboard bundle size and avoids global state at module import time.

Apply within this hunk:

-import { configure, listUserWallets } from "@thirdweb-dev/api";
+// Defer '@thirdweb-dev/api' imports to the fetch path to reduce bundle size.

Then inside the fetch function (outside this hunk), dynamically import and configure once:

let apiConfigured = false;
async function getListUserWallets() {
  const mod = await import("@thirdweb-dev/api");
  if (!apiConfigured) {
    mod.configure({ override: { baseUrl: THIRDWEB_API_HOST.replace(/\/+$/, "") } });
    apiConfigured = true;
  }
  return mod.listUserWallets;
}

And replace direct calls with:

const listUserWallets = await getListUserWallets();

11-18: Base URL config: sanitize and mark this as a client module; avoid top-level side effects

  • Sanitize trailing slashes to prevent //v1/... joins.
  • This hook uses React Query and browser-only auth headers; declare 'use client' to avoid accidental server import.
  • Consider moving configure(...) out of top-level (see previous comment).

Apply within this hunk:

-const THIRDWEB_API_HOST =
-  process.env.NEXT_PUBLIC_THIRDWEB_API_HOST || "https://api.thirdweb.com";
+const THIRDWEB_API_HOST = (process.env.NEXT_PUBLIC_THIRDWEB_API_HOST ??
+  "https://api.thirdweb.com").replace(/\/+$/, "");

Additionally (outside this hunk), add at the top of the file:

'use client';

38-44: Minor: pull page size into a constant and consider optional filters

Use a PAGE_SIZE constant and thread optional filters (email/phone/address/id) when provided by callers.


59-67: Propagate richer errors

Preserve the original error when possible; fallback to a readable message rather than "No data returned".

-      if (response.error || !response.data) {
-        const errorMessage =
-          typeof response.error === "string"
-            ? response.error
-            : "No data returned";
-        throw new Error(errorMessage);
-      }
+      if (response.error || !response.data) {
+        const err =
+          response.error instanceof Error
+            ? response.error
+            : new Error(
+                typeof response.error === "string"
+                  ? response.error
+                  : "Request failed with no payload",
+              );
+        throw err;
+      }

72-76: Improve log context (and consider routing to telemetry)

Include pageNumber, teamId, and client/ecosystem identifiers to speed up triage.

-      console.error("Failed to fetch wallets:", error);
+      console.error(
+        "Failed to fetch wallets",
+        { pageNumber, teamId, clientId, ecosystemSlug },
+        error,
+      );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 769019d and 3744fdb.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • apps/dashboard/package.json (1 hunks)
  • apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts (2 hunks)
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (2 hunks)
  • packages/api/src/client/sdk.gen.ts (20 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

Track bundle budgets via package.json#size-limit

Files:

  • apps/dashboard/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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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 @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
  • apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts
  • packages/api/src/client/sdk.gen.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
  • apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts
  • packages/api/src/client/sdk.gen.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
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
  • apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts
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)
Use NavLink for internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names with cn() from @/lib/utils for conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start with import "server-only"; use next/headers, server‑only env, heavy data fetching, and redirect() where appropriate
Client Components must start with 'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: call getAuthToken() from cookies, send Authorization: Bearer <token> header, and return typed results (avoid any)
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
Do not import posthog-js in server components (client-side only)

Files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
  • apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts
🧠 Learnings (9)
📓 Common learnings
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/wallets/** : Support for in-app wallets (social/email login)
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/wallets/** : Unified `Wallet` and `Account` interfaces in wallet architecture
📚 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/wallets/** : Unified `Wallet` and `Account` interfaces in wallet architecture

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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 packages/thirdweb/src/wallets/** : EIP-1193, EIP-5792, EIP-7702 standard support in wallet modules

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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 packages/thirdweb/src/wallets/** : Support for in-app wallets (social/email login)

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Use React Query (`tanstack/react-query`) for all client data fetching.

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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 apps/{dashboard,playground-web}/**/*.{ts,tsx} : Wrap client-side data fetching calls in React Query (`tanstack/react-query`)

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
🧬 Code graph analysis (3)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (2)
packages/api/src/client/types.gen.ts (2)
  • ListUserWalletsResponses (627-844)
  • ListUserWalletsData (601-614)
packages/api/src/client/sdk.gen.ts (1)
  • listUserWallets (356-373)
apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts (2)
packages/api/src/client/types.gen.ts (2)
  • ListUserWalletsResponses (627-844)
  • ListUserWalletsData (601-614)
packages/api/src/client/sdk.gen.ts (1)
  • listUserWallets (356-373)
packages/api/src/client/sdk.gen.ts (2)
packages/api/src/client/client/types.ts (1)
  • Options (191-199)
packages/api/src/client/types.gen.ts (86)
  • InitiateAuthenticationData (3-87)
  • InitiateAuthenticationResponses (100-164)
  • InitiateAuthenticationErrors (89-98)
  • CompleteAuthenticationData (169-303)
  • CompleteAuthenticationResponses (316-338)
  • CompleteAuthenticationErrors (305-314)
  • SocialAuthenticationData (343-374)
  • SocialAuthenticationErrors (376-381)
  • GetMyWalletData (383-388)
  • GetMyWalletResponses (405-596)
  • GetMyWalletErrors (390-403)
  • ListUserWalletsData (601-614)
  • ListUserWalletsResponses (627-844)
  • ListUserWalletsErrors (616-625)
  • CreateUserWalletData (849-875)
  • CreateUserWalletResponses (892-1083)
  • CreateUserWalletErrors (877-890)
  • ListServerWalletsData (1088-1096)
  • ListServerWalletsResponses (1109-1326)
  • ListServerWalletsErrors (1098-1107)
  • CreateServerWalletData (1331-1344)
  • CreateServerWalletResponses (1361-1552)
  • CreateServerWalletErrors (1346-1359)
  • SignMessageData (2160-2181)
  • SignMessageResponses (2198-2210)
  • SignMessageErrors (2183-2196)
  • SignTypedDataData (2215-2282)
  • SignTypedDataResponses (2299-2311)
  • SignTypedDataErrors (2284-2297)
  • SendTokensData (2316-2354)
  • SendTokensResponses (2371-2383)
  • SendTokensErrors (2356-2369)
  • ListContractsData (2387-2401)
  • ListContractsResponses (2422-2485)
  • ListContractsErrors (2403-2420)
  • DeployContractData (2490-2525)
  • DeployContractResponses (2546-2566)
  • DeployContractErrors (2527-2544)
  • ReadContractData (2571-2602)
  • ReadContractResponses (2619-2642)
  • ReadContractErrors (2604-2617)
  • WriteContractData (2647-2682)
  • WriteContractResponses (2703-2715)
  • WriteContractErrors (2684-2701)
  • GetContractTransactionsData (2720-2779)
  • GetContractTransactionsResponses (2800-2938)
  • GetContractTransactionsErrors (2781-2798)
  • GetContractEventsData (2943-3006)
  • GetContractEventsResponses (3027-3117)
  • GetContractEventsErrors (3008-3025)
  • GetContractMetadataData (3122-3136)
  • GetContractMetadataResponses (3161-3254)
  • GetContractMetadataErrors (3138-3159)
  • GetContractSignaturesData (3259-3273)
  • GetContractSignaturesResponses (3298-3308)
  • GetContractSignaturesErrors (3275-3296)
  • GetTransactionByIdData (3313-3323)
  • GetTransactionByIdResponses (3344-3416)
  • GetTransactionByIdErrors (3325-3342)
  • CreatePaymentData (3622-3669)
  • CreatePaymentResponses (3690-3707)
  • CreatePaymentErrors (3671-3688)
  • GetPaymentHistoryData (3712-3719)
  • GetPaymentHistoryResponses (3739-3807)
  • GetPaymentHistoryErrors (3721-3734)
  • PaymentsPurchaseData (3812-3828)
  • PaymentsPurchaseResponses (3849-3861)
  • PaymentsPurchaseErrors (3830-3847)
  • ListTokensData (3866-3896)
  • ListTokensResponses (3913-3956)
  • ListTokensErrors (3898-3911)
  • CreateTokenData (3960-4031)
  • CreateTokenResponses (4052-4066)
  • CreateTokenErrors (4033-4050)
  • GetTokenOwnersData (4071-4094)
  • GetTokenOwnersResponses (4115-4154)
  • GetTokenOwnersErrors (4096-4113)
  • BridgeSwapData (4159-4213)
  • BridgeSwapResponses (4234-4247)
  • BridgeSwapErrors (4215-4232)
  • ChatData (4251-4310)
  • ChatResponses (4312-4391)
  • McpServerData (4395-4400)
  • McpServerResponses (4402-4407)
  • LlmsTxtData (4409-4414)
  • LlmsTxtResponses (4416-4421)
⏰ 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: Size
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Build Packages
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (7)
packages/api/src/client/sdk.gen.ts (2)

350-373: Backend-only: listUserWallets requires x-secret-key

SDK correctly models this as secret-key–only. Ensure dashboard code (searchUsers.ts) does not call this from the browser or with a user Bearer token. Route via server action/internal API that injects x-secret-key.


472-479: Include secret-key auth in security for server-side usage

Docs say x-client-id or x-secret-key. The security section only lists x-client-id, which may prevent auto-auth via secret if your client supports it.

If your client auto-injects auth based on this array, add x-secret-key to security here (and similarly for getWalletTokens/Nfts/Transactions, getContractEvents/Transactions, listTokens, getTokenOwners) to match docs. Otherwise, confirm manual headers suffice.

apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts (1)

56-57: Verify wallet type mapping

Hardcoding type: "enclave" for all addresses may be incorrect. Derive from available fields (e.g., presence of smartWalletAddress) or align with WalletUser’s allowed types.

Would you like a tiny helper that infers type = "smart" | "eoa" | "custodial" based on apiWallet fields?

apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (4)

20-23: Type extraction LGTM

Good use of SDK-derived types to keep transformations honest.


120-134: Helper LGTM

Straightforward narrowing across profile variants.


45-57: Verify auth header, cancellation support, and drop Content-Type

  • Confirm that listUserWallets expects the SDK’s security header (e.g. x-secret-key) rather than sending Authorization: Bearer <jwt> from the client to avoid 401s.
  • Check whether listUserWallets accepts an AbortSignal; if so, forward React Query’s signal to cancel in-flight requests.
  • Remove the unnecessary "Content-Type": "application/json" on a GET.

79-118: Guarantee stable non-empty IDs, correct wallet mapping, and deterministic timestamps

  • Fallback id to apiWallet.address/apiWallet.smartWalletAddress to avoid empty keys.
  • Map both EOA (address) and smart wallets separately with the correct type, using the API’s createdAt.
  • Simplify details to Record<string, string>.

Verify that APIWallet includes smartWalletAddress and that these fields match the WalletUser specification.

Updated the knip.json configuration to include @thirdweb-dev/api in the ignoreDependencies list for the dashboard app.
@vercel vercel bot temporarily deployed to Preview – docs-v2 September 4, 2025 21:50 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 4, 2025 21:50 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 4, 2025 21:50 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula September 4, 2025 21:50 Inactive
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (1)

167-209: Use hasMore to terminate; avoid potential over-fetch

Rely on server pagination instead of zero-length heuristic.

-        const res = await queryClient.fetchQuery<{
-          users: WalletUser[];
-        }>({
+        const res = await queryClient.fetchQuery<{
+          users: WalletUser[];
+          hasMore?: boolean;
+        }>({
           queryFn: fetchAccountList({
             clientId,
             ecosystemSlug,
             teamId,
             jwt: authToken,
             pageNumber: page,
           }),
           queryKey: embeddedWalletsKeys.embeddedWallets(
             address || "",
             clientId || ecosystemSlug || "",
             page,
           ),
         });
 
-        if (res.users.length === 0) {
+        if (!res.hasMore) {
           break;
         }
 
         page++;
         responses.push(...res.users);
♻️ Duplicate comments (1)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (1)

68-70: Return pagination.hasMore to avoid length-based loops

Expose server intent to terminate pagination.

-      return {
-        users: response.data.result.wallets.map(transformToWalletUser),
-      };
+      return {
+        users: response.data.result.wallets.map(transformToWalletUser),
+        hasMore: Boolean(response.data.result.pagination?.hasMore),
+      };
🧹 Nitpick comments (10)
apps/dashboard/knip.json (1)

11-11: Do we need to ignore "@thirdweb-dev/api"?

It’s actively imported in dashboard code; removing it from ignoreDependencies helps Knip catch accidental removals. If Knip fails to detect type‑only usage, keep the ignore but add a comment explaining why.

apps/dashboard/src/@/constants/urls.ts (1)

1-2: Add fallback to old env var to smooth deploys

Keep backward compatibility during the env rollout.

-export const THIRDWEB_API_HOST =
-  process.env.NEXT_PUBLIC_THIRDWEB_API_HOST || "https://api.thirdweb-dev.com";
+export const THIRDWEB_API_HOST =
+  process.env.NEXT_PUBLIC_THIRDWEB_API_HOST ||
+  process.env.NEXT_PUBLIC_THIRDWEB_EWS_API_HOST || // fallback for older envs
+  "https://api.thirdweb-dev.com";
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (8)

12-17: Avoid module-scoped client configuration duplication

Consider centralizing API client configure() in a single module (e.g., apiClient.ts) to prevent accidental overrides across imports.


39-42: Extract page size to a constant and accept override

Improves reuse and testing; some lists may prefer 100.

-      const queryParams: ListUserWalletsData["query"] = {
-        page: pageNumber,
-        limit: 50, // Keep the same page size
-      };
+      const PAGE_SIZE = 50;
+      const queryParams: ListUserWalletsData["query"] = {
+        page: pageNumber,
+        limit: PAGE_SIZE,
+      };

45-56: Drop Content-Type on GET

Not needed and occasionally triggers CORS preflight unnecessarily.

       const response = await listUserWallets({
         query: queryParams,
         headers: {
           Authorization: `Bearer ${jwt}`,
-          "Content-Type": "application/json",
           "x-thirdweb-team-id": teamId,
           ...(clientId && { "x-client-id": clientId }),
           ...(ecosystemSlug && {
             "x-ecosystem-id": `ecosystem.${ecosystemSlug}`,
           }),
         },
       });

59-66: Preserve server error details

Surface message/code if present for better debugging.

-      if (response.error || !response.data) {
-        const errorMessage =
-          typeof response.error === "string"
-            ? response.error
-            : "No data returned";
-        throw new Error(errorMessage);
-      }
+      if (response.error || !response.data) {
+        const err = response.error as
+          | string
+          | { message?: string; code?: string; error?: string };
+        const msg =
+          typeof err === "string"
+            ? err
+            : err?.message || err?.error || "No data returned";
+        throw new Error(msg);
+      }

120-132: Broaden profile ID fallback, keep deterministic

If API profiles can include other identifiers (e.g., userId), consider extending fallback. If not, ignore.

   if ("id" in profile) {
     return profile.id;
   } else if ("credentialId" in profile) {
     return profile.credentialId;
   } else if ("identifier" in profile) {
     return profile.identifier;
+  } else if ("userId" in (profile as any)) {
+    return (profile as any).userId as string;
   }

144-158: Set sensible cache/stale timings and add explicit return type

Match dashboard data-fetching guidelines.

-  return useQuery({
+  return useQuery<{
+    users: WalletUser[];
+    hasMore?: boolean;
+  }>({
     enabled: !!address && !!(clientId || ecosystemSlug),
+    staleTime: 60_000,
+    gcTime: 5 * 60_000,

134-159: Add explicit hook return types

For maintainability and DX, annotate the return types of both hooks.

Also applies to: 167-209


23-35: Auth token usage in client

Ensure jwt is ephemeral and scoped. Prefer proxying via internal API route/server action to keep tokens off the client.

Also applies to: 144-158, 167-209

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 3744fdb and 51fe8c4.

📒 Files selected for processing (4)
  • apps/dashboard/knip.json (1 hunks)
  • apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.ts (2 hunks)
  • apps/dashboard/src/@/constants/urls.ts (1 hunks)
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/src/@/components/in-app-wallet-users-content/searchUsers.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 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
Avoid any and unknown unless 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 @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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:

  • apps/dashboard/src/@/constants/urls.ts
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • apps/dashboard/src/@/constants/urls.ts
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/constants/urls.ts
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
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)
Use NavLink for internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names with cn() from @/lib/utils for conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start with import "server-only"; use next/headers, server‑only env, heavy data fetching, and redirect() where appropriate
Client Components must start with 'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: call getAuthToken() from cookies, send Authorization: Bearer <token> header, and return typed results (avoid any)
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
Do not import posthog-js in server components (client-side only)

Files:

  • apps/dashboard/src/@/constants/urls.ts
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
🧠 Learnings (8)
📓 Common learnings
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/wallets/** : Unified `Wallet` and `Account` interfaces in wallet architecture
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/wallets/** : EIP-1193, EIP-5792, EIP-7702 standard support in wallet modules
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/wallets/** : Support for in-app wallets (social/email login)
📚 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/wallets/** : Unified `Wallet` and `Account` interfaces in wallet architecture

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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 packages/thirdweb/src/wallets/** : EIP-1193, EIP-5792, EIP-7702 standard support in wallet modules

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Use React Query (`tanstack/react-query`) for all client data fetching.

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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 apps/{dashboard,playground-web}/**/*.{ts,tsx} : Wrap client-side data fetching calls in React Query (`tanstack/react-query`)

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
⏰ 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 (1)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (1)

144-146: Revisit address gating

Listing users likely shouldn’t depend on active wallet address. If this was intentional, ignore.

Enhanced the fetchAccountList function and related hooks to handle paginated API responses using the hasMore flag. This ensures all wallet users are fetched across multiple pages, improving reliability and scalability of wallet data retrieval.
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 4, 2025 22:07 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 4, 2025 22:07 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula September 4, 2025 22:07 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 September 4, 2025 22:07 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 September 4, 2025 22:10 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula September 4, 2025 22:10 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 4, 2025 22:10 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 4, 2025 22:10 Inactive
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 (3)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (3)

68-71: Good: expose server pagination intent

Returning hasMore aligns the consumer loop with server pagination. Nice.


82-82: Stabilize user.id (avoid empty-string collisions)

Fallback to the wallet address when no profile id exists to keep ids unique.

-    id: getProfileId(apiWallet.profiles[0]) || "",
+    id: getProfileId(apiWallet.profiles[0]) || apiWallet.address || "",

112-112: Don’t fabricate createdAt

Avoid setting createdAt to client time; omit it when absent to prevent misleading data.

-            createdAt: apiWallet.createdAt || new Date().toISOString(),
+            createdAt: apiWallet.createdAt || undefined,
🧹 Nitpick comments (6)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (6)

12-17: Centralize API client configuration

Configuring the API client at module load is fine, but consider moving this to a single shared module (e.g., "@/lib/apiClient") to avoid divergent config if used elsewhere. Optionally lazy-load to keep bundles lean.


49-49: Drop Content-Type on GET

Content-Type isn’t needed for a GET without a body.

-          "Content-Type": "application/json",

145-159: Set sensible cache policy for React Query

Per guidelines, add ≥60s freshness. Also consider a GC time.

   return useQuery({
     enabled: !!address && !!(clientId || ecosystemSlug),
@@
     queryKey: embeddedWalletsKeys.embeddedWallets(
       address || "",
       clientId || ecosystemSlug || "",
       page,
     ),
+    staleTime: 60_000,
+    gcTime: 5 * 60_000,
   });

179-207: Add a pagination safety cap to avoid infinite loops

Guard against bad hasMore responses and empty pages.

   const responses: WalletUser[] = [];
   let page = 1;
+  const MAX_PAGES = 1000;

-  while (true) {
+  while (page <= MAX_PAGES) {
@@
-    if (!res.hasMore) {
+    if (!res.hasMore || res.users.length === 0) {
       break;
     }
@@
     page++;
   }

23-36: Annotate return types for clarity

Add an explicit page type and annotate the async factory’s return type.

 type APIProfile = APIWallet["profiles"][0];
 
+type WalletListPage = {
+  users: WalletUser[];
+  hasMore: boolean;
+};
@@
-}) => {
-  return async () => {
+}) => {
+  return async (): Promise<WalletListPage> => {

45-56: Hide tokens behind an internal API route

Passing authToken from the client and calling the Thirdweb API directly exposes credentials in the browser. Prefer a server action or internal API route that reads the JWT via getAuthToken() and forwards the request.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 51fe8c4 and 229aeb2.

📒 Files selected for processing (1)
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (1 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 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
Avoid any and unknown unless 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 @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
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)
Use NavLink for internal navigation to get active state handling
Use Tailwind CSS for styling; no inline styles
Merge class names with cn() from @/lib/utils for conditional classes
Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components must start with import "server-only"; use next/headers, server‑only env, heavy data fetching, and redirect() where appropriate
Client Components must start with 'use client'; handle interactivity with hooks and browser APIs
Server-side data fetching: call getAuthToken() from cookies, send Authorization: Bearer <token> header, and return typed results (avoid any)
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
Do not import posthog-js in server components (client-side only)

Files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
🧠 Learnings (8)
📓 Common learnings
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/wallets/** : Support for in-app wallets (social/email login)
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/wallets/** : Unified `Wallet` and `Account` interfaces in wallet architecture
📚 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/wallets/** : Unified `Wallet` and `Account` interfaces in wallet architecture

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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 packages/thirdweb/src/wallets/** : EIP-1193, EIP-5792, EIP-7702 standard support in wallet modules

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Use React Query (`tanstack/react-query`) for all client data fetching.

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.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 apps/{dashboard,playground-web}/**/*.{ts,tsx} : Wrap client-side data fetching calls in React Query (`tanstack/react-query`)

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
📚 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 : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
🧬 Code graph analysis (1)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (3)
apps/dashboard/src/@/constants/urls.ts (1)
  • THIRDWEB_API_HOST (1-2)
packages/api/src/client/types.gen.ts (2)
  • ListUserWalletsResponses (627-844)
  • ListUserWalletsData (601-614)
packages/api/src/client/sdk.gen.ts (1)
  • listUserWallets (356-373)
⏰ 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)
apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (2)

146-147: Verify address gating is intended

Fetching user wallets may not require a connected address. If admins should load lists without connecting, consider removing the address dependency from enabled.


47-55: Auth scheme and header names confirmed
The /v1/wallets/user endpoint accepts a Bearer JWT (Authorization: Bearer <token>) alongside x-thirdweb-team-id and x-ecosystem-id: ecosystem.<slug>. No x-secret-key header is required when authenticating with a valid Bearer JWT. [1][4][6]

@0xFirekeeper 0xFirekeeper merged commit 22d736c into main Sep 5, 2025
24 checks passed
@0xFirekeeper 0xFirekeeper deleted the firekeeper/fix-wallet-list branch September 5, 2025 01:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Dashboard Involves changes to the Dashboard. packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants