@merkl/api 0.20.45 → 0.20.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.
Files changed (39) hide show
  1. package/dist/database/api/.generated/drizzle/schema.d.ts +44 -1
  2. package/dist/database/api/.generated/drizzle/schema.js +3 -2
  3. package/dist/database/api/.generated/drizzle/schema.ts +3 -2
  4. package/dist/database/api/.generated/edge.js +7 -7
  5. package/dist/database/api/.generated/index-browser.js +9 -1
  6. package/dist/database/api/.generated/index.d.ts +97 -5
  7. package/dist/database/api/.generated/index.js +7 -7
  8. package/dist/database/api/.generated/package.json +1 -1
  9. package/dist/database/api/.generated/schema.prisma +13 -13
  10. package/dist/database/api/.generated/wasm.js +9 -1
  11. package/dist/src/eden/index.d.ts +341 -15
  12. package/dist/src/engine/dynamicData/implementations/Clamm.js +30 -31
  13. package/dist/src/index.d.ts +85 -3
  14. package/dist/src/jobs/update-dynamic-data.js +1 -1
  15. package/dist/src/modules/v4/campaign/campaign.controller.d.ts +3 -0
  16. package/dist/src/modules/v4/campaign/campaign.repository.d.ts +5 -0
  17. package/dist/src/modules/v4/campaign/campaign.service.d.ts +9 -0
  18. package/dist/src/modules/v4/dynamicData/dynamicData.service.js +1 -1
  19. package/dist/src/modules/v4/merklRoot/merklRoot.repository.js +1 -1
  20. package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +80 -0
  21. package/dist/src/modules/v4/opportunity/opportunity.controller.js +16 -3
  22. package/dist/src/modules/v4/opportunity/opportunity.model.d.ts +26 -4
  23. package/dist/src/modules/v4/opportunity/opportunity.model.js +8 -1
  24. package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +16 -40
  25. package/dist/src/modules/v4/opportunity/opportunity.repository.js +72 -181
  26. package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +44 -25
  27. package/dist/src/modules/v4/opportunity/opportunity.service.js +15 -33
  28. package/dist/src/modules/v4/programPayload/programPayload.repository.js +9 -3
  29. package/dist/src/modules/v4/protocol/protocol.repository.d.ts +1 -0
  30. package/dist/src/modules/v4/reward/reward.repository.d.ts +1 -0
  31. package/dist/src/modules/v4/reward/reward.service.d.ts +7 -0
  32. package/dist/src/modules/v4/router.d.ts +85 -3
  33. package/dist/src/modules/v4/token/token.controller.d.ts +0 -3
  34. package/dist/src/modules/v4/token/token.model.d.ts +0 -3
  35. package/dist/src/modules/v4/token/token.model.js +0 -1
  36. package/dist/src/modules/v4/token/token.service.js +5 -5
  37. package/dist/src/modules/v4/user/user.controller.d.ts +2 -0
  38. package/dist/tsconfig.package.tsbuildinfo +1 -1
  39. package/package.json +1 -1
@@ -13,7 +13,7 @@ import type { OpportunityRepository } from "./opportunity.repository";
13
13
  * @description Target description of rewards campaigns
14
14
  * @see {@link Resource}
15
15
  */
16
- export type Opportunity = Resource<"Opportunity", "mainProtocolId", {
16
+ export type Opportunity = Resource<"Opportunity", "mainProtocolId" | "manualOverrides", {
17
17
  depositUrl?: string;
18
18
  explorerAddress?: string;
19
19
  chain: Chain["model"];
@@ -351,12 +351,34 @@ export declare const UpdateOpportunityDto: import("@sinclair/typebox").TObject<{
351
351
  SOON: "SOON";
352
352
  }>>;
353
353
  }>;
354
+ export declare const OpportunityOverrideDto: import("@sinclair/typebox").TObject<{
355
+ name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
356
+ depositUrl: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
357
+ explorerAddress: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
358
+ action: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TEnum<{
359
+ POOL: "POOL";
360
+ HOLD: "HOLD";
361
+ DROP: "DROP";
362
+ LEND: "LEND";
363
+ BORROW: "BORROW";
364
+ LONG: "LONG";
365
+ SHORT: "SHORT";
366
+ SWAP: "SWAP";
367
+ INVALID: "INVALID";
368
+ }>>;
369
+ }>;
370
+ export declare const OpportunityDeleteOverrideDto: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TEnum<{
371
+ name: "name";
372
+ depositUrl: "depositUrl";
373
+ explorerAddress: "explorerAddress";
374
+ action: "action";
375
+ }>>;
354
376
  export type GetOpportunitiesQueryModel = typeof GetOpportunitiesQueryDto.static;
355
377
  export type GetOpportunityQueryModel = typeof GetOpportunityQueryDto.static;
356
- export type CreateOpportunityModel = typeof CreateOpportunityDto.static & {
357
- id: string;
358
- };
378
+ export type CreateOpportunityModel = typeof CreateOpportunityDto.static;
359
379
  export type OpportunityAggregateField = typeof OpportunityAggregateFieldDto.static;
360
380
  export type UpdateOpportunityModel = typeof UpdateOpportunityDto.static;
361
381
  export type OpportunityResourceModel = typeof OpportunityResourceDto.static;
362
382
  export type OpportunityWithCampaignsResourceModel = typeof OpportunityWithCampaignsResourceDto.static;
383
+ export type OpportunityOverrideModel = typeof OpportunityOverrideDto.static;
384
+ export type OpportunityDeleteOverrideModel = typeof OpportunityDeleteOverrideDto.static;
@@ -4,7 +4,7 @@ import { ProtocolResourceDto } from "@/modules/v4/protocol/protocol.model";
4
4
  import { DailyRewardsRecordResourceDto } from "@/modules/v4/reward/reward.model";
5
5
  import { TokenDto, TokenResourceDto } from "@/modules/v4/token/token.model";
6
6
  import { TvlRecordResourceDto } from "@/modules/v4/tvl/tvl.model";
7
- import { OpportunityAction, Status } from "@db/api";
7
+ import { OpportunityAction, OpportunityManualOverride, Status } from "@db/api";
8
8
  import { t } from "elysia";
9
9
  import { ChainResourceDto } from "../chain/chain.model";
10
10
  // ─── DTOs ────────────────────────────────────────────────────────────────────
@@ -113,3 +113,10 @@ export const UpdateOpportunityDto = t.Object({
113
113
  tags: t.Optional(t.Array(t.String())),
114
114
  status: t.Optional(t.Enum(Status)),
115
115
  });
116
+ export const OpportunityOverrideDto = t.Object({
117
+ name: t.Optional(t.String()),
118
+ depositUrl: t.Optional(t.String({ format: "uri" })),
119
+ explorerAddress: t.Optional(t.String({ format: "uri" })),
120
+ action: t.Optional(t.Enum(OpportunityAction)),
121
+ });
122
+ export const OpportunityDeleteOverrideDto = t.Array(t.Enum(OpportunityManualOverride));
@@ -7,7 +7,9 @@ import { type TvlRecord } from "../tvl";
7
7
  import type { CreateOpportunityModel, GetOpportunitiesQueryModel, Opportunity, UpdateOpportunityModel } from "./opportunity.model";
8
8
  export declare abstract class OpportunityRepository {
9
9
  #private;
10
- static create(newOpp: CreateOpportunityModel, upsert?: boolean): Promise<{
10
+ static create(newOpp: CreateOpportunityModel & {
11
+ id: string;
12
+ }, upsert?: boolean): Promise<{
11
13
  id: string;
12
14
  name: string;
13
15
  type: string;
@@ -15,6 +17,7 @@ export declare abstract class OpportunityRepository {
15
17
  tags: string[];
16
18
  identifier: string;
17
19
  action: import("@db/api").$Enums.OpportunityAction;
20
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
18
21
  chainId: number;
19
22
  depositUrl: string | null;
20
23
  explorerAddress: string | null;
@@ -171,6 +174,7 @@ export declare abstract class OpportunityRepository {
171
174
  tags: string[];
172
175
  identifier: string;
173
176
  action: import("@db/api").$Enums.OpportunityAction;
177
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
174
178
  chainId: number;
175
179
  depositUrl: string | null;
176
180
  explorerAddress: string | null;
@@ -311,6 +315,7 @@ export declare abstract class OpportunityRepository {
311
315
  tags: string[];
312
316
  identifier: string;
313
317
  action: import("@db/api").$Enums.OpportunityAction;
318
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
314
319
  chainId: number;
315
320
  depositUrl: string | null;
316
321
  explorerAddress: string | null;
@@ -509,6 +514,7 @@ export declare abstract class OpportunityRepository {
509
514
  tags: string[];
510
515
  identifier: string;
511
516
  action: import("@db/api").$Enums.OpportunityAction;
517
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
512
518
  chainId: number;
513
519
  depositUrl: string | null;
514
520
  explorerAddress: string | null;
@@ -656,6 +662,7 @@ export declare abstract class OpportunityRepository {
656
662
  tags: string[];
657
663
  identifier: string;
658
664
  action: import("@db/api").$Enums.OpportunityAction;
665
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
659
666
  chainId: number;
660
667
  depositUrl: string | null;
661
668
  explorerAddress: string | null;
@@ -855,6 +862,7 @@ export declare abstract class OpportunityRepository {
855
862
  tags: string[];
856
863
  identifier: string;
857
864
  action: import("@db/api").$Enums.OpportunityAction;
865
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
858
866
  chainId: number;
859
867
  depositUrl: string | null;
860
868
  explorerAddress: string | null;
@@ -864,17 +872,14 @@ export declare abstract class OpportunityRepository {
864
872
  dailyRewards: number;
865
873
  })[]>;
866
874
  static countMany(query: GetOpportunitiesQueryModel): Promise<number>;
867
- static getAllIdsForDynamicOpp(): Promise<{
868
- id: string;
869
- }[]>;
870
875
  /**
871
- * Updates Apr, Tvl and DailyRewards record
876
+ * Updates Apr, Tvl and DailyRewards records
872
877
  * @param opportunityId
873
878
  * @param apr
874
879
  * @param tvl
875
880
  * @returns
876
881
  */
877
- static updateRecords(opportunityId: string, apr: AprRecord["model"], tvl: TvlRecord["model"], dailyRewards: DailyRewardsRecord["model"]): Promise<{
882
+ static updateDynamicData(opportunityId: string, apr: AprRecord["model"], tvl: TvlRecord["model"], dailyRewards: DailyRewardsRecord["model"]): Promise<{
878
883
  aprRecord: false | {
879
884
  id: string;
880
885
  opportunityId: string;
@@ -916,6 +921,7 @@ export declare abstract class OpportunityRepository {
916
921
  tags: string[];
917
922
  identifier: string;
918
923
  action: import("@db/api").$Enums.OpportunityAction;
924
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
919
925
  chainId: number;
920
926
  depositUrl: string | null;
921
927
  explorerAddress: string | null;
@@ -933,6 +939,7 @@ export declare abstract class OpportunityRepository {
933
939
  tags: string[];
934
940
  identifier: string;
935
941
  action: import("@db/api").$Enums.OpportunityAction;
942
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
936
943
  chainId: number;
937
944
  depositUrl: string | null;
938
945
  explorerAddress: string | null;
@@ -941,23 +948,7 @@ export declare abstract class OpportunityRepository {
941
948
  apr: number;
942
949
  dailyRewards: number;
943
950
  }>;
944
- static updateName(id: string, name: string): Promise<{
945
- id: string;
946
- name: string;
947
- type: string;
948
- status: import("@db/api").$Enums.Status;
949
- tags: string[];
950
- identifier: string;
951
- action: import("@db/api").$Enums.OpportunityAction;
952
- chainId: number;
953
- depositUrl: string | null;
954
- explorerAddress: string | null;
955
- mainProtocolId: string | null;
956
- tvl: number;
957
- apr: number;
958
- dailyRewards: number;
959
- }>;
960
- static updateChainId(id: string, chainId: MerklChainId): Promise<{
951
+ static update(id: string, data: Partial<Opportunity["raw"]>): Promise<{
961
952
  id: string;
962
953
  name: string;
963
954
  type: string;
@@ -965,6 +956,7 @@ export declare abstract class OpportunityRepository {
965
956
  tags: string[];
966
957
  identifier: string;
967
958
  action: import("@db/api").$Enums.OpportunityAction;
959
+ manualOverrides: import("@db/api").$Enums.OpportunityManualOverride[];
968
960
  chainId: number;
969
961
  depositUrl: string | null;
970
962
  explorerAddress: string | null;
@@ -973,6 +965,7 @@ export declare abstract class OpportunityRepository {
973
965
  apr: number;
974
966
  dailyRewards: number;
975
967
  }>;
968
+ static updateMany(ids: string[], data: UpdateOpportunityModel): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
976
969
  static aggregateSum(field: keyof Prisma.OpportunitySumAggregateInputType, query: GetOpportunitiesQueryModel): Promise<{
977
970
  sum: string;
978
971
  }>;
@@ -982,21 +975,4 @@ export declare abstract class OpportunityRepository {
982
975
  static aggregateMax(field: keyof Prisma.OpportunityMaxAggregateInputType, query: GetOpportunitiesQueryModel): Promise<{
983
976
  max: string;
984
977
  }>;
985
- static update(id: string, data: Partial<Opportunity["raw"]>): Promise<{
986
- id: string;
987
- name: string;
988
- type: string;
989
- status: import("@db/api").$Enums.Status;
990
- tags: string[];
991
- identifier: string;
992
- action: import("@db/api").$Enums.OpportunityAction;
993
- chainId: number;
994
- depositUrl: string | null;
995
- explorerAddress: string | null;
996
- mainProtocolId: string | null;
997
- tvl: number;
998
- apr: number;
999
- dailyRewards: number;
1000
- }>;
1001
- static updateMany(ids: string[], data: UpdateOpportunityModel): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
1002
978
  }
@@ -7,6 +7,7 @@ import { AprService } from "../apr";
7
7
  import { RewardService } from "../reward";
8
8
  import { TvlService } from "../tvl";
9
9
  export class OpportunityRepository {
10
+ // ─── Utils ───────────────────────────────────────────────────────────
10
11
  static #transformQueryToPrismaFilters(query) {
11
12
  const { page: _page, items: _items, ...filters } = query;
12
13
  //TODO: abstract away query to not be strictly equal to controller
@@ -24,9 +25,7 @@ export class OpportunityRepository {
24
25
  const point = query.point ?? false;
25
26
  const creatorAddress = query.creatorAddress ?? null;
26
27
  const identifier = query.identifier ?? null;
27
- const orderBy = {
28
- [sort]: order,
29
- };
28
+ const orderBy = { [sort]: order };
30
29
  return {
31
30
  orderBy,
32
31
  where: {
@@ -60,26 +59,14 @@ export class OpportunityRepository {
60
59
  }
61
60
  static #getRecordInclusion(withTest = true, withPoints = true) {
62
61
  return {
63
- AprRecords: {
64
- take: 1,
65
- orderBy: { timestamp: "desc" },
66
- include: { AprBreakdown: true },
67
- },
68
- TvlRecords: {
69
- take: 1,
70
- orderBy: { timestamp: "desc" },
71
- include: { TvlBreakdown: true },
72
- },
62
+ AprRecords: { take: 1, orderBy: { timestamp: "desc" }, include: { AprBreakdown: true } },
63
+ TvlRecords: { take: 1, orderBy: { timestamp: "desc" }, include: { TvlBreakdown: true } },
73
64
  DailyRewardsRecords: {
74
65
  take: 1,
75
66
  orderBy: { timestamp: "desc" },
76
67
  include: {
77
68
  DailyRewardsBreakdown: {
78
- where: {
79
- Campaign: {
80
- RewardToken: withTest ? undefined : { isTest: false, isPoint: withPoints },
81
- },
82
- },
69
+ where: { Campaign: { RewardToken: withTest ? undefined : { isTest: false, isPoint: withPoints } } },
83
70
  include: {
84
71
  Campaign: {
85
72
  select: {
@@ -98,41 +85,28 @@ export class OpportunityRepository {
98
85
  }
99
86
  static #getCampaignInclusion(withTest = true, withPoints = true) {
100
87
  return {
101
- orderBy: {
102
- endTimestamp: "desc",
103
- },
104
- where: withTest
105
- ? undefined
106
- : {
107
- RewardToken: {
108
- isTest: false,
109
- isPoint: withPoints,
110
- },
111
- },
88
+ orderBy: { endTimestamp: "desc" },
89
+ where: withTest ? undefined : { RewardToken: { isTest: false, isPoint: withPoints } },
112
90
  include: {
113
91
  RewardToken: true,
114
92
  ComputeChain: true,
115
- DistributionChain: {
116
- include: {
117
- Explorer: true,
118
- },
119
- },
93
+ DistributionChain: { include: { Explorer: true } },
120
94
  Creator: true,
121
95
  CampaignStatus: true, // [][0]
122
96
  },
123
97
  };
124
98
  }
99
+ // ─── Create ──────────────────────────────────────────────────────────
125
100
  static async create(newOpp, upsert = false) {
126
101
  const previousOpportunity = await apiDbClient.opportunity.findUnique({
127
102
  where: { id: newOpp.id },
128
103
  include: { Tokens: true, Protocols: true },
129
104
  });
130
- if (!!previousOpportunity && !upsert) {
105
+ if (!!previousOpportunity && !upsert)
131
106
  return previousOpportunity;
132
- }
133
107
  if (!!newOpp.mainProtocol) {
134
108
  let mainProtocol = await apiDbClient.protocol.findUnique({ where: { id: newOpp.mainProtocol } });
135
- if (!mainProtocol) {
109
+ if (!mainProtocol)
136
110
  mainProtocol = await ProtocolService.create({
137
111
  id: newOpp.mainProtocol,
138
112
  name: newOpp.mainProtocol,
@@ -141,54 +115,47 @@ export class OpportunityRepository {
141
115
  icon: "",
142
116
  description: "",
143
117
  });
118
+ if (!previousOpportunity?.manualOverrides.includes("action")) {
119
+ // Override action with the protocol's action if it differs
120
+ if (mainProtocol.tags.includes("AMM") || mainProtocol.tags.includes("DEX"))
121
+ newOpp.action = "POOL";
122
+ if (mainProtocol.tags.includes("BORROWING"))
123
+ newOpp.action = "BORROW";
124
+ if (mainProtocol.tags.includes("LENDING") && !!newOpp.name && newOpp.name.includes("Supply"))
125
+ newOpp.action = "LEND";
144
126
  }
145
- // Override action with the protocol's action if it differs
146
- if (mainProtocol.tags.includes("AMM"))
147
- newOpp.action = "POOL";
148
- if (mainProtocol.tags.includes("DEX"))
149
- newOpp.action = "POOL";
150
- if (mainProtocol.tags.includes("BORROWING"))
151
- newOpp.action = "BORROW";
152
- if (mainProtocol.tags.includes("LENDING") && !!newOpp.name && newOpp.name.includes("Supply"))
153
- newOpp.action = "LEND";
154
127
  }
155
128
  // Safety check on urls:
156
- if (!!newOpp.depositUrl && !newOpp.depositUrl.includes("http")) {
129
+ if (!previousOpportunity?.manualOverrides.includes("depositUrl") &&
130
+ !!newOpp.depositUrl &&
131
+ !newOpp.depositUrl.includes("http")) {
157
132
  newOpp.depositUrl = undefined;
158
133
  log.warn(`deposit URL for opportunity ${newOpp.id} is not a valid URL`);
159
134
  }
160
- const toDisconnect = {
161
- mainProtocol: "",
162
- protocols: [],
163
- tokens: [],
164
- };
135
+ const toDisconnect = { mainProtocol: "", protocols: [], tokens: [] };
165
136
  if (!!previousOpportunity) {
166
- if (previousOpportunity.mainProtocolId !== newOpp.mainProtocol) {
137
+ if (previousOpportunity.mainProtocolId !== newOpp.mainProtocol)
167
138
  toDisconnect.mainProtocol = previousOpportunity.mainProtocolId ?? "";
168
- }
169
- for (const protocol of previousOpportunity.Protocols) {
170
- if (!newOpp.protocols || !newOpp.protocols.includes(protocol.id)) {
139
+ for (const protocol of previousOpportunity.Protocols)
140
+ if (!newOpp.protocols || !newOpp.protocols.includes(protocol.id))
171
141
  toDisconnect.protocols.push(protocol.id);
172
- }
173
- }
174
- for (const token of previousOpportunity.Tokens) {
175
- if (!newOpp.tokens.some(newToken => newToken.chainId === token.chainId && newToken.address === token.address)) {
176
- toDisconnect.tokens.push({
177
- chainId: token.chainId,
178
- address: token.address,
179
- });
180
- }
181
- }
142
+ for (const token of previousOpportunity.Tokens)
143
+ if (!newOpp.tokens.some(newToken => newToken.chainId === token.chainId && newToken.address === token.address))
144
+ toDisconnect.tokens.push({ chainId: token.chainId, address: token.address });
182
145
  }
183
146
  const data = {
184
147
  id: newOpp.id,
185
148
  action: newOpp.action ?? "HOLD",
186
149
  identifier: newOpp.identifier,
187
- name: newOpp.name,
150
+ name: !previousOpportunity?.manualOverrides.includes("name") ? newOpp.name : previousOpportunity.name,
188
151
  status: newOpp.status,
189
152
  type: newOpp.type,
190
- depositUrl: newOpp.depositUrl,
191
- explorerAddress: newOpp.explorerAddress,
153
+ depositUrl: !previousOpportunity?.manualOverrides.includes("depositUrl")
154
+ ? newOpp.depositUrl
155
+ : previousOpportunity.depositUrl,
156
+ explorerAddress: !previousOpportunity?.manualOverrides.includes("explorerAddress")
157
+ ? newOpp.explorerAddress
158
+ : previousOpportunity.explorerAddress,
192
159
  Chain: { connect: { id: newOpp.chainId } },
193
160
  MainProtocol: !!newOpp.mainProtocol ? { connect: { id: newOpp.mainProtocol } } : undefined,
194
161
  Protocols: {
@@ -198,12 +165,7 @@ export class OpportunityRepository {
198
165
  },
199
166
  Tokens: {
200
167
  connect: newOpp.tokens.map((token) => {
201
- return {
202
- chainId_address: {
203
- chainId: token.chainId,
204
- address: token.address,
205
- },
206
- };
168
+ return { chainId_address: { chainId: token.chainId, address: token.address } };
207
169
  }),
208
170
  },
209
171
  };
@@ -211,11 +173,13 @@ export class OpportunityRepository {
211
173
  id: newOpp.id,
212
174
  action: newOpp.action ?? "HOLD",
213
175
  identifier: newOpp.identifier,
214
- name: newOpp.name,
176
+ name: !previousOpportunity?.manualOverrides.includes("name") ? newOpp.name : undefined,
215
177
  status: newOpp.status,
216
178
  type: newOpp.type,
217
- depositUrl: newOpp.depositUrl,
218
- explorerAddress: newOpp.explorerAddress,
179
+ depositUrl: !previousOpportunity?.manualOverrides.includes("depositUrl") ? newOpp.depositUrl : undefined,
180
+ explorerAddress: !previousOpportunity?.manualOverrides.includes("explorerAddress")
181
+ ? newOpp.explorerAddress
182
+ : undefined,
219
183
  Chain: { connect: { id: newOpp.chainId } },
220
184
  MainProtocol: !!newOpp.mainProtocol
221
185
  ? { connect: { id: newOpp.mainProtocol } }
@@ -232,45 +196,30 @@ export class OpportunityRepository {
232
196
  },
233
197
  Tokens: {
234
198
  connect: newOpp.tokens.map((token) => {
235
- return {
236
- chainId_address: {
237
- chainId: token.chainId,
238
- address: token.address,
239
- },
240
- };
199
+ return { chainId_address: { chainId: token.chainId, address: token.address } };
241
200
  }),
242
201
  disconnect: toDisconnect.tokens.map((token) => {
243
- return {
244
- chainId_address: {
245
- chainId: token.chainId,
246
- address: token.address,
247
- },
248
- };
202
+ return { chainId_address: { chainId: token.chainId, address: token.address } };
249
203
  }),
250
204
  },
251
205
  };
252
- if (upsert) {
206
+ if (upsert)
253
207
  await apiDbClient.opportunity.upsert({
254
208
  where: { id: newOpp.id },
255
209
  create: data,
256
210
  update: dataWithDisconnect,
257
211
  });
258
- }
259
- else {
212
+ else
260
213
  await apiDbClient.opportunity.create({ data });
261
- }
262
214
  return await apiDbClient.opportunity.findUnique({ where: { id: newOpp.id } });
263
215
  }
216
+ // ─── Find ────────────────────────────────────────────────────────────
264
217
  static async findUnique(id) {
265
218
  return await apiDbClient.opportunity.findUnique({
266
219
  include: {
267
220
  ...OpportunityRepository.#getRecordInclusion(),
268
221
  Chain: true,
269
- Campaigns: {
270
- include: {
271
- RewardToken: true,
272
- },
273
- },
222
+ Campaigns: { include: { RewardToken: true } },
274
223
  MainProtocol: true,
275
224
  Protocols: true,
276
225
  Tokens: true,
@@ -278,6 +227,7 @@ export class OpportunityRepository {
278
227
  where: { id },
279
228
  });
280
229
  }
230
+ // wrong return type if you include campaigns (RewardToken is missing from the return type)
281
231
  static async findUniqueOrThrow(id, withTest = true, withPoints = true, withCampaigns = false) {
282
232
  return await apiDbClient.opportunity.findUniqueOrThrow({
283
233
  include: {
@@ -286,9 +236,7 @@ export class OpportunityRepository {
286
236
  Chain: { include: { Explorer: true } },
287
237
  MainProtocol: true,
288
238
  Protocols: true,
289
- Tokens: {
290
- where: !withTest ? { isTest: false } : undefined,
291
- },
239
+ Tokens: { where: !withTest ? { isTest: false } : undefined },
292
240
  },
293
241
  where: { id },
294
242
  });
@@ -300,19 +248,11 @@ export class OpportunityRepository {
300
248
  */
301
249
  static async findManyByCampaigns(where) {
302
250
  return await apiDbClient.opportunity.findMany({
303
- where: {
304
- Campaigns: {
305
- some: where,
306
- },
307
- },
251
+ where: { Campaigns: { some: where } },
308
252
  include: {
309
253
  ...OpportunityRepository.#getRecordInclusion(),
310
254
  Campaigns: OpportunityRepository.#getCampaignInclusion(true),
311
- Chain: {
312
- include: {
313
- Explorer: true,
314
- },
315
- },
255
+ Chain: { include: { Explorer: true } },
316
256
  MainProtocol: true,
317
257
  Protocols: true,
318
258
  Tokens: true,
@@ -335,15 +275,9 @@ export class OpportunityRepository {
335
275
  ...OpportunityRepository.#getRecordInclusion(withTest, withPoints),
336
276
  Campaigns: withCampaigns ? OpportunityRepository.#getCampaignInclusion(withTest, withPoints) : undefined,
337
277
  MainProtocol: true,
338
- Chain: {
339
- include: {
340
- Explorer: true,
341
- },
342
- },
278
+ Chain: { include: { Explorer: true } },
343
279
  Protocols: true,
344
- Tokens: {
345
- where: !withTest ? { isTest: false } : undefined,
346
- },
280
+ Tokens: { where: !withTest ? { isTest: false } : undefined },
347
281
  },
348
282
  ...args,
349
283
  });
@@ -363,11 +297,7 @@ export class OpportunityRepository {
363
297
  include: {
364
298
  RewardToken: true,
365
299
  ComputeChain: true,
366
- DistributionChain: {
367
- include: {
368
- Explorer: true,
369
- },
370
- },
300
+ DistributionChain: { include: { Explorer: true } },
371
301
  CampaignStatus: true,
372
302
  Creator: true,
373
303
  },
@@ -375,11 +305,7 @@ export class OpportunityRepository {
375
305
  orderBy: { endTimestamp: "desc" },
376
306
  },
377
307
  MainProtocol: true,
378
- Chain: {
379
- include: {
380
- Explorer: true,
381
- },
382
- },
308
+ Chain: { include: { Explorer: true } },
383
309
  Protocols: true,
384
310
  Tokens: true,
385
311
  },
@@ -389,15 +315,7 @@ export class OpportunityRepository {
389
315
  { status: "LIVE" },
390
316
  {
391
317
  Campaigns: {
392
- some: {
393
- RewardToken: { isTest: false },
394
- startTimestamp: {
395
- lte: now,
396
- },
397
- endTimestamp: {
398
- gte: now,
399
- },
400
- },
318
+ some: { RewardToken: { isTest: false }, startTimestamp: { lte: now }, endTimestamp: { gte: now } },
401
319
  },
402
320
  },
403
321
  ],
@@ -408,20 +326,15 @@ export class OpportunityRepository {
408
326
  const args = OpportunityRepository.#transformQueryToPrismaFilters(query);
409
327
  return await apiDbClient.opportunity.count(args);
410
328
  }
411
- static async getAllIdsForDynamicOpp() {
412
- return await apiDbClient.opportunity.findMany({
413
- where: { type: { notIn: ["ERC20_SNAPSHOT", "JSON_AIRDROP"] } },
414
- select: { id: true },
415
- });
416
- }
329
+ // ─── Update ──────────────────────────────────────────────────────────
417
330
  /**
418
- * Updates Apr, Tvl and DailyRewards record
331
+ * Updates Apr, Tvl and DailyRewards records
419
332
  * @param opportunityId
420
333
  * @param apr
421
334
  * @param tvl
422
335
  * @returns
423
336
  */
424
- static async updateRecords(opportunityId, apr, tvl, dailyRewards) {
337
+ static async updateDynamicData(opportunityId, apr, tvl, dailyRewards) {
425
338
  const aprRecord = apr.cumulated >= 0 &&
426
339
  (await apiDbClient.aprRecord.create({
427
340
  data: {
@@ -450,12 +363,10 @@ export class OpportunityRepository {
450
363
  total: dailyRewards.total,
451
364
  DailyRewardsBreakdown: {
452
365
  createMany: {
453
- data: dailyRewards.breakdowns.map(breakdown => {
454
- return {
455
- campaignId: breakdown.campaignId,
456
- value: breakdown.value,
457
- };
458
- }),
366
+ data: dailyRewards.breakdowns.map(breakdown => ({
367
+ campaignId: breakdown.campaignId,
368
+ value: breakdown.value,
369
+ })),
459
370
  },
460
371
  },
461
372
  },
@@ -477,46 +388,26 @@ export class OpportunityRepository {
477
388
  return await apiDbClient.opportunity.update({ where: { id }, data: { status, apr: 0, dailyRewards: 0 } });
478
389
  return await apiDbClient.opportunity.update({ where: { id }, data: { status } });
479
390
  }
480
- static async updateName(id, name) {
481
- return await apiDbClient.opportunity.update({ where: { id }, data: { name } });
391
+ static async update(id, data) {
392
+ return await apiDbClient.opportunity.update({ where: { id }, data });
482
393
  }
483
- static async updateChainId(id, chainId) {
484
- return await apiDbClient.opportunity.update({ where: { id }, data: { chainId } });
394
+ static async updateMany(ids, data) {
395
+ return await apiDbClient.opportunity.updateMany({ where: { id: { in: ids } }, data });
485
396
  }
397
+ // ─── Aggregation ─────────────────────────────────────────────────────
486
398
  static async aggregateSum(field, query) {
487
399
  const args = OpportunityRepository.#transformQueryToPrismaFilters(query);
488
- const result = await apiDbClient.opportunity.aggregate({
489
- _sum: {
490
- [field]: true,
491
- },
492
- ...args,
493
- });
400
+ const result = await apiDbClient.opportunity.aggregate({ _sum: { [field]: true }, ...args });
494
401
  return { sum: result._sum[field] ?? null };
495
402
  }
496
403
  static async aggregateMin(field, query) {
497
404
  const args = OpportunityRepository.#transformQueryToPrismaFilters(query);
498
- const result = await apiDbClient.opportunity.aggregate({
499
- _min: {
500
- [field]: true,
501
- },
502
- ...args,
503
- });
405
+ const result = await apiDbClient.opportunity.aggregate({ _min: { [field]: true }, ...args });
504
406
  return { min: result._min[field] ?? null };
505
407
  }
506
408
  static async aggregateMax(field, query) {
507
409
  const args = OpportunityRepository.#transformQueryToPrismaFilters(query);
508
- const result = await apiDbClient.opportunity.aggregate({
509
- _max: {
510
- [field]: true,
511
- },
512
- ...args,
513
- });
410
+ const result = await apiDbClient.opportunity.aggregate({ _max: { [field]: true }, ...args });
514
411
  return { max: result._max[field] ?? null };
515
412
  }
516
- static async update(id, data) {
517
- return await apiDbClient.opportunity.update({ where: { id }, data });
518
- }
519
- static async updateMany(ids, data) {
520
- return await apiDbClient.opportunity.updateMany({ where: { id: { in: ids } }, data });
521
- }
522
413
  }