Blockchain transaction explainer — understand any Bitcoin or Ethereum transaction in plain English.
Fully static frontend + a thin Cloudflare Worker proxy (for Ethereum only).
txplain/
├── frontend/ # Static site — deploy to Cloudflare Pages
│ ├── index.html
│ ├── css/style.css
│ └── js/
│ ├── app.js # UI, state, chain routing
│ ├── providers.js # Claude / OpenAI / Gemini streaming
│ ├── mempool.js # Bitcoin: mempool.space API client
│ ├── ethereum.js # Ethereum: calls the proxy worker
│ └── summary.js # Deterministic summaries (BTC + ETH)
│
└── proxy/ # Cloudflare Worker — deploy separately
├── worker.js # Rate limiting + Etherscan key proxy
└── wrangler.toml # Worker config
Bitcoin — fully client-side, no proxy needed:
Browser → mempool.space API (free, no key, CORS-enabled)
Ethereum — routes through the Worker:
Browser → Cloudflare Worker (rate limiter + key holder) → Etherscan API
The Worker enforces 3 requests per IP per 5 minutes using Cloudflare KV.
- Push this repo to GitHub
- In Cloudflare Pages → Connect repo
- Settings:
- Root directory:
frontend - Build command: (leave empty)
- Output directory:
frontend
- Root directory:
npm install -g wrangler
wrangler loginwrangler secret put ETHERSCAN_API_KEY
# paste the key when promptedcd proxy
wrangler deployThe Worker will be live at https://txplain-proxy.YOUR-SUBDOMAIN.workers.dev.
Paste that URL into frontend/index.html as shown above, then redeploy the frontend.
Frontend:
cd frontend
python3 -m http.server 8080
# open http://localhost:8080Worker (local):
cd proxy
wrangler dev
# runs on http://localhost:8787For local testing with the Worker, temporarily set in index.html:
window.ETH_PROXY_BASE = 'http://localhost:8787';The Worker enforces per-IP limits using Cloudflare KV:
- 3 requests per 5-minute window per IP
- Returns HTTP 429 with a
retryAfterfield on breach - The frontend surfaces a clear message to the user
- Configurable via
RATE_LIMIT_MAXandRATE_LIMIT_WINDOWconstants inworker.js
Click AI in the top-right. Select a provider and paste the key. Session-only — cleared on tab close.
- Claude: console.anthropic.com
- OpenAI: platform.openai.com
- Gemini: aistudio.google.com
Every lookup updates the URL:
- Bitcoin:
/?chain=btc&tx=<txid> - Ethereum:
/?chain=eth&tx=<hash>
The Copy link button copies the full URL. Shared links load the transaction directly.
- Create
frontend/js/<chain>.jsfollowing the pattern ofmempool.jsorethereum.js - Add a
build<Chain>SummaryRows()function - Add a chain button in
index.html - Wire it into
app.js
Add an entry to window.AI_PROVIDERS in providers.js and a button in the settings panel.
MIT