An autonomous agent that trades live World Cup markets from the TxLINE feed and settles every position with a cryptographic Merkle proof verified against Solana.
Built for the TxODDS Trading Tools and Agents track of the Superteam World Cup hackathon.
Every in-play trading system has the same weak point: settlement. You end up trusting a JSON feed to tell you who won. TxLINE is the first sports data layer where you don't have to — every update is Merkle-anchored on Solana. ProofDesk exploits that end to end: it ingests TxLINE's live odds and scores streams, prices matches with an in-play Poisson model calibrated to TxLINE's own StablePrice consensus, takes positions when the model finds an edge, and then — the part nobody else does — settles each position by fetching a Merkle multiproof from /api/scores/stat-validation and simulating validateStatV2 against the on-chain daily_scores_roots PDA. The final score that pays out a position is not an API response you trusted; it's a stat cryptographically bound to a root TxODDS anchored on Solana.
- Ingests — SSE streams
/api/odds/streamand/api/scores/stream(auto JWT renewal, Last-Event-ID resume, exponential backoff), plus fixture/odds snapshots for bootstrap. - Prices — de-margins consensus implied probabilities, calibrates per-team Poisson goal intensities from pre-match fair 1X2, then re-prices 1X2 and Over/Under continuously in-play conditioned on the live score, phase, and clock from the scores feed.
- Trades — when model probability exceeds market implied by >=4pp, it opens a fractional-Kelly position (virtual bankroll). It also flags sharp consensus moves (fast implied-probability jumps) as signals.
- Settles trustlessly — on
action=game_finalised(statusId=100), it requests the Merkle multiproof for statKeys1,2(final P1/P2 goals) at the observedseq, determines the outcome from the proven stat leaves, encodes it as avalidateStatV2predicate (e.g. HOME =>goals(P1) - goals(P2) > 0), and verifies it on-chain before paying out. - Shows everything — a live trading-terminal dashboard (WebSocket) with match states, market-vs-model edge table, signals, positions, PnL curve, and a settlement panel showing each proof.
npm install
npm run demo # mock TxLINE feed (accelerated World Cup replay) + agent
# open http://localhost:8787The mock feed replays 90-minute matches in ~90 seconds with the exact TxLINE payload shapes and SSE framing, so you can watch the full lifecycle: kickoff -> trades -> goals -> game_finalised -> proof-settled positions.
npm install
npm run setup-wallet # creates ./keys/wallet.json + devnet SOL airdrop
MODE=devnet npm run agent # on-chain free-tier subscribe -> activate -> streamThis performs the genuine flow: guest JWT -> on-chain subscribe(serviceLevel=1, 4 weeks) (free World Cup tier, only SOL fees) -> signed activation (${txSig}::${jwt}) -> X-Api-Token -> live streams. Settlement then runs real validateStatV2 view simulations against the devnet program 6pW64gN1s2uqjHkn1unFeEjAwJkPGHoppGvS715wyP2J.
For mainnet free tiers (service level 1 = 60s delay, 12 = real-time): MODE=mainnet SERVICE_LEVEL_ID=12 npm run agent.
npm start runs the mock feed + agent + dashboard in a single process and honours PORT — ideal for Render, Railway, or Fly.
Render (free): push this repo to GitHub -> render.com -> New -> Web Service -> pick the repo. The included render.yaml sets everything (npm install / npm start). Your public URL serves the live dashboard.
Docker: docker build -t proofdesk . && docker run -p 8787:8787 proofdesk
Note: Vercel/Netlify serverless platforms can't host this — the agent is a long-running process with SSE consumers and a WebSocket server.
npm test # 13 engine self-tests (parsing, calibration, state machine)TxLINE /odds/stream ---> fairvalue.ts ---> strategy.ts ---> positions.ts (Kelly ledger)
(de-margin) ^ |signals |
TxLINE /scores/stream --> state.ts ----------+ v v
| (match state) server/ws ---> dashboard (public/)
+- game_finalised --> settle.ts --> /scores/stat-validation (Merkle multiproof)
+------> onchain.ts --> validateStatV2 .view()
on daily_scores_roots PDA
| Path | Purpose |
|---|---|
src/txline/ |
auth (JWT + activation), REST client, resilient SSE |
src/engine/ |
fair value, Poisson in-play model, strategy, position ledger |
src/settlement/ |
on-chain subscribe + validateStatV2 proof verification |
src/replay/mock-server.ts |
TxLINE-shaped mock feed for demos/offline dev |
public/index.html |
live dashboard |
idl/, types/ |
official txoracle IDL/types (from txodds/tx-on-chain, Apache-2.0) |
POST /auth/guest/start— guest JWTPOST /api/token/activate— API token activation after on-chain subscribeGET /api/fixtures/snapshot— fixture metadata / team namesGET /api/odds/snapshot/{fixtureId}— odds bootstrapGET /api/odds/stream— live odds SSE (primary trading input)GET /api/scores/snapshot/{fixtureId}— score state bootstrapGET /api/scores/stream— live scores SSE (state + finalisation)GET /api/scores/stat-validation?fixtureId&seq&statKeys=1,2— Merkle multiproof for settlement- On-chain:
subscribe,validateStatV2(view) on the txoracle program
Proof-settled positions are the missing primitive for B2B sports trading: market makers, exchanges, and on-chain prediction markets all need settlement that no counterparty can dispute. ProofDesk demonstrates the full loop — data in, risk on, proof out — on infrastructure that exists today.
Apache-2.0. IDL/types from txodds/tx-on-chain (Apache-2.0).