You can win the bet and still be wrong โ grade every pick against the closing line, not the scoreboard.
Short-run results are noise. The professional gold standard for whether a bet was actually good is Closing Line Value (CLV) โ did the price you took beat the market's final price? Measuring it requires closing-odds capture, grading discipline, and a settled sample to calibrate grades against. Retail bettors and copy-trading agents have none of that. Meanwhile the leaderboards they do have all rank by raw P&L โ the exact metric CLV exists to correct.
CLV Scout is a micro-priced A2MCP grader: paste a bet you placed (or up to 25 of someone else's), pay a cent or two, and get back a calibrated grade โ not an opinion, a number backed by a settled truth table you can independently recompute.
Key Features:
- ๐ฏ
POST /api/grade($0.01) โ grades one bet:clv_grade(A+โฆF),clv_pct,beat_close, and the settled truth table for that exact grade band (n,win_rate,roi_pct). - ๐
POST /api/audit($0.20) โ up to 25 bets โ a full CLV dossier: beat-close rate, grade distribution, weighted expectancy, and an origin-disclosed Sharp Score (0โ100) โ the direct answer to raw-P&L leaderboards. - ๐ซ UNGRADED honesty path โ if we don't have a recorded closing line for a
market, the response is
clv_grade: "UNGRADED"with a reason. Never a guessed or interpolated close. - ๐ Free
POST /api/calibrationโ the full gradeโoutcome truth table plus the exact methodology text, computed live from the settled ledger, not hardcoded prose. - ๐ BuyerLens-lite โ
POST /api/mereturns a payer's own grading history keyed off theirX-PAYMENTsignature (payment identity doubles as login). - ๐งพ
POST /api/receipts/verifyโ free re-check of any settlement via the Facilitator'sGET /settle/status.
| Layer | Technology |
|---|---|
| Runtime | Node.js 20+, TypeScript (strict), tsx (no build/bundle step) |
| API | Express 4 |
| Payments | OKX x402 exact scheme, EIP-3009/EIP-712 (viem), X Layer eip155:196 |
| Validation | zod |
| Data | Flat-file settled ledger + line-history snapshots (fixtures/), no DB server |
| Testing | Vitest โ 124 tests, @vitest/coverage-v8 |
flowchart LR
A[Agent / bettor] -->|POST /api/grade + X-PAYMENT $0.01| MW[okxPayGate<br/>x402 exact scheme]
MW <--> FAC[OKX Facilitator<br/>verify + settle -> X Layer eip155:196]
MW --> G[Grade engine<br/>CLV% -> A+...F]
G --> LH[(line-history snapshots<br/>entry / close odds)]
G --> TT[truth-table rollup<br/>per-grade n . win% . ROI]
TT --> L[(settled ledger<br/>fixtures/picks.csv)]
A -->|POST /api/calibration free| TT
A -->|POST /api/audit + X-PAYMENT $0.20| MW
MW --> D[Audit dossier<br/>Sharp Score + sub_scores]
Self-contained sibling of EdgeLedger (same OKX rail shape, separate
service and listing) โ see ARCHITECTURE.md for the full spec.
price: "$0.01"with real settlement. The SDK converts a one-cent USD string into atomic USDโฎ0 and the Facilitator settles it on X Layer per call. On a general-purpose EVM rail, a $0.01 payment is un-economic the moment anyone pays gas.- USDโฎ0 zero-gas promo (
0x779ded0cโฆ3736) makes the buyer's marginal cost exactly one cent โ the only thing that makes "audit a tout's last 25 picks for $0.20" a rational agent action. - Multi-route pricing in one middleware โ
"$0.01"grade and"$0.20"audit are two entries in the same routes map; tiered pricing costs a config block, not an integration. - Public sold counts on the marketplace โ the 1ยข-volume thesis is verifiable by judges without trusting us.
- Same
exact/EIP-3009 wire as the primary, plus shared v2 modules:X-PAYMENT-identity BuyerLens and FacilitatorGET /settle/statusreceipt re-verification.
Take OKX out and the product dies at the till: no micro-payment rail clears
$0.01 profitably off the zero-gas promo, and there's no Session-Key + TEE
aggregation stack for sub-cent streaming elsewhere. The grader is portable โ
the economics are OKX-specific. Full brief: SPONSOR_DEFENSE.md.
A tout posts his last 5 World Cup moneyline picks. Naive record on flat
1-unit stakes: 3 wins, 2 losses, net +12.0% raw ROI โ looks like someone
worth following. Feed the exact same 5 picks to /api/audit ($0.20) against
the real, settled closing-line ledger:
{
"graded": 5,
"beat_close_rate": 0.2,
"grade_distribution": { "A+": 0, "A": 1, "B": 0, "C": 1, "D": 2, "F": 1 },
"weighted_expectancy_pct": -22.14,
"sharp_score": { "value": 40.7 },
"verdict_line": "Sharp Score 40.7/100 โ the record may look fine on raw P&L, but the numbers that predict future results say otherwise."
}Only 1 of 5 picks beat the closing line. +12% raw ROI, Sharp Score
40.7/100. Every number above is real, unmodified output from this build
against the shared 24-row settled seed ledger โ nothing here is scripted or
hand-typed. Full walkthrough (including the "won the bet and still made a
mistake" single-grade reveal, and the UNGRADED honesty path) is in
DEMO.md.
The first real x402 paid-call has settled on-chain. A live POST /api/grade
call was paid from a funded OKX Agentic Wallet โ TEE-signed EIP-3009
TransferWithAuthorization, replayed as X-PAYMENT โ and settled on X Layer
mainnet (eip155:196) through the OKX Facilitator: a real 0.01 USDโฎ0
transfer, status SUCCESS. This is the exact probe โ 402 โ sign โ pay โ 200 โ settle rail the whole product is built on, exercised end-to-end against
the deployed service (not a local demo).
| Field | Value |
|---|---|
| Tx hash | 0x33e65fc9โฆ45c903d8 |
| Network | X Layer mainnet ยท eip155:196 (zero-gas USDโฎ0 promo) |
| Asset / amount | USDโฎ0 (0x779ded0cโฆ3736) ยท 0.01 (10000 atomic, 6dp) |
| Payer โ payTo | 0x3e86โฆdbeb โ 0x0000โฆdEaD |
| Paid route | POST /api/grade โ HTTP 200 (clv_grade: C, clv_pct: -2.08) |
| Settlement | OKX Facilitator โ is_placeholder: false |
Re-verify it yourself against the running service (free, no wallet needed):
curl -s -X POST https://api.clvscout.edycu.dev/api/receipts/verify \
-H "Content-Type: application/json" \
-d '{"txHash":"0x33e65fc96d1abed0bb5229337f37f0106e1fc38648095dd43567042245c903d8"}'
# -> {"live":true,"source":"OKX Facilitator GET /settle/status","explorer_url":"โฆ"}Full captured evidence (raw 402, signed authorization, paid 200 body, on-chain
tx record, balance delta) is in docs/screenshots/PROOF.md.
- Node.js โฅ 20
- npm
npm install
cp .env.example .env # optional โ faithful-local mode works with no keys
npm run gen-line-history # regenerate fixtures/line-history.json from picks.csv (already committed)
npm run settle # compute CLV%/grade per row + truth table -> fixtures/ledger-settled.json
npm run typecheck
npm test # 124 vitest, offline
npm run api # boots on :4021Then open http://localhost:4021/ โ a served visible proof page that drives the live paid API and renders the reveal: the tout who's "+12% / 3-2" collapsing to a red Sharp Score 40.7/100, the WON-but-graded-C card, the UNGRADED refusal, and the live calibration table. Every button fires a real x402 round-trip (probe โ 402 โ sign EIP-3009 โ pay โ 200), signed server-side with a throwaway key because browsers can't sign โ nothing on the page is mocked (web/, api/demoRunner.ts). This is the 90-second demo surface โ see DEMO.md.
Or drive it from the terminal:
npm run buyer POST /api/grade '{"match":"NED vs URU","selection":"Netherlands to advance","odds_taken":1.88}'scripts/buyer.ts does the full round trip: probes the route unpaid, reads
the 402 challenge, signs a real EIP-3009 TransferWithAuthorization locally
(throwaway key), and replays with X-PAYMENT.
For judges: no account, no faucet needed to inspect the flow โ every paid route responds to an unpaid
curlwith a real 402 challenge (see Self-Check below), andnpm run readinessboots an ephemeral instance and runs that exact check for you.
A self-contained static landing page lives in docs/, wired to publish to
GitHub Pages at the target domain clvscout.edycu.dev (custom domain via
docs/CNAME) โ the product story, the x402 paid-edge flow, the endpoint
surface, and the money-shot output, fronted by the animated hero. Not yet live (this repo
is not pushed as of this snapshot โ see ยงLimitations). The page is static,
so the interactive demo (web/index.html) is served by the API at the target
api.clvscout.edycu.dev (npm run api locally); the Pages site shows the real sample
output and links back to this repo.
Publishing: .github/workflows/pages.yml deploys
the docs/ folder to Pages on every push to main. One-time repo setup:
Settings โ Pages โ Source = "GitHub Actions".
5-stage pipeline: Quality โ Security โ Build โ API Smoke โ Deploy Gate
# โโ Code Quality โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
npm run typecheck # tsc --noEmit
npm test # 124 tests (vitest)
npm run test:coverage # vitest run --coverage
npm run ci # lint + typecheck + coverage
# โโ API self-check โโโโโโโโโโโโโโโโโโโโโโโโโโ
npm run readiness # boots an ephemeral instance, checks 402/402/405/200 + truth-table sums| Layer | Tool | Status |
|---|---|---|
| Code Quality | TypeScript strict (tsc --noEmit) |
โ |
| Unit Testing | Vitest โ 124 tests (17 files) | โ |
| Coverage | @vitest/coverage-v8 (engine/api/db ~75%) |
โ |
| API Smoke | live-boot 402/402/405/200 self-check (CI + npm run readiness) |
โ |
| Security (SAST) | CodeQL (javascript-typescript) |
โ |
| Security (SCA) | Dependabot (npm + github-actions) + npm audit |
โ |
| Secret Scanning | TruffleHog | โ |
| License Compliance | license-checker (GPL/AGPL gate) |
โ |
| CI/CD Pipeline | 5-stage, parallel, concurrency-controlled | โ |
curl -i -X POST http://localhost:4021/api/grade # -> 402, x402Version:2
curl -i -X POST http://localhost:4021/api/audit # -> 402, x402Version:2
curl -i -X GET http://localhost:4021/api/grade # -> 405
curl -i -X POST http://localhost:4021/api/calibration # -> 200clvscout/
โโโ config.ts # env + constants (single source)
โโโ engine/
โ โโโ prob.ts, clv.ts # vendored from EdgeLedger's engine/{edge,clv}.ts
โ โโโ types.ts # CLV Scout domain types
โ โโโ grade.ts # grade bands, truth-table math, Sharp Score (pure)
โ โโโ grader.ts # line-history lookup + grade.ts -> GradeOutcome
โ โโโ dossier.ts # /api/audit aggregation
โโโ data/lineHistory.ts # closing-line snapshot lookup (never interpolates)
โโโ db/csv.ts, ledger.ts # picks.csv parsing + settled-ledger/truth-table build
โโโ api/
โ โโโ rails/okx.ts # the OKX x402 payment rail
โ โโโ buyerlens.ts # X-PAYMENT identity -> /api/me history
โ โโโ receipts.ts # /api/receipts/verify wiring
โ โโโ demoRunner.ts # real x402 round-trip for the proof page (POST /api/demo/run)
โ โโโ routes.ts, server.ts # Express app (+ serves web/ at /)
โโโ web/ # served visible proof page (index.html) โ the demo surface
โโโ scripts/ # gen-line-history, settle, audit, buyer, readiness
โโโ fixtures/ # picks.csv (shared with EdgeLedger), line-history.json, ledger-settled.json
โโโ test/ # 124 vitest across 17 files
โโโ ARCHITECTURE.md # full system spec (flows, invariants, Tier map)
โโโ docs/ # GitHub Pages site (index.html) + animated hero/icon
โโโ .github/ # CI workflows, CodeQL, Dependabot, community health files
โโโ .env.example # environment template
โโโ README.md # you are here
- Self-contained facilitator, not a mock. The real
@okxweb3/x402-express+x402-core+x402-evmpackages install cleanly and match the documented wire shapes โ the server-sideExactEvmSchemelives at the subpath@okxweb3/x402-evm/exact/server(the sibling EdgeLedger build imports it there and wires it for real). CLV Scout deliberately keeps this listing zero-dependency on@okxweb3:api/rails/okx.tshand-rolls the same documented wire shapes with onlyviem+express, so it installs, boots, and unit-tests the payment leg fully offline. EIP-3009/EIP-712 signature verification is real, offline cryptography (viem'srecoverTypedDataAddress), exercised end-to-end byscripts/buyer.tsagainst a live server. WithoutOKX_API_KEY/OKX_SECRET_KEY/OKX_PASSPHRASEset, settlement is recorded as an honestly-labeled local-pending receipt instead of a live Facilitator call โ the payment signature check still runs for real either way. - Real closes only โ UNGRADED otherwise. There is no synthetic-close code
path anywhere in this codebase. A market without a recorded closing-line
snapshot returns
clv_grade: "UNGRADED"with a reason, never an invented number (engine/grader.ts). - Grade bands are chosen, not curve-fit. The A+โฆF thresholds are fixed
round-number CLV cutoffs decided up front โ they are not tuned to make this
particular 24-row seed ledger look good, and
/api/calibrationstates that explicitly alongside the live truth table. - Live API โ with a real on-chain settlement on record. The service is deployed on Railway at
https://api.clvscout.edycu.dev(/health200; paid routes return real402challenges, free routes 200), and a real paid call has now settled on X Layer mainnet โ tx0x33e65fc9โฆ45c903d8, 0.01 USDโฎ0, statusSUCCESS(see ยงLive On-Chain Proof). Every number here remains reproducible from source. Remaining scope: only a single grade-route settlement is captured so far (the$0.20audit route uses the identical rail), and per-call settlement on the deployment depends on the server's OKX Facilitator credentials being present. - Narrow market coverage by design. World Cup 2026 knockout markets only
(
fixtures/picks.csv); coverage is stated in every/api/calibrationresponse rather than hidden. - Out of scope (Tier 1 only). No
POST /api/grade-stream(aggr_deferredbatch, Tier 2), no zk/bond/SDK/MCP (Tier 3). - Known dev-dependency advisory.
npm auditreports moderate/high/critical findings invitest's transitiveesbuild/vitechain (test-runner only, not shipped in the running service); CI runs it as advisory (continue-on-error) and Dependabot tracks upstream fixes rather than force-upgrading mid-build and risking the 124-test suite.
MIT ยฉ 2026 Edy Cu
Built for OKX.AI Genesis 2026. Thank you to OKX for the x402 payment rail, the X Layer zero-gas USDโฎ0 promo, and the Onchain OS / Agentic Wallet tooling that makes a $0.01 API call an economically real product.

