dubs-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +280 -0
- package/CLAUDE.md +46 -0
- package/CONNECT4_PRODUCTION_DEPLOY.md +155 -0
- package/CURRENT_SESSION.md +171 -0
- package/CURRENT_SESSION_DRAW.md +516 -0
- package/MARCH_MADNESS_SURVIVOR.md +254 -0
- package/PANDA.md +166 -0
- package/Procfile +4 -0
- package/README.md +476 -0
- package/controllers/livescoresController.js +376 -0
- package/controllers/pickemController.js +554 -0
- package/controllers/survivorAdminController.js +887 -0
- package/controllers/survivorController.js +623 -0
- package/cron/oracleMonitor.js +77 -0
- package/cron/pickemOracleMonitor.js +73 -0
- package/data/jackpot-history.json +952 -0
- package/data/ncaaTeams.js +406 -0
- package/documentation/API_SECURITY_GUIDE.md +327 -0
- package/documentation/ARCADE_API.md +593 -0
- package/documentation/ARCADE_IMPLEMENTATION_SUMMARY.md +399 -0
- package/documentation/ARCADE_QUICKSTART.md +242 -0
- package/documentation/AUTOMATIC_MODE_ORACLE.md +321 -0
- package/documentation/BUG_FIX_COHORT_DATE_DISPLAY.md +171 -0
- package/documentation/CLAIM_MIGRATION_INSTRUCTIONS.md +52 -0
- package/documentation/CLAIM_STATUS_FIX.md +67 -0
- package/documentation/CLI_TOOL_GUIDE.md +372 -0
- package/documentation/COHORT_RETENTION_ANALYSIS.md +295 -0
- package/documentation/COHORT_RETENTION_IMPLEMENTATION_COMPLETE.md +461 -0
- package/documentation/COHORT_RETENTION_SUMMARY.md +204 -0
- package/documentation/COMPLETE_PROJECT_SUMMARY.md +490 -0
- package/documentation/DATABASE_QUERIES.md +269 -0
- package/documentation/DATABASE_RETENTION_POLICY.md +390 -0
- package/documentation/DATABASE_SETUP_GUIDE.md +361 -0
- package/documentation/DATABASE_SETUP_SUMMARY.md +247 -0
- package/documentation/DEMO_API_CURL_COMMANDS.md +656 -0
- package/documentation/DEPLOYMENT_SUMMARY.txt +100 -0
- package/documentation/DUPLICATE_NOTIFICATIONS_FIXED.md +201 -0
- package/documentation/EXCHANGE_RATES_INTEGRATION.md +371 -0
- package/documentation/FINAL_API_PROTECTION_TABLE.md +175 -0
- package/documentation/GAME_START_NOTIFICATIONS_DEPLOYMENT.md +256 -0
- package/documentation/GAME_START_NOTIFICATIONS_INTEGRATION.md +275 -0
- package/documentation/HEROKU_DEPLOYMENT.md +134 -0
- package/documentation/HEROKU_SCHEDULER_SETUP.md +271 -0
- package/documentation/JACKPOT_API.md +521 -0
- package/documentation/JACKPOT_DEPLOYMENT_GUIDE.md +362 -0
- package/documentation/JWT_IMPLEMENTATION_SUMMARY.md +373 -0
- package/documentation/JWT_QUICK_SETUP.md +268 -0
- package/documentation/JWT_TESTING_GUIDE.md +404 -0
- package/documentation/KEEPER_RECOVERY_GUIDE.md +381 -0
- package/documentation/KEEPER_SETUP.md +206 -0
- package/documentation/KEEPER_STATE_MACHINE.md +423 -0
- package/documentation/LATEST_PRODUCTION_SETUP.md +387 -0
- package/documentation/LOCAL_VOTING_TEST.md +279 -0
- package/documentation/ORACLE_FIXES_SUMMARY.md +188 -0
- package/documentation/ORACLE_POSTGRESQL_UPDATE.md +202 -0
- package/documentation/PAYMENT_DEPLOYMENT.md +209 -0
- package/documentation/PNL_TRACKING_SETUP.md +189 -0
- package/documentation/PREVENTING_LOCKUP_ERRORS.md +472 -0
- package/documentation/PRODUCTION_READY_SUMMARY.md +227 -0
- package/documentation/PUBLIC_VS_PRIVATE_ENDPOINTS.md +278 -0
- package/documentation/QUICK_AUTH_SETUP.md +99 -0
- package/documentation/QUICK_DEPLOY.md +224 -0
- package/documentation/QUICK_FIX.md +114 -0
- package/documentation/QUICK_START.md +152 -0
- package/documentation/REFEREE_MODE_GUIDE.md +392 -0
- package/documentation/RETENTION_CORE_ACTION_UPDATE.md +313 -0
- package/documentation/RETENTION_UPDATE_SUMMARY.md +108 -0
- package/documentation/RUN_MIGRATION_NOW.md +39 -0
- package/documentation/SCRIPTS_UPDATE_SUMMARY.md +251 -0
- package/documentation/SETUP_GUIDE.md +184 -0
- package/documentation/STATE_MACHINE_IMPLEMENTATION.md +250 -0
- package/documentation/TELEGRAM_NOTIFICATIONS_DIAGNOSIS.md +361 -0
- package/documentation/UNIFIED_ARCHITECTURE.md +231 -0
- package/documentation/VOTING_DEPLOYMENT_SUMMARY.md +392 -0
- package/documentation/WEBSOCKET_ARCHITECTURE.md +881 -0
- package/documentation/WHAT_WE_BUILT_TODAY.md +369 -0
- package/documentation/latest/LATEST_PRODUCTION_SETUP.md +865 -0
- package/ecosystem.config.js +65 -0
- package/env.template +125 -0
- package/middleware/apiKeyAuth.js +136 -0
- package/middleware/authenticate.js +214 -0
- package/middleware/developerUserAuth.js +76 -0
- package/middleware/socketAuth.js +69 -0
- package/package.json +49 -0
- package/postman/Dubs-API-v1-With-Voting.postman_collection.json +555 -0
- package/postman/Dubs-API-v1.postman_collection.json +205 -0
- package/postman/Dubs_Developer_API.postman_collection.json +662 -0
- package/postman/QUICKSTART.md +118 -0
- package/postman/QUICK_REFERENCE.md +246 -0
- package/postman/README.md +71 -0
- package/postman/VOTING_API_GUIDE.md +426 -0
- package/refactor/Animations.md +148 -0
- package/refactor/Chat.md +252 -0
- package/routes/actionsRoutes.js +699 -0
- package/routes/adminRoutes.js +370 -0
- package/routes/analyticsRoutes.js +1262 -0
- package/routes/arcadeRoutes.js +557 -0
- package/routes/authRoutes.js +2310 -0
- package/routes/avatarRoutes.js +85 -0
- package/routes/botRoutes.js +211 -0
- package/routes/chatRoutes.js +377 -0
- package/routes/cryptoPriceRoutes.js +105 -0
- package/routes/developerRoutes.js +4201 -0
- package/routes/deviceRoutes.js +214 -0
- package/routes/dmRoutes.js +167 -0
- package/routes/esportsRoutes.js +806 -0
- package/routes/exchangeRateRoutes.js +233 -0
- package/routes/gamesRoutes.js +3028 -0
- package/routes/jackpotRoutes.js +754 -0
- package/routes/keeperMonitoringRoutes.js +156 -0
- package/routes/keeperWebhookRoutes.js +466 -0
- package/routes/livescoresRoutes.js +31 -0
- package/routes/pickemAdminRoutes.js +199 -0
- package/routes/pickemRoutes.js +231 -0
- package/routes/playerStatsRoutes.js +147 -0
- package/routes/portfolioRoutes.js +217 -0
- package/routes/promoRoutes.js +418 -0
- package/routes/referralEarningsRoutes.js +392 -0
- package/routes/socialRoutes.js +459 -0
- package/routes/sportsRoutes.js +1271 -0
- package/routes/survivorAdminRoutes.js +345 -0
- package/routes/survivorRoutes.js +756 -0
- package/routes/uploadRoutes.js +256 -0
- package/routes/userProfileRoutes.js +244 -0
- package/routes/whatsNewRoutes.js +331 -0
- package/scripts/.claude/settings.local.json +15 -0
- package/scripts/README.md +170 -0
- package/scripts/RESTART_EVERYTHING.sh +104 -0
- package/scripts/add-claim-columns.sql +48 -0
- package/scripts/add-crypto-prices-cache.sql +27 -0
- package/scripts/add-exchange-rates-cache.sql +40 -0
- package/scripts/add-game-invite-column.sql +23 -0
- package/scripts/add-game-invite-notification.sql +33 -0
- package/scripts/add-game-invite-telegram-pref.sql +16 -0
- package/scripts/add-game-joined-notification.sql +16 -0
- package/scripts/add-game-joined-pref.js +40 -0
- package/scripts/add-game-joined-preference.sql +6 -0
- package/scripts/add-game-start-notifications.sql +41 -0
- package/scripts/add-notification-flags-to-games.sql +55 -0
- package/scripts/add-pending-game-dismissals.sql +19 -0
- package/scripts/add-preferred-currency.sql +34 -0
- package/scripts/add-winner-columns.js +61 -0
- package/scripts/add_mention_system.sql +53 -0
- package/scripts/add_payment_system.sql +96 -0
- package/scripts/add_sports_event_id_column.sql +22 -0
- package/scripts/analyze-cohort-data-heroku.js +276 -0
- package/scripts/analyze-cohort-data.js +295 -0
- package/scripts/analyze-prod-cohorts.sh +10 -0
- package/scripts/backfill-matchup-images.js +245 -0
- package/scripts/backfill-missing-signatures.js +175 -0
- package/scripts/backfill-referral-earnings.js +202 -0
- package/scripts/check-chat-schema.js +130 -0
- package/scripts/check-db.sh +14 -0
- package/scripts/check_oracle_in_game.js +54 -0
- package/scripts/cleanup-database.js +193 -0
- package/scripts/clear-notification-cache.js +85 -0
- package/scripts/convert-mnemonic.js +50 -0
- package/scripts/create-users-table.sql +44 -0
- package/scripts/debug-cohort-counts.js +248 -0
- package/scripts/debug-winner-calc.js +84 -0
- package/scripts/deploy-payment-system.sh +118 -0
- package/scripts/deploy-to-heroku.sh +63 -0
- package/scripts/diagnose-locked-round.js +143 -0
- package/scripts/dubs-cli.js +720 -0
- package/scripts/dump-account.js +65 -0
- package/scripts/find-vrf-offset.js +48 -0
- package/scripts/fix-chat-notifications-constraint.sql +122 -0
- package/scripts/fix-claim-columns.js +124 -0
- package/scripts/fix-constraint-now.js +44 -0
- package/scripts/fix-lock-timestamps.js +96 -0
- package/scripts/fix-locked-round.sh +126 -0
- package/scripts/fix-missing-badges.sql +91 -0
- package/scripts/fix-payment-notifications.sql +41 -0
- package/scripts/force-new-round.js +55 -0
- package/scripts/force-resolve-and-claim.js +278 -0
- package/scripts/important/README.md +115 -0
- package/scripts/important/authority-force-lock.js +197 -0
- package/scripts/important/authority-resolve-game.js +267 -0
- package/scripts/important/check-game-status.js +373 -0
- package/scripts/important/list-pending-games-by-version.js +270 -0
- package/scripts/important/reconcile-v1-v2-payouts.js +270 -0
- package/scripts/initialize-jackpot.js +111 -0
- package/scripts/jackpot/.claude/settings.local.json +10 -0
- package/scripts/jackpot/force-reset.js +84 -0
- package/scripts/jackpot/initialize-mainnet.js +100 -0
- package/scripts/jackpot/keeper.js +742 -0
- package/scripts/jackpot/status.js +107 -0
- package/scripts/jackpot/update-round-duration.js +143 -0
- package/scripts/keeper-bot.js +112 -0
- package/scripts/list-pending-games.js +131 -0
- package/scripts/migrate-chat-v2.js +127 -0
- package/scripts/migrate-chat-winners.js +84 -0
- package/scripts/migrate-chat.sh +17 -0
- package/scripts/migrate-game-invite.js +83 -0
- package/scripts/migrate-heroku-game-notifications.sh +159 -0
- package/scripts/migrations/001_analytics_tables.sql +422 -0
- package/scripts/migrations/002_add_matchup_image_url.sql +14 -0
- package/scripts/migrations/003_referral_earnings.sql +208 -0
- package/scripts/migrations/004_add_whats_new_notification_type.sql +62 -0
- package/scripts/migrations/005_add_connect4_your_turn_notification.sql +61 -0
- package/scripts/migrations/005_push_notifications.sql +55 -0
- package/scripts/migrations/006_add_draw_team_players.sql +28 -0
- package/scripts/migrations/006_add_game_cancelled_notification.sql +62 -0
- package/scripts/migrations/007_add_gif_url.sql +8 -0
- package/scripts/migrations/008_add_connect4_columns.sql +139 -0
- package/scripts/migrations/008_add_pool_tracking.sql +22 -0
- package/scripts/migrations/009_create_survivor_pool_tables.sql +174 -0
- package/scripts/migrations/010_add_survivor_pool_outcome.sql +28 -0
- package/scripts/migrations/011_create_developer_tables.sql +67 -0
- package/scripts/migrations/011_fix_keeper_tables.sql +85 -0
- package/scripts/migrations/012_create_developer_webhooks.sql +31 -0
- package/scripts/migrations/013_add_network_mode.sql +18 -0
- package/scripts/migrations/014_create_developer_app_users.sql +19 -0
- package/scripts/migrations/015_add_ui_config.sql +4 -0
- package/scripts/migrations/016_add_resolution_secret.sql +4 -0
- package/scripts/migrations/017_add_external_game_id.sql +3 -0
- package/scripts/migrations/018_create_pickem_tables.sql +115 -0
- package/scripts/migrations/019_expo_push_tokens.sql +19 -0
- package/scripts/migrations/create_whats_new_tables.sql +88 -0
- package/scripts/migrations/drop_live_games_tables.sql +34 -0
- package/scripts/open-jackpot-round.js +85 -0
- package/scripts/purge-all-data.sh +329 -0
- package/scripts/purge-all-data.sql +142 -0
- package/scripts/purge-heroku-data.sh +149 -0
- package/scripts/purge-heroku-data.sql +62 -0
- package/scripts/rebuild-heroku-database.sh +113 -0
- package/scripts/recover-funds.js +357 -0
- package/scripts/regenerate-epl-images.js +278 -0
- package/scripts/resize-s3-matchup-images.js +374 -0
- package/scripts/resolve-direct.js +88 -0
- package/scripts/resolve-mock-game.js +124 -0
- package/scripts/resolve-pickem-game.js +55 -0
- package/scripts/resolve-round-manual.js +83 -0
- package/scripts/resolve-stuck-game.js +382 -0
- package/scripts/resolve-stuck-round.js +42 -0
- package/scripts/run-connect4-migration.sh +16 -0
- package/scripts/run-mention-migration.sh +32 -0
- package/scripts/run-payment-migration.sh +51 -0
- package/scripts/run-preferred-currency-migration.sh +31 -0
- package/scripts/run-referral-earnings-migration.sh +32 -0
- package/scripts/run-survivor-outcome-migration.sh +16 -0
- package/scripts/seed-test-users.js +346 -0
- package/scripts/setup-auth-tables.js +78 -0
- package/scripts/setup-complete-database.sql +992 -0
- package/scripts/setup-database-fresh.sh +359 -0
- package/scripts/setup-heroku-keeper.sh +48 -0
- package/scripts/setup-keeper-database.js +83 -0
- package/scripts/setup-keeper-state-db.sql +110 -0
- package/scripts/setup-oracle.sh +39 -0
- package/scripts/setup-pnl-tracking.js +111 -0
- package/scripts/start-devnet.sh +14 -0
- package/scripts/test-arcade-devnet.sh +160 -0
- package/scripts/test-arcade-match.sh +109 -0
- package/scripts/test-automatic-mode.sh +239 -0
- package/scripts/test-connect4-cancel-claim.js +370 -0
- package/scripts/test-connect4-e2e.js +369 -0
- package/scripts/test-connect4-resolve.js +369 -0
- package/scripts/test-game-state-endpoint.js +136 -0
- package/scripts/test-invite-notification.js +86 -0
- package/scripts/test-jackpot-api.sh +71 -0
- package/scripts/test-poll-confirmation.js +267 -0
- package/scripts/test-resolve-game.js +271 -0
- package/scripts/test-resolve-signature.js +223 -0
- package/scripts/test-signature-preservation.js +124 -0
- package/scripts/test-state-machine.js +291 -0
- package/scripts/test-webhook-receiver.js +60 -0
- package/scripts/update-notification-constraint.js +52 -0
- package/scripts/verify-account-layout.js +145 -0
- package/scripts/verify-winner-algorithm.js +278 -0
- package/server.js +5259 -0
- package/services/arcadeMatchService.js +763 -0
- package/services/automaticGameOracle.js +1596 -0
- package/services/chatService.js +1612 -0
- package/services/connect4GameService.js +1049 -0
- package/services/connect4NotificationService.js +374 -0
- package/services/cryptoPriceService.js +223 -0
- package/services/customGameResolver.js +260 -0
- package/services/db.js +79 -0
- package/services/directMessageService.js +389 -0
- package/services/discordNotifications.js +160 -0
- package/services/exchangeRateService.js +289 -0
- package/services/expoPushService.js +314 -0
- package/services/gamesCacheService.js +539 -0
- package/services/jackpotHistory.js +331 -0
- package/services/jackpotService.js +856 -0
- package/services/keeperStateService.js +355 -0
- package/services/matchupImageService.js +591 -0
- package/services/notificationCacheService.js +407 -0
- package/services/pickemOracle.js +440 -0
- package/services/playerStatsService.js +389 -0
- package/services/portfolioService.js +555 -0
- package/services/promoService.js +757 -0
- package/services/promoTreasuryService.js +239 -0
- package/services/pushNotifications.js +353 -0
- package/services/redisService.js +422 -0
- package/services/referralEarningsService.js +728 -0
- package/services/s3Service.js +396 -0
- package/services/socialService.js +1202 -0
- package/services/survivorOracle.js +469 -0
- package/services/survivorSimulator.js +475 -0
- package/services/telegramNotifications.js +461 -0
- package/services/userProfileStatsService.js +1185 -0
- package/services/whatsNewService.js +388 -0
- package/utils/urlHelper.js +95 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { Connection, PublicKey } = require('@solana/web3.js');
|
|
4
|
+
|
|
5
|
+
const RPC_URL = 'https://api.devnet.solana.com';
|
|
6
|
+
const PROGRAM_ID = new PublicKey('BHidyz25KWkNPdTHgeANzMg25MM2KEiNnG4yE5F46XUz');
|
|
7
|
+
|
|
8
|
+
async function dumpAccount() {
|
|
9
|
+
const connection = new Connection(RPC_URL, 'confirmed');
|
|
10
|
+
|
|
11
|
+
const [roundPda] = PublicKey.findProgramAddressSync(
|
|
12
|
+
[Buffer.from('round'), Buffer.from([1,0,0,0,0,0,0,0])],
|
|
13
|
+
PROGRAM_ID
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
console.log('Round PDA:', roundPda.toString());
|
|
17
|
+
|
|
18
|
+
const account = await connection.getAccountInfo(roundPda);
|
|
19
|
+
if (!account) {
|
|
20
|
+
console.log('Account not found!');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log('Account data length:', account.data.length);
|
|
25
|
+
console.log();
|
|
26
|
+
|
|
27
|
+
// Dump relevant sections
|
|
28
|
+
console.log('Bytes 0-16 (discriminator + round_id + status):');
|
|
29
|
+
console.log(account.data.slice(0, 17).toString('hex'));
|
|
30
|
+
console.log();
|
|
31
|
+
|
|
32
|
+
console.log('Bytes 49-54 (winner_index Option<u32>):');
|
|
33
|
+
console.log(account.data.slice(49, 54).toString('hex'));
|
|
34
|
+
console.log();
|
|
35
|
+
|
|
36
|
+
console.log('Bytes 54-87 (winner Option<Pubkey>):');
|
|
37
|
+
console.log(account.data.slice(54, 87).toString('hex'));
|
|
38
|
+
console.log();
|
|
39
|
+
|
|
40
|
+
console.log('Bytes 87-104 (vrf_result Option<u128>):');
|
|
41
|
+
console.log(account.data.slice(87, 104).toString('hex'));
|
|
42
|
+
console.log(' - Byte 87 (Option discriminant):', account.data[87]);
|
|
43
|
+
console.log(' - Bytes 88-104 (u128 if Some):', account.data.slice(88, 104).toString('hex'));
|
|
44
|
+
console.log();
|
|
45
|
+
|
|
46
|
+
console.log('Bytes 68-72 (entry_count u32):');
|
|
47
|
+
console.log(account.data.slice(68, 72).toString('hex'));
|
|
48
|
+
const entryCount = account.data.readUInt32LE(68);
|
|
49
|
+
console.log(' - Entry count:', entryCount);
|
|
50
|
+
console.log();
|
|
51
|
+
|
|
52
|
+
console.log('Bytes 108-140 (server_seed_hash [u8; 32]):');
|
|
53
|
+
console.log(account.data.slice(108, 140).toString('hex'));
|
|
54
|
+
console.log();
|
|
55
|
+
|
|
56
|
+
console.log('Bytes 140-173 (oracle_seed Option<[u8; 32]>):');
|
|
57
|
+
console.log(account.data.slice(140, 173).toString('hex'));
|
|
58
|
+
console.log(' - Byte 140 (Option discriminant):', account.data[140]);
|
|
59
|
+
if (account.data[140] === 1) {
|
|
60
|
+
console.log(' - Oracle seed:', account.data.slice(141, 173).toString('hex'));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
dumpAccount().catch(console.error);
|
|
65
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { Connection, PublicKey } = require('@solana/web3.js');
|
|
4
|
+
|
|
5
|
+
const RPC_URL = 'https://api.devnet.solana.com';
|
|
6
|
+
const PROGRAM_ID = new PublicKey('BHidyz25KWkNPdTHgeANzMg25MM2KEiNnG4yE5F46XUz');
|
|
7
|
+
|
|
8
|
+
async function findVrfOffset() {
|
|
9
|
+
const connection = new Connection(RPC_URL, 'confirmed');
|
|
10
|
+
|
|
11
|
+
const [roundPda] = PublicKey.findProgramAddressSync(
|
|
12
|
+
[Buffer.from('round'), Buffer.from([1,0,0,0,0,0,0,0])],
|
|
13
|
+
PROGRAM_ID
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const account = await connection.getAccountInfo(roundPda);
|
|
17
|
+
if (!account) {
|
|
18
|
+
console.log('Account not found!');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log('Account length:', account.data.length);
|
|
23
|
+
console.log('Full hex dump:');
|
|
24
|
+
console.log(account.data.toString('hex'));
|
|
25
|
+
console.log();
|
|
26
|
+
|
|
27
|
+
console.log('Searching for Option<u128> (discriminant = 1)...');
|
|
28
|
+
console.log();
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < account.data.length - 17; i++) {
|
|
31
|
+
if (account.data[i] === 1) {
|
|
32
|
+
const valueBytes = account.data.slice(i + 1, i + 17);
|
|
33
|
+
const value = BigInt('0x' + Buffer.from(valueBytes).reverse().toString('hex'));
|
|
34
|
+
console.log(`Offset ${i}: discriminant=1, value=${value.toString()}`);
|
|
35
|
+
console.log(` Hex: ${account.data.slice(i, i + 17).toString('hex')}`);
|
|
36
|
+
console.log();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
console.log('Known field offsets:');
|
|
41
|
+
console.log(' round_id (offset 8):', account.data.readBigUInt64LE(8).toString());
|
|
42
|
+
console.log(' status (offset 16):', account.data[16], ['Open', 'Locked', 'Resolved'][account.data[16]]);
|
|
43
|
+
console.log(' total_pot (offset 33):', account.data.readBigUInt64LE(33).toString());
|
|
44
|
+
console.log(' total_weight (offset 41):', account.data.readBigUInt64LE(41).toString());
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
findVrfOffset().catch(console.error);
|
|
48
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
-- ============================================
|
|
2
|
+
-- 🔧 FIX CHAT_NOTIFICATIONS CHECK CONSTRAINT
|
|
3
|
+
-- ============================================
|
|
4
|
+
-- This script updates the notification_type CHECK constraint
|
|
5
|
+
-- to include all notification types used by the application.
|
|
6
|
+
--
|
|
7
|
+
-- Run with: heroku pg:psql --app YOUR_APP_NAME < scripts/fix-chat-notifications-constraint.sql
|
|
8
|
+
-- Or locally: psql -d dubs_db -f scripts/fix-chat-notifications-constraint.sql
|
|
9
|
+
|
|
10
|
+
-- Step 1: Show current constraint (for debugging)
|
|
11
|
+
\echo 'Current constraints on chat_notifications:'
|
|
12
|
+
SELECT conname, pg_get_constraintdef(oid)
|
|
13
|
+
FROM pg_constraint
|
|
14
|
+
WHERE conrelid = 'chat_notifications'::regclass;
|
|
15
|
+
|
|
16
|
+
-- Step 2: Drop the old CHECK constraint
|
|
17
|
+
DO $$
|
|
18
|
+
BEGIN
|
|
19
|
+
-- Find and drop any CHECK constraint on notification_type
|
|
20
|
+
PERFORM 1 FROM pg_constraint
|
|
21
|
+
WHERE conrelid = 'chat_notifications'::regclass
|
|
22
|
+
AND contype = 'c';
|
|
23
|
+
|
|
24
|
+
IF FOUND THEN
|
|
25
|
+
-- Drop all check constraints (there should only be one on notification_type)
|
|
26
|
+
EXECUTE (
|
|
27
|
+
SELECT string_agg('ALTER TABLE chat_notifications DROP CONSTRAINT ' || conname, '; ')
|
|
28
|
+
FROM pg_constraint
|
|
29
|
+
WHERE conrelid = 'chat_notifications'::regclass
|
|
30
|
+
AND contype = 'c'
|
|
31
|
+
);
|
|
32
|
+
RAISE NOTICE 'Dropped existing CHECK constraint(s)';
|
|
33
|
+
ELSE
|
|
34
|
+
RAISE NOTICE 'No CHECK constraints found to drop';
|
|
35
|
+
END IF;
|
|
36
|
+
END $$;
|
|
37
|
+
|
|
38
|
+
-- Step 3: Add the updated CHECK constraint with ALL notification types
|
|
39
|
+
ALTER TABLE chat_notifications
|
|
40
|
+
ADD CONSTRAINT chat_notifications_notification_type_check
|
|
41
|
+
CHECK (notification_type IN (
|
|
42
|
+
'reply',
|
|
43
|
+
'mention',
|
|
44
|
+
'friend_message',
|
|
45
|
+
'reaction',
|
|
46
|
+
'friend_request',
|
|
47
|
+
'friend_request_accepted',
|
|
48
|
+
'friend_request_declined',
|
|
49
|
+
'referral',
|
|
50
|
+
'game_joined',
|
|
51
|
+
'game_invite',
|
|
52
|
+
'game_starting_soon',
|
|
53
|
+
'game_starting_now',
|
|
54
|
+
'game_won',
|
|
55
|
+
'game_lost',
|
|
56
|
+
'payment_received',
|
|
57
|
+
'payment_sent',
|
|
58
|
+
'dm'
|
|
59
|
+
));
|
|
60
|
+
|
|
61
|
+
\echo 'Updated CHECK constraint. New constraints:'
|
|
62
|
+
SELECT conname, pg_get_constraintdef(oid)
|
|
63
|
+
FROM pg_constraint
|
|
64
|
+
WHERE conrelid = 'chat_notifications'::regclass;
|
|
65
|
+
|
|
66
|
+
-- Step 4: Ensure notification_data column exists
|
|
67
|
+
DO $$
|
|
68
|
+
BEGIN
|
|
69
|
+
IF NOT EXISTS (
|
|
70
|
+
SELECT 1 FROM information_schema.columns
|
|
71
|
+
WHERE table_name = 'chat_notifications' AND column_name = 'notification_data'
|
|
72
|
+
) THEN
|
|
73
|
+
ALTER TABLE chat_notifications ADD COLUMN notification_data JSONB;
|
|
74
|
+
RAISE NOTICE 'Added notification_data column';
|
|
75
|
+
ELSE
|
|
76
|
+
RAISE NOTICE 'notification_data column already exists';
|
|
77
|
+
END IF;
|
|
78
|
+
END $$;
|
|
79
|
+
|
|
80
|
+
-- Step 5: Ensure user_relationships table exists
|
|
81
|
+
CREATE TABLE IF NOT EXISTS user_relationships (
|
|
82
|
+
id SERIAL PRIMARY KEY,
|
|
83
|
+
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
84
|
+
target_user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
85
|
+
relationship_type VARCHAR(20) NOT NULL CHECK (relationship_type IN ('friend', 'block')),
|
|
86
|
+
created_at TIMESTAMP DEFAULT NOW(),
|
|
87
|
+
UNIQUE(user_id, target_user_id)
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_relationships_user ON user_relationships(user_id);
|
|
91
|
+
CREATE INDEX IF NOT EXISTS idx_relationships_type ON user_relationships(relationship_type);
|
|
92
|
+
|
|
93
|
+
-- Step 6: Ensure friend_requests table exists with proper constraints
|
|
94
|
+
CREATE TABLE IF NOT EXISTS friend_requests (
|
|
95
|
+
id SERIAL PRIMARY KEY,
|
|
96
|
+
from_user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
97
|
+
to_user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
98
|
+
status VARCHAR(20) NOT NULL CHECK (status IN ('pending', 'accepted', 'rejected')) DEFAULT 'pending',
|
|
99
|
+
created_at TIMESTAMP DEFAULT NOW(),
|
|
100
|
+
updated_at TIMESTAMP DEFAULT NOW()
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
-- Add unique constraint for friend_requests if it doesn't exist
|
|
104
|
+
DO $$
|
|
105
|
+
BEGIN
|
|
106
|
+
IF NOT EXISTS (
|
|
107
|
+
SELECT 1 FROM pg_constraint
|
|
108
|
+
WHERE conname = 'friend_requests_from_user_id_to_user_id_key'
|
|
109
|
+
) THEN
|
|
110
|
+
ALTER TABLE friend_requests
|
|
111
|
+
ADD CONSTRAINT friend_requests_from_user_id_to_user_id_key
|
|
112
|
+
UNIQUE (from_user_id, to_user_id);
|
|
113
|
+
END IF;
|
|
114
|
+
END $$;
|
|
115
|
+
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_friend_requests_from ON friend_requests(from_user_id);
|
|
117
|
+
CREATE INDEX IF NOT EXISTS idx_friend_requests_to ON friend_requests(to_user_id);
|
|
118
|
+
CREATE INDEX IF NOT EXISTS idx_friend_requests_status ON friend_requests(status);
|
|
119
|
+
|
|
120
|
+
\echo '✅ Migration complete! Friend request functionality should now work.';
|
|
121
|
+
|
|
122
|
+
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration: Add claim columns to user_game_refs table
|
|
3
|
+
* Run this to fix the claim functionality
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { Pool } = require('pg');
|
|
7
|
+
|
|
8
|
+
const pool = new Pool({
|
|
9
|
+
connectionString: process.env.DATABASE_URL,
|
|
10
|
+
ssl: process.env.DATABASE_URL && (process.env.DATABASE_URL.includes('amazonaws') || process.env.DATABASE_URL.includes('heroku'))
|
|
11
|
+
? { rejectUnauthorized: false }
|
|
12
|
+
: false
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
async function runMigration() {
|
|
16
|
+
console.log('🔧 Starting migration: Adding claim columns to user_game_refs...');
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
// Add columns if they don't exist
|
|
20
|
+
await pool.query(`
|
|
21
|
+
DO $$
|
|
22
|
+
BEGIN
|
|
23
|
+
-- Add claimed_at column
|
|
24
|
+
IF NOT EXISTS (
|
|
25
|
+
SELECT 1 FROM information_schema.columns
|
|
26
|
+
WHERE table_name = 'user_game_refs' AND column_name = 'claimed_at'
|
|
27
|
+
) THEN
|
|
28
|
+
ALTER TABLE user_game_refs ADD COLUMN claimed_at TIMESTAMP;
|
|
29
|
+
RAISE NOTICE 'Added claimed_at column';
|
|
30
|
+
ELSE
|
|
31
|
+
RAISE NOTICE 'claimed_at column already exists';
|
|
32
|
+
END IF;
|
|
33
|
+
|
|
34
|
+
-- Add claim_signature column
|
|
35
|
+
IF NOT EXISTS (
|
|
36
|
+
SELECT 1 FROM information_schema.columns
|
|
37
|
+
WHERE table_name = 'user_game_refs' AND column_name = 'claim_signature'
|
|
38
|
+
) THEN
|
|
39
|
+
ALTER TABLE user_game_refs ADD COLUMN claim_signature TEXT;
|
|
40
|
+
RAISE NOTICE 'Added claim_signature column';
|
|
41
|
+
ELSE
|
|
42
|
+
RAISE NOTICE 'claim_signature column already exists';
|
|
43
|
+
END IF;
|
|
44
|
+
|
|
45
|
+
-- Add claim_explorer_url column
|
|
46
|
+
IF NOT EXISTS (
|
|
47
|
+
SELECT 1 FROM information_schema.columns
|
|
48
|
+
WHERE table_name = 'user_game_refs' AND column_name = 'claim_explorer_url'
|
|
49
|
+
) THEN
|
|
50
|
+
ALTER TABLE user_game_refs ADD COLUMN claim_explorer_url TEXT;
|
|
51
|
+
RAISE NOTICE 'Added claim_explorer_url column';
|
|
52
|
+
ELSE
|
|
53
|
+
RAISE NOTICE 'claim_explorer_url column already exists';
|
|
54
|
+
END IF;
|
|
55
|
+
|
|
56
|
+
-- Add amount_claimed column
|
|
57
|
+
IF NOT EXISTS (
|
|
58
|
+
SELECT 1 FROM information_schema.columns
|
|
59
|
+
WHERE table_name = 'user_game_refs' AND column_name = 'amount_claimed'
|
|
60
|
+
) THEN
|
|
61
|
+
ALTER TABLE user_game_refs ADD COLUMN amount_claimed DECIMAL(20, 9);
|
|
62
|
+
RAISE NOTICE 'Added amount_claimed column';
|
|
63
|
+
ELSE
|
|
64
|
+
RAISE NOTICE 'amount_claimed column already exists';
|
|
65
|
+
END IF;
|
|
66
|
+
|
|
67
|
+
-- Add updated_at column
|
|
68
|
+
IF NOT EXISTS (
|
|
69
|
+
SELECT 1 FROM information_schema.columns
|
|
70
|
+
WHERE table_name = 'user_game_refs' AND column_name = 'updated_at'
|
|
71
|
+
) THEN
|
|
72
|
+
ALTER TABLE user_game_refs ADD COLUMN updated_at TIMESTAMP DEFAULT NOW();
|
|
73
|
+
RAISE NOTICE 'Added updated_at column';
|
|
74
|
+
ELSE
|
|
75
|
+
RAISE NOTICE 'updated_at column already exists';
|
|
76
|
+
END IF;
|
|
77
|
+
END $$;
|
|
78
|
+
`);
|
|
79
|
+
|
|
80
|
+
console.log('✅ Migration completed successfully!');
|
|
81
|
+
|
|
82
|
+
// Verify the columns exist
|
|
83
|
+
const result = await pool.query(`
|
|
84
|
+
SELECT column_name, data_type
|
|
85
|
+
FROM information_schema.columns
|
|
86
|
+
WHERE table_name = 'user_game_refs'
|
|
87
|
+
AND column_name IN ('claimed_at', 'claim_signature', 'claim_explorer_url', 'amount_claimed', 'updated_at')
|
|
88
|
+
ORDER BY column_name
|
|
89
|
+
`);
|
|
90
|
+
|
|
91
|
+
console.log('\n📊 Verification - Columns in user_game_refs:');
|
|
92
|
+
result.rows.forEach(row => {
|
|
93
|
+
console.log(` ✓ ${row.column_name} (${row.data_type})`);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
console.log('\n🎉 Migration complete! Claim functionality should now work.');
|
|
97
|
+
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error('❌ Migration failed:', error);
|
|
100
|
+
throw error;
|
|
101
|
+
} finally {
|
|
102
|
+
await pool.end();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Run the migration
|
|
107
|
+
runMigration()
|
|
108
|
+
.then(() => {
|
|
109
|
+
console.log('\n✅ Done!');
|
|
110
|
+
process.exit(0);
|
|
111
|
+
})
|
|
112
|
+
.catch((error) => {
|
|
113
|
+
console.error('\n❌ Migration failed:', error);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick Fix: Update notification constraint
|
|
3
|
+
* Run with: node fix-constraint-now.js
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
require('dotenv').config(); // Load .env file
|
|
7
|
+
const { Pool } = require('pg');
|
|
8
|
+
|
|
9
|
+
async function fix() {
|
|
10
|
+
const pool = new Pool({
|
|
11
|
+
connectionString: process.env.DATABASE_URL,
|
|
12
|
+
ssl: process.env.DATABASE_URL && (process.env.DATABASE_URL.includes('amazonaws') || process.env.DATABASE_URL.includes('heroku'))
|
|
13
|
+
? { rejectUnauthorized: false }
|
|
14
|
+
: false
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
console.log('🔧 Fixing constraint...');
|
|
19
|
+
|
|
20
|
+
await pool.query(`ALTER TABLE chat_notifications DROP CONSTRAINT IF EXISTS chat_notifications_notification_type_check`);
|
|
21
|
+
console.log('✅ Dropped old constraint');
|
|
22
|
+
|
|
23
|
+
await pool.query(`ALTER TABLE chat_notifications ADD CONSTRAINT chat_notifications_notification_type_check CHECK (notification_type IN ('reply', 'mention', 'friend_message', 'reaction', 'friend_request', 'friend_request_accepted', 'friend_request_declined', 'referral', 'game_joined', 'game_invite'))`);
|
|
24
|
+
console.log('✅ Added new constraint with game_invite');
|
|
25
|
+
|
|
26
|
+
console.log('🎉 Done! Try inviting a friend now.');
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error('❌ Error:', error.message);
|
|
29
|
+
} finally {
|
|
30
|
+
await pool.end();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fix();
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Fix Lock Timestamps - Update existing games with NULL lock_timestamp
|
|
4
|
+
* This script calculates lock_timestamp from sportsEvent.strTimestamp
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
require('dotenv').config();
|
|
8
|
+
const { Pool } = require('pg');
|
|
9
|
+
|
|
10
|
+
const pool = new Pool({
|
|
11
|
+
connectionString: process.env.DATABASE_URL,
|
|
12
|
+
ssl: process.env.DATABASE_URL && (process.env.DATABASE_URL.includes('amazonaws') || process.env.DATABASE_URL.includes('heroku'))
|
|
13
|
+
? { rejectUnauthorized: false }
|
|
14
|
+
: false
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
async function fixLockTimestamps() {
|
|
18
|
+
try {
|
|
19
|
+
console.log('🔧 Fixing lock timestamps for automatic games...\n');
|
|
20
|
+
|
|
21
|
+
// Get all automatic games with NULL lock_timestamp
|
|
22
|
+
const result = await pool.query(`
|
|
23
|
+
SELECT game_id, sports_event
|
|
24
|
+
FROM games
|
|
25
|
+
WHERE game_mode = 4
|
|
26
|
+
AND lock_timestamp IS NULL
|
|
27
|
+
AND sports_event IS NOT NULL
|
|
28
|
+
`);
|
|
29
|
+
|
|
30
|
+
console.log(`Found ${result.rows.length} game(s) with NULL lock_timestamp\n`);
|
|
31
|
+
|
|
32
|
+
if (result.rows.length === 0) {
|
|
33
|
+
console.log('✅ No games need fixing!');
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let fixed = 0;
|
|
38
|
+
let failed = 0;
|
|
39
|
+
|
|
40
|
+
for (const row of result.rows) {
|
|
41
|
+
try {
|
|
42
|
+
const sportsEvent = row.sports_event;
|
|
43
|
+
|
|
44
|
+
if (!sportsEvent.strTimestamp) {
|
|
45
|
+
console.log(`⚠️ Game ${row.game_id}: No strTimestamp in sports event - skipping`);
|
|
46
|
+
failed++;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Convert ISO timestamp to Unix timestamp (seconds since epoch)
|
|
51
|
+
const lockDate = new Date(sportsEvent.strTimestamp + 'Z');
|
|
52
|
+
const lockTimestamp = Math.floor(lockDate.getTime() / 1000);
|
|
53
|
+
|
|
54
|
+
// Update the game
|
|
55
|
+
await pool.query(`
|
|
56
|
+
UPDATE games
|
|
57
|
+
SET lock_timestamp = $1, updated_at = NOW()
|
|
58
|
+
WHERE game_id = $2
|
|
59
|
+
`, [lockTimestamp, row.game_id]);
|
|
60
|
+
|
|
61
|
+
console.log(`✅ Game ${row.game_id}: Set lock_timestamp to ${lockTimestamp} (${sportsEvent.strTimestamp})`);
|
|
62
|
+
fixed++;
|
|
63
|
+
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error(`❌ Game ${row.game_id}: Error - ${error.message}`);
|
|
66
|
+
failed++;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
71
|
+
console.log(`✅ Fixed: ${fixed}`);
|
|
72
|
+
console.log(`❌ Failed: ${failed}`);
|
|
73
|
+
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
|
|
74
|
+
|
|
75
|
+
process.exit(0);
|
|
76
|
+
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error('❌ Error:', error.message);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
} finally {
|
|
81
|
+
await pool.end();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fixLockTimestamps();
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# 🔧 Fix Locked Round - Complete Recovery Script
|
|
4
|
+
# This script will:
|
|
5
|
+
# 1. Check if server is running
|
|
6
|
+
# 2. Check if keeper bot is running
|
|
7
|
+
# 3. Diagnose the locked round
|
|
8
|
+
# 4. Provide step-by-step fix
|
|
9
|
+
|
|
10
|
+
echo "🔧 Dubs Jackpot - Locked Round Recovery"
|
|
11
|
+
echo "========================================"
|
|
12
|
+
echo ""
|
|
13
|
+
|
|
14
|
+
# Colors
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
NC='\033[0m' # No Color
|
|
19
|
+
|
|
20
|
+
# Check if server is running
|
|
21
|
+
echo "1️⃣ Checking API server status..."
|
|
22
|
+
if curl -s http://localhost:3001/jackpot/health > /dev/null 2>&1; then
|
|
23
|
+
echo -e "${GREEN}✅ API server is running${NC}"
|
|
24
|
+
else
|
|
25
|
+
echo -e "${RED}❌ API server is NOT running${NC}"
|
|
26
|
+
echo ""
|
|
27
|
+
echo "To fix:"
|
|
28
|
+
echo " cd /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server"
|
|
29
|
+
echo " SOLANA_NETWORK=https://api.devnet.solana.com node server.js"
|
|
30
|
+
echo ""
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Check if keeper bot is running
|
|
35
|
+
echo ""
|
|
36
|
+
echo "2️⃣ Checking keeper bot status..."
|
|
37
|
+
if pgrep -f "jackpot-keeper.js" > /dev/null; then
|
|
38
|
+
echo -e "${GREEN}✅ Keeper bot is running${NC}"
|
|
39
|
+
echo " Process ID: $(pgrep -f 'jackpot-keeper.js')"
|
|
40
|
+
else
|
|
41
|
+
echo -e "${RED}❌ Keeper bot is NOT running${NC}"
|
|
42
|
+
echo ""
|
|
43
|
+
echo "This is likely why your round is stuck!"
|
|
44
|
+
echo ""
|
|
45
|
+
echo "To fix:"
|
|
46
|
+
echo " cd /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server"
|
|
47
|
+
echo " node scripts/jackpot-keeper.js"
|
|
48
|
+
echo ""
|
|
49
|
+
echo "💡 The keeper bot will automatically:"
|
|
50
|
+
echo " • Reveal oracle randomness"
|
|
51
|
+
echo " • Resolve the locked round"
|
|
52
|
+
echo " • Pay the winner"
|
|
53
|
+
echo " • Start a new round"
|
|
54
|
+
echo ""
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Get current round status
|
|
59
|
+
echo ""
|
|
60
|
+
echo "3️⃣ Checking round status..."
|
|
61
|
+
ROUND_INFO=$(curl -s http://localhost:3001/jackpot/round/current)
|
|
62
|
+
|
|
63
|
+
if echo "$ROUND_INFO" | grep -q "error"; then
|
|
64
|
+
echo -e "${YELLOW}⚠️ No active round found${NC}"
|
|
65
|
+
echo ""
|
|
66
|
+
echo "To fix:"
|
|
67
|
+
echo " The keeper bot should automatically open a new round"
|
|
68
|
+
echo " Or manually run: node scripts/jackpot-keeper.js"
|
|
69
|
+
exit 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
STATUS=$(echo "$ROUND_INFO" | grep -o '"status":"[^"]*"' | cut -d'"' -f4)
|
|
73
|
+
ROUND_ID=$(echo "$ROUND_INFO" | grep -o '"roundId":"[^"]*"' | cut -d'"' -f4)
|
|
74
|
+
POT=$(echo "$ROUND_INFO" | grep -o '"totalPotLamports":"[^"]*"' | cut -d'"' -f4)
|
|
75
|
+
|
|
76
|
+
echo " Round ID: $ROUND_ID"
|
|
77
|
+
echo " Status: $STATUS"
|
|
78
|
+
echo " Pot: $(echo "scale=4; $POT / 1000000000" | bc) SOL"
|
|
79
|
+
echo ""
|
|
80
|
+
|
|
81
|
+
if [ "$STATUS" = "Locked" ]; then
|
|
82
|
+
echo -e "${YELLOW}🔒 Round IS locked${NC}"
|
|
83
|
+
echo ""
|
|
84
|
+
echo "The keeper bot should automatically:"
|
|
85
|
+
echo " 1. Reveal oracle randomness (consume_randomness)"
|
|
86
|
+
echo " 2. Resolve the round (select winner, pay out)"
|
|
87
|
+
echo " 3. Reset for new round"
|
|
88
|
+
echo ""
|
|
89
|
+
echo "If the keeper bot is running, wait ~10 seconds."
|
|
90
|
+
echo "If not, start it with:"
|
|
91
|
+
echo " node scripts/jackpot-keeper.js"
|
|
92
|
+
elif [ "$STATUS" = "Open" ]; then
|
|
93
|
+
echo -e "${GREEN}✅ Round is Open (not locked)${NC}"
|
|
94
|
+
echo ""
|
|
95
|
+
echo "Everything looks good! Players can enter."
|
|
96
|
+
elif [ "$STATUS" = "Resolved" ]; then
|
|
97
|
+
echo -e "${GREEN}✅ Round is Resolved${NC}"
|
|
98
|
+
echo ""
|
|
99
|
+
echo "Keeper bot should reset it soon to start a new round."
|
|
100
|
+
else
|
|
101
|
+
echo -e "${YELLOW}⚠️ Unknown status: $STATUS${NC}"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
echo ""
|
|
105
|
+
echo "4️⃣ Summary"
|
|
106
|
+
echo "==========="
|
|
107
|
+
echo ""
|
|
108
|
+
echo "Your jackpot system architecture (from COMPREHENSIVE_DESIGN.md):"
|
|
109
|
+
echo ""
|
|
110
|
+
echo " Round Lifecycle:"
|
|
111
|
+
echo " 1. OPEN → Players enter → Timer expires"
|
|
112
|
+
echo " 2. LOCK → Keeper commits server seed hash"
|
|
113
|
+
echo " 3. REVEAL → Oracle reveals random seed"
|
|
114
|
+
echo " 4. RESOLVE → Winner selected & paid"
|
|
115
|
+
echo " 5. RESET → New round starts"
|
|
116
|
+
echo ""
|
|
117
|
+
echo "If stuck at step 2 (LOCKED), you need:"
|
|
118
|
+
echo " • API server running (port 3001)"
|
|
119
|
+
echo " • Keeper bot running (jackpot-keeper.js)"
|
|
120
|
+
echo " • Oracle wallet configured (wallets/jackpot_oracle.json)"
|
|
121
|
+
echo ""
|
|
122
|
+
echo "✅ Quick Fix: Just run the keeper bot!"
|
|
123
|
+
echo " cd /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server"
|
|
124
|
+
echo " node scripts/jackpot-keeper.js"
|
|
125
|
+
echo ""
|
|
126
|
+
|