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/README.md ADDED
@@ -0,0 +1,476 @@
1
+ # 🎮 Dubs API Server
2
+
3
+ Production-ready REST API for Solana wager games with operator fees, multi-game support, and clean architecture.
4
+
5
+ ---
6
+
7
+ ## Quick Links
8
+
9
+ - **Live Devnet API**: https://dubs-server-dev-55d1fba09a97.herokuapp.com
10
+ - **Program ID**: `8DJTkgk6MDr6tPtw4v2VzYAz9WWvmCg6786vZrEK3o5q`
11
+ - **Solana Explorer**: https://explorer.solana.com/address/8DJTkgk6MDr6tPtw4v2VzYAz9WWvmCg6786vZrEK3o5q?cluster=devnet
12
+
13
+ ---
14
+
15
+ ## Environments
16
+
17
+ ### Local Development (Localnet)
18
+ ```bash
19
+ # Start local validator
20
+ solana-test-validator --reset
21
+
22
+ # Deploy program
23
+ cd ../dubs
24
+ solana program deploy target/deploy/hello_world.so --url localhost
25
+
26
+ # Start server
27
+ cd ../dubs-server
28
+ node server.js
29
+
30
+ # API: http://localhost:3001
31
+ # Network: Localnet (your computer)
32
+ ```
33
+
34
+ ### Devnet Testing (Public Test Network)
35
+ ```bash
36
+ # Server already deployed to Heroku!
37
+ # API: https://dubs-server-dev-55d1fba09a97.herokuapp.com
38
+ # Network: Devnet (public)
39
+ # SOL: Free from faucet
40
+ ```
41
+
42
+ ### Mainnet Production (Future)
43
+ ```bash
44
+ # Deploy program to mainnet
45
+ cd ../dubs
46
+ solana program deploy target/deploy/hello_world.so --url mainnet-beta
47
+
48
+ # Deploy server to Heroku
49
+ heroku apps:create dubs-api-prod --team dubs
50
+ heroku config:set SOLANA_NETWORK=https://api.mainnet-beta.solana.com -a dubs-api-prod
51
+ git push heroku-prod main
52
+
53
+ # API: https://dubs-api-prod.herokuapp.com
54
+ # Network: Mainnet (real $$$)
55
+ ```
56
+
57
+ ---
58
+
59
+ ## API Structure
60
+
61
+ ### Production Endpoints (`/api/v1/prod`)
62
+ **For real users with Phantom/Solflare/Jelli wallets**
63
+
64
+ ```
65
+ GET /api/v1/prod/game/:gameId
66
+ POST /api/v1/prod/transaction/build/create
67
+ POST /api/v1/prod/transaction/build/join
68
+ POST /api/v1/prod/transaction/build/cast-vote 🗳️ NEW!
69
+ POST /api/v1/prod/transaction/build/distribute-by-vote 🗳️ NEW!
70
+ POST /api/v1/prod/transaction/build/distribute
71
+ POST /api/v1/prod/transaction/submit
72
+ ```
73
+
74
+ ### Demo Endpoints (`/api/v1/demo`)
75
+ **For testing with server-managed wallets (local only)**
76
+
77
+ ```
78
+ GET /api/v1/demo/game/:gameId
79
+ GET /api/v1/demo/wallets
80
+ POST /api/v1/demo/game/create
81
+ POST /api/v1/demo/game/join
82
+ POST /api/v1/demo/game/distribute
83
+ POST /api/v1/demo/vote/cast 🗳️ NEW!
84
+ POST /api/v1/demo/vote/distribute 🗳️ NEW!
85
+ POST /api/v1/demo/airdrop
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Using Production API (Real Wallets)
91
+
92
+ ### 1. Build Create Game Transaction
93
+
94
+ ```bash
95
+ curl -X POST https://dubs-server-dev-55d1fba09a97.herokuapp.com/api/v1/prod/transaction/build/create \
96
+ -H "Content-Type: application/json" \
97
+ -d '{
98
+ "creatorAddress": "YOUR_PHANTOM_WALLET_ADDRESS",
99
+ "buyIn": 0.5,
100
+ "maxPlayers": 4,
101
+ "operatorFee": 10,
102
+ "operatorAddress": "OPTIONAL_OPERATOR_WALLET"
103
+ }'
104
+ ```
105
+
106
+ **Response:**
107
+ ```json
108
+ {
109
+ "success": true,
110
+ "gameId": "a7d4648b-12b8-43db-9029-728496fb0634",
111
+ "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIEPTUQYzFd...",
112
+ "gameAddress": "6KSjVmzu9wKnCojhSvgNoojF9z5Pp3qXEygpJN1ft8rp",
113
+ "instructions": "Sign this transaction with your wallet..."
114
+ }
115
+ ```
116
+
117
+ ### 2. Sign Transaction with Phantom
118
+
119
+ ```javascript
120
+ import { Connection, Transaction } from '@solana/web3.js';
121
+
122
+ // Get unsigned transaction from API response
123
+ const unsignedTxBase64 = response.transaction;
124
+
125
+ // Decode transaction
126
+ const txBuffer = Buffer.from(unsignedTxBase64, 'base64');
127
+ const tx = Transaction.from(txBuffer);
128
+
129
+ // Sign with Phantom
130
+ const signedTx = await window.solana.signTransaction(tx);
131
+
132
+ // Serialize signed transaction
133
+ const signedTxBase64 = signedTx.serialize().toString('base64');
134
+ ```
135
+
136
+ ### 3. Submit Signed Transaction
137
+
138
+ ```bash
139
+ curl -X POST https://dubs-server-dev-55d1fba09a97.herokuapp.com/api/v1/prod/transaction/submit \
140
+ -H "Content-Type: application/json" \
141
+ -d '{
142
+ "signedTransaction": "SIGNED_TX_BASE64_HERE"
143
+ }'
144
+ ```
145
+
146
+ **Response:**
147
+ ```json
148
+ {
149
+ "success": true,
150
+ "transaction": "5m9hH7e2Dc59Y4dVuXsXJCJVbpq8gh2NFGHo6HT5cBMGL4aYPUW2rCcTZuLR2ETY71LXkZGjJBsDh5qzsfUuLMCi",
151
+ "message": "Transaction confirmed on blockchain"
152
+ }
153
+ ```
154
+
155
+ ### 4. View on Solana Explorer
156
+
157
+ ```
158
+ https://explorer.solana.com/tx/YOUR_TX_SIGNATURE?cluster=devnet
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Complete Client Integration Example
164
+
165
+ ### React/Next.js with Phantom
166
+
167
+ ```typescript
168
+ import { useWallet } from '@solana/wallet-adapter-react';
169
+ import { Connection, Transaction } from '@solana/web3.js';
170
+
171
+ const API_BASE = 'https://dubs-server-dev-55d1fba09a97.herokuapp.com';
172
+
173
+ async function createGame() {
174
+ const { publicKey, signTransaction } = useWallet();
175
+
176
+ // Step 1: Build unsigned transaction
177
+ const buildRes = await fetch(`${API_BASE}/api/v1/prod/transaction/build/create`, {
178
+ method: 'POST',
179
+ headers: { 'Content-Type': 'application/json' },
180
+ body: JSON.stringify({
181
+ creatorAddress: publicKey.toString(),
182
+ buyIn: 0.5,
183
+ maxPlayers: 4,
184
+ operatorFee: 10,
185
+ }),
186
+ });
187
+
188
+ const { transaction: unsignedTx, gameId } = await buildRes.json();
189
+
190
+ // Step 2: Decode and sign
191
+ const txBuffer = Buffer.from(unsignedTx, 'base64');
192
+ const tx = Transaction.from(txBuffer);
193
+ const signedTx = await signTransaction(tx);
194
+
195
+ // Step 3: Submit signed transaction
196
+ const submitRes = await fetch(`${API_BASE}/api/v1/prod/transaction/submit`, {
197
+ method: 'POST',
198
+ headers: { 'Content-Type': 'application/json' },
199
+ body: JSON.stringify({
200
+ signedTransaction: signedTx.serialize().toString('base64'),
201
+ }),
202
+ });
203
+
204
+ const result = await submitRes.json();
205
+ console.log('Game created!', { gameId, tx: result.transaction });
206
+
207
+ return gameId;
208
+ }
209
+ ```
210
+
211
+ ### Join Game
212
+
213
+ ```typescript
214
+ async function joinGame(gameId: string) {
215
+ const { publicKey, signTransaction } = useWallet();
216
+
217
+ // Build unsigned transaction
218
+ const buildRes = await fetch(`${API_BASE}/api/v1/prod/transaction/build/join`, {
219
+ method: 'POST',
220
+ headers: { 'Content-Type': 'application/json' },
221
+ body: JSON.stringify({
222
+ playerAddress: publicKey.toString(),
223
+ gameId,
224
+ }),
225
+ });
226
+
227
+ const { transaction } = await buildRes.json();
228
+
229
+ // Sign and submit
230
+ const txBuffer = Buffer.from(transaction, 'base64');
231
+ const tx = Transaction.from(txBuffer);
232
+ const signedTx = await signTransaction(tx);
233
+
234
+ const submitRes = await fetch(`${API_BASE}/api/v1/prod/transaction/submit`, {
235
+ method: 'POST',
236
+ headers: { 'Content-Type': 'application/json' },
237
+ body: JSON.stringify({
238
+ signedTransaction: signedTx.serialize().toString('base64'),
239
+ }),
240
+ });
241
+
242
+ return await submitRes.json();
243
+ }
244
+ ```
245
+
246
+ ### View Game
247
+
248
+ ```typescript
249
+ async function getGameInfo(gameId: string) {
250
+ const res = await fetch(`${API_BASE}/api/v1/prod/game/${gameId}`);
251
+ return await res.json();
252
+ }
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Postman Testing
258
+
259
+ **Import:** `postman/Dubs-API-v1.postman_collection.json`
260
+
261
+ **Update Variables:**
262
+ - `baseUrl`: `https://dubs-server-dev-55d1fba09a97.herokuapp.com` (for devnet)
263
+ - `gameId`: Auto-saved after creating game
264
+
265
+ **Test Flow:**
266
+ 1. Production API → Build Create Game Transaction
267
+ 2. (Sign with Phantom - do this manually or in your app)
268
+ 3. Production API → Submit Signed Transaction
269
+ 4. Production API → Get Game Info
270
+
271
+ ---
272
+
273
+ ## Environment Variables
274
+
275
+ ### Required:
276
+ ```bash
277
+ SOLANA_NETWORK=https://api.devnet.solana.com # or mainnet-beta
278
+ PROGRAM_ID=8DJTkgk6MDr6tPtw4v2VzYAz9WWvmCg6786vZrEK3o5q
279
+ ```
280
+
281
+ ### Optional:
282
+ ```bash
283
+ PORT=3001 # Heroku sets this automatically
284
+ ```
285
+
286
+ ### Set on Heroku:
287
+ ```bash
288
+ heroku config:set SOLANA_NETWORK=https://api.devnet.solana.com -a dubs-server-dev
289
+ heroku config:set PROGRAM_ID=8DJTkgk6MDr6tPtw4v2VzYAz9WWvmCg6786vZrEK3o5q -a dubs-server-dev
290
+ ```
291
+
292
+ ---
293
+
294
+ ## Deployment
295
+
296
+ ### Devnet (Current)
297
+
298
+ ```bash
299
+ # Already deployed!
300
+ # URL: https://dubs-server-dev-55d1fba09a97.herokuapp.com
301
+ ```
302
+
303
+ To redeploy:
304
+ ```bash
305
+ git add .
306
+ git commit -m "Update"
307
+ git push heroku-dev main
308
+ ```
309
+
310
+ ### Mainnet (Future)
311
+
312
+ ```bash
313
+ # 1. Deploy Solana program to mainnet
314
+ cd ../dubs
315
+ solana program deploy target/deploy/hello_world.so --url mainnet-beta
316
+
317
+ # 2. Create Heroku app for mainnet
318
+ heroku apps:create dubs-api-prod --team dubs
319
+
320
+ # 3. Add remote
321
+ git remote add heroku-prod https://git.heroku.com/dubs-api-prod.git
322
+
323
+ # 4. Configure for mainnet
324
+ heroku config:set SOLANA_NETWORK=https://api.mainnet-beta.solana.com -a dubs-api-prod
325
+ heroku config:set PROGRAM_ID=8DJTkgk6MDr6tPtw4v2VzYAz9WWvmCg6786vZrEK3o5q -a dubs-api-prod
326
+
327
+ # 5. Deploy
328
+ git push heroku-prod main
329
+ ```
330
+
331
+ ---
332
+
333
+ ## Features
334
+
335
+ ✅ **UUID Game IDs** - Professional, unique identifiers
336
+ ✅ **Address-Based Winners** - No confusing indices
337
+ ✅ **Multi-Game Support** - Unlimited simultaneous games
338
+ ✅ **Operator Fees** - Built-in monetization (0-100%)
339
+ ✅ **Multi-Winner Payouts** - Equal or custom splits
340
+ ✅ **3 Game Modes** - Manual, Democratic, Referee ⚖️ (NEW!)
341
+ ✅ **Democratic Voting** - 🗳️ Players vote for winners
342
+ ✅ **Majority Rules** - 🗳️ 50%+ players decide outcome
343
+ ✅ **Referee System** - ⚖️ Expert judges earn commission (NEW!)
344
+ ✅ **Trustless Distribution** - Anyone can trigger when ready
345
+ ✅ **Clean API** - Versioned (`/api/v1/`)
346
+ ✅ **Dual Mode** - Production & Demo endpoints
347
+ ✅ **Heroku Ready** - One-command deploy
348
+
349
+ ---
350
+
351
+ ## API Endpoints Summary
352
+
353
+ ### Production (Real Wallets):
354
+ - Build unsigned transactions
355
+ - Client signs with wallet
356
+ - Submit to blockchain
357
+
358
+ ### Demo (Server-Managed):
359
+ - Server creates & signs
360
+ - Easy testing
361
+ - Local development only
362
+
363
+ ---
364
+
365
+ ## Tech Stack
366
+
367
+ - **Node.js**: 20.x
368
+ - **Express**: 4.18.2
369
+ - **@solana/web3.js**: 1.95.8
370
+ - **Solana Program**: Anchor 0.29.0, Rust 1.88.0
371
+
372
+ ---
373
+
374
+ ## 🗳️ Democratic Voting System (NEW!)
375
+
376
+ ### Overview
377
+
378
+ Games can now be created with **democratic voting** enabled! Players vote for winners, and the smart contract automatically tallies votes and distributes prizes based on majority rules.
379
+
380
+ ### How It Works
381
+
382
+ 1. **Create Game with Voting:**
383
+ ```json
384
+ {
385
+ "creatorAddress": "...",
386
+ "buyIn": 0.5,
387
+ "maxPlayers": 4,
388
+ "votingEnabled": true ← Enable voting!
389
+ }
390
+ ```
391
+
392
+ 2. **Players Join:**
393
+ - Standard join flow
394
+ - All players can vote
395
+
396
+ 3. **Players Vote:**
397
+ ```json
398
+ POST /api/v1/prod/transaction/build/cast-vote
399
+ {
400
+ "voterAddress": "PlayerAddress",
401
+ "gameId": "uuid",
402
+ "votedFor": "AnotherPlayerAddress"
403
+ }
404
+ ```
405
+
406
+ 4. **Check Voting Progress:**
407
+ ```json
408
+ GET /api/v1/prod/game/:gameId
409
+
410
+ Response includes:
411
+ {
412
+ "votes": [
413
+ {"voter": "Player1", "votedFor": "Player2"},
414
+ {"voter": "Player2", "votedFor": "Player2"}
415
+ ],
416
+ "votingEnabled": true
417
+ }
418
+ ```
419
+
420
+ 5. **Distribute by Vote (When Majority Reached):**
421
+ ```json
422
+ POST /api/v1/prod/transaction/build/distribute-by-vote
423
+ {
424
+ "creatorAddress": "...",
425
+ "gameId": "uuid"
426
+ }
427
+ ```
428
+
429
+ ### Majority Rules
430
+
431
+ ```
432
+ Total Players: 3 → Need 2 votes (majority)
433
+ Total Players: 4 → Need 3 votes (majority)
434
+ Total Players: 2 → Need 2 votes (both)
435
+ ```
436
+
437
+ **Formula:** `(total_players / 2) + 1`
438
+
439
+ ### Tie Handling
440
+
441
+ If multiple players tied for most votes:
442
+ - Prize split equally among tied winners
443
+ - Example: 2-way tie → 50/50 split
444
+
445
+ ### Vote Changes
446
+
447
+ - ✅ Players can change votes before majority
448
+ - ✅ Latest vote overwrites previous vote
449
+ - ✅ All votes stored on-chain
450
+
451
+ ---
452
+
453
+ ## What's Next
454
+
455
+ ### Phase 6: Advanced Voting Features
456
+
457
+ - Time-based voting deadlines
458
+ - Weighted voting (based on buy-in multiples)
459
+ - Anonymous voting
460
+ - Vote delegation
461
+
462
+ ---
463
+
464
+ ## Support
465
+
466
+ - **Documentation**: See `DUBS-PROJECT.md` in parent directory
467
+ - **Postman Collection**: Import `postman/Dubs-API-v1-With-Voting.postman_collection.json`
468
+ - **Voting Guide**: See `postman/VOTING_API_GUIDE.md`
469
+ - **Referee Mode**: See `REFEREE_MODE_GUIDE.md` ⚖️ (NEW!)
470
+ - **CLI Tool**: Run `npm run cli` for interactive testing
471
+ - **Issues**: Check Heroku logs with `heroku logs --tail -a dubs-server-dev`
472
+
473
+ ---
474
+
475
+ **Built with ❤️ on Solana**
476
+