The okx.ai World Cup๐ฅ category is proven-selling but uniformly predict-only โ every listed agent tells you who wins. None of them will tell a user their proposed bet is bad, size a stake responsibly, or expose an auditable settled record of their own calls. Recreational bettors during a live World Cup mostly lose to sizing and discipline failures, not to a shortage of predictions.
EdgeLedger is an A2MCP ASP that answers a different question: "should I bet", not "who wins". POST a proposed bet and $0.05 over OKX x402 on X Layer; get back APPROVED, REJECTED, or SKIP โ with a named edge grade (A+โฆF), a conviction-ladder stake, and the settled historical ROI of similar calls. Two companion endpoints are free and public: today's BET/SKIP slate, and the full settled ledger โ losses included.
Key Features:
- ๐ซ Verdict engine โ
APPROVED/REJECTED/SKIPon edge-grade bands calibrated to a real settled record, not textbook Kelly. "No bet" is a first-class answer. - ๐ช Conviction ladder โ 5-rung stake sizing mapped to edge grade ร bankroll.
- ๐ช Mirror receipts โ every response cites what the seller actually staked on the same/most-similar fixture, with settled P&L.
- โณ Signal decay โ
decay_min_halflifestates honestly how fast the edge goes stale toward kickoff. - ๐ BuyerLens (no-login personalization) โ decodes the x402
X-PAYMENTheader's EIP-3009authorization.from(an unforgeable, ECDSA-recovered identity) into a per-buyer discipline memory โ the payment signature is the login.POST /api/me {address}reads it back;{forget:true}deletes it. - ๐งพ Independent receipt re-verification โ
POST /api/receipts/verifyre-checks any settlement live against OKX's own Facilitator API, so a buyer verifies without trusting EdgeLedger's database. - ๐ Public, loss-inclusive ledger โ
POST /api/ledgerreturns every settled call (pre-match odds, fair prob, edge grade, stake, result, P&L, CLV, pick-hash + receipt) โ a moat a predict-only competitor can't fabricate after the fact. - ๐ Pick-commit hashing โ every response's payload hash is stored beside its settlement reference for tamper-evidence.
| Layer | Technology |
|---|---|
| Runtime | Node 20 + Express (long-lived server โ the 402โpayโsettle handshake wants no cold starts) |
| Language | TypeScript (strict), run directly via tsx โ no bundler/build step |
| Payments | @okxweb3/x402-express + @okxweb3/x402-core + @okxweb3/x402-evm โ exact scheme, dual accepts (USDโฎ0 + USDG, both zero-gas) on X Layer |
| Database | better-sqlite3 (local ledger) seeded from fixtures/ledger-state.json |
| Testing | Vitest โ 188 tests, 18 files, @vitest/coverage-v8 |
| On-chain anchor | contracts/LedgerAnchor.sol (Hardhat, X Layer) โ daily Merkle root of the ledger |
flowchart LR
subgraph Buyer["Buyer (AI agent / Agentic Wallet)"]
B1[POST /api/edge<br/>no payment]
B2[POST /api/edge<br/>X-PAYMENT header]
end
subgraph API["Express API"]
MW["paymentMiddleware<br/>@okxweb3/x402-express<br/>POST /api/edge = $0.05"]
VE[Verdict engine<br/>edge % โ grade โ APPROVED/REJECTED/SKIP]
LAD[Conviction ladder<br/>5 rungs]
SL[POST /api/slate โ free]
LG[POST /api/ledger โ free]
end
subgraph OKX["OKX rails"]
FAC["OKXFacilitatorClient<br/>web3.okx.com /api/v6/pay/x402"]
XL[(X Layer eip155:196<br/>USDโฎ0 / USDG zero-gas)]
end
DB[(SQLite ledger<br/>picks + hashes + receipts)]
B1 -->|402 challenge x402Version:2| MW
B2 --> MW -->|verified| VE --> LAD -->|response + pick-hash| DB
MW <--> FAC <--> XL
SL --> DB
LG --> DB
EdgeLedger is x402-native: OKX's Express middleware + Facilitator turn a five-cent bet-verdict into a settled X Layer receipt with zero gas and zero payment code in the business logic. Named surfaces actually wired into this build:
| # | Surface | Where in code | What it does for us |
|---|---|---|---|
| 1 | @okxweb3/x402-express paymentMiddleware(routes, resourceServer) |
api/rails/okx.ts |
Gates POST /api/edge at $0.05 before business logic โ unpaid calls never touch the verdict engine |
| 2 | OKXFacilitatorClient({apiKey, secretKey, passphrase}) |
api/rails/okx.ts |
Signature verification + on-chain settlement as a service โ EdgeLedger holds only a receive address, no node, no KYC, no relayer |
| 3 | ExactEvmScheme on eip155:196 (X Layer), dual accepts |
api/rails/okx.ts |
Standard exact EIP-3009 charge; buyer pays 5ยข with either USDโฎ0 or USDG, both zero-gas |
| 4 | X-PAYMENT header decode โ EIP-3009 authorization.from |
api/routes.ts, db/buyers.ts |
BuyerLens โ per-buyer discipline memory with zero auth stack; the payment signature is the login |
| 5 | Facilitator GET /settle/status?txHash= (HMAC OK-ACCESS-*) |
api/routes.ts (receiptsVerifyHandler) |
Free /api/receipts/verify re-checks any receipt live against OKX's own API โ buyers verify without trusting EdgeLedger's DB |
Remove OKX and you'd need to rebuild an EIP-3009 verification service, a stablecoin settlement rail with a gas sponsor, a payments-aware marketplace with public sold metrics, and a buyer-identity mechanism that doesn't require a login โ before writing a single line of edge math.
- Node.js โฅ 20
- npm
git clone https://github.com/edycutjong/edgeledger.git
cd edgeledger
npm install
cp .env.example .env.local # fill in OKX_* only if you want real settlement
npm run settle # seeds fixtures/ledger-state.json + db/ledger.sqlite
npm run api # boots on :8403 with the REAL x402 payGatecurl -i -X POST http://localhost:8403/api/edge # โ 402, PAYMENT-REQUIRED header, x402Version:2
curl -i -X POST http://localhost:8403/api/slate # โ 200, today's BET/SKIP verdicts
curl -i http://localhost:8403/api/edge # (GET) โ 405To see the full verdict JSON shape without a live payment, run the paygate-bypassed demo mode (never used in production):
npm run api -- --demo
curl -s -X POST http://localhost:8403/api/edge -H "Content-Type: application/json" \
-d '{"fixture":"SF: FRA vs ESP","selection":"Spain to advance","odds":1.45,"bankroll":500}'npm run api -- --demo # then open the served proof surface:
open http://localhost:8403/ # โ live VerdictCard + public loss-inclusive ledgerGET / serves web/index.html โ a single self-contained page that calls this same API. On load it renders the headline REJECTED ยท grade F ยท $0 stake verdict and the full settled ledger (losses in pink, receipts labeled). Under the real paygate (no --demo) the verdict panel shows the honest HTTP 402 paywall instead โ the page hits real routes, nothing mocked.
| Route | Gate | Request | Response |
|---|---|---|---|
POST /api/edge |
$0.05 x402 (accepts USDโฎ0 or USDG, both zero-gas) | {fixture} or {fixture, selection, odds, bankroll?} |
{mode, verdict, edge_pct, edge_grade, stake, mirror, similar_settled, you, pick_hash, sources} |
POST /api/slate |
free | {} |
{fixtures:[{id, teams, kickoff, verdict: BET|SKIP}]} |
POST /api/ledger |
free | {} or {filter} |
{settled:[โฆ], totals:{n, roi_pct}, anchor:{merkle_root, contract, explorer_url}} |
POST /api/me |
free | {address} (+ {forget:true}) |
that buyer's graded call history, keyed by EIP-3009 authorization.from |
POST /api/receipts/verify |
free | {txHash} or {pick_hash} |
live re-check via OKX Facilitator GET /settle/status |
GET /api/edge |
โ | 405 (review-gate semantics โ never serves GET) |
|
GET / |
free | serves web/index.html โ the live VerdictCard + public ledger proof page |
|
GET /health |
โ | {ok, service, rows, price_usd, pay_rail} |
5-stage pipeline: Quality โ Security โ Build โ API Smoke โ Deploy Gate
# โโ Code Quality โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
npm run typecheck # tsc --noEmit
npm test # vitest run โ 188 tests
npm run test:coverage # vitest run --coverage
npm run ci # typecheck + coverage (the CI quality gate)
# โโ API smoke (what CI Stage 4 runs) โโโโโโโโโ
npm run api &
curl -i -X POST http://localhost:8403/api/edge # 402
curl -i -X POST http://localhost:8403/api/slate # 200
curl -i http://localhost:8403/api/edge # 405| Layer | Status | Details |
|---|---|---|
| Code Quality | โ | TypeScript strict (tsc --noEmit), zero errors |
| Unit Testing | โ | Vitest, 188 tests across 18 files, @vitest/coverage-v8 |
| API Smoke Test | โ | Boots the real x402 payGate offline, asserts 402 / 200 / 405 review-gate shape (CI Stage 4). The proof page at GET / is a static, dependency-free HTML surface that calls these same routes โ no separate build/test toolchain |
| Security (SAST) | โ | CodeQL (javascript-typescript), scheduled + on push/PR |
| Security (SCA) | โ | Dependabot (npm + github-actions) + npm audit --audit-level=high |
| Secret Scanning | โ | TruffleHog (verified secrets only) in CI |
| License Compliance | โ | license-checker fails on GPL-3.0/AGPL-3.0 in dependencies |
| CI/CD Pipeline | โ | 5-stage, parallel Quality/Security, concurrency-cancelled |
| Community Standards | โ | Code of Conduct, Contributing, Security policy, issue/PR templates |
edgeledger-okx/
โโโ api/
โ โโโ server.ts. # Express app โ route wiring, CORS, x402 gate
โ โโโ routes.ts # handler bodies (edge/slate/ledger/me/receipts/health)
โ โโโ rails/
โ โโโ okx.ts # the ONLY new infra file โ OKX x402 wiring
โ โโโ localFacilitator.ts # real EIP-3009 verify, honest settle-refusal
โโโ web/ # index.html โ the served proof page (VerdictCard + public ledger)
โโโ engine/ # verdict, ladder, edge, CLV, hash, merkle
โโโ db/ # SQLite ledger + BuyerLens store
โโโ data/ # odds/fixture data + known-picks model coverage
โโโ fixtures/ # seed ledger state, picks, anchors
โโโ contracts/ # LedgerAnchor.sol (X Layer)
โโโ scripts/ # settle, audit, bench, anchor, paid-call-smoke
โโโ test/ # 188 vitest tests
โโโ docs/ # README hero, icons, OG/social assets + landing & pitch pages
โโโ .env.example
โโโ .github/ # CI workflows + community health files
โโโ README.md # you are here
Stated plainly, not hidden โ see DEMO.md for the full, verbatim rehearsal log:
- No live on-chain settlement in this build session.
api/rails/localFacilitator.tsperforms real EIP-3009 signature verification (viem'srecoverTypedDataAddressover the exactTransferWithAuthorizationEIP-712 struct) but honestly refuses to fabricate a settlement receipt ({success:false, errorReason:"no_live_facilitator"}) when no OKX Developer Portal credentials are configured.scripts/paid-call-smoke.tsexits 3 rather than invent a receipt. Real end-to-end settlement needsOKX_API_KEY/OKX_SECRET_KEY/OKX_PASSPHRASEfrom web3.okx.com/onchainos/dev-portal plus a funded X Layer wallet. LedgerAnchor.solexists and is tested but has not been deployed โ daily Merkle roots are computed off-chain today;/api/ledger'sanchor.contract/explorer_urlarenulluntil deployment (credential/funds-gated, user-only step).- Proof surface is a single served HTML page, not a full Next.js app.
GET /servesweb/index.htmlโ a self-contained page that calls this same live API and renders the VerdictCard (APPROVED/REJECTED/SKIP + edge grade + conviction-ladder stake) and the public loss-inclusive ledger live. It hits the real routes: in demo mode it shows the verdict; under the real paygate it renders the honest HTTP 402 paywall. The planned full Next.js ledger site (filters, per-buyer views) is still roadmap โ deprioritized in favor of API + test depth โ but the headline "the agent said NO, and here's the record" moment is now visible, not curl-only. - Live API โ but no real on-chain settlement yet. Deployed on Railway at
https://api.edgeledger.edycu.dev(/health200 with the auto-seeded 24-row ledger;/api/edgereturns a real402, free routes 200). What's not done: no real paid call has settled on-chain yet, and the static landing onedgeledger.edycu.dev(Pages) is pending DNS โ live atedycutjong.github.io/edgeledgermeanwhile. Local verification useslocalhost:8403. - Model coverage is intentionally narrow โ
fixtures/known-picks.jsoncovers a small, labeled set of fixture/selection pairs by design (PRD: "no new prediction model โ accountability is the gap, not model novelty"). Anything outside it honestly returnsverdict: "SKIP", reason: "no_model_coverage"rather than a fabricated edge. - Tier-2 (
sessionPAYG channel,periodsubscription) and Tier-3 (zk attestation,ConvictionBond.sol) are explicitly out of scope for this build โ spec-only roadmap.
MIT ยฉ 2026 Edy Cu
Built for OKX.AI Genesis 2026. Thank you to OKX for the x402 SDK (@okxweb3/x402-express, -core, -evm), the Developer Portal, and X Layer's zero-gas USDโฎ0/USDG promo.