@levrbet/shared 0.2.45 → 0.2.46
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 +45 -46
- package/dist/core/prisma/index.d.ts +1 -1
- package/dist/core/prisma/index.js +7 -4
- package/dist/core/prisma/index.js.map +1 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.js +0 -1
- package/dist/server/index.js.map +1 -1
- package/package.json +7 -2
- package/prisma/schema.prisma +464 -0
- package/scripts/setup-prisma.js +98 -0
- package/dist/server/prisma/index.d.ts +0 -2
- package/dist/server/prisma/index.js +0 -24
- package/dist/server/prisma/index.js.map +0 -1
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
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
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
|
-
|
|
35
|
-
- **CommonJS** (`dist/cjs/`) - For Node.js servers
|
|
58
|
+
## Peer Dependencies
|
|
36
59
|
|
|
37
|
-
|
|
60
|
+
This package requires the following peer dependencies:
|
|
38
61
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
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
|
|
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 "
|
|
1
|
+
export * from "@prisma/client";
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
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("
|
|
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,
|
|
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/server/index.d.ts
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -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);
|
package/dist/server/index.js.map
CHANGED
|
@@ -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,
|
|
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.
|
|
3
|
+
"version": "0.2.46",
|
|
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,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"}
|