Technical Documentation
Architecture, integration guides, and API reference for ProofPlay Markets
ProofPlay Markets is a verifiable prediction market dApp for World Cup matches. Users create rooms, pick a side, stake SOL, and earn payouts when the match ends — all verified through TxLINE's real-time sports data oracle with settlement receipts anchored on Solana Devnet.
The system uses Next.js 15 API routes as the backend, with an Anchor program on Solana for on-chain market state. TxLINE provides real-time match data and Merkle-verified results.
- Next.js 15 App Router (React 19)
- Privy wallet auth (Solana)
- Tailwind CSS v4, glass UI
- Phantom wallet integration
- Next.js API routes (serverless)
- Vercel KV for room persistence
- Anchor + @coral-xyz/anchor SDK
- TxLINE REST + SSE client
The Anchor program manages prediction markets on-chain. Each fixture has one market PDA. Participants join via a derived participant PDA.
// Program IDD254EggCVsZ7jKtJJ29diEv3P4qqjn5APBAvcRwDNsyE// Market PDA seeds[b"market", creator, fixtureId_le]// Participant PDA seeds[b"participant", market, wallet]
- initializeMarket — Create a new market PDA
- joinMarket — Join with stake, creates participant PDA
- lockMarket — Lock before kickoff
- settleMarket — Settle with winner + merkle root
- claimPayout — Winner claims SOL from pool
- Market — Fixture ID, market type, threshold, status, participants, total stake
- Participant — Wallet, side, amount, claimed flag
All room management is handled through Next.js API routes under /api/rooms.
| Route | Method | Description |
|---|---|---|
| /api/rooms | POST | Create a new prediction room |
| /api/rooms | GET | List all rooms |
| /api/rooms/[id] | GET | Get room details |
| /api/rooms/[id]/join | POST | Join a room |
| /api/rooms/[id]/lock | POST | Lock room at kickoff |
| /api/rooms/[id]/settle | POST | Settle with TxLINE proof |
| /api/rooms/[id]/claim | POST | Build claim transaction |
| /api/rooms/[id]/claim/submit | POST | Submit payout |
| /api/rooms/[id]/receipt | GET | Get settlement receipt |
| /api/txline/fixtures | GET | List all fixtures |
| /api/txline/scores/[id] | GET | Get score snapshot |
| /api/txline/stream | GET | SSE score stream |
TxLINE is the real-time sports data oracle. All match data — scores, status, stats — flows through TxLINE's API with Merkle-tree based verification for on-chain settlement.
Authorization: BearerX-Api-Token[
{
"FixtureId": 123,
"Seq": 42,
"StatusId": 5,
"Score": {
"Participant1": { "Total": { "Goals": 2 } },
"Participant2": { "Total": { "Goals": 1 } }
},
"Clock": { "Seconds": 5580 }
}
]Settlement is triggered by the room creator after the match ends. The system fetches the final score from TxLINE, validates it with a Merkle proof, and records the result.
GET /api/scores/snapshot/{fixtureId} — retrieves the latest score event with StatusId 5/7/9 (finished)
Goal Rush: total goals vs threshold | Winner Pick: HOME/AWAY/DRAW based on scores
POST /api/scores/stat-validation — requests a Merkle proof for the winning stat
Calls settleMarket on the Anchor program with the winner side + merkle root
Stores the full settlement receipt: score, validation, merkle root, payout summary
Winner signs a claim transaction → server sends SOL from the pool to their wallet
Run the project locally to explore the full flow.
# 1. Clone and installgit clone https://github.com/Saber1Y/ProofPlayMarkets cd ProofPlayMarkets npm install --legacy-peer-deps# 2. Set up environmentcp .env.example .env# Add TXLINE_JWT, TXLINE_API_TOKEN, NEXT_PUBLIC_PRIVY_APP_ID# 3. Run locally (SSL workaround for expired devnet cert)NODE_TLS_REJECT_UNAUTHORIZED=0 npm run dev# 4. Open http://localhost:3000
- • Node.js 18+
- • Phantom wallet (Solana devnet)
- • Devnet SOL from faucet.solana.com
- • TxLINE API credentials