- ✅ Server-side rendered web app using Axum + Maud
- ✅ Dark theme with Tailwind CSS and Flowbite components
- ✅ Responsive design for mobile and desktop
- ✅ Persistent SQLite database with automatic migrations
- ✅ Create treasure locations with:
- Name and description
- GPS coordinates (manual entry or device GPS)
- Photo uploads (multiple images per location)
- Configurable maximum satoshi capacity
- ✅ Interactive map view using Leaflet.js
- Color-coded markers (green = full, yellow = partial, red = low)
- Click markers for location details
- Automatic map bounds fitting
- Dark theme map tiles
- ✅ Location detail pages with:
- Current sat balance and fill percentage
- Photo gallery
- Interactive map
- Statistics display
- ✅ LNURL-withdraw implementation (LUD-03 compliant)
- ✅ NFC sticker support via LNURL
- ✅ Unique LNURL secrets per location
- ✅ Withdrawal callback handling
- ✅ One-time setup tokens for NFC writing
- ✅ QR code generation for NFC setup
- ✅ Scan history tracking
- ✅ Global donation pool (database-backed)
- ✅ Background service for automatic refills
- ✅ Configurable refill rate (sats per hour)
- ✅ Per-location maximum capacity
- ✅ Last refill timestamp tracking
- ✅ Donation pool depletion prevention
- ✅ Real-time stats on landing page:
- Total locations
- Total sats available across all locations
- Total scans/withdrawals
- Current donation pool balance
- ✅ Scan history with timestamps
- ✅ Per-location withdrawal tracking
-
Landing Page (
/)- Game explanation
- How it works (3-step guide)
- Live statistics
- Call-to-action buttons
-
Map View (
/map)- Interactive Leaflet map
- Color-coded location markers
- Location list with details
- Sat balances for each location
-
New Location (
/locations/new)- Location creation form
- GPS coordinate picker
- "Use My Location" button
- Live map preview with draggable marker
- Multi-photo upload
- Max sats configuration
-
Location Detail (
/locations/:id)- Full location information
- Photo gallery
- Current sat balance with progress bar
- Location coordinates and map
- Back navigation
-
NFC Setup (
/setup/:write_token)- One-time setup instructions
- QR code for NFC writing apps
- LNURL display
- Usage warnings
GET /- Landing pageGET /map- Treasure mapGET /locations/new- Create location formGET /locations/:id- Location detailsGET /setup/:write_token- NFC setup (one-time use)
POST /api/locations- Create location (multipart/form-data)GET /api/lnurlw/:location_id- LNURL-withdraw initial requestGET /api/lnurlw/:location_id/callback- LNURL withdrawal executionGET /api/stats- Global statistics (JSON)
/uploads/*- Uploaded photos
Tables:
locations- Treasure locations with coordinates, balances, LNURL secretsphotos- Location photos with file pathsdonation_pool- Global sat pool (singleton)scans- Withdrawal history
Indexes:
- Coordinate-based location search
- Photo lookups by location
- Time-based scan queries
- Environment variable-based configuration
- Configurable refill rates
- Adjustable server host/port
- Custom upload directories
- Base URL for LNURL callbacks
- Automatic location refill service (runs every 5 minutes)
- Donation pool management
- Safe concurrent access with Arc
- Framework: Axum 0.7 (fast, type-safe routing)
- Templates: Maud (compile-time HTML templates)
- Database: SQLx with compile-time query checking
- Lightning: Blitzi integration (ready for real LN nodes)
- Styling: Tailwind CSS + Flowbite (dark theme)
- Maps: Leaflet.js with dark theme tiles
- QR Codes: QRCode.js for NFC setup
- Async Runtime: Tokio for high performance
src/
├── main.rs # Application setup, routing, server
├── db.rs # Database layer (29 methods)
├── models.rs # Data structures (6 models)
├── lightning.rs # LNURL-withdraw implementation
├── refill.rs # Background refill service
├── handlers/
│ ├── pages.rs # HTML page handlers (5 routes)
│ └── api.rs # API endpoint handlers (4 endpoints)
└── templates/
├── layout.rs # Base layout, nav, footer
├── home.rs # Landing page with stats
├── map.rs # Interactive map view
├── new_location.rs # Location creation form
├── location_detail.rs # Location details page
└── nfc_setup.rs # NFC setup instructions
The application is fully functional and ready to:
- ✅ Start the web server
- ✅ Create treasure locations
- ✅ Generate NFC setup QR codes
- ✅ Handle LNURL-withdraw requests
- ✅ Automatically refill locations
- ✅ Track all scans and withdrawals
# Create required directories
mkdir -p uploads lightning_data
# Run the application
cargo run --release
# Open in browser
# http://localhost:3000- Navigate to /locations/new
- Enter location name and description
- Either enter coordinates or click "Use My Location"
- Drag marker on map to fine-tune position
- Upload 1-3 photos showing the hiding spot
- Set maximum sats (e.g., 1000)
- Click "Create Location"
- Receive one-time QR code for NFC writing
- Use Boltcard or similar app to write NFC tag
- Place tag at the location
- Browse /map to see all locations
- Pick a nearby treasure (check the sat balance!)
- Navigate to the coordinates
- Use photos to find the exact spot
- Scan NFC tag with Lightning wallet
- Receive LNURL-withdraw offer
- Accept and claim the sats!
- Lines of Code: ~2,500+ lines of Rust
- Templates: 6 HTML pages
- Database Tables: 4 tables + indexes
- API Endpoints: 9 total (5 pages + 4 API)
- Background Jobs: 1 refill service
- Dependencies: 47 crates
- Consistent dark theme (slate-900 background)
- Yellow accent color (#fbbf24) for calls-to-action
- Gradient text effects
- Responsive grid layouts
- Interactive map with dark theme
- Card-based design
- Loading states
- Form validation
- HTTPS for LNURL callbacks
- Rate limiting on API endpoints
- File upload validation and sanitization
- User authentication for location management
- Real Lightning node integration
- Invoice amount parsing and validation
- CSRF protection
- Content Security Policy headers
- User accounts and authentication
- Location ownership and editing
- Donation interface
- Mobile app for NFC writing
- Advanced map features (clustering, search)
- Leaderboards and achievements
- Social features (comments, ratings)
- Multi-language support
- Admin dashboard
- Real-time updates via WebSockets
Built with ❤️ and ⚡ in Rust