@merkl/api 0.10.296 → 0.10.298

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.
@@ -1,6 +1,6 @@
1
1
  import type { Prisma } from "../../../../database/api/.generated";
2
2
  import type { ChainId } from "@sdk";
3
- import type { BreakdownForCampaignsRaw, CampaignIdModel, CampaignIdWithoutPageModel, CreateManyBreakdownModel, CreateManyRewardModel, PendingEntity } from "./reward.model";
3
+ import type { BreakdownForCampaignsRaw, CampaignIdModel, CampaignIdWithoutPageModel, CreateManyBreakdownModel, CreateManyRewardModel, PendingEntity, TokenIdModel } from "./reward.model";
4
4
  export declare abstract class RewardRepository {
5
5
  static createManyReward(rewards: CreateManyRewardModel): Promise<Prisma.BatchPayload>;
6
6
  static createManyBreakdown(data: CreateManyBreakdownModel): Promise<Prisma.BatchPayload>;
@@ -132,6 +132,18 @@ export declare abstract class RewardRepository {
132
132
  recipient: string;
133
133
  };
134
134
  }[]>;
135
+ static upsertPendings(rewardTokenId: string, root: string, campaignId: string, toUpdate: PendingEntity[]): Promise<{
136
+ reason: string;
137
+ pending: string;
138
+ id: number;
139
+ campaignId: string;
140
+ amount: string;
141
+ protocolId: string | null;
142
+ claimed: string;
143
+ auxiliaryData1: string | null;
144
+ auxiliaryData2: string | null;
145
+ rewardId: string;
146
+ }[]>;
135
147
  static updatePendings(rewardTokenId: string, root: string, campaignId: string, toUpdate: PendingEntity[]): Promise<{
136
148
  reason: string;
137
149
  pending: string;
@@ -158,16 +170,24 @@ export declare abstract class RewardRepository {
158
170
  }[]>;
159
171
  static findManyRootsWithRewardOnChain(chainId: number): Promise<string[]>;
160
172
  static breakdownForCampaign(root: string, id: string, query: CampaignIdModel): Promise<BreakdownForCampaignsRaw[]>;
161
- static total(campaignId: string, root: string): Promise<{
173
+ static totalForCampaign(campaignId: string, root: string): Promise<{
162
174
  campaignId: string;
163
175
  amount: bigint;
164
176
  }>;
177
+ static countForCampaign(campaignId: string, root: string): Promise<{
178
+ count: number;
179
+ }>;
180
+ static breakdownForToken(root: string, id: string, query: TokenIdModel): Promise<BreakdownForCampaignsRaw[]>;
181
+ static totalForToken(tokenId: string, root: string): Promise<{
182
+ tokenId: string;
183
+ amount: bigint;
184
+ }>;
185
+ static countForToken(tokenId: string, root: string): Promise<{
186
+ count: number;
187
+ }>;
165
188
  static getAmountAndClaimedForCampaigns(root: string, x: CampaignIdWithoutPageModel): Promise<{
166
189
  campaignId: string;
167
190
  amount: string;
168
191
  claimed: string;
169
192
  }[]>;
170
- static count(campaignId: string, root: string): Promise<{
171
- count: number;
172
- }>;
173
193
  }
@@ -158,6 +158,46 @@ export class RewardRepository {
158
158
  },
159
159
  });
160
160
  }
161
+ static async upsertPendings(rewardTokenId, root, campaignId, toUpdate) {
162
+ const users = toUpdate.map(x => x.recipient);
163
+ await UserService.createMany(users.map(x => ({ address: x, tags: [] })));
164
+ return await apiDbClient.$transaction(toUpdate.map(x => {
165
+ const rewardId = RewardService.hashId(root, x.recipient, rewardTokenId);
166
+ return apiDbClient.rewardBreakdown.upsert({
167
+ where: {
168
+ rewardId_campaignId_reason: {
169
+ rewardId: RewardService.hashId(root, x.recipient, rewardTokenId),
170
+ campaignId: campaignId,
171
+ reason: x.reason,
172
+ },
173
+ },
174
+ update: {
175
+ pending: x.pending,
176
+ auxiliaryData1: x.auxiliaryData1,
177
+ auxiliaryData2: x.auxiliaryData2,
178
+ },
179
+ create: {
180
+ reason: x.reason,
181
+ amount: "0",
182
+ pending: x.pending,
183
+ claimed: "0",
184
+ Reward: {
185
+ connectOrCreate: {
186
+ where: { id: rewardId },
187
+ create: {
188
+ id: rewardId,
189
+ MerklRoot: { connect: { root } },
190
+ User: { connect: { address: x.recipient } },
191
+ RewardToken: { connect: { id: rewardTokenId } },
192
+ proofs: [],
193
+ },
194
+ },
195
+ },
196
+ Campaign: { connect: { id: campaignId } },
197
+ },
198
+ });
199
+ }));
200
+ }
161
201
  static async updatePendings(rewardTokenId, root, campaignId, toUpdate) {
162
202
  return await apiDbClient.$transaction(toUpdate.map(x => {
163
203
  return apiDbClient.rewardBreakdown.update({
@@ -170,7 +210,6 @@ export class RewardRepository {
170
210
  },
171
211
  data: {
172
212
  pending: x.pending,
173
- reason: x.reason,
174
213
  auxiliaryData1: x.auxiliaryData1,
175
214
  auxiliaryData2: x.auxiliaryData2,
176
215
  },
@@ -245,7 +284,7 @@ export class RewardRepository {
245
284
  `, root, id, items, items * page);
246
285
  return result;
247
286
  }
248
- static async total(campaignId, root) {
287
+ static async totalForCampaign(campaignId, root) {
249
288
  const totalAmount = await apiDbClient.rewardBreakdown.findMany({
250
289
  where: {
251
290
  campaignId,
@@ -265,32 +304,88 @@ export class RewardRepository {
265
304
  }, { campaignId, amount: 0n });
266
305
  return reducedData;
267
306
  }
268
- static async getAmountAndClaimedForCampaigns(root, x) {
269
- return await apiDbClient.rewardBreakdown.findMany({
307
+ static async countForCampaign(campaignId, root) {
308
+ const count = await apiDbClient.rewardBreakdown.count({
309
+ where: {
310
+ campaignId,
311
+ Reward: {
312
+ root,
313
+ },
314
+ },
315
+ });
316
+ return { count };
317
+ }
318
+ static async breakdownForToken(root, id, query) {
319
+ const { page: _page, items: _items } = query;
320
+ const page = _page || 0;
321
+ const items = _items || 50;
322
+ const result = await apiDbClient.$queryRawUnsafe(`
323
+ SELECT
324
+ r."recipient",
325
+ SUM(rb."amount"::numeric)::text AS amount,
326
+ SUM(rb."claimed"::numeric)::text AS claimed,
327
+ SUM(rb."pending"::numeric)::text AS pending
328
+ FROM
329
+ "RewardBreakdown" rb
330
+ INNER JOIN
331
+ "Reward" r ON rb."rewardId" = r."id"
332
+ WHERE
333
+ r."root" = $1 AND r."rewardTokenId" = $2
334
+ GROUP BY
335
+ r."recipient"
336
+ ORDER BY
337
+ (SUM(rb."amount"::numeric) + SUM(rb."pending"::numeric)) DESC
338
+ LIMIT $3
339
+ OFFSET $4
340
+ `, root, id, items, items * page);
341
+ return result;
342
+ }
343
+ static async totalForToken(tokenId, root) {
344
+ const totalAmount = await apiDbClient.rewardBreakdown.findMany({
345
+ where: {
346
+ Reward: {
347
+ rewardTokenId: tokenId,
348
+ root,
349
+ },
350
+ },
270
351
  select: {
271
- claimed: true,
272
352
  amount: true,
353
+ pending: true,
273
354
  campaignId: true,
274
355
  },
356
+ });
357
+ const reducedData = totalAmount.reduce((acc, { amount, pending }) => {
358
+ acc.amount += BigInt(amount) + BigInt(pending ?? 0);
359
+ return acc;
360
+ }, { tokenId, amount: 0n });
361
+ return reducedData;
362
+ }
363
+ static async countForToken(tokenId, root) {
364
+ const count = await apiDbClient.rewardBreakdown.count({
275
365
  where: {
276
- campaignId: {
277
- in: x.campaignIds.map(campaignId => CampaignService.hashId({ distributionChain: x.chainId, campaignId })),
278
- },
279
366
  Reward: {
367
+ rewardTokenId: tokenId,
280
368
  root,
281
369
  },
282
370
  },
283
371
  });
372
+ return { count };
284
373
  }
285
- static async count(campaignId, root) {
286
- const count = await apiDbClient.rewardBreakdown.count({
374
+ static async getAmountAndClaimedForCampaigns(root, x) {
375
+ return await apiDbClient.rewardBreakdown.findMany({
376
+ select: {
377
+ claimed: true,
378
+ amount: true,
379
+ campaignId: true,
380
+ },
287
381
  where: {
288
- campaignId,
382
+ campaignId: {
383
+ in: x.campaignIds.map(campaignId => CampaignService.hashId({ distributionChain: x.chainId, campaignId })),
384
+ },
289
385
  Reward: {
290
386
  root,
291
387
  },
292
388
  },
293
389
  });
294
- return { count };
295
390
  }
296
391
  }
@@ -2,7 +2,7 @@ import type { CacheKeys } from "../../../cache/keys";
2
2
  import type { Chain } from "../../../../database/api/.generated";
3
3
  import { Campaign, type CampaignDynamicData, type ChainId, type MerklChainId } from "@sdk";
4
4
  import { type LightOpportunityFromDB, type Opportunity } from "../opportunity";
5
- import type { CampaignIdModel, CampaignIdWithoutPageModel, CreateManyBreakdownModel, CreateManyRewardModel, DailyRewardsRecord, RegisterClaimsModel, RewardBreakdown, UpdatePendingModel } from "./reward.model";
5
+ import type { CampaignIdModel, CampaignIdWithoutPageModel, CreateManyBreakdownModel, CreateManyRewardModel, DailyRewardsRecord, RegisterClaimsModel, RewardBreakdown, TokenIdModel, UpdatePendingModel } from "./reward.model";
6
6
  import { RewardRepository } from "./reward.repository";
7
7
  export declare abstract class RewardService {
8
8
  static hashId(root: string, recipient: string, rewardTokenId: string): string;
@@ -557,13 +557,21 @@ export declare abstract class RewardService {
557
557
  rewards: Record<string, number>;
558
558
  }>>;
559
559
  static breakdownForCampaign(query: CampaignIdModel): Promise<import("./reward.model").BreakdownForCampaignsRaw[]>;
560
- static count(query: CampaignIdModel): Promise<{
560
+ static countForCampaign(query: CampaignIdModel): Promise<{
561
561
  count: number;
562
562
  }>;
563
- static total(query: CampaignIdModel): Promise<{
563
+ static totalForCampaign(query: CampaignIdModel): Promise<{
564
564
  campaignId: string;
565
565
  amount: bigint;
566
566
  }>;
567
+ static breakdownForToken(query: TokenIdModel): Promise<import("./reward.model").BreakdownForCampaignsRaw[]>;
568
+ static countForToken(query: TokenIdModel): Promise<{
569
+ count: number;
570
+ }>;
571
+ static totalForToken(query: TokenIdModel): Promise<{
572
+ tokenId: string;
573
+ amount: bigint;
574
+ }>;
567
575
  static getAmountAndClaimedForCampaigns(x: CampaignIdWithoutPageModel): Promise<{
568
576
  campaignId: string;
569
577
  amount: string;
@@ -238,20 +238,23 @@ export class RewardService {
238
238
  distributionChain: data.distributionChainId,
239
239
  campaignId: data.campaignId,
240
240
  });
241
- const ids = (await RewardRepository.findManyBreakdownUniques(rewardTokenId, data.root, campaignId)).map(({ Reward, reason }) => Bun.hash(`${Reward.recipient}${reason}`).toString());
242
- const toUpdate = [];
243
- const toCreate = [];
244
- for (const point of data.data) {
245
- if (ids.includes(Bun.hash(`${point.recipient}${point.reason}`).toString())) {
246
- toUpdate.push(point);
247
- }
248
- else {
249
- toCreate.push(point);
250
- }
251
- }
252
- await RewardRepository.updatePendings(rewardTokenId, data.root, campaignId, toUpdate);
253
- await RewardRepository.createPendings(rewardTokenId, data.root, campaignId, toCreate);
254
- return { created: toCreate.length, updated: toUpdate.length };
241
+ // const ids = (await RewardRepository.findManyBreakdownUniques(rewardTokenId, data.root, campaignId)).map(
242
+ // ({ Reward, reason }) => Bun.hash(`${Reward.recipient}${reason}`).toString()
243
+ // );
244
+ // const toUpdate = [];
245
+ // const toCreate = [];
246
+ // for (const point of data.data) {
247
+ // if (ids.includes(Bun.hash(`${point.recipient}${point.reason}`).toString())) {
248
+ // toUpdate.push(point);
249
+ // } else {
250
+ // toCreate.push(point);
251
+ // }
252
+ // }
253
+ // await RewardRepository.updatePendings(rewardTokenId, data.root, campaignId, toUpdate);
254
+ // await RewardRepository.createPendings(rewardTokenId, data.root, campaignId, toCreate);
255
+ // return { created: toCreate.length, updated: toUpdate.length };
256
+ await RewardRepository.upsertPendings(rewardTokenId, data.root, campaignId, data.data);
257
+ return { created: data.data.length, updated: 0 };
255
258
  }
256
259
  static async countAllchains() {
257
260
  const rewardPerRewardTokenId = await RewardRepository.countRewardPerRewardTokenIdAndRoot();
@@ -282,14 +285,29 @@ export class RewardService {
282
285
  const id = CampaignService.hashId({ distributionChain: query.chainId, campaignId: query.campaignId });
283
286
  return RewardRepository.breakdownForCampaign(root.live, id, query);
284
287
  }
285
- static async count(query) {
288
+ static async countForCampaign(query) {
286
289
  const root = await MerklRootService.fetch(query.chainId);
287
290
  const id = CampaignService.hashId({ distributionChain: query.chainId, campaignId: query.campaignId });
288
- return RewardRepository.count(id, root.live);
291
+ return RewardRepository.countForCampaign(id, root.live);
292
+ }
293
+ static async totalForCampaign(query) {
294
+ const root = await MerklRootService.fetch(query.chainId);
295
+ return RewardRepository.totalForCampaign(CampaignService.hashId({ distributionChain: query.chainId, campaignId: query.campaignId }), root.live);
296
+ }
297
+ static async breakdownForToken(query) {
298
+ const root = await MerklRootService.fetch(query.chainId);
299
+ const id = TokenService.hashId({ chainId: query.chainId, address: query.address });
300
+ return RewardRepository.breakdownForToken(root.live, id, query);
301
+ }
302
+ static async countForToken(query) {
303
+ const root = await MerklRootService.fetch(query.chainId);
304
+ const id = TokenService.hashId({ chainId: query.chainId, address: query.address });
305
+ return RewardRepository.countForToken(id, root.live);
289
306
  }
290
- static async total(query) {
307
+ static async totalForToken(query) {
291
308
  const root = await MerklRootService.fetch(query.chainId);
292
- return RewardRepository.total(CampaignService.hashId({ distributionChain: query.chainId, campaignId: query.campaignId }), root.live);
309
+ const id = TokenService.hashId({ chainId: query.chainId, address: query.address });
310
+ return RewardRepository.totalForToken(id, root.live);
293
311
  }
294
312
  static async getAmountAndClaimedForCampaigns(x) {
295
313
  const currentRoot = await MerklRootService.fetch(x.chainId);
@@ -1169,6 +1169,85 @@ export declare const v4: Elysia<"/v4", false, {
1169
1169
  };
1170
1170
  };
1171
1171
  };
1172
+ } & {
1173
+ count: {
1174
+ get: {
1175
+ body: unknown;
1176
+ params: {};
1177
+ query: {
1178
+ items?: number | undefined;
1179
+ page?: number | undefined;
1180
+ chainId: number;
1181
+ campaignId: string;
1182
+ };
1183
+ headers: unknown;
1184
+ response: {
1185
+ 200: {
1186
+ count: number;
1187
+ };
1188
+ };
1189
+ };
1190
+ };
1191
+ } & {
1192
+ token: {
1193
+ get: {
1194
+ body: unknown;
1195
+ params: {};
1196
+ query: {
1197
+ items?: number | undefined;
1198
+ page?: number | undefined;
1199
+ chainId: number;
1200
+ address: string;
1201
+ };
1202
+ headers: unknown;
1203
+ response: {
1204
+ 200: import("./reward").BreakdownForCampaignsRaw[];
1205
+ };
1206
+ };
1207
+ };
1208
+ } & {
1209
+ token: {
1210
+ total: {
1211
+ get: {
1212
+ body: unknown;
1213
+ params: {};
1214
+ query: {
1215
+ items?: number | undefined;
1216
+ page?: number | undefined;
1217
+ chainId: number;
1218
+ address: string;
1219
+ };
1220
+ headers: unknown;
1221
+ response: {
1222
+ 200: {
1223
+ tokenId: string;
1224
+ amount: bigint;
1225
+ };
1226
+ };
1227
+ };
1228
+ };
1229
+ };
1230
+ } & {
1231
+ token: {
1232
+ count: {
1233
+ get: {
1234
+ body: unknown;
1235
+ params: {};
1236
+ query: {
1237
+ items?: number | undefined;
1238
+ page?: number | undefined;
1239
+ chainId: number;
1240
+ address: string;
1241
+ };
1242
+ headers: unknown;
1243
+ response: {
1244
+ 200: {
1245
+ count: number;
1246
+ };
1247
+ };
1248
+ };
1249
+ };
1250
+ };
1172
1251
  } & {
1173
1252
  engine: {
1174
1253
  post: {
@@ -1276,25 +1355,6 @@ export declare const v4: Elysia<"/v4", false, {
1276
1355
  };
1277
1356
  };
1278
1357
  };
1279
- } & {
1280
- count: {
1281
- get: {
1282
- body: unknown;
1283
- params: {};
1284
- query: {
1285
- items?: number | undefined;
1286
- page?: number | undefined;
1287
- chainId: number;
1288
- campaignId: string;
1289
- };
1290
- headers: unknown;
1291
- response: {
1292
- 200: {
1293
- count: number;
1294
- };
1295
- };
1296
- };
1297
- };
1298
1358
  } & {
1299
1359
  count: {
1300
1360
  chains: {
@@ -72,9 +72,6 @@ export class StatusRepository {
72
72
  return await apiDbClient.campaignStatus.update({
73
73
  where: {
74
74
  campaignId: CampaignService.hashId(campaignUnique),
75
- status: {
76
- not: "PROCESSING", // To throw an error if the status is already PROCESSING
77
- },
78
75
  },
79
76
  data: {
80
77
  status: "PROCESSING",
@@ -19,8 +19,8 @@ export class StatusService {
19
19
  }
20
20
  static async update(campaignUnique, status) {
21
21
  // Check if the status exists already, otherwise create it
22
- const campaignExists = await StatusRepository.findUnique(campaignUnique);
23
- if (!campaignExists) {
22
+ const campaignStatus = await StatusRepository.findUnique(campaignUnique);
23
+ if (!campaignStatus) {
24
24
  let campaign = await CampaignService.findUnique(campaignUnique);
25
25
  if (!campaign) {
26
26
  await CampaignService.fill([campaignUnique]);