@elizaos/plugin-wallet-ui 2.0.3-beta.5 → 2.0.3-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/InventoryView.d.ts +19 -0
  2. package/dist/InventoryView.d.ts.map +1 -0
  3. package/dist/InventoryView.helpers.d.ts +32 -0
  4. package/dist/InventoryView.helpers.d.ts.map +1 -0
  5. package/dist/InventoryView.helpers.js +104 -0
  6. package/dist/InventoryView.helpers.js.map +1 -0
  7. package/dist/InventoryView.interact.d.ts +2 -0
  8. package/dist/InventoryView.interact.d.ts.map +1 -0
  9. package/dist/InventoryView.interact.js +47 -0
  10. package/dist/InventoryView.interact.js.map +1 -0
  11. package/dist/InventoryView.js +242 -0
  12. package/dist/InventoryView.js.map +1 -0
  13. package/dist/components/InventoryAppView.d.ts +2 -0
  14. package/dist/components/InventoryAppView.d.ts.map +1 -0
  15. package/dist/components/InventoryAppView.js +1744 -0
  16. package/dist/components/InventoryAppView.js.map +1 -0
  17. package/dist/components/InventorySpatialView.d.ts +86 -0
  18. package/dist/components/InventorySpatialView.d.ts.map +1 -0
  19. package/dist/components/InventorySpatialView.js +218 -0
  20. package/dist/components/InventorySpatialView.js.map +1 -0
  21. package/dist/index.d.ts +15 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +65 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/inventory/ChainIcon.d.ts +9 -0
  26. package/dist/inventory/ChainIcon.d.ts.map +1 -0
  27. package/dist/inventory/ChainIcon.js +71 -0
  28. package/dist/inventory/ChainIcon.js.map +1 -0
  29. package/dist/inventory/TokenLogo.d.ts +8 -0
  30. package/dist/inventory/TokenLogo.d.ts.map +1 -0
  31. package/dist/inventory/TokenLogo.js +52 -0
  32. package/dist/inventory/TokenLogo.js.map +1 -0
  33. package/dist/inventory/chainConfig.d.ts +89 -0
  34. package/dist/inventory/chainConfig.d.ts.map +1 -0
  35. package/dist/inventory/chainConfig.js +252 -0
  36. package/dist/inventory/chainConfig.js.map +1 -0
  37. package/dist/inventory/constants.d.ts +31 -0
  38. package/dist/inventory/constants.d.ts.map +1 -0
  39. package/dist/inventory/constants.js +59 -0
  40. package/dist/inventory/constants.js.map +1 -0
  41. package/dist/inventory/index.d.ts +5 -0
  42. package/dist/inventory/index.d.ts.map +1 -0
  43. package/dist/inventory/index.js +43 -0
  44. package/dist/inventory/index.js.map +1 -0
  45. package/dist/inventory/inventory-chain-filters.d.ts +11 -0
  46. package/dist/inventory/inventory-chain-filters.d.ts.map +1 -0
  47. package/dist/inventory/inventory-chain-filters.js +49 -0
  48. package/dist/inventory/inventory-chain-filters.js.map +1 -0
  49. package/dist/inventory/media-url.d.ts +6 -0
  50. package/dist/inventory/media-url.d.ts.map +1 -0
  51. package/dist/inventory/media-url.js +32 -0
  52. package/dist/inventory/media-url.js.map +1 -0
  53. package/dist/inventory/useInventoryData.d.ts +38 -0
  54. package/dist/inventory/useInventoryData.d.ts.map +1 -0
  55. package/dist/inventory/useInventoryData.js +311 -0
  56. package/dist/inventory/useInventoryData.js.map +1 -0
  57. package/dist/plugin.d.ts +3 -0
  58. package/dist/plugin.d.ts.map +1 -0
  59. package/dist/plugin.js +55 -0
  60. package/dist/plugin.js.map +1 -0
  61. package/dist/register-routes.d.ts +9 -0
  62. package/dist/register-routes.d.ts.map +1 -0
  63. package/dist/register-routes.js +22 -0
  64. package/dist/register-routes.js.map +1 -0
  65. package/dist/register-terminal-view.d.ts +15 -0
  66. package/dist/register-terminal-view.d.ts.map +1 -0
  67. package/dist/register-terminal-view.js +33 -0
  68. package/dist/register-terminal-view.js.map +1 -0
  69. package/dist/register.d.ts +4 -0
  70. package/dist/register.d.ts.map +1 -0
  71. package/dist/register.js +20 -0
  72. package/dist/register.js.map +1 -0
  73. package/dist/ui.d.ts +13 -0
  74. package/dist/ui.d.ts.map +1 -0
  75. package/dist/ui.js +62 -0
  76. package/dist/ui.js.map +1 -0
  77. package/dist/views/bundle.js +1072 -0
  78. package/dist/views/bundle.js.map +1 -0
  79. package/dist/wallet-rpc.d.ts +2 -0
  80. package/dist/wallet-rpc.d.ts.map +1 -0
  81. package/dist/wallet-rpc.js +9 -0
  82. package/dist/wallet-rpc.js.map +1 -0
  83. package/dist/wallet-view-bundle.d.ts +3 -0
  84. package/dist/wallet-view-bundle.d.ts.map +1 -0
  85. package/dist/wallet-view-bundle.js +7 -0
  86. package/dist/wallet-view-bundle.js.map +1 -0
  87. package/dist/widgets/wallet-status.d.ts +3 -0
  88. package/dist/widgets/wallet-status.d.ts.map +1 -0
  89. package/dist/widgets/wallet-status.helpers.d.ts +3 -0
  90. package/dist/widgets/wallet-status.helpers.d.ts.map +1 -0
  91. package/dist/widgets/wallet-status.helpers.js +12 -0
  92. package/dist/widgets/wallet-status.helpers.js.map +1 -0
  93. package/dist/widgets/wallet-status.js +291 -0
  94. package/dist/widgets/wallet-status.js.map +1 -0
  95. package/package.json +7 -7
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/InventoryAppView.tsx"],"sourcesContent":["/**\n * InventoryAppView — the full-screen wallet dashboard mounted by the `/inventory`\n * nav tab (and the `@elizaos/plugin-wallet-ui#InventoryAppView` overlay export).\n *\n * It owns the rich multi-panel surface — holdings rail (tokens / DeFi / NFTs),\n * P&L window selector + chart, activity log, portfolio movers, LP positions, and\n * the NFT grid — backed by the app store + live trading-profile / market-overview\n * fetches. The cross-modality holdings view (`InventoryView`) renders the same\n * data through the spatial vocabulary for GUI / XR / TUI; this is the DOM-only\n * dashboard.\n */\nimport type {\n WalletConfigStatus,\n WalletMarketMover,\n WalletMarketOverviewResponse,\n WalletMarketOverviewSource,\n WalletMarketPriceSnapshot,\n WalletTradingProfileResponse,\n WalletTradingProfileWindow,\n} from \"@elizaos/shared\";\nimport { useAgentElement } from \"@elizaos/ui/agent-surface\";\nimport { client } from \"@elizaos/ui/api\";\nimport { Button } from \"@elizaos/ui/components\";\nimport { type ActivityEvent, useActivityEvents } from \"@elizaos/ui/hooks\";\nimport type { InventoryChainFilters } from \"@elizaos/ui/state\";\nimport { useAppSelectorShallow } from \"@elizaos/ui/state\";\nimport { cn } from \"@elizaos/ui/utils\";\nimport {\n Activity,\n AlertTriangle,\n ArrowLeftRight,\n BarChart3,\n CheckCircle2,\n Copy,\n EyeOff,\n Image as ImageIcon,\n Layers3,\n type LucideIcon,\n Sparkles,\n TrendingDown,\n TrendingUp,\n Wallet,\n} from \"lucide-react\";\nimport {\n memo,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { resolveWalletAddresses } from \"../InventoryView.helpers\";\nimport { getNativeLogoUrl } from \"../inventory/chainConfig.js\";\nimport {\n formatBalance,\n type NftItem,\n type TokenRow,\n} from \"../inventory/constants.js\";\nimport { TokenLogo } from \"../inventory/TokenLogo.js\";\nimport { useInventoryData } from \"../inventory/useInventoryData.js\";\n\ntype DashboardWindow = \"24h\" | \"7d\" | \"30d\";\ntype WalletRailTab = \"tokens\" | \"defi\" | \"nfts\";\n\nconst ALL_INVENTORY_FILTERS: InventoryChainFilters = {\n ethereum: true,\n base: true,\n bsc: true,\n avax: true,\n solana: true,\n};\nconst SUPPORTED_WALLET_CHAINS = Object.keys(ALL_INVENTORY_FILTERS);\n\nconst DASHBOARD_WINDOWS: DashboardWindow[] = [\"24h\", \"7d\", \"30d\"];\nconst HIDDEN_TOKEN_IDS_KEY = \"eliza:wallet:hidden-token-ids:v1\";\nconst WALLET_REFRESH_INTERVAL_MS = 20_000;\ninterface InventoryPositionAsset {\n id: string;\n kind: \"token\" | \"nft\";\n label: string;\n detail: string;\n valueUsd: number | null;\n imageUrl: string | null;\n}\n\ninterface PortfolioMover {\n row: TokenRow;\n realizedPnlBnb: number;\n}\n\ninterface WalletTimelineEntry {\n id: string;\n timestamp: number;\n title: string;\n detail?: string;\n href?: string;\n icon: LucideIcon;\n tone?: \"default\" | \"ok\" | \"warn\" | \"danger\";\n}\n\nconst usdFormatter = new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: 2,\n});\n\nconst compactFormatter = new Intl.NumberFormat(\"en-US\", {\n maximumFractionDigits: 4,\n});\n\nfunction readHiddenTokenIds(): Set<string> {\n if (typeof window === \"undefined\") return new Set();\n try {\n const raw = window.localStorage.getItem(HIDDEN_TOKEN_IDS_KEY);\n if (!raw) return new Set();\n\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return new Set();\n return new Set(\n parsed.filter((item): item is string => typeof item === \"string\"),\n );\n } catch {\n return new Set();\n }\n}\n\nfunction writeHiddenTokenIds(next: Set<string>): void {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(\n HIDDEN_TOKEN_IDS_KEY,\n JSON.stringify([...next]),\n );\n } catch {\n return;\n }\n}\n\nfunction tokenId(row: TokenRow): string {\n const address =\n row.contractAddress && row.contractAddress.length > 0\n ? row.contractAddress.toLowerCase()\n : `native:${row.symbol.toLowerCase()}`;\n return `${row.chain.toLowerCase()}:${address}`;\n}\n\n/** Kebab-cased, agent-surface-safe id slug for a single token row. */\nfunction tokenAgentSlug(row: TokenRow): string {\n return tokenId(row)\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/(^-|-$)/g, \"\");\n}\n\nfunction normalizeTokenAddress(address: string | null): string | null {\n return address ? address.toLowerCase() : null;\n}\n\nfunction formatUsd(value: number): string {\n if (!Number.isFinite(value)) return usdFormatter.format(0);\n return usdFormatter.format(value);\n}\n\nfunction formatMarketUsd(value: number): string {\n if (!Number.isFinite(value)) return usdFormatter.format(0);\n const fractionDigits =\n value >= 1_000 ? 0 : value >= 1 ? 2 : value >= 0.01 ? 4 : 6;\n const minimumFractionDigits = value >= 1 ? Math.min(2, fractionDigits) : 0;\n return value.toLocaleString(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits,\n maximumFractionDigits: fractionDigits,\n });\n}\n\nfunction formatPercentDelta(value: number): string {\n if (!Number.isFinite(value)) return \"0.0%\";\n const magnitude = Math.abs(value).toLocaleString(\"en-US\", {\n minimumFractionDigits: 1,\n maximumFractionDigits: 1,\n });\n const sign = value > 0 ? \"+\" : value < 0 ? \"-\" : \"\";\n return `${sign}${magnitude}%`;\n}\n\nfunction formatCompactAddress(address: string): string {\n if (address.length <= 12) return address;\n return `${address.slice(0, 5)}...${address.slice(-4)}`;\n}\n\nfunction formatBnb(value: string | null | undefined): string {\n if (!value) return \"0 BNB\";\n const parsed = Number.parseFloat(value);\n if (!Number.isFinite(parsed)) return `${value} BNB`;\n return `${compactFormatter.format(parsed)} BNB`;\n}\n\nfunction parseAmount(value: string | null | undefined): number | null {\n if (!value) return null;\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction formatSignedBnb(value: number): string {\n const sign = value > 0 ? \"+\" : value < 0 ? \"-\" : \"\";\n return `${sign}${compactFormatter.format(Math.abs(value))} BNB`;\n}\n\nfunction hasClosedTradePnl(\n profile: WalletTradingProfileResponse | null,\n): boolean {\n return (profile?.summary.evaluatedTrades ?? 0) > 0;\n}\n\nfunction providerLabel(\n provider: string | null | undefined,\n chain?: \"evm\" | \"bsc\" | \"solana\",\n): string {\n switch (provider) {\n case \"eliza-cloud\":\n return chain === \"solana\" ? \"Eliza Cloud / Helius\" : \"Eliza Cloud\";\n case \"alchemy\":\n return \"Alchemy\";\n case \"quicknode\":\n return \"QuickNode\";\n case \"helius-birdeye\":\n return \"Helius + Birdeye\";\n case \"custom\":\n return \"Custom\";\n default:\n return \"Not configured\";\n }\n}\n\nfunction formatRelativeTimestamp(timestamp: number): string {\n const diff = Date.now() - timestamp;\n if (diff < 0) return \"now\";\n if (diff < 60_000) return \"just now\";\n if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m ago`;\n if (diff < 86_400_000) return `${Math.floor(diff / 3_600_000)}h ago`;\n if (diff < 604_800_000) return `${Math.floor(diff / 86_400_000)}d ago`;\n return new Date(timestamp).toLocaleDateString();\n}\n\nfunction tradingProfileWindow(\n window: DashboardWindow,\n): WalletTradingProfileWindow {\n return window === \"24h\" ? \"24h\" : window;\n}\n\nfunction tokenHasInventory(row: TokenRow): boolean {\n return row.balanceRaw > 0 || row.valueUsd > 0;\n}\n\nfunction assetAllocationRows(rows: TokenRow[]): TokenRow[] {\n return rows\n .filter((row) => row.valueUsd > 0)\n .sort((left, right) => right.valueUsd - left.valueUsd)\n .slice(0, 5);\n}\n\nfunction looksLikeLpPosition(value: string): boolean {\n const text = ` ${value.toLowerCase()} `;\n return (\n text.includes(\" liquidity \") ||\n text.includes(\" lp \") ||\n text.includes(\"-lp\") ||\n text.includes(\"/lp\") ||\n text.includes(\" pool \") ||\n text.includes(\" position \") ||\n text.includes(\" clmm \") ||\n text.includes(\" amm \")\n );\n}\n\nfunction deriveInventoryPositionAssets({\n tokenRows,\n nfts,\n}: {\n tokenRows: TokenRow[];\n nfts: NftItem[];\n}): InventoryPositionAsset[] {\n const positions: InventoryPositionAsset[] = [];\n\n for (const row of tokenRows) {\n if (!looksLikeLpPosition(`${row.name} ${row.symbol}`)) continue;\n positions.push({\n id: `token:${tokenId(row)}`,\n kind: \"token\",\n label: row.symbol,\n detail: `${formatBalance(row.balance)} ${row.symbol}`,\n valueUsd: row.valueUsd,\n imageUrl: row.logoUrl,\n });\n }\n\n for (const nft of nfts) {\n if (!looksLikeLpPosition(`${nft.collectionName} ${nft.name}`)) continue;\n positions.push({\n id: `nft:${nft.collectionName}:${nft.name}:${nft.imageUrl}`,\n kind: \"nft\",\n label: nft.name,\n detail: nft.collectionName,\n valueUsd: null,\n imageUrl: nft.imageUrl,\n });\n }\n\n return positions;\n}\n\nfunction tokenBreakdownForRow(\n row: TokenRow,\n profile: WalletTradingProfileResponse | null,\n) {\n const normalizedAddress = normalizeTokenAddress(row.contractAddress);\n if (!normalizedAddress || !profile) return null;\n return (\n profile.tokenBreakdown.find(\n (item) => item.tokenAddress.toLowerCase() === normalizedAddress,\n ) ?? null\n );\n}\n\nfunction portfolioMovers(\n rows: TokenRow[],\n profile: WalletTradingProfileResponse | null,\n): PortfolioMover[] {\n if (!profile) return [];\n return rows\n .map((row) => {\n const breakdown = tokenBreakdownForRow(row, profile);\n const realizedPnlBnb = parseAmount(breakdown?.realizedPnlBnb);\n if (realizedPnlBnb === null || realizedPnlBnb === 0) return null;\n return {\n row,\n realizedPnlBnb,\n };\n })\n .filter((mover): mover is PortfolioMover => mover !== null);\n}\n\nfunction TokenPerformance({\n row,\n profile,\n maxAbsPnl,\n}: {\n row: TokenRow;\n profile: WalletTradingProfileResponse | null;\n maxAbsPnl: number;\n}) {\n const breakdown = tokenBreakdownForRow(row, profile);\n\n if (!breakdown) {\n return null;\n }\n\n const pnl = parseAmount(breakdown.realizedPnlBnb);\n if (pnl === null) return null;\n\n const width =\n maxAbsPnl > 0 ? Math.max(18, (Math.abs(pnl) / maxAbsPnl) * 56) : 18;\n const TrendIcon = pnl >= 0 ? TrendingUp : TrendingDown;\n const tone = pnl === 0 ? \"text-muted\" : pnl > 0 ? \"text-txt\" : \"text-danger\";\n const barTone =\n pnl === 0 ? \"bg-border\" : pnl > 0 ? \"bg-txt/70\" : \"bg-danger/80\";\n\n return (\n <span className=\"flex min-w-[4.5rem] flex-col items-end gap-1\">\n <span\n className={cn(\n \"inline-flex items-center gap-1 text-[0.68rem] font-medium\",\n tone,\n )}\n >\n <TrendIcon className=\"h-3 w-3\" />\n {pnl > 0 ? \"+\" : \"\"}\n {formatBnb(breakdown.realizedPnlBnb)}\n </span>\n <span\n className=\"flex h-1.5 w-14 justify-end overflow-hidden rounded-full bg-border/45\"\n aria-hidden=\"true\"\n >\n <span\n className={cn(\"h-full rounded-full\", barTone)}\n style={{ width }}\n />\n </span>\n </span>\n );\n}\n\nfunction maxAbsTokenPnl(\n rows: TokenRow[],\n profile: WalletTradingProfileResponse | null,\n): number {\n if (!profile) return 0;\n let max = 0;\n for (const row of rows) {\n const breakdown = tokenBreakdownForRow(row, profile);\n const pnl = parseAmount(breakdown?.realizedPnlBnb);\n if (pnl !== null) max = Math.max(max, Math.abs(pnl));\n }\n return max;\n}\n\nfunction ChainLogoBadge({\n chain,\n size = 18,\n className,\n}: {\n chain: string;\n size?: number;\n className?: string;\n}) {\n const [errored, setErrored] = useState(false);\n const logoUrl = errored ? null : getNativeLogoUrl(chain);\n\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-bg ring-2 ring-bg\",\n className,\n )}\n style={{ width: size, height: size }}\n title={chain}\n role=\"img\"\n aria-label={chain}\n >\n {logoUrl ? (\n <img\n src={logoUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n onError={() => setErrored(true)}\n />\n ) : (\n <span className=\"font-mono text-[0.58rem] font-bold uppercase text-muted\">\n {chain.charAt(0)}\n </span>\n )}\n </span>\n );\n}\n\nfunction TokenIdentityIcon({\n row,\n size = 46,\n}: {\n row: TokenRow;\n size?: number;\n}) {\n const badgeSize = Math.max(16, Math.round(size * 0.38));\n return (\n <span\n className=\"relative inline-flex shrink-0\"\n style={{ width: size, height: size }}\n >\n <TokenLogo\n symbol={row.symbol}\n chain={row.chain}\n contractAddress={row.contractAddress}\n preferredLogoUrl={row.logoUrl}\n size={size}\n />\n <ChainLogoBadge\n chain={row.chain}\n size={badgeSize}\n className=\"-bottom-0.5 -right-0.5 absolute\"\n />\n </span>\n );\n}\n\nfunction allocationToneClass(index: number): string {\n return index === 0\n ? \"bg-accent\"\n : index === 1\n ? \"bg-accent/70\"\n : index === 2\n ? \"bg-accent/45\"\n : index === 3\n ? \"bg-muted/60\"\n : \"bg-muted/35\";\n}\n\nfunction AssetAllocationStrip({\n rows,\n compact = false,\n}: {\n rows: TokenRow[];\n compact?: boolean;\n}) {\n const allocationRows = useMemo(() => assetAllocationRows(rows), [rows]);\n const total = allocationRows.reduce((sum, row) => sum + row.valueUsd, 0);\n if (total <= 0 || allocationRows.length === 0) return null;\n\n return (\n <div className={cn(\"space-y-2\", compact && \"space-y-3\")}>\n <div\n className={cn(\n \"flex overflow-hidden rounded-full bg-border/40\",\n compact ? \"h-2.5\" : \"h-2\",\n )}\n >\n {allocationRows.map((row, index) => (\n <span\n key={tokenId(row)}\n className={cn(\"h-full\", allocationToneClass(index))}\n style={{ width: `${(row.valueUsd / total) * 100}%` }}\n title={`${row.symbol}: ${formatUsd(row.valueUsd)}`}\n />\n ))}\n </div>\n {compact ? (\n <div className=\"flex flex-wrap gap-2\">\n {allocationRows.slice(0, 3).map((row, index) => (\n <div\n key={tokenId(row)}\n className=\"inline-flex items-center gap-1.5 text-[0.68rem] font-medium text-txt\"\n >\n <span\n className={cn(\n \"h-1.5 w-1.5 rounded-full\",\n allocationToneClass(index),\n )}\n />\n <span>{row.symbol}</span>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"grid gap-1\">\n {allocationRows.slice(0, 3).map((row) => (\n <div\n key={tokenId(row)}\n className=\"flex items-center justify-between gap-2 text-[0.68rem]\"\n >\n <span className=\"truncate text-muted\">{row.symbol}</span>\n <span className=\"shrink-0 font-mono text-txt\">\n {formatUsd(row.valueUsd)}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction PortfolioMoverRow({\n mover,\n maxAbsPnl,\n}: {\n mover: PortfolioMover;\n maxAbsPnl: number;\n}) {\n const isGain = mover.realizedPnlBnb > 0;\n const width =\n maxAbsPnl > 0\n ? Math.max(18, (Math.abs(mover.realizedPnlBnb) / maxAbsPnl) * 100)\n : 18;\n\n return (\n <div className=\"grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 px-1 py-2\">\n <TokenIdentityIcon row={mover.row} size={34} />\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-semibold text-txt\">\n {mover.row.symbol}\n </div>\n <div className=\"mt-1 h-1.5 overflow-hidden rounded-full bg-border/45\">\n <div\n className={cn(\n \"h-full rounded-full\",\n isGain ? \"bg-txt/70\" : \"bg-danger/85\",\n )}\n style={{ width: `${width}%` }}\n />\n </div>\n </div>\n <div\n className={cn(\n \"shrink-0 text-right font-mono text-xs font-semibold\",\n isGain ? \"text-txt\" : \"text-danger\",\n )}\n >\n {formatSignedBnb(mover.realizedPnlBnb)}\n </div>\n </div>\n );\n}\n\nfunction PortfolioMoverColumn({\n title,\n movers,\n maxAbsPnl,\n tone,\n}: {\n title: string;\n movers: PortfolioMover[];\n maxAbsPnl: number;\n tone: \"gain\" | \"loss\";\n}) {\n return (\n <div className=\"min-w-0 space-y-2\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-txt\">\n {tone === \"gain\" ? (\n <TrendingUp className=\"h-3.5 w-3.5 text-muted\" />\n ) : (\n <TrendingDown className=\"h-3.5 w-3.5 text-danger\" />\n )}\n {title}\n </div>\n {movers.length > 0 ? (\n <div className=\"space-y-1\">\n {movers.map((mover) => (\n <PortfolioMoverRow\n key={`${tokenId(mover.row)}:${mover.realizedPnlBnb}`}\n mover={mover}\n maxAbsPnl={maxAbsPnl}\n />\n ))}\n </div>\n ) : (\n <div className=\"flex h-[3.75rem] items-center px-1 text-xs-tight text-muted\">\n None\n </div>\n )}\n </div>\n );\n}\n\nfunction PortfolioMoversPanel({\n rows,\n profile,\n marketOverview,\n}: {\n rows: TokenRow[];\n profile: WalletTradingProfileResponse | null;\n marketOverview: WalletMarketOverviewResponse | null;\n}) {\n const movers = useMemo(() => portfolioMovers(rows, profile), [rows, profile]);\n const gainers = useMemo(\n () =>\n movers\n .filter((mover) => mover.realizedPnlBnb > 0)\n .sort((left, right) => right.realizedPnlBnb - left.realizedPnlBnb)\n .slice(0, 3),\n [movers],\n );\n const losers = useMemo(\n () =>\n movers\n .filter((mover) => mover.realizedPnlBnb < 0)\n .sort((left, right) => left.realizedPnlBnb - right.realizedPnlBnb)\n .slice(0, 3),\n [movers],\n );\n const maxAbsPnl = useMemo(\n () =>\n movers.reduce(\n (max, mover) => Math.max(max, Math.abs(mover.realizedPnlBnb)),\n 0,\n ),\n [movers],\n );\n\n if (movers.length === 0) {\n if (marketOverview?.movers.length) {\n return (\n <MarketMoverList\n movers={marketOverview.movers}\n source={marketOverview.sources.movers}\n />\n );\n }\n\n return <EmptyState icon={TrendingUp} title=\"None\" />;\n }\n\n return (\n <div className=\"grid gap-4 md:grid-cols-2\">\n <PortfolioMoverColumn\n title=\"Gainers\"\n movers={gainers}\n maxAbsPnl={maxAbsPnl}\n tone=\"gain\"\n />\n <PortfolioMoverColumn\n title=\"Losers\"\n movers={losers}\n maxAbsPnl={maxAbsPnl}\n tone=\"loss\"\n />\n </div>\n );\n}\n\nfunction EmptyState({\n icon: Icon,\n title,\n body,\n}: {\n icon: LucideIcon;\n title: string;\n body?: string;\n}) {\n return (\n <div className=\"flex min-h-[8rem] flex-col items-center justify-center px-4 py-6 text-center\">\n <Icon className=\"mb-3 h-5 w-5 text-muted\" />\n <div className=\"text-sm font-semibold text-txt\">{title}</div>\n {body ? (\n <div className=\"sr-only mt-1 max-w-sm text-xs-tight text-muted\">\n {body}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction MarketAvatar({\n imageUrl,\n label,\n}: {\n imageUrl: string | null;\n label: string;\n}) {\n if (imageUrl) {\n return (\n <img\n src={imageUrl}\n alt={label}\n className=\"h-11 w-11 shrink-0 object-cover\"\n loading=\"lazy\"\n />\n );\n }\n\n return (\n <div className=\"flex h-11 w-11 shrink-0 items-center justify-center text-sm font-semibold text-txt\">\n {label.slice(0, 1).toUpperCase()}\n </div>\n );\n}\n\nfunction MarketSourceBadge({ source }: { source: WalletMarketOverviewSource }) {\n return (\n <a\n href={source.providerUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-[0.68rem] font-medium text-muted transition-colors hover:text-txt\"\n >\n {source.providerName}\n </a>\n );\n}\n\nfunction MarketSectionHeader({\n icon: Icon,\n title,\n source,\n}: {\n icon: LucideIcon;\n title: string;\n source: WalletMarketOverviewSource;\n}) {\n return (\n <div className=\"mb-3 flex flex-wrap items-center gap-2 text-sm font-semibold text-txt\">\n <Icon className=\"h-4 w-4 text-accent\" />\n <span>{title}</span>\n <MarketSourceBadge source={source} />\n </div>\n );\n}\n\nfunction MarketDataUnavailable({\n title,\n source,\n}: {\n title: string;\n source: WalletMarketOverviewSource;\n}) {\n return (\n <div className=\"px-1 py-2\" title={`${title} unavailable`}>\n <div className=\"text-sm font-semibold text-warn\">Unavailable</div>\n <div className=\"sr-only mt-1 text-xs text-muted\">\n {source.error ?? `${source.providerName} did not return live data.`}\n </div>\n </div>\n );\n}\n\nfunction MajorPriceCard({ snapshot }: { snapshot: WalletMarketPriceSnapshot }) {\n const isPositive = snapshot.change24hPct >= 0;\n\n return (\n <div className=\"min-w-0 p-2\">\n <div className=\"flex items-center gap-3\">\n <MarketAvatar imageUrl={snapshot.imageUrl} label={snapshot.symbol} />\n <div className=\"min-w-0\">\n <div className=\"text-sm font-semibold text-txt\">\n {snapshot.symbol}\n </div>\n <div className=\"truncate text-xs-tight text-muted\">\n {snapshot.name}\n </div>\n </div>\n </div>\n <div className=\"mt-4 flex flex-wrap items-end justify-between gap-x-3 gap-y-1\">\n <div className=\"min-w-0 font-mono text-lg font-semibold text-txt sm:text-xl\">\n {formatMarketUsd(snapshot.priceUsd)}\n </div>\n <div\n className={cn(\n \"shrink-0 text-sm font-semibold\",\n isPositive ? \"text-txt\" : \"text-danger\",\n )}\n >\n {formatPercentDelta(snapshot.change24hPct)}\n </div>\n </div>\n </div>\n );\n}\n\nfunction MarketPriceGrid({\n prices,\n source,\n}: {\n prices: WalletMarketPriceSnapshot[];\n source: WalletMarketOverviewSource;\n}) {\n if (!source.available) {\n return <MarketDataUnavailable title=\"Spot prices\" source={source} />;\n }\n\n if (prices.length === 0) {\n return <EmptyState icon={BarChart3} title=\"None\" />;\n }\n\n return (\n <div className=\"grid grid-cols-[repeat(auto-fit,minmax(min(100%,13.5rem),1fr))] gap-3\">\n {prices.map((snapshot) => (\n <MajorPriceCard key={snapshot.id} snapshot={snapshot} />\n ))}\n </div>\n );\n}\n\nfunction MarketMoverList({\n movers,\n source,\n}: {\n movers: WalletMarketMover[];\n source: WalletMarketOverviewSource;\n}) {\n if (!source.available) {\n return <MarketDataUnavailable title=\"Top movers\" source={source} />;\n }\n\n if (movers.length === 0) {\n return <EmptyState icon={TrendingUp} title=\"None\" />;\n }\n\n return (\n <div className=\"space-y-2\">\n {movers.map((mover) => {\n const isPositive = mover.change24hPct >= 0;\n return (\n <div\n key={mover.id}\n className=\"flex min-w-0 items-center gap-3 px-1 py-2.5\"\n >\n <MarketAvatar imageUrl={mover.imageUrl} label={mover.symbol} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-txt\">\n {mover.symbol}\n </span>\n <span className=\"truncate text-xs-tight text-muted\">\n {mover.name}\n </span>\n </div>\n {mover.marketCapRank !== null ? (\n <div className=\"mt-1 text-[0.68rem] font-medium text-muted\">\n Cap rank #{mover.marketCapRank}\n </div>\n ) : null}\n </div>\n <div className=\"shrink-0 text-right\">\n <div className=\"font-mono text-sm font-semibold text-txt\">\n {formatMarketUsd(mover.priceUsd)}\n </div>\n <div\n className={cn(\n \"text-xs font-semibold\",\n isPositive ? \"text-txt\" : \"text-danger\",\n )}\n >\n {formatPercentDelta(mover.change24hPct)}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction WalletMotif() {\n return (\n <svg\n viewBox=\"0 0 120 120\"\n role=\"img\"\n aria-label=\"Empty wallet\"\n className=\"h-24 w-24\"\n >\n <defs>\n <linearGradient id=\"walletMotifFill\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"var(--accent)\" stopOpacity=\"0.9\" />\n <stop offset=\"100%\" stopColor=\"var(--accent)\" stopOpacity=\"0.35\" />\n </linearGradient>\n </defs>\n <circle\n cx=\"60\"\n cy=\"60\"\n r=\"56\"\n fill=\"url(#walletMotifFill)\"\n opacity=\"0.12\"\n />\n <rect\n x=\"30\"\n y=\"42\"\n width=\"60\"\n height=\"40\"\n rx=\"10\"\n fill=\"url(#walletMotifFill)\"\n opacity=\"0.85\"\n />\n <rect\n x=\"30\"\n y=\"42\"\n width=\"60\"\n height=\"14\"\n rx=\"7\"\n fill=\"var(--accent)\"\n opacity=\"0.5\"\n />\n <circle cx=\"78\" cy=\"62\" r=\"6\" fill=\"var(--bg)\" opacity=\"0.85\" />\n <circle cx=\"78\" cy=\"62\" r=\"2.5\" fill=\"var(--accent)\" />\n </svg>\n );\n}\n\nfunction WalletEmptyHero({\n hasKeys,\n onConfigureKeys,\n}: {\n hasKeys: boolean;\n onConfigureKeys: () => void;\n}) {\n return (\n <div className=\"flex flex-col items-center gap-4 px-6 py-10 text-center\">\n <WalletMotif />\n <div className=\"text-base font-semibold text-txt\">\n {hasKeys ? \"None\" : \"Wallet\"}\n </div>\n {hasKeys ? null : (\n <Button\n type=\"button\"\n variant=\"surfaceAccent\"\n size=\"sm\"\n onClick={onConfigureKeys}\n >\n Keys\n </Button>\n )}\n </div>\n );\n}\n\nfunction MarketPulseHero({\n overview,\n loading,\n hasKeys,\n onConfigureKeys,\n}: {\n overview: WalletMarketOverviewResponse | null;\n loading: boolean;\n hasKeys: boolean;\n onConfigureKeys: () => void;\n}) {\n return (\n <section className=\"space-y-6\">\n <WalletEmptyHero hasKeys={hasKeys} onConfigureKeys={onConfigureKeys} />\n\n {overview ? (\n <div className=\"grid gap-4 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.92fr)]\">\n <div className=\"space-y-4\">\n <div>\n <MarketSectionHeader\n icon={BarChart3}\n title=\"Spot prices\"\n source={overview.sources.prices}\n />\n <MarketPriceGrid\n prices={overview.prices}\n source={overview.sources.prices}\n />\n </div>\n\n <div>\n <MarketSectionHeader\n icon={TrendingUp}\n title=\"Top movers\"\n source={overview.sources.movers}\n />\n <MarketMoverList\n movers={overview.movers}\n source={overview.sources.movers}\n />\n </div>\n </div>\n </div>\n ) : loading ? (\n <div className=\"grid grid-cols-[repeat(auto-fit,minmax(min(100%,13.5rem),1fr))] gap-3\">\n {[\"btc\", \"eth\", \"sol\"].map((loadingCardId) => (\n <div key={loadingCardId} className=\"h-28 animate-pulse bg-bg/20\" />\n ))}\n </div>\n ) : null}\n </section>\n );\n}\n\nfunction activityEventMeta(eventType: string): {\n icon: LucideIcon;\n tone: WalletTimelineEntry[\"tone\"];\n} {\n if (eventType === \"task_complete\" || eventType === \"blocked_auto_resolved\") {\n return { icon: Sparkles, tone: \"ok\" };\n }\n if (eventType === \"blocked\" || eventType === \"escalation\") {\n return { icon: Activity, tone: \"warn\" };\n }\n if (eventType === \"error\") {\n return { icon: Activity, tone: \"danger\" };\n }\n return { icon: Activity, tone: \"default\" };\n}\n\nfunction walletTimelineEntries({\n profile,\n events,\n}: {\n profile: WalletTradingProfileResponse | null;\n events: ActivityEvent[];\n}): WalletTimelineEntry[] {\n const swapEntries = (profile?.recentSwaps ?? []).reduce<\n WalletTimelineEntry[]\n >((entries, swap) => {\n const timestamp = Date.parse(swap.createdAt);\n if (!Number.isFinite(timestamp)) return entries;\n entries.push({\n id: `swap:${swap.hash}`,\n timestamp,\n title: `${swap.side === \"buy\" ? \"Bought\" : \"Sold\"} ${swap.tokenSymbol}`,\n detail: `${swap.inputAmount} ${swap.inputSymbol} -> ${swap.outputAmount} ${swap.outputSymbol}`,\n href: swap.explorerUrl,\n icon: ArrowLeftRight,\n tone:\n swap.status === \"success\"\n ? \"ok\"\n : swap.status === \"pending\"\n ? \"warn\"\n : \"danger\",\n });\n return entries;\n }, []);\n const agentEntries: WalletTimelineEntry[] = events.map((event) => {\n const meta = activityEventMeta(event.eventType);\n return {\n id: `agent:${event.id}`,\n timestamp: event.timestamp,\n title: event.summary,\n icon: meta.icon,\n tone: meta.tone,\n };\n });\n\n return [...swapEntries, ...agentEntries]\n .sort((left, right) => right.timestamp - left.timestamp)\n .slice(0, 18);\n}\n\nfunction PnlChart({\n profile,\n}: {\n profile: WalletTradingProfileResponse | null;\n}) {\n const points = profile?.pnlSeries ?? [];\n const values = points\n .map((point) => parseAmount(point.realizedPnlBnb))\n .filter((value): value is number => value !== null);\n\n if (values.length < 2) {\n return (\n <div className=\"flex h-40 items-center justify-center text-xs text-muted\">\n P&amp;L pending\n </div>\n );\n }\n\n const min = Math.min(...values);\n const max = Math.max(...values);\n const span = max - min || 1;\n const svgPoints = values\n .map((value, index) => {\n const x = (index / (values.length - 1)) * 100;\n const y = 88 - ((value - min) / span) * 72;\n return `${x},${y}`;\n })\n .join(\" \");\n const latest = values[values.length - 1];\n const stroke = latest >= 0 ? \"var(--muted-strong)\" : \"var(--danger)\";\n\n return (\n <svg\n className=\"h-40 w-full\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-label=\"Trade P&L chart\"\n >\n <polyline\n fill=\"none\"\n stroke={stroke}\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n points={svgPoints}\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n );\n}\n\nfunction SummaryChip({\n icon: Icon,\n value,\n tone = \"default\",\n title,\n}: {\n icon: LucideIcon;\n value: string;\n tone?: \"default\" | \"gain\" | \"loss\";\n title?: string;\n}) {\n return (\n <div\n className={cn(\n \"inline-flex items-center gap-2 px-1 py-1.5 text-sm font-medium\",\n tone === \"loss\" ? \"text-danger\" : \"text-txt\",\n )}\n title={title}\n >\n <Icon className=\"h-3.5 w-3.5 shrink-0\" />\n <span>{value}</span>\n </div>\n );\n}\n\nfunction WalletRailAddress({\n address,\n chains,\n emptyLabel,\n label,\n agentId,\n agentLabel,\n}: {\n address: string | null;\n chains: string[];\n emptyLabel: string;\n label: string;\n /** Stable agent-surface id so the agent can copy this address by name. */\n agentId: string;\n /** Human/agent-facing label for the copy action. */\n agentLabel: string;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(() => {\n if (!address) return;\n void navigator.clipboard.writeText(address).then(() => {\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1200);\n });\n }, [address]);\n\n const { ref, agentProps } = useAgentElement<HTMLButtonElement>({\n id: agentId,\n role: \"button\",\n label: agentLabel,\n group: \"wallet-account\",\n status: address ? undefined : \"inactive\",\n description: `Copy the ${agentLabel} to the clipboard`,\n });\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n \"group inline-flex min-w-0 items-center gap-2 px-1 py-1.5 text-left transition-colors\",\n address ? \"text-txt hover:text-accent\" : \"text-muted\",\n )}\n onClick={handleCopy}\n disabled={!address}\n title={address ?? emptyLabel}\n aria-label={\n address ? `Copy ${emptyLabel} address` : `${emptyLabel} unavailable`\n }\n {...agentProps}\n >\n <span className=\"flex shrink-0 -space-x-1.5\">\n {chains.map((chain) => (\n <ChainLogoBadge\n key={chain}\n chain={chain}\n size={18}\n className=\"ring-1 ring-bg\"\n />\n ))}\n </span>\n <span className=\"shrink-0 text-[0.68rem] font-medium text-muted\">\n {label}\n </span>\n <span\n className={cn(\n \"min-w-0 truncate font-mono text-xs font-semibold\",\n address ? \"max-w-24 text-txt\" : \"max-w-20 text-muted\",\n )}\n >\n {address ? formatCompactAddress(address) : emptyLabel}\n </span>\n {address ? (\n copied ? (\n <CheckCircle2 className=\"h-3.5 w-3.5 shrink-0 text-accent\" />\n ) : (\n <Copy className=\"h-3.5 w-3.5 shrink-0 text-muted transition-colors group-hover:text-txt\" />\n )\n ) : (\n <AlertTriangle className=\"h-3.5 w-3.5 shrink-0 text-warn\" />\n )}\n </button>\n );\n}\n\nfunction WalletConnectionChip({\n label,\n ready,\n}: {\n label: string;\n ready: boolean;\n}) {\n return (\n <span\n className=\"inline-flex items-center gap-1.5 text-[0.68rem] font-medium text-muted\"\n title={`${label} ${ready ? \"ready\" : \"needs RPC\"}`}\n >\n <span\n className={cn(\n \"h-1.5 w-1.5 rounded-full\",\n ready ? \"bg-muted/60\" : \"bg-warn\",\n )}\n />\n {label}\n </span>\n );\n}\n\nfunction WalletChainCluster() {\n return (\n <span className=\"flex shrink-0 -space-x-1.5\">\n {SUPPORTED_WALLET_CHAINS.map((chain) => (\n <ChainLogoBadge\n key={chain}\n chain={chain}\n size={18}\n className=\"ring-1 ring-bg\"\n />\n ))}\n </span>\n );\n}\n\nfunction WalletAddressCluster({\n addresses,\n}: {\n addresses: { evmAddress: string | null; solanaAddress: string | null };\n}) {\n return (\n <div className=\"flex min-w-0 flex-wrap gap-2\">\n <WalletRailAddress\n address={addresses.evmAddress}\n chains={SUPPORTED_WALLET_CHAINS.filter((chain) => chain !== \"solana\")}\n emptyLabel=\"EVM\"\n label=\"EVM\"\n agentId=\"account-copy-evm-address\"\n agentLabel=\"EVM address\"\n />\n <WalletRailAddress\n address={addresses.solanaAddress}\n chains={[\"solana\"]}\n emptyLabel=\"SOL\"\n label=\"SOL\"\n agentId=\"account-copy-solana-address\"\n agentLabel=\"Solana address\"\n />\n </div>\n );\n}\n\nfunction WalletProviderDots({\n walletConfig,\n}: {\n walletConfig: WalletConfigStatus | null;\n}) {\n const allReady =\n Boolean(walletConfig?.evmBalanceReady) &&\n Boolean(walletConfig?.solanaBalanceReady);\n return (\n <span\n className={cn(\n \"h-2 w-2 rounded-full\",\n allReady ? \"bg-muted/60\" : \"bg-warn\",\n )}\n />\n );\n}\n\nfunction WalletRailRpcButton({\n walletConfig,\n onOpenSettings,\n}: {\n walletConfig: WalletConfigStatus | null;\n onOpenSettings: () => void;\n}) {\n const evmProvider = providerLabel(\n walletConfig?.selectedRpcProviders?.evm,\n \"evm\",\n );\n const solanaProvider = providerLabel(\n walletConfig?.selectedRpcProviders?.solana,\n \"solana\",\n );\n\n const { ref, agentProps } = useAgentElement<HTMLButtonElement>({\n id: \"account-rpc-settings\",\n role: \"button\",\n label: \"RPC settings\",\n group: \"wallet-account\",\n description: `Open RPC provider settings (EVM ${evmProvider}, Solana ${solanaProvider})`,\n });\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className=\"inline-flex h-9 items-center gap-2 px-2 text-xs font-semibold text-txt transition-colors hover:text-accent\"\n onClick={onOpenSettings}\n title={`RPC providers: EVM ${evmProvider}, Solana ${solanaProvider}`}\n aria-label=\"Open RPC settings\"\n {...agentProps}\n >\n <WalletProviderDots walletConfig={walletConfig} />\n RPC\n </button>\n );\n}\n\nfunction WalletRailAccount({\n addresses,\n portfolioValueUsd,\n walletConfig,\n onOpenSettings,\n}: {\n addresses: { evmAddress: string | null; solanaAddress: string | null };\n portfolioValueUsd: number;\n walletConfig: WalletConfigStatus | null;\n onOpenSettings: () => void;\n}) {\n const evmReady = Boolean(walletConfig?.evmBalanceReady);\n const solanaReady = Boolean(walletConfig?.solanaBalanceReady);\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-start gap-4\">\n <div className=\"relative flex h-16 w-16 items-center justify-center\">\n <Wallet className=\"h-7 w-7 text-accent\" />\n </div>\n <div className=\"min-w-0 flex-1 basis-64\">\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-2\">\n <div className=\"font-mono text-2xl font-semibold leading-none text-txt\">\n {formatUsd(portfolioValueUsd)}\n </div>\n <WalletChainCluster />\n </div>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <WalletConnectionChip label=\"EVM\" ready={evmReady} />\n <WalletConnectionChip label=\"SOL\" ready={solanaReady} />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <WalletRailRpcButton\n walletConfig={walletConfig}\n onOpenSettings={onOpenSettings}\n />\n </div>\n </div>\n <WalletAddressCluster addresses={addresses} />\n </div>\n );\n}\n\nfunction WalletRailTabButton({\n tab,\n active,\n onSelect,\n}: {\n tab: { id: WalletRailTab; label: string; icon: LucideIcon; count: number };\n active: boolean;\n onSelect: (id: WalletRailTab) => void;\n}) {\n const { ref, agentProps } = useAgentElement<HTMLButtonElement>({\n id: `tab-${tab.id}`,\n role: \"tab\",\n label: tab.label,\n group: \"wallet-tabs\",\n status: active ? \"active\" : \"inactive\",\n description: `Show the ${tab.label} list`,\n });\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n \"inline-flex min-w-0 items-center justify-center gap-1.5 px-2 py-2 text-sm font-semibold transition-colors\",\n active ? \"text-txt\" : \"text-muted hover:text-txt\",\n )}\n onClick={() => onSelect(tab.id)}\n aria-label={tab.label}\n aria-current={active ? \"true\" : undefined}\n title={tab.label}\n {...agentProps}\n >\n <tab.icon className=\"h-3.5 w-3.5 shrink-0\" />\n <span className=\"truncate\">{tab.label}</span>\n <span\n className={cn(\"ml-0.5 px-1 py-0.5 font-mono text-[0.62rem] text-muted\")}\n >\n {tab.count}\n </span>\n </button>\n );\n}\n\nfunction WalletRailEmpty({\n icon: Icon,\n title,\n body,\n}: {\n icon: LucideIcon;\n title: string;\n body?: string;\n}) {\n return (\n <div className=\"flex min-h-[13rem] flex-col items-center justify-center px-5 text-center\">\n <Icon className=\"mb-3 h-5 w-5 text-muted\" />\n <div className=\"text-sm font-semibold text-txt\">{title}</div>\n {body ? <div className=\"sr-only\">{body}</div> : null}\n </div>\n );\n}\n\nfunction TokenRailRowImpl({\n row,\n profile,\n maxPnl,\n onHideToken,\n}: {\n row: TokenRow;\n profile: WalletTradingProfileResponse | null;\n maxPnl: number;\n onHideToken: (row: TokenRow) => void;\n}) {\n const slug = tokenAgentSlug(row);\n const { ref: hideRef, agentProps: hideAgentProps } =\n useAgentElement<HTMLButtonElement>({\n id: `token-${slug}-hide`,\n role: \"button\",\n label: `Hide ${row.symbol}`,\n group: \"token-list\",\n description: `Hide the ${row.symbol} token from the list`,\n });\n return (\n <div className=\"group flex min-w-0 items-center gap-3 px-2 py-2 transition-colors hover:bg-bg-muted/20\">\n <TokenIdentityIcon row={row} size={46} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-txt\">\n {row.symbol}\n </div>\n <div className=\"truncate text-xs-tight text-muted\">\n {formatBalance(row.balance)} {row.symbol}\n </div>\n <div className=\"mt-1\">\n <TokenPerformance row={row} profile={profile} maxAbsPnl={maxPnl} />\n </div>\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-2\">\n <div className=\"font-mono text-sm font-semibold text-txt\">\n {formatUsd(row.valueUsd)}\n </div>\n <div className=\"flex gap-1 opacity-70 transition-opacity group-hover:opacity-100\">\n <button\n ref={hideRef}\n type=\"button\"\n className=\"flex h-7 w-7 items-center justify-center text-muted transition-colors hover:text-danger\"\n onClick={() => onHideToken(row)}\n aria-label={`Hide ${row.symbol}`}\n title={`Hide ${row.symbol}`}\n {...hideAgentProps}\n >\n <EyeOff className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// The 20s balance poll replaces row objects wholesale, so default shallow\n// compare always sees a new `row` reference. Compare only the fields that drive\n// rendering (identity, displayed balance/value, performance inputs) so the row\n// re-renders only when its visible content actually changes.\nconst TokenRailRow = memo(\n TokenRailRowImpl,\n (prev, next) =>\n prev.onHideToken === next.onHideToken &&\n prev.maxPnl === next.maxPnl &&\n prev.profile === next.profile &&\n prev.row.chain === next.row.chain &&\n prev.row.symbol === next.row.symbol &&\n prev.row.name === next.row.name &&\n prev.row.contractAddress === next.row.contractAddress &&\n prev.row.logoUrl === next.row.logoUrl &&\n prev.row.balance === next.row.balance &&\n prev.row.valueUsd === next.row.valueUsd &&\n prev.row.balanceRaw === next.row.balanceRaw &&\n prev.row.isNative === next.row.isNative,\n);\n\nfunction RailNftList({ nfts }: { nfts: NftItem[] }) {\n if (nfts.length === 0) {\n return <WalletRailEmpty icon={ImageIcon} title=\"None\" />;\n }\n\n return (\n <div className=\"space-y-1\">\n {nfts.slice(0, 20).map((nft) => (\n <div\n key={`${nft.chain}:${nft.collectionName}:${nft.name}:${nft.imageUrl}`}\n className=\"flex min-w-0 items-center gap-3 px-2 py-2 transition-colors hover:bg-bg-muted/20\"\n >\n {nft.imageUrl ? (\n <img\n src={nft.imageUrl}\n alt={nft.name}\n className=\"h-11 w-11 shrink-0 object-cover\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex h-11 w-11 shrink-0 items-center justify-center\">\n <ImageIcon className=\"h-4 w-4 text-muted\" />\n </div>\n )}\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-semibold text-txt\">\n {nft.name}\n </div>\n <div className=\"truncate text-xs-tight text-muted\">\n {nft.collectionName}\n </div>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction RailPositionList({\n positions,\n}: {\n positions: InventoryPositionAsset[];\n}) {\n if (positions.length === 0) {\n return <WalletRailEmpty icon={Layers3} title=\"None\" />;\n }\n\n return (\n <div className=\"space-y-1\">\n {positions.map((position) => (\n <div\n key={position.id}\n className=\"flex min-w-0 items-center gap-3 px-2 py-2 transition-colors hover:bg-bg-muted/20\"\n >\n {position.imageUrl ? (\n <img\n src={position.imageUrl}\n alt={position.label}\n className=\"h-11 w-11 shrink-0 object-cover\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex h-11 w-11 shrink-0 items-center justify-center\">\n <Layers3 className=\"h-4 w-4 text-muted\" />\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-txt\">\n {position.label}\n </div>\n <div className=\"truncate text-xs-tight text-muted\">\n {position.detail}\n </div>\n </div>\n {position.valueUsd !== null && position.valueUsd > 0 ? (\n <div className=\"shrink-0 font-mono text-sm font-semibold text-txt\">\n {formatUsd(position.valueUsd)}\n </div>\n ) : null}\n </div>\n ))}\n </div>\n );\n}\n\nfunction WalletHoldingsSection({\n rows,\n nfts,\n positions,\n addresses,\n hiddenTokenIds,\n walletConfig,\n profile,\n onHideToken,\n onOpenRpcSettings,\n walletEnabled,\n onEnableWallet,\n}: {\n rows: TokenRow[];\n nfts: NftItem[];\n positions: InventoryPositionAsset[];\n addresses: { evmAddress: string | null; solanaAddress: string | null };\n hiddenTokenIds: Set<string>;\n walletConfig: WalletConfigStatus | null;\n profile: WalletTradingProfileResponse | null;\n onHideToken: (row: TokenRow) => void;\n onOpenRpcSettings: () => void;\n walletEnabled: boolean | null;\n onEnableWallet: () => void;\n}) {\n const [activeTab, setActiveTab] = useState<WalletRailTab>(\"tokens\");\n const visibleRows = useMemo(\n () =>\n rows.filter((row) => {\n if (hiddenTokenIds.has(tokenId(row))) return false;\n return tokenHasInventory(row);\n }),\n [hiddenTokenIds, rows],\n );\n const totalUsd = useMemo(\n () => visibleRows.reduce((sum, row) => sum + row.valueUsd, 0),\n [visibleRows],\n );\n const maxPnl = useMemo(\n () => maxAbsTokenPnl(visibleRows, profile),\n [visibleRows, profile],\n );\n const tabs: Array<{\n id: WalletRailTab;\n label: string;\n icon: LucideIcon;\n count: number;\n }> = [\n {\n id: \"tokens\",\n label: \"Tokens\",\n icon: Wallet,\n count: visibleRows.length,\n },\n { id: \"defi\", label: \"DeFi\", icon: Layers3, count: positions.length },\n { id: \"nfts\", label: \"NFTs\", icon: ImageIcon, count: nfts.length },\n ];\n const { ref: enableWalletRef, agentProps: enableWalletAgentProps } =\n useAgentElement<HTMLButtonElement>({\n id: \"action-enable-wallet\",\n role: \"button\",\n label: \"Enable wallet\",\n group: \"wallet-actions\",\n description: \"Turn on the wallet to load balances and trading data\",\n });\n\n return (\n <section data-testid=\"wallets-sidebar\" className=\"px-3 py-3 md:px-4\">\n <WalletRailAccount\n addresses={addresses}\n portfolioValueUsd={totalUsd}\n walletConfig={walletConfig}\n onOpenSettings={onOpenRpcSettings}\n />\n <div className=\"mt-4 space-y-4\">\n {visibleRows.length > 0 ? (\n <AssetAllocationStrip rows={visibleRows} compact />\n ) : null}\n\n {walletEnabled === false ? (\n <Button\n ref={enableWalletRef}\n className=\"w-full\"\n onClick={onEnableWallet}\n {...enableWalletAgentProps}\n >\n Enable wallet\n </Button>\n ) : null}\n\n <div className=\"grid min-w-0 grid-cols-3 gap-1\">\n {tabs.map((tab) => (\n <WalletRailTabButton\n key={tab.id}\n tab={tab}\n active={activeTab === tab.id}\n onSelect={setActiveTab}\n />\n ))}\n </div>\n\n <div className=\"space-y-1\">\n {activeTab === \"tokens\" ? (\n visibleRows.length === 0 ? (\n <WalletRailEmpty icon={Wallet} title=\"None\" />\n ) : (\n visibleRows.map((row) => (\n <TokenRailRow\n key={tokenId(row)}\n row={row}\n profile={profile}\n maxPnl={maxPnl}\n onHideToken={onHideToken}\n />\n ))\n )\n ) : activeTab === \"defi\" ? (\n <RailPositionList positions={positions} />\n ) : activeTab === \"nfts\" ? (\n <RailNftList nfts={nfts} />\n ) : null}\n </div>\n </div>\n </section>\n );\n}\n\nfunction DashboardWindowButton({\n window,\n active,\n onSelect,\n}: {\n window: DashboardWindow;\n active: boolean;\n onSelect: (window: DashboardWindow) => void;\n}) {\n const { ref, agentProps } = useAgentElement<HTMLButtonElement>({\n id: `pnl-window-${window}`,\n role: \"tab\",\n label: `P&L window ${window}`,\n group: \"pnl-window\",\n status: active ? \"active\" : \"inactive\",\n description: `Show profit and loss over the ${window} window`,\n });\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n \"px-2 py-1.5 text-xs font-medium transition-colors\",\n active ? \"text-accent\" : \"text-muted hover:text-txt\",\n )}\n onClick={() => onSelect(window)}\n aria-current={active ? \"true\" : undefined}\n {...agentProps}\n >\n {window}\n </button>\n );\n}\n\nfunction DashboardSection({\n title,\n icon: Icon,\n action,\n children,\n}: {\n title: string;\n icon: LucideIcon;\n action?: ReactNode;\n children: ReactNode;\n}) {\n return (\n <section className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-txt\">\n <Icon className=\"h-4 w-4 text-accent\" />\n {title}\n </div>\n {action}\n </div>\n {children}\n </section>\n );\n}\n\nfunction ActivityLog({\n profile,\n events,\n}: {\n profile: WalletTradingProfileResponse | null;\n events: ActivityEvent[];\n}) {\n const entries = useMemo(\n () => walletTimelineEntries({ profile, events }),\n [events, profile],\n );\n\n if (entries.length === 0) {\n return <EmptyState icon={Activity} title=\"None\" />;\n }\n\n return (\n <div className=\"space-y-2\">\n {entries.map((entry) => {\n const toneClass =\n entry.tone === \"ok\"\n ? \"bg-ok/10 text-ok\"\n : entry.tone === \"warn\"\n ? \"bg-warn/10 text-warn\"\n : entry.tone === \"danger\"\n ? \"bg-danger/10 text-danger\"\n : \"bg-bg/55 text-muted\";\n const body = (\n <div className=\"flex min-w-0 items-center gap-3 px-2 py-2 text-sm transition-colors hover:bg-bg-muted/20\">\n <span\n className={cn(\n \"flex h-8 w-8 shrink-0 items-center justify-center\",\n toneClass,\n )}\n >\n <entry.icon className=\"h-4 w-4\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium text-txt\">\n {entry.title}\n </span>\n {entry.detail ? (\n <span className=\"block truncate text-xs-tight text-muted\">\n {entry.detail}\n </span>\n ) : null}\n </span>\n <span className=\"shrink-0 text-[0.68rem] font-medium text-muted\">\n {formatRelativeTimestamp(entry.timestamp)}\n </span>\n </div>\n );\n\n if (entry.href) {\n return (\n <a\n key={entry.id}\n href={entry.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {body}\n </a>\n );\n }\n\n return <div key={entry.id}>{body}</div>;\n })}\n </div>\n );\n}\n\nfunction NftPreview({ nfts }: { nfts: NftItem[] }) {\n const visible = nfts.slice(0, 6);\n\n if (visible.length === 0) {\n return <EmptyState icon={ImageIcon} title=\"None\" />;\n }\n\n return (\n <div className=\"grid grid-cols-2 gap-3 md:grid-cols-3\">\n {visible.map((nft) => (\n <div\n key={`${nft.chain}:${nft.collectionName}:${nft.name}:${nft.imageUrl}`}\n className=\"overflow-hidden\"\n >\n {nft.imageUrl ? (\n <img\n src={nft.imageUrl}\n alt={nft.name}\n className=\"aspect-square w-full object-cover\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex aspect-square items-center justify-center\">\n <ImageIcon className=\"h-5 w-5 text-muted\" />\n </div>\n )}\n <div className=\"min-w-0 p-2\">\n <div className=\"truncate text-xs font-medium text-txt\">\n {nft.name}\n </div>\n <div className=\"truncate text-[0.68rem] text-muted\">\n {nft.collectionName}\n </div>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction LpPositionsPanel({\n positions,\n}: {\n positions: InventoryPositionAsset[];\n}) {\n if (positions.length === 0) {\n return <EmptyState icon={Layers3} title=\"None\" />;\n }\n\n return (\n <div className=\"grid gap-1\">\n {positions.map((position) => (\n <div\n key={position.id}\n className=\"flex min-w-0 items-center gap-3 px-2 py-2 transition-colors hover:bg-bg-muted/20\"\n >\n {position.imageUrl ? (\n <img\n src={position.imageUrl}\n alt={position.label}\n className=\"h-10 w-10 shrink-0 object-cover\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center\">\n {position.kind === \"nft\" ? (\n <ImageIcon className=\"h-4 w-4 text-muted\" />\n ) : (\n <Layers3 className=\"h-4 w-4 text-muted\" />\n )}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-txt\">\n {position.label}\n </div>\n <div className=\"truncate text-xs-tight text-muted\">\n {position.detail}\n </div>\n </div>\n {position.valueUsd !== null && position.valueUsd > 0 ? (\n <div className=\"shrink-0 font-mono text-sm font-semibold text-txt\">\n {formatUsd(position.valueUsd)}\n </div>\n ) : null}\n </div>\n ))}\n </div>\n );\n}\n\nexport function InventoryAppView() {\n const {\n walletEnabled,\n walletAddresses,\n walletConfig,\n walletBalances,\n walletNfts,\n walletLoading,\n walletNftsLoading,\n walletError,\n loadWalletConfig,\n loadBalances,\n loadNfts,\n setState,\n setTab,\n setActionNotice,\n } = useAppSelectorShallow((s) => ({\n walletEnabled: s.walletEnabled,\n walletAddresses: s.walletAddresses,\n walletConfig: s.walletConfig,\n walletBalances: s.walletBalances,\n walletNfts: s.walletNfts,\n walletLoading: s.walletLoading,\n walletNftsLoading: s.walletNftsLoading,\n walletError: s.walletError,\n loadWalletConfig: s.loadWalletConfig,\n loadBalances: s.loadBalances,\n loadNfts: s.loadNfts,\n setState: s.setState,\n setTab: s.setTab,\n setActionNotice: s.setActionNotice,\n }));\n const { events: activityEvents } = useActivityEvents();\n const [hiddenTokenIds, setHiddenTokenIds] = useState<Set<string>>(() =>\n readHiddenTokenIds(),\n );\n const [dashboardWindow, setDashboardWindow] =\n useState<DashboardWindow>(\"30d\");\n const [tradingProfile, setTradingProfile] =\n useState<WalletTradingProfileResponse | null>(null);\n const [tradingProfileLoading, setTradingProfileLoading] = useState(false);\n const [tradingProfileError, setTradingProfileError] = useState<string | null>(\n null,\n );\n const [marketOverview, setMarketOverview] =\n useState<WalletMarketOverviewResponse | null>(null);\n const [marketOverviewLoading, setMarketOverviewLoading] = useState(false);\n const initialLoadRef = useRef(false);\n const tradingProfileRequestRef = useRef(0);\n const marketOverviewRequestRef = useRef(0);\n\n const loadTradingProfile = useCallback(async () => {\n const requestId = tradingProfileRequestRef.current + 1;\n tradingProfileRequestRef.current = requestId;\n setTradingProfileLoading(true);\n setTradingProfileError(null);\n\n try {\n const profile = await client.getWalletTradingProfile(\n tradingProfileWindow(dashboardWindow),\n );\n if (tradingProfileRequestRef.current === requestId) {\n setTradingProfile(profile);\n }\n } catch (cause) {\n const message =\n cause instanceof Error && cause.message.trim().length > 0\n ? cause.message.trim()\n : \"Failed to load trading profile.\";\n if (tradingProfileRequestRef.current === requestId) {\n setTradingProfile(null);\n setTradingProfileError(message);\n }\n } finally {\n if (tradingProfileRequestRef.current === requestId) {\n setTradingProfileLoading(false);\n }\n }\n }, [dashboardWindow]);\n\n const loadMarketOverview = useCallback(async () => {\n const requestId = marketOverviewRequestRef.current + 1;\n marketOverviewRequestRef.current = requestId;\n setMarketOverviewLoading(true);\n\n try {\n const overview = await client.getWalletMarketOverview();\n if (marketOverviewRequestRef.current === requestId) {\n setMarketOverview(overview);\n }\n } catch {\n // Market overview is an optional capability — when the feed is\n // unavailable the empty-wallet hero simply omits the market panels\n // rather than surfacing an error.\n if (marketOverviewRequestRef.current === requestId) {\n setMarketOverview(null);\n }\n } finally {\n if (marketOverviewRequestRef.current === requestId) {\n setMarketOverviewLoading(false);\n }\n }\n }, []);\n\n useEffect(() => {\n if (initialLoadRef.current) return;\n initialLoadRef.current = true;\n void loadWalletConfig();\n void loadMarketOverview();\n if (walletEnabled === false) return;\n void loadBalances();\n void loadNfts();\n }, [\n loadBalances,\n loadMarketOverview,\n loadNfts,\n loadWalletConfig,\n walletEnabled,\n ]);\n\n useEffect(() => {\n void loadTradingProfile();\n }, [loadTradingProfile]);\n\n // No manual refresh control: keep balances, NFTs, trading profile, and\n // market data fresh with a quiet background poll while the view is mounted.\n useEffect(() => {\n if (walletEnabled === false) return;\n const interval = window.setInterval(() => {\n void loadWalletConfig();\n void loadBalances();\n void loadNfts();\n void loadTradingProfile();\n void loadMarketOverview();\n }, WALLET_REFRESH_INTERVAL_MS);\n return () => window.clearInterval(interval);\n }, [\n loadBalances,\n loadMarketOverview,\n loadNfts,\n loadTradingProfile,\n loadWalletConfig,\n walletEnabled,\n ]);\n\n const inventoryData = useInventoryData({\n walletBalances,\n walletAddresses,\n walletConfig,\n walletNfts,\n inventorySort: \"value\",\n inventorySortDirection: \"desc\",\n inventoryChainFilters: ALL_INVENTORY_FILTERS,\n });\n\n const addresses = useMemo(\n () => resolveWalletAddresses({ walletAddresses, walletConfig }),\n [walletAddresses, walletConfig],\n );\n\n const visibleAssetRows = useMemo(\n () => inventoryData.tokenRowsAllChains.filter(tokenHasInventory),\n [inventoryData.tokenRowsAllChains],\n );\n const displayedAssetRows = useMemo(\n () => visibleAssetRows.filter((row) => !hiddenTokenIds.has(tokenId(row))),\n [hiddenTokenIds, visibleAssetRows],\n );\n const lpPositions = useMemo(\n () =>\n deriveInventoryPositionAssets({\n tokenRows: displayedAssetRows,\n nfts: inventoryData.allNfts,\n }),\n [displayedAssetRows, inventoryData.allNfts],\n );\n\n const pnlValue = parseAmount(tradingProfile?.summary.realizedPnlBnb);\n const showTradePnl = hasClosedTradePnl(tradingProfile);\n const hasWalletTimeline =\n activityEvents.length > 0 || (tradingProfile?.recentSwaps.length ?? 0) > 0;\n const showMarketPulseHero =\n walletEnabled === false ||\n (!walletLoading &&\n !walletNftsLoading &&\n !tradingProfileLoading &&\n displayedAssetRows.length === 0 &&\n lpPositions.length === 0 &&\n inventoryData.allNfts.length === 0 &&\n !showTradePnl &&\n !hasWalletTimeline);\n\n const handleHideToken = useCallback(\n (row: TokenRow) => {\n const next = new Set(hiddenTokenIds);\n next.add(tokenId(row));\n setHiddenTokenIds(next);\n writeHiddenTokenIds(next);\n setActionNotice(`${row.symbol} hidden from this wallet view.`);\n },\n [hiddenTokenIds, setActionNotice],\n );\n\n const handleOpenRpcSettings = useCallback(() => {\n setTab(\"settings\");\n if (typeof window !== \"undefined\") {\n window.location.hash = \"wallet-rpc\";\n }\n }, [setTab]);\n\n const handleEnableWallet = useCallback(() => {\n setState(\"walletEnabled\", true);\n void loadWalletConfig();\n void loadBalances();\n void loadNfts();\n }, [loadBalances, loadNfts, loadWalletConfig, setState]);\n\n return (\n <main\n data-testid=\"wallet-shell\"\n className=\"h-full min-h-0 w-full overflow-y-auto bg-bg\"\n >\n <div className=\"mx-auto flex w-full max-w-4xl flex-col gap-6 px-5 pt-6 pb-28\">\n {walletError ? (\n <div className=\"px-1 py-2 text-sm text-danger\">{walletError}</div>\n ) : null}\n\n <WalletHoldingsSection\n rows={visibleAssetRows}\n nfts={inventoryData.allNfts}\n positions={lpPositions}\n addresses={addresses}\n hiddenTokenIds={hiddenTokenIds}\n walletConfig={walletConfig}\n profile={tradingProfile}\n onHideToken={handleHideToken}\n onOpenRpcSettings={handleOpenRpcSettings}\n walletEnabled={walletEnabled}\n onEnableWallet={handleEnableWallet}\n />\n\n {showMarketPulseHero ? (\n <MarketPulseHero\n overview={marketOverview}\n loading={marketOverviewLoading}\n hasKeys={\n addresses.evmAddress !== null || addresses.solanaAddress !== null\n }\n onConfigureKeys={handleOpenRpcSettings}\n />\n ) : null}\n\n {!showMarketPulseHero ? (\n <div className=\"flex flex-col gap-8\">\n <DashboardSection\n title=\"P&L\"\n icon={BarChart3}\n action={\n <div className=\"flex gap-1\">\n {DASHBOARD_WINDOWS.map((window) => (\n <DashboardWindowButton\n key={window}\n window={window}\n active={dashboardWindow === window}\n onSelect={setDashboardWindow}\n />\n ))}\n </div>\n }\n >\n {(showTradePnl && pnlValue !== null) ||\n displayedAssetRows.length > 0 ? (\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n {showTradePnl && pnlValue !== null ? (\n <SummaryChip\n icon={pnlValue >= 0 ? TrendingUp : TrendingDown}\n value={`${pnlValue > 0 ? \"+\" : \"\"}${formatBnb(tradingProfile?.summary.realizedPnlBnb)}`}\n tone={pnlValue >= 0 ? \"gain\" : \"loss\"}\n title=\"Realized P&L\"\n />\n ) : null}\n {displayedAssetRows.length > 0 ? (\n <div className=\"min-w-0 flex-1\">\n <AssetAllocationStrip rows={displayedAssetRows} compact />\n </div>\n ) : null}\n </div>\n ) : null}\n <PnlChart profile={tradingProfile} />\n {tradingProfileError ? (\n <div className=\"mt-3 text-xs-tight text-danger\">\n {tradingProfileError}\n </div>\n ) : null}\n </DashboardSection>\n\n <DashboardSection title=\"Activity\" icon={Activity}>\n <ActivityLog profile={tradingProfile} events={activityEvents} />\n </DashboardSection>\n\n <DashboardSection title=\"Movers\" icon={TrendingUp}>\n <PortfolioMoversPanel\n rows={displayedAssetRows}\n profile={tradingProfile}\n marketOverview={marketOverview}\n />\n </DashboardSection>\n\n <DashboardSection title=\"LP positions\" icon={Layers3}>\n <LpPositionsPanel positions={lpPositions} />\n </DashboardSection>\n\n <DashboardSection title=\"NFTs\" icon={ImageIcon}>\n <NftPreview nfts={inventoryData.allNfts} />\n </DashboardSection>\n </div>\n ) : null}\n </div>\n </main>\n );\n}\n"],"mappings":"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","names":["window"]}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * InventorySpatialView - the wallet inventory surface authored once with the
3
+ * spatial vocabulary, so it renders correctly wherever it is displayed:
4
+ *
5
+ * - GUI / XR - mounted in `<SpatialSurface>` (DOM; XR scales up).
6
+ * - TUI - rendered to real terminal lines by the agent terminal, via
7
+ * `registerSpatialTerminalView` (see `register-terminal-view.tsx`).
8
+ *
9
+ * It is purely presentational (a snapshot + an action callback in, primitives
10
+ * out) and imports only the cross-modality primitives, so it is safe to render
11
+ * in the Node agent process where the terminal lives (no wallet RPC client or
12
+ * `@elizaos/ui` runtime hook import). The unified `InventoryView` wraps this in a
13
+ * `SpatialSurface` and owns the live data + the `onAction` dispatch.
14
+ */
15
+ /** A single token holding, pre-formatted for display. */
16
+ export interface WalletTokenRow {
17
+ id: string;
18
+ symbol: string;
19
+ chain: string;
20
+ /** Pre-formatted human balance, e.g. "1.25". */
21
+ balance: string;
22
+ /** USD value of the holding. */
23
+ valueUsd: number;
24
+ contractAddress: string | null;
25
+ logoUrl: string | null;
26
+ }
27
+ /** A single NFT, pre-formatted for display. */
28
+ export interface WalletNftRow {
29
+ id: string;
30
+ chain: string;
31
+ collectionName: string;
32
+ name: string;
33
+ imageUrl: string;
34
+ }
35
+ /** A market mover, pre-formatted for display. */
36
+ export interface WalletMarketMover {
37
+ id: string;
38
+ symbol: string;
39
+ priceUsd: number;
40
+ change24hPct: number;
41
+ }
42
+ /** A recent swap from the trading profile. */
43
+ export interface WalletRecentSwap {
44
+ id: string;
45
+ /** Display label, e.g. "BNB -> CAKE". */
46
+ pair: string;
47
+ /** Pre-formatted relative/short time. */
48
+ when: string;
49
+ }
50
+ export interface WalletAddresses {
51
+ evmAddress: string | null;
52
+ solanaAddress: string | null;
53
+ }
54
+ export interface WalletConfig {
55
+ evmBalanceReady: boolean;
56
+ solanaBalanceReady: boolean;
57
+ selectedRpcProviders: string[];
58
+ }
59
+ export interface WalletTradingProfile {
60
+ realizedPnlBnb: number;
61
+ recentSwaps: WalletRecentSwap[];
62
+ }
63
+ export interface WalletSnapshot {
64
+ portfolioValueUsd: number;
65
+ tokenRows: WalletTokenRow[];
66
+ walletNfts: WalletNftRow[];
67
+ marketMovers: WalletMarketMover[];
68
+ tradingProfile: WalletTradingProfile;
69
+ addresses: WalletAddresses;
70
+ config: WalletConfig;
71
+ /** `false` when the wallet is turned off; surfaces the Enable control. */
72
+ walletEnabled?: boolean | null;
73
+ loading?: boolean;
74
+ error?: string | null;
75
+ }
76
+ export interface InventorySpatialViewProps {
77
+ snapshot: WalletSnapshot;
78
+ /**
79
+ * Dispatched action ids: `tab:<id>`, `refresh`, `enable-wallet`,
80
+ * `rpc-settings`, `open-token:<id>`, `hide-token:<id>`, `copy-evm`,
81
+ * `copy-solana`.
82
+ */
83
+ onAction?: (action: string) => void;
84
+ }
85
+ export declare function InventorySpatialView({ snapshot, onAction, }: InventorySpatialViewProps): import("react/jsx-runtime").JSX.Element;
86
+ //# sourceMappingURL=InventorySpatialView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InventorySpatialView.d.ts","sourceRoot":"","sources":["../../src/components/InventorySpatialView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAaH,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,EAAE,oBAAoB,CAAC;IACrC,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAqCD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,GACT,EAAE,yBAAyB,2CAuO3B"}
@@ -0,0 +1,218 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import {
3
+ Button,
4
+ Card,
5
+ Divider,
6
+ HStack,
7
+ List,
8
+ Text,
9
+ VStack
10
+ } from "@elizaos/ui/spatial";
11
+ const TAB_KEYS = ["tokens", "defi", "nfts"];
12
+ function formatUsd(value) {
13
+ if (!Number.isFinite(value)) return "$0";
14
+ if (Math.abs(value) >= 1e3) {
15
+ return `$${value.toLocaleString("en-US", { maximumFractionDigits: 0 })}`;
16
+ }
17
+ return `$${value.toFixed(2)}`;
18
+ }
19
+ function shortAddress(address) {
20
+ if (!address) return "-";
21
+ if (address.length <= 12) return address;
22
+ return `${address.slice(0, 6)}..${address.slice(-4)}`;
23
+ }
24
+ function changeTone(pct) {
25
+ if (pct > 0) return "success";
26
+ if (pct < 0) return "danger";
27
+ return "muted";
28
+ }
29
+ function changeMark(pct) {
30
+ if (pct > 0) return "+";
31
+ if (pct < 0) return "-";
32
+ return ".";
33
+ }
34
+ function pnlTone(value) {
35
+ if (value > 0) return "success";
36
+ if (value < 0) return "danger";
37
+ return "muted";
38
+ }
39
+ function InventorySpatialView({
40
+ snapshot,
41
+ onAction
42
+ }) {
43
+ const dispatch = (action) => () => onAction?.(action);
44
+ const {
45
+ portfolioValueUsd,
46
+ tokenRows,
47
+ walletNfts,
48
+ marketMovers,
49
+ tradingProfile,
50
+ addresses,
51
+ config,
52
+ walletEnabled
53
+ } = snapshot;
54
+ const rpc = config.selectedRpcProviders.length > 0 ? config.selectedRpcProviders.join(", ") : "default";
55
+ return /* @__PURE__ */ jsxs(Card, { gap: 1, padding: 1, children: [
56
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
57
+ /* @__PURE__ */ jsx(Text, { style: "subheading", grow: 1, children: formatUsd(portfolioValueUsd) }),
58
+ /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", children: snapshot.loading ? "loading" : `${tokenRows.length} tokens` })
59
+ ] }),
60
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
61
+ /* @__PURE__ */ jsx(
62
+ Text,
63
+ {
64
+ style: "caption",
65
+ tone: config.evmBalanceReady ? "success" : "muted",
66
+ children: config.evmBalanceReady ? "evm-ready" : "evm-off"
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsx(
70
+ Text,
71
+ {
72
+ style: "caption",
73
+ tone: config.solanaBalanceReady ? "success" : "muted",
74
+ grow: 1,
75
+ children: config.solanaBalanceReady ? "sol-ready" : "sol-off"
76
+ }
77
+ ),
78
+ /* @__PURE__ */ jsx(
79
+ Button,
80
+ {
81
+ variant: "outline",
82
+ tone: "default",
83
+ agent: "rpc-settings",
84
+ onPress: dispatch("rpc-settings"),
85
+ children: rpc
86
+ }
87
+ )
88
+ ] }),
89
+ snapshot.error ? /* @__PURE__ */ jsx(Text, { tone: "danger", style: "caption", children: snapshot.error }) : null,
90
+ walletEnabled === false ? /* @__PURE__ */ jsx(
91
+ Button,
92
+ {
93
+ grow: 1,
94
+ agent: "enable-wallet",
95
+ onPress: dispatch("enable-wallet"),
96
+ children: "Enable wallet"
97
+ }
98
+ ) : null,
99
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, wrap: true, children: [
100
+ TAB_KEYS.map((tab) => /* @__PURE__ */ jsx(
101
+ Button,
102
+ {
103
+ variant: "outline",
104
+ tone: "default",
105
+ grow: 1,
106
+ agent: `tab-${tab}`,
107
+ onPress: dispatch(`tab:${tab}`),
108
+ children: tab
109
+ },
110
+ tab
111
+ )),
112
+ /* @__PURE__ */ jsx(Button, { agent: "refresh", onPress: dispatch("refresh"), children: "Refresh" })
113
+ ] }),
114
+ /* @__PURE__ */ jsx(Divider, { label: "tokens" }),
115
+ tokenRows.length === 0 ? /* @__PURE__ */ jsx(Text, { tone: "muted", align: "center", style: "caption", children: "None" }) : /* @__PURE__ */ jsx(List, { gap: 0, children: tokenRows.slice(0, 8).map((token) => /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
116
+ /* @__PURE__ */ jsxs(VStack, { gap: 0, grow: 1, children: [
117
+ /* @__PURE__ */ jsx(Text, { bold: true, wrap: false, children: token.symbol }),
118
+ /* @__PURE__ */ jsxs(Text, { style: "caption", tone: "muted", wrap: false, children: [
119
+ token.chain,
120
+ " ",
121
+ token.balance
122
+ ] })
123
+ ] }),
124
+ /* @__PURE__ */ jsx(Text, { wrap: false, children: formatUsd(token.valueUsd) }),
125
+ /* @__PURE__ */ jsx(
126
+ Button,
127
+ {
128
+ variant: "ghost",
129
+ tone: "default",
130
+ agent: `open-${token.id}`,
131
+ onPress: dispatch(`open-token:${token.id}`),
132
+ children: "Open"
133
+ }
134
+ ),
135
+ /* @__PURE__ */ jsx(
136
+ Button,
137
+ {
138
+ variant: "ghost",
139
+ tone: "danger",
140
+ agent: `hide-${token.id}`,
141
+ onPress: dispatch(`hide-token:${token.id}`),
142
+ children: "Hide"
143
+ }
144
+ )
145
+ ] }, token.id)) }),
146
+ /* @__PURE__ */ jsx(Divider, { label: "movers" }),
147
+ marketMovers.length === 0 ? /* @__PURE__ */ jsx(Text, { tone: "muted", align: "center", style: "caption", children: "\u2014" }) : /* @__PURE__ */ jsx(List, { gap: 0, children: marketMovers.slice(0, 5).map((mover) => /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
148
+ /* @__PURE__ */ jsx(Text, { bold: true, grow: 1, wrap: false, children: mover.symbol }),
149
+ /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", wrap: false, children: formatUsd(mover.priceUsd) }),
150
+ /* @__PURE__ */ jsxs(Text, { tone: changeTone(mover.change24hPct), wrap: false, children: [
151
+ changeMark(mover.change24hPct),
152
+ Math.abs(mover.change24hPct).toFixed(1),
153
+ "%"
154
+ ] })
155
+ ] }, mover.id)) }),
156
+ /* @__PURE__ */ jsx(Divider, { label: "pnl" }),
157
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
158
+ /* @__PURE__ */ jsx(Text, { grow: 1, children: "Realized P&L" }),
159
+ /* @__PURE__ */ jsxs(Text, { tone: pnlTone(tradingProfile.realizedPnlBnb), wrap: false, children: [
160
+ tradingProfile.realizedPnlBnb >= 0 ? "+" : "",
161
+ tradingProfile.realizedPnlBnb.toFixed(4),
162
+ " BNB"
163
+ ] })
164
+ ] }),
165
+ tradingProfile.recentSwaps.length > 0 ? /* @__PURE__ */ jsx(List, { gap: 0, children: tradingProfile.recentSwaps.slice(0, 4).map((swap) => /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
166
+ /* @__PURE__ */ jsx(Text, { grow: 1, wrap: false, children: swap.pair }),
167
+ /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", wrap: false, children: swap.when })
168
+ ] }, swap.id)) }) : null,
169
+ /* @__PURE__ */ jsx(Divider, { label: "nfts" }),
170
+ walletNfts.length === 0 ? /* @__PURE__ */ jsx(Text, { tone: "muted", align: "center", style: "caption", children: "None" }) : /* @__PURE__ */ jsx(List, { gap: 0, children: walletNfts.slice(0, 6).map((nft) => /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", agent: `nft-${nft.id}`, children: [
171
+ /* @__PURE__ */ jsx(Text, { tone: "primary", wrap: false, children: "#" }),
172
+ /* @__PURE__ */ jsxs(VStack, { gap: 0, grow: 1, children: [
173
+ /* @__PURE__ */ jsx(Text, { bold: true, wrap: false, children: nft.name }),
174
+ /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", wrap: false, children: nft.collectionName })
175
+ ] }),
176
+ /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", wrap: false, children: nft.chain })
177
+ ] }, nft.id)) }),
178
+ /* @__PURE__ */ jsx(Divider, { label: "addresses" }),
179
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
180
+ /* @__PURE__ */ jsxs(Text, { style: "caption", tone: "muted", grow: 1, wrap: false, children: [
181
+ "EVM ",
182
+ shortAddress(addresses.evmAddress)
183
+ ] }),
184
+ /* @__PURE__ */ jsx(
185
+ Button,
186
+ {
187
+ variant: "ghost",
188
+ tone: "default",
189
+ disabled: !addresses.evmAddress,
190
+ agent: "copy-evm",
191
+ onPress: dispatch("copy-evm"),
192
+ children: "Copy"
193
+ }
194
+ )
195
+ ] }),
196
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
197
+ /* @__PURE__ */ jsxs(Text, { style: "caption", tone: "muted", grow: 1, wrap: false, children: [
198
+ "SOL ",
199
+ shortAddress(addresses.solanaAddress)
200
+ ] }),
201
+ /* @__PURE__ */ jsx(
202
+ Button,
203
+ {
204
+ variant: "ghost",
205
+ tone: "default",
206
+ disabled: !addresses.solanaAddress,
207
+ agent: "copy-solana",
208
+ onPress: dispatch("copy-solana"),
209
+ children: "Copy"
210
+ }
211
+ )
212
+ ] })
213
+ ] });
214
+ }
215
+ export {
216
+ InventorySpatialView
217
+ };
218
+ //# sourceMappingURL=InventorySpatialView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/InventorySpatialView.tsx"],"sourcesContent":["/**\n * InventorySpatialView - the wallet inventory surface authored once with the\n * spatial vocabulary, so it renders correctly wherever it is displayed:\n *\n * - GUI / XR - mounted in `<SpatialSurface>` (DOM; XR scales up).\n * - TUI - rendered to real terminal lines by the agent terminal, via\n * `registerSpatialTerminalView` (see `register-terminal-view.tsx`).\n *\n * It is purely presentational (a snapshot + an action callback in, primitives\n * out) and imports only the cross-modality primitives, so it is safe to render\n * in the Node agent process where the terminal lives (no wallet RPC client or\n * `@elizaos/ui` runtime hook import). The unified `InventoryView` wraps this in a\n * `SpatialSurface` and owns the live data + the `onAction` dispatch.\n */\n\nimport {\n Button,\n Card,\n Divider,\n HStack,\n List,\n type SpatialTone,\n Text,\n VStack,\n} from \"@elizaos/ui/spatial\";\n\n/** A single token holding, pre-formatted for display. */\nexport interface WalletTokenRow {\n id: string;\n symbol: string;\n chain: string;\n /** Pre-formatted human balance, e.g. \"1.25\". */\n balance: string;\n /** USD value of the holding. */\n valueUsd: number;\n contractAddress: string | null;\n logoUrl: string | null;\n}\n\n/** A single NFT, pre-formatted for display. */\nexport interface WalletNftRow {\n id: string;\n chain: string;\n collectionName: string;\n name: string;\n imageUrl: string;\n}\n\n/** A market mover, pre-formatted for display. */\nexport interface WalletMarketMover {\n id: string;\n symbol: string;\n priceUsd: number;\n change24hPct: number;\n}\n\n/** A recent swap from the trading profile. */\nexport interface WalletRecentSwap {\n id: string;\n /** Display label, e.g. \"BNB -> CAKE\". */\n pair: string;\n /** Pre-formatted relative/short time. */\n when: string;\n}\n\nexport interface WalletAddresses {\n evmAddress: string | null;\n solanaAddress: string | null;\n}\n\nexport interface WalletConfig {\n evmBalanceReady: boolean;\n solanaBalanceReady: boolean;\n selectedRpcProviders: string[];\n}\n\nexport interface WalletTradingProfile {\n realizedPnlBnb: number;\n recentSwaps: WalletRecentSwap[];\n}\n\nexport interface WalletSnapshot {\n portfolioValueUsd: number;\n tokenRows: WalletTokenRow[];\n walletNfts: WalletNftRow[];\n marketMovers: WalletMarketMover[];\n tradingProfile: WalletTradingProfile;\n addresses: WalletAddresses;\n config: WalletConfig;\n /** `false` when the wallet is turned off; surfaces the Enable control. */\n walletEnabled?: boolean | null;\n loading?: boolean;\n error?: string | null;\n}\n\n/** Wallet sections the agent can switch between, mirroring the GUI tabs. */\nconst TAB_KEYS = [\"tokens\", \"defi\", \"nfts\"] as const;\n\nfunction formatUsd(value: number): string {\n if (!Number.isFinite(value)) return \"$0\";\n if (Math.abs(value) >= 1000) {\n return `$${value.toLocaleString(\"en-US\", { maximumFractionDigits: 0 })}`;\n }\n return `$${value.toFixed(2)}`;\n}\n\nfunction shortAddress(address: string | null): string {\n if (!address) return \"-\";\n if (address.length <= 12) return address;\n return `${address.slice(0, 6)}..${address.slice(-4)}`;\n}\n\nfunction changeTone(pct: number): SpatialTone {\n if (pct > 0) return \"success\";\n if (pct < 0) return \"danger\";\n return \"muted\";\n}\n\nfunction changeMark(pct: number): string {\n if (pct > 0) return \"+\";\n if (pct < 0) return \"-\";\n return \".\";\n}\n\nfunction pnlTone(value: number): SpatialTone {\n if (value > 0) return \"success\";\n if (value < 0) return \"danger\";\n return \"muted\";\n}\n\nexport interface InventorySpatialViewProps {\n snapshot: WalletSnapshot;\n /**\n * Dispatched action ids: `tab:<id>`, `refresh`, `enable-wallet`,\n * `rpc-settings`, `open-token:<id>`, `hide-token:<id>`, `copy-evm`,\n * `copy-solana`.\n */\n onAction?: (action: string) => void;\n}\n\nexport function InventorySpatialView({\n snapshot,\n onAction,\n}: InventorySpatialViewProps) {\n const dispatch = (action: string) => () => onAction?.(action);\n const {\n portfolioValueUsd,\n tokenRows,\n walletNfts,\n marketMovers,\n tradingProfile,\n addresses,\n config,\n walletEnabled,\n } = snapshot;\n const rpc =\n config.selectedRpcProviders.length > 0\n ? config.selectedRpcProviders.join(\", \")\n : \"default\";\n\n return (\n <Card gap={1} padding={1}>\n <HStack gap={1} align=\"center\">\n <Text style=\"subheading\" grow={1}>\n {formatUsd(portfolioValueUsd)}\n </Text>\n <Text style=\"caption\" tone=\"muted\">\n {snapshot.loading ? \"loading\" : `${tokenRows.length} tokens`}\n </Text>\n </HStack>\n\n <HStack gap={1} align=\"center\">\n <Text\n style=\"caption\"\n tone={config.evmBalanceReady ? \"success\" : \"muted\"}\n >\n {config.evmBalanceReady ? \"evm-ready\" : \"evm-off\"}\n </Text>\n <Text\n style=\"caption\"\n tone={config.solanaBalanceReady ? \"success\" : \"muted\"}\n grow={1}\n >\n {config.solanaBalanceReady ? \"sol-ready\" : \"sol-off\"}\n </Text>\n <Button\n variant=\"outline\"\n tone=\"default\"\n agent=\"rpc-settings\"\n onPress={dispatch(\"rpc-settings\")}\n >\n {rpc}\n </Button>\n </HStack>\n\n {snapshot.error ? (\n <Text tone=\"danger\" style=\"caption\">\n {snapshot.error}\n </Text>\n ) : null}\n\n {walletEnabled === false ? (\n <Button\n grow={1}\n agent=\"enable-wallet\"\n onPress={dispatch(\"enable-wallet\")}\n >\n Enable wallet\n </Button>\n ) : null}\n\n <HStack gap={1} wrap>\n {TAB_KEYS.map((tab) => (\n <Button\n key={tab}\n variant=\"outline\"\n tone=\"default\"\n grow={1}\n agent={`tab-${tab}`}\n onPress={dispatch(`tab:${tab}`)}\n >\n {tab}\n </Button>\n ))}\n <Button agent=\"refresh\" onPress={dispatch(\"refresh\")}>\n Refresh\n </Button>\n </HStack>\n\n <Divider label=\"tokens\" />\n {tokenRows.length === 0 ? (\n <Text tone=\"muted\" align=\"center\" style=\"caption\">\n None\n </Text>\n ) : (\n <List gap={0}>\n {tokenRows.slice(0, 8).map((token) => (\n <HStack key={token.id} gap={1} align=\"center\">\n <VStack gap={0} grow={1}>\n <Text bold wrap={false}>\n {token.symbol}\n </Text>\n <Text style=\"caption\" tone=\"muted\" wrap={false}>\n {token.chain} {token.balance}\n </Text>\n </VStack>\n <Text wrap={false}>{formatUsd(token.valueUsd)}</Text>\n <Button\n variant=\"ghost\"\n tone=\"default\"\n agent={`open-${token.id}`}\n onPress={dispatch(`open-token:${token.id}`)}\n >\n Open\n </Button>\n <Button\n variant=\"ghost\"\n tone=\"danger\"\n agent={`hide-${token.id}`}\n onPress={dispatch(`hide-token:${token.id}`)}\n >\n Hide\n </Button>\n </HStack>\n ))}\n </List>\n )}\n\n <Divider label=\"movers\" />\n {marketMovers.length === 0 ? (\n <Text tone=\"muted\" align=\"center\" style=\"caption\">\n —\n </Text>\n ) : (\n <List gap={0}>\n {marketMovers.slice(0, 5).map((mover) => (\n <HStack key={mover.id} gap={1} align=\"center\">\n <Text bold grow={1} wrap={false}>\n {mover.symbol}\n </Text>\n <Text style=\"caption\" tone=\"muted\" wrap={false}>\n {formatUsd(mover.priceUsd)}\n </Text>\n <Text tone={changeTone(mover.change24hPct)} wrap={false}>\n {changeMark(mover.change24hPct)}\n {Math.abs(mover.change24hPct).toFixed(1)}%\n </Text>\n </HStack>\n ))}\n </List>\n )}\n\n <Divider label=\"pnl\" />\n <HStack gap={1} align=\"center\">\n <Text grow={1}>Realized P&amp;L</Text>\n <Text tone={pnlTone(tradingProfile.realizedPnlBnb)} wrap={false}>\n {tradingProfile.realizedPnlBnb >= 0 ? \"+\" : \"\"}\n {tradingProfile.realizedPnlBnb.toFixed(4)} BNB\n </Text>\n </HStack>\n {tradingProfile.recentSwaps.length > 0 ? (\n <List gap={0}>\n {tradingProfile.recentSwaps.slice(0, 4).map((swap) => (\n <HStack key={swap.id} gap={1} align=\"center\">\n <Text grow={1} wrap={false}>\n {swap.pair}\n </Text>\n <Text style=\"caption\" tone=\"muted\" wrap={false}>\n {swap.when}\n </Text>\n </HStack>\n ))}\n </List>\n ) : null}\n\n <Divider label=\"nfts\" />\n {walletNfts.length === 0 ? (\n <Text tone=\"muted\" align=\"center\" style=\"caption\">\n None\n </Text>\n ) : (\n <List gap={0}>\n {walletNfts.slice(0, 6).map((nft) => (\n <HStack key={nft.id} gap={1} align=\"center\" agent={`nft-${nft.id}`}>\n <Text tone=\"primary\" wrap={false}>\n #\n </Text>\n <VStack gap={0} grow={1}>\n <Text bold wrap={false}>\n {nft.name}\n </Text>\n <Text style=\"caption\" tone=\"muted\" wrap={false}>\n {nft.collectionName}\n </Text>\n </VStack>\n <Text style=\"caption\" tone=\"muted\" wrap={false}>\n {nft.chain}\n </Text>\n </HStack>\n ))}\n </List>\n )}\n\n <Divider label=\"addresses\" />\n <HStack gap={1} align=\"center\">\n <Text style=\"caption\" tone=\"muted\" grow={1} wrap={false}>\n EVM {shortAddress(addresses.evmAddress)}\n </Text>\n <Button\n variant=\"ghost\"\n tone=\"default\"\n disabled={!addresses.evmAddress}\n agent=\"copy-evm\"\n onPress={dispatch(\"copy-evm\")}\n >\n Copy\n </Button>\n </HStack>\n <HStack gap={1} align=\"center\">\n <Text style=\"caption\" tone=\"muted\" grow={1} wrap={false}>\n SOL {shortAddress(addresses.solanaAddress)}\n </Text>\n <Button\n variant=\"ghost\"\n tone=\"default\"\n disabled={!addresses.solanaAddress}\n agent=\"copy-solana\"\n onPress={dispatch(\"copy-solana\")}\n >\n Copy\n </Button>\n </HStack>\n </Card>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,15 @@
1
+ export { useWalletState } from "@elizaos/ui/state";
2
+ export { InventoryView } from "./InventoryView.tsx";
3
+ export { InventoryAppView } from "./components/InventoryAppView.tsx";
4
+ export { ChainIcon } from "./inventory/ChainIcon.tsx";
5
+ export { CHAIN_CONFIGS, type ChainConfig, type ChainKey, chainKeyToWalletRpcChain, getChainConfig, getContractLogoUrl, getExplorerTokenUrl, getExplorerTxUrl, getNativeLogoUrl, getStablecoinAddress, PRIMARY_CHAIN_KEYS, resolveChainKey, } from "./inventory/chainConfig.ts";
6
+ export { BSC_GAS_READY_THRESHOLD, BSC_GAS_THRESHOLD, HEX_ADDRESS_RE, isAvaxChainName, isBscChainName, type NftItem, type TokenRow, toNormalizedAddress, } from "./inventory/constants.ts";
7
+ export { TokenLogo } from "./inventory/TokenLogo.tsx";
8
+ export { useInventoryData } from "./inventory/useInventoryData.ts";
9
+ export { walletAppPlugin } from "./plugin.ts";
10
+ export * from "./register.ts";
11
+ export * from "./ui.ts";
12
+ export { buildWalletRpcUpdateRequest, resolveInitialWalletRpcSelections, } from "./wallet-rpc.ts";
13
+ export { WALLET_STATUS_WIDGET } from "./widgets/wallet-status.helpers.ts";
14
+ export { WalletStatusSidebarWidget } from "./widgets/wallet-status.tsx";
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EACL,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,wBAAwB,EACxB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,GAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,cAAc,EACd,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC"}