Michilis 3bc067f691 feat: display truncated lightning address for winners
- Add truncateLightningAddress utility (shows first 2 chars + ******)
- Backend: Include winner_address in past-wins API response
- Frontend: Display truncated address in past winners list
- Telegram: Add truncated address to draw announcements for transparency

Example: username@blink.sv -> us******@blink.sv
2025-12-12 16:20:18 +00:00

Lightning Lotto

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
  • Flexible Cycles: Configurable draw intervals (minutes, hours, days, weekly, or cron)
  • 🔄 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
  • 🤖 Telegram Bot: Full-featured bot for buying tickets and receiving notifications

Architecture

The system consists of four main components:

  1. Backend API (Node.js + TypeScript + Express)
  2. Frontend (Next.js + React + TypeScript + TailwindCSS)
  3. Telegram Bot (Node.js + TypeScript + node-telegram-bot-api)
  4. Database (PostgreSQL or SQLite)

Backend

  • RESTful API with comprehensive endpoints
  • LNbits integration for Lightning payments
  • Automated scheduler for draws and cycle generation
  • Configurable cycle types (minutes, hours, days, weekly, cron)
  • 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
  • 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
  • Fully responsive mobile-first design

Telegram Bot

  • Buy tickets directly from Telegram
  • Lightning Address management (with 21Tipbot & Bittip integration)
  • View tickets and wins
  • Notification preferences (draw reminders, results, new jackpot alerts)
  • Group support with admin controls
  • Customizable reminders (up to 3 reminder slots per group)
  • SQLite database for persistent user/group settings

Quick Start

  1. Clone the repository:
git clone <repository-url>
cd LightningLotto
  1. Configure environment:
cp back_end/env.example back_end/.env
cp front_end/env.example front_end/.env.local
cp telegram_bot/env.example telegram_bot/.env
# Edit all files with your configuration
  1. Start services:
docker-compose up -d
  1. Access the application:

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

Telegram Bot

cd telegram_bot
npm install
cp env.example .env
# Edit .env with your bot token and API URL

# 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

# Cycle Configuration (choose one type)
CYCLE_TYPE=hours                    # minutes | hours | days | weekly | cron
CYCLE_INTERVAL_MINUTES=30           # For 'minutes' type
CYCLE_INTERVAL_HOURS=1              # For 'hours' type
CYCLE_DAILY_TIME=20:00              # For 'days' type (HH:MM UTC)
CYCLE_WEEKLY_DAY=saturday           # For 'weekly' type
CYCLE_WEEKLY_TIME=20:00             # For 'weekly' type (HH:MM UTC)
CYCLE_CRON_EXPRESSION=0 */6 * * *   # For 'cron' type

Frontend (.env.local)

NEXT_PUBLIC_API_BASE_URL=http://localhost:3000

Telegram Bot (.env)

TELEGRAM_BOT_TOKEN=your-telegram-bot-token
API_BASE_URL=http://localhost:3000
FRONTEND_BASE_URL=http://localhost:3001
# BOT_DATABASE_PATH=./data/bot.db  # Optional, defaults to ./data/bot.db

See back_end/env.example, front_end/env.example, and telegram_bot/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).

Telegram Bot Commands

Private Chat Commands

Command Description
/start Start the bot and register
/lottomenu Show main menu
/buyticket Buy lottery tickets
/tickets View your tickets
/wins View your wins
/lottoaddress Set your Lightning Address
/lottosettings Notification settings
/lottohelp Show help

Group Commands (Admin Only)

Command Description
/lottosettings Configure group lottery settings
/jackpot Show current jackpot info

Group Features

  • Enable/disable draw announcements
  • Enable/disable new jackpot alerts
  • Up to 3 customizable draw reminders
  • Adjustable reminder times (minutes/hours/days)
  • Auto-deleting settings messages (2 min TTL)

Database Schema

Backend Database (7 main tables)

  • lotteries - Lottery configuration
  • jackpot_cycles - Draw cycles with status and winners
  • ticket_purchases - Purchase records with Lightning invoice info
  • tickets - Individual tickets with random serial numbers
  • payouts - Winner payouts with retry logic
  • users - Nostr user accounts (optional)
  • draw_logs - Audit trail for transparency

Telegram Bot Database (SQLite)

  • users - Telegram user profiles and notification preferences
  • user_purchases - Tracks purchases per user
  • cycle_participants - Tracks participants per cycle
  • groups - Group settings and reminder configurations

How It Works

  1. Cycle Generation: Scheduler automatically creates future draw cycles
  2. Ticket Purchase: Users buy tickets via web or Telegram, receive Lightning invoice
  3. Payment Processing: LNbits webhook or polling confirms payment
  4. Ticket Issuance: Random ticket numbers assigned in database transaction
  5. Draw Execution: At scheduled time, winner selected using CSPRNG
  6. Notifications: Telegram bot sends draw results to participants and groups
  7. Payout: Winner's Lightning Address paid automatically
  8. 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 selection
  • crypto.randomInt() for ticket number generation
  • No floating-point math (BIGINT for all sats)
  • Lightning Address LNURL verification

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

Production Deployment

Systemd Services & Nginx

The setup/ folder contains production-ready configuration files:

  • lightning-lotto-backend.service - Backend systemd service
  • lightning-lotto-frontend.service - Frontend systemd service
  • lightning-lotto-telegram.service - Telegram bot systemd service
  • nginx-lightning-lotto.conf - Nginx reverse proxy with SSL

See setup/README.md for detailed deployment instructions.

Production Considerations

  1. Use strong secrets for JWT_SECRET and ADMIN_API_KEY
  2. Configure proper CORS origins in backend
  3. Use SSL/TLS (HTTPS) for all connections
  4. Set up monitoring and logging
  5. Configure database backups
  6. Set up proper firewall rules
  7. Consider using a CDN for frontend
  8. 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
├── telegram_bot/
│   ├── src/
│   │   ├── config/         # Bot configuration
│   │   ├── handlers/       # Command and callback handlers
│   │   ├── messages/       # Centralized message strings
│   │   ├── services/       # Database, API, notifications
│   │   ├── types/          # TypeScript types
│   │   └── utils/          # Keyboards, formatting
│   └── data/               # SQLite database for bot
├── setup/                  # Production deployment configs
│   ├── *.service           # Systemd service files
│   ├── nginx-*.conf        # Nginx configuration
│   └── README.md           # Deployment guide
├── App_info/               # Documentation
└── docker-compose.yml

Testing

Backend Tests

cd back_end
npm test

Frontend Tests

cd front_end
npm test

License

MIT License - see LICENSE file for details

Acknowledgments

  • Built with LNbits for Lightning Network integration
  • Uses Nostr for decentralized authentication
  • Telegram bot integration for mobile-first experience
  • Inspired by the Bitcoin Lightning Network community

Win Bitcoin on the Lightning Network!

Description
Lightning Lottery app
Readme 641 KiB
Languages
TypeScript 98.9%
CSS 0.5%
Dockerfile 0.4%
JavaScript 0.2%