import { cn } from "~/lib/utils"; import { Activity, TrendingUp, TrendingDown, RefreshCw, ExternalLink, Droplets, BarChart3 } from "lucide-react"; import { Button } from "@/routes/ui/button"; import { ChainIcon } from "../components/shared/ChainIcon"; export interface LiveTokenDataInfo { chain: string; tokenAddress: string; tokenSymbol?: string; tokenName?: string; priceUsd?: string; priceNative?: string; priceChange5m?: number; priceChange1h?: number; priceChange6h?: number; priceChange24h?: number; volume24h?: number; volume6h?: number; volume1h?: number; liquidityUsd?: number; marketCap?: number; fdv?: number; txns24hBuys?: number; txns24hSells?: number; dex?: string; pairUrl?: string; totalPairs?: number; error?: string; } export interface LiveTokenDataWidgetProps { /** Live token data */ data: LiveTokenDataInfo; /** Whether data is loading */ isLoading?: boolean; /** Callback when view on DexScreener is clicked */ onViewDexScreener?: () => void; /** Additional class names */ className?: string; } const formatPrice = (price: string | undefined): string => { if (!price || price === "N/A") return "N/A"; const num = parseFloat(price); if (isNaN(num)) return price; if (num < 0.00001) return `$${num.toExponential(2)}`; if (num < 1) return `$${num.toFixed(6)}`; return `$${num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; }; const formatLargeNumber = (num: number | undefined): string => { if (num === undefined || num === null || num === 0) return "N/A"; if (num >= 1e9) return `$${(num / 1e9).toFixed(2)}B`; if (num >= 1e6) return `$${(num / 1e6).toFixed(2)}M`; if (num >= 1e3) return `$${(num / 1e3).toFixed(2)}K`; return `$${num.toFixed(2)}`; }; const formatNumber = (num: number | undefined): string => { if (num === undefined || num === null) return "0"; return num.toLocaleString(); }; const PriceChange = ({ value, label }: { value: number | undefined; label: string }) => { if (value === undefined || value === null) return null; const isPositive = value >= 0; return (

{label}

{isPositive ? "+" : ""}{value.toFixed(2)}%

); }; /** * LiveTokenDataWidget - Displays comprehensive real-time market data * Used when AI fetches detailed live market information */ export function LiveTokenDataWidget({ data, isLoading = false, onViewDexScreener, className, }: LiveTokenDataWidgetProps) { const handleOpenDexScreener = () => { if (onViewDexScreener) { onViewDexScreener(); } else if (data.pairUrl) { window.open(data.pairUrl, "_blank"); } else if (data.tokenAddress) { window.open(`https://dexscreener.com/${data.chain}/${data.tokenAddress}`, "_blank"); } }; const totalTxns24h = (data.txns24hBuys || 0) + (data.txns24hSells || 0); const buyRatio = totalTxns24h > 0 ? ((data.txns24hBuys || 0) / totalTxns24h) * 100 : 50; return (
{/* Header */}
Live Market Data {isLoading ? ( Fetching... ) : ( Real-time )}
{data.error ? (
⚠️ {data.error}
) : ( <> {/* Token Header */}
{data.tokenSymbol || "Token"} {data.tokenName && ( {data.tokenName} )}
{formatPrice(data.priceUsd)} {data.priceChange24h !== undefined && ( = 0 ? "text-green-500" : "text-red-500" )}> {data.priceChange24h >= 0 ? : } {data.priceChange24h >= 0 ? "+" : ""}{data.priceChange24h.toFixed(2)}% )}
{/* Price Changes */}
{/* Metrics Grid */}

24h Volume

{formatLargeNumber(data.volume24h)}

Liquidity

{formatLargeNumber(data.liquidityUsd)}

Market Cap

{formatLargeNumber(data.marketCap)}

FDV

{formatLargeNumber(data.fdv)}

{/* Transaction Activity */}

24h Transactions

{formatNumber(data.txns24hBuys)} buys {formatNumber(totalTxns24h)} total {formatNumber(data.txns24hSells)} sells
{/* DEX Info & Actions */}
DEX: {data.dex || "Unknown"} {data.totalPairs && data.totalPairs > 1 && ( • {data.totalPairs} pairs )}
)}
); }