Skip to content

Conversation

@MananTank
Copy link
Member

@MananTank MananTank commented Sep 10, 2025


PR-Codex overview

This PR focuses on removing the token-price-data API and PriceChart component while adding a new mapping for chain IDs to DexScreener chain slugs. It introduces a DexScreener component to display DexScreener information based on the selected chain and contract address.

Detailed summary

  • Deleted token-price-data.ts and PriceChart.tsx.
  • Added mapChainIdToDexScreenerChainSlug for mapping chain IDs to DexScreener slugs.
  • Introduced DexScreener and DexScreenerIframe components for displaying DexScreener data.
  • Updated ERC20PublicPage to use DexScreener based on the chain ID.

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

Summary by CodeRabbit

  • New Features

    • Embedded DexScreener chart on ERC20 public pages for supported chains with auto light/dark theming, responsive SSR fallback, and type-safe chain slug mapping.
  • Refactor

    • Removed token price fetching and TokenStats/price-chart UI from ERC20 public pages; flow restructured to integrate DexScreener.
  • Style

    • Wider layout (max-w-7xl), simplified Buy section spacing, and repositioned DexScreener before analytics with unified bottom container for analytics and transfers.

@linear
Copy link

linear bot commented Sep 10, 2025

@changeset-bot
Copy link

changeset-bot bot commented Sep 10, 2025

⚠️ No Changeset found

Latest commit: c82b606

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

@vercel
Copy link

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 10, 2025

Walkthrough

Removes the server-side token price API and the TokenStats/PriceChart UI, adds a readonly chainId→DexScreener slug map and a theme-aware DexScreener iframe component, and updates the ERC20 public page layout to conditionally render the DexScreener embed and reorganize surrounding sections.

Changes

Cohort / File(s) Summary of changes
Remove token price API
apps/dashboard/src/app/(app)/(dashboard)/(chain)/.../[contractAddress]/public-pages/erc20/_apis/token-price-data.ts
Deleted TokenPriceData type and getTokenPriceData function; removed server-side Insights API client and error handling.
Remove price chart UI
apps/dashboard/src/app/(app)/(dashboard)/(chain)/.../[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
Deleted TokenStats/PriceChart component, interval logic, chart helpers, and all formatting/tooltip subhelpers.
Add DexScreener chain map
apps/dashboard/src/app/(app)/(dashboard)/(chain)/.../[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
Added readonly mapChainIdToDexScreenerChainSlug mapping and exported DexScreenerChainSlug union type.
Add DexScreener component
apps/dashboard/src/app/(app)/(dashboard)/(chain)/.../[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
Added client-only DexScreener component with DexScreenerIframe that builds a theme-aware embed URL and renders an iframe with an SSR fallback spinner.
Integrate DexScreener and adjust layout
apps/dashboard/src/app/(app)/(dashboard)/(chain)/.../[contractAddress]/public-pages/erc20/erc20.tsx
Removed token price fetch and TokenStats usage; imported and conditionally rendered DexScreener via the chain slug map; widened container classes and reorganized page sections (BuyEmbed, DexScreener, analytics, transfers).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant ERC20Page as ERC20 Public Page
  participant SlugMap as mapChainIdToDexScreenerChainSlug
  participant DexComp as DexScreener
  participant Theme as next-themes
  participant Iframe as DexScreener Iframe

  User->>ERC20Page: Navigate to token page
  ERC20Page->>SlugMap: lookup(chainId)
  alt slug exists
    ERC20Page->>DexComp: render(slug, contractAddress)
    DexComp->>Theme: read current theme
    DexComp->>DexComp: build embed URL (slug, addr, query params, theme)
    DexComp->>Iframe: render iframe (ClientOnly)
  else slug missing
    ERC20Page-->>User: omit DexScreener section
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

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.

Pre-merge checks (4 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "[MNY-166] Dashboard: Add Dex Screener charts in public ERC20 token page" is concise, follows the repository issue-tag format, and accurately captures the primary change (adding DexScreener charts to the public ERC20 page). It is specific and readable for teammates scanning history.
Linked Issues Check ✅ Passed The changes directly implement the linked issue MNY-166: token-price-data.ts and PriceChart.tsx were removed, mapChainIdToDexScreenerChainSlug and the DexScreener/DexScreenerIframe components were added, and ERC20PublicPage was updated to use the mapped slug and render the embed. The render is gated by the chainId mapping and the mapped slug is passed into the embed, satisfying the requirement to use a chain-specific DexScreener slug. Based on the provided summaries, the PR meets the coding-related objectives described in the linked issue.
Out of Scope Changes Check ✅ Passed I do not see unrelated or unexpected changes in the summarized diffs; the main additions (chain slug map and DexScreener) and deletions (token price API and PriceChart) align with the issue, and the layout/container width and BuyEmbed adjustments appear to be supportive changes for the new embed. No new API endpoints or unrelated feature code were introduced in the provided summaries. To be safe, validate that no other modules still import the removed exports to avoid accidental breakage.
Description Check ✅ Passed The PR description contains a clear PR-Codex overview and a detailed summary of changes and objectives (files removed, new DexScreener components, layout changes), so reviewers can understand intent and impact. However, the repository template's required sections (an explicit PR title in the "[SDK/Dashboard/Portal] ..." format, a filled "Notes for the reviewer" section, and a "How to test" section) are present only as comments and not populated with concrete values or testing steps. Despite these omissions, the description is sufficiently detailed for a code review to proceed.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mny-136

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

@MananTank MananTank marked this pull request as ready for review September 10, 2025 14:45
@MananTank MananTank requested review from a team as code owners September 10, 2025 14:45
@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label Sep 10, 2025
Copy link
Member Author

MananTank commented Sep 10, 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.

@codecov
Copy link

codecov bot commented Sep 10, 2025

Codecov Report

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

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8035   +/-   ##
=======================================
  Coverage   56.64%   56.64%           
=======================================
  Files         904      904           
  Lines       58755    58755           
  Branches     4170     4170           
=======================================
  Hits        33280    33280           
  Misses      25369    25369           
  Partials      106      106           
Flag Coverage Δ
packages 56.64% <ø> (ø)
🚀 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 10, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 63.96 KB (0%) 1.3 s (0%) 764 ms (+236.15% 🔺) 2.1 s
thirdweb (cjs) 356.86 KB (0%) 7.2 s (0%) 2.4 s (+27.83% 🔺) 9.5 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 452 ms (+4325.33% 🔺) 567 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 178 ms (+2119% 🔺) 188 ms
thirdweb/react (minimal + tree-shaking) 19.15 KB (0%) 383 ms (0%) 393 ms (+3890.52% 🔺) 776 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: 7

🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (2)

12-29: Use resolvedTheme to avoid flicker; normalize address; memo deps

Prevents dark-default flash and redundant reloads when theme=system.

-  const { theme } = useTheme();
+  const { resolvedTheme } = useTheme();
@@
-  const iframeUrl = useMemo(() => {
-    const resolvedTheme = theme === "light" ? "light" : "dark";
+  const iframeUrl = useMemo(() => {
+    const themeParam = resolvedTheme === "light" ? "light" : "dark";
+    const address = props.contractAddress.toLowerCase();
     const url = new URL("https://dexscreener.com");
-    url.pathname = `${props.chain}/${props.contractAddress}`;
+    url.pathname = `${props.chain}/${address}`;
-    url.searchParams.set("chartTheme", resolvedTheme);
-    url.searchParams.set("theme", resolvedTheme);
+    url.searchParams.set("chartTheme", themeParam);
+    url.searchParams.set("theme", themeParam);
     url.searchParams.set("trades", "1");
@@
-    return url.toString();
-  }, [theme, props.chain, props.contractAddress]);
+    return url.toString();
+  }, [resolvedTheme, props.chain, props.contractAddress]);

31-36: Minor: defer iframe work and improve a11y

Lazy-load and make the title more descriptive.

-    <iframe
-      className="w-full h-[500px] lg:h-[1000px] rounded-lg overflow-hidden border bg-card"
-      src={iframeUrl}
-      title="DexScreener"
-    ></iframe>
+    <iframe
+      className={props.className ?? "w-full h-[500px] lg:h-[1000px] rounded-lg overflow-hidden border bg-card"}
+      src={iframeUrl}
+      title={`DexScreener: ${props.chain}`}
+      loading="lazy"
+      referrerPolicy="no-referrer-when-downgrade"
+    />
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • 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 a724bc3 and f528d3b.

📒 Files selected for processing (5)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (3 hunks)
💤 Files with no reviewable changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/_ (e.g., Button, Input, Tabs, Card)
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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Expose a className prop on the root element of every component

Files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧠 Learnings (4)
📚 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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
📚 Learning: 2025-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-27T19:55:25.056Z
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (`useTokenPriceData.ts`), direct array access on `json.data[0]` without optional chaining is intentionally correct and should not be changed to use safety checks.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Use the `container` class with a `max-w-7xl` cap for page width consistency.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧬 Code graph analysis (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
  • DexScreenerChainSlug (76-77)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (1)
  • PageHeader (7-32)
apps/dashboard/src/@/components/ui/background-patterns.tsx (1)
  • GridPattern (32-86)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
  • mapChainIdToDexScreenerChainSlug (1-74)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
  • DexScreener (40-58)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx (1)
  • ContractAnalyticsOverview (10-66)
⏰ 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: Lint Packages
  • GitHub Check: Unit Tests
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)

81-81: Width cap: matches dashboard standard

max-w-7xl is consistent with container guidance.


149-155: LGTM: analytics section placement

Ordering after the chart keeps the narrative coherent.

@vercel vercel bot temporarily deployed to Preview – nebula September 10, 2025 15:21 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 10, 2025 15:21 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 10, 2025 15:21 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 September 10, 2025 15:21 Inactive
@MananTank MananTank changed the title [MNY-136] Dashboard: Add Dex Screener charts in public ERC20 token page [MNY-166] Dashboard: Add Dex Screener charts in public ERC20 token page Sep 10, 2025
@linear
Copy link

linear bot commented Sep 10, 2025

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

♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)

105-120: Replace inline style with Tailwind arbitrary property

Inline styles are disallowed in dashboard. Use Tailwind’s arbitrary property for mask-image.

             <GridPattern
               width={30}
               height={30}
               x={-1}
               y={-1}
               strokeDasharray={"4 2"}
-              className="text-border dark:text-border/70"
-              style={{
-                maskImage:
-                  "linear-gradient(to bottom right,white,transparent,transparent)",
-              }}
+              className='text-border dark:text-border/70 [mask-image:linear-gradient(to_bottom_right,white,transparent,transparent)]'
             />

135-147: Safer slug lookup and cleaner conditional render

Avoid in checks + index assertions. Use a helper and render only when slug exists.

-      {props.chainMetadata.chainId in mapChainIdToDexScreenerChainSlug && (
-        <div className="container max-w-7xl pb-10">
-          <DexScreener
-            chain={
-              mapChainIdToDexScreenerChainSlug[
-                props.chainMetadata
-                  .chainId as keyof typeof mapChainIdToDexScreenerChainSlug
-              ]
-            }
-            contractAddress={props.clientContract.address}
-          />
-        </div>
-      )}
+      {(() => {
+        const slug = getDexScreenerSlug(props.chainMetadata.chainId);
+        return slug ? (
+          <div className="container max-w-7xl pb-10">
+            <DexScreener
+              chain={slug}
+              contractAddress={props.clientContract.address}
+            />
+          </div>
+        ) : null;
+      })()}
🧹 Nitpick comments (6)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (6)

1-1: Mark this as a Server Component

Add the server-only directive to prevent accidental client-side imports.

import "server-only";

15-16: Import the slug helper instead of the raw map (used below)

Switch to a typed helper to avoid unsafe index assertions later.

 import { DexScreener } from "./_components/dex-screener";
-import { mapChainIdToDexScreenerChainSlug } from "./_components/dex-screener-chains";
+import { getDexScreenerSlug } from "./_components/dex-screener-chains";

131-132: Remove stray whitespace node

The {" "} after the closing div renders an unnecessary text node.

-          </div>{" "}
+          </div>

22-27: Add explicit return types for exported/inner functions

Meets the TypeScript guideline for explicit returns.

Example:

export async function ERC20PublicPage(...): Promise<JSX.Element> { /* ... */ }

function BuyEmbed(...): JSX.Element { /* ... */ }

async function getActiveClaimConditionWithErrorHandler(
  contract: ThirdwebContract,
): Promise<ActiveClaimCondition | undefined> { /* ... */ }

75-77: Keep boolean semantics for showBuyEmbed

Prevent object | boolean truthy leaks; coerce to boolean.

-const showBuyEmbed = isUBSupported || claimConditionMeta;
+const showBuyEmbed = isUBSupported || !!claimConditionMeta;

135-147: Helper implementation (in chains file) if not present

If getDexScreenerSlug doesn’t exist yet, add it alongside the map.

// apps/dashboard/.../erc20/_components/dex-screener-chains.ts
export type DexScreenerChainSlug =
  (typeof mapChainIdToDexScreenerChainSlug)[keyof typeof mapChainIdToDexScreenerChainSlug];

export function getDexScreenerSlug(
  chainId: number,
): DexScreenerChainSlug | undefined {
  return (mapChainIdToDexScreenerChainSlug as Partial<
    Record<number, DexScreenerChainSlug>
  >)[chainId];
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • 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 f528d3b and f7230de.

📒 Files selected for processing (5)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (3 hunks)
💤 Files with no reviewable changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/_ (e.g., Button, Input, Tabs, Card)
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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Expose a className prop on the root element of every component

Files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧠 Learnings (11)
📚 Learning: 2025-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Never hard-code colors – always go through Tailwind variables.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Use Tailwind CSS for styling; no inline styles

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 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} : Use Tailwind CSS only – no inline styles or CSS modules

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Stick to design-tokens: background (`bg-card`), borders (`border-border`), muted text (`text-muted-foreground`) etc.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-29T00:46:09.063Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Spacing utilities (`px-*`, `py-*`, `gap-*`) are preferred over custom margins.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Use the `container` class with a `max-w-7xl` cap for page width consistency.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧬 Code graph analysis (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (1)
  • PageHeader (7-32)
apps/dashboard/src/@/components/ui/background-patterns.tsx (1)
  • GridPattern (32-86)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
  • mapChainIdToDexScreenerChainSlug (1-74)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
  • DexScreener (40-58)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx (1)
  • ContractAnalyticsOverview (10-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Unit Tests
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (3)

81-81: Header width bump to 7xl is consistent with dashboard guidelines

LGTM.


84-100: Container max-w-7xl aligns with the layout cap

LGTM.


149-155: Analytics section container and growth look good

Matches the flex/grow guidance from prior layout learnings.

@graphite-app
Copy link
Contributor

graphite-app bot commented Sep 12, 2025

Merge activity

…ge (#8035)

<!--

## 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 primarily focuses on removing the `token-price-data` API and the `PriceChart` component, while introducing a new `DexScreener` feature that displays token price information based on the chain ID and contract address.

### Detailed summary
- Deleted `token-price-data.ts` and `PriceChart.tsx`.
- Added `mapChainIdToDexScreenerChainSlug` to map chain IDs to DexScreener chain slugs.
- Introduced `DexScreener` and `DexScreenerIframe` components for displaying token price data.
- Updated `erc20.tsx` to integrate `DexScreener` and remove token price fetching logic.

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

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added embedded DexScreener chart on ERC20 public pages for supported chains with automatic light/dark theming and responsive SSR fallback.
  * Introduced chain-to-DexScreener slug mapping for type-safe embeds.

* **Refactor**
  * Removed token price data fetching and the TokenStats/price chart UI from ERC20 public pages.

* **Style**
  * Widened layout to max-w-7xl, simplified Buy section spacing, and moved DexScreener before analytics; analytics and recent transfers now sit in a unified bottom container.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 12, 2025 19:26 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula September 12, 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

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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (1)

22-26: Mark as server-only module

This is a server component (uses next/headers). Add the server-only marker to prevent accidental client bundling.

+import "server-only";
 import { cookies } from "next/headers";
♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)

135-147: Safer slug lookup + cleaner conditional render

Avoid in + index assertions; compute slug once and render conditionally.

-      {props.chainMetadata.chainId in mapChainIdToDexScreenerChainSlug && (
-        <div className="container max-w-7xl pb-10">
-          <DexScreener
-            chain={
-              mapChainIdToDexScreenerChainSlug[
-                props.chainMetadata
-                  .chainId as keyof typeof mapChainIdToDexScreenerChainSlug
-              ]
-            }
-            contractAddress={props.clientContract.address}
-          />
-        </div>
-      )}
+      {(() => {
+        const slug = getDexScreenerSlug(props.chainMetadata.chainId);
+        return slug ? (
+          <div className="container max-w-7xl pb-10">
+            <DexScreener
+              chain={slug}
+              contractAddress={props.clientContract.address}
+            />
+          </div>
+        ) : null;
+      })()}

114-118: Replace inline style with Tailwind arbitrary property

Dashboard forbids inline styles; use an arbitrary property in className.

-              className="text-border dark:text-border/70"
-              style={{
-                maskImage:
-                  "linear-gradient(to bottom right,white,transparent,transparent)",
-              }}
+              className='text-border dark:text-border/70 [mask-image:linear-gradient(to_bottom_right,white,transparent,transparent)]'
🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)

22-26: Add explicit return types for exported and local functions

Keep TS explicit per repo guidelines.

-export async function ERC20PublicPage(props: {
+export async function ERC20PublicPage(props: {
   serverContract: ThirdwebContract;
   clientContract: ThirdwebContract;
   chainMetadata: ChainMetadata;
-}) {
+}): Promise<JSX.Element> {

And below in the same file:

-function BuyEmbed(props: { /* … */ }) {
+function BuyEmbed(props: { /* … */ }): JSX.Element {
-async function getActiveClaimConditionWithErrorHandler(
+async function getActiveClaimConditionWithErrorHandler(
   contract: ThirdwebContract,
-) {
+): Promise<ActiveClaimCondition | undefined> {

15-16: Prefer a typed slug resolver over importing the map here

Import a helper (getDexScreenerSlug) and drop direct map usage to keep this module decoupled from the mapping details.

-import { DexScreener } from "./_components/dex-screener";
-import { mapChainIdToDexScreenerChainSlug } from "./_components/dex-screener-chains";
+import { DexScreener } from "./_components/dex-screener";
+import { getDexScreenerSlug } from "./_components/dex-screener-chains";

Apply the usage change in Lines 135-147 (see dedicated comment).
Additional helper to add in ./_components/dex-screener-chains.ts:

export function getDexScreenerSlug(
  chainId: number,
): DexScreenerChainSlug | undefined {
  return mapChainIdToDexScreenerChainSlug[
    chainId as keyof typeof mapChainIdToDexScreenerChainSlug
  ];
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f7230de and c82b606.

📒 Files selected for processing (5)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (3 hunks)
💤 Files with no reviewable changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_apis/token-price-data.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

apps/{dashboard,playground}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/_ (e.g., Button, Input, Tabs, Card)
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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
apps/{dashboard,playground}/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Expose a className prop on the root element of every component

Files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧠 Learnings (13)
📚 Learning: 2025-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-27T19:55:25.056Z
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (`useTokenPriceData.ts`), direct array access on `json.data[0]` without optional chaining is intentionally correct and should not be changed to use safety checks.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Never hard-code colors – always go through Tailwind variables.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Use Tailwind CSS for styling; no inline styles

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 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} : Use Tailwind CSS only – no inline styles or CSS modules

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Stick to design-tokens: background (`bg-card`), borders (`border-border`), muted text (`text-muted-foreground`) etc.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
📚 Learning: 2025-05-29T00:46:09.063Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Spacing utilities (`px-*`, `py-*`, `gap-*`) are preferred over custom margins.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.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} : Use the `container` class with a `max-w-7xl` cap for page width consistency.

Applied to files:

  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx
🧬 Code graph analysis (1)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx (1)
  • PageHeader (7-32)
apps/dashboard/src/@/components/ui/background-patterns.tsx (1)
  • GridPattern (32-86)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener-chains.ts (1)
  • mapChainIdToDexScreenerChainSlug (1-74)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/dex-screener.tsx (1)
  • DexScreener (40-58)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/contract-analytics/contract-analytics.tsx (1)
  • ContractAnalyticsOverview (10-66)
⏰ 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/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx (2)

84-100: LGTM: container sizing aligned to 7xl

Header block wrapper matches dashboard width guidance.


149-155: LGTM: analytics block reflow

Containerization and ordering look good; props remain typed and consistent.

<div className="flex grow flex-col">
<AssetPageView assetType="coin" chainId={props.chainMetadata.chainId} />
<PageHeader containerClassName="max-w-5xl" />
<PageHeader containerClassName="max-w-7xl" />
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

Width cap: verify PageHeader default doesn’t override 7xl

PageHeader internally uses "container max-w-8xl" (see file snippet). Passing "max-w-7xl" here may not win the cascade. Either change PageHeader’s default to 7xl or add a specific wrapper outside PageHeader.

Run to confirm current default:


🏁 Script executed:

#!/bin/bash
rg -nC2 'export function PageHeader' apps/dashboard/src/app | sed -n '1,40p'

Length of output: 788


🏁 Script executed:

#!/bin/bash
sed -n '1,240p' "apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx"

Length of output: 1052


Change PageHeader default max-width to max-w-7xl

PageHeader.tsx currently sets container flex max-w-8xl ..., so passing max-w-7xl from the call site may not override Tailwind; update apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx to use max-w-7xl (or wrap PageHeader in an outer container that enforces the 7xl cap).

🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/_components/PageHeader.tsx
(around the component root/container className), the component hardcodes
"max-w-8xl" which prevents callers passing containerClassName="max-w-7xl" from
taking effect; change the default class to "max-w-7xl" (or remove the hardcoded
max-w-* and merge/compose the passed containerClassName so callers can override)
so that PageHeader respects the 7xl cap from the call site.

@graphite-app graphite-app bot merged commit c82b606 into main Sep 12, 2025
24 checks passed
@graphite-app graphite-app bot deleted the mny-136 branch September 12, 2025 19:36
@vercel vercel bot temporarily deployed to Production – docs-v2 September 12, 2025 19:36 Inactive
@vercel vercel bot temporarily deployed to Production – wallet-ui September 12, 2025 19:36 Inactive
@vercel vercel bot temporarily deployed to Production – thirdweb_playground September 12, 2025 19:36 Inactive
@vercel vercel bot temporarily deployed to Production – nebula September 12, 2025 19:36 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