Skip to content

Conversation

@MananTank
Copy link
Member

@MananTank MananTank commented Aug 21, 2025


PR-Codex overview

This PR enhances the v5-adapter by introducing new hooks for managing chains in the dashboard. It updates several components to utilize these hooks, improving the handling of chain data across the application.

Detailed summary

  • Added useGetV5DashboardChain and useGetV5DashboardChain hooks in v5-adapter.ts.
  • Replaced direct calls to defineChain with the new hooks in multiple components.
  • Updated LaunchNFT, CreateTokenAssetPageUI, CreateNFTPage, and CreateTokenAssetPage to use the new hooks for chain management.

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

Summary by CodeRabbit

  • Refactor

    • Unified chain resolution across NFT creation, launch, and token creation flows via a new hook-based resolver for consistent behavior.
    • Replaced older runtime chain handling with the new approach to streamline chain selection.
  • Bug Fixes

    • Improved reliability of chain selection during deployments and validations, reducing wrong-network occurrences and improving form/launch consistency.

@vercel vercel bot temporarily deployed to Preview – wallet-ui August 21, 2025 15:20 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground August 21, 2025 15:20 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 August 21, 2025 15:20 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 21, 2025 15:20 Inactive
@vercel
Copy link

vercel bot commented Aug 21, 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 Aug 21, 2025 7:33pm
4 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
docs-v2 Skipped Skipped Aug 21, 2025 7:33pm
nebula Skipped Skipped Aug 21, 2025 7:33pm
thirdweb_playground Skipped Skipped Aug 21, 2025 7:33pm
wallet-ui Skipped Skipped Aug 21, 2025 7:33pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 21, 2025

Walkthrough

Adds a v5 dashboard chain adapter hook and refactors token/NFT creation flows to use it for chain resolution instead of runtime defineChain; updates imports, query keys, and TokenProvider/deploy paths to consume resolved Dashboard Chain objects.

Changes

Cohort / File(s) Summary
V5 chain adapter hook
apps/dashboard/src/@/hooks/chains/v5-adapter.ts
Adds useGetV5DashboardChain() returning a memoized factory (via useCallback) to resolve dashboard Chain objects by chainId; retains useV5DashboardChain; imports updated.
NFT creation pages
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx, apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
Replaces defineChain(...) calls with hook-based resolution (useGetV5DashboardChain / useV5DashboardChain), passes resolved chain to TokenProvider and deployment functions; removes defineChain imports and ESLint disables.
Token creation pages
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx, apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx
Replaces defineChain usage with useGetV5DashboardChain factory and local chain variables across deployed contract lookups, create/deploy calls, and query keys; updates imports and argument passing.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as Page / Component
  participant HookFactory as useGetV5DashboardChain()
  participant HookSingle as useV5DashboardChain
  participant Map as idToChain
  participant Def as defineDashboardChain
  participant Ops as Deployment / TokenProvider / Queries

  UI->>HookFactory: const getChain = useGetV5DashboardChain()
  UI->>HookFactory: getChain(chainId)
  HookFactory->>Map: lookup metadata (idToChain.get(chainId))
  HookFactory->>Def: defineDashboardChain(chainId, metadata)
  Def-->>HookFactory: Dashboard Chain
  HookFactory-->>UI: Dashboard Chain
  UI->>Ops: call deploy/provider/query with Dashboard Chain

  alt existing single-hook usage
    UI->>HookSingle: useV5DashboardChain(chainId)
    HookSingle->>Map: lookup & defineDashboardChain(...)
    HookSingle-->>UI: Dashboard Chain
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
MNY-115: Fix deployment errors on Freeq testnet (hidden chain) Unclear if hidden-chain RPC handling (e.g., custom RPC routing or indexing for hidden chains) is fully covered; changes wire chain resolution to dashboard-managed chains but do not show explicit RPC override or additional handling for hidden networks.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 08-21-_mny-115_dashboard_fix_token_creation_flow_not_working_for_custom_chains

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

@linear
Copy link

linear bot commented Aug 21, 2025

@MananTank MananTank marked this pull request as ready for review August 21, 2025 15:20
@MananTank MananTank requested review from a team as code owners August 21, 2025 15:20
@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label Aug 21, 2025
Copy link
Member Author

MananTank commented Aug 21, 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.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@changeset-bot
Copy link

changeset-bot bot commented Aug 21, 2025

⚠️ No Changeset found

Latest commit: 6caba38

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

@codecov
Copy link

codecov bot commented Aug 21, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.53%. Comparing base (68a07ed) to head (6caba38).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7896   +/-   ##
=======================================
  Coverage   56.53%   56.53%           
=======================================
  Files         904      904           
  Lines       58592    58592           
  Branches     4143     4143           
=======================================
  Hits        33126    33126           
  Misses      25360    25360           
  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 Aug 21, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.06 KB (0%) 1.3 s (0%) 241 ms (+180.34% 🔺) 1.6 s
thirdweb (cjs) 357.05 KB (0%) 7.2 s (0%) 713 ms (+15.06% 🔺) 7.9 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 76 ms (+1337.14% 🔺) 191 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 60 ms (+3681.36% 🔺) 70 ms
thirdweb/react (minimal + tree-shaking) 19.15 KB (0%) 383 ms (0%) 77 ms (+573.54% 🔺) 460 ms

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: 0

Caution

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

⚠️ Outside diff range comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx (2)

100-113: Use a stable, serializable query key and gate query until chain is ready

Using the Chain object in a React Query key can lead to cache misses due to object identity and serialization. Also, the query can fire with an undefined chain on first render. Use the numeric chainId in the key, set enabled, and add a conservative staleTime to reduce refetches.

Apply this diff:

-  const isERC20AssetSupportedQuery = useQuery({
-    queryKey: ["is-erc20-asset-supported", chain],
+  const isERC20AssetSupportedQuery = useQuery({
+    queryKey: ["is-erc20-asset-supported", Number(tokenInfoForm.watch("chain"))],
     queryFn: async () => {
       try {
         const res = await getDeployedContractFactory({
           // eslint-disable-next-line no-restricted-syntax
-          chain: chain,
+          chain: chain,
           client: props.client,
         });
         return !!res;
       } catch {
         return false;
       }
     },
+    enabled: !!chain,
+    staleTime: 60_000,
   });

115-127: Mirror the same improvements on router-enabled query

Key off the chainId (not the Chain object), and gate execution until chain is available. Add staleTime for sensible caching.

Apply this diff:

-  const isAssetRouterEnabledQuery = useQuery({
+  const isAssetRouterEnabledQuery = useQuery({
     queryFn: async () => {
       try {
         return await isPoolRouterEnabled({
-          chain: chain,
+          chain: chain,
           client: props.client,
         });
       } catch {
         return false;
       }
     },
-    queryKey: ["is-asset-router-enabled", chain],
+    queryKey: ["is-asset-router-enabled", Number(tokenInfoForm.watch("chain"))],
+    enabled: !!chain,
+    staleTime: 60_000,
   });
🧹 Nitpick comments (7)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx (1)

63-63: Consider guarding against missing custom metadata before deploy/lookup

If idToChain isn't populated yet (slow network, first load), getChain(Number(...)) may fall back to a default chain definition without the custom RPC, risking the same RPC routing failure seen in MNY-115. Two light options:

  • Block actions until chain metadata is ready.
  • Validate the chain object (e.g., has expected RPC URL) and surface a friendly error/toast if not.

I can wire a tiny helper that checks readiness and disables the launch button until resolved.

Also applies to: 91-91

apps/dashboard/src/@/hooks/chains/v5-adapter.ts (2)

30-39: Add an explicit return type for stability and DX

Small typing nit: declare the return type so the hook’s API stays stable and discoverable.

Apply this diff:

-export function useGetV5DashboardChain() {
+export function useGetV5DashboardChain(): (chainId: number) => Chain {
   const { idToChain } = useAllChainsData();
   return useCallback(
     (chainId: number) => {
       // eslint-disable-next-line no-restricted-syntax
       return defineDashboardChain(chainId, idToChain.get(chainId));
     },
     [idToChain],
   );
 }

19-27: Optional: Protect custom networks from silent fallback

If idToChain lacks metadata for a custom chain, defineDashboardChain(chainId, undefined) may produce a generic chain that routes via default RPCs. Consider a dev-time invariant/log when idToChain.get(chainId) is undefined for a non-known chain to surface configuration issues early. I can add a DEV-only warn with a single line guard.

Also applies to: 30-39

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx (3)

114-119: Consistency nit: avoid passing “chain: chain” and parse once

Not functional, but a quick cleanup improves readability:

  • Prefer “chain,” shorthand.
  • Parse chainId to number once per function and reuse.

Apply this diff:

-    const chain = getChain(Number(params.values.chain));
+    const chainId = Number(params.values.chain);
+    const chain = getChain(chainId);
@@
-      chain: chain,
+      chain,

And similarly in DropERC20_deployContract:

-    const chain = getChain(Number(params.values.chain));
+    const chainId = Number(params.values.chain);
+    const chain = getChain(chainId);
@@
-      chain: chain,
+      chain,

Also applies to: 249-254


156-163: Analytics label mismatch (‘ERC20Asset’ path reported as ‘DropERC20’)

This is likely skewing metrics. In the ERC20Asset_deployContract flow, contractType is “ERC20Asset” when saving to the project, but reportContractDeployed uses contractName: "DropERC20".

Apply this diff:

-    reportContractDeployed({
-      address: contractAddress,
-      chainId: Number(params.values.chain),
-      contractName: "DropERC20",
-      deploymentType: "asset",
-      publisher: account.address,
-    });
+    reportContractDeployed({
+      address: contractAddress,
+      chainId: Number(params.values.chain),
+      contractName: "ERC20Asset",
+      deploymentType: "asset",
+      publisher: account.address,
+    });

454-456: Likely wrong path segment (projectId vs projectSlug) for revalidation

Routes are under [project_slug], but the revalidate path uses props.projectId. This can prevent cache invalidation for the visible page.

Apply this diff:

-        revalidatePathAction(
-          `/team/${props.teamSlug}/project/${props.projectId}/tokens`,
-          "page",
-        );
+        revalidatePathAction(
+          `/team/${props.teamSlug}/project/${props.projectSlug}/tokens`,
+          "page",
+        );
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx (1)

506-507: TokenProvider chain: safe usage, but consider a tiny guard for edge cases

In practice chainId is always provided, but a defensive check (e.g., render Skeleton until chain exists) would avoid passing undefined in any edge case. Low priority.

📜 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 2d12249 and dda44c7.

📒 Files selected for processing (5)
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts (2 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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

Files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
**/*.{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/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.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
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/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
🧠 Learnings (7)
📚 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/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
📚 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:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
📚 Learning: 2025-07-07T21:21:47.488Z
Learnt from: saminacodes
PR: thirdweb-dev/js#7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
📚 Learning: 2025-05-30T17:14:25.332Z
Learnt from: MananTank
PR: thirdweb-dev/js#7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use `Omit<ModuleCardUIProps, "children" | "updateButton">`, they inherit the client prop without needing to add it explicitly.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.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/**/*.{tsx,jsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.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/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
🧬 Code graph analysis (5)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx (1)
apps/dashboard/src/@/hooks/chains/v5-adapter.ts (1)
  • useV5DashboardChain (14-28)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx (1)
apps/dashboard/src/@/hooks/chains/v5-adapter.ts (1)
  • useGetV5DashboardChain (30-39)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx (1)
apps/dashboard/src/@/hooks/chains/v5-adapter.ts (1)
  • useGetV5DashboardChain (30-39)
apps/dashboard/src/@/hooks/chains/v5-adapter.ts (1)
apps/playground-web/src/hooks/chains.ts (1)
  • useAllChainsData (17-39)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx (1)
apps/dashboard/src/@/hooks/chains/v5-adapter.ts (1)
  • useV5DashboardChain (14-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Build Packages
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Lint Packages
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Unit Tests
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (10)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx (1)

27-27: Good move: centralizing chain resolution via v5 adapter

Switching to useGetV5DashboardChain removes scattered defineChain calls and should reliably include custom/hidden chain metadata (custom RPCs) from idToChain. This aligns with MNY-115.

Also applies to: 44-44

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx (1)

20-20: Hook adoption looks solid

Deriving Chain via useV5DashboardChain keeps behavior consistent with NFT flow and centralizes v5 dashboard chain logic.

Also applies to: 97-98

apps/dashboard/src/@/hooks/chains/v5-adapter.ts (1)

30-39: Nice addition: get-by-id helper for v5 dashboard chains

Returning a memoized function keeps call sites ergonomic and avoids repeating idToChain wiring.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx (5)

35-56: Good refactor: centralized chain resolution for all token flows

Replacing inline defineChain with useGetV5DashboardChain reduces duplication and ensures custom/hidden network RPCs are respected consistently across deploy and interactions.


79-86: OK: contract retrieval now uses resolved Chain

getContract now binds to the v5 dashboard chain object, which should prevent RPC mismatches on custom chains.


354-361: Verify token units for claimTo to avoid fractional/rounding issues

ownerSupplyTokens can be fractional based on percentages. Depending on thirdweb’s ERC20 Drop API, claimTo may expect human-readable units or wei. Please confirm and, if needed, convert via toUnits with token decimals and round down. I can patch this, but wanted to validate expected units first.


55-56: Sanity check: ensure custom chain metadata is loaded before calling getChain

If idToChain hasn't resolved yet, getChain may lack custom RPCs. If we see sporadic “eth_getCode” failures on hidden networks, we should gate deploy buttons until useAllChainsData has hydrated. I can add a hook-provided isReady flag and wire it up here.

Also applies to: 114-115, 249-250


1-1: All direct defineChain usages removed – no findings

I searched the entire apps/dashboard/src/app directory for any occurrences of defineChain( or defineDashboardChain( in TypeScript/TSX files and found none. No legacy chain definitions remain in the dashboard’s token or NFT flows.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx (2)

10-10: Imports look correct and respect lint rules

type-only ThirdwebClient import and v5 chain hook import conform to project linting.

Also applies to: 38-38


312-313: Good: derive Chain once and reuse across children

useV5DashboardChain(Number(...)) gives TokenProvider a consistent Chain object for custom chains.

@graphite-app
Copy link
Contributor

graphite-app bot commented Aug 21, 2025

Merge activity

…hains (#7896)

<!--

## 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 a new custom hook `useGetV5DashboardChain` and modifies existing components to utilize this hook for chain management, improving code clarity and reducing redundancy.

### Detailed summary
- Added `useGetV5DashboardChain` hook in `v5-adapter.ts`.
- Updated `LaunchNFT` component to use `useV5DashboardChain`.
- Refactored `CreateTokenAssetPageUI` to use `useV5DashboardChain`.
- Refactored `CreateNFTPage` to use `getChain` from `useGetV5DashboardChain`.
- Refactored `CreateTokenAssetPage` to use `getChain` from `useGetV5DashboardChain`.

> ✨ 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

- Refactor
  - Unified chain selection across NFT creation, NFT launch, and token creation flows using a single, consistent resolver.
  - Modernized internals for better compatibility with the latest chain data.

- Bug Fixes
  - Improved reliability of chain selection during deployments and validations, reducing chances of selecting the wrong network.
  - More consistent behavior when switching chains in forms and launch steps.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@graphite-app graphite-app bot force-pushed the 08-21-_mny-115_dashboard_fix_token_creation_flow_not_working_for_custom_chains branch from dda44c7 to 6caba38 Compare August 21, 2025 19:26
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground August 21, 2025 19:26 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui August 21, 2025 19:26 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 21, 2025 19:26 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 August 21, 2025 19:26 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

🧹 Nitpick comments (4)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx (4)

62-75: Harden chainId parsing to support CAIP-2 and prevent NaN

Using Number(params.chain) assumes a plain decimal or hex string and will produce NaN for inputs like "eip155:80087". Given custom/hidden chains often come through various formats, parse defensively and fail fast with a clear error.

Apply this diff within the selected lines:

-  function getDeployedContract(params: { chain: string }) {
-    const chain = getChain(Number(params.chain));
+  function getDeployedContract(params: { chain: string }) {
+    const chain = getChain(parseChainId(params.chain));

Add this helper once in the module (outside selected lines):

// tolerant parser: decimal, hex, or CAIP-2 (eip155:<id>)
function parseChainId(input: string | number): number {
  if (typeof input === "number") return input;
  const trimmed = input.trim();
  const maybeId = trimmed.includes(":") ? trimmed.split(":").pop()! : trimmed;
  const id = Number(maybeId);
  if (!Number.isFinite(id) || id <= 0) {
    throw new Error(`Invalid chain id: "${input}"`);
  }
  return id;
}

Verification: please try with "80087", 80087, "0x138A7" (hex for 80087), and "eip155:80087" to ensure all resolve identically through useGetV5DashboardChain.


87-100: Same parsing robustness needed here

Mirror the safer parsing when resolving the deployment chain to avoid silent NaN issues for custom networks.

Apply this diff within the selected lines:

-    const chain = getChain(Number(collectionInfo.chain));
+    const chain = getChain(parseChainId(collectionInfo.chain));

141-149: Ensure chainId type is numeric when adding contract to project

You coerce to number for analytics (Line 133) but pass collectionInfo.chain (string) to addContractToProject. If the mutation expects a number, this can cause subtle bugs in cache keys or backend validation.

Apply this diff:

-      chainId: collectionInfo.chain,
+      chainId: Number(collectionInfo.chain),

If the mutation type already accepts string | number, still prefer a number here for consistency with reportContractDeployed and to keep query keys stable.


62-75: Surface friendlier error messages when chain resolution fails

If useGetV5DashboardChain cannot resolve a chain (e.g., missing custom network in local storage), the raw error will bubble up. Wrap resolution with a helpful message that hints at fixing the custom network configuration.

You can minimally wrap the calls:

-    const chain = getChain(parseChainId(params.chain));
+    let chain;
+    try {
+      chain = getChain(parseChainId(params.chain));
+    } catch (err) {
+      throw new Error(
+        "Failed to resolve selected network. Please verify your custom network settings and try again.",
+      );
+    }

Repeat the same pattern in handleContractDeploy for collectionInfo.chain.

Also applies to: 87-100

📜 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 dda44c7 and 6caba38.

📒 Files selected for processing (5)
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts (2 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/dashboard/src/@/hooks/chains/v5-adapter.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page.client.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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

Files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-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:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-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
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/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx
🧠 Learnings (3)
📚 Learning: 2025-06-06T23:46:08.795Z
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:424-424
Timestamp: 2025-06-06T23:46:08.795Z
Learning: The thirdweb project has an ESLint rule that restricts direct usage of `defineChain`. When it's necessary to use `defineChain` directly, it's acceptable to disable the rule with `// eslint-disable-next-line no-restricted-syntax`.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-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 : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: Unit Tests
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx (2)

27-27: Good move: centralize chain resolution via v5 adapter hook

Replacing ad-hoc chain resolution with a single hook is a solid step toward consistency across dashboard flows.


44-44: Hook usage looks correct

Storing the resolver once per render and calling it where needed keeps things simple and avoids repeated lookups. No issues here.

import { revalidatePathAction } from "@/actions/revalidate";
import { reportContractDeployed } from "@/analytics/report";
import type { Team } from "@/api/team/get-team";
import { useGetV5DashboardChain } from "@/hooks/chains/v5-adapter";
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Double-check hook export and RPC source for custom chains (Freeq 80087)

To ensure MNY-115 is fully addressed, verify that useGetV5DashboardChain returns a chain whose rpc array prioritizes the user-provided RPC (e.g., https://rpc.testnet.superfreeq.com/) rather than a thirdweb aggregator URL for hidden/custom networks. This was the root cause of batched getCode failures.

Run this quick repo inspection to confirm the hook’s export and the RPC behavior:


🏁 Script executed:

#!/bin/bash
# Verify the hook is a named export
fd v5-adapter.ts
rg -nP 'export\s+(const|function)\s+useGetV5DashboardChain' -n

# Inspect how RPCs are selected/constructed inside the hook
rg -n 'rpc' $(fd v5-adapter.ts)

Length of output: 305


🏁 Script executed:

#!/bin/bash
file="apps/dashboard/src/@/hooks/chains/v5-adapter.ts"

echo "===== Lines 1-200 of $file ====="
sed -n '1,200p' "$file"

echo ""
echo "===== Case-insensitive search for 'rpc' ====="
rg -n -i 'rpc' "$file" || echo "No matches for 'rpc'"

echo ""
echo "===== Search for 'url' ====="
rg -n 'url' "$file" || echo "No matches for 'url'"

Length of output: 2386


🏁 Script executed:

#!/bin/bash
# Locate defineDashboardChain implementation
file=$(fd defineDashboardChain.ts)

echo "=== File: $file ==="
sed -n '1,200p' "$file"

echo ""
echo "=== Search for 'rpc' occurrences ==="
rg -n 'rpc' "$file" || echo "No 'rpc' references found"

echo ""
echo "=== Search for array of RPCs or custom RPC logic ==="
rg -nP 'rpc[s]?[\s]*=' "$file" || echo "No RPC assignment pattern found"

echo ""
echo "=== Search for user-provided RPC override handling ==="
rg -nP 'custom|override|user' "$file" || echo "No custom RPC override logic found"

Length of output: 1665


RPC override not implemented in defineDashboardChain

We confirmed that:

  • useGetV5DashboardChain is correctly exported (apps/dashboard/src/@/hooks/chains/v5-adapter.ts:30).
  • defineDashboardChain (apps/dashboard/src/@/lib/defineDashboardChain.ts:15–20) always falls back to a single default RPC URL (https://${chainId}.rpc.${PROD_OR_DEV_URL}) and does not include or prioritize any user-provided/custom RPCs.

To fully address MNY-115 and avoid batched getCode failures on hidden/custom networks, you need to update defineDashboardChain to:

  • Accept an optional user-provided RPC override (e.g. https://rpc.testnet.superfreeq.com/).
  • Construct the resulting chain’s rpc field as an array that places the override first, followed by the default/aggregator URLs.

Locations to update:

  • apps/dashboard/src/@/lib/defineDashboardChain.ts (around the return defineChain({ … rpc: … }) block)
  • Ensure useGetV5DashboardChain consumers pass through any available override into defineDashboardChain.

Please implement these changes so that custom RPCs are prioritized over the default aggregator URLs.

🤖 Prompt for AI Agents
In apps/dashboard/src/@/lib/defineDashboardChain.ts (around the defineChain
return block) and update usages in
apps/dashboard/src/@/hooks/chains/v5-adapter.ts (and any consumers) —
defineDashboardChain currently always builds a single default RPC URL; change
its signature to accept an optional rpcOverride string (or array) and set the
chain.rpc field to an array that places the override(s) first followed by the
existing default/aggregator URLs (de-duplicate if needed), then update
useGetV5DashboardChain to accept/forward any available override into
defineDashboardChain so consumers pass the custom RPC through and it is
prioritized over defaults.

@graphite-app graphite-app bot merged commit 6caba38 into main Aug 21, 2025
25 checks passed
@graphite-app graphite-app bot deleted the 08-21-_mny-115_dashboard_fix_token_creation_flow_not_working_for_custom_chains branch August 21, 2025 19:34
@vercel vercel bot temporarily deployed to Production – docs-v2 August 21, 2025 19:34 Inactive
@vercel vercel bot temporarily deployed to Production – nebula August 21, 2025 19:34 Inactive
@vercel vercel bot temporarily deployed to Production – wallet-ui August 21, 2025 19:34 Inactive
@vercel vercel bot temporarily deployed to Production – thirdweb_playground August 21, 2025 19:34 Inactive
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants