Note
This is an earlier version — the build I run now is drastically improved. The public one is a bit more expensive to run, since it leans on the RPC for real-time coverage. Making it cheaper is an infra change, not a logic one — ask Claude to move discovery and grading to polled Helius RPC, and keep LaserStream / WebSocket for only the coins you want live.
Real-time pump.fun token discovery. Lily watches the chain and surfaces coins side by side, filtered by transparent on-chain quality gates — so you spend time on interesting coins instead of scrolling past obvious rugs.
It is a discovery board only. No trading, no wallet connection, no order placement, no financial advice anywhere in this repo.
┌────────────────────┬────────────────────┬────────────────────┐
│ Old pre-bond │ New pairs │ Bonded │
│ │ │ │
│ older, un-bonded │ fresh launches, │ freshly graduated │
│ coins that just │ gated live for │ coins, gated for │
│ took fresh bids │ bundles / rug │ bundles / rug │
│ again │ holders / dumps │ holders / dumps │
└────────────────────┴────────────────────┴────────────────────┘
New pairs and Bonded share one gate pipeline, and each coin flows through three mutually-exclusive states — Unchecked → Blocked → Tradable.
Most coins die young. Once in a while an older coin that never bonded starts taking bids again. Lily lists tokens that are old enough, still un-bonded, and have logged a burst of recent on-chain activity (measured with a key-less RPC signature probe).
Brand-new pump.fun launches, tracked live on their pre-bond trade tape. Launches are a firehose, so cost is bounded: Lily caps how many it watches at once and only spends RPC gating coins that show real traction. Survivors run the same gates as Bonded. A coin leaves this column when it bonds (it then appears in Bonded).
Coins that bond (migrate to an AMM) are tracked live for market cap, all-time high
and drawdown, and gated for bundles, rug holders (whale-float /
creator-retention), early dumps (deeply negative first-minute return and net
flow), and craters. Three tabs reflect each coin's state — Unchecked
(pending), Blocked (tripped a gate), Tradable (passed every gate). Gate
thresholds live in
discovery/lib/gates.mjs as documented, tunable
constants — verify them on your own data.
Each row shows accurate, on-chain-derived stats only: USD market cap, volume, TX count, age, dev (creator) %, top-10 holder concentration, and the gate verdict.
discovery/
lib/ config · PumpPortal WS client · Solana RPC (Token-2022 safe) ·
gates · SQLite store · sol price · request metrics
old-prebond.mjs reawakened old coins -> SQLite (feed "old")
new-pairs.mjs fresh launches + gates -> SQLite (feed "new")
bonded.mjs migrations + gates -> SQLite (feed "bonded")
watchdog.mjs re-verifies Tradable coins, quarantines leaks
server/server.mjs read API (CORS, cache, optional keys, rate limit)
src/ Vite + React UI (three-column board)
Daemons persist each flush to SQLite (durable current board + ~48h history); the API reads from it. Nothing shares memory, so you can run any subset, and the board survives restarts.
cp .env.example .env # then edit — at minimum set a real SOLANA_RPC_URL
npm installA dedicated RPC provider (Helius / Triton / QuickNode) is strongly recommended —
the gates make many getSignaturesForAddress / getTokenLargestAccounts calls.
The PumpPortal data WebSocket is free and key-less. Each column header shows that
section's live API request rate so you can watch your load.
Two terminals:
npm start # API server + all four discovery daemons (auto-restart)
npm run dev # the UI at http://localhost:5174Or individually: npm run api, npm run discover:old, npm run discover:new,
npm run discover:bonded, npm run watchdog.
There is no hosted Lily service — you run the backend yourself. Once it's up it
serves precomputed JSON (CORS-open, ~2s cache, optional keys via LILY_API_KEYS,
rate-limited via RATE_LIMIT_PER_MIN):
GET /api/old reawakened old pre-bond coins
GET /api/new gated fresh launches
GET /api/bonded gated graduates
GET /api/token-meta ?mints=<comma-separated> — name / symbol / image
GET /api/watchdog last re-verification pass (quarantine, revivals)
GET /api/health liveness — the one route that skips auth + rate limit,
so host health checks work without a key
Discovery runs once on the backend, so serving the three feeds to many consumers
does not increase RPC cost — readers just read cached output. The exception is
/api/token-meta, which resolves uncached mints against the pump.fun API on
demand (capped at 25 per request).
See DEPLOY.md for Render (blueprint included), Railway, persistence
(SQLite on a volume), and serving the UI under a subpath like enrich.fun/lily.
MIT — see LICENSE. Provided as-is, for informational/educational use. Nothing here is financial advice.
