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,359 @@
1
+ #!/bin/bash
2
+
3
+ # ============================================
4
+ # 🎮 DUBS SERVER - DATABASE SETUP SCRIPT
5
+ # ============================================
6
+ # This script sets up the complete database from scratch
7
+ # Handles PostgreSQL startup, database creation, and schema setup
8
+ # Safe to run multiple times
9
+
10
+ set -e # Exit on error
11
+
12
+ echo "╔════════════════════════════════════════════════╗"
13
+ echo "║ 🎮 DUBS SERVER - DATABASE SETUP 🎮 ║"
14
+ echo "╚════════════════════════════════════════════════╝"
15
+ echo ""
16
+
17
+ # Colors for output
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ BLUE='\033[0;34m'
22
+ NC='\033[0m' # No Color
23
+
24
+ # Configuration
25
+ DB_NAME="${DB_NAME:-dubs_db}"
26
+ DB_USER="${DB_USER:-$(whoami)}"
27
+ DB_HOST="${DB_HOST:-localhost}"
28
+ DB_PORT="${DB_PORT:-5432}"
29
+
30
+ # ============================================
31
+ # 1. CHECK POSTGRESQL
32
+ # ============================================
33
+
34
+ echo "📋 Step 1: Checking PostgreSQL..."
35
+ echo ""
36
+
37
+ # Check if PostgreSQL is installed
38
+ if ! command -v psql &> /dev/null; then
39
+ echo -e "${RED}❌ PostgreSQL is not installed${NC}"
40
+ echo ""
41
+ echo "Install with Homebrew:"
42
+ echo " brew install postgresql@14"
43
+ exit 1
44
+ fi
45
+
46
+ echo -e "${GREEN}✅ PostgreSQL is installed${NC}"
47
+
48
+ # Check if PostgreSQL is running
49
+ if ! pg_isready -h $DB_HOST -p $DB_PORT &> /dev/null; then
50
+ echo -e "${YELLOW}⚠️ PostgreSQL is not running${NC}"
51
+ echo "Starting PostgreSQL..."
52
+
53
+ # Try to start with Homebrew
54
+ if brew services list | grep -q "postgresql@14"; then
55
+ brew services start postgresql@14
56
+ echo "Waiting for PostgreSQL to start..."
57
+ sleep 3
58
+ elif brew services list | grep -q "postgresql"; then
59
+ brew services start postgresql
60
+ echo "Waiting for PostgreSQL to start..."
61
+ sleep 3
62
+ else
63
+ echo -e "${RED}❌ Could not start PostgreSQL${NC}"
64
+ echo "Try manually: brew services start postgresql@14"
65
+ exit 1
66
+ fi
67
+
68
+ # Check again
69
+ if ! pg_isready -h $DB_HOST -p $DB_PORT &> /dev/null; then
70
+ echo -e "${RED}❌ PostgreSQL failed to start${NC}"
71
+ exit 1
72
+ fi
73
+ fi
74
+
75
+ echo -e "${GREEN}✅ PostgreSQL is running${NC}"
76
+ echo ""
77
+
78
+ # ============================================
79
+ # 2. CREATE DATABASE
80
+ # ============================================
81
+
82
+ echo "📋 Step 2: Setting up database..."
83
+ echo ""
84
+
85
+ # Check if database exists
86
+ if psql -lqt | cut -d \| -f 1 | grep -qw $DB_NAME; then
87
+ echo -e "${YELLOW}⚠️ Database '$DB_NAME' already exists${NC}"
88
+ read -p "Do you want to drop and recreate it? (y/N): " -n 1 -r
89
+ echo ""
90
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
91
+ echo "Dropping existing database..."
92
+ dropdb $DB_NAME || true
93
+ echo "Creating new database..."
94
+ createdb $DB_NAME
95
+ echo -e "${GREEN}✅ Database recreated${NC}"
96
+ else
97
+ echo -e "${BLUE}ℹ️ Using existing database (will update schema)${NC}"
98
+ fi
99
+ else
100
+ echo "Creating database '$DB_NAME'..."
101
+ createdb $DB_NAME
102
+ echo -e "${GREEN}✅ Database created${NC}"
103
+ fi
104
+
105
+ echo ""
106
+
107
+ # ============================================
108
+ # 3. RUN SCHEMA SETUP
109
+ # ============================================
110
+
111
+ echo "📋 Step 3: Setting up database schema..."
112
+ echo ""
113
+
114
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
115
+ SQL_FILE="$SCRIPT_DIR/setup-complete-database.sql"
116
+
117
+ if [ ! -f "$SQL_FILE" ]; then
118
+ echo -e "${RED}❌ SQL file not found: $SQL_FILE${NC}"
119
+ exit 1
120
+ fi
121
+
122
+ echo "Running SQL schema setup..."
123
+ psql -d $DB_NAME -f "$SQL_FILE"
124
+
125
+ echo ""
126
+ echo -e "${GREEN}✅ Base schema setup complete${NC}"
127
+ echo ""
128
+
129
+ # ============================================
130
+ # 3B. RUN PREFERRED CURRENCY MIGRATION
131
+ # ============================================
132
+
133
+ echo "📋 Step 3c: Adding preferred_currency support..."
134
+ echo ""
135
+
136
+ PREFERRED_CURRENCY_SQL="$SCRIPT_DIR/add-preferred-currency.sql"
137
+
138
+ if [ -f "$PREFERRED_CURRENCY_SQL" ]; then
139
+ echo "Running preferred_currency migration..."
140
+ psql -d $DB_NAME -f "$PREFERRED_CURRENCY_SQL"
141
+ echo ""
142
+ echo -e "${GREEN}✅ Preferred currency migration complete${NC}"
143
+ else
144
+ echo -e "${YELLOW}⚠️ preferred_currency migration file not found (optional)${NC}"
145
+ echo "File expected at: $PREFERRED_CURRENCY_SQL"
146
+ fi
147
+
148
+ echo ""
149
+
150
+ # ============================================
151
+ # 3D. RUN PENDING GAME DISMISSALS MIGRATION
152
+ # ============================================
153
+
154
+ echo "📋 Step 3d: Adding pending_game_dismissals table..."
155
+ echo ""
156
+
157
+ PENDING_DISMISSALS_SQL="$SCRIPT_DIR/add-pending-game-dismissals.sql"
158
+
159
+ if [ -f "$PENDING_DISMISSALS_SQL" ]; then
160
+ echo "Running pending_game_dismissals migration..."
161
+ psql -d $DB_NAME -f "$PENDING_DISMISSALS_SQL"
162
+ echo ""
163
+ echo -e "${GREEN}✅ Pending game dismissals migration complete${NC}"
164
+ else
165
+ echo -e "${YELLOW}⚠️ pending_game_dismissals migration file not found (optional)${NC}"
166
+ echo "File expected at: $PENDING_DISMISSALS_SQL"
167
+ fi
168
+
169
+ echo ""
170
+
171
+ # ============================================
172
+ # 3E. RUN MATCHUP IMAGE URL MIGRATION
173
+ # ============================================
174
+
175
+ echo "📋 Step 3e: Adding matchup_image_url column to games..."
176
+ echo ""
177
+
178
+ MATCHUP_IMAGE_SQL="$SCRIPT_DIR/migrations/002_add_matchup_image_url.sql"
179
+
180
+ if [ -f "$MATCHUP_IMAGE_SQL" ]; then
181
+ echo "Running matchup_image_url migration..."
182
+ psql -d $DB_NAME -f "$MATCHUP_IMAGE_SQL"
183
+ echo ""
184
+ echo -e "${GREEN}✅ Matchup image URL migration complete${NC}"
185
+ else
186
+ echo -e "${YELLOW}⚠️ matchup_image_url migration file not found (optional)${NC}"
187
+ echo "File expected at: $MATCHUP_IMAGE_SQL"
188
+ fi
189
+
190
+ echo ""
191
+
192
+ # ============================================
193
+ # 3F. RUN REFERRAL EARNINGS MIGRATION
194
+ # ============================================
195
+
196
+ echo "📋 Step 3f: Setting up referral earnings system..."
197
+ echo ""
198
+
199
+ REFERRAL_EARNINGS_SQL="$SCRIPT_DIR/migrations/003_referral_earnings.sql"
200
+
201
+ if [ -f "$REFERRAL_EARNINGS_SQL" ]; then
202
+ echo "Running referral earnings migration..."
203
+ psql -d $DB_NAME -f "$REFERRAL_EARNINGS_SQL"
204
+ echo ""
205
+ echo -e "${GREEN}✅ Referral earnings migration complete${NC}"
206
+ else
207
+ echo -e "${YELLOW}⚠️ referral_earnings migration file not found (optional)${NC}"
208
+ echo "File expected at: $REFERRAL_EARNINGS_SQL"
209
+ fi
210
+
211
+ echo ""
212
+
213
+ # ============================================
214
+ # 3G. RUN WHAT'S NEW TABLES MIGRATION
215
+ # ============================================
216
+
217
+ echo "📋 Step 3g: Setting up What's New tables..."
218
+ echo ""
219
+
220
+ WHATS_NEW_SQL="$SCRIPT_DIR/migrations/create_whats_new_tables.sql"
221
+
222
+ if [ -f "$WHATS_NEW_SQL" ]; then
223
+ echo "Running What's New tables migration..."
224
+ psql -d $DB_NAME -f "$WHATS_NEW_SQL"
225
+ echo ""
226
+ echo -e "${GREEN}✅ What's New tables migration complete${NC}"
227
+ else
228
+ echo -e "${YELLOW}⚠️ What's New tables migration file not found (optional)${NC}"
229
+ echo "File expected at: $WHATS_NEW_SQL"
230
+ fi
231
+
232
+ echo ""
233
+
234
+ # ============================================
235
+ # 3H. RUN WHAT'S NEW NOTIFICATION TYPE MIGRATION
236
+ # ============================================
237
+
238
+ echo "📋 Step 3h: Adding What's New notification type..."
239
+ echo ""
240
+
241
+ WHATS_NEW_NOTIF_SQL="$SCRIPT_DIR/migrations/004_add_whats_new_notification_type.sql"
242
+
243
+ if [ -f "$WHATS_NEW_NOTIF_SQL" ]; then
244
+ echo "Running What's New notification type migration..."
245
+ psql -d $DB_NAME -f "$WHATS_NEW_NOTIF_SQL"
246
+ echo ""
247
+ echo -e "${GREEN}✅ What's New notification type migration complete${NC}"
248
+ else
249
+ echo -e "${YELLOW}⚠️ What's New notification type migration file not found (optional)${NC}"
250
+ echo "File expected at: $WHATS_NEW_NOTIF_SQL"
251
+ fi
252
+
253
+ echo ""
254
+
255
+ # ============================================
256
+ # 4. SETUP .env FILE
257
+ # ============================================
258
+
259
+ echo "📋 Step 4: Checking .env configuration..."
260
+ echo ""
261
+
262
+ ENV_FILE="$SCRIPT_DIR/../.env"
263
+
264
+ if [ ! -f "$ENV_FILE" ]; then
265
+ echo -e "${YELLOW}⚠️ .env file not found${NC}"
266
+ echo "Creating .env file from template..."
267
+
268
+ # Generate JWT secret
269
+ JWT_SECRET=$(openssl rand -hex 32)
270
+
271
+ cat > "$ENV_FILE" << EOF
272
+ # Solana Configuration
273
+ SOLANA_NETWORK=http://127.0.0.1:8899
274
+ PROGRAM_ID=8DJTkgk6MDr6tPtw4v2VzYAz9WWvmCg6786vZrEK3o5q
275
+
276
+ # Server Configuration
277
+ PORT=3001
278
+ NODE_ENV=development
279
+
280
+ # Database Configuration
281
+ DATABASE_URL=postgresql://$DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
282
+
283
+ # Authentication & Security
284
+ JWT_SECRET=$JWT_SECRET
285
+ JWT_EXPIRES_IN=7d
286
+
287
+ # Oracle Configuration
288
+ ORACLE_WALLET_PATH=./wallets/oracle.json
289
+ ORACLE_CHECK_INTERVAL=60000
290
+ NOTIFY_BEFORE_MINUTES=10
291
+
292
+ # API URLs
293
+ LIVE_SCORES_API_URL=http://localhost:3000
294
+ DUBS_GAMES_API_URL=http://localhost:3001
295
+ EOF
296
+
297
+ echo -e "${GREEN}✅ .env file created${NC}"
298
+ else
299
+ echo -e "${GREEN}✅ .env file already exists${NC}"
300
+
301
+ # Check if DATABASE_URL is correct
302
+ if ! grep -q "DATABASE_URL=postgresql://$DB_USER@$DB_HOST:$DB_PORT/$DB_NAME" "$ENV_FILE"; then
303
+ echo -e "${YELLOW}⚠️ DATABASE_URL may need updating${NC}"
304
+ echo "Expected: DATABASE_URL=postgresql://$DB_USER@$DB_HOST:$DB_PORT/$DB_NAME"
305
+ fi
306
+ fi
307
+
308
+ echo ""
309
+
310
+ # ============================================
311
+ # 5. VERIFY SETUP
312
+ # ============================================
313
+
314
+ echo "📋 Step 5: Verifying setup..."
315
+ echo ""
316
+
317
+ # Count tables
318
+ TABLE_COUNT=$(psql -d $DB_NAME -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE';" | xargs)
319
+
320
+ echo "Database: $DB_NAME"
321
+ echo "Tables: $TABLE_COUNT"
322
+ echo ""
323
+
324
+ # Test connection
325
+ if psql -d $DB_NAME -c "SELECT 1" &> /dev/null; then
326
+ echo -e "${GREEN}✅ Database connection successful${NC}"
327
+ else
328
+ echo -e "${RED}❌ Database connection failed${NC}"
329
+ exit 1
330
+ fi
331
+
332
+ echo ""
333
+
334
+ # ============================================
335
+ # 6. SUMMARY
336
+ # ============================================
337
+
338
+ echo "╔════════════════════════════════════════════════╗"
339
+ echo "║ 🎉 SETUP COMPLETE! 🎉 ║"
340
+ echo "╚════════════════════════════════════════════════╝"
341
+ echo ""
342
+ echo -e "${GREEN}✅ PostgreSQL is running${NC}"
343
+ echo -e "${GREEN}✅ Database '$DB_NAME' is ready${NC}"
344
+ echo -e "${GREEN}✅ Schema with $TABLE_COUNT tables created${NC}"
345
+ echo -e "${GREEN}✅ .env file configured${NC}"
346
+ echo ""
347
+ echo "📊 Next steps:"
348
+ echo " 1. Start the server: npm start"
349
+ echo " 2. Test authentication: curl http://localhost:3001/api/v1/auth/nonce/YOUR_WALLET"
350
+ echo ""
351
+ echo "📝 Useful commands:"
352
+ echo " • View tables: psql -d $DB_NAME -c '\\dt'"
353
+ echo " • Drop database: dropdb $DB_NAME"
354
+ echo " • Restart server: npm start"
355
+ echo ""
356
+
357
+
358
+
359
+
@@ -0,0 +1,48 @@
1
+ #!/bin/bash
2
+
3
+ # 🔐 Setup Keeper Wallet on Heroku
4
+ # This script sets the keeper's private key as an environment variable
5
+
6
+ set -e
7
+
8
+ echo "🔐 Setting up Jackpot Keeper on Heroku"
9
+ echo "======================================"
10
+ echo ""
11
+
12
+ # Check if we're in the right directory
13
+ if [ ! -f "server.js" ]; then
14
+ echo "❌ Error: Must run from dubs-server directory"
15
+ exit 1
16
+ fi
17
+
18
+ # Check if oracle wallet exists
19
+ ORACLE_WALLET="wallets/jackpot_oracle.json"
20
+ if [ ! -f "$ORACLE_WALLET" ]; then
21
+ echo "❌ Error: Oracle wallet not found at $ORACLE_WALLET"
22
+ exit 1
23
+ fi
24
+
25
+ # Read the wallet
26
+ PRIVATE_KEY=$(cat "$ORACLE_WALLET")
27
+
28
+ echo "✅ Found oracle wallet"
29
+ echo ""
30
+
31
+ # Escape the JSON for Heroku (remove newlines, escape quotes)
32
+ ESCAPED_KEY=$(echo "$PRIVATE_KEY" | tr -d '\n' | sed 's/"/\\"/g')
33
+
34
+ # Set on Heroku
35
+ echo "📤 Setting KEEPER_PRIVATE_KEY on Heroku..."
36
+ heroku config:set KEEPER_PRIVATE_KEY="$PRIVATE_KEY" -a dubs-server-dev
37
+
38
+ echo ""
39
+ echo "✅ Keeper wallet configured!"
40
+ echo ""
41
+ echo "Wallet address: $(solana-keygen pubkey "$ORACLE_WALLET")"
42
+ echo ""
43
+ echo "Next steps:"
44
+ echo " 1. Deploy code: git push heroku-dev main"
45
+ echo " 2. Scale keeper: heroku ps:scale jackpot-keeper=1 -a dubs-server-dev"
46
+ echo " 3. Check logs: heroku logs --tail --ps jackpot-keeper -a dubs-server-dev"
47
+ echo ""
48
+
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Setup Keeper State Machine Database
5
+ *
6
+ * Run this once to create the necessary tables and views
7
+ */
8
+
9
+ const { Pool } = require('pg');
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+
13
+ async function setup() {
14
+ console.log('🔧 Setting up Keeper State Machine Database...\n');
15
+
16
+ const pool = new Pool({
17
+ connectionString: process.env.DATABASE_URL,
18
+ ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
19
+ });
20
+
21
+ try {
22
+ // Read SQL file
23
+ const sqlPath = path.join(__dirname, 'setup-keeper-state-db.sql');
24
+ const sql = fs.readFileSync(sqlPath, 'utf-8');
25
+
26
+ console.log('📝 Executing schema creation...');
27
+ await pool.query(sql);
28
+
29
+ console.log('✅ Database schema created successfully!\n');
30
+
31
+ // Test the setup
32
+ console.log('🧪 Testing database...');
33
+
34
+ // Test tables exist
35
+ const tablesResult = await pool.query(`
36
+ SELECT table_name
37
+ FROM information_schema.tables
38
+ WHERE table_schema = 'public'
39
+ AND table_name IN ('keeper_rounds', 'keeper_health', 'keeper_actions')
40
+ ORDER BY table_name
41
+ `);
42
+
43
+ console.log(' Tables created:');
44
+ tablesResult.rows.forEach(row => {
45
+ console.log(` ✓ ${row.table_name}`);
46
+ });
47
+
48
+ // Test views exist
49
+ const viewsResult = await pool.query(`
50
+ SELECT table_name
51
+ FROM information_schema.views
52
+ WHERE table_schema = 'public'
53
+ AND table_name IN ('stuck_rounds', 'keeper_health_summary')
54
+ ORDER BY table_name
55
+ `);
56
+
57
+ console.log(' Views created:');
58
+ viewsResult.rows.forEach(row => {
59
+ console.log(` ✓ ${row.table_name}`);
60
+ });
61
+
62
+ console.log('\n✅ Database setup complete!\n');
63
+ console.log('📊 You can now:');
64
+ console.log(' - Start the keeper: node scripts/jackpot-keeper.js');
65
+ console.log(' - View health: curl http://localhost:3001/api/keeper/health');
66
+ console.log(' - View dashboard: curl http://localhost:3001/api/keeper/dashboard');
67
+ console.log(' - View stuck rounds: curl http://localhost:3001/api/keeper/rounds/stuck');
68
+ console.log();
69
+
70
+ } catch (error) {
71
+ console.error('❌ Setup failed:', error.message);
72
+ console.error('\nMake sure:');
73
+ console.error(' 1. DATABASE_URL environment variable is set');
74
+ console.error(' 2. PostgreSQL is running');
75
+ console.error(' 3. You have database permissions');
76
+ process.exit(1);
77
+ } finally {
78
+ await pool.end();
79
+ }
80
+ }
81
+
82
+ setup();
83
+
@@ -0,0 +1,110 @@
1
+ -- Keeper State Machine Database Schema
2
+ -- Tracks every round's lifecycle for reliability and recovery
3
+
4
+ -- Main table tracking round lifecycle
5
+ CREATE TABLE IF NOT EXISTS keeper_rounds (
6
+ round_id BIGINT PRIMARY KEY,
7
+ status VARCHAR(20) NOT NULL, -- 'open', 'locking', 'locked', 'revealing', 'revealed', 'resolving', 'resolved', 'resetting'
8
+
9
+ -- Timestamps for each phase
10
+ created_at TIMESTAMP DEFAULT NOW(),
11
+ locked_at TIMESTAMP,
12
+ revealed_at TIMESTAMP,
13
+ resolved_at TIMESTAMP,
14
+ reset_at TIMESTAMP,
15
+
16
+ -- Retry tracking
17
+ retry_count INTEGER DEFAULT 0,
18
+ last_error TEXT,
19
+ last_attempt_at TIMESTAMP,
20
+
21
+ -- Metadata
22
+ total_pot BIGINT,
23
+ entry_count INTEGER,
24
+ winner_pubkey VARCHAR(44),
25
+ win_amount BIGINT,
26
+
27
+ -- Signatures for verification
28
+ lock_signature VARCHAR(88),
29
+ reveal_signature VARCHAR(88),
30
+ resolve_signature VARCHAR(88),
31
+ reset_signature VARCHAR(88),
32
+
33
+ updated_at TIMESTAMP DEFAULT NOW()
34
+ );
35
+
36
+ -- Index for fast queries
37
+ CREATE INDEX IF NOT EXISTS idx_status ON keeper_rounds(status);
38
+ CREATE INDEX IF NOT EXISTS idx_updated_at ON keeper_rounds(updated_at);
39
+ CREATE INDEX IF NOT EXISTS idx_round_id_status ON keeper_rounds(round_id, status);
40
+
41
+ -- Table for tracking keeper health metrics
42
+ CREATE TABLE IF NOT EXISTS keeper_health (
43
+ id SERIAL PRIMARY KEY,
44
+ timestamp TIMESTAMP DEFAULT NOW(),
45
+ rounds_completed INTEGER,
46
+ consecutive_failures INTEGER,
47
+ last_success_round BIGINT,
48
+ last_error TEXT,
49
+ uptime_seconds INTEGER
50
+ );
51
+
52
+ -- Table for detailed action log (debugging)
53
+ CREATE TABLE IF NOT EXISTS keeper_actions (
54
+ id SERIAL PRIMARY KEY,
55
+ round_id BIGINT NOT NULL,
56
+ action VARCHAR(50) NOT NULL, -- 'lock', 'reveal', 'resolve', 'reset'
57
+ success BOOLEAN NOT NULL,
58
+ error_message TEXT,
59
+ signature VARCHAR(88),
60
+ duration_ms INTEGER,
61
+ timestamp TIMESTAMP DEFAULT NOW()
62
+ );
63
+
64
+ CREATE INDEX IF NOT EXISTS idx_actions_round ON keeper_actions(round_id);
65
+ CREATE INDEX IF NOT EXISTS idx_actions_timestamp ON keeper_actions(timestamp DESC);
66
+
67
+ -- Function to update updated_at timestamp
68
+ CREATE OR REPLACE FUNCTION update_updated_at_column()
69
+ RETURNS TRIGGER AS $$
70
+ BEGIN
71
+ NEW.updated_at = NOW();
72
+ RETURN NEW;
73
+ END;
74
+ $$ language 'plpgsql';
75
+
76
+ -- Trigger to auto-update updated_at
77
+ DROP TRIGGER IF EXISTS update_keeper_rounds_updated_at ON keeper_rounds;
78
+ CREATE TRIGGER update_keeper_rounds_updated_at
79
+ BEFORE UPDATE ON keeper_rounds
80
+ FOR EACH ROW
81
+ EXECUTE FUNCTION update_updated_at_column();
82
+
83
+ -- View for monitoring stuck rounds
84
+ CREATE OR REPLACE VIEW stuck_rounds AS
85
+ SELECT
86
+ round_id,
87
+ status,
88
+ retry_count,
89
+ last_error,
90
+ EXTRACT(EPOCH FROM (NOW() - updated_at)) as seconds_stuck
91
+ FROM keeper_rounds
92
+ WHERE status NOT IN ('resolved', 'open')
93
+ AND updated_at < NOW() - INTERVAL '5 minutes'
94
+ ORDER BY updated_at ASC;
95
+
96
+ -- View for keeper health summary
97
+ CREATE OR REPLACE VIEW keeper_health_summary AS
98
+ SELECT
99
+ COUNT(*) FILTER (WHERE status = 'resolved') as resolved_rounds,
100
+ COUNT(*) FILTER (WHERE status NOT IN ('resolved', 'open')) as stuck_rounds,
101
+ COUNT(*) FILTER (WHERE retry_count > 0) as rounds_with_retries,
102
+ AVG(EXTRACT(EPOCH FROM (resolved_at - created_at))) as avg_completion_seconds,
103
+ MAX(round_id) as latest_round_id,
104
+ MIN(updated_at) FILTER (WHERE status NOT IN ('resolved', 'open')) as oldest_stuck_round_time
105
+ FROM keeper_rounds;
106
+
107
+ COMMENT ON TABLE keeper_rounds IS 'Tracks lifecycle of each jackpot round for keeper state management';
108
+ COMMENT ON TABLE keeper_health IS 'Periodic health check snapshots of keeper performance';
109
+ COMMENT ON TABLE keeper_actions IS 'Detailed log of every keeper action for debugging';
110
+
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+ # Setup Oracle Wallet for Automatic Sports Games
3
+
4
+ echo "🤖 Setting up Oracle Wallet..."
5
+
6
+ WALLETS_DIR="./wallets"
7
+ ORACLE_WALLET="$WALLETS_DIR/oracle.json"
8
+
9
+ # Create wallets directory if it doesn't exist
10
+ mkdir -p $WALLETS_DIR
11
+
12
+ # Check if oracle wallet already exists
13
+ if [ -f "$ORACLE_WALLET" ]; then
14
+ echo "✅ Oracle wallet already exists"
15
+ solana-keygen pubkey $ORACLE_WALLET
16
+ else
17
+ echo "📝 Creating new oracle wallet..."
18
+ solana-keygen new --no-bip39-passphrase -o $ORACLE_WALLET
19
+ echo "✅ Oracle wallet created!"
20
+ fi
21
+
22
+ # Get the public key
23
+ ORACLE_PUBKEY=$(solana-keygen pubkey $ORACLE_WALLET)
24
+ echo ""
25
+ echo "📌 Oracle Public Key: $ORACLE_PUBKEY"
26
+ echo ""
27
+ echo "⚠️ IMPORTANT: When creating automatic games, use this address as the 'oracle' parameter"
28
+ echo ""
29
+ echo "💰 Funding oracle wallet on devnet..."
30
+ solana airdrop 2 $ORACLE_PUBKEY --url devnet
31
+
32
+ echo ""
33
+ echo "✅ Oracle setup complete!"
34
+ echo ""
35
+ echo "Next steps:"
36
+ echo "1. Use this oracle pubkey when creating automatic games"
37
+ echo "2. Start the oracle monitor: npm run oracle:start"
38
+ echo "3. Oracle will automatically resolve games when sports events finish"
39
+