Inspiration

Thousands of BSC memecoins die quietly: liquidity vanishes, holders drift away, the dev wallet empties — and nobody writes the obituary. CryptKeeper is a graveyard monitor that examines dead and dying tokens, determines a cause of death, and presents each verdict as a tombstone: the label, the exact evidence numbers that produced it, and a short autopsy with a one-line epitaph.

What it does

Causes of death:

  • RUG_PULL — liquidity drained suddenly and insiders exited, or sells blocked/taxed ~100% while the dev exited.
  • SLOW_BLEED — liquidity and holders eroded gradually; still trading, nobody pronounced it dead.
  • ABANDONED — no trades for a long time and holders collapsed, but no insider-exit evidence — the dev simply walked away.
  • DORMANT_ALIVE — quiet but healthy — not dead, just sleeping.

How we built it

(1) The feed (cryptkeeper/feed.py) pulls real data for real BSC tokens from free, read-only, key-less sources and normalises it into one fixed input shape: DexScreener (best BSC pair: liquidity now, transaction counts), GeckoTerminal (daily OHLCV to age the last trade), raw BSC RPC (LP-token burn share — ≥90% burned proves the LP was NOT removed), and honeypot.is (sell blocked / sell-tax simulation). Every field carries written provenance. Fields no free public source can provide — peak liquidity, holder counts, dev-wallet share — are left UNKNOWN, never guessed.

(2) The coroner (cryptkeeper/classifier.py) is a deterministic, pure rule engine — no network, no clock, no randomness, no language model. Every verdict ships with the evidence object that produced it; unknown evidence can never fire a rule — the verdict degrades to low confidence with the exact list of missing evidence.

(3) The narrator (cryptkeeper/narrator.py) writes the story the classifier certified — a 3–6 sentence autopsy plus a one-line epitaph — using deterministic templates that contain no literal digits at all: every number printed is a formatted evidence value.

(4) The dashboard (web/) is a static single page rendering tombstone cards with a Fixtures | Live toggle, confidence badges and per-card missing-evidence lists.

The honest first live round (2026-11-14)

9 real tokens examined (CAKE and BabyDoge as alive controls; FEG, SQUID, PIT, HERO, RACA, POOCOIN, SAFEMARS as the graveyard set) — all nine came back DORMANT_ALIVE at low confidence. That is the design working, not failing: every candidate had still traded within 24 hours (even SQUID, the 2021 rug — its residual pool still sees ~41 transactions a day), and certifying a historical cause of death needs peak-liquidity, holder and dev-wallet history that free data does not provide. The coroner can certify present silence; he will not fake an autopsy.

The Frankenstein stitch

BSC on-chain data (LP burn share via raw RPC) + DexScreener and GeckoTerminal APIs (two independent aggregators, cross-checked — a "no pair" claim is never made from one endpoint alone) + honeypot.is sell simulation + a deterministic coroner with an evidence-bound narrator bolted on as the voice. Each part covers another part's blind spot; the seams are deliberate: provenance per field, unknowns labelled, confidence graded.

How Kiro was used

The project was built spec-first with Kiro, and the /.kiro/ directory in the repo is the working record. Specs (.kiro/specs/cryptkeeper/): requirements.md (the four labels, rule order, evidence and honesty constraints as acceptance criteria), design.md (classifier contract: a pure classify(token) -> {label, reason, evidence} with thresholds exported verbatim into every report), tasks.md (the phased build plan, checked off as each phase landed). Steering (.kiro/steering/, all inclusion: always): product.md pins the non-negotiables (the classifier decides, narration only retells; no invented numbers; fixtures always labelled fictional; scope stays at one chain, one page, four labels); tech.md pins the constraints (Python stdlib only, vanilla static dashboard, /.kiro/ always committed, no wallets/keys/transactions anywhere); structure.md pins layout and change order. Agent hooks (.kiro/hooks/): run-classifier-tests-on-save fires on fileEdited for the classifier, fixtures or demo runner and runs the classifier tests plus a demo regeneration; spec-check-on-prompt fires on promptSubmit and asks the agent to check the incoming request against the requirements and product steering. The specs and steering were not decoration: the UNKNOWN-evidence path, the narrator's no-literal-digits construction, and the per-field provenance table all trace back to acceptance criteria written in the spec before the code existed.

Challenges

Free public data cannot prove a historical cause of death (no peak liquidity, holder history, or dev-wallet history), and one candidate (ALPACA) had to be excluded because no aggregator reliably indexes its only pair anymore — the coroner reports UNKNOWN instead of guessing.

Accomplishments

A fully reproducible pipeline — classifier tests 8/8, narrator number-traceability audits 12/12, a live round over 9 real tokens with per-field provenance, and a public dashboard.

What's next

An LLM narrator backend may be swapped in behind the same narrate() interface, but only after passing the number-traceability audit; more chains; scheduled live rounds.

Built With

Share this project:

Updates

Submission history