A Solana-first crypto news terminal: a 3D globe plots live news at the real-world location of the entity involved, a horizontal instrument strip streams live Solana network vitals and SOL/ETH/BTC prices, and a synced feed panel runs down the side. "Mission Control" aesthetic — inspired by plotted.live, pushed well past it on polish and data depth.
- Live Solana network vitals — real TPS (from non-vote transactions) with a sparkline, epoch progress, and slot height, straight from the free public Solana RPC.
- Live price strip — SOL/ETH/BTC spot + 24h change (CoinGecko), SOL weighted first.
- 3D dark globe (maplibre-gl) — auto-rotating, draggable, category-colored event markers. Overlapping pins are automatically dispersed so nothing stacks into a smear.
- Click a marker → popup with full story info (headline, source, chain, sentiment, time, link). Closes on outside click or globe interaction.
- Live feed panel — the same events, selection synced both ways with the globe, "New" flash on fresh arrivals, live/sample badge.
- Floating filters — glass control cluster over the globe; toggle by chain (SOL / ETH / BTC / OTHER) and category (REGULATORY / MARKET / SECURITY / INSTITUTIONAL / ON-CHAIN / DEFI).
- Solana-first, zero cost, no keys — server-side RSS ingestion (Solana-tagged + CoinDesk / CoinTelegraph / Decrypt / The Block), classified into category/chain/sentiment, Solana ecosystem projects recognized as SOL, a guaranteed floor of Solana stories, deduped, 60 events, edge-cached. Falls back to a mock dataset if every source fails, so the UI never goes empty.
- Next.js 16 (App Router, Turbopack) + TypeScript
- Tailwind CSS 4 — Archivo (UI), Geist Mono (numerals), Instrument Serif (wordmark)
- maplibre-gl (globe projection) + Framer Motion (feed animations)
- fast-xml-parser (RSS parsing)
- Data: Solana public RPC + CoinGecko + free crypto RSS — all keyless
Note on the public RPC:
api.mainnet-beta.solana.comand CoinGecko's free tier are rate-limited and not meant for production traffic. Server-side edge caching (15s vitals / 60s prices) keeps one deployment well under the limits; swapping in a Helius RPC URL later is a one-line change inlib/solana.ts.
npm install
npm run devOpen http://localhost:3000. The news feed works immediately — no API keys or .env required.
src/
app/
api/news/route.ts # RSS ingestion + pin de-collision (falls back to mock)
api/vitals/route.ts # Solana network vitals (TPS, epoch, slot)
api/prices/route.ts # SOL/ETH/BTC prices
page.tsx # HUD shell: polling, filter state, globe↔feed sync
components/
CommandBar.tsx # logo, wordmark, live clock, slot readout
StatsStrip.tsx # SOL/ETH/BTC + TPS + epoch instrument strip
Sparkline.tsx / EpochBar.tsx # pure-SVG chart primitives
GlobeView.tsx # maplibre globe, markers, popup lifecycle
NewsPopupCard.tsx # marker-click popup content
FeedPanel.tsx / FeedItem.tsx # live feed side panel
FilterCluster.tsx # floating glass chain/category filters
lib/
solana.ts # Solana RPC → network vitals (TPS from non-vote txns)
prices.ts # CoinGecko → SOL/ETH/BTC quotes
rss.ts # feed fetch + classify + Solana floor + safe-URL filter
geo.ts # headline → coordinates + collision dispersal
format.ts / theme.ts / time.ts / types.ts
data/mockNews.ts # fallback dataset, same shape as live data
GET /api/news fetches the RSS feeds server-side in parallel (Promise.allSettled, one failing feed doesn't break the rest), classifies each item's category/chain/sentiment from its headline, reserves a floor of Solana stories, resolves a map location (known entity/regulator/exchange/protocol HQ, or a chain-level anchor as fallback), disperses any colliding coordinates, and validates each link's URL scheme before it's ever rendered as a clickable href.
GET /api/vitals and GET /api/prices fetch the Solana RPC and CoinGecko server-side and are edge-cached (15s / 60s). Every field is null-safe, so a throttled upstream degrades to an em dash in the strip rather than breaking the page. The client polls news every 30s, vitals every 15s, prices every 60s.
Works on Vercel's free tier with zero configuration — every feed re-fetches server-side per request (edge-cached), so no cron job or persistent server is needed to keep it "live." Set NEXT_PUBLIC_SITE_URL to your deployed origin so Open Graph/social image URLs resolve.
Real data: free keyless sources only — Solana public RPC, CoinGecko, and crypto RSS. CryptoPanic / Firecrawl / Helius on-chain feeds remain mocked pending API keys. See CHANGELOG.md for version history.