Case study

chain-scanner

A read-only observatory and security scanner for Robinhood Chain, built so that a failed request never turns into the word “safe”, and an unknown never reads as a pass.

Solo: product, design, frontend, backend and deploy.

LiveKlein BlueNext 16Cloudflare WorkersTypeScript
The observatory. Launch pulse over the last two hours, measured on the server, with the UTC instant printed on screen.
/The observatory. Launch pulse over the last two hours, measured on the server, with the UTC instant printed on screen.
The instrument. Four axes measured live, each reporting whether it reached a conclusion.
/scanThe instrument. Four axes measured live, each reporting whether it reached a conclusion.

The problem

One launchpad on this chain emits more than 300 tokens an hour, a rate the observatory measures live and prints on its own front page. Someone looking at a fresh token has minutes to decide, and the tools that help them hand back a green badge reading SAFE.

That word is a promise about the future, and reading a chain cannot keep it. I wanted a tool that says what it measured, names what it could not see, and never rounds the gap in the reassuring direction.

What it measures

Paste an address and four measurements run against a public RPC and Blockscout. No API key, no wallet, no execution.

  1. Can holders sell?A transfer simulated three ways from a real holder's balance.
  2. Is the liquidity locked?Every position in the pool resolved to whoever owns it right now.
  3. Who made this token?The deployer's earlier launches, and what happened to them.
  4. Was the launch farmed?Who took supply in the first 120 seconds, and who funded those wallets.

The rule it is built on

Every axis can come back unknown, and one unknown blocks the pass. The verdict reads PARTIAL with a line under it that the whole tool exists to say:

Unknowns are not passes

Nothing red was found, but part of the picture could not be seen. Structure, not price. A token with nothing red here can still go to zero.

In one scan the liquidity positions covered 40% of the pool. Showing the biggest holder and calling it locked would have looked better. It reported unknown instead.

Finding its own blind spot

The observatory counted new tokens by listening for the launchpad's event. That misses anything deployed without one.

A canary against the live chain measured the gap: 278 contracts creating supply against 27 the counter could see, from eight different creators in thirteen minutes.

So I added a second counter that counts supply appearing on the chain, with no launchpad involved. It cannot share the first one's blind spot, and the distance between the two is the measurement of what the first one misses.

Public sources, and what they cost

Every source is public: an RPC node, Blockscout, DexScreener. No key is needed to run the project, so infrastructure costs nothing and anyone who clones it gets the same numbers I do.

Rate limits are the price. Public endpoints throttle per IP, and Cloudflare Workers leaves through an address shared with the platform, so code that answered on my machine came back HTTP 429 in production. The keys I added do not buy quota. They buy a path that does not depend on our address.

Nothing is cached, so a scan takes about a minute. When a source fails, that axis reports NOT MEASURED and the verdict drops toPARTIAL. A failed request can never round into a pass.

What it will not tell you

Printed in the product, next to the verdict

  • Whether the contract code hides a fee or a blacklist. It watches behaviour and does not read source.
  • What a Uniswap V4 hook charges on a swap. It reports what the hook is allowed to do, never what it does.
  • Anything a source failed to answer, which shows as NOT MEASUREDand never as a guess.

Shipped

In production, and what guards it

  • Live on Cloudflare Workers, redeployed on every push to main.
  • 400 tests, plus a live check that diffs the current output against a frozen baseline and fails on any difference.
  • Full UI coverage in English and Portuguese, enforced by the build.
  • Every verdict names the block it measured against and the UTC instant it was taken, so two runs are comparable.

Next 16, TypeScript, Cloudflare Workers. One accent colour drives the theme from a registry of 18, each checked for contrast on a page that makes zero network calls.

Open the scanner →← Back to all work