A prediction market application built on Demos Network where users bet on dice roll outcomes using DEM cryptocurrency.
Kybos is a real-money prediction market for d20 dice rolls. Users connect their Demos Network wallet, place bets on dice outcomes (high/low, even/odd, exact numbers, or ranges), and win payouts based on blockchain-verified random dice rolls.
The application uses Decentralized Autonomous Honest Randomness (DAHR) to ensure provably fair dice rolls, with all results verifiable on the Demos blockchain.
- Four bet types: High/Low, Even/Odd, Exact Number, Range (1-10)
- Real-time dice roll updates via WebSocket
- Blockchain-verified payment transactions
- Automatic payout processing for winning bets
- Full betting history tracking
- Responsive design for mobile and desktop
- React 18 with TypeScript
- Vite build system
- Zustand for state management
- TailwindCSS for styling
- Demos SDK for wallet integration
- Bun runtime with TypeScript
- Hono web framework
- SQLite database for persistence
- Redis for caching and real-time state
- WebSocket for live updates
- Demos Network for payments and identity
- DAHR (Decentralized Autonomous Honest Randomness) for dice rolls
- On-chain transaction verification
- Docker and Docker Compose installed
- Demos Network wallet mnemonic for server
- Domain names configured:
kybos.demos.sh- Frontendbackendkybos.demos.sh- Backend API
Create a .env file in the project root:
# Backend Configuration
SERVER_MNEMONIC=your_twelve_word_mnemonic_here
DEMOS_RPC_URL=https://node2.demos.sh
PORT=3001
NODE_ENV=production
DICE_ROLL_INTERVAL=60000
DATABASE_URL=./data/dice_rolls.db
REDIS_URL=redis://redis:6379
# Frontend Configuration
VITE_BACKEND_URL=https://backendkybos.demos.sh
VITE_WEBSOCKET_URL=wss://backendkybos.demos.sh/ws
VITE_DEMOS_RPC_URL=https://node2.demos.sh# Start all services
docker-compose -f docker-compose.prod.yml up -d
# View logs
docker-compose -f docker-compose.prod.yml logs -f
# Stop services
docker-compose -f docker-compose.prod.yml down
# Restart specific service
docker-compose -f docker-compose.prod.yml restart backendThe production setup includes:
- frontend - React application (port 80)
- backend - API server (ports 3001-3002)
- redis - Caching layer (port 6379)
- db-backup - Automated daily database backups
- nginx (optional) - Reverse proxy for SSL termination
All services include health checks for reliability:
# Backend health
curl https://backendkybos.demos.sh/health
# Frontend health (through reverse proxy)
curl https://kybos.demos.shAutomated backups run daily and are stored in ./backups/:
# List backups
ls -lh backups/
# Restore from backup
cp backups/dice_rolls_20250124_120000.db server/data/dice_rolls.db
docker-compose -f docker-compose.prod.yml restart backendBackups are automatically cleaned up after 7 days.
- Bun 1.0+ installed
- Node.js 18+ (for compatibility)
- Redis running locally
# Install dependencies
bun install
# Start backend
cd server
bun run dev
# Start frontend (in new terminal)
bun run dev- Frontend: http://localhost:3000
- Backend API: http://localhost:3001
- WebSocket: ws://localhost:3002/ws
Create .env files:
Root .env:
VITE_BACKEND_URL=http://localhost:3001
VITE_WEBSOCKET_URL=ws://localhost:3002/ws
VITE_DEMOS_RPC_URL=https://node2.demos.shserver/.env:
SERVER_MNEMONIC=your_development_mnemonic
DEMOS_RPC_URL=https://node2.demos.sh
PORT=3001All bet placement requires a valid Demos Network wallet signature.
Health check endpoint
{
"status": "healthy",
"services": {
"database": true,
"redis": true,
"diceService": true
}
}Get available betting markets
{
"success": true,
"data": [
{
"id": "high_low",
"title": "High or Low",
"description": "Bet if dice lands 11-20 (High) or 1-10 (Low)",
"status": "active"
}
]
}Place a bet with DEM payment
Headers:
X-Idempotency-Key: Unique request identifier (required)
Body:
{
"marketId": "high_low",
"userId": "0x...",
"prediction": "high",
"amount": 5,
"transactionHash": "0x..."
}Response:
{
"success": true,
"data": {
"id": "bet_abc123",
"status": "pending",
"prediction": "high",
"amount": 5
}
}Get most recent dice roll
{
"success": true,
"data": {
"result": 15,
"timestamp": 1706112000000,
"attestation_hash": "0x...",
"valid": true
}
}Get betting history for a user
{
"success": true,
"data": [
{
"id": "bet_123",
"prediction": "high",
"amount": 5,
"status": "won",
"payout": 10,
"created_at": 1706112000000
}
]
}Connect to /ws for real-time updates:
const ws = new WebSocket('wss://backendkybos.demos.sh/ws');
ws.onmessage = (event) => {
const { type, data } = JSON.parse(event.data);
switch (type) {
case 'dice_roll':
// New dice roll result
console.log('Roll:', data.result);
break;
case 'bet_verified':
// Bet payment verified
console.log('Bet verified:', data.betId);
break;
case 'bet_resolved':
// Bet outcome determined
console.log('Bet result:', data.status);
break;
}
};- Environment variable validation at startup
- Circuit breakers for RPC calls (30s timeout, auto-retry)
- Idempotency keys for duplicate bet prevention
- Transaction hash uniqueness constraints
- CORS restrictions to known domains
- Health checks for all services
- Automated database backups
- Enable rate limiting on reverse proxy
- Implement structured logging (Pino/Winston)
- Add Prometheus metrics for monitoring
- Set up blockchain payment verification
- Configure automated alerts for health check failures
See TODO.md for remaining production hardening tasks.
.
├── src/ # Frontend React application
│ ├── components/ # React components
│ ├── services/ # API and WebSocket clients
│ ├── stores/ # Zustand state management
│ └── lib/ # Utility functions
├── server/ # Backend Bun application
│ ├── src/
│ │ ├── services/ # Business logic services
│ │ ├── utils/ # Utilities and helpers
│ │ └── schemas/ # Validation schemas
│ └── data/ # SQLite database
├── docker-compose.prod.yml # Production deployment
├── Dockerfile.frontend # Frontend container
├── Dockerfile.backend # Backend container
└── backups/ # Database backups directory
Check environment variables:
docker-compose -f docker-compose.prod.yml exec backend env | grep SERVER_MNEMONICVerify reverse proxy WebSocket support:
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
https://backendkybos.demos.sh/wsStop all containers and restart:
docker-compose -f docker-compose.prod.yml down
docker-compose -f docker-compose.prod.yml up -dRPC endpoint is failing. Check Demos Network status:
curl https://node2.demos.shFor issues and questions:
- Check
TODO.mdfor known limitations - Review
PAYMENT_VERIFICATIONS.mdfor payment architecture - Consult Demos Network documentation: https://docs.demos.sh
Proprietary - All rights reserved