DeFi Security Intelligence · x402 v2

RektWatch

Protocol incident history, audit reports, bug bounties, and risk scores for 500+ DeFi protocols. Pay per call in USDC on Base — no account, no subscription.

500+
protocols tracked
$0.02
min per call
4
live data sources
USDC
Base mainnet

How it works

1
Discover protocols
Call /protocols to get the list of valid slugs. No wallet needed.
free
2
Request data
Server returns 402. Payment requirements are in the Payment-Required header (base64 JSON). The body is empty.
402 + requirements
3
Pay & retry
Sign an EIP-3009 authorization with viem. Retry the request with a Payment-Signature header.
200 + data
Get valid slugs from /protocols first

Paid endpoints return 404 for unknown protocol slugs at no charge. Call GET /protocols (free) to retrieve the full list of valid slugs before calling paid endpoints.

Endpoints

Path Description Price
GET /health DB status and per-source scraper freshness free
GET /protocols Start here. All tracked protocols with TVL, incident count, and audit count. Use this to discover valid slugs before calling paid endpoints. free
GET /alerts/recent-24h All incidents from the last 24 hours across all protocols $0.02
GET /protocol/{slug}/incidents Paginated incident history — amounts stolen, attack types, dates, source links $0.05
GET /protocol/{slug}/risk-score 0–100 risk score with per-factor breakdown explaining every delta $0.10
GET /protocol/{slug}/audits All audit reports with auditor name, date, finding counts by severity $0.10
GET /compare?a={a}&b={b} Side-by-side security comparison of two protocols in one call $0.10
GET /protocol/{slug}/security-summary Risk score + incidents + audits + bounty in one call. Best value for due diligence. $0.15

Quick start

shell — free endpoints (no wallet needed)
# List all protocols and pick a slug curl https://rektwatch.dev/protocols | jq '.[0:3] | .[] | {slug, incident_count}' # Check data freshness across all sources curl https://rektwatch.dev/health
typescript — x402 v2 with viem (Node 18 + / Bun)
import { privateKeyToAccount } from "viem/accounts" const signer = privateKeyToAccount("0xYOUR_PRIVATE_KEY") // needs USDC on Base mainnet async function paidFetch(url: string) { const first = await fetch(url) if (first.status !== 402) return first.json() // x402 v2: payment requirements live in the Payment-Required header (base64 JSON) // The 402 body is intentionally empty — do NOT call res.json() on a 402 const reqs = JSON.parse(Buffer.from(first.headers.get("payment-required")!, "base64").toString()) const req = reqs.accepts.find((a: any) => a.scheme === "exact" && a.network === "eip155:8453") const now = Math.floor(Date.now() / 1000) const nonce = ("0x" + Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString("hex")) as `0x${string}` const sig = await signer.signTypedData({ domain: { name: req.extra?.name ?? "USD Coin", version: req.extra?.version ?? "2", chainId: 8453, verifyingContract: req.asset, }, types: { TransferWithAuthorization: [ { name: "from", type: "address" }, { name: "to", type: "address" }, { name: "value", type: "uint256" }, { name: "validAfter", type: "uint256" }, { name: "validBefore", type: "uint256" }, { name: "nonce", type: "bytes32" }, ]}, primaryType: "TransferWithAuthorization", message: { from: signer.address, to: req.payTo as `0x${string}`, value: BigInt(req.amount), nonce, validAfter: BigInt(now - 60), validBefore: BigInt(now + (req.maxTimeoutSeconds ?? 300)), }, }) const payment = Buffer.from(JSON.stringify({ x402Version: reqs.x402Version, accepted: req, // ← required: the matched entry from Payment-Required.accepts payload: { signature: sig, authorization: { from: signer.address, to: req.payTo, value: req.amount, // string, e.g. "20000" nonce, validAfter: String(now - 60), // stringified integer, not a number validBefore: String(now + (req.maxTimeoutSeconds ?? 300)), }, }, })).toString("base64") return (await fetch(url, { headers: { "Payment-Signature": payment } })).json() } // Step 1: get valid slugs — free, no wallet needed const protocols = await fetch("https://rektwatch.dev/protocols").then(r => r.json()) // Note: paid endpoints return 402 (not 404) for unknown slugs — always validate slugs here first // Step 2: call paid endpoints using slugs from /protocols const score = await paidFetch("https://rektwatch.dev/protocol/aave-v3/risk-score") const summary = await paidFetch("https://rektwatch.dev/protocol/uniswap-v3/security-summary") const compare = await paidFetch("https://rektwatch.dev/compare?a=aave-v3&b=compound-v3")
Claude MCP integration

Install once from npm, then Claude handles everything — browsing protocols, paying for risk scores, explaining results. Add this to claude_desktop_config.json:

claude_desktop_config.json
{ "mcpServers": { "defi-security": { "command": "npx", "args": ["-y", "defi-security-mcp"], "env": { "API_URL": "https://rektwatch.dev", "WALLET_PRIVATE_KEY": "0xYOUR_PRIVATE_KEY" } } } }

Requires Node 18+ and a wallet with USDC on Base mainnet. The -y flag auto-installs on first run. Package: defi-security-mcp on npm.

Always call GET /protocols first to get valid slugs — paid endpoints return 404 at no charge for unknown slugs.

Example responses

GET /protocols (excerpt)

[ { "slug": "aave-v3", "display_name": "Aave V3", "tvl_usd": "12400000000", "coverage_tier": "full", "incident_count": 2, "audit_count": 7 } // … 500+ more ]

GET /health

{ "db": "ok", "sources": { "rekt": { "last_success_at": "2026-05-11T13:00Z", "stale": false }, "defillama": { "last_success_at": "2026-05-11T14:10Z", "stale": false }, "immunefi": { "last_success_at": "2026-05-11T11:45Z", "stale": false } }, "data_freshness_utc": "2026-05-11T14:23Z" }

GET /protocol/{slug}/risk-score — $0.10

{ "protocol": "aave-v3", "score": 68, "factors": [ { "name": "base", "delta": 50 }, { "name": "tier1_audit_12m", "delta": 3 }, { "name": "active_bug_bounty_500k", "delta": 5 }, { "name": "unresolved_high_findings", "delta": -9 } ], "data_freshness_utc": "2026-05-11T14:23Z" }

GET /protocol/{slug}/security-summary — $0.15

{ "protocol": "uniswap-v3", "risk_score": 74, "incidents": { "total": 0, "recent_90d": 0 }, "audits": { "count": 4, "latest_date": "2024-01-20", "open_criticals": 0 }, "bug_bounty": { "active": true, "max_usd": 2250000, "platform": "immunefi" }, "data_freshness_utc": "2026-05-11T14:23Z" }

GET /alerts/recent-24h — $0.02

{ "window_hours": 24, "count": 1, "incidents": [{ "protocol": "euler-finance", "title": "Flash Loan Attack", "amount_usd": 197000000, "attack_type": "flash-loan", "detected_at": "2026-05-11T09:12Z", "source_url": "https://rekt.news/euler-finance-rekt" }] }

GET /compare — $0.10

{ "a": { "protocol": "aave-v3", "score": 68, "incident_count": 2, "audit_count": 7, "bug_bounty_max_usd": 2000000 }, "b": { "protocol": "compound-v3", "score": 61, "incident_count": 3, "audit_count": 5, "bug_bounty_max_usd": 150000 } }

GET /protocol/{slug}/audits — $0.10

{ "protocol": "aave-v3", "audit_count": 7, "audits": [{ "auditor": "Trail of Bits", "date": "2023-09-15", "critical": 0, "high": 1, "medium": 4, "low": 9 }] }

GET /protocol/{slug}/incidents — $0.05

{ "protocol": "compound-v2", "total": 3, "incidents": [{ "title": "Oracle Price Manipulation", "amount_usd": 89000000, "attack_type": "oracle-manipulation", "date": "2023-11-28" }], "limit": 50, "offset": 0 }

Data sources

DeFiLlama
500+ protocols seeded by TVL. Hacks database cross-referenced against incidents. Refreshed every hour.
Rekt News
300+ historical exploits with stolen amounts, attack vectors, and post-mortems. Refreshed every 2 hours.
Immunefi
224+ live bug bounty programs with maximum payout amounts. Refreshed every 6 hours.
Audit Reports
PDFs from Trail of Bits, OpenZeppelin, Spearbit, Crytic — parsed by Claude Sonnet. Refreshed every 24 hours.