A fast, privacy-friendly Pong with self custodial bets, built on the Bison Relay network.
Self‑custodial with Schnorr adaptor signatures. You fund your own escrow pkscript, bet and play.
- Self‑custodial escrow – You fund a script you control (P2SH). The server never holds your funds.
- Schnorr adaptor settlement – Matches resolve by revealing a secret embedded in a final Schnorr signature, unlocking the winner’s payout without giving custody to anyone in the middle.
- Safety valve (CSV timeout) – If settlement stalls, the redeem script includes a CSV (relative timelock) refund path so you can reclaim funds.
- Privacy by design – Bison Relay RPC authentication with payment and messages over an end‑to‑end, censorship‑resistant network.
- 🏓 Real‑time Pong (Terminal UI with Bubble Tea, or Flutter UI)
- 💸 Escrow‑backed betting in DCR
- 🎯 Waiting rooms & matchmaking by stake
- 🔔 In‑app notifications
- Create your self‑escrow. The client derives a redeem script from your public key and safety params (e.g., CSV blocks). It shows a script address (P2SH) for you to fund.
- Fund it. Send DCR to that address. The bot sees your funding tx (mempool or after N confirms—policy dependent) and marks your escrow “ready.”
- Join or create a waiting room. Rooms are grouped by the stake available in your escrow.
- Play the match. First to 3 points wins.
- Settlement via Schnorr adaptor. The winner learns a secret (γ) from the final signature and uses it to unlock the payout from the escrow script.
- Timeout fallback. If something goes wrong, you can reclaim funds after the CSV timeout with your own key.
Self‑custody note: If you see a “deposit address,” it’s a script address you control. The server cannot move your funds. The script is constructed from your key and rules you can verify.
- Go 1.22+
- Bison Relay client running with RPC enabled (brclient or bruig)
- (Optional) Flutter if you want the GUI
Bot (referee & API)
go build -o pongbot ./cmd/pongbotTerminal Client
go build -o pongclient ./cmd/pongclientFlutter UI
cd pongui
# See detailed steps in pongui/README.mdStart the server (bot):
./pongbotStart the terminal client:
./pongclientStart the Flutter UI:
cd pongui
# run via Flutter tooling (see pongui/README.md)Your Bison Relay RPC must be enabled and reachable. On first run, each component creates a config file with defaults that you can edit.
- Bot config:
{appdata}/.pongbot/pongbot.conf - Terminal client config:
{appdata}/.pongclient/pongclient.conf - Flutter client config:
{appdata}/.pongui/pongui.conf
Example BR RPC (clientrpc) config
[clientrpc]
jsonrpclisten = 127.0.0.1:7676
rpccertpath = /home/{user}/.brclient/rpc.cert
rpckeypath = /home/{user}/.brclient/rpc.key
rpcuser = your_user
rpcpass = your_pass
rpcauthmode = basic
rpcclientcapath = /home/{user}/.brclient/rpc-ca.cert
rpcissueclientcert = 1Example bot config
datadir=/home/{user}/.pongbot
isf2p=false
minbetamt=0.00000001
rpcurl=wss://127.0.0.1:7676/ws
grpchost=localhost
grpcport=50051
httpport=8888
servercertpath=/home/{user}/.brclient/rpc.cert
clientcertpath=/home/{user}/.brclient/rpc-client.cert
clientkeypath=/home/{user}/.brclient/rpc-client.key
rpcuser=your_user
rpcpass=your_pass
debug=debugExample terminal client config
serveraddr=localhost:50051
rpcurl=wss://127.0.0.1:7676/ws
servercertpath=/home/{user}/.brclient/rpc.cert
clientcertpath=/home/{user}/.brclient/rpc-client.cert
clientkeypath=/home/{user}/.brclient/rpc-client.key
grpcservercert=/home/{user}/server.cert
rpcuser=your_user
rpcpass=your_passExample Flutter client config
serveraddr={server_ip_or_localhost}:50051
rpcurl=wss://127.0.0.1:7676/ws
servercertpath=/home/{user}/.brclient/rpc.cert
clientcertpath=/home/{user}/.brclient/rpc-client.cert
clientkeypath=/home/{user}/.brclient/rpc-client.key
grpcservercert=/home/{user}/server.cert
rpcuser=your_user
rpcpass=your_pass- Client shows a script address (P2SH).
- You send DCR to it (any wallet).
- Bot detects your funding tx and marks your escrow as available stake.
- You can now enter rooms that match your available stake.
The redeem script: P2SH(pk, CSV) — spend path (winner via adaptor‑revealed secret) and a refund path after CSV with your own key.
- Fund your escrow pkscript (above).
- Create or join a waiting room that matches your available stake.
- Ready up. When both players are ready, the match starts.
- Controls: W/S or ↑/↓.
- First to 3 points wins. Winner unlocks the escrow payout.
- Minimum Stake: set by the bot (
minbetamt, default0.00000001 DCR). - Free‑to‑Play:
isf2p=trueuses simulated escrows for testing. - CSV Timeout: protects you if settlement is delayed; you can refund after the relative timelock.
- Connectivity: confirm your Bison Relay client is connected before playing.
- gRPC API: see
pongrpc/README.md - Flutter UI: see
pongui/README.md
If funds are self‑custodial, why do I see a “deposit address”?
That’s a script address you control (P2SH). The redeem script is built from your public key and safety parameters (like a CSV timeout). It’s not a server wallet.
How does Schnorr adaptor settlement work here?
Before the match, the protocol prepares signatures so that the final winner’s signature reveals a secret (γ). Knowing γ lets the winner satisfy the script’s spend path and unlock the payout—without giving the server custody of anyone’s funds.
You can see more about it here
What if settlement fails?
Wait the configured CSV period, then use the refund path with your key to reclaim your funds.

