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
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "dubs-server",
3
+ "version": "1.0.0",
4
+ "description": "Dubs wager game API server",
5
+ "main": "server.js",
6
+ "engines": {
7
+ "node": "20.x",
8
+ "npm": "10.x"
9
+ },
10
+ "scripts": {
11
+ "start": "node server.js",
12
+ "dev": "nodemon server.js",
13
+ "cli": "node dubs-cli.js",
14
+ "test:voting": "node dubs-cli.js",
15
+ "oracle:start": "node cron/oracleMonitor.js",
16
+ "oracle:dev": "nodemon cron/oracleMonitor.js",
17
+ "oracle:setup": "bash setup-oracle.sh",
18
+ "arcade:test": "bash test-arcade-match.sh",
19
+ "arcade:test:devnet": "bash test-arcade-devnet.sh"
20
+ },
21
+ "dependencies": {
22
+ "@aws-sdk/client-s3": "^3.936.0",
23
+ "@aws-sdk/s3-request-presigner": "^3.936.0",
24
+ "@dubsdotapp/node": "^0.2.2",
25
+ "@solana/web3.js": "^1.95.8",
26
+ "axios": "^1.6.0",
27
+ "bs58": "^6.0.0",
28
+ "canvas": "^3.2.0",
29
+ "cookie": "^0.6.0",
30
+ "cookie-parser": "^1.4.6",
31
+ "cors": "^2.8.5",
32
+ "dotenv": "^16.3.1",
33
+ "expo-server-sdk": "^6.0.0",
34
+ "express": "^4.18.2",
35
+ "ioredis": "^5.4.1",
36
+ "jsonwebtoken": "^9.0.2",
37
+ "multer": "^2.0.2",
38
+ "pg": "^8.16.3",
39
+ "sharp": "^0.33.5",
40
+ "socket.io": "^4.8.1",
41
+ "thesportsdb": "^0.0.2",
42
+ "tweetnacl": "^1.0.3",
43
+ "uuid": "^10.0.0",
44
+ "web-push": "^3.6.7"
45
+ },
46
+ "devDependencies": {
47
+ "nodemon": "^3.0.1"
48
+ }
49
+ }
@@ -0,0 +1,555 @@
1
+ {
2
+ "info": {
3
+ "name": "Dubs API v1 - Democratic Voting Edition",
4
+ "description": "Complete Dubs wager game API with democratic voting, majority rules, and trustless distribution. Includes all production and demo endpoints.",
5
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6
+ "version": "1.1.0"
7
+ },
8
+ "variable": [
9
+ {
10
+ "key": "baseUrl",
11
+ "value": "https://dubs-server-dev-55d1fba09a97.herokuapp.com",
12
+ "type": "string"
13
+ },
14
+ {
15
+ "key": "gameId",
16
+ "value": "",
17
+ "type": "string"
18
+ },
19
+ {
20
+ "key": "walletAddress",
21
+ "value": "YOUR_WALLET_ADDRESS_HERE",
22
+ "type": "string"
23
+ }
24
+ ],
25
+ "item": [
26
+ {
27
+ "name": "Health Check",
28
+ "request": {
29
+ "method": "GET",
30
+ "header": [],
31
+ "url": "{{baseUrl}}/health",
32
+ "description": "Check if server is running"
33
+ }
34
+ },
35
+ {
36
+ "name": "Production API (Real Wallets)",
37
+ "item": [
38
+ {
39
+ "name": "1. Game Management",
40
+ "item": [
41
+ {
42
+ "name": "Get Game Info",
43
+ "request": {
44
+ "method": "GET",
45
+ "header": [],
46
+ "url": "{{baseUrl}}/api/v1/prod/game/{{gameId}}",
47
+ "description": "Fetch game details from blockchain including players, pot, votes, and voting status"
48
+ }
49
+ }
50
+ ]
51
+ },
52
+ {
53
+ "name": "2. Game Creation",
54
+ "item": [
55
+ {
56
+ "name": "Build Create Game Transaction",
57
+ "request": {
58
+ "method": "POST",
59
+ "header": [{"key": "Content-Type", "value": "application/json"}],
60
+ "body": {
61
+ "mode": "raw",
62
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"buyIn\": 0.5,\n \"maxPlayers\": 4,\n \"operatorFee\": 10,\n \"operatorAddress\": \"OPTIONAL_OPERATOR_ADDRESS\",\n \"votingEnabled\": true\n}"
63
+ },
64
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/create",
65
+ "description": "Build unsigned transaction for creating a game. NEW: votingEnabled parameter for democratic voting!"
66
+ },
67
+ "event": [
68
+ {
69
+ "listen": "test",
70
+ "script": {
71
+ "exec": [
72
+ "const response = pm.response.json();",
73
+ "if (response.gameId) {",
74
+ " pm.collectionVariables.set('gameId', response.gameId);",
75
+ " console.log('✅ Game ID saved:', response.gameId);",
76
+ " console.log('📋 Game Address:', response.gameAddress);",
77
+ "}"
78
+ ],
79
+ "type": "text/javascript"
80
+ }
81
+ }
82
+ ]
83
+ },
84
+ {
85
+ "name": "Build Create Game (Voting Disabled)",
86
+ "request": {
87
+ "method": "POST",
88
+ "header": [{"key": "Content-Type", "value": "application/json"}],
89
+ "body": {
90
+ "mode": "raw",
91
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"buyIn\": 1.0,\n \"maxPlayers\": 2,\n \"operatorFee\": 5,\n \"votingEnabled\": false\n}"
92
+ },
93
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/create",
94
+ "description": "Create game without voting (creator chooses winners manually)"
95
+ }
96
+ }
97
+ ]
98
+ },
99
+ {
100
+ "name": "3. Join Game",
101
+ "item": [
102
+ {
103
+ "name": "Build Join Game Transaction",
104
+ "request": {
105
+ "method": "POST",
106
+ "header": [{"key": "Content-Type", "value": "application/json"}],
107
+ "body": {
108
+ "mode": "raw",
109
+ "raw": "{\n \"playerAddress\": \"{{walletAddress}}\",\n \"gameId\": \"{{gameId}}\"\n}"
110
+ },
111
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/join",
112
+ "description": "Build unsigned transaction for joining a game"
113
+ }
114
+ }
115
+ ]
116
+ },
117
+ {
118
+ "name": "4. Democratic Voting (NEW!)",
119
+ "item": [
120
+ {
121
+ "name": "Build Cast Vote Transaction",
122
+ "request": {
123
+ "method": "POST",
124
+ "header": [{"key": "Content-Type", "value": "application/json"}],
125
+ "body": {
126
+ "mode": "raw",
127
+ "raw": "{\n \"voterAddress\": \"{{walletAddress}}\",\n \"gameId\": \"{{gameId}}\",\n \"votedFor\": \"PLAYER_ADDRESS_TO_VOTE_FOR\"\n}"
128
+ },
129
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/cast-vote",
130
+ "description": "Build unsigned transaction for casting a vote. Each player can vote for any player in the game. Can change vote before majority is reached."
131
+ }
132
+ },
133
+ {
134
+ "name": "Build Distribute by Vote Transaction",
135
+ "request": {
136
+ "method": "POST",
137
+ "header": [{"key": "Content-Type", "value": "application/json"}],
138
+ "body": {
139
+ "mode": "raw",
140
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"gameId\": \"{{gameId}}\"\n}"
141
+ },
142
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/distribute-by-vote",
143
+ "description": "Build unsigned transaction for distributing winnings based on votes. MAJORITY RULES: Requires 50%+ of players to vote. Tallies votes automatically, handles ties by equal split."
144
+ }
145
+ }
146
+ ]
147
+ },
148
+ {
149
+ "name": "5. Manual Distribution",
150
+ "item": [
151
+ {
152
+ "name": "Build Distribute Transaction (Manual)",
153
+ "request": {
154
+ "method": "POST",
155
+ "header": [{"key": "Content-Type", "value": "application/json"}],
156
+ "body": {
157
+ "mode": "raw",
158
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"gameId\": \"{{gameId}}\",\n \"winners\": [\"WINNER1_ADDRESS\", \"WINNER2_ADDRESS\"]\n}"
159
+ },
160
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/distribute",
161
+ "description": "Manually specify winners (creator chooses). Use this for non-voting games or to override voting."
162
+ }
163
+ }
164
+ ]
165
+ },
166
+ {
167
+ "name": "6. Transaction Submission",
168
+ "item": [
169
+ {
170
+ "name": "Submit Signed Transaction",
171
+ "request": {
172
+ "method": "POST",
173
+ "header": [{"key": "Content-Type", "value": "application/json"}],
174
+ "body": {
175
+ "mode": "raw",
176
+ "raw": "{\n \"signedTransaction\": \"BASE64_ENCODED_SIGNED_TRANSACTION\"\n}"
177
+ },
178
+ "url": "{{baseUrl}}/api/v1/prod/transaction/submit",
179
+ "description": "Submit any signed transaction to the blockchain. Returns transaction signature and confirmation."
180
+ }
181
+ }
182
+ ]
183
+ }
184
+ ],
185
+ "description": "🎮 Production endpoints for real wallets (Phantom, Solflare, Jelli, etc.)"
186
+ },
187
+ {
188
+ "name": "Demo/Test API (Server-Managed Wallets)",
189
+ "item": [
190
+ {
191
+ "name": "List Demo Wallets",
192
+ "request": {
193
+ "method": "GET",
194
+ "header": [],
195
+ "url": "{{baseUrl}}/api/v1/demo/wallets",
196
+ "description": "See all test wallets and their balances"
197
+ }
198
+ },
199
+ {
200
+ "name": "Create Game (Server Signs)",
201
+ "request": {
202
+ "method": "POST",
203
+ "header": [{"key": "Content-Type", "value": "application/json"}],
204
+ "body": {
205
+ "mode": "raw",
206
+ "raw": "{\n \"player\": \"creator\",\n \"buyIn\": 0.5,\n \"maxPlayers\": 4,\n \"operatorFee\": 10,\n \"operatorPlayer\": \"jelli\"\n}"
207
+ },
208
+ "url": "{{baseUrl}}/api/v1/demo/game/create",
209
+ "description": "Create game with server-managed wallet"
210
+ },
211
+ "event": [
212
+ {
213
+ "listen": "test",
214
+ "script": {
215
+ "exec": [
216
+ "const response = pm.response.json();",
217
+ "if (response.gameId) {",
218
+ " pm.collectionVariables.set('gameId', response.gameId);",
219
+ " console.log('✅ Game ID saved:', response.gameId);",
220
+ "}"
221
+ ],
222
+ "type": "text/javascript"
223
+ }
224
+ }
225
+ ]
226
+ },
227
+ {
228
+ "name": "Get Game Info",
229
+ "request": {
230
+ "method": "GET",
231
+ "header": [],
232
+ "url": "{{baseUrl}}/api/v1/demo/game/{{gameId}}",
233
+ "description": "View game state"
234
+ }
235
+ },
236
+ {
237
+ "name": "Alice Joins",
238
+ "request": {
239
+ "method": "POST",
240
+ "header": [{"key": "Content-Type", "value": "application/json"}],
241
+ "body": {
242
+ "mode": "raw",
243
+ "raw": "{\n \"player\": \"alice\",\n \"gameId\": \"{{gameId}}\"\n}"
244
+ },
245
+ "url": "{{baseUrl}}/api/v1/demo/game/join"
246
+ }
247
+ },
248
+ {
249
+ "name": "Bob Joins",
250
+ "request": {
251
+ "method": "POST",
252
+ "header": [{"key": "Content-Type", "value": "application/json"}],
253
+ "body": {
254
+ "mode": "raw",
255
+ "raw": "{\n \"player\": \"bob\",\n \"gameId\": \"{{gameId}}\"\n}"
256
+ },
257
+ "url": "{{baseUrl}}/api/v1/demo/game/join"
258
+ }
259
+ },
260
+ {
261
+ "name": "Charlie Joins",
262
+ "request": {
263
+ "method": "POST",
264
+ "header": [{"key": "Content-Type", "value": "application/json"}],
265
+ "body": {
266
+ "mode": "raw",
267
+ "raw": "{\n \"player\": \"charlie\",\n \"gameId\": \"{{gameId}}\"\n}"
268
+ },
269
+ "url": "{{baseUrl}}/api/v1/demo/game/join"
270
+ }
271
+ },
272
+ {
273
+ "name": "Distribute Winnings (Manual)",
274
+ "request": {
275
+ "method": "POST",
276
+ "header": [{"key": "Content-Type", "value": "application/json"}],
277
+ "body": {
278
+ "mode": "raw",
279
+ "raw": "{\n \"gameId\": \"{{gameId}}\",\n \"winners\": [\"PASTE_WINNER_ADDRESSES_FROM_GET_GAME_INFO\"]\n}"
280
+ },
281
+ "url": "{{baseUrl}}/api/v1/demo/game/distribute",
282
+ "description": "Manually distribute to specified winners"
283
+ }
284
+ },
285
+ {
286
+ "name": "Airdrop SOL to Player",
287
+ "request": {
288
+ "method": "POST",
289
+ "header": [{"key": "Content-Type", "value": "application/json"}],
290
+ "body": {
291
+ "mode": "raw",
292
+ "raw": "{\n \"player\": \"alice\"\n}"
293
+ },
294
+ "url": "{{baseUrl}}/api/v1/demo/airdrop",
295
+ "description": "Airdrop 2 SOL to a demo wallet"
296
+ }
297
+ },
298
+ {
299
+ "name": "Check Final Balances",
300
+ "request": {
301
+ "method": "GET",
302
+ "header": [],
303
+ "url": "{{baseUrl}}/api/v1/demo/wallets",
304
+ "description": "Verify winnings were distributed correctly"
305
+ }
306
+ }
307
+ ],
308
+ "description": "🧪 Demo endpoints for testing with server-managed wallets"
309
+ },
310
+ {
311
+ "name": "Complete Workflows",
312
+ "item": [
313
+ {
314
+ "name": "🎮 Standard Game Flow (No Voting)",
315
+ "item": [
316
+ {
317
+ "name": "1️⃣ Build Create Game",
318
+ "request": {
319
+ "method": "POST",
320
+ "header": [{"key": "Content-Type", "value": "application/json"}],
321
+ "body": {
322
+ "mode": "raw",
323
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"buyIn\": 0.5,\n \"maxPlayers\": 4,\n \"operatorFee\": 10,\n \"votingEnabled\": false\n}"
324
+ },
325
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/create"
326
+ },
327
+ "event": [
328
+ {
329
+ "listen": "test",
330
+ "script": {
331
+ "exec": [
332
+ "const response = pm.response.json();",
333
+ "if (response.gameId) {",
334
+ " pm.collectionVariables.set('gameId', response.gameId);",
335
+ " console.log('✅ Game created:', response.gameId);",
336
+ "}"
337
+ ],
338
+ "type": "text/javascript"
339
+ }
340
+ }
341
+ ]
342
+ },
343
+ {
344
+ "name": "2️⃣ Player Joins",
345
+ "request": {
346
+ "method": "POST",
347
+ "header": [{"key": "Content-Type", "value": "application/json"}],
348
+ "body": {
349
+ "mode": "raw",
350
+ "raw": "{\n \"playerAddress\": \"FRIEND_WALLET_ADDRESS\",\n \"gameId\": \"{{gameId}}\"\n}"
351
+ },
352
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/join"
353
+ }
354
+ },
355
+ {
356
+ "name": "3️⃣ Check Game Status",
357
+ "request": {
358
+ "method": "GET",
359
+ "header": [],
360
+ "url": "{{baseUrl}}/api/v1/prod/game/{{gameId}}"
361
+ }
362
+ },
363
+ {
364
+ "name": "4️⃣ Distribute to Winners",
365
+ "request": {
366
+ "method": "POST",
367
+ "header": [{"key": "Content-Type", "value": "application/json"}],
368
+ "body": {
369
+ "mode": "raw",
370
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"gameId\": \"{{gameId}}\",\n \"winners\": [\"WINNER1_ADDRESS\", \"WINNER2_ADDRESS\"]\n}"
371
+ },
372
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/distribute"
373
+ }
374
+ }
375
+ ],
376
+ "description": "Traditional flow: Creator chooses winners manually"
377
+ },
378
+ {
379
+ "name": "🗳️ Democratic Game Flow (With Voting)",
380
+ "item": [
381
+ {
382
+ "name": "1️⃣ Build Create Game (Voting ON)",
383
+ "request": {
384
+ "method": "POST",
385
+ "header": [{"key": "Content-Type", "value": "application/json"}],
386
+ "body": {
387
+ "mode": "raw",
388
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"buyIn\": 0.5,\n \"maxPlayers\": 3,\n \"operatorFee\": 10,\n \"votingEnabled\": true\n}"
389
+ },
390
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/create",
391
+ "description": "Create game with democratic voting enabled"
392
+ },
393
+ "event": [
394
+ {
395
+ "listen": "test",
396
+ "script": {
397
+ "exec": [
398
+ "const response = pm.response.json();",
399
+ "if (response.gameId) {",
400
+ " pm.collectionVariables.set('gameId', response.gameId);",
401
+ " console.log('✅ Game created with voting:', response.gameId);",
402
+ "}"
403
+ ],
404
+ "type": "text/javascript"
405
+ }
406
+ }
407
+ ]
408
+ },
409
+ {
410
+ "name": "2️⃣ Player 1 Joins",
411
+ "request": {
412
+ "method": "POST",
413
+ "header": [{"key": "Content-Type", "value": "application/json"}],
414
+ "body": {
415
+ "mode": "raw",
416
+ "raw": "{\n \"playerAddress\": \"PLAYER1_ADDRESS\",\n \"gameId\": \"{{gameId}}\"\n}"
417
+ },
418
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/join"
419
+ }
420
+ },
421
+ {
422
+ "name": "3️⃣ Player 2 Joins",
423
+ "request": {
424
+ "method": "POST",
425
+ "header": [{"key": "Content-Type", "value": "application/json"}],
426
+ "body": {
427
+ "mode": "raw",
428
+ "raw": "{\n \"playerAddress\": \"PLAYER2_ADDRESS\",\n \"gameId\": \"{{gameId}}\"\n}"
429
+ },
430
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/join"
431
+ }
432
+ },
433
+ {
434
+ "name": "4️⃣ Check Game (See Players)",
435
+ "request": {
436
+ "method": "GET",
437
+ "header": [],
438
+ "url": "{{baseUrl}}/api/v1/prod/game/{{gameId}}",
439
+ "description": "Verify all players joined. Copy player addresses for voting."
440
+ }
441
+ },
442
+ {
443
+ "name": "5️⃣ Player 1 Votes",
444
+ "request": {
445
+ "method": "POST",
446
+ "header": [{"key": "Content-Type", "value": "application/json"}],
447
+ "body": {
448
+ "mode": "raw",
449
+ "raw": "{\n \"voterAddress\": \"PLAYER1_ADDRESS\",\n \"gameId\": \"{{gameId}}\",\n \"votedFor\": \"PLAYER2_ADDRESS\"\n}"
450
+ },
451
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/cast-vote",
452
+ "description": "Player 1 votes for Player 2"
453
+ }
454
+ },
455
+ {
456
+ "name": "6️⃣ Player 2 Votes",
457
+ "request": {
458
+ "method": "POST",
459
+ "header": [{"key": "Content-Type", "value": "application/json"}],
460
+ "body": {
461
+ "mode": "raw",
462
+ "raw": "{\n \"voterAddress\": \"PLAYER2_ADDRESS\",\n \"gameId\": \"{{gameId}}\",\n \"votedFor\": \"PLAYER1_ADDRESS\"\n}"
463
+ },
464
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/cast-vote",
465
+ "description": "Player 2 votes for Player 1"
466
+ }
467
+ },
468
+ {
469
+ "name": "7️⃣ Check Voting Progress",
470
+ "request": {
471
+ "method": "GET",
472
+ "header": [],
473
+ "url": "{{baseUrl}}/api/v1/prod/game/{{gameId}}",
474
+ "description": "Check votes array and votingEnabled status. For 3 players, need 2 votes for majority."
475
+ }
476
+ },
477
+ {
478
+ "name": "8️⃣ Distribute by Vote (Majority Reached)",
479
+ "request": {
480
+ "method": "POST",
481
+ "header": [{"key": "Content-Type", "value": "application/json"}],
482
+ "body": {
483
+ "mode": "raw",
484
+ "raw": "{\n \"creatorAddress\": \"{{walletAddress}}\",\n \"gameId\": \"{{gameId}}\"\n}"
485
+ },
486
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/distribute-by-vote",
487
+ "description": "Distribute prize pool based on votes. Response includes winners and vote counts."
488
+ }
489
+ },
490
+ {
491
+ "name": "9️⃣ Final Game State",
492
+ "request": {
493
+ "method": "GET",
494
+ "header": [],
495
+ "url": "{{baseUrl}}/api/v1/prod/game/{{gameId}}",
496
+ "description": "Verify game is closed and pot is empty"
497
+ }
498
+ }
499
+ ],
500
+ "description": "🗳️ Complete democratic voting workflow from creation to distribution"
501
+ }
502
+ ],
503
+ "description": "📋 Complete end-to-end workflows for testing"
504
+ },
505
+ {
506
+ "name": "Examples & Documentation",
507
+ "item": [
508
+ {
509
+ "name": "📖 API Overview",
510
+ "request": {
511
+ "method": "GET",
512
+ "header": [],
513
+ "url": "{{baseUrl}}/",
514
+ "description": "Get API information and available endpoints"
515
+ }
516
+ },
517
+ {
518
+ "name": "Example Responses",
519
+ "item": [
520
+ {
521
+ "name": "Game Info Response (No Voting)",
522
+ "request": {
523
+ "method": "GET",
524
+ "header": [],
525
+ "url": "{{baseUrl}}/api/v1/prod/game/example-id",
526
+ "description": "Example response:\n{\n \"exists\": true,\n \"game\": {\n \"gameId\": 12345,\n \"authority\": \"CreatorAddress...\",\n \"buyIn\": 0.5,\n \"maxPlayers\": 4,\n \"operatorWallet\": \"OperatorAddress...\",\n \"operatorFeePercentage\": 10,\n \"players\": [\"Player1...\", \"Player2...\"],\n \"totalPot\": 1.0,\n \"isActive\": true,\n \"votes\": [],\n \"votingEnabled\": false\n },\n \"calculated\": {\n \"operatorFeeAmount\": \"0.1000\",\n \"prizePool\": \"0.9000\"\n }\n}"
527
+ }
528
+ },
529
+ {
530
+ "name": "Game Info Response (With Voting)",
531
+ "request": {
532
+ "method": "GET",
533
+ "header": [],
534
+ "url": "{{baseUrl}}/api/v1/prod/game/example-id",
535
+ "description": "Example response with votes:\n{\n \"exists\": true,\n \"game\": {\n \"gameId\": 12345,\n \"authority\": \"Creator...\",\n \"buyIn\": 0.5,\n \"maxPlayers\": 3,\n \"players\": [\"Player1...\", \"Player2...\", \"Player3...\"],\n \"totalPot\": 1.5,\n \"isActive\": true,\n \"votes\": [\n {\"voter\": \"Player1...\", \"votedFor\": \"Player2...\"},\n {\"voter\": \"Player2...\", \"votedFor\": \"Player2...\"}\n ],\n \"votingEnabled\": true\n },\n \"calculated\": {\n \"operatorFeeAmount\": \"0.1500\",\n \"prizePool\": \"1.3500\"\n }\n}"
536
+ }
537
+ },
538
+ {
539
+ "name": "Distribute by Vote Response",
540
+ "request": {
541
+ "method": "POST",
542
+ "header": [],
543
+ "url": "{{baseUrl}}/api/v1/prod/transaction/build/distribute-by-vote",
544
+ "description": "Example response:\n{\n \"success\": true,\n \"transaction\": \"BASE64_UNSIGNED_TX...\",\n \"winners\": [\"Player2Address...\"],\n \"voteCounts\": {\n \"Player1Address\": 1,\n \"Player2Address\": 2\n },\n \"instructions\": \"Sign and submit...\"\n}"
545
+ }
546
+ }
547
+ ],
548
+ "description": "Example API responses for reference"
549
+ }
550
+ ],
551
+ "description": "📚 Documentation and examples"
552
+ }
553
+ ]
554
+ }
555
+