The meme moves first. FLETCH tells you why.
Meme tokens on Robinhood Chain launch by the thousand, and most of what "moves" is noise. FLETCH is the intelligence layer that reads the chain directly — launches, trades, holders, liquidity, deployer behavior — and turns it into three plain-English answers: what's happening, why, and whether it's worth your attention. Every number is either a real chain read or explicitly marked unavailable. Nothing here is a fabricated demo dressed up as a live product.
FLETCH is not a token screener, a trading bot, an AI chatbot, or a price predictor. There is no execution path in this repository.
A discovery feed, a risk engine, and an explanation layer, all reading the same source of truth: Pons V2 launch and trade events on Robinhood Chain.
| The problem | What FLETCH does |
|---|---|
| Hundreds of new tokens a day, most of them noise | Ranks by FLETCH Score — an explainable blend of momentum, liquidity, holders, and safety — not by market cap |
| "Is this a bundle / bot / bot-farm launch?" | Reads the launch transaction itself: dev-buy %, wallets exempted from the opening snipe tax, serial-deployer count — see docs/RISK.md |
| "Why is this moving right now?" | A templated explanation built directly from the structured numbers FLETCH computed — never a free-form model call touching raw data — see docs/SIGNALS.md |
| Dashboards that quietly fake the numbers they can't get | Smart Money and Social components render UNAVAILABLE with a stated reason instead of a plausible-looking guess — see docs/DATA.md |
| "Trust me, it's risky" | Every risk finding names its evidence — top 10 holders own 82%, not high risk |
flowchart LR
A[Robinhood Chain<br/>Pons V2 launches + trades] --> B[Data Provider]
B --> C[Risk Engine]
B --> D[Signal Detection]
C --> E[FLETCH Score]
D --> E
E --> F[AI Explanation]
C --> F
E --> G[API]
F --> G
B --> G
G --> H[Dashboard]
Full breakdown, including why the data-provider boundary exists and what it unlocks later: docs/ARCHITECTURE.md.
Real terminal output — npm run dev booting the actual API, then two real requests against it: a health check, and a malformed address. No RPC connection is configured in this capture, and FLETCH says exactly that instead of pretending otherwise. That's the whole point of the project.
FLETCH starts with the chain, not the chart.
Launches, trades, holders, liquidity, and whale activity are read directly off Robinhood Chain — not scraped, not estimated. Those reads feed a risk engine and a signal engine that run on every check, and both feed into the FLETCH Score. None of that is optional or mocked: turn off RPC_URL and the app tells you so, the way it just did above, instead of drawing a chart from nothing.
The pipeline, in order:
launch → trades → holders → liquidity → wallets → signals → risk → score
The full diagram is above, in How it works. The exact rule for each stage — what counts as a signal, what triggers a risk finding, how the score is weighted — is written down in docs/SIGNALS.md, docs/RISK.md, and docs/SCORING.md.
Point it at a live RPC endpoint and the dashboard screenshots itself: npm run screenshot (see Quick Start) captures the real, populated UI once there's real chain activity to show. Nothing here was staged with fake tokens to look more impressive.
The discovery feed scans the Pons V2 factory for every TokenLaunched event and ranks by FLETCH Score — not market cap, not recency. Age, dev-buy %, risk level, and score all come from the same real chain reads.
TOKEN AGE DEV BUY RISK FLETCH SCORE
(shape shown — see Live Data below; this repo doesn't ship fabricated rows to fill that table in.)
Details on what counts as a signal today: docs/SIGNALS.md.
Beyond the discovery feed, FLETCH runs a real signal engine (src/signals/signalEngine.ts) that detects buy/sell pressure, whale moves classified against the token's own curve address, and — once snapshot history exists — holder growth, liquidity change, price movement, activity acceleration, and phase transitions (curve → graduated). Every signal has a type, severity, confidence, exact evidence, and a plain explanation; trend signals never fire without a real previous snapshot to compare against. The dashboard's Signals tab shows the live, chain-wide feed — events worth attention, not a token list. Full breakdown: docs/SIGNALS.md.
FLETCH doesn't wait for someone to open a token page. A durable, prioritized monitoring queue (a SQLite table, survives restart) discovers new launches on a bounded scan, then checks whatever's due with bounded concurrency — new launches and tokens with recent signals get checked often, quiet ones less so. A check that fails never writes fake data: only the queue's own failure count and last error change, and a token failing repeatedly is marked FAILED and stops being scheduled, so one broken address can't retry forever. History is pruned on a retention schedule so storage stays bounded. Every real check still goes through the same signal engine and analyzeAndPersist() the API already uses — this is scheduling and bounding, not a second signal system. GET /api/monitoring shows whether it's actually running. Full breakdown, including the priority model and what's honestly not built yet: docs/MONITORING.md.
THE CHAIN MOVES FIRST. FLETCH FINDS IT.
The Tokens feed ranks by FLETCH Score. Radar ranks by something different: how much is changing right now. A token with a mediocre score can top Radar because buy pressure just accelerated, a whale just bought off the curve, and holders just started growing — all at once. That convergence is the point: one signal type firing repeatedly scores the same as it firing once, but two or three distinct kinds of signal firing together get a real multiplier. Recency matters too — a signal from two minutes ago outweighs an identical one from two hours ago, and past a 30-minute window it stops counting at all.
Risk is never hidden by momentum. Every Radar entry shows its risk level next to the score, plainly — Radar is a ranking system, not a buy signal.
Ranking needs no live chain call: candidates and scores come straight from persisted signals and snapshots (GET /api/radar). Full formula, with every constant spelled out: docs/RADAR.md.
Six components, each either a real number or an explicit null with a reason. The overall score re-weights across only the components that are actually available for a given token — a token isn't punished for Smart Money and Social not existing yet.
DEMO — illustrative shape only, not a real token's output
$ARROWCAT FLETCH SCORE 91
MOMENTUM 96 buy pressure + activity level, since launch
SMART MONEY UNAVAILABLE no cross-token wallet history store yet
HOLDERS 91 +42% since the last check (real, once history exists)
LIQUIDITY 82 curve balance, converted to USD
WHALE ACTIVITY 78 3 whale buys from the curve, no sells
SAFETY 71 inverse of the risk report
Exact formulas, weight re-normalization, and what "not yet a growth rate" means for Holder Growth: docs/SCORING.md.
Every bullet traces back to a number FLETCH already computed — buy/sell counts, holder count, liquidity, risk findings. This is deliberately not a free-form LLM call: the safest way to guarantee the brief's "AI must never invent blockchain data" rule is to never let generated text see raw numbers and write from scratch. See src/ai/explain.ts and its test file for exactly what that means in code.
DEMO — illustrative shape only
WHY IS IT MOVING?
18 buys vs 3 sells since launch
312 holders tracked (lifetime)
liquidity currently $41,800
smart-money activity: unavailable (no wallet history store yet)
RISK
[HIGH] top 10 holders own 61% of tracked supply
[MEDIUM] liquidity is $41,800 — thin
LOW / MEDIUM / HIGH / CRITICAL, never a bare "SCAM." Launch-moment checks (dev buy, bundled wallets, serial deployer) plus ongoing checks (holder concentration, liquidity depth, trend-based findings). Full threshold table and what isn't checked yet (mint permissions, blacklist functions — needs bytecode analysis, not built): docs/RISK.md.
Not implemented as real intelligence yet — and the dashboard says so, in src/wallets/smartMoney.ts and on the Wallets tab, rather than shipping a leaderboard built on nothing. Real win-rate/early-entry tracking needs either a persistence layer accumulating outcomes over weeks-to-months, or an indexer with that history already built. See docs/DATA.md for exactly what closes this gap.
chain/ (raw Robinhood Chain + Pons V2 reads) → data/ (the ChainDataProvider abstraction) → persistence/ (SQLite snapshot/signal history) + risk/ + signals/ + scoring/ + ai/ (pure, unit-tested logic where possible) → api/ (Express) → web/ (dashboard).
The ChainDataProvider interface is the seam that lets a Bitquery-backed provider (unlocks post-graduation Uniswap v4 pricing, decoded trade history, wallet tracking) get swapped in later without touching scoring, risk, or the API. The signal engine (signals/signalEngine.ts) is a pure function over metrics + risk + an optional previous snapshot — no chain calls, no DB access, fully unit-tested. Full writeup: docs/ARCHITECTURE.md.
Every command below is a real script in package.json — nothing here is invented.
git clone https://github.com/leopardracer/FLETCH.git
cd FLETCH
npm install
cp .env.example .env
# edit .env — at minimum, set RPC_URL (see .env.example for where to get one)
npm run dev
# open http://localhost:8787RPC_URL is required — there's no default baked in, on purpose (see src/core/config.ts). Full environment variable reference and what each optional one unlocks: docs/DEVELOPMENT.md.
FLETCH reads Robinhood Chain directly — no seed data, no fixtures shipped in the repo. What's real today versus what's unavailable and why: docs/DATA.md. Short version:
Real: new-token discovery, launch risk signals, holder counts + whale moves, pre-graduation liquidity/price, buy/sell activity, FLETCH Score (Momentum/Liquidity/Holder Growth/Whale Activity/Safety), risk levels with evidence, persisted snapshot + signal history, trend-based signals and risk findings once history exists.
Explicitly unavailable, not faked: post-graduation (Uniswap v4) pricing, Smart Money win-rate/PnL (the participation record is real; PnL isn't — see docs/DATA.md), Social signal.
Every DEMO-labeled block above is illustrative shape, not real output — this repo doesn't ship a screenshot gallery built from fabricated tokens. To see real output: run Quick Start against a live RPC_URL, or generate real dashboard screenshots yourself with npm run screenshot (needs Playwright — see scripts/screenshot.mjs for why that's a separate install rather than a project dependency).
FLETCH's test suite covers the parts of the product where correctness actually matters: every FLETCH Score formula, every risk-finding threshold, every signal type the signal engine can emit, the persistence layer that backs all of it, and the API surface end-to-end over real HTTP. All of it runs deterministically — no live RPC calls, no real database file, no wall-clock timing — using Node's built-in test runner and node:sqlite's in-memory mode, so a run is exact and reproducible every time.
npm testtests 182
pass 182
fail 0
npm run test:coverageall files | 79.79 | 81.28 | 71.96 |
79.79% line coverage on real application code (test files themselves excluded from that number). Core business logic — signal detection, risk analysis, scoring, persistence, wallet intelligence, the "why is it moving" explainer — sits at 90–100%. The lower spots are chain/*.ts and data/providers/rpcProvider.ts, which genuinely need a live RPC connection to exercise meaningfully; per this project's own rule against fabricating chain data, those aren't mocked into a false 100%. See docs/DEVELOPMENT.md for the full breakdown and the reasoning file by file.
npm run test:integration # the two test files that exercise multiple layers together —
# chain metrics → risk → score → signals → persistence, and a
# real Express app over real HTTP
npm run test:watch # re-runs on every change to the compiled outputSetup, environment variables, and the current next-steps list: docs/DEVELOPMENT.md.
npm run devType-checks, builds, and starts the API + dashboard. npm run build does the first two only.
Priority order, detailed in docs/DEVELOPMENT.md:
- Verify the Blockscout provider against a live API key; wire it into the feed to cut per-token RPC round-trips
- Thread each token's launch timestamp into the signal engine so activity acceleration compares against a true baseline, not just the last snapshot
- Evaluate Bitquery for Uniswap v4 pricing and decoded trade history — a provider swap, not a rewrite
- Record price-at-trade in wallet activity — the specific piece blocking real Smart Money PnL/win-rate
- Decide on a social data source, or keep it honestly unavailable
- Wallet-clustering detection off existing transfer data
- Batch per-launch RPC calls in the feed endpoint via multicall
| Source | What was used |
|---|---|
| docs.robinhood.com/chain | RPC endpoint, chain ID, network model |
| Bitquery's Pons launchpad docs | cross-verification for the Pons V2 contract addresses and event signatures |
| Blockscout | official Robinhood Chain explorer; optional holder-count acceleration API |
FLETCH is independent of Pons and Robinhood, refers to the network as "Robinhood Chain," and uses none of their marks.
MIT — see LICENSE.


