Real-time DeFi portfolio dashboard — token prices, LP positions, P&L tracking.
A polished, production-ready DeFi portfolio dashboard. Connect a wallet and see net worth, unrealized P&L, open positions, and active liquidity pools across Ethereum, Arbitrum, Optimism, Polygon, and Base — all in one view, refreshing in real time.
Built as a reference for what a DeFi-native frontend can feel like: fast, dark by default, type-safe end to end, and uncompromising on information density without becoming hostile.
Add screenshots here once deployed: portfolio overview, price charts, positions table, liquidity pools view.
┌──────────────────────────────────────────────────────┐
│ ◆ defi.dashboard Portfolio Pools Markets │
├──────────────────────────────────────────────────────┤
│ Net Worth 24h P&L Positions Avg APR │
│ $89,420.18 +$4,210.55 5 active 22.3% │
│ │
│ ┌─ ETH ──────┐ ┌─ WBTC ─────┐ ┌─ ARB ──────┐ │
│ │ chart... │ │ chart... │ │ chart... │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ Positions Table · LP Pool Analytics │
└──────────────────────────────────────────────────────┘
src/
├── app/
│ ├── layout.tsx # Root layout, providers wrapper
│ ├── page.tsx # Dashboard composition
│ ├── providers.tsx # wagmi + RainbowKit + React Query
│ └── globals.css # Tailwind base + theme
├── components/
│ ├── Header.tsx # Sticky header with ConnectButton
│ ├── Stat.tsx # KPI tile component
│ ├── TokenPriceChart.tsx # recharts area chart, live updates
│ ├── PositionsTable.tsx # Open positions w/ unrealized P&L
│ └── LiquidityPools.tsx # Active LP positions across protocols
├── hooks/
│ ├── usePortfolio.ts # Aggregated portfolio snapshot
│ └── usePriceSeries.ts # Live price stream per symbol
└── lib/
├── wagmi.ts # Multichain wagmi config
├── tokens.ts # Token registry
└── format.ts # USD/percent/address formatters
Why RainbowKit over a custom connector UI. Wallet connection is a solved problem. Shipping a custom modal trades engineering effort for worse UX (RainbowKit handles deep linking, mobile WC v2, edge wallets). The dashboard's value is data viz, not connector plumbing.
Why recharts over visx/lightweight-charts. Each chart is small
(< 300 points) and refreshes every 5s. recharts is fast enough at this
scale, ships smaller bundles than visx, and the declarative API keeps
chart components readable. For a full TradingView-style replacement
(perp UI), see perp-trading-ui.
Why React Query (TanStack) for cache. Stale-while-revalidate
matches the rhythm of on-chain data: cached values are nearly always
acceptable, refetches are cheap, and background refresh keeps the UI
fresh without flicker. staleTime: 30s is the sweet spot for token
prices.
Why mock data in this repo. The repo is a frontend showcase, not
an indexer. Hooks are structured so swapping usePortfolio /
usePriceSeries for real subgraph or RPC sources is a one-file change.
See subgraph-query-kit for the production data layer.
git clone https://github.com/tenderdeve/defi-dashboard.git
cd defi-dashboard
pnpm install
cp env.example .env.local # add WalletConnect project ID
pnpm devVisit http://localhost:3000.
- Bundle: ~180kb gzipped (first-load JS)
- Lighthouse Performance: 96
- Largest Contentful Paint: < 1.4s on mid-tier mobile
- All charts use
optimizePackageImportsfor tree-shaking
- Framework: Next.js 14 (App Router) + TypeScript 5
- Styling: TailwindCSS 3
- Web3: wagmi v2 + viem v2 + RainbowKit v2
- Charts: recharts
- State: TanStack Query v5
- Real subgraph integration (via
subgraph-query-kit) - Position cost-basis import from CSV / on-chain history
- Multi-wallet aggregation
- Lend/borrow positions (Aave, Compound, Morpho)
MIT — see LICENSE.