Confidential Texas Hold’em on Inco Lightning + Megapot Sealed River
pi River is a production-style heads-up poker product: Google sign-in, silent Base Sepolia play wallets, Inco-encrypted hole cards, fun-chip progression, cosmetics shop, club chat, and real Megapot ticket claims — one live URL for both jam tracks.
| Live app | https://pi.sithunyein.com |
| Network | Base Sepolia (84532) |
| Jam | Inco × Megapot Summer Game Jam (submit once per track) |
| Surface | What players get |
|---|---|
| Table | Heads-up Hold’em vs bot / friends · buy-in on-chain · encrypted holes until sealed showdown |
| Inco | shuffledRange deal · player-only attestedDecrypt · covalidator-backed reveal |
| Megapot | Ticket credits on wins · house-minted NFT via JackpotRandomTicketBuyer (source=pi-river) |
| Progress | Daily bonus (UTC once/day) · missions · achievements · durable cloud sync (Supabase) |
| Shop | Frames & stickers · chip packs (on-chain deposit → credit) |
| Social | Live club chat · ladder presence · friend challenges · public profiles |
flowchart TB
subgraph Client["Next.js App Router · Vercel"]
UI["Shell UI<br/>Lobby · Table · Shop · Rewards · Profile"]
GC["GameContext<br/>progress · cosmetics · wallet session"]
WG["wagmi / viem<br/>silent play wallet"]
end
subgraph Auth["Identity"]
SB["Supabase Auth<br/>Google OAuth"]
ID["Silent play wallet<br/>Google-bound key in browser storage"]
end
subgraph Chain["Base Sepolia"]
RH["RiverHoldem<br/>Inco Lightning holes"]
RC["RiverChips / economy"]
MP["Megapot<br/>RandomTicketBuyer"]
end
subgraph Server["API routes · house key"]
API["/api/progress · chips · megapot<br/>rewards · chat · players"]
DRIP["ETH drip · USDC mint · ticket buy"]
end
subgraph Data["Supabase"]
PP["player_progress"]
CH["club_chat"]
OW["owned frames / stickers"]
end
UI --> GC --> WG
UI --> SB --> ID --> WG
WG --> RH
WG --> RC
UI --> API
API --> PP
API --> CH
API --> OW
API --> DRIP --> MP
API --> RH
RH -. encrypt / decrypt .-> Inco["Inco Lightning TEE"]
sequenceDiagram
participant P as Player (play wallet)
participant App as pi River
participant RH as RiverHoldem
participant I as Inco Lightning
App->>RH: start / buy-in
RH->>I: shuffledRange + encrypted deal
I-->>RH: encrypted hole handles
RH-->>P: encrypted holes (only P can decrypt)
P->>I: attestedDecrypt (own holes)
I-->>P: plaintext for local UI
Note over RH,I: Opponent holes stay sealed until showdown
App->>RH: showdown
RH->>I: verify covalidator attestations
RH-->>App: reveal + settle
flowchart LR
W[Win hand] --> C[Ticket credit in progress]
C --> R[Rewards → Claim]
R --> API["/api/megapot/claim"]
API --> Buy[House calls RandomTicketBuyer]
Buy --> NFT[Megapot NFT → play wallet]
- Open Live → Google sign-in
- Quick Play / vs Bot — fold / check with zero MetaMask (silent play wallet)
- Watch Inco · encrypted holes until sealed showdown reveal
- Win a hand → toast / overlay credits a Megapot ticket (progression credit)
- Rewards → Claim Megapot ticket
- House buys a real Megapot NFT via
JackpotRandomTicketBuyerto your play wallet on Base Sepolia (source=pi-river)
| Layer | Choice |
|---|---|
| App | Next.js 15 · React 19 · TypeScript · Tailwind |
| Chain | Base Sepolia · viem · wagmi |
| Privacy | Inco Lightning (@inco/lightning-js) |
| Jackpot | Megapot Sealed River buyer contracts |
| Auth / DB | Supabase (Google + player_progress + chat) |
| Contracts | Foundry (contracts/) |
| Deploy | Vercel |
pi-river/
├── public/
│ ├── brand/
│ │ ├── mi-mark.svg # App logo (favicon / README)
│ │ └── …
│ ├── frames/ # Avatar ornate frames
│ ├── stickers/ # Shop / chat stickers
│ └── audio/
├── src/
│ ├── app/
│ │ ├── (shell)/ # Lobby, table, shop, rewards, profile
│ │ ├── api/ # progress, chips, megapot, rewards, chat, …
│ │ └── auth/ # OAuth callbacks
│ ├── components/ # Table UI, shop, chat, overlays
│ ├── context/GameContext.tsx # Client game + progress state
│ ├── hooks/ # Ladder / seat presence
│ └── lib/
│ ├── inco/ # Encrypt / decrypt helpers
│ ├── megapot/ # Ticket claim client
│ ├── wallet/ # Silent play wallet
│ ├── cloudProgress.ts # Supabase merge / flush
│ ├── missions.ts
│ ├── frames.ts · stickers.ts
│ └── …
├── contracts/
│ ├── src/
│ │ ├── RiverHoldem.sol # Confidential Hold’em table
│ │ ├── RiverChips.sol # Chip economy
│ │ ├── RiverClub.sol
│ │ ├── CardLib.sol · HoldemEval.sol
│ │ └── kit/ConfidentialDeck.sol
│ └── script/ # Foundry deploys
├── supabase/
│ ├── migrations/ # 001…008 durable progress / shop / daily
│ └── FULL_SETUP.sql # One-shot paste for empty projects
├── scripts/ # Asset generators (stickers, crops)
├── package.json
└── README.md
bun install
cp .env.example .env.local
# Fill Supabase + contract addresses
# PRIVATE_KEY = house/bot wallet (ETH drip + Megapot USDC mint) — local / Vercel only
bun run devOptional: apply supabase/FULL_SETUP.sql (or migrations 001–008) in the Supabase SQL editor.
| Contract | Notes |
|---|---|
| RiverHoldem | NEXT_PUBLIC_RIVER_HOLDEM_ADDRESS |
| Megapot Jackpot | 0x465dA3c859f193A3807386387bEE941B2A4c3279 |
| Megapot RandomBuyer | 0x53c04e7e5044B28Ea8A4F9c4b26E3Ac1aeb63746 |
Fun chips / shop cosmetics are progression. Table buy-in + Megapot tickets are on-chain testnet.
App logo (same as in-app / favicon): public/brand/mi-mark.svg
See .env.example. Never commit PRIVATE_KEY or .env.local.
Typical production keys (Vercel):
NEXT_PUBLIC_SUPABASE_URL/NEXT_PUBLIC_SUPABASE_ANON_KEYNEXT_PUBLIC_RIVER_HOLDEM_ADDRESS(+ chips / club if used)PRIVATE_KEY(house — drip, Megapot mint)- Base Sepolia RPC URLs
Summer Game Jam week (Aug 2026). Dual-track product on one URL — submit separately for Inco and Megapot tracks per Typeform rules.
| Doc | |
|---|---|
| License | MIT |
| Security | SECURITY.md — report vulns privately, not as public issues |
| Contributing | CONTRIBUTING.md |
Built with Inco Lightning · Megapot · Base Sepolia · Supabase · Next.js