@merkl/api 0.10.306 → 0.10.308

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, TokenIdModel } from "./reward.model";
3
+ import type { BreakdownForCampaignsRaw, BreakdownForTokenRaw, 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>;
@@ -78,17 +78,20 @@ export declare abstract class RewardRepository {
78
78
  id: number;
79
79
  campaignId: string;
80
80
  amount: string;
81
- protocolId: string | null;
82
81
  claimed: string;
82
+ protocolId: string | null;
83
83
  auxiliaryData1: string | null;
84
84
  auxiliaryData2: string | null;
85
85
  rewardId: string;
86
86
  })[];
87
87
  } & {
88
+ pending: string;
88
89
  id: string;
89
90
  recipient: string;
90
91
  rewardTokenId: string;
92
+ amount: string;
91
93
  root: string;
94
+ claimed: string;
92
95
  proofs: string[];
93
96
  })[]>;
94
97
  static getByChainRecipientToken(recipient: string, root: string, tokenId: string): Promise<({
@@ -102,17 +105,20 @@ export declare abstract class RewardRepository {
102
105
  id: number;
103
106
  campaignId: string;
104
107
  amount: string;
105
- protocolId: string | null;
106
108
  claimed: string;
109
+ protocolId: string | null;
107
110
  auxiliaryData1: string | null;
108
111
  auxiliaryData2: string | null;
109
112
  rewardId: string;
110
113
  })[];
111
114
  } & {
115
+ pending: string;
112
116
  id: string;
113
117
  recipient: string;
114
118
  rewardTokenId: string;
119
+ amount: string;
115
120
  root: string;
121
+ claimed: string;
116
122
  proofs: string[];
117
123
  }) | null>;
118
124
  static countRewardPerRewardTokenIdAndRoot(): Promise<(Prisma.PickEnumerable<Prisma.RewardGroupByOutputType, ("rewardTokenId" | "root")[]> & {
@@ -131,49 +137,57 @@ export declare abstract class RewardRepository {
131
137
  campaignId: string;
132
138
  reason: string;
133
139
  }[]): Promise<({
134
- reason: string;
135
140
  pending: string;
136
- id: number;
137
- campaignId: string;
141
+ } | null)[]>;
142
+ static findManyRewardUniques(rewardIds: string[]): Promise<({
143
+ pending: string;
144
+ } | null)[]>;
145
+ static updateRewardPendings(rewardTokenId: string, root: string, toUpdate: {
146
+ recipient: string;
147
+ pending: string;
148
+ }[]): Promise<{
149
+ pending: string;
150
+ id: string;
151
+ recipient: string;
152
+ rewardTokenId: string;
138
153
  amount: string;
139
- protocolId: string | null;
154
+ root: string;
140
155
  claimed: string;
141
- auxiliaryData1: string | null;
142
- auxiliaryData2: string | null;
143
- rewardId: string;
144
- } | null)[]>;
145
- static upsertPendings(rewardTokenId: string, root: string, campaignId: string, toUpdate: PendingEntity[]): Promise<{
156
+ proofs: string[];
157
+ }[]>;
158
+ static updateBreakdownPendings(rewardTokenId: string, root: string, campaignId: string, toUpdate: PendingEntity[]): Promise<{
146
159
  reason: string;
147
160
  pending: string;
148
161
  id: number;
149
162
  campaignId: string;
150
163
  amount: string;
151
- protocolId: string | null;
152
164
  claimed: string;
165
+ protocolId: string | null;
153
166
  auxiliaryData1: string | null;
154
167
  auxiliaryData2: string | null;
155
168
  rewardId: string;
156
169
  }[]>;
157
- static updatePendings(rewardTokenId: string, root: string, campaignId: string, toUpdate: PendingEntity[]): Promise<{
158
- reason: string;
170
+ static createRewardPendings(rewardTokenId: string, root: string, toCreate: {
171
+ recipient: string;
159
172
  pending: string;
160
- id: number;
161
- campaignId: string;
173
+ }[]): Promise<{
174
+ pending: string;
175
+ id: string;
176
+ recipient: string;
177
+ rewardTokenId: string;
162
178
  amount: string;
163
- protocolId: string | null;
179
+ root: string;
164
180
  claimed: string;
165
- auxiliaryData1: string | null;
166
- auxiliaryData2: string | null;
167
- rewardId: string;
181
+ proofs: string[];
168
182
  }[]>;
169
- static createPendings(rewardTokenId: string, root: string, campaignId: string, toCreate: PendingEntity[]): Promise<{
183
+ static createBreakdownPendings(rewardTokenId: string, root: string, campaignId: string, toCreate: PendingEntity[]): Promise<{
170
184
  reason: string;
171
185
  pending: string;
172
186
  id: number;
173
187
  campaignId: string;
174
188
  amount: string;
175
- protocolId: string | null;
176
189
  claimed: string;
190
+ protocolId: string | null;
177
191
  auxiliaryData1: string | null;
178
192
  auxiliaryData2: string | null;
179
193
  rewardId: string;
@@ -187,7 +201,7 @@ export declare abstract class RewardRepository {
187
201
  static countForCampaign(campaignId: string, root: string): Promise<{
188
202
  count: number;
189
203
  }>;
190
- static breakdownForToken(root: string, id: string, query: TokenIdModel): Promise<BreakdownForCampaignsRaw[]>;
204
+ static breakdownForToken(root: string, id: string, query: TokenIdModel): Promise<BreakdownForTokenRaw[]>;
191
205
  static totalForToken(tokenId: string, root: string): Promise<{
192
206
  tokenId: string;
193
207
  amount: bigint;
@@ -17,6 +17,9 @@ export class RewardRepository {
17
17
  return {
18
18
  id: RewardService.hashId(reward.root, reward.recipient, rewardTokenId),
19
19
  root: reward.root,
20
+ amount: reward.amount,
21
+ pending: reward.pending,
22
+ claimed: reward.claimed,
20
23
  recipient: reward.recipient,
21
24
  rewardTokenId,
22
25
  proofs: reward.proofs,
@@ -141,6 +144,9 @@ export class RewardRepository {
141
144
  }
142
145
  static async findManyBreakdownUniques(uniques) {
143
146
  return await apiDbClient.$transaction(uniques.map(x => apiDbClient.rewardBreakdown.findUnique({
147
+ select: {
148
+ pending: true,
149
+ },
144
150
  where: {
145
151
  rewardId_campaignId_reason: {
146
152
  rewardId: x.rewardId,
@@ -150,47 +156,30 @@ export class RewardRepository {
150
156
  },
151
157
  })));
152
158
  }
153
- static async upsertPendings(rewardTokenId, root, campaignId, toUpdate) {
154
- const users = toUpdate.map(x => x.recipient);
155
- await UserService.createMany(users.map(x => ({ address: x, tags: [] })));
159
+ static async findManyRewardUniques(rewardIds) {
160
+ return await apiDbClient.$transaction(rewardIds.map(x => apiDbClient.reward.findUnique({
161
+ select: {
162
+ pending: true,
163
+ },
164
+ where: {
165
+ id: x,
166
+ },
167
+ })));
168
+ }
169
+ static async updateRewardPendings(rewardTokenId, root, toUpdate) {
156
170
  return await apiDbClient.$transaction(toUpdate.map(x => {
157
171
  const rewardId = RewardService.hashId(root, x.recipient, rewardTokenId);
158
- return apiDbClient.rewardBreakdown.upsert({
172
+ return apiDbClient.reward.update({
159
173
  where: {
160
- rewardId_campaignId_reason: {
161
- rewardId: RewardService.hashId(root, x.recipient, rewardTokenId),
162
- campaignId: campaignId,
163
- reason: x.reason,
164
- },
174
+ id: rewardId,
165
175
  },
166
- update: {
167
- pending: x.pending,
168
- auxiliaryData1: x.auxiliaryData1,
169
- auxiliaryData2: x.auxiliaryData2,
170
- },
171
- create: {
172
- reason: x.reason,
173
- amount: "0",
176
+ data: {
174
177
  pending: x.pending,
175
- claimed: "0",
176
- Reward: {
177
- connectOrCreate: {
178
- where: { id: rewardId },
179
- create: {
180
- id: rewardId,
181
- MerklRoot: { connect: { root } },
182
- User: { connect: { address: x.recipient } },
183
- RewardToken: { connect: { id: rewardTokenId } },
184
- proofs: [],
185
- },
186
- },
187
- },
188
- Campaign: { connect: { id: campaignId } },
189
178
  },
190
179
  });
191
180
  }));
192
181
  }
193
- static async updatePendings(rewardTokenId, root, campaignId, toUpdate) {
182
+ static async updateBreakdownPendings(rewardTokenId, root, campaignId, toUpdate) {
194
183
  return await apiDbClient.$transaction(toUpdate.map(x => {
195
184
  return apiDbClient.rewardBreakdown.update({
196
185
  where: {
@@ -208,7 +197,26 @@ export class RewardRepository {
208
197
  });
209
198
  }));
210
199
  }
211
- static async createPendings(rewardTokenId, root, campaignId, toCreate) {
200
+ static async createRewardPendings(rewardTokenId, root, toCreate) {
201
+ const users = toCreate.map(x => x.recipient);
202
+ await UserService.createMany(users.map(x => ({ address: x, tags: [] })));
203
+ return await apiDbClient.$transaction(toCreate.map(x => {
204
+ const rewardId = RewardService.hashId(root, x.recipient, rewardTokenId);
205
+ return apiDbClient.reward.create({
206
+ data: {
207
+ id: rewardId,
208
+ MerklRoot: { connect: { root } },
209
+ User: { connect: { address: x.recipient } },
210
+ RewardToken: { connect: { id: rewardTokenId } },
211
+ proofs: [],
212
+ amount: "0",
213
+ pending: x.pending,
214
+ claimed: "0",
215
+ },
216
+ });
217
+ }));
218
+ }
219
+ static async createBreakdownPendings(rewardTokenId, root, campaignId, toCreate) {
212
220
  const users = toCreate.map(x => x.recipient);
213
221
  await UserService.createMany(users.map(x => ({ address: x, tags: [] })));
214
222
  return await apiDbClient.$transaction(toCreate.map(x => {
@@ -220,15 +228,8 @@ export class RewardRepository {
220
228
  pending: x.pending,
221
229
  claimed: "0",
222
230
  Reward: {
223
- connectOrCreate: {
224
- where: { id: rewardId },
225
- create: {
226
- id: rewardId,
227
- MerklRoot: { connect: { root } },
228
- User: { connect: { address: x.recipient } },
229
- RewardToken: { connect: { id: rewardTokenId } },
230
- proofs: [],
231
- },
231
+ connect: {
232
+ id: rewardId,
232
233
  },
233
234
  },
234
235
  Campaign: { connect: { id: campaignId } },
@@ -313,40 +314,30 @@ export class RewardRepository {
313
314
  const items = _items || 50;
314
315
  const result = await apiDbClient.$queryRawUnsafe(`
315
316
  SELECT
316
- rb."amount",
317
- rb."reason",
318
- rb."claimed",
319
- rb."pending",
317
+ r."amount",
318
+ r."claimed",
319
+ r."pending",
320
320
  r."recipient",
321
- r."campaignId",
322
- t."address" as "rewardTokenAddress"
323
321
  FROM
324
- "RewardBreakdown" rb
325
- INNER JOIN
326
- "Reward" r ON rb."rewardId" = r."id"
327
- INNER JOIN
328
- "Token" t ON r."rewardTokenId" = t."id"
322
+ "Reward" r
329
323
  WHERE
330
324
  r."root" = $1 AND r."rewardTokenId" = $2
331
325
  ORDER BY
332
- (rb."amount"::numeric + rb."pending"::numeric) DESC
326
+ (r."amount"::numeric + r."pending"::numeric) DESC
333
327
  LIMIT $3
334
328
  OFFSET $4
335
329
  `, root, id, items, items * page);
336
330
  return result;
337
331
  }
338
332
  static async totalForToken(tokenId, root) {
339
- const totalAmount = await apiDbClient.rewardBreakdown.findMany({
333
+ const totalAmount = await apiDbClient.reward.findMany({
340
334
  where: {
341
- Reward: {
342
- rewardTokenId: tokenId,
343
- root,
344
- },
335
+ rewardTokenId: tokenId,
336
+ root,
345
337
  },
346
338
  select: {
347
339
  amount: true,
348
340
  pending: true,
349
- campaignId: true,
350
341
  },
351
342
  });
352
343
  const reducedData = totalAmount.reduce((acc, { amount, pending }) => {
@@ -356,12 +347,10 @@ export class RewardRepository {
356
347
  return reducedData;
357
348
  }
358
349
  static async countForToken(tokenId, root) {
359
- const count = await apiDbClient.rewardBreakdown.count({
350
+ const count = await apiDbClient.reward.count({
360
351
  where: {
361
- Reward: {
362
- rewardTokenId: tokenId,
363
- root,
364
- },
352
+ rewardTokenId: tokenId,
353
+ root,
365
354
  },
366
355
  });
367
356
  return { count };
@@ -232,17 +232,20 @@ export declare abstract class RewardService {
232
232
  id: number;
233
233
  campaignId: string;
234
234
  amount: string;
235
- protocolId: string | null;
236
235
  claimed: string;
236
+ protocolId: string | null;
237
237
  auxiliaryData1: string | null;
238
238
  auxiliaryData2: string | null;
239
239
  rewardId: string;
240
240
  })[];
241
241
  } & {
242
+ pending: string;
242
243
  id: string;
243
244
  recipient: string;
244
245
  rewardTokenId: string;
246
+ amount: string;
245
247
  root: string;
248
+ claimed: string;
246
249
  proofs: string[];
247
250
  })[]>;
248
251
  /**
@@ -530,17 +533,20 @@ export declare abstract class RewardService {
530
533
  id: number;
531
534
  campaignId: string;
532
535
  amount: string;
533
- protocolId: string | null;
534
536
  claimed: string;
537
+ protocolId: string | null;
535
538
  auxiliaryData1: string | null;
536
539
  auxiliaryData2: string | null;
537
540
  rewardId: string;
538
541
  })[];
539
542
  } & {
543
+ pending: string;
540
544
  id: string;
541
545
  recipient: string;
542
546
  rewardTokenId: string;
547
+ amount: string;
543
548
  root: string;
549
+ claimed: string;
544
550
  proofs: string[];
545
551
  })[]>;
546
552
  static getUserRewardsByChain(user: string, withToken: boolean, chainFilter?: ChainId[], connectedChainId?: MerklChainId | null, withTestTokens?: boolean): Promise<{
@@ -564,7 +570,7 @@ export declare abstract class RewardService {
564
570
  campaignId: string;
565
571
  amount: bigint;
566
572
  }>;
567
- static breakdownForToken(query: TokenIdModel): Promise<import("./reward.model").BreakdownForCampaignsRaw[]>;
573
+ static breakdownForToken(query: TokenIdModel): Promise<import("./reward.model").BreakdownForTokenRaw[]>;
568
574
  static countForToken(query: TokenIdModel): Promise<{
569
575
  count: number;
570
576
  }>;
@@ -238,17 +238,29 @@ export class RewardService {
238
238
  distributionChain: data.distributionChainId,
239
239
  campaignId: data.campaignId,
240
240
  });
241
+ const rewardUniques = {};
242
+ // Adds a record to the Reward row where pendings need to be updated
243
+ const updateRewardUniques = (recipient, pending, previousPending) => {
244
+ const rewardId = RewardService.hashId(data.root, recipient, rewardTokenId);
245
+ if (!rewardUniques[rewardId]) {
246
+ rewardUniques[rewardId] = { pending: "0", recipient: recipient };
247
+ }
248
+ rewardUniques[rewardId].pending = (BigInt(rewardUniques[rewardId].pending) +
249
+ BigInt(pending) -
250
+ BigInt(previousPending ?? "0")).toString();
251
+ };
241
252
  let totalCreated = 0;
242
253
  let totalUpdated = 0;
243
- const uniques = await data.data.map(({ recipient, reason }) => {
254
+ const breakdownUniques = await data.data.map(({ recipient, reason }) => {
244
255
  const rewardId = RewardService.hashId(data.root, recipient, rewardTokenId);
245
256
  return { rewardId, reason, campaignId };
246
257
  });
247
- for (let i = 0; i < uniques.length; i += 1000) {
258
+ for (let i = 0; i < breakdownUniques.length; i += 1_000) {
248
259
  const toUpdate = [];
249
260
  const toCreate = [];
250
- const exists = await RewardRepository.findManyBreakdownUniques(uniques.slice(i, Math.min(i + 1000, uniques.length)));
251
- for (const [pointIndex, point] of data.data.slice(i, Math.min(i + 1000, uniques.length)).entries()) {
261
+ const exists = await RewardRepository.findManyBreakdownUniques(breakdownUniques.slice(i, Math.min(i + 1_000, breakdownUniques.length)));
262
+ for (const [pointIndex, point] of data.data.slice(i, Math.min(i + 1_000, breakdownUniques.length)).entries()) {
263
+ updateRewardUniques(point.recipient, point.pending, exists[pointIndex]?.pending);
252
264
  if (!!exists[pointIndex]) {
253
265
  toUpdate.push(point);
254
266
  }
@@ -256,11 +268,36 @@ export class RewardService {
256
268
  toCreate.push(point);
257
269
  }
258
270
  }
259
- await RewardRepository.updatePendings(rewardTokenId, data.root, campaignId, toUpdate);
260
- await RewardRepository.createPendings(rewardTokenId, data.root, campaignId, toCreate);
271
+ await RewardRepository.updateBreakdownPendings(rewardTokenId, data.root, campaignId, toUpdate);
272
+ await RewardRepository.createBreakdownPendings(rewardTokenId, data.root, campaignId, toCreate);
261
273
  totalCreated += toCreate.length;
262
274
  totalUpdated += toUpdate.length;
263
275
  }
276
+ try {
277
+ for (let i = 0; i < Object.keys(rewardUniques).length; i += 1_000) {
278
+ const toUpdate = [];
279
+ const toCreate = [];
280
+ const exists = await RewardRepository.findManyRewardUniques(Object.keys(rewardUniques).slice(i, Math.min(i + 1_000, Object.keys(rewardUniques).length)));
281
+ for (const [pointIndex, point] of Object.values(rewardUniques)
282
+ .slice(i, Math.min(i + 1_000, Object.keys(rewardUniques).length))
283
+ .entries()) {
284
+ if (!!exists[pointIndex]) {
285
+ toUpdate.push({
286
+ ...point,
287
+ pending: (BigInt(exists[pointIndex].pending) + BigInt(point.pending)).toString(),
288
+ });
289
+ }
290
+ else {
291
+ toCreate.push(point);
292
+ }
293
+ }
294
+ await RewardRepository.updateRewardPendings(rewardTokenId, data.root, toUpdate);
295
+ await RewardRepository.createRewardPendings(rewardTokenId, data.root, toCreate);
296
+ }
297
+ }
298
+ catch (e) {
299
+ log.error("updatePendings - error updating reward pendings", e);
300
+ }
264
301
  return { created: totalCreated, updated: totalUpdated };
265
302
  }
266
303
  static async countAllchains() {
@@ -1190,18 +1190,20 @@ export declare const v4: Elysia<"/v4", false, {
1190
1190
  };
1191
1191
  } & {
1192
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[];
1193
+ index: {
1194
+ get: {
1195
+ body: unknown;
1196
+ params: {};
1197
+ query: {
1198
+ items?: number | undefined;
1199
+ page?: number | undefined;
1200
+ chainId: number;
1201
+ address: string;
1202
+ };
1203
+ headers: unknown;
1204
+ response: {
1205
+ 200: import("./reward").BreakdownForTokenRaw[];
1206
+ };
1205
1207
  };
1206
1208
  };
1207
1209
  };
@@ -1250,22 +1252,27 @@ export declare const v4: Elysia<"/v4", false, {
1250
1252
  };
1251
1253
  } & {
1252
1254
  engine: {
1253
- post: {
1254
- body: {
1255
- recipient: string;
1256
- distributionChainId: number;
1257
- root: string;
1258
- proofs: string[];
1259
- rewardToken: string;
1260
- }[];
1261
- params: {};
1262
- query: unknown;
1263
- headers: {
1264
- authorization: string;
1265
- };
1266
- response: {
1267
- 200: {
1268
- count: number;
1255
+ index: {
1256
+ post: {
1257
+ body: {
1258
+ pending: string;
1259
+ recipient: string;
1260
+ distributionChainId: number;
1261
+ amount: string;
1262
+ root: string;
1263
+ claimed: string;
1264
+ proofs: string[];
1265
+ rewardToken: string;
1266
+ }[];
1267
+ params: {};
1268
+ query: unknown;
1269
+ headers: {
1270
+ authorization: string;
1271
+ };
1272
+ response: {
1273
+ 200: {
1274
+ count: number;
1275
+ };
1269
1276
  };
1270
1277
  };
1271
1278
  };