Live social match rooms powered by TxLINE on Solana.
Built for the TxODDS · Consumer & Fan Experiences track on Superteam Earn’s World Cup hackathon.
Friends open a shared room for a fixture, watch the scoreline and key moments update from TxLINE in real time, and react together — Clutch Hold, VAR Sentinel, Mood, Odds Weather, on-chain Proofs, and Match Recap. Social only — no real-money betting.
| Track | Consumer & Fan Experiences (TxODDS) |
| Network | Solana devnet · TxLINE https://txline-dev.txodds.com |
| Repo | https://github.com/ChiJian28/CHORUS |
| Stack | Next.js 15 · Fastify · Anchor · TxLINE SSE |
Most fans watch the World Cup with a phone in their hand. Live scores and odds used to sit behind big operators. TxLINE puts that data on Solana so builders can invent new fan experiences.
CHORUS is not another score ticker and not a bookmaker UI. It is a co-watch room: the same live feed friends share, with short social interactions settled by real pitch events, plus a trust layer fans can open (TxLINE Merkle proof + Solana validateStatV2).
| Problem | CHORUS |
|---|---|
| Group chats lag behind the match | Moments stream into the room as TxLINE events land |
| Spreadsheet sweepstakes wait for a human updater | Rooms hydrate from live SSE or historical replay |
| “Is this data real?” is opaque | Proof Drawer: Merkle + on-chain check + explorer links |
| Live demos die after full time | Replay Director replays historical scores + odds through the same engine |
| Feature | Description |
|---|---|
| Match Rooms | Live or replay rooms; join by code; display name + side (no wallet required for fans) |
| Moment feed | Goals, cards, corners, VAR, phase changes as Moment Cards |
| Clutch Hold | ~10s social micro-prompts (e.g. who scores next), settled by the next TxLINE event |
| VAR Sentinel | On var / var_end, room votes stands vs overturned under a stand-off UX |
| Mood dock | Shared fire / shock / rage / sharp → room ambient |
| Odds Weather | 1X2 moves from TxLINE odds (Pct[] / Prices[]) → calm / breeze / storm |
| Proof Drawer | stat-validation Merkle payload + Solana validateStatV2 simulation |
| Hydration break | Fan-friendly handling of water-drinking-break comments |
| Match Recap | Energy curve, clutch record, top moments at full time |
| Replay Director | Historical scores + odds timeline for demos when matches are over |
| Layer | Role |
|---|---|
| ① DATA | TxLINE fixtures, scores, odds, stat-validation (guest JWT + API token) |
| ② INGEST | TxLINE client, dual SSE FeedHub, Replay Director |
| ③ ENGINE | RoomEngine — moments, Clutch, Sentinel, Mood, weather, recap |
| ④ PROOF | Merkle → Anchor validateStatV2 → Verified badge |
| ⑤ EXPERIENCE | Next.js PWA + WebSocket room fanout |
Next.js (PWA) ←── REST / WS ──→ Fastify (RoomEngine · FeedHub · Replay)
│
guest JWT + X-Api-Token
▼
TxLINE API (devnet)
│
stat-validation payload
▼
Solana · validateStatV2 (.view())
- Node.js ≥ 20
- TxLINE free-tier activation on Solana devnet (API token)
- Optional: funded devnet wallet for on-chain proof badges
cd backend
cp .env.example .env
# set TXLINE_API_TOKEN (from activation)
# optional: SOLANA_KEYPAIR_PATH / wallet for proofs
npm install
npm run activate # once: free-tier subscribe + activate (if needed)
npm run dev # http://127.0.0.1:3001Health check:
curl -s http://127.0.0.1:3001/api/healthcd frontend
cp .env.example .env.local
# NEXT_PUBLIC_API_URL=http://127.0.0.1:3001
# NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001
npm install
npm run dev # http://localhost:3000- Open http://localhost:3000
- Launch demo replay (or fixture
18175981→ Replay) - Join with a display name + side
- Play at 20×–40× — moments, clutch, weather, proofs, recap
Manual UI checklist: steps.md (if present).
Base (devnet): https://txline-dev.txodds.com
| Area | Endpoints |
|---|---|
| Auth | POST /auth/guest/start · free-tier subscribe/activate on Solana |
| Fixtures | GET /api/fixtures/snapshot |
| Scores | GET /api/scores/snapshot/{id} · /updates/{id} · /historical/{id} · /stream · /stat-validation |
| Odds | GET /api/odds/snapshot/{id} · /updates/{id} · /updates/{epochDay}/{hour}/{interval} · /stream |
Headers on data routes: Authorization: Bearer <guest JWT> + X-Api-Token: <token>.
More detail: tech_docs.md.
| Method | Path | Purpose |
|---|---|---|
GET |
/api/health |
Liveness |
GET |
/api/txline/status |
Network / token / proof capability |
GET |
/api/fixtures |
Normalized fixtures |
POST |
/api/rooms |
Create room { fixtureId, mode?: "live"|"replay" } |
GET |
/api/rooms/:id |
Room snapshot |
POST |
/api/rooms/:id/join |
Join fan |
POST |
/api/rooms/:id/clutch/vote |
Clutch vote |
POST |
/api/rooms/:id/sentinel/vote |
VAR Sentinel vote |
POST |
/api/rooms/:id/mood |
Mood tap |
POST |
/api/rooms/:id/replay/* |
prepare / start / pause |
POST |
/api/proof/verify |
Proof + optional on-chain check |
WS |
/ws/rooms/:id |
Realtime fanout |
| Layer | Tech |
|---|---|
| Frontend | Next.js 15, React 19, TypeScript, Tailwind v4, Zustand, TanStack Query, Framer Motion, Recharts |
| Backend | Node ≥20, Fastify 5, Zod, WebSocket, Pino |
| Chain | Solana web3.js, Anchor 0.30, TxOracle IDL, validateStatV2 |
| Data | TxLINE fixtures · scores · odds · Merkle proofs |
Clutch and Sentinel are social streaks only. CHORUS does not take bets, stake tokens, or settle real money. Odds Weather is market atmosphere from consensus prices — not a bookmaker ticket. Participants must comply with applicable laws in their jurisdiction.
- Technical overview for submission:
tech_docs.md - TxLINE builder feedback:
feedback.txt - Backend notes:
backend/README.md - Frontend notes:
frontend/README.md
Hackathon submission — see repository terms. TxLINE / TxODDS data access subject to TxODDS terms and hackathon rules.