A high-performance web application to track and analyze Solana wallet holdings across multiple addresses, providing real-time portfolio valuation and PNL (Profit/Loss) analytics.
- π Portfolio Overview - Aggregated view of total assets under management
- π° Multi-Wallet Tracking - Monitor 1000+ Solana wallets simultaneously
- π PNL Analytics - Track profit/loss across time periods (24h, 7d, 30d)
- β‘ High Performance - Sub-100ms response times with SQLite caching
- π Real-time Prices - Live token prices with automatic refresh on dashboard load
- πΌοΈ Token Images - Display real token logos fetched from Jupiter Token List
- π± Modern UI - Sleek dark theme with glass morphism design
- π Detailed Views - Individual wallet and token detail pages
- Runtime: Bun - Fast all-in-one JavaScript runtime
- Framework: Hono - Lightweight web framework with JSX support
- Database: SQLite with WAL mode for concurrent reads
- Blockchain:
- Solana Web3.js - Core Solana blockchain interactions
- Helius SDK - Enhanced RPC with asset APIs
- Metaplex Foundation JS - NFT and token metadata
- @solana/spl-token - SPL token program interactions
- UI: Server-side JSX with Tailwind CSS via CDN
- Bun runtime (latest version)
- Helius RPC endpoint (required)
- Clone the repository:
git clone https://github.com/elizaOS/aum-tracker
cd aum-tracker
- Install dependencies:
bun install
- Set up environment variables:
cp .env.example .env
- Edit
.env
with your configuration:
# Required
HELIUS_RPC_URL=your_helius_rpc_endpoint_here
# Optional (defaults provided)
JUPITER_API_URL=https://lite-api.jup.ag/price/v2
JUPITER_TOKENS_API_URL=https://lite-api.jup.ag/tokens/v1
DATABASE_PATH=./data/portfolio.db
PORT=3000
Web Server Commands (API endpoints)
bun run dev # Starts development server with hot reload (port 3000)
bun run start # Starts production server (port 3000)
These start the Hono web server that serves the API endpoints.
Data Prefetch Commands (populate database)
bun run prefetch # Fetches wallet data from blockchain
bun run prefetch:force # Force refresh all wallet data
bun run prefetch:test # Test with 5 wallets
bun run prefetch:test10 # Test with 10 wallets
bun run prefetch:test-force # Test with 5 wallets + force refresh
bun run prefetch:health # Check system health
bun run db:cleanup # Database cleanup with batch processing
These run the data prefetch script that reads wallet addresses from CSV, fetches balance data from Solana blockchain, and populates the SQLite database.
Token Metadata Service (background processing)
bun run token-metadata:start # Starts continuous background service
bun run token-metadata:refresh # One-time metadata refresh
bun run token-metadata:health # Check metadata service health
bun run token-metadata:queue # Show metadata queue status
bun run token-metadata:clear # Clear metadata queue
These manage the background token metadata service that processes tokens one at a time to respect Jupiter API rate limits.
-
First time setup - Populate database with wallet data:
# Test with a few wallets first bun run prefetch:test # Then fetch all wallet data bun run prefetch
-
Start the web server:
# Development (with hot reload) bun run dev # OR Production bun run start
-
Optional: Start background metadata service (in a separate terminal):
bun run token-metadata:start
-
View the dashboard: Open http://localhost:3000
Command | Purpose | Runs Once | Continuous |
---|---|---|---|
bun run dev |
Web server with hot reload | β | β |
bun run start |
Production web server | β | β |
bun run prefetch |
Fetch wallet data | β | β |
bun run token-metadata:start |
Background metadata service | β | β |
Important: The prefetch needs to be run first to populate the database, then you can start the web server to access the API endpoints.
Build and run for production:
bun run build
bun run start
GET /api/portfolio/overview
- Aggregated portfolio statisticsGET /api/portfolio/status
- System health and data freshnessGET /api/portfolio/metrics
- Performance and error metricsGET /api/portfolio/pnl
- Combined PNL across all walletsGET /api/portfolio/pnl/timeframe/:period
- PNL for specific timeframe
GET /api/wallets/balance/:address
- Individual wallet dataPOST /api/wallets/balances
- Batch wallet dataGET /api/wallets/history/:address
- Historical balance dataGET /api/wallets/pnl/:address
- Individual wallet PNLGET /api/wallets/pnl/:address/:period
- Wallet PNL for specific timeframeGET /api/wallets/all
- All wallet balances (paginated)
GET /api/tokens/prices
- Current token pricesPOST /api/tokens/prices/refresh
- Force price refreshGET /api/tokens/aggregated
- Aggregated token holdings with real-time pricesGET /api/tokens/holders/:mint
- Get all wallets holding a specific tokenGET /api/tokens/pnl
- Top gainers and losers
POST /api/admin/refresh
- Trigger full data refreshGET /api/admin/logs
- View recent error logsPOST /api/admin/snapshot
- Create manual portfolio snapshot
GET /api/health
- Service health check
.
βββ src/
β βββ index.ts # Main server entry point
β βββ routes/
β β βββ api.ts # API route definitions
β βββ services/
β β βββ database.ts # SQLite operations
β β βββ solana.ts # Blockchain integration
β β βββ csv.ts # CSV parsing
β βββ components/
β β βββ ModernDashboard.tsx # Modern dashboard UI
β β βββ ModernLayout.tsx # Dark theme layout
β β βββ WalletDetail.tsx # Individual wallet view
β β βββ TokenDetail.tsx # Individual token view
β βββ scripts/
β βββ prefetch.ts # Data prefetching script
βββ data/
β βββ wallets.csv # Wallet addresses
β βββ portfolio.db # SQLite database (created at runtime)
βββ .gitignore
βββ CLAUDE.md # Development guidelines
βββ PRD.md # Product requirements
βββ README.md
βββ bun.lock
βββ package.json
βββ tsconfig.json
- Response Times: <100ms for cached data
- Data Freshness: Real-time price updates on dashboard load
- Rate Limits:
- Premium Helius RPC: 1000+ requests/minute
- Jupiter API: 600 requests/minute
- Batch Processing: 50 wallets per batch (optimized for premium endpoints)
- Token Metadata: Cached with images from Jupiter Token List
- Database: SQLite with WAL mode for concurrent read performance
- Caching: 5-minute cache freshness with automatic refresh
Variable | Description | Required | Default |
---|---|---|---|
HELIUS_RPC_URL |
Helius RPC endpoint | Yes | - |
JUPITER_API_URL |
Jupiter price API URL | No | https://lite-api.jup.ag/price/v2 |
JUPITER_TOKENS_API_URL |
Jupiter tokens API URL | No | https://lite-api.jup.ag/tokens/v1 |
DATABASE_PATH |
SQLite database path | No | ./data/portfolio.db |
PORT |
Server port | No | 3000 |
Note: Only HELIUS_RPC_URL
is currently required. Other environment variables are defined in .env.example
but may use hardcoded defaults in the current implementation.
All available development scripts:
# Development & Production
bun run dev # Development server with hot reload
bun run start # Production server
bun run build # Build for production
# Data Management
bun run prefetch # Fetch all wallet data
bun run prefetch:force # Force refresh all data
bun run prefetch:test # Test with 5 wallets
bun run prefetch:test10 # Test with 10 wallets
bun run prefetch:test-force # Test with 5 wallets + force refresh
bun run prefetch:health # Check system health
bun run db:cleanup # Database cleanup with batch processing
# Token Metadata Management
bun run token-metadata:start # Start continuous token metadata service
bun run token-metadata:refresh # Refresh stale metadata once
bun run token-metadata:health # Check metadata service health
bun run token-metadata:queue # Show metadata queue status
bun run token-metadata:clear # Clear metadata queue
# Testing
bun run test # Run tests (not configured yet)
See CLAUDE.md for detailed development guidelines and architecture information.
MIT