13fd2b8989c9773ad5b632552a6eb87fe68ec2c4
- Replace Redis/in-memory storage with SQLite for persistence - Add database.ts service with tables for users, groups, purchases, participants - Update state.ts and groupState.ts to use SQLite backend - Fix buyer_name to use display name instead of Telegram ID - Remove legacy reminder array handlers (now using 3-slot system) - Add better-sqlite3 dependency, remove ioredis - Update env.example with BOT_DATABASE_PATH option - Add data/ directory to .gitignore for database files
⚡ Lightning Lottery
A complete Bitcoin Lightning Network powered lottery system with instant payouts to Lightning Addresses.
Features
- ⚡ Lightning Fast: Instant ticket purchases and payouts via Lightning Network
- 🎲 Provably Fair: Cryptographically secure random number generation (CSPRNG)
- 🔐 Secure: Transaction-based ticket issuance, idempotent operations
- 🌐 Anonymous or Nostr: Buy tickets anonymously or login with Nostr
- 📱 Mobile First: Beautiful responsive design optimized for all devices
- 🏆 Automatic Payouts: Winners get paid automatically to their Lightning Address
- ⏰ Multiple Cycles: Support for hourly, daily, weekly, and monthly draws
- 🔄 Auto-Redraw: If payout fails, automatically selects a new winner
- 🎰 Random Tickets: Ticket numbers are randomly generated, not sequential
- 📊 Swagger Docs: Full API documentation at
/api-docs
Architecture
The system consists of three main components:
- Backend API (Node.js + TypeScript + Express)
- Frontend (Next.js + React + TypeScript + TailwindCSS)
- Database (PostgreSQL or SQLite)
Backend
- RESTful API with comprehensive endpoints
- LNbits integration for Lightning payments
- Automated scheduler for draws and cycle generation
- JWT authentication for Nostr users
- Admin API for manual operations
- Payment monitoring with polling fallback
- Webhook support for instant payment confirmation
Frontend
- Server-side rendered Next.js application
- Redux state management
- Real-time countdown timers
- Invoice QR code display with payment animations
- Automatic status polling
- Nostr NIP-07 authentication
- Draw animation with winner reveal
- Past winners display
Quick Start
Using Docker Compose (Recommended)
- Clone the repository:
git clone <repository-url>
cd LightningLotto
- Configure environment:
cp back_end/env.example back_end/.env
cp front_end/env.example front_end/.env.local
# Edit both files with your configuration
- Start services:
docker-compose up -d
- Access the application:
- Frontend: http://localhost:3001
- Backend API: http://localhost:3000
- API Docs: http://localhost:3000/api-docs
- Health check: http://localhost:3000/health
Manual Setup
Backend
cd back_end
npm install
cp env.example .env
# Edit .env with your configuration
# For PostgreSQL:
createdb lightning_lotto
psql lightning_lotto < src/database/schema.sql
# For SQLite (default, no setup needed):
# Database file created automatically at data/lightning_lotto.db
# Run development server
npm run dev
# Or build and run production
npm run build
npm start
Frontend
cd front_end
npm install
cp env.example .env.local
# Edit .env.local
# Run development server
npm run dev
# Or build and run production
npm run build
npm start
Configuration
Required Environment Variables
Backend (.env)
# Database (PostgreSQL or SQLite)
DATABASE_URL=postgresql://user:pass@localhost:5432/lightning_lotto
# Or for SQLite (leave DATABASE_URL empty or use):
USE_SQLITE=true
# LNbits Configuration
LNBITS_API_BASE_URL=https://your-lnbits-instance.com
LNBITS_ADMIN_KEY=your-lnbits-admin-key
LNBITS_WEBHOOK_SECRET=your-webhook-secret
# Security
JWT_SECRET=your-jwt-secret-min-32-chars
ADMIN_API_KEY=your-admin-api-key
# Lottery Settings
DEFAULT_TICKET_PRICE_SATS=1000
DEFAULT_HOUSE_FEE_PERCENT=5
PAYOUT_MAX_ATTEMPTS_BEFORE_REDRAW=2
Frontend (.env.local)
NEXT_PUBLIC_API_BASE_URL=http://localhost:3000
See back_end/env.example and front_end/env.example for all configuration options.
API Endpoints
Public Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /jackpot/next |
Get next upcoming draw |
| POST | /jackpot/buy |
Purchase tickets |
| GET | /jackpot/past-wins |
List past winners |
| GET | /tickets/:id |
Check ticket status |
User Endpoints (Nostr Auth)
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/nostr |
Authenticate with Nostr |
| GET | /me |
Get user profile |
| PATCH | /me/lightning-address |
Update Lightning address |
| GET | /me/tickets |
User's ticket history |
| GET | /me/wins |
User's win history |
Admin Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /admin/cycles |
List all cycles |
| POST | /admin/cycles/:id/run-draw |
Manually trigger draw |
| GET | /admin/payouts |
List payouts |
| POST | /admin/payouts/:id/retry |
Retry failed payout |
Webhooks
| Method | Endpoint | Description |
|---|---|---|
| POST | /webhooks/lnbits/payment |
LNbits payment callback |
Full API documentation available at /api-docs (Swagger UI).
Database Schema
7 main tables:
lotteries- Lottery configurationjackpot_cycles- Draw cycles with status and winnersticket_purchases- Purchase records with Lightning invoice infotickets- Individual tickets with random serial numberspayouts- Winner payouts with retry logicusers- Nostr user accounts (optional)draw_logs- Audit trail for transparency
How It Works
- Cycle Generation: Scheduler automatically creates future draw cycles
- Ticket Purchase: Users buy tickets, receive Lightning invoice
- Payment Processing: LNbits webhook or polling confirms payment
- Ticket Issuance: Random ticket numbers assigned in database transaction
- Draw Execution: At scheduled time, winner selected using CSPRNG
- Payout: Winner's Lightning Address paid automatically
- Retry/Redraw: Failed payouts retried; new winner drawn after max attempts
Security Features
- JWT tokens for user authentication
- Admin API key protection
- Webhook signature verification
- Rate limiting on all endpoints
- Idempotent payment processing
- Database transactions for atomic operations
crypto.randomBytes()for winner selectioncrypto.randomInt()for ticket number generation- No floating-point math (BIGINT for all sats)
Frontend Pages
| Page | Description |
|---|---|
/ |
Home page with jackpot countdown and winner display |
/buy |
Purchase tickets with Lightning invoice |
/tickets/:id |
View ticket status and draw results |
/past-wins |
Public list of past winners |
/about |
About page with how it works |
/dashboard |
User dashboard (Nostr login required) |
/dashboard/tickets |
User's ticket history |
/dashboard/wins |
User's win history |
Testing
Backend Tests
cd back_end
npm test
Frontend Tests
cd front_end
npm test
Deployment
Production Considerations
- Use strong secrets for
JWT_SECRETandADMIN_API_KEY - Configure proper CORS origins in backend
- Use SSL/TLS (HTTPS) for all connections
- Set up monitoring and logging
- Configure database backups
- Set up proper firewall rules
- Consider using a CDN for frontend
- Use PostgreSQL for production (SQLite for development)
Scaling
- Backend is stateless and can be horizontally scaled
- Use connection pooling for database
- Consider Redis for caching
- Use message queue for high-volume webhooks
Monitoring
Health check endpoint:
curl http://localhost:3000/health
Returns database and LNbits connectivity status.
Project Structure
LightningLotto/
├── back_end/
│ ├── src/
│ │ ├── config/ # Configuration and Swagger setup
│ │ ├── controllers/ # Route handlers
│ │ ├── database/ # Database wrapper and schema
│ │ ├── middleware/ # Auth and rate limiting
│ │ ├── routes/ # API routes
│ │ ├── scheduler/ # Automated jobs
│ │ ├── services/ # Business logic
│ │ ├── types/ # TypeScript types
│ │ └── utils/ # Validation helpers
│ └── data/ # SQLite database (if used)
├── front_end/
│ └── src/
│ ├── app/ # Next.js pages
│ ├── components/ # React components
│ ├── config/ # Frontend config
│ ├── constants/ # Text strings
│ ├── lib/ # API client and utilities
│ └── store/ # Redux state
└── docker-compose.yml
License
MIT License - see LICENSE file for details
Acknowledgments
- Built with LNbits for Lightning Network integration
- Uses Nostr for decentralized authentication
- Inspired by the Bitcoin Lightning Network community
⚡ Win Bitcoin on the Lightning Network! ⚡
Description
Languages
TypeScript
98.9%
CSS
0.5%
Dockerfile
0.4%
JavaScript
0.2%