diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1f61602 --- /dev/null +++ b/.env.example @@ -0,0 +1,40 @@ +# ASDForecast Environment Variables +# Copy this file to .env and fill in your values + +# =================== +# REQUIRED +# =================== + +# Helius API key for Solana RPC (https://helius.dev) +HELIUS_API_KEY=your_helius_api_key + +# House wallet keypair as JSON array (for payouts) +# Generate with: solana-keygen new --outfile house-wallet.json +SOLANA_WALLET_JSON={"privateKey":[1,2,3,...]} + +# Admin password for control panel endpoints +ADMIN_ACTION_PASSWORD=your_secure_password + +# =================== +# OPTIONAL +# =================== + +# Server port (default: 3000) +PORT=3000 + +# CoinGecko API key for price data (https://coingecko.com/api) +COINGECKO_API_KEY= + +# Jupiter API key (optional, for token prices) +JUPITER_API_KEY= + +# =================== +# IMAGES (optional) +# =================== + +# Custom images for the frontend +BASE_IMAGE_SRC= +ITSFINE_IMG_SRC= +ITSOVER_IMG_SRC= +SENTIMENT_UP_IMG_SRC= +SENTIMENT_DOWN_IMG_SRC= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba8bdc4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,53 @@ +# Dependencies +node_modules/ + +# Environment variables +.env +.env.local +.env.*.local + +# Data persistence (production data) +data/ +/var/data/ + +# Wallet keys (NEVER commit) +*.json.key +house-wallet.json +*-wallet.json +*-keypair.json + +# Logs +logs/ +*.log +npm-debug.log* + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# IDE / Editor +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# Build outputs +dist/ +build/ + +# Test coverage +coverage/ + +# Temporary files +tmp/ +temp/ +*.tmp + +# Package lock (optional - uncomment if you want to ignore) +# package-lock.json diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..dd054ef --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,797 @@ +# ASDForecast Changelog + +## Version 151.0 - WebSocket Feature Enhancements + +### Overview + +This update adds real-time WebSocket features for improved user experience and transparency. + +--- + +## New WebSocket Events + +### 1. User Stats WS (Per-User Broadcast) + +**`USER_POSITION_UPDATE`** - Sent to user after bet confirmation +- Current position (up/down shares, totalSOL) +- Potential payout if UP/DOWN wins +- Current odds and pool share percentage + +**`USER_FRAME_RESULT`** - Sent to user when frame closes +- Personal result (won/lost) +- Wagered amount, payout, profit/loss +- Frame details (open, close, direction) + +### 2. Frame Result Animation + +Enhanced **`FRAME_CLOSE`** event with animation data: +- `priceMovement` - Price difference (open vs close) +- `percentChange` - Percentage price change +- `payoutMultiplier` - Actual payout ratio +- `topWinner` - Top winner pubKey and payout + +**Frontend:** +- Full-screen result overlay (4s display) +- Color flash effect (green=UP, red=DOWN, gray=FLAT) +- Personal win/loss toast notification + +### 3. Leaderboard Live + +**`LEADERBOARD_UPDATE`** - Broadcast when leaderboard changes +- Full leaderboard array with ranks +- `changedPositions` - Rank changes with direction (up/down/new) +- Triggers on: frame close, interval (60s) + +**Frontend:** +- Animated rank changes (highlight moved rows) +- Medal icons for top 3 positions + +### 4. Transaction Queue Dashboard + +**`PAYOUT_QUEUE_UPDATE`** - Broadcast during payout processing +- `queueLength` - Pending batches +- `processing` - Currently processing flag +- `lastBatch` - Details of last processed batch +- `recentPayouts` - Last 5 payout records + +**Frontend:** +- Queue status indicator +- Payout success toast notifications +- Recent payouts list + +--- + +## Technical Notes + +- `getUserPositionData(pubKey)` helper calculates user position/payouts +- `updateLeaderboard(broadcast)` accepts broadcast flag for WS events +- Animation CSS: `fadeOut`, `slideIn` keyframes added + +--- + +## Version 150.0 - User Features & Golden Ratio Decay + +### Overview + +This update adds user-facing features (bet history, badges, price alerts) and introduces Golden Ratio (φ) decay for referrer rewards to prevent farming while rewarding organic growth. + +--- + +## New Features + +### 1. Bet History API + +**GET `/api/user/history?user=&limit=50&offset=0`** +- Paginated bet history with stats +- Returns: bets[], pagination, stats (wins, losses, winRate, totalWagered) + +**GET `/api/user/stats?user=`** +- Overall user statistics including lottery and referral info + +### 2. Achievements/Badges System + +**11 badges available:** +| Badge | Name | Condition | +|-------|------|-----------| +| FIRST_BET | First Steps | Place your first bet | +| FIRST_WIN | Winner | Win your first frame | +| WIN_STREAK_3 | Hot Streak | Win 3 frames in a row | +| WINS_10/50/100 | Rising Star/Veteran/Legend | Win milestones | +| FRAMES_100 | Dedicated | Play 100 frames | +| VOLUME_1/10 | Trader/High Roller | Wager 1/10 SOL total | +| REFERRER_5 | Ambassador | Refer 5 users | +| HODLER | Diamond Hands | Hold ASDF for 4+ weeks | + +**GET `/api/user/badges?user=`** - Returns earned and available badges + +**WebSocket event:** `BADGE_EARNED` - Real-time notification on unlock + +### 3. Price Alerts (WebSocket) + +**Commands:** +| Command | Description | +|---------|-------------| +| `SET_PRICE_ALERT` | Create alert (max 5/client) | +| `REMOVE_PRICE_ALERT` | Delete by ID | +| `LIST_PRICE_ALERTS` | View active alerts | + +**Events:** `PRICE_ALERT_SET`, `PRICE_ALERT_TRIGGERED` + +### 4. Admin Dashboard Stats + +**GET `/api/admin/stats`** (requires auth) +- Overview: totalUsers, totalBets, totalVolume +- Today/Week: volume, bets, uniqueUsers +- Frame stats: totalFrames, avgBets, upWins, downWins +- Lottery: pool, draws, totalPrizePaid +- WebSocket: connected clients +- System: memory, uptime + +### 5. Rate Limit Headers + +All rate-limited endpoints now return: +- Standard: `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` +- Legacy: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` + +### 6. Golden Ratio Referrer Rate Decay + +**Anti-farming mechanism using φ (1.618...):** + +| Referrals | Rate | +|-----------|------| +| 0 | 0.448% (base) | +| 1 | 0.277% | +| 2-4 | 0.171% | +| 5-7 | 0.106% | +| 8-12 | 0.065% | +| 13+ | Continues decaying... | + +**Formula:** `rate = baseRate / φ^floor(log_φ(n+1))` + +**Benefits:** +- Rewards early/organic referrals +- Prevents referral farming +- Mathematically elegant decay + +--- + +## Files Modified + +| File | Change | +|------|--------| +| `server.js` | +User APIs, +Badges, +Price Alerts, +Admin Stats, +Golden Ratio decay | +| `config.js` | +PHI constant, +ACHIEVEMENTS config, +BASE_REFERRER_RATE | +| `package.json` | Version 1.50.0 | +| `README.md` | New endpoints documented | + +--- + +--- + +## Version 149.0 - WebSocket Real-time Updates + +### Overview + +This update replaces HTTP polling with WebSocket streaming for near-instant UI updates, reducing latency from 2-4 seconds to ~500ms while significantly reducing server load. + +--- + +## Changes + +### 1. WebSocket Server + +**Backend WebSocket integration:** +- WebSocket server runs on same port (3000) alongside Express +- Client tracking with Map for connection management +- Heartbeat ping/pong every 30 seconds with 60s timeout +- Automatic cleanup of dead connections + +**Broadcast events:** +| Event | Trigger | Data | +|-------|---------|------| +| `STATE` | Every 500ms | Full game state snapshot | +| `PRICE` | Price update (~10s) | price, change, timestamp | +| `FRAME_CLOSE` | Frame ends | result, winners, payout | + +### 2. Frontend WebSocket Client + +**Auto-connecting client with:** +- Exponential backoff reconnection (1s to 30s max) +- Automatic auth when wallet connects +- Graceful fallback to HTTP polling if WS unavailable +- Reduced polling frequency (10s) when WS active + +### 3. Monitoring Integration + +**WebSocket metrics in endpoints:** +- `/api/health`: `websocket.connectedClients` +- `/api/metrics`: `asdforecast_websocket_clients` (Prometheus) + +### 4. Performance Impact + +| Metric | Before | After | +|--------|--------|-------| +| Update latency | 2-4s | ~500ms | +| Requests/min/client | 120 | ~6 (fallback) | +| Server CPU | Higher | ~80% reduction | + +--- + +## Version 148.0 - Infrastructure Hardening & Monitoring + +### Overview + +This update improves infrastructure reliability, security, and observability with centralized configuration, enhanced rate limiting, and monitoring endpoints. + +--- + +## Changes + +### 1. Centralized Configuration + +**New file: `config.js`** + +All hardcoded constants extracted to a single configuration file: +- Solana addresses (ASDF_MINT, wallets, pool accounts) +- Game economy parameters (fees, payouts, frame duration) +- Lottery and Referral configs +- Rate limiting settings +- External API URLs + +```javascript +const config = require('./config'); +const ASDF_MINT = config.ASDF_MINT; +``` + +### 2. Enhanced Rate Limiting + +**New limiters for sensitive endpoints:** + +| Endpoint | Old Limiter | New Limiter | +|----------|-------------|-------------| +| `/api/referral/claim` | stateLimiter (120/min) | claimLimiter (3/5min) | +| `/api/referral/register` | stateLimiter (120/min) | registerLimiter (5/min) | + +### 3. Health Check Endpoint + +**GET `/api/health`** + +Returns comprehensive service status: +```json +{ + "status": "ok", + "version": "148.0", + "uptime": 3600, + "services": { + "rpc": { "status": "ok", "latency": 45 }, + "pumpswap": { "status": "ok", "price": 0.000000871 }, + "pyth": { "status": "ok", "price": 135.52 } + }, + "memory": { "heapUsed": 85, "rss": 120 }, + "gameState": { "isInitialized": true, "isPaused": false } +} +``` + +### 4. Prometheus Metrics Endpoint + +**GET `/api/metrics`** + +Prometheus-compatible metrics: +- `asdforecast_uptime_seconds` +- `asdforecast_total_volume_sol` +- `asdforecast_total_fees_sol` +- `asdforecast_active_users` +- `asdforecast_payout_queue_length` +- `asdforecast_sol_price` +- `asdforecast_asdf_price_sol` +- `asdforecast_lottery_pool` +- `asdforecast_memory_heap_bytes` +- And more... + +--- + +## Files Modified + +| File | Change | +|------|--------| +| `config.js` | **NEW** - Centralized configuration | +| `server.js` | Import config, new rate limiters, health/metrics endpoints | +| `package.json` | Version 1.48.0 | +| `README.md` | Security section, monitoring docs | + +--- + +## Security Improvements + +- Stricter rate limiting on claim/register endpoints +- Documented frontend Helius key restriction requirements +- Rate limit configuration externalized for easy adjustment + +--- + +--- + +## Version 147.0 - On-chain ASDF Price (PumpSwap Pool) + +### Overview + +This update replaces the Jupiter Price API with direct on-chain price calculation from the PumpSwap liquidity pool. This provides more accurate, real-time pricing based on actual pool reserves. + +--- + +## Changes + +### 1. On-chain Price Source + +**Pool Configuration:** +```javascript +const PUMPSWAP_POOL = { + POOL_ADDRESS: "DuhRX5JTPtsWU5n44t8tcFEfmzy2Eu27p4y6z8Rhf2bb", + BASE_TOKEN_ACCOUNT: "9NXgzYh3ZhrqiLn994fhkGx7ikAUbEcWux9SGuxyXq2z", // ASDF reserve + QUOTE_TOKEN_ACCOUNT: "HmmH9j2BHmJHQDRGMswBMccMfsr6jknGTux3wFqmXrya", // SOL reserve + BASE_DECIMALS: 6, + QUOTE_DECIMALS: 9 +}; +``` + +**Price Calculation:** +``` +priceInSol = quoteReserve / baseReserve +priceInUsd = priceInSol * solPriceUsd +``` + +### 2. Startup Validation + +- **HELIUS_API_KEY** required at startup (fatal error if missing) +- **Pool accessibility** validated on boot with test price fetch +- Clear logging of price data and pool reserves + +### 3. Enhanced Price Data + +The `getASDF_PriceFromPool()` function now returns: +```javascript +{ + priceInSol: 0.000000870939, + priceInUsd: 0.00011854, + baseReserve: 181879310, // ASDF in pool + quoteReserve: 158.4, // SOL in pool + timestamp: Date.now() +} +``` + +### 4. API Enhancements + +**`/api/referral/stats`** now includes: +- `priceAvailable: boolean` - Indicates if price is available +- `priceWarning: string | null` - Warning message if price unavailable + +**External stats cache** now includes: +- `tokenPriceInSol` - ASDF price in SOL +- `poolReserves.asdf` - ASDF reserve amount +- `poolReserves.sol` - SOL reserve amount + +--- + +## Files Modified + +### server.js + +**New Configuration (lines 40-52):** +- `PUMPSWAP_POOL` constant with pool addresses + +**Modified Functions:** +| Function | Change | +|----------|--------| +| `getASDF_PriceFromPool()` | New - reads on-chain pool reserves | +| `getASDF_Price()` | Now wraps `getASDF_PriceFromPool()` for backward compatibility | +| `fetchTokenPricesStaggered()` | Uses on-chain price instead of Jupiter API | +| `loadAndInit()` | Validates pool accessibility on startup | + +### New Files + +- `scripts/find_asdf_pools.js` - Utility to discover ASDF pools +- `scripts/find_pumpswap_pool.js` - PumpSwap pool discovery utility + +--- + +## Benefits + +| Aspect | Before (Jupiter API) | After (On-chain) | +|--------|---------------------|------------------| +| Source | Third-party API | Direct blockchain | +| Latency | ~500ms | ~200ms | +| Reliability | API dependent | RPC dependent | +| Data | Price only | Price + reserves | +| Cache | 60 seconds | 30 seconds | + +--- + +## Testing + +```bash +# Server startup shows: +✓ HELIUS_API_KEY loaded (ac94987a...) +✓ PumpSwap pool validated: 0.000000870939 SOL/ASDF +> [PRICE] ASDF on-chain: 0.000000870939 SOL ($0.00011854) | Pool: 181,879,310 ASDF / 158.41 SOL +``` + +--- + +--- + +## Version 145.0 - Referral Flywheel System (552 SYMMETRY) + +### Overview + +This update introduces a referral rewards system designed to align gamblers and holders through economic incentives. The "552 SYMMETRY" design forces users to hold ASDF to claim rewards, creating a virtuous flywheel. + +--- + +## Philosophy + +**Goal:** Transform every gambler into a long-term ASDF holder via aligned incentives. + +``` +┌─────────────────────────────────────────────────────────────┐ +│ REFERRAL FLYWHEEL │ +├─────────────────────────────────────────────────────────────┤ +│ 1. User joins via referral code │ +│ 2. User bets → accumulates 0.552% in ASDF (pending) │ +│ 3. Referrer accumulates 0.448% in ASDF (pending) │ +│ 4. To claim: must HOLD as much ASDF as pending │ +│ 5. User buys ASDF → can claim → holds more │ +│ 6. Repeat: more play + hold → more earnings │ +└─────────────────────────────────────────────────────────────┘ +``` + +--- + +## New Features + +### 1. Referral Code System + +**Requirements:** +- Hold >= 55,200 ASDF to create a referral code +- 8-character unique code per user + +**Rewards (based on BET amount, not fees):** +| Role | Reward | Description | +|------|--------|-------------| +| Filleul (referred user) | 0.552% | Rebate on your own bets | +| Parrain (referrer) | 0.448% | Commission on referral's bets | + +### 2. Proportional Claim Mechanism + +```javascript +claimableAmount = min(pendingRewards, currentASDF_Balance) +``` + +**Example Flywheel:** +1. User referred bets 10 SOL → accumulates ~0.0552 SOL worth of ASDF +2. User holds 0 ASDF → can claim 0 (must buy first) +3. User buys 1000 ASDF → can claim up to 1000 ASDF rewards +4. User claims → now holds more ASDF +5. Continues playing → accumulates more → buys more to claim more + +### 3. Live ASDF Price Conversion + +- Rewards tracked in SOL value +- Converted to ASDF at claim time using Jupiter Price API +- Ensures fair conversion regardless of price volatility + +--- + +## Files Modified + +### server.js + +**New Configuration (line 56-67):** +```javascript +const REFERRAL_CONFIG = { + USER_REBATE_PERCENT: 0.00552, // 0.552% of bet → Filleul + REFERRER_REWARD_PERCENT: 0.00448, // 0.448% of bet → Parrain + MIN_ASDF_TO_REFER: 55200, + CODE_LENGTH: 8, + MAX_REFERRALS_PER_USER: 100, + REWARD_CURRENCY: 'ASDF', + CLAIM_RATIO: 1.0 +}; +``` + +**New Data Structure:** +```javascript +referralData = { + links: {}, // referrer -> {code, referredUsers[], ...} + codeToReferrer: {}, // code -> referrer + userToReferrer: {}, // user -> referrer + pendingRewards: {} // user -> {asReferrer, asUser, totalClaimedASDF} +}; +``` + +**New Functions:** +| Function | Purpose | +|----------|---------| +| `getASDF_Price()` | Fetches live ASDF/SOL price from Jupiter API | +| `getOrCreateReferralCode(pubKey)` | Creates referral code if eligible | +| `processReferralRewards(bet)` | Calculates rewards based on bet amount | +| `transferASDF(recipient, amount)` | SPL token transfer for claims | + +**New API Endpoints:** +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/referral/code?user=` | GET | Get or create referral code | +| `/api/referral/register` | POST | Register with a referral code | +| `/api/referral/stats?user=` | GET | User's referral stats & pending rewards | +| `/api/referral/claim` | POST | Claim pending ASDF rewards | + +**New Data File:** +- `data/referral_data.json` - Referral links and pending rewards + +--- + +### frontend.html + +**New UI Section (lines 391-487):** +- Referral code display with copy button +- Pending rewards / Balance / Claimable grid +- Claim button with transaction link +- Stats grid (referred users, volume, total claimed) +- Register with code section +- 552 SYMMETRY explanation + +**New JavaScript Functions (lines 1010-1238):** +| Function | Purpose | +|----------|---------| +| `fetchReferralStats()` | Fetches user's referral data from API | +| `startReferralPolling()` | Polls every 30 seconds when connected | +| `copyReferralCode()` | Copies code to clipboard | +| `createReferralCode()` | Requests code creation | +| `registerReferralCode()` | Registers user with referral code | +| `claimReferralRewards()` | Claims pending ASDF rewards | + +**New UI Element IDs:** +- `#referral-code-display`, `#referral-code-status` +- `#referral-pending-asdf`, `#referral-your-balance`, `#referral-claimable` +- `#claim-btn`, `#claim-message` +- `#referral-users-count`, `#referral-volume`, `#referral-total-claimed` +- `#register-code-input`, `#register-btn`, `#register-message` + +--- + +### package.json + +**New Dependency:** +```json +"@solana/spl-token": "^0.4.14" +``` + +--- + +## API Response Examples + +**GET /api/referral/stats:** +```json +{ + "isReferrer": true, + "referralCode": "ASDF1234", + "referredUsers": 5, + "totalVolumeGenerated": 125.5, + "referredBy": "FuLg...miPn", + "pending": { + "asReferrerSOL": 0.125, + "asUserSOL": 0.055, + "totalASDF": 18000, + "totalClaimedASDF": 5000 + }, + "claim": { + "userASDF_Balance": 50000, + "claimableASDF": 18000, + "asdfPriceSOL": 0.00001 + } +} +``` + +--- + +## Testing + +```bash +# Test referral stats +curl "http://localhost:3000/api/referral/stats?user=YOUR_PUBKEY" + +# Create/get referral code +curl "http://localhost:3000/api/referral/code?user=YOUR_PUBKEY" + +# Register with code +curl -X POST http://localhost:3000/api/referral/register \ + -H "Content-Type: application/json" \ + -d '{"user":"YOUR_PUBKEY","code":"ASDF1234"}' + +# Claim rewards +curl -X POST http://localhost:3000/api/referral/claim \ + -H "Content-Type: application/json" \ + -d '{"user":"YOUR_PUBKEY"}' +``` + +--- + +## Migration Notes + +- No database migration needed - uses JSON file storage +- Referral data auto-initializes on first run +- Existing users can create referral codes if they hold enough ASDF +- Rewards start accumulating immediately for referred users + +--- + +--- + +## Version 121.0 - Lottery System with Activity Requirement + +### Overview + +This update introduces a weekly ASDF lottery system designed to reward long-term holders who actively participate in the platform. The system is built to be ungameable and follows a libertarian philosophy - no artificial barriers, just organic engagement. + +--- + +## New Features + +### 1. Weekly ASDF Lottery + +**Eligibility Requirements:** +- Hold >= 0.00552% of ASDF circulating supply (~52,255 ASDF at current supply) +- Play on the platform at least once in the last 7 days + +**Ticket Calculation:** +``` +baseTickets = 1 + weeksHolding (max 52) +activityMultiplier = activeDays / 7 +effectiveTickets = baseTickets * activityMultiplier +``` + +**Example:** +| Holding Duration | Active Days | Base Tickets | Multiplier | Effective Tickets | +|-----------------|-------------|--------------|------------|-------------------| +| 10 weeks | 7/7 | 11 | 100% | 11 | +| 10 weeks | 5/7 | 11 | 71% | 8 | +| 10 weeks | 0/7 | 11 | 0% | 0 (ineligible) | + +**Prize Pool:** +``` +prize = BASE_PRIZE (100,000 ASDF) + (totalTickets * 10,000 ASDF) +``` + +--- + +## Files Modified + +### server.js + +**New Constants (lines 44-53):** +```javascript +const LOTTERY_CONFIG = { + ELIGIBILITY_PERCENT: 0.0000552, // 0.00552% of supply + MAX_TICKETS: 52, + DRAW_INTERVAL_MS: 7 * 24 * 60 * 60 * 1000, // 7 days + ACTIVITY_WINDOW_DAYS: 7, + BASE_PRIZE: 100000, + PRIZE_PER_TICKET: 10000, + SUPPLY_CACHE_MS: 5 * 60 * 1000 +}; +``` + +**New Functions:** +| Function | Purpose | +|----------|---------| +| `recordUserActivity(pubKey)` | Records daily activity when user places bet | +| `calculateActivityMultiplier(activityDays)` | Returns 0-1 based on days active | +| `getCirculatingSupply()` | On-chain query for ASDF supply | +| `getUserASDFBalance(pubKey)` | On-chain query for user's ASDF balance | +| `checkLotteryEligibility(pubKey)` | Checks if user meets threshold | +| `calculateTickets(user)` | Returns base + effective tickets | +| `getTokenAccountFirstTransaction(connection, address)` | Finds first tx for holding duration | +| `getEligibleParticipants()` | Scans all on-chain holders with activity | +| `executeLotteryDraw()` | Runs the lottery draw with mutex protection | +| `checkLotterySchedule()` | Scheduled task for auto-draws | + +**New API Endpoints:** +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/lottery/status` | GET | Current round, countdown, config | +| `/api/lottery/eligibility?user=` | GET | User's eligibility, tickets, activity | +| `/api/lottery/history` | GET | Past draws | +| `/api/admin/lottery/draw` | POST | Manual draw trigger (admin only) | + +**New Data Files:** +- `data/lottery_state.json` - Current round state +- `data/lottery_history.json` - Draw history + +--- + +### frontend.html + +**New UI Section (lines 250-305):** +- Lottery panel with round number, countdown timer +- Your tickets display with activity indicator +- Last winner display +- Eligibility status (ELIGIBLE / NEED ACTIVITY / NOT ELIGIBLE) +- "How it works" explanation + +**New UI Elements:** +- `#lottery-round` - Current round number +- `#lottery-countdown` - Time until next draw +- `#lottery-tickets` - User's effective ticket count +- `#lottery-activity` - Activity status (X/7 days) +- `#lottery-winner` - Last winner address +- `#lottery-prize` - Last prize amount + +--- + +### control_panel.html + +**New Admin Section:** +- Manual lottery draw trigger button +- Displays lottery round, countdown, winner, prize + +--- + +## Security Measures + +| Measure | Implementation | +|---------|----------------| +| Race condition prevention | `lotteryMutex` for concurrent draw protection | +| Cryptographic randomness | `crypto.randomInt()` for winner selection | +| Input validation | All pubKeys validated with regex | +| Activity verification | On-chain tx required before activity recorded | +| Admin authentication | Environment variable password | +| Rate limiting | `stateLimiter` on lottery endpoints | + +--- + +## Anti-Gaming Design + +**Why it can't be exploited:** + +1. **Activity requires real SOL** - Must send actual SOL to house wallet (verified on Solana blockchain) +2. **Wallet splitting loses duration** - New wallets start at 0 weeks +3. **Duration verified on-chain** - First transaction timestamp queried from Solana +4. **No Sybil advantage** - More wallets = less time per wallet = fewer tickets each + +--- + +## Configuration + +**Environment Variables:** +```bash +HELIUS_API_KEY=your_api_key # For Solana RPC +ADMIN_ACTION_PASSWORD=your_pwd # For admin endpoints +``` + +**Schedule:** +- Draws every 7 days automatically +- Checked every hour via `setInterval` +- Can be triggered manually via admin endpoint + +--- + +## Testing + +```bash +# Test lottery status +curl http://localhost:3000/api/lottery/status + +# Test user eligibility +curl "http://localhost:3000/api/lottery/eligibility?user=YOUR_PUBKEY" + +# Trigger manual draw (admin) +curl -X POST http://localhost:3000/api/admin/lottery/draw \ + -H "x-admin-secret: YOUR_ADMIN_PASSWORD" +``` + +--- + +## Migration Notes + +- No database migration needed - uses JSON file storage +- Lottery state auto-initializes on first run +- Existing users automatically tracked on next bet diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..8e941a7 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,185 @@ +# ASDForecast - Deployment Guide + +## Feature Flags Configuration + +All new features are **modular** and can be enabled/disabled via `config.js` without code changes. + +### Location + +Edit `config.js` and find the `FEATURES` section: + +```javascript +FEATURES: { + WEBSOCKET_ENABLED: true, // Real-time WebSocket updates + LOTTERY_ENABLED: true, // Weekly ASDF lottery system + REFERRAL_ENABLED: true, // Referral/affiliate system with Golden Ratio decay + BADGES_ENABLED: true, // Achievement/badge system + EXTERNAL_TRACKER_ENABLED: true, // External wallet tracking service + SENTIMENT_ENABLED: true // Daily sentiment voting +} +``` + +### Feature Descriptions + +| Feature | Description | Impact When Disabled | +|---------|-------------|---------------------| +| `WEBSOCKET_ENABLED` | Real-time price/state updates via WebSocket | Falls back to HTTP polling (2-10s intervals) | +| `LOTTERY_ENABLED` | Weekly ASDF lottery with holding-based tickets | Lottery endpoints return 404, UI section hidden | +| `REFERRAL_ENABLED` | Referral codes with Golden Ratio decay rewards | Referral endpoints return 404, UI section hidden | +| `BADGES_ENABLED` | Achievement badges (11 badges) | Badge endpoint returns 404, no badge checks | +| `EXTERNAL_TRACKER_ENABLED` | External wallet tracking service | Tracker service not started | +| `SENTIMENT_ENABLED` | Daily UP/DOWN sentiment voting | Voting UI hidden (if implemented) | + +### Recommended Deployment Strategy + +#### Phase 1: Base Platform (Minimal Risk) +```javascript +FEATURES: { + WEBSOCKET_ENABLED: false, // Keep HTTP polling for stability + LOTTERY_ENABLED: false, + REFERRAL_ENABLED: false, + BADGES_ENABLED: false, + EXTERNAL_TRACKER_ENABLED: false, + SENTIMENT_ENABLED: true // Already in production +} +``` + +#### Phase 2: Add WebSocket +```javascript +WEBSOCKET_ENABLED: true, // Test real-time updates +``` + +#### Phase 3: Add Lottery +```javascript +LOTTERY_ENABLED: true, // Test lottery eligibility checks +``` + +#### Phase 4: Add Referral +```javascript +REFERRAL_ENABLED: true, // Test referral code creation/rewards +``` + +#### Phase 5: Add Badges +```javascript +BADGES_ENABLED: true, // Test achievement system +``` + +--- + +## What Happens When Features Are Disabled + +### Lottery Disabled +- `/api/lottery/*` endpoints are NOT registered (return 404) +- `lotteryState` is not loaded from disk +- Lottery UI section is automatically hidden in frontend +- Lottery scheduled tasks do not run +- No lottery-related calculations in payout flow + +### Referral Disabled +- `/api/referral/*` endpoints are NOT registered (return 404) +- `referralData` is not loaded from disk +- Referral UI section is automatically hidden in frontend +- `processReferralRewards()` is skipped during payouts +- No referral reward calculations + +### Badges Disabled +- `/api/user/badges` endpoint returns 404 +- `checkAndAwardBadges()` is skipped after frame results +- No badge-related database updates + +### WebSocket Disabled +- WebSocket server is not initialized +- `wsBroadcast()` calls are no-ops +- Frontend falls back to HTTP polling automatically +- Slightly higher latency for state updates (2-10s vs real-time) + +--- + +## Startup Logs + +When the server starts, it logs which features are enabled: + +``` +> [SYS] WebSocket server ENABLED +> [SYS] Lottery module ENABLED +> [SYS] Referral module ENABLED +> ASDForecast Engine v151.0 running on 3000 +> Features: WS=true LOTTERY=true REFERRAL=true BADGES=true +``` + +Or when disabled: + +``` +> [SYS] WebSocket server DISABLED (HTTP polling only) +> [SYS] Lottery module DISABLED +> [SYS] Referral module DISABLED +> ASDForecast Engine v151.0 running on 3000 +> Features: WS=false LOTTERY=false REFERRAL=false BADGES=false +``` + +--- + +## Data Files + +Each feature stores its data in separate files under `RENDER_DISK_PATH` (default: `/var/data`): + +| File | Feature | Created When | +|------|---------|--------------| +| `lottery_state.json` | Lottery | First lottery interaction | +| `referral_data.json` | Referral | First referral code creation | +| `user_activity.json` | Lottery | First user activity recorded | + +**Note**: These files are only loaded if the corresponding feature is enabled. + +--- + +## Testing Checklist + +### With All Features OFF +- [ ] Server starts without errors +- [ ] Betting flow works (buy UP/DOWN) +- [ ] Payouts process correctly +- [ ] Frontend displays core betting UI only +- [ ] Lottery/Referral sections are hidden + +### Enabling Lottery +- [ ] Lottery section appears in frontend +- [ ] `/api/lottery/eligibility` returns data +- [ ] Lottery scheduled task runs hourly +- [ ] Activity is recorded during betting + +### Enabling Referral +- [ ] Referral section appears in frontend +- [ ] `/api/referral/code` works with wallet connected +- [ ] Referral rewards calculated during payouts +- [ ] Golden Ratio decay applied correctly + +### Enabling WebSocket +- [ ] Console shows "WebSocket server ready" +- [ ] Frontend connects via WebSocket +- [ ] Real-time price/state updates work +- [ ] Graceful fallback if connection fails + +--- + +## Environment Variables + +These remain in `.env` (not in config.js): + +```bash +HELIUS_API_KEY=your_key_here +FEE_WALLET_PRIVATE_KEY=base58_encoded +UPKEEP_WALLET_PRIVATE_KEY=base58_encoded +ADMIN_KEY=your_admin_secret +PORT=3000 # Optional, defaults to 3000 +``` + +--- + +## Version Info + +- Backend: v151.0 +- Frontend: v147.0 +- Config: Centralized in `config.js` + +Generated with Claude Code diff --git a/README.md b/README.md new file mode 100644 index 0000000..8da41db --- /dev/null +++ b/README.md @@ -0,0 +1,167 @@ +# ASDForecast + +Prediction market platform on Solana for SOL price movements with ASDF token lottery system. + +## Features + +- **15-minute price prediction frames** - Bet UP or DOWN on SOL price +- **Dynamic pricing** - Share prices adjust based on market demand +- **ASDF Lottery** - Weekly draws for eligible ASDF holders +- **Referral Flywheel** - 552 SYMMETRY rewards with Golden Ratio (φ) decay for referrers +- **On-chain ASDF price** - Direct price calculation from PumpSwap pool reserves +- **Sentiment voting** - Daily community sentiment polls +- **Real-time updates** - Live price feeds via Pyth Oracle +- **WebSocket streaming** - Sub-second UI updates with automatic fallback to polling + +## Quick Start + +### Prerequisites +- Node.js >= 14.0.0 +- Helius API key (for Solana RPC) + +### Installation + +```bash +npm install +``` + +### Configuration + +Create a `.env` file: + +```env +# Required +HELIUS_API_KEY=your_helius_api_key + +# Required for payouts (JSON string of Solana keypair) +SOLANA_WALLET_JSON={"privateKey":[...]} + +# Required for admin endpoints +ADMIN_ACTION_PASSWORD=your_secure_password + +# Optional +PORT=3000 +COINGECKO_API_KEY=your_coingecko_key +``` + +### Running + +```bash +# Production +npm start + +# Development (with file server for frontend) +node server.js & +python3 -m http.server 8080 +``` + +### Access + +- **Frontend**: http://localhost:8080/frontend.html +- **Admin Panel**: http://localhost:8080/control_panel.html +- **Monitor Widget**: http://localhost:8080/status_monitor_widget.html +- **API**: http://localhost:3000/api/state + +## API Endpoints + +### Public +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/state` | GET | Current game state | +| `/api/health` | GET | Service health status | +| `/api/metrics` | GET | Prometheus metrics | +| `/api/verify-bet` | POST | Verify a bet transaction | +| `/api/sentiment/vote` | POST | Submit sentiment vote | +| `/api/lottery/status` | GET | Lottery status | +| `/api/lottery/eligibility` | GET | Check wallet eligibility | +| `/api/lottery/history` | GET | Past lottery draws | +| `/api/referral/code` | GET | Get/create referral code | +| `/api/referral/register` | POST | Register with referral code | +| `/api/referral/stats` | GET | Referral statistics | +| `/api/referral/claim` | POST | Claim referral rewards | +| `/api/user/history` | GET | Paginated bet history | +| `/api/user/stats` | GET | User statistics | +| `/api/user/badges` | GET | User achievements/badges | + +### Admin (requires `x-admin-secret` header) +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/admin/toggle-pause` | POST | Pause/unpause market | +| `/api/admin/cancel-frame` | POST | Cancel current frame | +| `/api/admin/broadcast` | POST | Set broadcast message | +| `/api/admin/lottery/draw` | POST | Trigger manual lottery draw | +| `/api/admin/stats` | GET | Comprehensive dashboard stats | + +## Lottery System + +- **Eligibility**: Hold 0.00552% of ASDF circulating supply +- **Max Tickets**: 52 per holder +- **Activity Bonus**: 7-day activity window multiplier +- **Draw Interval**: Weekly (every 7 days) +- **Prizes**: Base 100,000 ASDF + 10,000 per ticket in pool + +## Project Structure + +``` +├── server.js # Main backend (Express + Solana) +├── frontend.html # User interface +├── control_panel.html # Admin dashboard +├── status_monitor_widget.html # OBS/streaming widget +├── data/ # Persistent data (gitignored) +│ ├── state.json +│ ├── history.json +│ ├── lottery_state.json +│ └── users/ +└── package.json +``` + +## Version + +- **Backend**: v151.0 +- **Frontend**: v123.0 + +## Security + +### Frontend Helius API Key + +The frontend (`frontend.html:548`) contains a Helius RPC key for client-side Solana connections. This is intentional for browser wallet interactions. + +**Important:** Configure origin restrictions in your [Helius Dashboard](https://dashboard.helius.dev): +- Allowed origins: `https://yourdomain.com`, `http://localhost:*` +- This prevents unauthorized usage from other domains. + +### Rate Limiting + +| Endpoint Type | Limit | Window | +|---------------|-------|--------| +| State polling | 120 req | 1 min | +| Bet submission | 10 req | 1 min | +| Sentiment vote | 1 req | 1 hour | +| Referral claim | 3 req | 5 min | +| Referral register | 5 req | 1 min | + +### Admin Authentication + +All `/api/admin/*` endpoints require `x-admin-secret` header matching `ADMIN_ACTION_PASSWORD` env var. + +## Monitoring + +### Health Check + +```bash +curl http://localhost:3000/api/health +``` + +Returns service status for RPC, PumpSwap pool, and Pyth oracle. + +### Prometheus Metrics + +```bash +curl http://localhost:3000/api/metrics +``` + +Compatible with Prometheus/Grafana. Exposes: uptime, volume, fees, users, queue length, prices, lottery pool, memory usage. + +## License + +Proprietary - All rights reserved diff --git a/config.js b/config.js new file mode 100644 index 0000000..ac40b80 --- /dev/null +++ b/config.js @@ -0,0 +1,152 @@ +/** + * ASDForecast Configuration + * Centralized constants for the entire application + * + * Environment variables (HELIUS_API_KEY, etc.) remain in server.js + */ + +module.exports = { + // =================== + // VERSION + // =================== + BACKEND_VERSION: "151.0", + + // =================== + // SOLANA ADDRESSES + // =================== + ASDF_MINT: "9zB5wRarXMj86MymwLumSKA1Dx35zPqqKfcZtK1Spump", + FEE_WALLET: "5xfyqaDzaj1XNvyz3gnuRJMSNUzGkkMbYbh2bKzWxuan", + UPKEEP_WALLET: "BH8aAiEDgZGJo6pjh32d5b6KyrNt6zA9U8WTLZShmVXq", + TRACKED_WALLET: "vcGYZbvDid6cRUkCCqcWpBxow73TLpmY6ipmDUtrTF8", + PURCHASE_SOURCE_ADDRESS: "DuhRX5JTPtsWU5n44t8tcFEfmzy2Eu27p4y6z8Rhf2bb", + + // =================== + // PUMPSWAP POOL (On-chain price source) + // =================== + PUMPSWAP_POOL: { + POOL_ADDRESS: "DuhRX5JTPtsWU5n44t8tcFEfmzy2Eu27p4y6z8Rhf2bb", + BASE_TOKEN_ACCOUNT: "9NXgzYh3ZhrqiLn994fhkGx7ikAUbEcWux9SGuxyXq2z", // ASDF reserve + QUOTE_TOKEN_ACCOUNT: "HmmH9j2BHmJHQDRGMswBMccMfsr6jknGTux3wFqmXrya", // SOL reserve + BASE_DECIMALS: 6, + QUOTE_DECIMALS: 9 + }, + + // =================== + // GAME ECONOMY + // =================== + PRICE_SCALE: 0.1, + PAYOUT_MULTIPLIER: 0.94, // 94% to winners + FEE_PERCENT: 0.0552, // 5.52% fees (buyback & burn) + UPKEEP_PERCENT: 0.0048, // 0.48% upkeep (gas costs) + FRAME_DURATION_MS: 15 * 60 * 1000, // 15 minutes + PRIORITY_FEE_UNITS: 50000, + + // =================== + // LOTTERY CONFIG + // =================== + LOTTERY_CONFIG: { + ELIGIBILITY_PERCENT: 0.0000552, // 0.00552% of circulating supply + MAX_TICKETS: 52, + DRAW_INTERVAL_MS: 7 * 24 * 60 * 60 * 1000, // 7 days + ACTIVITY_WINDOW_DAYS: 7, + BASE_PRIZE: 100000, // Legacy - now uses pool + PRIZE_PER_TICKET: 10000, // Legacy + SUPPLY_CACHE_MS: 5 * 60 * 1000, // 5 minutes + PRIZE_POOL_THRESHOLD: 1_000_000, // 1M ASDF to trigger draw + ASDF_TO_POOL_PERCENT: 0.552 // 55.2% to lottery pool + }, + + // =================== + // GOLDEN RATIO (φ) + // =================== + // φ = (1 + √5) / 2 - mathematically defined for maximum precision + PHI: (1 + Math.sqrt(5)) / 2, + + // =================== + // REFERRAL CONFIG (552 SYMMETRY + Golden Ratio Decay) + // =================== + REFERRAL_CONFIG: { + USER_REBATE_PERCENT: 0.00552, // 0.552% rebate to user (fixed) + BASE_REFERRER_RATE: 0.00448, // 0.448% base rate (decays with φ) + MIN_ASDF_TO_REFER: 55200, // Min ASDF to create code + CODE_LENGTH: 8, + MAX_REFERRALS_PER_USER: 100, + REWARD_CURRENCY: 'ASDF', + CLAIM_RATIO: 1.0 + // Rate decay: 0.448% → 0.277% → 0.171% → 0.106% → 0.065%... + // Formula: baseRate / φ^floor(log_φ(n+1)) + }, + + // =================== + // EXTERNAL APIs + // =================== + PYTH_HERMES_URL: "https://hermes.pyth.network/v2/updates/price/latest", + SOL_FEED_ID: "0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d", + HELIUS_ENHANCED_BASE: "https://api-mainnet.helius-rpc.com/v0", + JUP_PRICE_URL: "https://lite-api.jup.ag/price/v3", + + // =================== + // TOKEN SUPPLY + // =================== + TOKEN_TOTAL_SUPPLY: 1_000_000_000, + + // =================== + // RATE LIMITING + // =================== + RATE_LIMITS: { + BET: { windowMs: 60 * 1000, max: 10 }, // 10 bets/min + STATE: { windowMs: 60 * 1000, max: 120 }, // 120 polls/min + VOTE: { windowMs: 3600 * 1000, max: 1 }, // 1 vote/hour + CLAIM: { windowMs: 5 * 60 * 1000, max: 3 }, // 3 claims/5min + REGISTER: { windowMs: 60 * 1000, max: 5 } // 5 registers/min + }, + + // =================== + // WEBSOCKET + // =================== + WEBSOCKET: { + HEARTBEAT_INTERVAL: 30000, // 30s ping/pong + STATE_BROADCAST_THROTTLE: 500, // 500ms min between state broadcasts + RECONNECT_BACKOFF_MAX: 30000 // 30s max reconnect delay + }, + + // =================== + // ACHIEVEMENTS (Badges) + // =================== + ACHIEVEMENTS: { + // Badge definitions: id -> { name, description, condition } + BADGES: { + FIRST_BET: { name: 'First Steps', description: 'Place your first bet', icon: '🎲' }, + FIRST_WIN: { name: 'Winner', description: 'Win your first frame', icon: '🏆' }, + WIN_STREAK_3: { name: 'Hot Streak', description: 'Win 3 frames in a row', icon: '🔥' }, + WINS_10: { name: 'Rising Star', description: 'Win 10 frames', icon: '⭐' }, + WINS_50: { name: 'Veteran', description: 'Win 50 frames', icon: '🎖️' }, + WINS_100: { name: 'Legend', description: 'Win 100 frames', icon: '👑' }, + FRAMES_100: { name: 'Dedicated', description: 'Play 100 frames', icon: '💪' }, + VOLUME_1: { name: 'Trader', description: 'Wager 1 SOL total', icon: '💰' }, + VOLUME_10: { name: 'High Roller', description: 'Wager 10 SOL total', icon: '💎' }, + REFERRER_5: { name: 'Ambassador', description: 'Refer 5 users', icon: '🤝' }, + HODLER: { name: 'Diamond Hands', description: 'Hold ASDF for 4+ weeks', icon: '💎' } + } + }, + + // =================== + // FEATURE FLAGS + // =================== + // Toggle features ON/OFF without code changes + // Set to false to disable a feature completely + FEATURES: { + WEBSOCKET_ENABLED: false, // Real-time WebSocket updates (disable = HTTP polling only) + LOTTERY_ENABLED: false, // Weekly ASDF lottery system + REFERRAL_ENABLED: false, // Referral/affiliate system with Golden Ratio decay + BADGES_ENABLED: false, // Achievement/badge system + EXTERNAL_TRACKER_ENABLED: false, // External wallet tracking service + SENTIMENT_ENABLED: false // Daily sentiment voting + }, + + // =================== + // MISC + // =================== + MAX_LOGS: 100, + RENDER_DISK_PATH: '/var/data' +}; diff --git a/control_panel.html b/control_panel.html index fc1c3d4..45efe06 100644 --- a/control_panel.html +++ b/control_panel.html @@ -1,4 +1,4 @@ - + @@ -70,6 +70,11 @@

ASDForecast // CONTROL PANEL

⚠️ Cancel + + +
@@ -86,10 +91,34 @@

ASDForecast // CONTROL PANEL

SOL Price
$0.00
-
- -
-

MARKET DEPTH

+ +
+

🎟️ LOTTERY STATUS

+
+
+
Current Round
+
#--
+
+
+
Next Draw
+
--
+
+
+
Last Winner
+
--
+
+
+
Last Prize
+
-- ASDF
+
+
+
+ + +
+ +
+

UP POOL 📈

UP Price
0.000 SOL
@@ -172,8 +201,8 @@

Frame History

-