@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.
- package/dist/database/api/.generated/edge.js +6 -3
- package/dist/database/api/.generated/index-browser.js +3 -0
- package/dist/database/api/.generated/index.d.ts +113 -0
- package/dist/database/api/.generated/index.js +6 -3
- package/dist/database/api/.generated/package.json +1 -1
- package/dist/database/api/.generated/schema.prisma +17 -15
- package/dist/database/api/.generated/wasm.js +3 -0
- package/dist/src/cache/declaration.d.ts +0 -30
- package/dist/src/cache/declaration.js +0 -30
- package/dist/src/eden/index.d.ts +167 -15
- package/dist/src/index.d.ts +59 -5
- package/dist/src/libs/campaigns/campaignTypes/CLAMMDynamicData.js +2 -2
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/factoryFinder.js +2 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.d.ts +3 -1
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.js +8 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/PendleYTProcessor.d.ts +29 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/PendleYTProcessor.js +31 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/processorMapping.js +3 -0
- package/dist/src/libs/positions/clamm/index.d.ts +1 -2
- package/dist/src/libs/positions/clamm/index.js +322 -330
- package/dist/src/libs/positions/clamm/thegraph/fetchAlmPositions.d.ts +1 -1
- package/dist/src/libs/positions/clamm/thegraph/fetchAlmPositions.js +1 -1
- package/dist/src/libs/positions/clamm/thegraph/fetchAmmPositions.d.ts +1 -1
- package/dist/src/libs/positions/clamm/thegraph/fetchAmmPositions.js +2 -2
- package/dist/src/libs/positions/clamm/thegraph/fetchFarmedPositions.d.ts +1 -2
- package/dist/src/libs/positions/clamm/thegraph/fetchFarmedPositions.js +1 -4
- package/dist/src/libs/positions/euler/index.js +2 -3
- package/dist/src/libs/positions/index.js +1 -1
- package/dist/src/modules/v4/campaign/campaign.controller.d.ts +6 -2
- package/dist/src/modules/v4/campaign/campaign.model.d.ts +1 -0
- package/dist/src/modules/v4/campaign/campaign.model.js +1 -0
- package/dist/src/modules/v4/campaign/campaign.repository.d.ts +2 -0
- package/dist/src/modules/v4/campaign/campaign.repository.js +2 -1
- package/dist/src/modules/v4/campaign/campaign.service.d.ts +10 -5
- package/dist/src/modules/v4/campaign/campaign.service.js +10 -2
- package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +20 -3
- package/dist/src/modules/v4/opportunity/opportunity.model.d.ts +2 -1
- package/dist/src/modules/v4/opportunity/opportunity.model.js +1 -0
- package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +83 -5
- package/dist/src/modules/v4/opportunity/opportunity.repository.js +31 -0
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +162 -8
- package/dist/src/modules/v4/opportunity/opportunity.service.js +11 -0
- package/dist/src/modules/v4/position/implementations/AjnaPositionFetcher.d.ts +6 -0
- package/dist/src/modules/v4/position/implementations/AjnaPositionFetcher.js +90 -0
- package/dist/src/modules/v4/position/implementations/BadgerPositionFetcher.d.ts +6 -0
- package/dist/src/modules/v4/position/implementations/BadgerPositionFetcher.js +69 -0
- package/dist/src/modules/v4/position/implementations/ClammPositionFetcher.d.ts +6 -0
- package/dist/src/modules/v4/position/implementations/ClammPositionFetcher.js +71 -0
- package/dist/src/modules/v4/position/implementations/DolomitePositionFetcher.d.ts +6 -0
- package/dist/src/modules/v4/position/implementations/DolomitePositionFetcher.js +45 -0
- package/dist/src/modules/v4/position/implementations/ERC20PositionFetcher.d.ts +6 -0
- package/dist/src/modules/v4/position/implementations/ERC20PositionFetcher.js +47 -0
- package/dist/src/modules/v4/position/implementations/EulerPositionFetcher.d.ts +6 -0
- package/dist/src/modules/v4/position/implementations/EulerPositionFetcher.js +40 -0
- package/dist/src/modules/v4/position/index.d.ts +2 -0
- package/dist/src/modules/v4/position/index.js +2 -0
- package/dist/src/modules/v4/position/position.controller.d.ts +39 -0
- package/dist/src/modules/v4/position/position.controller.js +16 -0
- package/dist/src/modules/v4/position/position.model.d.ts +25 -0
- package/dist/src/modules/v4/position/position.model.js +5 -0
- package/dist/src/modules/v4/position/position.repository.d.ts +14 -0
- package/dist/src/modules/v4/position/position.repository.js +6 -0
- package/dist/src/modules/v4/position/position.service.d.ts +5 -0
- package/dist/src/modules/v4/position/position.service.js +34 -0
- package/dist/src/modules/v4/price/price.controller.js +1 -1
- package/dist/src/modules/v4/price/price.service.d.ts +1 -1
- package/dist/src/modules/v4/price/price.service.js +3 -3
- package/dist/src/modules/v4/reward/reward.repository.d.ts +4 -0
- package/dist/src/modules/v4/reward/reward.service.d.ts +27 -0
- package/dist/src/modules/v4/reward/reward.service.js +5 -2
- package/dist/src/modules/v4/router.d.ts +59 -5
- package/dist/src/modules/v4/router.js +3 -1
- package/dist/src/modules/v4/token/token.controller.d.ts +6 -0
- package/dist/src/modules/v4/token/token.service.d.ts +12 -0
- package/dist/src/modules/v4/user/user.controller.d.ts +8 -0
- package/dist/src/routes/v1/prices.js +2 -4
- package/dist/src/routes/v3/blacklist.d.ts +59 -5
- package/dist/src/routes/v3/campaigns.d.ts +60 -6
- package/dist/src/routes/v3/campaignsInfo.d.ts +59 -5
- package/dist/src/routes/v3/multiChainPositions.d.ts +59 -5
- package/dist/src/routes/v3/opportunity.d.ts +59 -5
- package/dist/src/routes/v3/positions.d.ts +59 -5
- package/dist/src/routes/v3/recipients.d.ts +6 -2
- package/dist/src/routes/v3/recipients.js +14 -8
- package/dist/src/routes/v3/rewards.d.ts +59 -5
- package/dist/src/routes/v3/updates.d.ts +59 -5
- package/dist/src/routes/v3/userRewards.d.ts +59 -5
- package/dist/src/utils/decodeCalls.js +4 -1
- package/dist/src/utils/encodeCalls.js +4 -1
- package/dist/src/utils/generateCardName.js +2 -0
- package/dist/src/utils/prices/services/erc4626Service.js +10 -4
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/src/libs/reports/campaignReport.d.ts +0 -9
- package/dist/src/libs/reports/campaignReport.js +0 -37
- package/dist/src/libs/reports/mainParameterRewards.d.ts +0 -3
- 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,
|
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
|
-
}
|
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:
|
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:
|
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:
|
452
|
-
sum:
|
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
|
+
}
|