The World Cup broadcast built from pure data. No video stream — a living pitch, a breathing crowd, and the world's sharpest market calling the game.
Built for the TxODDS × Solana World Cup Hackathon · Consumer & Fan Experiences track.
| Live app | https://roarline-production.up.railway.app — no wallet, no signup, no credentials |
| Demo video | https://youtu.be/_FNnlGS6eZ8 — script at DEMO-SCRIPT.md |
| On-chain, verifiable now | program 6d1Se4dj…B32HFy deployed on devnet · our own TxLINE subscription tx · 4 confirmed MomentReceipts (table below) |
| Feel the decisive 90 seconds | open the live app, press play: goal → market swing → second goal → VAR reversal → final whistle |
Authenticity: everything on the judge path is reconstructed from an authentic public TxLINE World Cup capture (France 0–2 Spain), pinned by commit and SHA-256, replayed through a deterministic hash-chained ledger. No simulated data, no seeded metrics.
Three measured results (full records in evidence/):
- Four confirmed on-chain Proof-of-Broadcast receipts — each atomically CPI-verifies its goal against TxLINE's oracle (
Evaluate predicate to: true) before the receipt PDA is written, including one linked VAR-reversal correction. Example transaction. - 41.8% fewer serialized bytes in low-data mode on the 90-second cut (76,450 → 44,504 bytes); 38.6% fewer across the full 239-minute fixture (852,314 → 523,137 bytes). Measured on real connections.
- Feed ingest → deterministic package in p50 0 ms / p95 1 ms (26 samples from the running process), with bit-identical hash-chained replay determinism across runs.
Three billion people follow the World Cup. At any given kick-off, most of them cannot watch it — they're at work, on a bus, in a country without broadcast rights, or on a data plan that won't stream video. What they get today is a static 1–0 push notification.
ROARLINE turns TxLINE's live feed into the broadcast itself:
- 🏟 A living pitch — a pressure orb drifts toward the goal under siege, goal-mouths glow with danger, the whole field breathes with the match's fever. Feed signals are interpolated with
requestAnimationFrameat the browser's available display cadence. - 🎙 The Booth — deterministic play-by-play and market analysis with no LLM in the hot path. Browser TTS speaks synchronized EN/ES/FR/PT presentation while canonical match facts stay language-independent.
- 📣 A synthesized crowd — an entire stadium generated by WebAudio: the bed swells with the fever signal, roars erupt on goals, gasps on woodwork, whistles at kick-off. No samples, no copyright, no bandwidth.
- 📈 The market as narrator — TxLINE's de-margined consensus odds become a win-probability river flowing across the screen, and a voice in the booth: "the global market just moved 23 points on Croatia — something changed out there." Data only big operators had, handed to fans as drama.
- 🃏 Moment cards — goals, reversals and red cards carry their exact TxLINE proof coordinates (
fixtureId · seq · statKey). Cards distinguish an archived proof-log record, a fetched live TxLINE bundle, and a confirmed custom Proof-of-Broadcast receipt; none is silently promoted to another. - ♻️ Authentic replay — the default judge experience is a reproducibly reduced, hash-pinned public TxLINE France–Spain capture: goal → odds move → second goal → correction → final score. Live and historical sources enter the same normalized engine; simulation is an explicit lab mode only.
- ♿ Accessible by construction — audio description, synchronized captions, silent+haptics, low-data delivery, EN/ES/FR/PT phrase packs, and a walletless
<roarline-match>Web Component.
git clone https://github.com/iamdflame/ler1.git && cd ler1
node server/index.mjs # Node 20+ · authentic replay, zero credentials
# → http://localhost:8080That boots the authentic 90-second replay — France v Spain from a public TxLINE capture pinned by commit and SHA-256. No TxLINE credentials, wallet, or synthetic score data are needed. Then verify the engine from a second terminal:
npm run judge # transcribes the broadcast in your terminal
npm install && npm test # full engine, replay, proof and telemetry suiteOpen /evidence for measurements from the current process and /publisher-demo for the two-tag embed demonstration. The latter is deliberately described as a reproducible integration demo, not a third-party pilot.
- Public capture:
LightCreator1007/steamlineat commitb3bd417c1e28089c885a5454f654b1caadbde942. - Fixture
18237038: France 0–2 Spain, World Cup semi-final. - Deterministic package-body JSON SHA-256:
83cc7c4266f44a2272f80deb4bcecbc97be997939ac8bc9041b233728df3c25c(the exact generated JSON bytes with the top-levelpackageHashfield omitted). - The 0–3 state remains in history; the later 0–2 correction links to and supersedes that package instead of deleting it.
- Three matching signatures and proof coordinates are preserved as archived proof-log records in
danySSG/moment-mintscommit2f10829f4a4e95c571a72b43eada1088c63642bd; the pinned proof-log SHA-256 is6810cad65784e3a1c79b642a33bb6642ca655e88ab4483fc2aca828bf0f1ff46. - Current devnet RPC does not return those third-party historical transactions; they are presented as commit-pinned archive evidence. Our own receipts for the same four moments are confirmed and retrievable on devnet right now — see the table below.
The build script at scripts/build-hero-replay.mjs downloads the pinned inputs, verifies both source-file hashes plus the external proof-log hash and selected records, and reconstructs the director cut.
npm install
solana-keygen new -o wallet.json # fund with a little SOL (fees only — WC tier is free)
npm run activate # guest JWT → ON-CHAIN subscribe → signed activation → API token
npm run live # ROARLINE, powered by the real tournamentactivate performs TxLINE's documented onboarding end-to-end: an on-chain subscribe transaction signed by your wallet (that's the "sign up through Solana"), then a wallet-signed "{txSig}::{jwt}" activation message, and writes TXLINE_API_TOKEN to .env. Credentials live server-side only — nothing TxLINE-related ever reaches the browser.
Available source modes are hero (default authentic package), txline (live API plus historical replay), and sim (explicit simulation lab).
┌────────────────────────────── one normalized pipeline ─────┐
TxLINE live SSE ───┤ │
(scores + odds) │ normalize → MatchState → MomentDetector → DramaEngine │ SSE phone
TxLINE historical ─┤ (counter diffs — the source of truth) │ ├──────────► living pitch
(original ts, 8×) │ Commentator ┘ │ 1 frame/s crowd audio
pinned capture ────┤ hash-chained ledger → deterministic package hashes │ + moments booth + TTS
sim (explicit) ────┤ Room = one fixture, one broadcast, │
│ full timeline kept for late joiners │ moment cards
└───────────────┬────────────────────────────────────────────┘
│ /api/scores/stat-validation (Merkle proof bundles)
▼
TxLINE source validation on Solana
│ atomic CPI when enabled
▼
custom package-addressed MomentReceipt PDA
- Server core: Node 20+ stdlib, no framework or database. Solana packages are loaded only for activation, proof PDA derivation, or optional receipt submission.
- Frontend: hand-written canvas + WebAudio + SSE — no framework or bundler; animation follows the browser's available display cadence.
- Every assumption about feed field names lives in server/txline/normalize.mjs (case-tolerant, shape-tolerant), so adapting to feed nuances is a one-file change. Raw messages are inspectable at
/api/debug/raw. - Finished fixtures vanish from
/api/fixtures/snapshot, so live mode persists discovered fixture metadata todata/fixtures.json. Replay availability still follows TxLINE's historical API window; the pinned judge package is self-contained.
programs/roarline-receipts/src/lib.rs atomically CPI-calls TxLINE validate_stat, requires an exact-equality verdict, and writes a PDA addressed by ['moment', broadcaster, package_hash]. Corrections match the supplied prior hash to the prior receipt and link both accounts without deleting history. The CPI proves fixture/stat/value; sequence, timestamps, and off-chain hashes remain broadcaster metadata with explicit ordering, batch, and Solana Clock constraints.
The program is deployed on devnet as 6d1Se4dj…B32HFy (deploy tx 4yHwNHLe…38AbWL), and on 2026-07-19 it minted four receipts for the France–Spain moments from real stat-validation bundles fetched with our own on-chain TxLINE subscription (subscribe tx). Every transaction shows the full CPI: our program → TxLINE ValidateStat → Evaluate predicate to: true → receipt PDA written.
| Moment | seq | Receipt transaction (devnet) |
|---|---|---|
| GOAL — penalty, 0–1 Spain | 221 | 5JAYBk77…nLFi1 |
| GOAL — 0–2 Spain | 618 | 3mogoKDh…Nk9mb |
| GOAL — 0–3, later revoked | 641 | 3CrQg3Lx…smyoKz |
| VAR correction — 0–3 → 0–2, links & supersedes the receipt above | 682 | 35GFE9rh…UfALWh |
Honesty notes: these receipts were minted while re-broadcasting the archived fixture five days after it was played, so each receipt's broadcaster-reported reaction timestamp is ~4.9 days after its source timestamp — the on-chain record states exactly that, and the CPI-proved source facts are unaffected. Reproducibility: with Anchor CLI 0.31.1 and Agave 2.1.0/platform-tools v1.43 on PATH, npm run build:receipt reproduces the deployed 265,656-byte SBF binary and verifies SHA-256 3ac6bac37a00dc09eb1d5756587fe99e9105512bc77154ba417022e1e779dd63 without generating or requiring the deployment keypair; Rust tests pass.
/api/evidence reports only data observed by the running process: serialized standard/low-data bytes, ingest-to-package samples, browser-monotonic SSE-handler-to-animation-frame-callback samples, server-monotonic SSE-write-to-frame-acknowledgment samples, ledger head/gaps/rejections, package hashes, and proof/correction status. A frame callback is not claimed as visual paint. Both frame metrics require an active SSE telemetry token and a real package written to that client. Historical source age and unsynchronized server/browser clocks are intentionally not presented as network latency. Completed replay evidence remains frozen and queryable until a new replay request replaces the room.
Completed reference run — 2026-07-19, full 90.001-second director cut, one standard and one low-data connection:
| Measurement | Observed |
|---|---|
| Ingest → deterministic package | p50 0 ms · p95 1 ms · 26 samples |
| Browser SSE handler → animation-frame callback | p50 1.3 ms · p95 2.8 ms · 26 active-browser samples |
| Server SSE write → matching frame acknowledgment | p50 208 ms · p95 413.3 ms · 26 server-monotonic samples |
| Standard serialization | 76,450 bytes (74.66 KiB) |
| Low-data serialization | 44,504 bytes (43.46 KiB) · 41.8% fewer bytes |
| Actual bytes written to measured clients | standard 76,732 · low 44,929 |
| Ledger | 56 source events (48 score + 8 odds) · 0 duplicate/stale rejections · head 9b9bed363aab3a98e9bcaf94a0bbe16f6d21c7be7c8c2201db77d023f06f7e16 |
| Proof chain | 4 confirmed custom MomentReceipts on devnet (table above) · 3 commit-pinned archived third-party proof-log records |
Full-fixture run — 2026-07-19, the complete 238.8-minute France–Spain recording (evidence/full-fixture-run-2026-07-19.json): whole-capture ledger of 848 entries reproduces head 17c50be9… bit-identically across runs; the match block through the production room produced 852,314 standard vs 523,137 low-data bytes (38.6% fewer), room ledger head f9affad7…; the pipeline independently reconverges on the official 0–2 final score. The capture's own gaps are counted, not hidden: 505 missing source sequence numbers out of the 0–1026 range.
The server acknowledgment includes the forwarded browser transport in both directions, browser handling, the frame callback, and the return POST; it is not a one-way network or paint claim. These are environment-specific observations, not universal promises. /evidence always shows the current process instead of silently reusing the table. The complete measured record, all 26 package hashes, protocol, and qualifications are committed at evidence/reference-run-2026-07-19.json.
| Endpoint | Role in ROARLINE |
|---|---|
POST /auth/guest/start |
guest JWT (auto-renewed on 401) |
on-chain txoracle.subscribe + POST /api/token/activate |
Solana-signed signup → API token |
GET /api/fixtures/snapshot |
lobby + fixture ledger |
GET /api/scores/stream (SSE) |
the live heartbeat of every broadcast |
GET /api/odds/stream (SSE) |
the market narrator + probability river |
GET /api/scores/snapshot/{id} · GET /api/odds/snapshot/{id} |
instant whole-state for late joiners |
GET /api/scores/historical/{id} |
the archive: full re-broadcasts on original timestamps |
GET /api/odds/updates/{day}/{hour}/{5min} |
market emotions for replays |
GET /api/scores/stat-validation |
Merkle-proof bundles requested for eligible goal/red-card moments |
For fans: zero onboarding — open a URL, you're inside the match. No wallet, no signup, no odds jargon. Sound on, phone in pocket, and you feel the game.
Commercially: ROARLINE is a broadcast layer for the places video can't go —
- B2B white-label: betting operators, fantasy apps, and airlines (seat-back "live match" without video rights) embed the room as a second-screen; the data license is TxLINE's business model working as intended.
- B2C premium: multi-language booth voices, stat overlays, personalized fever alerts.
- Share loop: moment cards are acquisition assets carrying explicit proof coordinates and their actual evidence status; a receipt is shown only when separately confirmed.
| Path | What |
|---|---|
| server/engine/ | state machine, moment detector, drama signals, the booth |
| server/sources/ | TxLINE live (shared SSE mux) · TxLINE historical replay · labelled sim |
| server/txline/ | auth-aware client + the one-file feed normalizer |
| server/proofs.mjs | TxLINE proof retrieval, shaping, caching and receipt submission |
| server/receipts.mjs | retry-safe custom MomentReceipt worker |
| programs/roarline-receipts/ | Anchor CPI verifier + correction-linked receipts |
| web/ | the app: living pitch, river, crowd synth, TTS, cards |
| web/embed/roarline-match.js | framework-free publisher Web Component |
| scripts/activate.mjs | full Solana onboarding (on-chain subscribe → token) |
| scripts/build-receipt-program.mjs | secret-free, identity-checked SBF + IDL build |
| scripts/judge.mjs | zero-credential verification: transcribes the broadcast in a terminal |
| test/ | engine, deterministic replay, proof mapping, receipt PDA and telemetry tests |
| SUBMISSION.md | technical documentation + TxLINE API feedback |
| DEMO-SCRIPT.md | the 5-minute demo video plan |
Hackathon build, July 2026. The default replay is a provenance-pinned public capture; simulation mode is separately labelled. Archived records, fetched proof bundles, current RPC verification, and custom receipt confirmation are distinct claims. Not affiliated with FIFA.