A Solana program explorer. Browse, search, and track on-chain account data with labels, favorites, and historical snapshots.
SolanaMyAdmin follows a "Lightweight Index, Heavy Client" pattern:
- Supabase stores only pubkeys, discriminators, and change hashes (lightweight index)
- Binary account data is fetched just-in-time from Solana RPC (heavy client)
- Token metadata is enriched via Birdeye API
- A gRPC streaming worker (separate service) detects real-time account changes via Triton Dragon's Mouth
Two services run in parallel:
- Next.js app -- web UI, API routes, auth
- gRPC worker -- streams account changes from Solana into Supabase
Two programs are supported (hardcoded):
| Program | Program ID | Description |
|---|---|---|
| marginfi | MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA | Production marginfi |
| marginfi-staging | stag8sTKds2h4KzjUw3zKTsxbqvT4XKHdaR9X9E6Rct | Staging marginfi |
- Node.js 18+
- pnpm
- Supabase project
- Solana RPC endpoint (e.g., Ironforge, Helius, Triton)
- Triton Dragon's Mouth gRPC subscription (for the streaming worker)
pnpm install
cd worker && pnpm install && cd ..Create .env.local in the project root:
# Supabase
NEXT_PUBLIC_SUPABASE_URL="https://xxx.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY="your-anon-key"
SUPABASE_SERVICE_ROLE_KEY="your-service-role-key"
# Solana RPC (server-side only)
RPC_URL="https://your-rpc-endpoint.com"
# Token enrichment
BIRDEYE_API_KEY="your-birdeye-key"Create worker/.env for the gRPC worker:
# Triton Dragon's Mouth gRPC
GRPC_ENDPOINT="https://your-grpc-endpoint.com"
GRPC_TOKEN="your-grpc-token"
# Supabase (service role - bypasses RLS)
SUPABASE_URL="https://xxx.supabase.co"
SUPABASE_SERVICE_ROLE_KEY="your-service-role-key"
# Optional (defaults shown)
UPDATE_BUFFER_MS="100"
MAX_CHANGES_PER_ACCOUNT="10"Run the migrations in Supabase SQL Editor:
migrations/init.sql
migrations/002_internal_tool.sql
This creates all tables, RLS policies, indexes, and helper functions.
pnpm seed-defaults # Seed default labels, favorites, and views
pnpm indexer # Index marginfi program accounts# Terminal 1: Next.js app
pnpm dev
# Terminal 2: gRPC streaming worker
cd worker && pnpm dev| Command | Description |
|---|---|
pnpm dev |
Start dev server |
pnpm build |
Production build |
pnpm start |
Start production server |
pnpm lint |
Run ESLint |
pnpm indexer |
Index marginfi program accounts |
pnpm seed-defaults |
Seed default labels/favorites/views |
| Command | Description |
|---|---|
pnpm dev |
Start worker with hot reload |
pnpm build |
Compile TypeScript |
pnpm start |
Run compiled worker |
pnpm cleanup |
Prune old account state rows |
src/
├── app/ # Next.js App Router
│ ├── api/ # API routes
│ │ ├── accounts/ # Account listing, info, history
│ │ ├── favorites/ # User favorites
│ │ ├── labels/ # User labels
│ │ ├── rpc/ # RPC proxy (account-info)
│ │ ├── search/ # Account search
│ │ ├── token-metadata/ # Birdeye token metadata
│ │ └── views/ # Saved views
│ ├── auth/ # OAuth callback
│ └── page.tsx # Main explorer page
├── components/
│ ├── ui/ # shadcn/ui primitives
│ └── *.tsx # Feature components
├── hooks/ # Custom React hooks
├── lib/
│ ├── config/ # Program and IDL configuration
│ ├── db/ # Supabase client
│ ├── solana/ # Data service
│ └── utils/ # Encoder, enricher, formatter
└── middleware.ts # Auth guard
scripts/ # Indexer and seed scripts
migrations/ # SQL schema
worker/ # Standalone gRPC streaming worker
└── src/
├── index.ts # Main loop
├── config.ts # Environment + program config
├── db.ts # Database queries
├── grpc.ts # Dragon's Mouth gRPC client
├── processor.ts # Change detection and buffering
└── cleanup.ts # History pruning job
- Google OAuth -- any Google account can sign in
- Read access is public -- anyone can browse account data
- Write operations require auth -- labels, favorites, views need sign-in
- API routes authenticate via
Authorization: Bearer <token>headers
default_labels- Labels seeded viapnpm seed-defaultsdefault_favorites- Favorites seeded viapnpm seed-defaultsdefault_views- Saved views seeded viapnpm seed-defaults
user_labels- User-created labels (override defaults)user_favorites- User-created favorites (merged with defaults)user_views- User-created saved views
account_state- Historical snapshots with composite PK(program_id, pubkey, created_at)