diff --git a/apps/playground-web/src/app/data/pages-metadata.ts b/apps/playground-web/src/app/data/pages-metadata.ts
index b3ba3ecbadc..ebf073c34b9 100644
--- a/apps/playground-web/src/app/data/pages-metadata.ts
+++ b/apps/playground-web/src/app/data/pages-metadata.ts
@@ -16,6 +16,7 @@ import {
SquareIcon,
SquircleDashedIcon,
StampIcon,
+ TrendingUpIcon,
UserIcon,
WalletCardsIcon,
} from "lucide-react";
@@ -203,6 +204,13 @@ export const tokensFeatureCards: FeatureCardMetadata[] = [
link: "/tokens/nft-components",
description: "Headless UI components for rendering NFT Media and metadata",
},
+ {
+ icon: TrendingUpIcon,
+ title: "Price Tracker",
+ link: "/tokens/price-tracker",
+ description:
+ "Live token prices, market cap, and 24h volume across chains",
+ },
];
export const aiFeatureCards: FeatureCardMetadata[] = [
diff --git a/apps/playground-web/src/app/navLinks.ts b/apps/playground-web/src/app/navLinks.ts
index 864beb4dc60..7ef4732be34 100644
--- a/apps/playground-web/src/app/navLinks.ts
+++ b/apps/playground-web/src/app/navLinks.ts
@@ -173,6 +173,10 @@ const tokens: ShadcnSidebarLink = {
href: "/tokens/nft-components",
label: "NFT Components",
},
+ {
+ href: "/tokens/price-tracker",
+ label: "Price Tracker",
+ },
],
};
diff --git a/apps/playground-web/src/app/tokens/price-tracker/page.tsx b/apps/playground-web/src/app/tokens/price-tracker/page.tsx
new file mode 100644
index 00000000000..8c116ea09d0
--- /dev/null
+++ b/apps/playground-web/src/app/tokens/price-tracker/page.tsx
@@ -0,0 +1,34 @@
+import { TrendingUpIcon } from "lucide-react";
+import { PageLayout } from "@/components/blocks/APIHeader";
+import { TokenPriceTracker } from "@/components/token-price/token-price-tracker";
+import ThirdwebProvider from "@/components/thirdweb-provider";
+import { createMetadata } from "@/lib/metadata";
+
+const title = "Price Tracker";
+const description =
+ "Live token prices, market cap, and 24h volume across chains";
+
+export const metadata = createMetadata({
+ title,
+ description,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
+
+export default function Page() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/apps/playground-web/src/components/token-price/token-price-tracker.tsx b/apps/playground-web/src/components/token-price/token-price-tracker.tsx
new file mode 100644
index 00000000000..196bcbdfd21
--- /dev/null
+++ b/apps/playground-web/src/components/token-price/token-price-tracker.tsx
@@ -0,0 +1,209 @@
+"use client";
+
+import { useQuery } from "@tanstack/react-query";
+import { useState } from "react";
+import { Bridge } from "thirdweb";
+import {
+ arbitrum,
+ base,
+ ethereum,
+ optimism,
+ polygon,
+} from "thirdweb/chains";
+import { THIRDWEB_CLIENT } from "@/lib/client";
+import { CodeExample } from "../code/code-example";
+
+const CHAINS = [
+ { chain: ethereum, label: "Ethereum", id: 1 },
+ { chain: base, label: "Base", id: 8453 },
+ { chain: polygon, label: "Polygon", id: 137 },
+ { chain: arbitrum, label: "Arbitrum", id: 42161 },
+ { chain: optimism, label: "Optimism", id: 10 },
+] as const;
+
+function formatUsd(value: number): string {
+ if (value >= 1_000_000_000) {
+ return `$${(value / 1_000_000_000).toFixed(2)}B`;
+ }
+ if (value >= 1_000_000) {
+ return `$${(value / 1_000_000).toFixed(2)}M`;
+ }
+ if (value >= 1_000) {
+ return `$${(value / 1_000).toFixed(2)}K`;
+ }
+ return `$${value.toFixed(2)}`;
+}
+
+function formatPrice(value: number): string {
+ if (value >= 1) {
+ return `$${value.toFixed(2)}`;
+ }
+ if (value >= 0.01) {
+ return `$${value.toFixed(4)}`;
+ }
+ return `$${value.toFixed(6)}`;
+}
+
+function TokenPriceTrackerPreview() {
+ const [selectedChainId, setSelectedChainId] = useState(1);
+
+ const tokensQuery = useQuery({
+ queryKey: ["bridge-tokens-price", selectedChainId],
+ queryFn: () =>
+ Bridge.tokens({
+ client: THIRDWEB_CLIENT,
+ chainId: selectedChainId,
+ limit: 15,
+ sortBy: "market_cap",
+ includePrices: true,
+ }),
+ refetchInterval: 30_000,
+ });
+
+ return (
+
+ {/* Chain Selector */}
+
+ {CHAINS.map((c) => (
+
+ ))}
+
+
+ {/* Token List */}
+
+ {/* Header */}
+
+ Token
+ Price
+ Market Cap
+ 24h Volume
+
+
+ {/* Loading State */}
+ {tokensQuery.isLoading && (
+
+ {Array.from({ length: 8 }).map((_, i) => (
+
+ ))}
+
+ )}
+
+ {/* Error State */}
+ {tokensQuery.isError && (
+
+ Failed to load token data. Please try again.
+
+ )}
+
+ {/* Data */}
+ {tokensQuery.data?.map((token) => (
+
+
+ {token.iconUri ? (
+

+ ) : (
+
+ )}
+
+
+ {token.name}
+
+
{token.symbol}
+
+
+
+ {token.prices?.usd ? formatPrice(token.prices.usd) : "—"}
+
+
+ {token.marketCapUsd ? formatUsd(token.marketCapUsd) : "—"}
+
+
+ {token.volume24hUsd ? formatUsd(token.volume24hUsd) : "—"}
+
+
+ ))}
+
+
+ {/* Auto-refresh indicator */}
+
+ Auto-refreshes every 30s
+ {tokensQuery.isFetching && !tokensQuery.isLoading && (
+
+ )}
+
+
+ );
+}
+
+export function TokenPriceTracker() {
+ return (
+
+ Bridge.tokens({
+ client: THIRDWEB_CLIENT,
+ chainId: 1, // Ethereum
+ limit: 15,
+ sortBy: "market_cap",
+ includePrices: true,
+ }),
+ refetchInterval: 30_000, // auto-refresh every 30s
+ });
+
+ return tokens?.map((token) => (
+
+

+
{token.name} ({token.symbol})
+
\${token.prices?.usd?.toFixed(2)}
+
MCap: {token.marketCapUsd}
+
Vol: {token.volume24hUsd}
+
+ ));
+}`}
+ lang="tsx"
+ preview={}
+ />
+ );
+}