@merkl/api 0.10.168 → 0.10.170

Sign up to get free protection for your applications and to get access to all the features.
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
+ }