@levrbet/shared 0.2.45 → 0.2.47

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.
package/README.md CHANGED
@@ -5,15 +5,43 @@ Shared utilities, components, and types for the LEVR platform.
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @levrbet/shared
8
+ npm install @levrbet/shared @prisma/client prisma
9
9
  ```
10
10
 
11
+ ## Prisma Setup
12
+
13
+ This package includes a Prisma schema. After installation, run the setup script to generate the Prisma client:
14
+
15
+ ```bash
16
+ npx levrbet-prisma-setup
17
+ ```
18
+
19
+ Or add it to your `postinstall` script in `package.json`:
20
+
21
+ ```json
22
+ {
23
+ "scripts": {
24
+ "postinstall": "levrbet-prisma-setup"
25
+ }
26
+ }
27
+ ```
28
+
29
+ This will:
30
+
31
+ 1. Copy the Prisma schema to your project's `prisma/` folder.
32
+ 2. Generate the `@prisma/client` in your `node_modules`
33
+
11
34
  ## Usage
12
35
 
13
36
  ```typescript
14
37
  // Core utilities (universal - works in both browser and Node.js)
15
38
  import { e18, LevrBaseMarket } from "@levrbet/shared/core"
16
39
 
40
+ // Prisma types and client (requires running prisma setup first)
41
+ import { PrismaClient, GamePhase, MarketStatus } from "@levrbet/shared/core"
42
+ // Or directly from @prisma/client
43
+ import { PrismaClient, GamePhase } from "@prisma/client"
44
+
17
45
  // Server-only utilities
18
46
  import { authMiddleWare, validateApiKey } from "@levrbet/shared/server"
19
47
 
@@ -23,68 +51,39 @@ import { useAuth } from "@levrbet/shared/react"
23
51
 
24
52
  ## Package Structure
25
53
 
26
- - **`/core`** - Blockchain contracts, types, and universal utilities
27
- - **`/server`** - Node.js server utilities (auth, database, logging, middleware)
28
- - **`/react`** - React components and hooks
29
-
30
- ## Module Formats
31
-
32
- This package provides **dual builds** for maximum compatibility:
54
+ - **`/core`** - Blockchain contracts, types, Prisma re-exports, and universal utilities
55
+ - **`/server`** - Node.js server utilities (auth, database, logging, middleware)
56
+ - **`/react`** - React components and hooks
33
57
 
34
- - **ESM** (`dist/esm/`) - For React/Vite consumers (preserves React context)
35
- - **CommonJS** (`dist/cjs/`) - For Node.js servers
58
+ ## Peer Dependencies
36
59
 
37
- Both formats are automatically selected based on how you import:
60
+ This package requires the following peer dependencies:
38
61
 
39
- ```javascript
40
- // ESM (React/Vite)
41
- import { e18 } from "@levrbet/shared/core"
42
-
43
- // CommonJS (Node.js servers)
44
- const { e18 } = require("@levrbet/shared/core")
45
- ```
46
-
47
- ### TypeScript Configuration
48
-
49
- **React/Vite consumers** - Use bundler resolution:
50
-
51
- ```json
52
- {
53
- "compilerOptions": {
54
- "moduleResolution": "bundler"
55
- }
56
- }
57
- ```
58
-
59
- **Node.js servers** - Use classic resolution:
60
-
61
- ```json
62
- {
63
- "compilerOptions": {
64
- "module": "CommonJS",
65
- "moduleResolution": "node",
66
- "esModuleInterop": true
67
- }
68
- }
69
- ```
62
+ | Package | Required For |
63
+ | ----------------------- | ---------------------------- |
64
+ | `@prisma/client` | Database types and client |
65
+ | `prisma` | Generating the Prisma client |
66
+ | `react` | React hooks (optional) |
67
+ | `@tanstack/react-query` | React query hooks (optional) |
68
+ | `@privy-io/react-auth` | Privy auth hooks (optional) |
70
69
 
71
70
  ## Development
72
71
 
73
72
  ```bash
74
73
  npm install # Install dependencies
75
74
  npm run build # Build package
76
- npm run watch # Watch mode
75
+ npm run dev # Build and pack for local testing
77
76
  ```
78
77
 
79
78
  ### Local Testing
80
79
 
81
80
  ```bash
82
81
  # In this package
83
- npm run dev
84
- npm link
82
+ npm run dev # Creates a .tgz file
85
83
 
86
84
  # In consumer project
87
- npm link @levrbet/shared
85
+ npm install /path/to/levr-shared/*.tgz
86
+ npx levrbet-prisma-setup
88
87
  ```
89
88
 
90
89
  ## License
@@ -1 +1 @@
1
- export * from "./generated";
1
+ export * from "@prisma/client";
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
- // Core exports Prisma types and enums for browser/React consumers
3
- // The ESM build uses a custom generated wrapper (pure ESM enums)
4
- // The CJS build (server) gets the full client
2
+ // Re-export everything from the Prisma client
3
+ // This allows consumers to import from "@levrbet/shared/core" instead of "@prisma/client"
4
+ //
5
+ // Note: Consumers must run `levrbet-setup-prisma` (postinstall) to generate the Prisma client
6
+ // PrismaClient requires Node.js runtime and won't work in browsers.
7
+ // Browser/React consumers should only use types and enums.
5
8
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
9
  if (k2 === undefined) k2 = k;
7
10
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -17,5 +20,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
20
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
21
  };
19
22
  Object.defineProperty(exports, "__esModule", { value: true });
20
- __exportStar(require("./generated"), exports);
23
+ __exportStar(require("@prisma/client"), exports);
21
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/prisma/index.ts"],"names":[],"mappings":";AAAA,kEAAkE;AAClE,iEAAiE;AACjE,8CAA8C;;;;;;;;;;;;;;;;AAE9C,8CAA2B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/prisma/index.ts"],"names":[],"mappings":";AAAA,8CAA8C;AAC9C,0FAA0F;AAC1F,EAAE;AACF,8FAA8F;AAC9F,oEAAoE;AACpE,2DAA2D;;;;;;;;;;;;;;;;AAE3D,iDAA8B"}
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  // Main entry point - exports everything from core by default
18
18
  __exportStar(require("./core"), exports);
19
- // Note: Server and React modules should be imported via specific paths:
19
+ // Note: Server and React modules should be imported via specific paths:..
20
20
  // import { ... } from "@levrbet/shared/server"
21
21
  // import { ... } from "@levrbet/shared/react"
22
22
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,yCAAsB;AAEtB,wEAAwE;AAExE,+CAA+C;AAC/C,8CAA8C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,yCAAsB;AAEtB,0EAA0E;AAE1E,+CAA+C;AAC/C,8CAA8C"}
@@ -4,7 +4,6 @@ export * from "./contracts";
4
4
  export * from "./liquidation-engine";
5
5
  export * from "./middleware";
6
6
  export * from "./oracle";
7
- export * from "./prisma";
8
7
  export * from "./repositories";
9
8
  export * from "./services";
10
9
  export * from "./types";
@@ -26,7 +26,6 @@ __exportStar(require("./contracts"), exports);
26
26
  __exportStar(require("./liquidation-engine"), exports);
27
27
  __exportStar(require("./middleware"), exports);
28
28
  __exportStar(require("./oracle"), exports);
29
- __exportStar(require("./prisma"), exports);
30
29
  __exportStar(require("./repositories"), exports);
31
30
  __exportStar(require("./services"), exports);
32
31
  __exportStar(require("./types"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iFAAiF;AACjF,IAAI,OAAQ,UAAkB,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;IACpD,MAAM,IAAI,KAAK,CACX,0EAA0E;QACtE,0GAA0G;QAC1G,kFAAkF,CACzF,CAAA;AACL,CAAC;AAED,0CAAuB;AACvB,2CAAwB;AACxB,8CAA2B;AAC3B,uDAAoC;AACpC,+CAA4B;AAC5B,2CAAwB;AACxB,2CAAwB;AACxB,iDAA8B;AAC9B,6CAA0B;AAC1B,0CAAuB;AACvB,0CAAuB;AAEvB,0CAA0C;AAC1C,6DAA6D"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iFAAiF;AACjF,IAAI,OAAQ,UAAkB,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;IACpD,MAAM,IAAI,KAAK,CACX,0EAA0E;QACtE,0GAA0G;QAC1G,kFAAkF,CACzF,CAAA;AACL,CAAC;AAED,0CAAuB;AACvB,2CAAwB;AACxB,8CAA2B;AAC3B,uDAAoC;AACpC,+CAA4B;AAC5B,2CAAwB;AACxB,iDAA8B;AAC9B,6CAA0B;AAC1B,0CAAuB;AACvB,0CAAuB;AAEvB,0CAA0C;AAC1C,6DAA6D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levrbet/shared",
3
- "version": "0.2.45",
3
+ "version": "0.2.47",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -26,8 +26,13 @@
26
26
  }
27
27
  },
28
28
  "files": [
29
- "dist"
29
+ "dist",
30
+ "prisma/schema.prisma",
31
+ "scripts"
30
32
  ],
33
+ "bin": {
34
+ "levrbet-prisma-setup": "./scripts/setup-prisma.js"
35
+ },
31
36
  "sideEffects": false,
32
37
  "scripts": {
33
38
  "build": "npm run clean && npx tsc",
@@ -0,0 +1,464 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ binaryTargets = ["native"]
4
+ }
5
+
6
+ datasource db {
7
+ provider = "mongodb"
8
+ url = env("MONGO_URI")
9
+ }
10
+
11
+ enum GamePhase {
12
+ PreGame
13
+ LiveGame
14
+ PostGame
15
+ Cancelled
16
+ }
17
+
18
+ enum Sides {
19
+ A
20
+ B
21
+ C
22
+ }
23
+
24
+ enum MarketTypes {
25
+ FullTimeWinner
26
+ OverUnder
27
+ }
28
+
29
+ enum MarketStatus {
30
+ Open
31
+ Closed
32
+ Settled
33
+ Refunded
34
+ }
35
+
36
+ enum ScoringType {
37
+ Points
38
+ Goals
39
+ }
40
+
41
+ enum FixtureStatus {
42
+ Scheduled
43
+ Cancelled
44
+ }
45
+
46
+ enum SportGroup {
47
+ Football
48
+ Basketball
49
+ Baseball
50
+ Soccer
51
+ }
52
+
53
+ enum LevrService {
54
+ Auth
55
+ Orderbook
56
+ OracleCore
57
+ OraclePeriphery
58
+ OracleProcessor
59
+ Leaderboard
60
+ Lab
61
+ }
62
+
63
+ model Provider {
64
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
65
+ name String @unique
66
+ providerUrl String @unique
67
+
68
+ createdAt DateTime @default(now())
69
+ updatedAt DateTime @updatedAt
70
+ }
71
+
72
+ model Tournament {
73
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
74
+ levrTournamentId String @unique
75
+ chainId Int
76
+ name String
77
+ description String
78
+ bannerUrl String
79
+ startDate DateTime
80
+ endDate DateTime
81
+
82
+ games LevrGame[]
83
+ leagues League[]
84
+
85
+ createdAt DateTime @default(now())
86
+ updatedAt DateTime @updatedAt
87
+
88
+ @@unique([chainId, name])
89
+ @@unique([chainId, description])
90
+ @@unique([chainId, bannerUrl])
91
+ @@index([name])
92
+ }
93
+
94
+ model Sport {
95
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
96
+ levrSportId String @unique
97
+ name String @unique
98
+ periodType String
99
+ scoringType ScoringType
100
+ standardDurationMs Int
101
+ standardPeriods Int
102
+ periodDuration Int?
103
+ hasDrawMarket Boolean
104
+ sportGroup SportGroup
105
+
106
+ leagues League[]
107
+
108
+ createdAt DateTime @default(now())
109
+ updatedAt DateTime @updatedAt
110
+ }
111
+
112
+ model League {
113
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
114
+ name String @unique
115
+ abbreviation String
116
+ country String
117
+ levrLeagueId String @unique
118
+ opticOddsLeagueId String @unique
119
+ lsportsLeagueId String @unique
120
+ logoKey String
121
+ logoUrl String
122
+
123
+ tournamentObjectId String @db.ObjectId
124
+ tournament Tournament @relation(fields: [tournamentObjectId], references: [objectId])
125
+ sportObjectId String @db.ObjectId
126
+ sport Sport @relation(fields: [sportObjectId], references: [objectId])
127
+ levrSportId String
128
+
129
+ games LevrGame[]
130
+ fixtures Fixture[]
131
+ teams TeamData[]
132
+
133
+ createdAt DateTime @default(now())
134
+ updatedAt DateTime @updatedAt
135
+ }
136
+
137
+ model TeamData {
138
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
139
+ levrTeamName String
140
+ levrTeamOfficialAbbreviation String
141
+ lsportsTeamName String
142
+ opticOddsTeamName String
143
+ lsportsTeamId String @unique
144
+ opticOddsTeamId String @unique
145
+ levrTeamId String @unique
146
+ opticOddsTeamLogoUrl String @unique
147
+ levrTeamLogoUrlAsHome String @unique
148
+ levrTeamLogoUrlAsAway String @unique
149
+ leagueObjectId String @db.ObjectId
150
+ levrLeagueId String
151
+ league League @relation(fields: [leagueObjectId], references: [objectId])
152
+
153
+ @@unique([levrTeamId, levrTeamName, leagueObjectId])
154
+ }
155
+
156
+ model Fixture {
157
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
158
+ levrFixtureId String @unique
159
+ opticOddsFixtureId String? @unique
160
+ lsportsFixtureId String? @unique
161
+ seasonType String
162
+ venue String
163
+ eventName String
164
+ location String
165
+ venueLocation String
166
+ fixtureDate DateTime
167
+ lastUpdated DateTime
168
+ homeTeam Json
169
+ awayTeam Json
170
+ fixtureStatus FixtureStatus
171
+ registeredChainIds Int[] // list of chain IDs where this fixture is registered
172
+
173
+ leagueObjectId String @db.ObjectId
174
+ league League @relation(fields: [leagueObjectId], references: [objectId])
175
+
176
+ createdAt DateTime @default(now())
177
+ updatedAt DateTime @updatedAt
178
+
179
+ @@index([fixtureDate])
180
+ @@index([leagueObjectId])
181
+ @@index([eventName])
182
+ }
183
+
184
+ model Scores {
185
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
186
+ scoresByPeriodHome Json
187
+ scoresByPeriodAway Json
188
+ totalScoresHome Float
189
+ totalScoresAway Float
190
+ chainId Int
191
+
192
+ gameObjectId String @unique @db.ObjectId
193
+ LevrGame LevrGame @relation(fields: [gameObjectId], references: [objectId])
194
+
195
+ createdAt DateTime @default(now())
196
+ updatedAt DateTime @updatedAt
197
+ }
198
+
199
+ model LevrGame {
200
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
201
+ gameId Int @unique
202
+ txHash String @unique
203
+ chainId Int
204
+ seasonType String
205
+ venue String
206
+ eventName String
207
+ location String
208
+ venueLocation String
209
+ gameClock String
210
+ gameProgressBps Int @default(0)
211
+ paused Boolean @default(false)
212
+ fixtureDate DateTime
213
+ wentLiveAt DateTime?
214
+ homeTeam Json // as defined in sample-data/lever/levr-game.json
215
+ awayTeam Json // as defined in sample-data/lever/levr-game.json
216
+ currentPeriod Int @default(0)
217
+ actualDuration Float @default(0) // in milliseconds
218
+ gamePhase GamePhase @default(PreGame)
219
+ levrFixtureId String
220
+ opticOddsFixtureId String?
221
+ lsportsFixtureId String?
222
+ sportGroup SportGroup
223
+
224
+ tournamentObjectId String @db.ObjectId
225
+ fixtureObjectId String @db.ObjectId
226
+ tournament Tournament @relation(fields: [tournamentObjectId], references: [objectId])
227
+ leagueObjectId String @db.ObjectId
228
+ league League @relation(fields: [leagueObjectId], references: [objectId])
229
+ scores Scores?
230
+
231
+ markets Market[]
232
+
233
+ createdAt DateTime @default(now())
234
+ updatedAt DateTime @updatedAt
235
+
236
+ @@unique([chainId, levrFixtureId])
237
+ @@unique([chainId, gameId])
238
+ @@index([opticOddsFixtureId])
239
+ @@index([lsportsFixtureId])
240
+ @@index([eventName])
241
+ @@index([fixtureDate])
242
+ }
243
+
244
+ model Odds {
245
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
246
+ txHash String
247
+ odds Json // define for the specific market type
248
+ prices Json
249
+ timestamp DateTime
250
+ marketType MarketTypes
251
+ details Json? // the unique details for the odds
252
+ gamePhase GamePhase
253
+ gamePeriod Int
254
+ gameClock Int
255
+ chainId Int
256
+ marketPhase MarketStatus
257
+
258
+ levrGameObjectId String @db.ObjectId
259
+ marketObjectId String @db.ObjectId
260
+ gameMarketId String
261
+ market Market @relation(fields: [marketObjectId], references: [objectId])
262
+
263
+ createdAt DateTime @default(now())
264
+ updatedAt DateTime @updatedAt
265
+ }
266
+
267
+ model Market {
268
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
269
+ chainId Int
270
+ gameId Int
271
+ levrMarketId String
272
+ levrMarketContract String
273
+ gameMarketId String @unique
274
+ txHash String
275
+ maturedAt DateTime?
276
+ leveraged Boolean @default(false)
277
+ isMatured Boolean @default(false)
278
+ normalizationFactor Float
279
+ marketDetails Json
280
+ marketRiskAllocation Json
281
+ providers Json
282
+ activeProvider Json
283
+ marketType MarketTypes
284
+ status MarketStatus
285
+ winner Sides?
286
+
287
+ levrGameObjectId String @db.ObjectId // new unique identifier
288
+ levrGame LevrGame @relation(fields: [levrGameObjectId], references: [objectId])
289
+
290
+ odds Odds[]
291
+
292
+ createdAt DateTime @default(now())
293
+ updatedAt DateTime @updatedAt
294
+ }
295
+
296
+ enum UserOddsPreference {
297
+ American
298
+ Decimal
299
+ European
300
+ }
301
+
302
+ model User {
303
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
304
+ walletAddress String @unique
305
+ userName String @unique
306
+ email String? @unique
307
+ timeZone String @default("UTC")
308
+ preferredTimeZone String? @default("UTC")
309
+ userOddsPreference UserOddsPreference @default(American)
310
+ profileImageUrl String?
311
+ profileImageKey String?
312
+ language String @default("en")
313
+ showRiskWarnings Boolean @default(true)
314
+ showPreTransactionReminders Boolean @default(true)
315
+ twoFactorEnabled Boolean @default(false)
316
+ autoDetectTimeZone Boolean @default(true)
317
+ referralCode String @unique
318
+
319
+ // Inverse relations (these fix your P1012 errors)
320
+ referralsMade Referral[] @relation("ReferrerRelations") // users they referred
321
+ referredBy Referral[] @relation("ReferredRelations") // who referred them
322
+ referralRewards ReferralReward[] @relation("UserRewards") // their reward entries
323
+
324
+ createdAt DateTime @default(now())
325
+ updatedAt DateTime @updatedAt
326
+ }
327
+
328
+ enum ReferralStatus {
329
+ Pending
330
+ Active
331
+ Suspended
332
+ Completed
333
+ }
334
+
335
+ model Referral {
336
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
337
+ referrerId String @db.ObjectId
338
+ referredId String @db.ObjectId
339
+ referralCode String
340
+ referralSource String? // e.g. campaign or link source
341
+ status ReferralStatus @default(Active)
342
+
343
+ // Relations
344
+ referrer User @relation("ReferrerRelations", fields: [referrerId], references: [objectId])
345
+ referred User @relation("ReferredRelations", fields: [referredId], references: [objectId])
346
+
347
+ createdAt DateTime @default(now())
348
+ updatedAt DateTime @updatedAt
349
+
350
+ @@index([referrerId])
351
+ @@index([referredId])
352
+ }
353
+
354
+ model ReferralEpoch {
355
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
356
+ periodId String @unique
357
+ periodStart DateTime
358
+ periodEnd DateTime
359
+ timezone String @default("America/Mexico_City")
360
+ status EpochStatus @default(Active)
361
+
362
+ // On-chain reward info (one root per epoch)
363
+ totalFeesUsd Float?
364
+ rewardPoolUsd Float?
365
+ merkleRoot String?
366
+ merkleTxHash String?
367
+ rootPublishedAt DateTime?
368
+ notes String?
369
+
370
+ ReferralRewards ReferralReward[]
371
+
372
+ createdAt DateTime @default(now())
373
+ updatedAt DateTime @updatedAt
374
+ }
375
+
376
+ enum EpochStatus {
377
+ Active
378
+ Processing
379
+ Completed
380
+ Failed
381
+ }
382
+
383
+ enum ReferralTier {
384
+ T1
385
+ T2
386
+ T3
387
+ }
388
+
389
+ model ReferralReward {
390
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
391
+ userId String @db.ObjectId
392
+ epochId String @db.ObjectId
393
+ periodId String // denormalized for readability (e.g. "2025W45")
394
+
395
+ // --- Aggregates ---
396
+ referredBetVolumeUsd Float @default(0.0)
397
+ referredFeeUsd Float @default(0.0)
398
+ tier ReferralTier @default(T1)
399
+ tierPercentage Float @default(0.025)
400
+
401
+ // --- Payouts ---
402
+ payoutBeforeScaleUsd Float @default(0.0)
403
+ payoutScaledUsd Float @default(0.0)
404
+ payoutTokenUnits String? // token base units (string for precision)
405
+ scaleFactor Float?
406
+
407
+ // --- Claim sync info ---
408
+ isClaimedOnChain Boolean @default(false)
409
+ claimedTxHash String?
410
+ lastSyncedFromChainAt DateTime?
411
+
412
+ createdAt DateTime @default(now())
413
+ updatedAt DateTime @updatedAt
414
+
415
+ // --- Relations ---
416
+ user User @relation("UserRewards", fields: [userId], references: [objectId])
417
+ epoch ReferralEpoch @relation(fields: [epochId], references: [objectId])
418
+
419
+ @@unique([userId, periodId])
420
+ @@index([epochId])
421
+ @@index([userId])
422
+ }
423
+
424
+ enum ApiKeyScope {
425
+ Read
426
+ Write
427
+ }
428
+
429
+ model ApiKey {
430
+ objectId String @id @default(auto()) @map("_id") @db.ObjectId
431
+ apiKeyId String @unique
432
+ userId String
433
+ ethAddress String?
434
+ name String
435
+ ciphertext String
436
+ kmsKeyId String
437
+ service LevrService? // Optional: restrict key to a specific service
438
+ scopes ApiKeyScope[]
439
+ isActive Boolean @default(true)
440
+ expiresAt DateTime?
441
+ lastUsedAt DateTime?
442
+ usageCount Int @default(0)
443
+ createdAt DateTime @default(now())
444
+ updatedAt DateTime @updatedAt
445
+
446
+ @@index([userId, isActive])
447
+ @@index([service, isActive])
448
+ }
449
+
450
+ model AuditLog {
451
+ objectId String @id @default(cuid()) @map("_id")
452
+ action String // e.g., "api_key.created", "application.created", "token.validated"
453
+ resourceId String? // ID of the resource being acted upon
454
+ metadata Json @default("{}")
455
+ ipAddress String?
456
+ userAgent String?
457
+ timestamp DateTime @default(now())
458
+ // Relations
459
+ userId String
460
+
461
+ @@index([action])
462
+ @@index([timestamp])
463
+ @@index([userId])
464
+ }
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * This script sets up Prisma for consumers of @levrbet/shared.
5
+ * It copies the schema.prisma file and generates the Prisma client.
6
+ *
7
+ * Runs automatically on postinstall, or manually via: npx levrbet-prisma-setup
8
+ */
9
+ console.log("\nStarting Prisma setup for @levrbet/shared...\n")
10
+ const { execSync } = require("child_process")
11
+ const fs = require("fs")
12
+ const path = require("path")
13
+
14
+ // Find the consumer's project root (walk up from node_modules/@levrbet/shared)
15
+ function findProjectRoot() {
16
+ let dir = __dirname
17
+
18
+ // Walk up to find the project root (where we exit node_modules)
19
+ while (dir !== path.dirname(dir)) {
20
+ const parentDir = path.dirname(dir)
21
+ const parentName = path.basename(parentDir)
22
+
23
+ // If parent is node_modules, go up one more level to get project root
24
+ if (parentName === "node_modules") {
25
+ return path.dirname(parentDir)
26
+ }
27
+
28
+ // If we find a package.json that's not in node_modules, we're at project root
29
+ const packageJsonPath = path.join(dir, "package.json")
30
+ if (fs.existsSync(packageJsonPath)) {
31
+ try {
32
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"))
33
+ // Make sure it's not our own package
34
+ if (pkg.name !== "@levrbet/shared") {
35
+ return dir
36
+ }
37
+ } catch (e) {
38
+ // Ignore parse errors
39
+ }
40
+ }
41
+
42
+ dir = parentDir
43
+ }
44
+
45
+ // Fallback to current working directory
46
+ return process.cwd()
47
+ }
48
+
49
+ const projectRoot = findProjectRoot()
50
+ const schemaSource = path.join(__dirname, "..", "prisma", "schema.prisma")
51
+ const prismaDir = path.join(projectRoot, "prisma")
52
+ const schemaDest = path.join(prismaDir, "schema.prisma")
53
+
54
+ // Check if we're in the package itself (development mode) - skip setup
55
+ const ownPackageJson = path.join(__dirname, "..", "package.json")
56
+ if (fs.existsSync(ownPackageJson)) {
57
+ try {
58
+ const pkg = JSON.parse(fs.readFileSync(ownPackageJson, "utf8"))
59
+ if (pkg.name === "@levrbet/shared" && projectRoot === path.join(__dirname, "..")) {
60
+ // We're in the package itself during development, skip consumer setup
61
+ console.log("Skipping consumer setup (running in @levrbet/shared development mode)")
62
+ process.exit(0)
63
+ }
64
+ } catch (e) {
65
+ // Ignore
66
+ }
67
+ }
68
+
69
+ console.log("🔧 Setting up Prisma for @levrbet/shared...")
70
+ console.log(` Project root: ${projectRoot}\n`)
71
+
72
+ // Create prisma directory if it doesn't exist
73
+ if (!fs.existsSync(prismaDir)) {
74
+ fs.mkdirSync(prismaDir, { recursive: true })
75
+ console.log("Created prisma/ directory")
76
+ }
77
+
78
+ // Copy schema.prisma
79
+ try {
80
+ fs.copyFileSync(schemaSource, schemaDest)
81
+ console.log("Copied schema.prisma to prisma/schema.prisma")
82
+ } catch (err) {
83
+ console.error("Failed to copy schema.prisma:", err.message)
84
+ process.exit(1)
85
+ }
86
+
87
+ // Generate Prisma client
88
+ console.log("\nGenerating Prisma client...")
89
+ try {
90
+ execSync("npx prisma generate", { stdio: "inherit", cwd: projectRoot })
91
+ console.log("\nPrisma client generated successfully!")
92
+ } catch (err) {
93
+ console.error("\nFailed to generate Prisma client:", err.message)
94
+ process.exit(1)
95
+ }
96
+
97
+ console.log("\nPrisma setup complete!")
98
+ console.log("\nMake sure to set the MONGO_URI environment variable in your .env file.")
@@ -1,2 +0,0 @@
1
- export { Prisma, PrismaClient } from "../../core/prisma/generated";
2
- export * from "../../core/prisma";
@@ -1,24 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.PrismaClient = exports.Prisma = void 0;
18
- // Server exports the full Prisma Client for database operations
19
- var generated_1 = require("../../core/prisma/generated");
20
- Object.defineProperty(exports, "Prisma", { enumerable: true, get: function () { return generated_1.Prisma; } });
21
- Object.defineProperty(exports, "PrismaClient", { enumerable: true, get: function () { return generated_1.PrismaClient; } });
22
- // Re-export all types and enums from core
23
- __exportStar(require("../../core/prisma"), exports);
24
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/prisma/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,gEAAgE;AAChE,yDAAkE;AAAzD,mGAAA,MAAM,OAAA;AAAE,yGAAA,YAAY,OAAA;AAE7B,0CAA0C;AAC1C,oDAAiC"}