@merkl/api 0.10.168 → 0.10.170

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 (97) hide show
  1. package/dist/database/api/.generated/edge.js +6 -3
  2. package/dist/database/api/.generated/index-browser.js +3 -0
  3. package/dist/database/api/.generated/index.d.ts +113 -0
  4. package/dist/database/api/.generated/index.js +6 -3
  5. package/dist/database/api/.generated/package.json +1 -1
  6. package/dist/database/api/.generated/schema.prisma +17 -15
  7. package/dist/database/api/.generated/wasm.js +3 -0
  8. package/dist/src/cache/declaration.d.ts +0 -30
  9. package/dist/src/cache/declaration.js +0 -30
  10. package/dist/src/eden/index.d.ts +167 -15
  11. package/dist/src/index.d.ts +59 -5
  12. package/dist/src/libs/campaigns/campaignTypes/CLAMMDynamicData.js +2 -2
  13. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/factoryFinder.js +2 -0
  14. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.d.ts +3 -1
  15. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.js +8 -0
  16. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/PendleYTProcessor.d.ts +29 -0
  17. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/PendleYTProcessor.js +31 -0
  18. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/processorMapping.js +3 -0
  19. package/dist/src/libs/positions/clamm/index.d.ts +1 -2
  20. package/dist/src/libs/positions/clamm/index.js +322 -330
  21. package/dist/src/libs/positions/clamm/thegraph/fetchAlmPositions.d.ts +1 -1
  22. package/dist/src/libs/positions/clamm/thegraph/fetchAlmPositions.js +1 -1
  23. package/dist/src/libs/positions/clamm/thegraph/fetchAmmPositions.d.ts +1 -1
  24. package/dist/src/libs/positions/clamm/thegraph/fetchAmmPositions.js +2 -2
  25. package/dist/src/libs/positions/clamm/thegraph/fetchFarmedPositions.d.ts +1 -2
  26. package/dist/src/libs/positions/clamm/thegraph/fetchFarmedPositions.js +1 -4
  27. package/dist/src/libs/positions/euler/index.js +2 -3
  28. package/dist/src/libs/positions/index.js +1 -1
  29. package/dist/src/modules/v4/campaign/campaign.controller.d.ts +6 -2
  30. package/dist/src/modules/v4/campaign/campaign.model.d.ts +1 -0
  31. package/dist/src/modules/v4/campaign/campaign.model.js +1 -0
  32. package/dist/src/modules/v4/campaign/campaign.repository.d.ts +2 -0
  33. package/dist/src/modules/v4/campaign/campaign.repository.js +2 -1
  34. package/dist/src/modules/v4/campaign/campaign.service.d.ts +10 -5
  35. package/dist/src/modules/v4/campaign/campaign.service.js +10 -2
  36. package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +20 -3
  37. package/dist/src/modules/v4/opportunity/opportunity.model.d.ts +2 -1
  38. package/dist/src/modules/v4/opportunity/opportunity.model.js +1 -0
  39. package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +83 -5
  40. package/dist/src/modules/v4/opportunity/opportunity.repository.js +31 -0
  41. package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +162 -8
  42. package/dist/src/modules/v4/opportunity/opportunity.service.js +11 -0
  43. package/dist/src/modules/v4/position/implementations/AjnaPositionFetcher.d.ts +6 -0
  44. package/dist/src/modules/v4/position/implementations/AjnaPositionFetcher.js +90 -0
  45. package/dist/src/modules/v4/position/implementations/BadgerPositionFetcher.d.ts +6 -0
  46. package/dist/src/modules/v4/position/implementations/BadgerPositionFetcher.js +69 -0
  47. package/dist/src/modules/v4/position/implementations/ClammPositionFetcher.d.ts +6 -0
  48. package/dist/src/modules/v4/position/implementations/ClammPositionFetcher.js +71 -0
  49. package/dist/src/modules/v4/position/implementations/DolomitePositionFetcher.d.ts +6 -0
  50. package/dist/src/modules/v4/position/implementations/DolomitePositionFetcher.js +45 -0
  51. package/dist/src/modules/v4/position/implementations/ERC20PositionFetcher.d.ts +6 -0
  52. package/dist/src/modules/v4/position/implementations/ERC20PositionFetcher.js +47 -0
  53. package/dist/src/modules/v4/position/implementations/EulerPositionFetcher.d.ts +6 -0
  54. package/dist/src/modules/v4/position/implementations/EulerPositionFetcher.js +40 -0
  55. package/dist/src/modules/v4/position/index.d.ts +2 -0
  56. package/dist/src/modules/v4/position/index.js +2 -0
  57. package/dist/src/modules/v4/position/position.controller.d.ts +39 -0
  58. package/dist/src/modules/v4/position/position.controller.js +16 -0
  59. package/dist/src/modules/v4/position/position.model.d.ts +25 -0
  60. package/dist/src/modules/v4/position/position.model.js +5 -0
  61. package/dist/src/modules/v4/position/position.repository.d.ts +14 -0
  62. package/dist/src/modules/v4/position/position.repository.js +6 -0
  63. package/dist/src/modules/v4/position/position.service.d.ts +5 -0
  64. package/dist/src/modules/v4/position/position.service.js +34 -0
  65. package/dist/src/modules/v4/price/price.controller.js +1 -1
  66. package/dist/src/modules/v4/price/price.service.d.ts +1 -1
  67. package/dist/src/modules/v4/price/price.service.js +3 -3
  68. package/dist/src/modules/v4/reward/reward.repository.d.ts +4 -0
  69. package/dist/src/modules/v4/reward/reward.service.d.ts +27 -0
  70. package/dist/src/modules/v4/reward/reward.service.js +5 -2
  71. package/dist/src/modules/v4/router.d.ts +59 -5
  72. package/dist/src/modules/v4/router.js +3 -1
  73. package/dist/src/modules/v4/token/token.controller.d.ts +6 -0
  74. package/dist/src/modules/v4/token/token.service.d.ts +12 -0
  75. package/dist/src/modules/v4/user/user.controller.d.ts +8 -0
  76. package/dist/src/routes/v1/prices.js +2 -4
  77. package/dist/src/routes/v3/blacklist.d.ts +59 -5
  78. package/dist/src/routes/v3/campaigns.d.ts +60 -6
  79. package/dist/src/routes/v3/campaignsInfo.d.ts +59 -5
  80. package/dist/src/routes/v3/multiChainPositions.d.ts +59 -5
  81. package/dist/src/routes/v3/opportunity.d.ts +59 -5
  82. package/dist/src/routes/v3/positions.d.ts +59 -5
  83. package/dist/src/routes/v3/recipients.d.ts +6 -2
  84. package/dist/src/routes/v3/recipients.js +14 -8
  85. package/dist/src/routes/v3/rewards.d.ts +59 -5
  86. package/dist/src/routes/v3/updates.d.ts +59 -5
  87. package/dist/src/routes/v3/userRewards.d.ts +59 -5
  88. package/dist/src/utils/decodeCalls.js +4 -1
  89. package/dist/src/utils/encodeCalls.js +4 -1
  90. package/dist/src/utils/generateCardName.js +2 -0
  91. package/dist/src/utils/prices/services/erc4626Service.js +10 -4
  92. package/dist/tsconfig.package.tsbuildinfo +1 -1
  93. package/package.json +1 -1
  94. package/dist/src/libs/reports/campaignReport.d.ts +0 -9
  95. package/dist/src/libs/reports/campaignReport.js +0 -37
  96. package/dist/src/libs/reports/mainParameterRewards.d.ts +0 -3
  97. package/dist/src/libs/reports/mainParameterRewards.js +0 -48
@@ -1,7 +1,7 @@
1
1
  import { type CreateCampaignModel } from "../campaign";
2
2
  import { Prisma } from "../../../../database/api/.generated";
3
- import { type ChainId } from "@sdk";
4
- import type { CreateOpportunityModel, GetOpportunitiesQueryEntity, LightOpportunityFromDB, OpportunityMetadata, OpportunityUnique } from "./opportunity.model";
3
+ import { type ChainId, type MerklChainId } from "@sdk";
4
+ import type { CreateOpportunityModel, GetOpportunitiesQueryModel, LightOpportunityFromDB, OpportunityMetadata, OpportunityUnique } from "./opportunity.model";
5
5
  import { OpportunityRepository } from "./opportunity.repository";
6
6
  export declare abstract class OpportunityService {
7
7
  static hashId(opportunity: OpportunityUnique): string;
@@ -60,7 +60,9 @@ export declare abstract class OpportunityService {
60
60
  address: string;
61
61
  icon: string;
62
62
  decimals: number;
63
+ displaySymbol: string;
63
64
  verified: boolean;
65
+ isTest: boolean;
64
66
  price: number | null;
65
67
  };
66
68
  amount: bigint;
@@ -75,7 +77,9 @@ export declare abstract class OpportunityService {
75
77
  address: string;
76
78
  icon: string;
77
79
  decimals: number;
80
+ displaySymbol: string;
78
81
  verified: boolean;
82
+ isTest: boolean;
79
83
  price: number | null;
80
84
  }[];
81
85
  chain: {
@@ -102,7 +106,7 @@ export declare abstract class OpportunityService {
102
106
  apr: number;
103
107
  dailyRewards: number;
104
108
  } & {
105
- campaigns: ({
109
+ campaigns: {
106
110
  params: any;
107
111
  chain: {
108
112
  name: string;
@@ -117,7 +121,9 @@ export declare abstract class OpportunityService {
117
121
  address: string;
118
122
  icon: string;
119
123
  decimals: number;
124
+ displaySymbol: string;
120
125
  verified: boolean;
126
+ isTest: boolean;
121
127
  price: number | null;
122
128
  };
123
129
  distributionChain: {
@@ -145,7 +151,7 @@ export declare abstract class OpportunityService {
145
151
  amount: string;
146
152
  opportunityId: string;
147
153
  creatorAddress: string;
148
- } | null)[];
154
+ }[];
149
155
  }) | null>;
150
156
  static getUniqueOrThrow(opportunityId: string | OpportunityUnique): Promise<{
151
157
  aprRecord: {
@@ -188,7 +194,9 @@ export declare abstract class OpportunityService {
188
194
  address: string;
189
195
  icon: string;
190
196
  decimals: number;
197
+ displaySymbol: string;
191
198
  verified: boolean;
199
+ isTest: boolean;
192
200
  price: number | null;
193
201
  };
194
202
  amount: bigint;
@@ -203,7 +211,9 @@ export declare abstract class OpportunityService {
203
211
  address: string;
204
212
  icon: string;
205
213
  decimals: number;
214
+ displaySymbol: string;
206
215
  verified: boolean;
216
+ isTest: boolean;
207
217
  price: number | null;
208
218
  }[];
209
219
  chain: {
@@ -235,7 +245,7 @@ export declare abstract class OpportunityService {
235
245
  * @param query
236
246
  * @returns A list of opportunities
237
247
  */
238
- static getMany(query: GetOpportunitiesQueryEntity): Promise<({
248
+ static getMany(query: GetOpportunitiesQueryModel): Promise<({
239
249
  aprRecord: {
240
250
  cumulated: number;
241
251
  timestamp: bigint;
@@ -276,7 +286,9 @@ export declare abstract class OpportunityService {
276
286
  address: string;
277
287
  icon: string;
278
288
  decimals: number;
289
+ displaySymbol: string;
279
290
  verified: boolean;
291
+ isTest: boolean;
280
292
  price: number | null;
281
293
  };
282
294
  amount: bigint;
@@ -291,7 +303,9 @@ export declare abstract class OpportunityService {
291
303
  address: string;
292
304
  icon: string;
293
305
  decimals: number;
306
+ displaySymbol: string;
294
307
  verified: boolean;
308
+ isTest: boolean;
295
309
  price: number | null;
296
310
  }[];
297
311
  chain: {
@@ -318,6 +332,140 @@ export declare abstract class OpportunityService {
318
332
  apr: number;
319
333
  dailyRewards: number;
320
334
  } | null)[]>;
335
+ static findLiveWithFirstCampaign(chainId: MerklChainId): Promise<({
336
+ aprRecord: {
337
+ cumulated: number;
338
+ timestamp: bigint;
339
+ breakdowns: {
340
+ type: import("../../../../database/api/.generated").$Enums.AprType;
341
+ id: number;
342
+ identifier: string;
343
+ value: number;
344
+ aprRecordId: string;
345
+ }[];
346
+ };
347
+ tvlRecord: {
348
+ id: string;
349
+ total: number;
350
+ timestamp: bigint;
351
+ breakdowns: {
352
+ type: import("../../../../database/api/.generated").$Enums.TvlType;
353
+ id: number;
354
+ identifier: string;
355
+ value: number;
356
+ tvlRecordId: string;
357
+ }[];
358
+ };
359
+ rewardsRecord: {
360
+ id: string;
361
+ total: number;
362
+ timestamp: bigint;
363
+ breakdowns: {
364
+ id: number;
365
+ value: number;
366
+ campaignId: string;
367
+ dailyRewardsRecordId: string;
368
+ token: {
369
+ symbol: string;
370
+ name: string | null;
371
+ id: string;
372
+ chainId: number;
373
+ address: string;
374
+ icon: string;
375
+ decimals: number;
376
+ displaySymbol: string;
377
+ verified: boolean;
378
+ isTest: boolean;
379
+ price: number | null;
380
+ };
381
+ amount: bigint;
382
+ }[];
383
+ };
384
+ id: string;
385
+ tokens: {
386
+ symbol: string;
387
+ name: string | null;
388
+ id: string;
389
+ chainId: number;
390
+ address: string;
391
+ icon: string;
392
+ decimals: number;
393
+ displaySymbol: string;
394
+ verified: boolean;
395
+ isTest: boolean;
396
+ price: number | null;
397
+ }[];
398
+ chain: {
399
+ name: string;
400
+ id: number;
401
+ icon: string;
402
+ };
403
+ protocol: {
404
+ name: string;
405
+ url: string;
406
+ description: string;
407
+ id: string;
408
+ tags: import("../../../../database/api/.generated").$Enums.ProtocolTag[];
409
+ icon: string;
410
+ } | undefined;
411
+ name: string;
412
+ type: import("../../../../database/api/.generated").$Enums.CampaignType;
413
+ status: import("../../../../database/api/.generated").$Enums.Status;
414
+ tags: string[];
415
+ identifier: string;
416
+ chainId: number;
417
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
418
+ tvl: number;
419
+ apr: number;
420
+ dailyRewards: number;
421
+ } & {
422
+ campaigns: {
423
+ params: any;
424
+ chain: {
425
+ name: string;
426
+ id: number;
427
+ icon: string;
428
+ };
429
+ rewardToken: {
430
+ symbol: string;
431
+ name: string | null;
432
+ id: string;
433
+ chainId: number;
434
+ address: string;
435
+ icon: string;
436
+ decimals: number;
437
+ displaySymbol: string;
438
+ verified: boolean;
439
+ isTest: boolean;
440
+ price: number | null;
441
+ };
442
+ distributionChain: {
443
+ name: string;
444
+ id: number;
445
+ icon: string;
446
+ } | undefined;
447
+ campaignStatus: {
448
+ error: string;
449
+ details: Prisma.JsonValue;
450
+ status: import("../../../../database/api/.generated").$Enums.RunStatus;
451
+ campaignId: string;
452
+ computedUntil: bigint;
453
+ processingStarted: bigint;
454
+ };
455
+ type: import("../../../../database/api/.generated").$Enums.CampaignType;
456
+ id: string;
457
+ subType: number | null;
458
+ startTimestamp: bigint;
459
+ endTimestamp: bigint;
460
+ computeChainId: number;
461
+ distributionChainId: number;
462
+ campaignId: string;
463
+ rewardTokenId: string;
464
+ amount: string;
465
+ opportunityId: string;
466
+ creatorAddress: string;
467
+ }[];
468
+ })[]>;
321
469
  static getAllIds(): Promise<{
322
470
  id: string;
323
471
  }[]>;
@@ -327,7 +475,7 @@ export declare abstract class OpportunityService {
327
475
  * @param query
328
476
  * @returns the number of opportunities
329
477
  */
330
- static countMany(query: GetOpportunitiesQueryEntity): Promise<number>;
478
+ static countMany(query: GetOpportunitiesQueryModel): Promise<number>;
331
479
  static formatResponse(opportunity: Awaited<ReturnType<typeof OpportunityRepository.findUniqueOrThrow>>): {
332
480
  aprRecord: {
333
481
  cumulated: number;
@@ -369,7 +517,9 @@ export declare abstract class OpportunityService {
369
517
  address: string;
370
518
  icon: string;
371
519
  decimals: number;
520
+ displaySymbol: string;
372
521
  verified: boolean;
522
+ isTest: boolean;
373
523
  price: number | null;
374
524
  };
375
525
  amount: bigint;
@@ -384,7 +534,9 @@ export declare abstract class OpportunityService {
384
534
  address: string;
385
535
  icon: string;
386
536
  decimals: number;
537
+ displaySymbol: string;
387
538
  verified: boolean;
539
+ isTest: boolean;
388
540
  price: number | null;
389
541
  }[];
390
542
  chain: {
@@ -421,7 +573,9 @@ export declare abstract class OpportunityService {
421
573
  address: string;
422
574
  icon: string;
423
575
  decimals: number;
576
+ displaySymbol: string;
424
577
  verified: boolean;
578
+ isTest: boolean;
425
579
  price: number | null;
426
580
  }[];
427
581
  chain: {
@@ -448,7 +602,7 @@ export declare abstract class OpportunityService {
448
602
  apr: number;
449
603
  dailyRewards: number;
450
604
  };
451
- static aggregate(query: GetOpportunitiesQueryEntity, field: keyof Prisma.OpportunitySumAggregateInputType): Promise<{
452
- sum: never;
605
+ static aggregate(query: GetOpportunitiesQueryModel, field: keyof Prisma.OpportunitySumAggregateInputType): Promise<{
606
+ sum: number | null;
453
607
  }>;
454
608
  }
@@ -152,6 +152,17 @@ export class OpportunityService {
152
152
  }, query);
153
153
  });
154
154
  }
155
+ static async findLiveWithFirstCampaign(chainId) {
156
+ return record("data-layer.access", async () => {
157
+ return await CacheService.wrap(TTLPresets.MIN_10, async (chainId) => {
158
+ const opportunities = await OpportunityRepository.findLiveWithFirstCampaign(chainId);
159
+ return opportunities.map(o => {
160
+ const formatted = OpportunityService.formatResponse(o);
161
+ return Object.assign(formatted, { campaigns: o.Campaigns.map(CampaignService.format) });
162
+ });
163
+ }, chainId);
164
+ });
165
+ }
155
166
  static async getAllIds() {
156
167
  return await OpportunityRepository.getAllIdsForDynamicOpp();
157
168
  }
@@ -0,0 +1,6 @@
1
+ import { type MerklChainId } from "@sdk";
2
+ import type { Opportunity } from "../../opportunity";
3
+ import type { PositionFetcher } from "../position.model";
4
+ export declare class AjnaPositionFetcher implements PositionFetcher {
5
+ fetchPositions: (chainId: MerklChainId, user: string, opportunities: Opportunity["model"][]) => Promise<import("..").PositionT[]>;
6
+ }
@@ -0,0 +1,90 @@
1
+ import { AjnaSubCampaignType, BN2Number, Campaign, ChainInteractionService, NETWORK_LABELS, POOL_INFO_UTILS, PoolInfoUtilsInterface, } from "@sdk";
2
+ import axios from "axios";
3
+ import { CampaignService } from "../../campaign";
4
+ const campaignType = Campaign.AJNA;
5
+ export class AjnaPositionFetcher {
6
+ fetchPositions = async (chainId, user, opportunities) => {
7
+ opportunities = opportunities.filter(o => o.type === Campaign[campaignType] && o.tokens?.length > 0 && o.chainId === chainId && !!o?.campaigns?.length);
8
+ const calls = [];
9
+ for (const opportunity of opportunities) {
10
+ const campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
11
+ // Call per opportunity
12
+ if (campaign.campaignSubType === AjnaSubCampaignType.lend) {
13
+ calls.push({
14
+ allowFailure: true,
15
+ callData: PoolInfoUtilsInterface.encodeFunctionData("poolPricesInfo", [campaign.campaignParameters.poolId]),
16
+ target: POOL_INFO_UTILS[chainId],
17
+ });
18
+ }
19
+ else {
20
+ calls.push({
21
+ allowFailure: true,
22
+ callData: PoolInfoUtilsInterface.encodeFunctionData("borrowerInfo", [
23
+ campaign.campaignParameters.poolId,
24
+ user,
25
+ ]),
26
+ target: POOL_INFO_UTILS[chainId],
27
+ });
28
+ }
29
+ }
30
+ const res = await ChainInteractionService(chainId).fetchState(calls);
31
+ const result = [];
32
+ for (const [index, opportunity] of opportunities.entries()) {
33
+ // Decoding per opportunity
34
+ const campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
35
+ let userSupply = 0;
36
+ // @Lamicham it's not scalable at all to do this.. We do 1 call per opportunity, sequentially, so it ends up
37
+ // slowing the whole position route
38
+ const resAjna = await axios.get(`https://ajna-api.blockanalitica.com/v4/${NETWORK_LABELS[chainId].toLowerCase()}/wallets/${user.toLowerCase()}/pools/${campaign.campaignParameters.poolId.toLowerCase()}/buckets/?p=1&p_size=50`);
39
+ if (resAjna.data.count === 0) {
40
+ continue;
41
+ }
42
+ if (campaign.campaignSubType === AjnaSubCampaignType.lend) {
43
+ const htpIndex = PoolInfoUtilsInterface.decodeFunctionResult("poolPricesInfo", res[index].returnData)[3];
44
+ const lupIndex = PoolInfoUtilsInterface.decodeFunctionResult("poolPricesInfo", res[index].returnData)[5];
45
+ const threshold = BN2Number(BN2Number(lupIndex, 0) === 0 ? lupIndex : lupIndex.gt(htpIndex) ? lupIndex.add(22) : htpIndex.add(22), 0);
46
+ let nextRoute = null;
47
+ if (!!resAjna.data.next) {
48
+ nextRoute = `https://${resAjna.data.next.slice(resAjna.data.next.indexOf(":") + 1)}`;
49
+ }
50
+ let position;
51
+ for (position of resAjna.data.results) {
52
+ if (position.bucket_index < threshold) {
53
+ userSupply += Number(position.deposit);
54
+ }
55
+ }
56
+ while (nextRoute !== null) {
57
+ const resNext = await axios.get(nextRoute);
58
+ let position;
59
+ for (position of resNext.data.results) {
60
+ if (position.bucket_index < threshold) {
61
+ userSupply += Number(position.deposit);
62
+ }
63
+ }
64
+ if (!!resNext.data.next) {
65
+ nextRoute = `https://${resNext.data.next.slice(resNext.data.next.indexOf(":") + 1)}`;
66
+ }
67
+ else {
68
+ nextRoute = null;
69
+ }
70
+ }
71
+ }
72
+ else {
73
+ userSupply = BN2Number(PoolInfoUtilsInterface.decodeFunctionResult("borrowerInfo", res[index].returnData)[0], 18);
74
+ }
75
+ if (userSupply > 0) {
76
+ result.push({
77
+ flags: {},
78
+ opportunity,
79
+ tokens: [
80
+ {
81
+ token: opportunity.tokens.find(t => t.address === campaign.campaignParameters.quoteToken),
82
+ breakdown: [{ type: "balance", value: userSupply }],
83
+ },
84
+ ],
85
+ });
86
+ }
87
+ }
88
+ return result;
89
+ };
90
+ }
@@ -0,0 +1,6 @@
1
+ import { type MerklChainId } from "@sdk";
2
+ import type { Opportunity } from "../../opportunity";
3
+ import type { PositionFetcher, PositionT } from "../position.model";
4
+ export declare class BadgerPositionFetcher implements PositionFetcher {
5
+ fetchPositions: (chainId: MerklChainId, user: string, opportunities: Opportunity["model"][]) => Promise<PositionT[]>;
6
+ }
@@ -0,0 +1,69 @@
1
+ import { CDPMANAGER_ADDRESS, SORTEDCDPS_ADDRESS } from "../../../../constants";
2
+ import { BN2Number, Campaign, CdpManagerInterface, ChainInteractionService, ERC20Interface, SortedCdpsInterface, } from "@sdk";
3
+ import { CampaignService } from "../../campaign";
4
+ const campaignType = Campaign.BADGER;
5
+ export class BadgerPositionFetcher {
6
+ fetchPositions = async (chainId, user, opportunities) => {
7
+ opportunities = opportunities.filter(o => o.type === Campaign[campaignType] && o.tokens?.length > 0 && o.chainId === chainId);
8
+ const calls = [];
9
+ calls.push({
10
+ allowFailure: false,
11
+ callData: CdpManagerInterface.encodeFunctionData("getSystemDebt"),
12
+ target: CDPMANAGER_ADDRESS,
13
+ });
14
+ for (const opportunity of opportunities) {
15
+ // Call per opportunity
16
+ const _campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
17
+ calls.push({
18
+ allowFailure: false,
19
+ callData: SortedCdpsInterface.encodeFunctionData("getCdpsOf", [user]),
20
+ target: SORTEDCDPS_ADDRESS,
21
+ });
22
+ for (const _token of opportunity.tokens) {
23
+ // Call per token
24
+ }
25
+ }
26
+ const res = await ChainInteractionService(chainId).fetchState(calls);
27
+ const result = [];
28
+ let i = 0;
29
+ const totalSupplyEBTC = BN2Number(CdpManagerInterface.decodeFunctionResult("getSystemDebt", res[i++].returnData)[0], 18);
30
+ for (const [index, opportunity] of opportunities.entries()) {
31
+ // Decoding per opportunity
32
+ const campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
33
+ let userSupply = 0;
34
+ const cdps = SortedCdpsInterface.decodeFunctionResult("getCdpsOf", res[i++].returnData)[0];
35
+ if (cdps.length !== 0) {
36
+ const secondCalls = cdps.map((cdp) => {
37
+ return {
38
+ allowFailure: false,
39
+ callData: CdpManagerInterface.encodeFunctionData("Cdps", cdp),
40
+ target: CDPMANAGER_ADDRESS,
41
+ };
42
+ });
43
+ const secondRes = await ChainInteractionService(chainId).fetchState(secondCalls);
44
+ cdps.forEach((cdp, j) => {
45
+ const cdpSupply = CdpManagerInterface.decodeFunctionResult("Cdps", secondRes[j].returnData)[0];
46
+ userSupply += BN2Number(cdpSupply, campaign.campaignParameters.decimalsTargetToken);
47
+ });
48
+ }
49
+ for (const [subIndex, token] of opportunity.tokens.entries()) {
50
+ // Decoding per token
51
+ const balance = ERC20Interface.decodeFunctionResult("balanceOf", res[index + subIndex].returnData)[0].toString();
52
+ if (BigInt(balance) > 0n) {
53
+ const position = {
54
+ flags: {},
55
+ opportunity,
56
+ tokens: [
57
+ {
58
+ token,
59
+ breakdown: [{ type: "balance", value: BN2Number(balance, token.decimals) }],
60
+ },
61
+ ],
62
+ };
63
+ result.push(position);
64
+ }
65
+ }
66
+ }
67
+ return result;
68
+ };
69
+ }
@@ -0,0 +1,6 @@
1
+ import { type MerklChainId } from "@sdk";
2
+ import type { Opportunity } from "../../opportunity";
3
+ import type { PositionFetcher, PositionT } from "../position.model";
4
+ export declare class ClammPositionFetcher implements PositionFetcher {
5
+ fetchPositions: (chainId: MerklChainId, user: string, opportunities: Opportunity["model"][]) => Promise<PositionT[]>;
6
+ }
@@ -0,0 +1,71 @@
1
+ import { getClammUserPositions } from "../../../../libs/positions/clamm";
2
+ import { Campaign } from "@sdk";
3
+ import { CampaignService } from "../../campaign";
4
+ const campaignType = Campaign.CLAMM;
5
+ export class ClammPositionFetcher {
6
+ fetchPositions = async (chainId, user, opportunities) => {
7
+ opportunities = opportunities.filter(o => o.type === Campaign[campaignType] && o.tokens?.length > 0 && o.chainId === chainId);
8
+ // AMM => pool address => pool data
9
+ const poolsByAmm = {};
10
+ for (const opportunity of opportunities) {
11
+ // Call per opportunity
12
+ const campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
13
+ if (!poolsByAmm[campaign.campaignParameters.amm]) {
14
+ poolsByAmm[campaign.campaignParameters.amm] = {};
15
+ }
16
+ if (!poolsByAmm[campaign.campaignParameters.amm][campaign.campaignParameters.poolAddress]) {
17
+ poolsByAmm[campaign.campaignParameters.amm][campaign.campaignParameters.poolAddress] = {
18
+ token0: campaign.campaignParameters.token0,
19
+ token1: campaign.campaignParameters.token1,
20
+ symbolToken0: campaign.campaignParameters.symbolToken0,
21
+ symbolToken1: campaign.campaignParameters.symbolToken1,
22
+ decimalsToken0: campaign.campaignParameters.decimalsToken0,
23
+ decimalsToken1: campaign.campaignParameters.decimalsToken1,
24
+ mainParameter: campaign.mainParameter,
25
+ forwarders: {},
26
+ };
27
+ }
28
+ }
29
+ console.log(poolsByAmm);
30
+ const clammPositions = await getClammUserPositions(user, chainId, poolsByAmm, false);
31
+ console.log(clammPositions);
32
+ const result = [];
33
+ for (const opportunity of opportunities) {
34
+ const campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
35
+ const clammPosition = clammPositions[`2_${campaign.campaignParameters.poolAddress}`];
36
+ const poolData = poolsByAmm[campaign.campaignParameters.amm][campaign.campaignParameters.poolAddress];
37
+ if (!!clammPosition) {
38
+ const position = {
39
+ flags: {},
40
+ opportunity,
41
+ tokens: [
42
+ {
43
+ token: {
44
+ address: poolData.token0,
45
+ decimals: poolData.decimalsToken0,
46
+ symbol: poolData.symbolToken0,
47
+ },
48
+ breakdown: [
49
+ { type: "balance", value: clammPosition.userBalanceToken0 },
50
+ { type: "liquidity", value: clammPosition.userInRangeLiquidity },
51
+ ],
52
+ },
53
+ {
54
+ token: {
55
+ address: poolData.token1,
56
+ decimals: poolData.decimalsToken1,
57
+ symbol: poolData.symbolToken1,
58
+ },
59
+ breakdown: [
60
+ { type: "balance", value: clammPosition.userBalanceToken1 },
61
+ { type: "liquidity", value: clammPosition.userInRangeLiquidity },
62
+ ],
63
+ },
64
+ ],
65
+ };
66
+ result.push(position);
67
+ }
68
+ }
69
+ return result;
70
+ };
71
+ }
@@ -0,0 +1,6 @@
1
+ import { type MerklChainId } from "@sdk";
2
+ import type { Opportunity } from "../../opportunity";
3
+ import type { PositionFetcher } from "../position.model";
4
+ export declare class DolomitePositionFetcher implements PositionFetcher {
5
+ fetchPositions: (chainId: MerklChainId, user: string, opportunities: Opportunity["model"][]) => Promise<import("..").PositionT[]>;
6
+ }
@@ -0,0 +1,45 @@
1
+ import { Campaign } from "@sdk";
2
+ import { utils } from "ethers";
3
+ import { CampaignService } from "../../campaign";
4
+ import { PositionRepository } from "../position.repository";
5
+ const campaignType = Campaign.DOLOMITE;
6
+ export class DolomitePositionFetcher {
7
+ fetchPositions = async (chainId, user, opportunities) => {
8
+ opportunities = opportunities.filter(o => o.type === Campaign[campaignType] && o.tokens?.length > 0 && o.chainId === chainId);
9
+ const dolomitePositions = await PositionRepository.findManyDolomitePositions(chainId, user);
10
+ // Generic calls
11
+ for (const opportunity of opportunities) {
12
+ // Call per opportunity
13
+ const _campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
14
+ for (const _token of opportunity.tokens) {
15
+ // Call per token
16
+ }
17
+ }
18
+ const result = [];
19
+ // Decoding Generic calls
20
+ for (const [_index, opportunity] of opportunities.entries()) {
21
+ const campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
22
+ // Decoding per opportunity
23
+ const positionIndex = dolomitePositions.findIndex(y => utils.getAddress(y.token.id) === campaign.campaignParameters.targetToken);
24
+ const position = positionIndex >= 0 ? dolomitePositions[positionIndex] : undefined;
25
+ if (!position)
26
+ continue;
27
+ const borrowBalance = Number.parseFloat(position.token.borrowLiquidity);
28
+ const supplyBalance = Number.parseFloat(position.token.supplyLiquidity);
29
+ result.push({
30
+ flags: {},
31
+ opportunity,
32
+ tokens: [
33
+ {
34
+ token: opportunity.tokens.find(t => utils.getAddress(t.address) === campaign.campaignParameters.targetToken),
35
+ breakdown: [
36
+ { type: "borrowed", value: borrowBalance },
37
+ { type: "supplied", value: supplyBalance },
38
+ ],
39
+ },
40
+ ],
41
+ });
42
+ }
43
+ return result;
44
+ };
45
+ }
@@ -0,0 +1,6 @@
1
+ import { type MerklChainId } from "@sdk";
2
+ import type { Opportunity } from "../../opportunity";
3
+ import type { PositionFetcher, PositionT } from "../position.model";
4
+ export declare class ERC20PositionFetcher implements PositionFetcher {
5
+ fetchPositions: (chainId: MerklChainId, user: string, opportunities: Opportunity["model"][]) => Promise<PositionT[]>;
6
+ }
@@ -0,0 +1,47 @@
1
+ import { BN2Number, Campaign, ChainInteractionService, ERC20Interface } from "@sdk";
2
+ import { CampaignService } from "../../campaign";
3
+ const campaignType = Campaign.ERC20;
4
+ export class ERC20PositionFetcher {
5
+ fetchPositions = async (chainId, user, opportunities) => {
6
+ opportunities = opportunities.filter(o => o.type === Campaign[campaignType] && o.tokens?.length > 0 && o.chainId === chainId);
7
+ const calls = [];
8
+ // Generic calls
9
+ for (const opportunity of opportunities) {
10
+ // Call per opportunity
11
+ const _campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
12
+ for (const token of opportunity.tokens) {
13
+ // Call per token
14
+ calls.push({
15
+ allowFailure: true,
16
+ callData: ERC20Interface.encodeFunctionData("balanceOf", [user]),
17
+ target: token.address,
18
+ });
19
+ }
20
+ }
21
+ const res = await ChainInteractionService(chainId).fetchState(calls);
22
+ const result = [];
23
+ // Decoding Generic calls
24
+ for (const [index, opportunity] of opportunities.entries()) {
25
+ // Decoding per opportunity
26
+ const _campaign = CampaignService.formatAsCampaignParameters(opportunity.campaigns[0]);
27
+ for (const [subIndex, token] of opportunity.tokens.entries()) {
28
+ // Decoding per token
29
+ const balance = ERC20Interface.decodeFunctionResult("balanceOf", res[index + subIndex].returnData)[0].toString();
30
+ if (BigInt(balance) > 0n) {
31
+ const position = {
32
+ flags: {},
33
+ opportunity,
34
+ tokens: [
35
+ {
36
+ token,
37
+ breakdown: [{ type: "balance", value: BN2Number(balance, token.decimals) }],
38
+ },
39
+ ],
40
+ };
41
+ result.push(position);
42
+ }
43
+ }
44
+ }
45
+ return result;
46
+ };
47
+ }