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.
Files changed (304) hide show
  1. package/.claude/settings.local.json +280 -0
  2. package/CLAUDE.md +46 -0
  3. package/CONNECT4_PRODUCTION_DEPLOY.md +155 -0
  4. package/CURRENT_SESSION.md +171 -0
  5. package/CURRENT_SESSION_DRAW.md +516 -0
  6. package/MARCH_MADNESS_SURVIVOR.md +254 -0
  7. package/PANDA.md +166 -0
  8. package/Procfile +4 -0
  9. package/README.md +476 -0
  10. package/controllers/livescoresController.js +376 -0
  11. package/controllers/pickemController.js +554 -0
  12. package/controllers/survivorAdminController.js +887 -0
  13. package/controllers/survivorController.js +623 -0
  14. package/cron/oracleMonitor.js +77 -0
  15. package/cron/pickemOracleMonitor.js +73 -0
  16. package/data/jackpot-history.json +952 -0
  17. package/data/ncaaTeams.js +406 -0
  18. package/documentation/API_SECURITY_GUIDE.md +327 -0
  19. package/documentation/ARCADE_API.md +593 -0
  20. package/documentation/ARCADE_IMPLEMENTATION_SUMMARY.md +399 -0
  21. package/documentation/ARCADE_QUICKSTART.md +242 -0
  22. package/documentation/AUTOMATIC_MODE_ORACLE.md +321 -0
  23. package/documentation/BUG_FIX_COHORT_DATE_DISPLAY.md +171 -0
  24. package/documentation/CLAIM_MIGRATION_INSTRUCTIONS.md +52 -0
  25. package/documentation/CLAIM_STATUS_FIX.md +67 -0
  26. package/documentation/CLI_TOOL_GUIDE.md +372 -0
  27. package/documentation/COHORT_RETENTION_ANALYSIS.md +295 -0
  28. package/documentation/COHORT_RETENTION_IMPLEMENTATION_COMPLETE.md +461 -0
  29. package/documentation/COHORT_RETENTION_SUMMARY.md +204 -0
  30. package/documentation/COMPLETE_PROJECT_SUMMARY.md +490 -0
  31. package/documentation/DATABASE_QUERIES.md +269 -0
  32. package/documentation/DATABASE_RETENTION_POLICY.md +390 -0
  33. package/documentation/DATABASE_SETUP_GUIDE.md +361 -0
  34. package/documentation/DATABASE_SETUP_SUMMARY.md +247 -0
  35. package/documentation/DEMO_API_CURL_COMMANDS.md +656 -0
  36. package/documentation/DEPLOYMENT_SUMMARY.txt +100 -0
  37. package/documentation/DUPLICATE_NOTIFICATIONS_FIXED.md +201 -0
  38. package/documentation/EXCHANGE_RATES_INTEGRATION.md +371 -0
  39. package/documentation/FINAL_API_PROTECTION_TABLE.md +175 -0
  40. package/documentation/GAME_START_NOTIFICATIONS_DEPLOYMENT.md +256 -0
  41. package/documentation/GAME_START_NOTIFICATIONS_INTEGRATION.md +275 -0
  42. package/documentation/HEROKU_DEPLOYMENT.md +134 -0
  43. package/documentation/HEROKU_SCHEDULER_SETUP.md +271 -0
  44. package/documentation/JACKPOT_API.md +521 -0
  45. package/documentation/JACKPOT_DEPLOYMENT_GUIDE.md +362 -0
  46. package/documentation/JWT_IMPLEMENTATION_SUMMARY.md +373 -0
  47. package/documentation/JWT_QUICK_SETUP.md +268 -0
  48. package/documentation/JWT_TESTING_GUIDE.md +404 -0
  49. package/documentation/KEEPER_RECOVERY_GUIDE.md +381 -0
  50. package/documentation/KEEPER_SETUP.md +206 -0
  51. package/documentation/KEEPER_STATE_MACHINE.md +423 -0
  52. package/documentation/LATEST_PRODUCTION_SETUP.md +387 -0
  53. package/documentation/LOCAL_VOTING_TEST.md +279 -0
  54. package/documentation/ORACLE_FIXES_SUMMARY.md +188 -0
  55. package/documentation/ORACLE_POSTGRESQL_UPDATE.md +202 -0
  56. package/documentation/PAYMENT_DEPLOYMENT.md +209 -0
  57. package/documentation/PNL_TRACKING_SETUP.md +189 -0
  58. package/documentation/PREVENTING_LOCKUP_ERRORS.md +472 -0
  59. package/documentation/PRODUCTION_READY_SUMMARY.md +227 -0
  60. package/documentation/PUBLIC_VS_PRIVATE_ENDPOINTS.md +278 -0
  61. package/documentation/QUICK_AUTH_SETUP.md +99 -0
  62. package/documentation/QUICK_DEPLOY.md +224 -0
  63. package/documentation/QUICK_FIX.md +114 -0
  64. package/documentation/QUICK_START.md +152 -0
  65. package/documentation/REFEREE_MODE_GUIDE.md +392 -0
  66. package/documentation/RETENTION_CORE_ACTION_UPDATE.md +313 -0
  67. package/documentation/RETENTION_UPDATE_SUMMARY.md +108 -0
  68. package/documentation/RUN_MIGRATION_NOW.md +39 -0
  69. package/documentation/SCRIPTS_UPDATE_SUMMARY.md +251 -0
  70. package/documentation/SETUP_GUIDE.md +184 -0
  71. package/documentation/STATE_MACHINE_IMPLEMENTATION.md +250 -0
  72. package/documentation/TELEGRAM_NOTIFICATIONS_DIAGNOSIS.md +361 -0
  73. package/documentation/UNIFIED_ARCHITECTURE.md +231 -0
  74. package/documentation/VOTING_DEPLOYMENT_SUMMARY.md +392 -0
  75. package/documentation/WEBSOCKET_ARCHITECTURE.md +881 -0
  76. package/documentation/WHAT_WE_BUILT_TODAY.md +369 -0
  77. package/documentation/latest/LATEST_PRODUCTION_SETUP.md +865 -0
  78. package/ecosystem.config.js +65 -0
  79. package/env.template +125 -0
  80. package/middleware/apiKeyAuth.js +136 -0
  81. package/middleware/authenticate.js +214 -0
  82. package/middleware/developerUserAuth.js +76 -0
  83. package/middleware/socketAuth.js +69 -0
  84. package/package.json +49 -0
  85. package/postman/Dubs-API-v1-With-Voting.postman_collection.json +555 -0
  86. package/postman/Dubs-API-v1.postman_collection.json +205 -0
  87. package/postman/Dubs_Developer_API.postman_collection.json +662 -0
  88. package/postman/QUICKSTART.md +118 -0
  89. package/postman/QUICK_REFERENCE.md +246 -0
  90. package/postman/README.md +71 -0
  91. package/postman/VOTING_API_GUIDE.md +426 -0
  92. package/refactor/Animations.md +148 -0
  93. package/refactor/Chat.md +252 -0
  94. package/routes/actionsRoutes.js +699 -0
  95. package/routes/adminRoutes.js +370 -0
  96. package/routes/analyticsRoutes.js +1262 -0
  97. package/routes/arcadeRoutes.js +557 -0
  98. package/routes/authRoutes.js +2310 -0
  99. package/routes/avatarRoutes.js +85 -0
  100. package/routes/botRoutes.js +211 -0
  101. package/routes/chatRoutes.js +377 -0
  102. package/routes/cryptoPriceRoutes.js +105 -0
  103. package/routes/developerRoutes.js +4201 -0
  104. package/routes/deviceRoutes.js +214 -0
  105. package/routes/dmRoutes.js +167 -0
  106. package/routes/esportsRoutes.js +806 -0
  107. package/routes/exchangeRateRoutes.js +233 -0
  108. package/routes/gamesRoutes.js +3028 -0
  109. package/routes/jackpotRoutes.js +754 -0
  110. package/routes/keeperMonitoringRoutes.js +156 -0
  111. package/routes/keeperWebhookRoutes.js +466 -0
  112. package/routes/livescoresRoutes.js +31 -0
  113. package/routes/pickemAdminRoutes.js +199 -0
  114. package/routes/pickemRoutes.js +231 -0
  115. package/routes/playerStatsRoutes.js +147 -0
  116. package/routes/portfolioRoutes.js +217 -0
  117. package/routes/promoRoutes.js +418 -0
  118. package/routes/referralEarningsRoutes.js +392 -0
  119. package/routes/socialRoutes.js +459 -0
  120. package/routes/sportsRoutes.js +1271 -0
  121. package/routes/survivorAdminRoutes.js +345 -0
  122. package/routes/survivorRoutes.js +756 -0
  123. package/routes/uploadRoutes.js +256 -0
  124. package/routes/userProfileRoutes.js +244 -0
  125. package/routes/whatsNewRoutes.js +331 -0
  126. package/scripts/.claude/settings.local.json +15 -0
  127. package/scripts/README.md +170 -0
  128. package/scripts/RESTART_EVERYTHING.sh +104 -0
  129. package/scripts/add-claim-columns.sql +48 -0
  130. package/scripts/add-crypto-prices-cache.sql +27 -0
  131. package/scripts/add-exchange-rates-cache.sql +40 -0
  132. package/scripts/add-game-invite-column.sql +23 -0
  133. package/scripts/add-game-invite-notification.sql +33 -0
  134. package/scripts/add-game-invite-telegram-pref.sql +16 -0
  135. package/scripts/add-game-joined-notification.sql +16 -0
  136. package/scripts/add-game-joined-pref.js +40 -0
  137. package/scripts/add-game-joined-preference.sql +6 -0
  138. package/scripts/add-game-start-notifications.sql +41 -0
  139. package/scripts/add-notification-flags-to-games.sql +55 -0
  140. package/scripts/add-pending-game-dismissals.sql +19 -0
  141. package/scripts/add-preferred-currency.sql +34 -0
  142. package/scripts/add-winner-columns.js +61 -0
  143. package/scripts/add_mention_system.sql +53 -0
  144. package/scripts/add_payment_system.sql +96 -0
  145. package/scripts/add_sports_event_id_column.sql +22 -0
  146. package/scripts/analyze-cohort-data-heroku.js +276 -0
  147. package/scripts/analyze-cohort-data.js +295 -0
  148. package/scripts/analyze-prod-cohorts.sh +10 -0
  149. package/scripts/backfill-matchup-images.js +245 -0
  150. package/scripts/backfill-missing-signatures.js +175 -0
  151. package/scripts/backfill-referral-earnings.js +202 -0
  152. package/scripts/check-chat-schema.js +130 -0
  153. package/scripts/check-db.sh +14 -0
  154. package/scripts/check_oracle_in_game.js +54 -0
  155. package/scripts/cleanup-database.js +193 -0
  156. package/scripts/clear-notification-cache.js +85 -0
  157. package/scripts/convert-mnemonic.js +50 -0
  158. package/scripts/create-users-table.sql +44 -0
  159. package/scripts/debug-cohort-counts.js +248 -0
  160. package/scripts/debug-winner-calc.js +84 -0
  161. package/scripts/deploy-payment-system.sh +118 -0
  162. package/scripts/deploy-to-heroku.sh +63 -0
  163. package/scripts/diagnose-locked-round.js +143 -0
  164. package/scripts/dubs-cli.js +720 -0
  165. package/scripts/dump-account.js +65 -0
  166. package/scripts/find-vrf-offset.js +48 -0
  167. package/scripts/fix-chat-notifications-constraint.sql +122 -0
  168. package/scripts/fix-claim-columns.js +124 -0
  169. package/scripts/fix-constraint-now.js +44 -0
  170. package/scripts/fix-lock-timestamps.js +96 -0
  171. package/scripts/fix-locked-round.sh +126 -0
  172. package/scripts/fix-missing-badges.sql +91 -0
  173. package/scripts/fix-payment-notifications.sql +41 -0
  174. package/scripts/force-new-round.js +55 -0
  175. package/scripts/force-resolve-and-claim.js +278 -0
  176. package/scripts/important/README.md +115 -0
  177. package/scripts/important/authority-force-lock.js +197 -0
  178. package/scripts/important/authority-resolve-game.js +267 -0
  179. package/scripts/important/check-game-status.js +373 -0
  180. package/scripts/important/list-pending-games-by-version.js +270 -0
  181. package/scripts/important/reconcile-v1-v2-payouts.js +270 -0
  182. package/scripts/initialize-jackpot.js +111 -0
  183. package/scripts/jackpot/.claude/settings.local.json +10 -0
  184. package/scripts/jackpot/force-reset.js +84 -0
  185. package/scripts/jackpot/initialize-mainnet.js +100 -0
  186. package/scripts/jackpot/keeper.js +742 -0
  187. package/scripts/jackpot/status.js +107 -0
  188. package/scripts/jackpot/update-round-duration.js +143 -0
  189. package/scripts/keeper-bot.js +112 -0
  190. package/scripts/list-pending-games.js +131 -0
  191. package/scripts/migrate-chat-v2.js +127 -0
  192. package/scripts/migrate-chat-winners.js +84 -0
  193. package/scripts/migrate-chat.sh +17 -0
  194. package/scripts/migrate-game-invite.js +83 -0
  195. package/scripts/migrate-heroku-game-notifications.sh +159 -0
  196. package/scripts/migrations/001_analytics_tables.sql +422 -0
  197. package/scripts/migrations/002_add_matchup_image_url.sql +14 -0
  198. package/scripts/migrations/003_referral_earnings.sql +208 -0
  199. package/scripts/migrations/004_add_whats_new_notification_type.sql +62 -0
  200. package/scripts/migrations/005_add_connect4_your_turn_notification.sql +61 -0
  201. package/scripts/migrations/005_push_notifications.sql +55 -0
  202. package/scripts/migrations/006_add_draw_team_players.sql +28 -0
  203. package/scripts/migrations/006_add_game_cancelled_notification.sql +62 -0
  204. package/scripts/migrations/007_add_gif_url.sql +8 -0
  205. package/scripts/migrations/008_add_connect4_columns.sql +139 -0
  206. package/scripts/migrations/008_add_pool_tracking.sql +22 -0
  207. package/scripts/migrations/009_create_survivor_pool_tables.sql +174 -0
  208. package/scripts/migrations/010_add_survivor_pool_outcome.sql +28 -0
  209. package/scripts/migrations/011_create_developer_tables.sql +67 -0
  210. package/scripts/migrations/011_fix_keeper_tables.sql +85 -0
  211. package/scripts/migrations/012_create_developer_webhooks.sql +31 -0
  212. package/scripts/migrations/013_add_network_mode.sql +18 -0
  213. package/scripts/migrations/014_create_developer_app_users.sql +19 -0
  214. package/scripts/migrations/015_add_ui_config.sql +4 -0
  215. package/scripts/migrations/016_add_resolution_secret.sql +4 -0
  216. package/scripts/migrations/017_add_external_game_id.sql +3 -0
  217. package/scripts/migrations/018_create_pickem_tables.sql +115 -0
  218. package/scripts/migrations/019_expo_push_tokens.sql +19 -0
  219. package/scripts/migrations/create_whats_new_tables.sql +88 -0
  220. package/scripts/migrations/drop_live_games_tables.sql +34 -0
  221. package/scripts/open-jackpot-round.js +85 -0
  222. package/scripts/purge-all-data.sh +329 -0
  223. package/scripts/purge-all-data.sql +142 -0
  224. package/scripts/purge-heroku-data.sh +149 -0
  225. package/scripts/purge-heroku-data.sql +62 -0
  226. package/scripts/rebuild-heroku-database.sh +113 -0
  227. package/scripts/recover-funds.js +357 -0
  228. package/scripts/regenerate-epl-images.js +278 -0
  229. package/scripts/resize-s3-matchup-images.js +374 -0
  230. package/scripts/resolve-direct.js +88 -0
  231. package/scripts/resolve-mock-game.js +124 -0
  232. package/scripts/resolve-pickem-game.js +55 -0
  233. package/scripts/resolve-round-manual.js +83 -0
  234. package/scripts/resolve-stuck-game.js +382 -0
  235. package/scripts/resolve-stuck-round.js +42 -0
  236. package/scripts/run-connect4-migration.sh +16 -0
  237. package/scripts/run-mention-migration.sh +32 -0
  238. package/scripts/run-payment-migration.sh +51 -0
  239. package/scripts/run-preferred-currency-migration.sh +31 -0
  240. package/scripts/run-referral-earnings-migration.sh +32 -0
  241. package/scripts/run-survivor-outcome-migration.sh +16 -0
  242. package/scripts/seed-test-users.js +346 -0
  243. package/scripts/setup-auth-tables.js +78 -0
  244. package/scripts/setup-complete-database.sql +992 -0
  245. package/scripts/setup-database-fresh.sh +359 -0
  246. package/scripts/setup-heroku-keeper.sh +48 -0
  247. package/scripts/setup-keeper-database.js +83 -0
  248. package/scripts/setup-keeper-state-db.sql +110 -0
  249. package/scripts/setup-oracle.sh +39 -0
  250. package/scripts/setup-pnl-tracking.js +111 -0
  251. package/scripts/start-devnet.sh +14 -0
  252. package/scripts/test-arcade-devnet.sh +160 -0
  253. package/scripts/test-arcade-match.sh +109 -0
  254. package/scripts/test-automatic-mode.sh +239 -0
  255. package/scripts/test-connect4-cancel-claim.js +370 -0
  256. package/scripts/test-connect4-e2e.js +369 -0
  257. package/scripts/test-connect4-resolve.js +369 -0
  258. package/scripts/test-game-state-endpoint.js +136 -0
  259. package/scripts/test-invite-notification.js +86 -0
  260. package/scripts/test-jackpot-api.sh +71 -0
  261. package/scripts/test-poll-confirmation.js +267 -0
  262. package/scripts/test-resolve-game.js +271 -0
  263. package/scripts/test-resolve-signature.js +223 -0
  264. package/scripts/test-signature-preservation.js +124 -0
  265. package/scripts/test-state-machine.js +291 -0
  266. package/scripts/test-webhook-receiver.js +60 -0
  267. package/scripts/update-notification-constraint.js +52 -0
  268. package/scripts/verify-account-layout.js +145 -0
  269. package/scripts/verify-winner-algorithm.js +278 -0
  270. package/server.js +5259 -0
  271. package/services/arcadeMatchService.js +763 -0
  272. package/services/automaticGameOracle.js +1596 -0
  273. package/services/chatService.js +1612 -0
  274. package/services/connect4GameService.js +1049 -0
  275. package/services/connect4NotificationService.js +374 -0
  276. package/services/cryptoPriceService.js +223 -0
  277. package/services/customGameResolver.js +260 -0
  278. package/services/db.js +79 -0
  279. package/services/directMessageService.js +389 -0
  280. package/services/discordNotifications.js +160 -0
  281. package/services/exchangeRateService.js +289 -0
  282. package/services/expoPushService.js +314 -0
  283. package/services/gamesCacheService.js +539 -0
  284. package/services/jackpotHistory.js +331 -0
  285. package/services/jackpotService.js +856 -0
  286. package/services/keeperStateService.js +355 -0
  287. package/services/matchupImageService.js +591 -0
  288. package/services/notificationCacheService.js +407 -0
  289. package/services/pickemOracle.js +440 -0
  290. package/services/playerStatsService.js +389 -0
  291. package/services/portfolioService.js +555 -0
  292. package/services/promoService.js +757 -0
  293. package/services/promoTreasuryService.js +239 -0
  294. package/services/pushNotifications.js +353 -0
  295. package/services/redisService.js +422 -0
  296. package/services/referralEarningsService.js +728 -0
  297. package/services/s3Service.js +396 -0
  298. package/services/socialService.js +1202 -0
  299. package/services/survivorOracle.js +469 -0
  300. package/services/survivorSimulator.js +475 -0
  301. package/services/telegramNotifications.js +461 -0
  302. package/services/userProfileStatsService.js +1185 -0
  303. package/services/whatsNewService.js +388 -0
  304. package/utils/urlHelper.js +95 -0
@@ -0,0 +1,111 @@
1
+ /**
2
+ * 🔥 Complete PNL Tracking Setup
3
+ *
4
+ * Sets up ALL tables needed for PNL tracking and winner announcements
5
+ * Run with: heroku run node scripts/setup-pnl-tracking.js --app YOUR_APP_NAME
6
+ */
7
+
8
+ const { Pool } = require('pg');
9
+
10
+ async function setup() {
11
+ const pool = new Pool({
12
+ connectionString: process.env.DATABASE_URL,
13
+ ssl: process.env.DATABASE_URL ? { rejectUnauthorized: false } : false,
14
+ });
15
+
16
+ try {
17
+ console.log('🚀 Starting PNL tracking setup...\n');
18
+
19
+ // ============ STEP 1: Add winner announcement columns to chat ============
20
+ console.log('📝 Step 1: Adding winner announcement columns to chat_messages...');
21
+ await pool.query(`
22
+ ALTER TABLE chat_messages
23
+ ADD COLUMN IF NOT EXISTS is_winner_announcement BOOLEAN DEFAULT FALSE,
24
+ ADD COLUMN IF NOT EXISTS win_amount NUMERIC(20, 9),
25
+ ADD COLUMN IF NOT EXISTS round_id INTEGER;
26
+ `);
27
+ await pool.query(`
28
+ CREATE INDEX IF NOT EXISTS idx_chat_winner ON chat_messages(is_winner_announcement);
29
+ `);
30
+ console.log(' ✅ Chat winner columns added!');
31
+
32
+ // ============ STEP 2: Create player stats table ============
33
+ console.log('\n📝 Step 2: Creating player_stats table...');
34
+ await pool.query(`
35
+ CREATE TABLE IF NOT EXISTS player_stats (
36
+ wallet_address VARCHAR(100) PRIMARY KEY,
37
+ total_wagered NUMERIC(20, 9) DEFAULT 0,
38
+ total_won NUMERIC(20, 9) DEFAULT 0,
39
+ net_pnl NUMERIC(20, 9) DEFAULT 0,
40
+ rounds_played INTEGER DEFAULT 0,
41
+ rounds_won INTEGER DEFAULT 0,
42
+ biggest_win NUMERIC(20, 9) DEFAULT 0,
43
+ biggest_win_round INTEGER,
44
+ last_played TIMESTAMP,
45
+ created_at TIMESTAMP DEFAULT NOW()
46
+ );
47
+
48
+ CREATE INDEX IF NOT EXISTS idx_player_stats_pnl ON player_stats(net_pnl DESC);
49
+ CREATE INDEX IF NOT EXISTS idx_player_stats_wagered ON player_stats(total_wagered DESC);
50
+ `);
51
+ console.log(' ✅ Player stats table created!');
52
+
53
+ // ============ STEP 3: Create player history table ============
54
+ console.log('\n📝 Step 3: Creating player_history table...');
55
+ await pool.query(`
56
+ CREATE TABLE IF NOT EXISTS player_history (
57
+ id SERIAL PRIMARY KEY,
58
+ wallet_address VARCHAR(100) NOT NULL,
59
+ round_id INTEGER NOT NULL,
60
+ action VARCHAR(20) NOT NULL,
61
+ amount NUMERIC(20, 9) NOT NULL,
62
+ cumulative_pnl NUMERIC(20, 9) NOT NULL,
63
+ timestamp TIMESTAMP DEFAULT NOW()
64
+ );
65
+
66
+ CREATE INDEX IF NOT EXISTS idx_player_history_wallet ON player_history(wallet_address, timestamp DESC);
67
+ CREATE INDEX IF NOT EXISTS idx_player_history_round ON player_history(round_id);
68
+ `);
69
+ console.log(' ✅ Player history table created!');
70
+
71
+ // ============ VERIFY ============
72
+ console.log('\n🔍 Verifying setup...');
73
+
74
+ const chatCols = await pool.query(`
75
+ SELECT column_name FROM information_schema.columns
76
+ WHERE table_name = 'chat_messages'
77
+ AND column_name IN ('is_winner_announcement', 'win_amount', 'round_id');
78
+ `);
79
+ console.log(` Chat columns: ${chatCols.rows.length}/3 added`);
80
+
81
+ const tables = await pool.query(`
82
+ SELECT table_name FROM information_schema.tables
83
+ WHERE table_name IN ('player_stats', 'player_history');
84
+ `);
85
+ console.log(` Player tables: ${tables.rows.length}/2 created`);
86
+
87
+ // Count existing data
88
+ const statsCount = await pool.query('SELECT COUNT(*) FROM player_stats');
89
+ const historyCount = await pool.query('SELECT COUNT(*) FROM player_history');
90
+ console.log(` Current player_stats records: ${statsCount.rows[0].count}`);
91
+ console.log(` Current player_history records: ${historyCount.rows[0].count}`);
92
+
93
+ console.log('\n🎉 PNL TRACKING SETUP COMPLETE!');
94
+ console.log('\n📊 What you can now do:');
95
+ console.log(' ✅ Track all player entries and wins automatically');
96
+ console.log(' ✅ Show epic winner announcements in chat with lasers!');
97
+ console.log(' ✅ View player PNL with beautiful animated charts');
98
+ console.log(' ✅ Click any username to see their stats');
99
+ console.log('\n🔥 Next: Restart your server and start playing!');
100
+
101
+ await pool.end();
102
+ } catch (error) {
103
+ console.error('❌ Setup failed:', error.message);
104
+ console.error(error);
105
+ await pool.end();
106
+ process.exit(1);
107
+ }
108
+ }
109
+
110
+ setup();
111
+
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ echo "🚀 Starting Dubs API on DEVNET..."
4
+ echo ""
5
+
6
+ export SOLANA_NETWORK=https://api.devnet.solana.com
7
+ export PROGRAM_ID=8DJTkgk6MDr6tPtw4v2VzYAz9WWvmCg6786vZrEK3o5q
8
+
9
+ echo "Network: $SOLANA_NETWORK"
10
+ echo "Program: $PROGRAM_ID"
11
+ echo ""
12
+
13
+ node server.js
14
+
@@ -0,0 +1,160 @@
1
+ #!/bin/bash
2
+
3
+ # 🎮 Arcade Match Test - DEVNET VERSION
4
+ # Tests complete match lifecycle on Solana devnet
5
+
6
+ # Colors for output
7
+ GREEN='\033[0;32m'
8
+ BLUE='\033[0;34m'
9
+ YELLOW='\033[1;33m'
10
+ RED='\033[0;31m'
11
+ NC='\033[0m' # No Color
12
+
13
+ # Configuration
14
+ API_URL="${ARCADE_API_URL:-http://localhost:3001}"
15
+ PLAYER1="alice_devnet"
16
+ PLAYER2="bob_devnet"
17
+ STAKE=100000000 # 0.1 SOL in lamports
18
+
19
+ echo -e "${BLUE}🎮 Arcade Match Test - DEVNET${NC}"
20
+ echo -e "${BLUE}================================${NC}\n"
21
+
22
+ # Step 1: Check server health
23
+ echo -e "${YELLOW}Step 1: Checking server health...${NC}"
24
+ HEALTH=$(curl -s "$API_URL/arcade/health")
25
+ echo "$HEALTH" | json_pp
26
+
27
+ # Check if server is on devnet
28
+ if echo "$HEALTH" | grep -q "devnet"; then
29
+ echo -e "${GREEN}✅ Connected to devnet${NC}\n"
30
+ else
31
+ echo -e "${YELLOW}⚠️ Server might not be on devnet. Check RPC URL.${NC}\n"
32
+ fi
33
+
34
+ # Step 2: Get devnet SOL
35
+ echo -e "${YELLOW}Step 2: Getting devnet SOL...${NC}"
36
+ echo -e "${BLUE}Note: Devnet airdrops might fail if rate-limited. You may need to:${NC}"
37
+ echo -e "${BLUE} 1. Use https://faucet.solana.com${NC}"
38
+ echo -e "${BLUE} 2. Or wait and retry${NC}\n"
39
+
40
+ # Get wallet addresses
41
+ ALICE_WALLET=$(curl -s "$API_URL/arcade/wallet/$PLAYER1/balance" | grep -o '"pubkey":"[^"]*"' | cut -d'"' -f4)
42
+ BOB_WALLET=$(curl -s "$API_URL/arcade/wallet/$PLAYER2/balance" | grep -o '"pubkey":"[^"]*"' | cut -d'"' -f4)
43
+
44
+ echo "Alice wallet: $ALICE_WALLET"
45
+ echo "Bob wallet: $BOB_WALLET"
46
+ echo ""
47
+
48
+ # Attempt airdrops (these may fail on devnet due to rate limits)
49
+ echo "Attempting airdrop to $PLAYER1..."
50
+ curl -s -X POST "$API_URL/arcade/wallet/airdrop" \
51
+ -H "Content-Type: application/json" \
52
+ -d "{\"playerName\": \"$PLAYER1\", \"amount\": 2}" | json_pp || echo -e "${RED}Airdrop failed - use faucet${NC}"
53
+ echo ""
54
+
55
+ echo "Attempting airdrop to $PLAYER2..."
56
+ curl -s -X POST "$API_URL/arcade/wallet/airdrop" \
57
+ -H "Content-Type: application/json" \
58
+ -d "{\"playerName\": \"$PLAYER2\", \"amount\": 2}" | json_pp || echo -e "${RED}Airdrop failed - use faucet${NC}"
59
+ echo ""
60
+
61
+ # Check balances
62
+ echo -e "${YELLOW}Checking balances...${NC}"
63
+ ALICE_BAL=$(curl -s "$API_URL/arcade/wallet/$PLAYER1/balance")
64
+ BOB_BAL=$(curl -s "$API_URL/arcade/wallet/$PLAYER2/balance")
65
+
66
+ echo "Alice balance:"
67
+ echo "$ALICE_BAL" | json_pp
68
+ echo ""
69
+
70
+ echo "Bob balance:"
71
+ echo "$BOB_BAL" | json_pp
72
+ echo ""
73
+
74
+ # Check if we have enough SOL
75
+ ALICE_LAMPORTS=$(echo "$ALICE_BAL" | grep -o '"lamports":[0-9]*' | cut -d':' -f2)
76
+ BOB_LAMPORTS=$(echo "$BOB_BAL" | grep -o '"lamports":[0-9]*' | cut -d':' -f2)
77
+
78
+ if [ "$ALICE_LAMPORTS" -lt "$STAKE" ] || [ "$BOB_LAMPORTS" -lt "$STAKE" ]; then
79
+ echo -e "${RED}❌ Insufficient balance for testing!${NC}"
80
+ echo -e "${YELLOW}Please fund wallets using:${NC}"
81
+ echo -e " https://faucet.solana.com"
82
+ echo -e " Alice: $ALICE_WALLET"
83
+ echo -e " Bob: $BOB_WALLET"
84
+ exit 1
85
+ fi
86
+
87
+ echo -e "${GREEN}✅ Wallets funded!${NC}\n"
88
+
89
+ # Step 3: Create match
90
+ echo -e "${YELLOW}Step 3: Creating match...${NC}"
91
+ CREATE_RESPONSE=$(curl -s -X POST "$API_URL/arcade/matches/create" \
92
+ -H "Content-Type: application/json" \
93
+ -d "{
94
+ \"creatorName\": \"$PLAYER1\",
95
+ \"stake\": $STAKE,
96
+ \"gameType\": \"asteroids\",
97
+ \"matchType\": \"bestOf1\",
98
+ \"deadlineMinutes\": 60
99
+ }")
100
+
101
+ echo "$CREATE_RESPONSE" | json_pp
102
+ MATCH_ID=$(echo "$CREATE_RESPONSE" | grep -o '"matchId":"[^"]*"' | cut -d'"' -f4)
103
+ echo -e "${GREEN}Match ID: $MATCH_ID${NC}\n"
104
+
105
+ if [ -z "$MATCH_ID" ]; then
106
+ echo -e "${RED}⚠️ Failed to create match. Check server logs.${NC}"
107
+ exit 1
108
+ fi
109
+
110
+ # Step 4: Join match
111
+ echo -e "${YELLOW}Step 4: $PLAYER2 joining match...${NC}"
112
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/join" \
113
+ -H "Content-Type: application/json" \
114
+ -d "{\"opponentName\": \"$PLAYER2\"}" | json_pp
115
+ echo ""
116
+
117
+ # Step 5: Submit scores
118
+ echo -e "${YELLOW}Step 5: Submitting scores...${NC}"
119
+ echo "$PLAYER1 score: 15000"
120
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/score" \
121
+ -H "Content-Type: application/json" \
122
+ -d "{
123
+ \"playerName\": \"$PLAYER1\",
124
+ \"score\": 15000,
125
+ \"gameRound\": 1
126
+ }" | json_pp
127
+ echo ""
128
+
129
+ echo "$PLAYER2 score: 12000"
130
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/score" \
131
+ -H "Content-Type: application/json" \
132
+ -d "{
133
+ \"playerName\": \"$PLAYER2\",
134
+ \"score\": 12000,
135
+ \"gameRound\": 1
136
+ }" | json_pp
137
+ echo ""
138
+
139
+ # Step 6: Resolve match
140
+ echo -e "${YELLOW}Step 6: Resolving match...${NC}"
141
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/resolve" \
142
+ -H "Content-Type: application/json" \
143
+ -d "{\"callerName\": \"$PLAYER1\"}" | json_pp
144
+ echo ""
145
+
146
+ # Step 7: Check final balances
147
+ echo -e "${YELLOW}Step 7: Final balances${NC}"
148
+ echo "$PLAYER1 balance:"
149
+ curl -s "$API_URL/arcade/wallet/$PLAYER1/balance" | json_pp
150
+ echo ""
151
+
152
+ echo "$PLAYER2 balance:"
153
+ curl -s "$API_URL/arcade/wallet/$PLAYER2/balance" | json_pp
154
+ echo ""
155
+
156
+ echo -e "${GREEN}✅ Test completed on DEVNET!${NC}"
157
+ echo -e "${GREEN}$PLAYER1 should have won and received ~0.198 SOL (prize pool after 1% fee)${NC}"
158
+ echo -e "\n${BLUE}🔍 View transaction on Solana Explorer:${NC}"
159
+ echo -e "${BLUE}https://explorer.solana.com/address/$MATCH_ID?cluster=devnet${NC}"
160
+
@@ -0,0 +1,109 @@
1
+ #!/bin/bash
2
+
3
+ # 🎮 Arcade Match Test Script
4
+ # Tests complete match lifecycle
5
+
6
+ # Colors for output
7
+ GREEN='\033[0;32m'
8
+ BLUE='\033[0;34m'
9
+ YELLOW='\033[1;33m'
10
+ NC='\033[0m' # No Color
11
+
12
+ # Configuration
13
+ API_URL="${ARCADE_API_URL:-http://localhost:3001}"
14
+ PLAYER1="alice"
15
+ PLAYER2="bob"
16
+ STAKE=100000000 # 0.1 SOL in lamports
17
+
18
+ echo -e "${BLUE}🎮 Arcade Match Test${NC}"
19
+ echo -e "${BLUE}===================${NC}\n"
20
+
21
+ # Step 1: Check server health
22
+ echo -e "${YELLOW}Step 1: Checking server health...${NC}"
23
+ curl -s "$API_URL/arcade/health" | json_pp
24
+ echo ""
25
+
26
+ # Step 2: Fund player wallets
27
+ echo -e "${YELLOW}Step 2: Funding wallets...${NC}"
28
+ echo "Airdropping 2 SOL to $PLAYER1..."
29
+ curl -s -X POST "$API_URL/arcade/wallet/airdrop" \
30
+ -H "Content-Type: application/json" \
31
+ -d "{\"playerName\": \"$PLAYER1\", \"amount\": 2}" | json_pp
32
+ echo ""
33
+
34
+ echo "Airdropping 2 SOL to $PLAYER2..."
35
+ curl -s -X POST "$API_URL/arcade/wallet/airdrop" \
36
+ -H "Content-Type: application/json" \
37
+ -d "{\"playerName\": \"$PLAYER2\", \"amount\": 2}" | json_pp
38
+ echo ""
39
+
40
+ # Step 3: Create match
41
+ echo -e "${YELLOW}Step 3: Creating match...${NC}"
42
+ CREATE_RESPONSE=$(curl -s -X POST "$API_URL/arcade/matches/create" \
43
+ -H "Content-Type: application/json" \
44
+ -d "{
45
+ \"creatorName\": \"$PLAYER1\",
46
+ \"stake\": $STAKE,
47
+ \"gameType\": \"asteroids\",
48
+ \"matchType\": \"bestOf1\",
49
+ \"deadlineMinutes\": 60
50
+ }")
51
+
52
+ echo "$CREATE_RESPONSE" | json_pp
53
+ MATCH_ID=$(echo "$CREATE_RESPONSE" | grep -o '"matchId":"[^"]*"' | cut -d'"' -f4)
54
+ echo -e "${GREEN}Match ID: $MATCH_ID${NC}\n"
55
+
56
+ if [ -z "$MATCH_ID" ]; then
57
+ echo -e "${YELLOW}⚠️ Failed to create match. Check if server is running on $API_URL${NC}"
58
+ exit 1
59
+ fi
60
+
61
+ # Step 4: Join match
62
+ echo -e "${YELLOW}Step 4: $PLAYER2 joining match...${NC}"
63
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/join" \
64
+ -H "Content-Type: application/json" \
65
+ -d "{\"opponentName\": \"$PLAYER2\"}" | json_pp
66
+ echo ""
67
+
68
+ # Step 5: Submit scores
69
+ echo -e "${YELLOW}Step 5: Submitting scores...${NC}"
70
+ echo "$PLAYER1 score: 15000"
71
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/score" \
72
+ -H "Content-Type: application/json" \
73
+ -d "{
74
+ \"playerName\": \"$PLAYER1\",
75
+ \"score\": 15000,
76
+ \"gameRound\": 1
77
+ }" | json_pp
78
+ echo ""
79
+
80
+ echo "$PLAYER2 score: 12000"
81
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/score" \
82
+ -H "Content-Type: application/json" \
83
+ -d "{
84
+ \"playerName\": \"$PLAYER2\",
85
+ \"score\": 12000,
86
+ \"gameRound\": 1
87
+ }" | json_pp
88
+ echo ""
89
+
90
+ # Step 6: Resolve match
91
+ echo -e "${YELLOW}Step 6: Resolving match...${NC}"
92
+ curl -s -X POST "$API_URL/arcade/matches/$MATCH_ID/resolve" \
93
+ -H "Content-Type: application/json" \
94
+ -d "{\"callerName\": \"$PLAYER1\"}" | json_pp
95
+ echo ""
96
+
97
+ # Step 7: Check final balances
98
+ echo -e "${YELLOW}Step 7: Final balances${NC}"
99
+ echo "$PLAYER1 balance:"
100
+ curl -s "$API_URL/arcade/wallet/$PLAYER1/balance" | json_pp
101
+ echo ""
102
+
103
+ echo "$PLAYER2 balance:"
104
+ curl -s "$API_URL/arcade/wallet/$PLAYER2/balance" | json_pp
105
+ echo ""
106
+
107
+ echo -e "${GREEN}✅ Test completed!${NC}"
108
+ echo -e "${GREEN}$PLAYER1 should have won and received ~0.198 SOL (prize pool after 1% fee)${NC}"
109
+
@@ -0,0 +1,239 @@
1
+ #!/bin/bash
2
+ # End-to-End Test for Automatic Sports Mode
3
+ # Tests the full flow from game creation to automatic resolution
4
+
5
+ set -e # Exit on error
6
+
7
+ API_URL="http://localhost:3001"
8
+ LIVE_SCORES_URL="http://localhost:3000"
9
+
10
+ echo "🎮 =================================="
11
+ echo " AUTOMATIC SPORTS MODE - E2E TEST"
12
+ echo " =================================="
13
+ echo ""
14
+
15
+ # Test wallets
16
+ CREATOR_WALLET="BVZXwZpfgyzTBdRFHohkHZppPHnAyqyctRsKy3vWfQib"
17
+ PLAYER_ADAM="5XhBYsVRTRs3oQwBLRCPTcB3dQfKLzqMqPCXJCHVXQPZ" # Picks Adam (Home)
18
+ PLAYER_AMY="9yVN8xPzQnPFbGbJcRY5s2M4ZzQqJz8KnXqE3tFvW9Kx" # Picks Amy (Away)
19
+
20
+ # Game will use mock data with pre-rigged score:
21
+ # Amy (away) beats Adam (home) 3-2
22
+ GAME_ID="test-amy-vs-adam-$(date +%s)"
23
+
24
+ echo "📋 Test Setup:"
25
+ echo " Game ID: $GAME_ID"
26
+ echo " Creator: $CREATOR_WALLET"
27
+ echo " Player (Team Adam): $PLAYER_ADAM"
28
+ echo " Player (Team Amy): $PLAYER_AMY"
29
+ echo ""
30
+ echo "🏀 Mock Event: Amy @ Adam"
31
+ echo " Final Score: Amy 3, Adam 2"
32
+ echo " Winner: Amy (Away Team)"
33
+ echo ""
34
+
35
+ # Step 1: Create Automatic Game
36
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
37
+ echo "STEP 1: Creating Automatic Sports Game"
38
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
39
+ echo ""
40
+
41
+ CREATE_RESPONSE=$(curl -s -X POST "$API_URL/api/auth/games/save" \
42
+ -H "Content-Type: application/json" \
43
+ -d "{
44
+ \"walletAddress\": \"$CREATOR_WALLET\",
45
+ \"gameId\": \"$GAME_ID\",
46
+ \"sharedGameData\": {
47
+ \"gameMode\": 4,
48
+ \"gameType\": \"sports\",
49
+ \"title\": \"Adam vs. Amy\",
50
+ \"buyIn\": 0.5,
51
+ \"createdBy\": \"$CREATOR_WALLET\",
52
+ \"sportsEvent\": {
53
+ \"idEvent\": \"mock-123456\",
54
+ \"strEvent\": \"Adam vs. Amy\",
55
+ \"strHomeTeam\": \"Adam\",
56
+ \"strAwayTeam\": \"Amy\",
57
+ \"strTimestamp\": \"2025-10-27T13:00:00\",
58
+ \"dateEvent\": \"2025-10-27\",
59
+ \"strLeague\": \"NBA\",
60
+ \"strHomeTeamBadge\": \"https://dubs-api-dev-f14bd1509129.herokuapp.com/images/adam.png\",
61
+ \"strAwayTeamBadge\": \"https://dubs-api-dev-f14bd1509129.herokuapp.com/images/amy.png\"
62
+ }
63
+ },
64
+ \"userGameRef\": {
65
+ \"role\": \"creator\",
66
+ \"status\": \"active\"
67
+ }
68
+ }")
69
+
70
+ echo "Response: $CREATE_RESPONSE"
71
+ echo ""
72
+
73
+ if echo "$CREATE_RESPONSE" | grep -q "success.*true"; then
74
+ echo "✅ Game created successfully!"
75
+ else
76
+ echo "❌ Failed to create game"
77
+ exit 1
78
+ fi
79
+
80
+ sleep 2
81
+
82
+ # Step 2: Player 1 Joins (Picks Adam - Home Team)
83
+ echo ""
84
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
85
+ echo "STEP 2: Player 1 Joins (Picks Team Adam - HOME)"
86
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
87
+ echo ""
88
+
89
+ JOIN1_RESPONSE=$(curl -s -X POST "$API_URL/api/auth/games/automatic/join" \
90
+ -H "Content-Type: application/json" \
91
+ -d "{
92
+ \"walletAddress\": \"$PLAYER_ADAM\",
93
+ \"gameId\": \"$GAME_ID\",
94
+ \"teamChoice\": \"home\"
95
+ }")
96
+
97
+ echo "Response: $JOIN1_RESPONSE"
98
+ echo ""
99
+
100
+ if echo "$JOIN1_RESPONSE" | grep -q "success.*true"; then
101
+ echo "✅ Player 1 joined Team Adam!"
102
+ else
103
+ echo "❌ Failed to join"
104
+ exit 1
105
+ fi
106
+
107
+ sleep 2
108
+
109
+ # Step 3: Player 2 Joins (Picks Amy - Away Team)
110
+ echo ""
111
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
112
+ echo "STEP 3: Player 2 Joins (Picks Team Amy - AWAY)"
113
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
114
+ echo ""
115
+
116
+ JOIN2_RESPONSE=$(curl -s -X POST "$API_URL/api/auth/games/automatic/join" \
117
+ -H "Content-Type: application/json" \
118
+ -d "{
119
+ \"walletAddress\": \"$PLAYER_AMY\",
120
+ \"gameId\": \"$GAME_ID\",
121
+ \"teamChoice\": \"away\"
122
+ }")
123
+
124
+ echo "Response: $JOIN2_RESPONSE"
125
+ echo ""
126
+
127
+ if echo "$JOIN2_RESPONSE" | grep -q "success.*true"; then
128
+ echo "✅ Player 2 joined Team Amy!"
129
+ else
130
+ echo "❌ Failed to join"
131
+ exit 1
132
+ fi
133
+
134
+ sleep 2
135
+
136
+ # Step 4: Check Game Status
137
+ echo ""
138
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
139
+ echo "STEP 4: Checking Game Status"
140
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
141
+ echo ""
142
+
143
+ GAME_STATUS=$(curl -s "$API_URL/api/auth/games/$GAME_ID/metadata")
144
+ echo "$GAME_STATUS" | jq '.' 2>/dev/null || echo "$GAME_STATUS"
145
+ echo ""
146
+ echo "📊 Game State:"
147
+ echo " - 2 players joined"
148
+ echo " - Team Adam (home): 1 player"
149
+ echo " - Team Amy (away): 1 player"
150
+ echo " - Lock time has passed (game was at 1:00 PM)"
151
+ echo ""
152
+
153
+ sleep 2
154
+
155
+ # Step 5: Check Live Scores (what oracle will see)
156
+ echo ""
157
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
158
+ echo "STEP 5: Checking Live Scores (Oracle's View)"
159
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
160
+ echo ""
161
+
162
+ LIVE_SCORES=$(curl -s "$LIVE_SCORES_URL/api/livescores/NBA")
163
+ echo "$LIVE_SCORES" | jq '.' 2>/dev/null || echo "$LIVE_SCORES"
164
+ echo ""
165
+ echo "🔍 Oracle will see:"
166
+ echo " - Game: Amy @ Adam"
167
+ echo " - Status: Final"
168
+ echo " - Score: Amy 3, Adam 2"
169
+ echo " - Winner: AMY (Away Team)"
170
+ echo ""
171
+
172
+ sleep 2
173
+
174
+ # Step 6: Oracle Resolution
175
+ echo ""
176
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
177
+ echo "STEP 6: Oracle Resolves Game"
178
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
179
+ echo ""
180
+ echo "🤖 Simulating Oracle Resolution..."
181
+ echo ""
182
+
183
+ RESOLVE_RESPONSE=$(curl -s -X POST "$API_URL/api/auth/games/$GAME_ID/resolve" \
184
+ -H "Content-Type: application/json" \
185
+ -d '{
186
+ "winner": "away",
187
+ "homeScore": 2,
188
+ "awayScore": 3,
189
+ "resolvedBy": "oracle"
190
+ }')
191
+
192
+ echo "Response: $RESOLVE_RESPONSE"
193
+ echo ""
194
+
195
+ if echo "$RESOLVE_RESPONSE" | grep -q "success.*true"; then
196
+ echo "✅ Game resolved! Amy (away) wins!"
197
+ else
198
+ echo "❌ Failed to resolve"
199
+ exit 1
200
+ fi
201
+
202
+ sleep 2
203
+
204
+ # Step 7: Check Final Game State
205
+ echo ""
206
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
207
+ echo "STEP 7: Final Game State"
208
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
209
+ echo ""
210
+
211
+ FINAL_STATE=$(curl -s "$API_URL/api/auth/games/$GAME_ID/metadata")
212
+ echo "$FINAL_STATE" | jq '.' 2>/dev/null || echo "$FINAL_STATE"
213
+ echo ""
214
+
215
+ # Step 8: Summary
216
+ echo ""
217
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
218
+ echo "🎉 TEST COMPLETE - SUMMARY"
219
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
220
+ echo ""
221
+ echo "✅ Game Created: $GAME_ID"
222
+ echo "✅ Player 1 Joined: Team Adam (home)"
223
+ echo "✅ Player 2 Joined: Team Amy (away)"
224
+ echo "✅ Oracle Resolved: Amy wins 3-2"
225
+ echo ""
226
+ echo "💰 Winners:"
227
+ echo " - $PLAYER_AMY (picked Amy) → CAN CLAIM WINNINGS"
228
+ echo ""
229
+ echo "😢 Losers:"
230
+ echo " - $PLAYER_ADAM (picked Adam) → No payout"
231
+ echo ""
232
+ echo "🔗 Next Steps:"
233
+ echo " 1. Player Amy would call claim_automatic_winnings on-chain"
234
+ echo " 2. Smart contract distributes SOL to Team Amy bettors"
235
+ echo " 3. Game complete!"
236
+ echo ""
237
+ echo "🎯 All systems working! Automatic mode is LIVE!"
238
+ echo ""
239
+