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,656 @@
1
+ # 🎮 Dubs Demo API - Complete Curl Reference
2
+
3
+ **All commands ready to copy & paste!** No Postman needed!
4
+
5
+ ---
6
+
7
+ ## 🌐 **Server Info**
8
+
9
+ ```bash
10
+ # Local
11
+ http://localhost:3001
12
+
13
+ # Devnet (when Heroku is back)
14
+ https://dubs-server-dev-55d1fba09a97.herokuapp.com
15
+ ```
16
+
17
+ ---
18
+
19
+ ## 📋 **All Demo Endpoints**
20
+
21
+ ### **1. Health Check**
22
+
23
+ ```bash
24
+ curl http://localhost:3001/health
25
+ ```
26
+
27
+ **Response:**
28
+ ```json
29
+ {"status":"ok","message":"🎮 Dubs API Server is running!"}
30
+ ```
31
+
32
+ ---
33
+
34
+ ### **2. List All Demo Wallets**
35
+
36
+ ```bash
37
+ curl http://localhost:3001/api/v1/demo/wallets | python3 -m json.tool
38
+ ```
39
+
40
+ **Response:**
41
+ ```json
42
+ {
43
+ "wallets": [
44
+ {
45
+ "name": "creator",
46
+ "address": "2rHd6Fe7KzbUAJwH56iVSmAcRy4X9rdqutS2hzc1PM4d",
47
+ "balance": "2.0000"
48
+ },
49
+ {
50
+ "name": "alice",
51
+ "address": "GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc",
52
+ "balance": "0.0000"
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+
58
+ ---
59
+
60
+ ### **3. Airdrop SOL to Player**
61
+
62
+ ```bash
63
+ # Airdrop to alice
64
+ curl -X POST http://localhost:3001/api/v1/demo/airdrop \
65
+ -H "Content-Type: application/json" \
66
+ -d '{"player":"alice"}' \
67
+ | python3 -m json.tool
68
+
69
+ # Airdrop to bob
70
+ curl -X POST http://localhost:3001/api/v1/demo/airdrop \
71
+ -H "Content-Type: application/json" \
72
+ -d '{"player":"bob"}' \
73
+ | python3 -m json.tool
74
+
75
+ # Airdrop to charlie
76
+ curl -X POST http://localhost:3001/api/v1/demo/airdrop \
77
+ -H "Content-Type: application/json" \
78
+ -d '{"player":"charlie"}' \
79
+ | python3 -m json.tool
80
+ ```
81
+
82
+ **Response:**
83
+ ```json
84
+ {
85
+ "success": true,
86
+ "message": "Airdropped 2 SOL to alice",
87
+ "address": "GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc",
88
+ "balance": "2.0000"
89
+ }
90
+ ```
91
+
92
+ ---
93
+
94
+ ### **4. Create Game**
95
+
96
+ ```bash
97
+ # Standard game (no voting)
98
+ curl -X POST http://localhost:3001/api/v1/demo/game/create \
99
+ -H "Content-Type: application/json" \
100
+ -d '{
101
+ "player": "creator",
102
+ "buyIn": 0.5,
103
+ "maxPlayers": 4,
104
+ "operatorFee": 10,
105
+ "operatorPlayer": "jelli"
106
+ }' \
107
+ | python3 -m json.tool
108
+ ```
109
+
110
+ **Response:**
111
+ ```json
112
+ {
113
+ "success": true,
114
+ "gameId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
115
+ "message": "Game created by creator, operator: jelli",
116
+ "transaction": "signature...",
117
+ "gameAddress": "PDA..."
118
+ }
119
+ ```
120
+
121
+ **💾 SAVE THE GAME ID!**
122
+
123
+ ---
124
+
125
+ ### **5. Get Game Info**
126
+
127
+ ```bash
128
+ # Replace GAME_ID with the UUID from create response
129
+ curl http://localhost:3001/api/v1/demo/game/GAME_ID | python3 -m json.tool
130
+ ```
131
+
132
+ **Response:**
133
+ ```json
134
+ {
135
+ "exists": true,
136
+ "game": {
137
+ "gameId": 12345,
138
+ "authority": "2rHd6Fe7...",
139
+ "buyIn": 0.5,
140
+ "maxPlayers": 4,
141
+ "players": ["2rHd6Fe7..."],
142
+ "totalPot": 0.5,
143
+ "isActive": true,
144
+ "votes": [],
145
+ "votingEnabled": false
146
+ },
147
+ "calculated": {
148
+ "operatorFeeAmount": "0.0500",
149
+ "prizePool": "0.4500"
150
+ }
151
+ }
152
+ ```
153
+
154
+ ---
155
+
156
+ ### **6. Players Join Game**
157
+
158
+ ```bash
159
+ # Alice joins
160
+ curl -X POST http://localhost:3001/api/v1/demo/game/join \
161
+ -H "Content-Type: application/json" \
162
+ -d '{
163
+ "player": "alice",
164
+ "gameId": "PASTE_GAME_ID_HERE"
165
+ }' \
166
+ | python3 -m json.tool
167
+
168
+ # Bob joins
169
+ curl -X POST http://localhost:3001/api/v1/demo/game/join \
170
+ -H "Content-Type: application/json" \
171
+ -d '{
172
+ "player": "bob",
173
+ "gameId": "PASTE_GAME_ID_HERE"
174
+ }' \
175
+ | python3 -m json.tool
176
+
177
+ # Charlie joins
178
+ curl -X POST http://localhost:3001/api/v1/demo/game/join \
179
+ -H "Content-Type: application/json" \
180
+ -d '{
181
+ "player": "charlie",
182
+ "gameId": "PASTE_GAME_ID_HERE"
183
+ }' \
184
+ | python3 -m json.tool
185
+ ```
186
+
187
+ **Response:**
188
+ ```json
189
+ {
190
+ "success": true,
191
+ "message": "alice joined game",
192
+ "transaction": "signature...",
193
+ "playersCount": 2
194
+ }
195
+ ```
196
+
197
+ ---
198
+
199
+ ### **7. Cast Votes** 🗳️ **NEW!**
200
+
201
+ ```bash
202
+ # Creator votes for Alice
203
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
204
+ -H "Content-Type: application/json" \
205
+ -d '{
206
+ "player": "creator",
207
+ "gameId": "PASTE_GAME_ID",
208
+ "votedFor": "GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc"
209
+ }' \
210
+ | python3 -m json.tool
211
+
212
+ # Alice votes for herself
213
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
214
+ -H "Content-Type: application/json" \
215
+ -d '{
216
+ "player": "alice",
217
+ "gameId": "PASTE_GAME_ID",
218
+ "votedFor": "GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc"
219
+ }' \
220
+ | python3 -m json.tool
221
+
222
+ # Bob votes for Charlie
223
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
224
+ -H "Content-Type: application/json" \
225
+ -d '{
226
+ "player": "bob",
227
+ "gameId": "PASTE_GAME_ID",
228
+ "votedFor": "B6ZDc5TA31nLeffsFffvsPx6EUbuCeDRjoo9KgcUAR5E"
229
+ }' \
230
+ | python3 -m json.tool
231
+ ```
232
+
233
+ **Response:**
234
+ ```json
235
+ {
236
+ "success": true,
237
+ "message": "alice voted for GvE3wSwh...",
238
+ "transaction": "signature...",
239
+ "votesCount": 2,
240
+ "votingProgress": "2/3 votes"
241
+ }
242
+ ```
243
+
244
+ ---
245
+
246
+ ### **8. Distribute by Vote** 🗳️ **NEW!**
247
+
248
+ ```bash
249
+ curl -X POST http://localhost:3001/api/v1/demo/vote/distribute \
250
+ -H "Content-Type: application/json" \
251
+ -d '{
252
+ "gameId": "PASTE_GAME_ID"
253
+ }' \
254
+ | python3 -m json.tool
255
+ ```
256
+
257
+ **Response:**
258
+ ```json
259
+ {
260
+ "success": true,
261
+ "message": "Winnings distributed by vote to 1 winners",
262
+ "transaction": "signature...",
263
+ "winners": ["GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc"],
264
+ "voteCounts": {
265
+ "2rHd6Fe7...": 0,
266
+ "GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc": 2,
267
+ "B6ZDc5TA31nLeff...": 1
268
+ },
269
+ "winnersCount": 1
270
+ }
271
+ ```
272
+
273
+ ---
274
+
275
+ ### **9. Distribute Manually (Creator Chooses)**
276
+
277
+ ```bash
278
+ # Get player addresses from game info first!
279
+ curl -X POST http://localhost:3001/api/v1/demo/game/distribute \
280
+ -H "Content-Type: application/json" \
281
+ -d '{
282
+ "gameId": "PASTE_GAME_ID",
283
+ "winners": [
284
+ "GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc",
285
+ "AuskVDhGKzZ9xWJaY5RKWzBZzeGuEYZ6mZXCDeTQCJcw"
286
+ ]
287
+ }' \
288
+ | python3 -m json.tool
289
+ ```
290
+
291
+ **Response:**
292
+ ```json
293
+ {
294
+ "success": true,
295
+ "message": "Winnings distributed to 2 winners",
296
+ "transaction": "signature...",
297
+ "operatorFee": "0.1500",
298
+ "prizePool": "1.3500",
299
+ "winnersCount": 2,
300
+ "winnerAddresses": ["GvE3wSwh...", "AuskVDhG..."]
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ## 🎯 **Complete Test Flow (Copy All!)**
307
+
308
+ ### **Democratic Voting Test:**
309
+
310
+ ```bash
311
+ # Step 1: Create game
312
+ GAME_ID=$(curl -s -X POST http://localhost:3001/api/v1/demo/game/create \
313
+ -H "Content-Type: application/json" \
314
+ -d '{"player":"creator","buyIn":0.5,"maxPlayers":3,"operatorFee":10,"operatorPlayer":"jelli"}' \
315
+ | python3 -c "import sys, json; print(json.load(sys.stdin)['gameId'])")
316
+
317
+ echo "✅ Game created: $GAME_ID"
318
+
319
+ # Step 2: Players join
320
+ echo "👥 Alice joining..."
321
+ curl -s -X POST http://localhost:3001/api/v1/demo/game/join \
322
+ -H "Content-Type: application/json" \
323
+ -d "{\"player\":\"alice\",\"gameId\":\"$GAME_ID\"}" \
324
+ | python3 -m json.tool
325
+
326
+ echo "👥 Bob joining..."
327
+ curl -s -X POST http://localhost:3001/api/v1/demo/game/join \
328
+ -H "Content-Type: application/json" \
329
+ -d "{\"player\":\"bob\",\"gameId\":\"$GAME_ID\"}" \
330
+ | python3 -m json.tool
331
+
332
+ # Step 3: Get game info and player addresses
333
+ echo "📊 Game Info:"
334
+ curl -s http://localhost:3001/api/v1/demo/game/$GAME_ID | python3 -m json.tool
335
+
336
+ # Step 4: Cast votes (COPY ALICE ADDRESS FROM ABOVE!)
337
+ ALICE_ADDR="GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc"
338
+
339
+ echo "🗳️ Creator votes for Alice..."
340
+ curl -s -X POST http://localhost:3001/api/v1/demo/vote/cast \
341
+ -H "Content-Type: application/json" \
342
+ -d "{\"player\":\"creator\",\"gameId\":\"$GAME_ID\",\"votedFor\":\"$ALICE_ADDR\"}" \
343
+ | python3 -m json.tool
344
+
345
+ echo "🗳️ Alice votes for herself..."
346
+ curl -s -X POST http://localhost:3001/api/v1/demo/vote/cast \
347
+ -H "Content-Type: application/json" \
348
+ -d "{\"player\":\"alice\",\"gameId\":\"$GAME_ID\",\"votedFor\":\"$ALICE_ADDR\"}" \
349
+ | python3 -m json.tool
350
+
351
+ # Step 5: Distribute by vote (2/3 = majority!)
352
+ echo "🏆 Distributing by vote..."
353
+ curl -s -X POST http://localhost:3001/api/v1/demo/vote/distribute \
354
+ -H "Content-Type: application/json" \
355
+ -d "{\"gameId\":\"$GAME_ID\"}" \
356
+ | python3 -m json.tool
357
+
358
+ # Step 6: Check final balances
359
+ echo "💰 Final balances:"
360
+ curl -s http://localhost:3001/api/v1/demo/wallets | python3 -m json.tool
361
+ ```
362
+
363
+ ---
364
+
365
+ ## 📝 **Quick Reference (Single Commands)**
366
+
367
+ ### **List Wallets:**
368
+ ```bash
369
+ curl http://localhost:3001/api/v1/demo/wallets | python3 -m json.tool
370
+ ```
371
+
372
+ ### **Airdrop:**
373
+ ```bash
374
+ curl -X POST http://localhost:3001/api/v1/demo/airdrop \
375
+ -H "Content-Type: application/json" \
376
+ -d '{"player":"alice"}' | python3 -m json.tool
377
+ ```
378
+
379
+ ### **Create Game:**
380
+ ```bash
381
+ curl -X POST http://localhost:3001/api/v1/demo/game/create \
382
+ -H "Content-Type: application/json" \
383
+ -d '{"player":"creator","buyIn":0.5,"maxPlayers":3,"operatorFee":10}' \
384
+ | python3 -m json.tool
385
+ ```
386
+
387
+ ### **Join Game:**
388
+ ```bash
389
+ curl -X POST http://localhost:3001/api/v1/demo/game/join \
390
+ -H "Content-Type: application/json" \
391
+ -d '{"player":"alice","gameId":"YOUR_GAME_ID"}' \
392
+ | python3 -m json.tool
393
+ ```
394
+
395
+ ### **Get Game:**
396
+ ```bash
397
+ curl http://localhost:3001/api/v1/demo/game/YOUR_GAME_ID | python3 -m json.tool
398
+ ```
399
+
400
+ ### **Cast Vote:** 🗳️
401
+ ```bash
402
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
403
+ -H "Content-Type: application/json" \
404
+ -d '{"player":"alice","gameId":"YOUR_GAME_ID","votedFor":"PLAYER_ADDRESS"}' \
405
+ | python3 -m json.tool
406
+ ```
407
+
408
+ ### **Distribute by Vote:** 🗳️
409
+ ```bash
410
+ curl -X POST http://localhost:3001/api/v1/demo/vote/distribute \
411
+ -H "Content-Type: application/json" \
412
+ -d '{"gameId":"YOUR_GAME_ID"}' \
413
+ | python3 -m json.tool
414
+ ```
415
+
416
+ ### **Distribute Manually:**
417
+ ```bash
418
+ curl -X POST http://localhost:3001/api/v1/demo/game/distribute \
419
+ -H "Content-Type: application/json" \
420
+ -d '{"gameId":"YOUR_GAME_ID","winners":["ADDR1","ADDR2"]}' \
421
+ | python3 -m json.tool
422
+ ```
423
+
424
+ ---
425
+
426
+ ## 🎮 **Complete Game Scenarios**
427
+
428
+ ### **Scenario 1: Alice Wins by Vote (2/3 Majority)**
429
+
430
+ ```bash
431
+ # Setup
432
+ GAME_ID=$(curl -s -X POST http://localhost:3001/api/v1/demo/game/create \
433
+ -H "Content-Type: application/json" \
434
+ -d '{"player":"creator","buyIn":0.5,"maxPlayers":3,"operatorFee":10,"operatorPlayer":"jelli"}' \
435
+ | python3 -c "import sys, json; print(json.load(sys.stdin)['gameId'])")
436
+ echo "Game ID: $GAME_ID"
437
+
438
+ # Players join
439
+ curl -X POST http://localhost:3001/api/v1/demo/game/join \
440
+ -H "Content-Type: application/json" \
441
+ -d "{\"player\":\"alice\",\"gameId\":\"$GAME_ID\"}"
442
+
443
+ curl -X POST http://localhost:3001/api/v1/demo/game/join \
444
+ -H "Content-Type: application/json" \
445
+ -d "{\"player\":\"bob\",\"gameId\":\"$GAME_ID\"}"
446
+
447
+ # Get player addresses
448
+ echo "Getting player addresses..."
449
+ curl -s http://localhost:3001/api/v1/demo/game/$GAME_ID | python3 -m json.tool
450
+
451
+ # COPY ALICE ADDRESS, then:
452
+ ALICE="GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc"
453
+
454
+ # Creator votes for Alice
455
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
456
+ -H "Content-Type: application/json" \
457
+ -d "{\"player\":\"creator\",\"gameId\":\"$GAME_ID\",\"votedFor\":\"$ALICE\"}"
458
+
459
+ # Alice votes for herself (2/3 majority!)
460
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
461
+ -H "Content-Type: application/json" \
462
+ -d "{\"player\":\"alice\",\"gameId\":\"$GAME_ID\",\"votedFor\":\"$ALICE\"}"
463
+
464
+ # Distribute (Alice wins!)
465
+ curl -X POST http://localhost:3001/api/v1/demo/vote/distribute \
466
+ -H "Content-Type: application/json" \
467
+ -d "{\"gameId\":\"$GAME_ID\"}" \
468
+ | python3 -m json.tool
469
+
470
+ # Check balances
471
+ curl http://localhost:3001/api/v1/demo/wallets | python3 -m json.tool
472
+ ```
473
+
474
+ ---
475
+
476
+ ### **Scenario 2: 3-Way Tie (Equal Split)**
477
+
478
+ ```bash
479
+ # After creating game and 3 players joining...
480
+
481
+ # Get all 3 addresses first
482
+ CREATOR="2rHd6Fe7KzbUAJwH56iVSmAcRy4X9rdqutS2hzc1PM4d"
483
+ ALICE="GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc"
484
+ BOB="AuskVDhGKzZ9xWJaY5RKWzBZzeGuEYZ6mZXCDeTQCJcw"
485
+
486
+ # Creator votes for Alice
487
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
488
+ -H "Content-Type: application/json" \
489
+ -d "{\"player\":\"creator\",\"gameId\":\"$GAME_ID\",\"votedFor\":\"$ALICE\"}"
490
+
491
+ # Alice votes for Bob
492
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
493
+ -H "Content-Type: application/json" \
494
+ -d "{\"player\":\"alice\",\"gameId\":\"$GAME_ID\",\"votedFor\":\"$BOB\"}"
495
+
496
+ # Bob votes for Creator
497
+ curl -X POST http://localhost:3001/api/v1/demo/vote/cast \
498
+ -H "Content-Type: application/json" \
499
+ -d "{\"player\":\"bob\",\"gameId\":\"$GAME_ID\",\"votedFor\":\"$CREATOR\"}"
500
+
501
+ # Distribute (All 3 tied at 1 vote each = equal split!)
502
+ curl -X POST http://localhost:3001/api/v1/demo/vote/distribute \
503
+ -H "Content-Type: application/json" \
504
+ -d "{\"gameId\":\"$GAME_ID\"}" \
505
+ | python3 -m json.tool
506
+ ```
507
+
508
+ **Result: All 3 players get 33% each!**
509
+
510
+ ---
511
+
512
+ ### **Scenario 3: 2-Way Tie**
513
+
514
+ ```bash
515
+ # After 4 players joined...
516
+
517
+ # 2 vote for Alice, 2 vote for Bob
518
+ # Result: 50/50 split between Alice and Bob
519
+ ```
520
+
521
+ ---
522
+
523
+ ## 🔧 **Helper Commands**
524
+
525
+ ### **Save Game ID:**
526
+ ```bash
527
+ # After creating game, extract gameId
528
+ GAME_ID=$(curl -s -X POST http://localhost:3001/api/v1/demo/game/create \
529
+ -H "Content-Type: application/json" \
530
+ -d '{"player":"creator","buyIn":0.5,"maxPlayers":3,"operatorFee":10}' \
531
+ | python3 -c "import sys, json; print(json.load(sys.stdin)['gameId'])")
532
+
533
+ echo $GAME_ID
534
+ ```
535
+
536
+ ### **Get Player Addresses:**
537
+ ```bash
538
+ # Extract just the players array
539
+ curl -s http://localhost:3001/api/v1/demo/game/$GAME_ID \
540
+ | python3 -c "import sys, json; data=json.load(sys.stdin); print('\n'.join(data['game']['players']))"
541
+ ```
542
+
543
+ ### **Check Vote Counts:**
544
+ ```bash
545
+ # See who voted for whom
546
+ curl -s http://localhost:3001/api/v1/demo/game/$GAME_ID \
547
+ | python3 -c "import sys, json; data=json.load(sys.stdin); [print(f\"{v['voter'][:8]}... → {v['votedFor'][:8]}...\") for v in data['game']['votes']]"
548
+ ```
549
+
550
+ ---
551
+
552
+ ## 🗳️ **Demo Voting Endpoints**
553
+
554
+ ### **Cast Vote:**
555
+ ```
556
+ POST /api/v1/demo/vote/cast
557
+
558
+ Body:
559
+ {
560
+ "player": "alice", ← Demo player name
561
+ "gameId": "uuid",
562
+ "votedFor": "player-address" ← Full Solana address
563
+ }
564
+
565
+ Response:
566
+ {
567
+ "success": true,
568
+ "message": "alice voted for GvE3wSwh...",
569
+ "transaction": "signature",
570
+ "votesCount": 2,
571
+ "votingProgress": "2/3 votes"
572
+ }
573
+ ```
574
+
575
+ ### **Distribute by Vote:**
576
+ ```
577
+ POST /api/v1/demo/vote/distribute
578
+
579
+ Body:
580
+ {
581
+ "gameId": "uuid"
582
+ }
583
+
584
+ Response:
585
+ {
586
+ "success": true,
587
+ "message": "Winnings distributed by vote to 1 winners",
588
+ "transaction": "signature",
589
+ "winners": ["winner-address"],
590
+ "voteCounts": {
591
+ "player1": 2,
592
+ "player2": 1
593
+ },
594
+ "winnersCount": 1
595
+ }
596
+ ```
597
+
598
+ ---
599
+
600
+ ## 📊 **Wallet Addresses Reference**
601
+
602
+ ```
603
+ Creator: 2rHd6Fe7KzbUAJwH56iVSmAcRy4X9rdqutS2hzc1PM4d
604
+ Alice: GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc
605
+ Bob: AuskVDhGKzZ9xWJaY5RKWzBZzeGuEYZ6mZXCDeTQCJcw
606
+ Charlie: B6ZDc5TA31nLeffsFffvsPx6EUbuCeDRjoo9KgcUAR5E
607
+ Jelli: 9tMoLukuPD5cV5K3xs8medMBGjkqsS26webAzFbqPZJr
608
+ ```
609
+
610
+ ---
611
+
612
+ ## 🎉 **One-Line Full Test**
613
+
614
+ ```bash
615
+ # Complete voting test in one command chain
616
+ curl -s -X POST http://localhost:3001/api/v1/demo/game/create -H "Content-Type: application/json" -d '{"player":"creator","buyIn":0.5,"maxPlayers":3,"operatorFee":10}' | python3 -c "import sys,json; gid=json.load(sys.stdin)['gameId']; print(f'Game: {gid}'); import os; os.system(f'curl -X POST http://localhost:3001/api/v1/demo/game/join -H \"Content-Type: application/json\" -d \\'{{\"player\":\"alice\",\"gameId\":\"{gid}\"}}\\''); os.system(f'curl -X POST http://localhost:3001/api/v1/demo/game/join -H \"Content-Type: application/json\" -d \\'{{\"player\":\"bob\",\"gameId\":\"{gid}\"}}\\''); os.system(f'curl -X POST http://localhost:3001/api/v1/demo/vote/cast -H \"Content-Type: application/json\" -d \\'{{\"player\":\"creator\",\"gameId\":\"{gid}\",\"votedFor\":\"GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc\"}}\\''); os.system(f'curl -X POST http://localhost:3001/api/v1/demo/vote/cast -H \"Content-Type: application/json\" -d \\'{{\"player\":\"alice\",\"gameId\":\"{gid}\",\"votedFor\":\"GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc\"}}\\''); os.system(f'curl -X POST http://localhost:3001/api/v1/demo/vote/distribute -H \"Content-Type: application/json\" -d \\'{{\"gameId\":\"{gid}}\\' | python3 -m json.tool')"
617
+ ```
618
+
619
+ ---
620
+
621
+ ## ⚡ **Tips**
622
+
623
+ ### **Pretty Print:**
624
+ ```bash
625
+ # Always pipe to python3 -m json.tool for readable output
626
+ curl ... | python3 -m json.tool
627
+ ```
628
+
629
+ ### **Save Variables:**
630
+ ```bash
631
+ # Save game ID
632
+ GAME_ID="paste-here"
633
+
634
+ # Save addresses
635
+ ALICE="GvE3wSwh2HDpER7x3WXmipqH8Q9zDmHiAc8Qc8U8jTTc"
636
+ BOB="AuskVDhGKzZ9xWJaY5RKWzBZzeGuEYZ6mZXCDeTQCJcw"
637
+ ```
638
+
639
+ ### **Silent Mode:**
640
+ ```bash
641
+ # Use -s flag to hide curl progress
642
+ curl -s http://...
643
+ ```
644
+
645
+ ---
646
+
647
+ ## 🎯 **Test Everything!**
648
+
649
+ **You now have ALL the commands to test the complete democratic voting system locally!**
650
+
651
+ **No Postman, no Heroku, no AWS - just pure local testing! 🚀**
652
+
653
+ ---
654
+
655
+ **Copy and paste away! 🎮🗳️**
656
+