Skip to content

dharmanan/Arcium-poker

Repository files navigation

Arcium Poker (Crypto Bluff)

Privacy-first poker on Solana using Arcium’s privacy (MPC). Sensitive steps (shuffle, deal, hand evaluation) are intended to run through confidential MPC. A demo fallback keeps the game playable if devnet MPC callbacks are delayed.

This is an MVP prototype built for the Solana Hackathon, focused on demonstrating privacy-first gameplay and rapid iteration. It is not a final production release.

The Problem

Online poker has a trust problem. Players have to trust the house to shuffle fairly, deal cards honestly, and evaluate hands correctly. Even "provably fair" systems still require trusting a central authority at some point.

Our Solution

We use Arcium's Multi-Party Computation to handle the sensitive parts of the game in a way that nobody (not even us) can see or manipulate. The deck shuffle, card dealing, and hand evaluation happen through encrypted computations. The blockchain only stores encrypted data; the actual game logic runs securely off-chain through MPC.

What We Built

  • Confidential Card Shuffling: Deck shuffle is queued through MPC and encrypted on-chain (localnet only; devnet uses fallback)
  • Private Card Dealing: Player cards are encrypted with client keys and decrypted locally
  • Secure Hand Evaluation: Winner determination queued through MPC (localnet only; devnet uses fallback)
  • Demo Fallback: Deterministic flow keeps the game playable when MPC callbacks are unavailable
  • Bot Workers: Optional automated players for testing and demos

On devnet, MPC transactions are queued but callbacks may not arrive due to executor availability. The fallback ensures the game remains demoable. For full MPC with real callbacks, run localnet (see below).

Devnet On-Chain Evidence (Fallback)

The latest devnet transactions for the demo wallet show the explicit fallback instructions used when MPC callbacks are unavailable:

These confirm the devnet fallback path. Full MPC callbacks are currently verifiable on localnet runs only.

Devnet On-Chain Evidence (MPC Enqueue)

These devnet transactions show MPC enqueue instructions in program logs (e.g., QueueShuffleAndDealCardsV3, QueueProveEntryFee, QueueComputation):

Screenshots

Lobby Screen

Initial lobby screen

Players Joining

Players joining the table

Game in Progress

Poker game in progress

Project Structure (current)

Current Devnet Deployment

Live Demo (Offchain)

Chip Token (Demo Chips)

The UI creates a demo chip token on the current network the first time a wallet buys chips.

  • By default, the mint is per-wallet and stored in local storage.
  • For a fixed, shared chip mint, set VITE_CHIP_MINT in your local frontend env file.

Current shared devnet mint (demo):

Ew7gouQS6xNTtmoTVBvcNyHSW44g3KFR8dPdNZh8iT3W

Example:

VITE_CHIP_MINT=<YOUR_DEVNET_MINT_ADDRESS>

Quick Start (Recommended: Devnet Demo)

Prerequisites

  • Node.js 18+
  • A Solana wallet extension (Phantom or Backpack)

Install Dependencies

From the repository root:

npm install
cd frontend
npm install
cd ..

Configure Environment

Create a local env file in the frontend folder (this file is intentionally not committed).

Example:

VITE_SOLANA_RPC_URL=https://api.devnet.solana.com
VITE_SOLANA_CLUSTER=devnet
VITE_PROGRAM_ID=3JPRmpPsWuCAb6KiudBaPG2o5t7duJ55gobsEgK1WDZa
VITE_ARCIUM_CLUSTER_OFFSET=456
# Optional: fixed chip mint for all wallets
VITE_CHIP_MINT=Ew7gouQS6xNTtmoTVBvcNyHSW44g3KFR8dPdNZh8iT3W

Run the UI

cd frontend
npm run dev

This will start the dev server and print the local URL (typically http://localhost:3000).

Before Playing (Recommended: Auto Bots via Script)

We run the demo with automatic bots, so you don’t need to create multiple wallets manually.

  1. Prepare bot.env

    • Copy bot.env.examplebot.env
    • Fill in your bot keypairs as BASE64 (BOT_1/2/3)
    • Set BOT_HOST_KEYPAIR_PATH (host keypair file)
    • (Optional) Set BOT_HOST_PUBLIC_KEY and BOT_GAME_ID to lock the worker to a specific game
  2. Choose your bot mode

    • Trigger mode (default in bot.env.example):
      • BOT_REQUIRE_TRIGGER=true
      • The worker opens port 8787 and waits for the UI trigger
      • You must click “Bots On” in the game screen, otherwise bots will NOT start
    • Auto-detect mode:
      • Set BOT_REQUIRE_TRIGGER=false
      • No port is required; the worker auto-detects the latest WaitingForPlayers game
  3. Fund the host + bot keypairs

    • Generate host + bot keypairs and fill bot.env:
      # create keypairs
      mkdir -p .keys
      solana-keygen new -o .keys/host.json
      solana-keygen new -o .keys/bot_1.json
      solana-keygen new -o .keys/bot_2.json
      solana-keygen new -o .keys/bot_3.json
      
      # pubkeys
      solana-keygen pubkey .keys/bot_1.json
      solana-keygen pubkey .keys/bot_2.json
      solana-keygen pubkey .keys/bot_3.json
      
      # base64 secrets (paste into BOT_*_SECRET_BASE64)
      cat .keys/bot_1.json | python3 - <<'PY'
      import sys, json, base64
      data = json.load(sys.stdin)
      print(base64.b64encode(bytes(data)).decode())
      PY
    • Set BOT_HOST_KEYPAIR_PATH=.keys/host.json in bot.env.
    • Airdrop SOL to host + bots (devnet):
      solana airdrop 2 $(solana-keygen pubkey .keys/host.json) --url https://api.devnet.solana.com
      solana airdrop 2 $(solana-keygen pubkey .keys/bot_1.json) --url https://api.devnet.solana.com
      solana airdrop 2 $(solana-keygen pubkey .keys/bot_2.json) --url https://api.devnet.solana.com
      solana airdrop 2 $(solana-keygen pubkey .keys/bot_3.json) --url https://api.devnet.solana.com
    • For required envs and behavior, see scripts/bot-worker.ts.
  4. Run the bot worker (keep it running)

npm run bot:worker

Notes:

  • Recommended: run this in a separate terminal so the process keeps running while you use the UI.
  • If BOT_REQUIRE_TRIGGER=true (or BOT_WORKER_PORT is set), the worker opens an HTTP trigger on port 8787. The UI calls this when you click “Bots On”.
  • If BOT_REQUIRE_TRIGGER=false, no port is required; the worker auto-detects the latest game.
  • If you’re on Codespaces or a remote host, set VITE_BOT_WORKER_URL to your forwarded URL for port 8787.
  1. Run the UI and create a game
    • The bot worker auto-detects the new game (WaitingForPlayers) and joins it.
    • It bypasses entry fees and progresses the hand automatically.
    • Important: If your UI requires manual trigger, you must click “Bots On” on the game screen, otherwise bots will NOT start.
    • If you enable a “Bots On” button in the UI, it simply triggers the worker (when trigger mode is enabled).

If bots don’t move, double-check bot.env values and that the bot worker is running.

Devnet Demo Defaults

The UI uses devnet by default. If MPC callbacks do not arrive in time, the fallback keeps the game progressing. This behavior is controlled via VITE_MPC_MODE (default: devnet-fallback).

Full MPC (Advanced: Localnet)

For a complete MPC setup with real callbacks, you can run the full stack locally. This requires a local Solana validator and Arcium MXE nodes.

Prerequisites

  • Docker and Docker Compose
  • Solana CLI tools

Steps

  1. Start a local Solana validator

    solana-test-validator --reset
  2. Deploy the program to localnet

    arcium deploy --cluster-offset 0

    This will deploy the program and initialize MXE on localnet.

  3. Start the MXE nodes

    docker compose -f artifacts/docker-compose-arx-env.yml up -d
  4. Configure the frontend for localnet Create or update your local frontend env file:

    VITE_SOLANA_RPC_URL=http://localhost:8899
    VITE_SOLANA_CLUSTER=localnet
    VITE_PROGRAM_ID=<YOUR_LOCALNET_PROGRAM_ID>
    VITE_ARCIUM_CLUSTER_OFFSET=0
    VITE_MPC_MODE=localnet
    
  5. Run the frontend

    cd frontend
    npm run dev

With this setup, all MPC callbacks will be processed by your local executor nodes. The game will use real encrypted card shuffling and hand evaluation instead of the fallback.

Troubleshooting

  • 403 from RPC: your RPC endpoint is blocked or rate-limited. Switch VITE_SOLANA_RPC_URL in your local frontend env file to a public devnet RPC or your own provider.
  • 429 Too Many Requests: your RPC is rate-limiting. Set BOT_RPC_URL to a dedicated RPC (Helius/QuickNode), or pause and retry after a minute.
  • No chip balance: the chip mint is network-specific. If the mint is missing, mint chips again using the UI.

Key Files

Built With

  • Solana - Blockchain layer
  • Anchor - Solana program framework
  • Arcium MPC - Confidential computation
  • React + Vite - Frontend
  • TypeScript - Type safety throughout

License

MIT

About

The core privacy mechanism uses Arcium's Multi-Party Computation (MPC) to evaluate poker hands

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages