@merkl/api 0.16.40 → 0.16.41
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.
- package/dist/database/api/.generated/edge.js +2 -2
- package/dist/database/api/.generated/index.js +2 -2
- package/dist/database/api/.generated/package.json +1 -1
- package/dist/database/api/.generated/schema.prisma +4 -0
- package/dist/src/eden/index.d.ts +7600 -5065
- package/dist/src/entities/opportunity.js +4 -0
- package/dist/src/index.d.ts +753 -246
- package/dist/src/jobs/etl/update-dynamic-data.d.ts +1 -0
- package/dist/src/jobs/etl/update-dynamic-data.js +71 -0
- package/dist/src/libs/campaigns/campaignsDynamicData.d.ts +1 -1
- package/dist/src/libs/campaigns/campaignsDynamicData.js +22 -0
- package/dist/src/modules/v4/airflow/airflow.service.d.ts +3 -0
- package/dist/src/modules/v4/airflow/airflow.service.js +20 -0
- package/dist/src/modules/v4/campaign/campaign.repository.d.ts +81 -1
- package/dist/src/modules/v4/campaign/campaign.repository.js +57 -1
- package/dist/src/modules/v4/campaign/campaign.service.d.ts +57 -3
- package/dist/src/modules/v4/campaign/campaign.service.js +15 -6
- package/dist/src/modules/v4/campaign/index.d.ts +0 -1
- package/dist/src/modules/v4/campaign/index.js +0 -1
- package/dist/src/modules/v4/chain/chain.controller.d.ts +12 -36
- package/dist/src/modules/v4/chain/chain.controller.js +8 -6
- package/dist/src/modules/v4/chain/chain.model.d.ts +2 -0
- package/dist/src/modules/v4/chain/chain.model.js +2 -0
- package/dist/src/modules/v4/chain/chain.repository.d.ts +9 -11
- package/dist/src/modules/v4/chain/chain.repository.js +5 -18
- package/dist/src/modules/v4/chain/chain.service.d.ts +5 -0
- package/dist/src/modules/v4/chain/chain.service.js +4 -1
- package/dist/src/modules/v4/chain/index.d.ts +2 -1
- package/dist/src/modules/v4/chain/index.js +6 -1
- package/dist/src/modules/v4/computedValue/computedValue.repository.d.ts +1 -1
- package/dist/src/modules/v4/computedValue/computedValue.service.d.ts +1 -1
- package/dist/src/modules/v4/computedValue/index.d.ts +0 -1
- package/dist/src/modules/v4/computedValue/index.js +0 -1
- package/dist/src/modules/v4/dynamicData/dynamicData.service.js +1 -1
- package/dist/src/modules/v4/enso/enso.service.d.ts +1 -12
- package/dist/src/modules/v4/interaction/interaction.controller.d.ts +2 -12
- package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +703 -134
- package/dist/src/modules/v4/opportunity/opportunity.controller.js +2 -4
- package/dist/src/modules/v4/opportunity/opportunity.model.js +1 -1
- package/dist/src/modules/v4/opportunity/opportunity.repository.js +2 -1
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +0 -204
- package/dist/src/modules/v4/opportunity/opportunity.service.js +6 -4
- package/dist/src/modules/v4/opportunity/subservices/getVestMetaData.service.d.ts +1 -1
- package/dist/src/modules/v4/opportunity/subservices/getVestMetaData.service.js +1 -1
- package/dist/src/modules/v4/protocol/index.d.ts +2 -1
- package/dist/src/modules/v4/protocol/index.js +8 -1
- package/dist/src/modules/v4/protocol/protocol.controller.d.ts +10 -40
- package/dist/src/modules/v4/protocol/protocol.controller.js +11 -9
- package/dist/src/modules/v4/protocol/protocol.service.d.ts +7 -7
- package/dist/src/modules/v4/protocol/protocol.service.js +10 -10
- package/dist/src/modules/v4/reward/index.d.ts +0 -1
- package/dist/src/modules/v4/reward/index.js +0 -1
- package/dist/src/modules/v4/reward/reward.service.d.ts +5 -5
- package/dist/src/modules/v4/reward/reward.service.js +6 -7
- package/dist/src/modules/v4/router.d.ts +752 -245
- package/dist/src/modules/v4/status/index.d.ts +0 -1
- package/dist/src/modules/v4/status/index.js +0 -1
- package/dist/src/modules/v4/status/status.controller.d.ts +1 -1
- package/dist/src/modules/v4/status/status.repository.d.ts +1 -1
- package/dist/src/modules/v4/status/status.service.d.ts +2 -2
- package/dist/src/modules/v4/token/token.controller.d.ts +2 -0
- package/dist/src/modules/v4/token/token.model.d.ts +1 -0
- package/dist/src/modules/v4/token/token.model.js +1 -0
- package/dist/src/modules/v4/token/token.repository.js +4 -1
- package/dist/src/modules/v4/token/token.service.d.ts +1 -0
- package/dist/src/modules/v4/token/token.service.js +10 -0
- package/dist/src/routes/v3/campaigns.d.ts +1 -1
- package/dist/src/routes/v3/router.d.ts +1 -1
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +2 -1
@@ -45,7 +45,7 @@ export const OpportunityController = new Elysia({
|
|
45
45
|
detail: { hide: true },
|
46
46
|
})
|
47
47
|
// ─── Get All Opportunities ───────────────────────────────────────────
|
48
|
-
.get("/", async ({ query }) =>
|
48
|
+
.get("/", async ({ query }) => OpportunityService.findMany(query), {
|
49
49
|
query: GetOpportunitiesQueryDto,
|
50
50
|
detail: {
|
51
51
|
description: `**Retrieve Multiple Opportunities**
|
@@ -88,9 +88,7 @@ export const OpportunityController = new Elysia({
|
|
88
88
|
},
|
89
89
|
detail: { description: "Get a unique opportunity." },
|
90
90
|
})
|
91
|
-
.get("/campaigns", async ({ query }) => {
|
92
|
-
return await OpportunityService.findManyByCampaigns(query);
|
93
|
-
}, {
|
91
|
+
.get("/campaigns", async ({ query }) => OpportunityService.findManyByCampaigns(query), {
|
94
92
|
query: GetCampaignQueryDto,
|
95
93
|
response: {
|
96
94
|
200: t.Array(OpportunityWithCampaignsResourceDto),
|
@@ -66,7 +66,7 @@ export const GetOpportunitiesQueryDto = t.Object({
|
|
66
66
|
status: t.Optional(t.RegExp(/^(LIVE|PAST|SOON)(,(LIVE|PAST|SOON)){0,2}$/, {
|
67
67
|
description: "A comma separeted list of status. Legal values are: `LIVE`, `PAST`, `SOON`",
|
68
68
|
})),
|
69
|
-
identifier: t.Optional(t.String({ description: "Filter by identifier" })),
|
69
|
+
identifier: t.Optional(t.String({ description: "Filter by identifier (mainParameter)." })),
|
70
70
|
campaigns: t.Optional(t.Boolean({ description: "Include campaign data. Will slow down the request. Default: false" })),
|
71
71
|
tokens: t.Optional(t.String({ description: "A comma separated list of token symbol. Use to filter by token" })),
|
72
72
|
sort: t.Optional(t.RegExp(/(apr|tvl|rewards)/, { description: "Sort by `apr`, `tvl` or `rewards`" })),
|
@@ -15,6 +15,7 @@ export class OpportunityRepository {
|
|
15
15
|
const tokens = query.tokens?.split(",");
|
16
16
|
const types = query.type?.split(",");
|
17
17
|
const protocols = query.mainProtocolId?.split(",");
|
18
|
+
const identifiers = query.identifier?.split(",");
|
18
19
|
const sort = (query.sort === "rewards" ? "dailyRewards" : query.sort) ?? "dailyRewards";
|
19
20
|
const order = query.order ?? "desc";
|
20
21
|
const test = query.test ?? false;
|
@@ -34,7 +35,7 @@ export class OpportunityRepository {
|
|
34
35
|
action: !actions ? undefined : { in: actions },
|
35
36
|
status: !status ? undefined : { in: status },
|
36
37
|
mainProtocolId: !protocols ? undefined : { in: protocols },
|
37
|
-
identifier: !identifier ? undefined : {
|
38
|
+
identifier: !identifier ? undefined : { in: identifiers },
|
38
39
|
Campaigns: test || !creatorAddress
|
39
40
|
? undefined
|
40
41
|
: {
|
@@ -172,57 +172,6 @@ export declare abstract class OpportunityService {
|
|
172
172
|
amount: bigint;
|
173
173
|
}[];
|
174
174
|
};
|
175
|
-
campaigns: {
|
176
|
-
params: any;
|
177
|
-
chain: {
|
178
|
-
name: string;
|
179
|
-
id: number;
|
180
|
-
icon: string;
|
181
|
-
};
|
182
|
-
rewardToken: {
|
183
|
-
symbol: string;
|
184
|
-
name: string | null;
|
185
|
-
id: string;
|
186
|
-
icon: string;
|
187
|
-
chainId: number;
|
188
|
-
address: string;
|
189
|
-
decimals: number;
|
190
|
-
verified: boolean;
|
191
|
-
isTest: boolean;
|
192
|
-
} & {
|
193
|
-
price?: number | null | undefined;
|
194
|
-
};
|
195
|
-
distributionChain: {
|
196
|
-
name: string;
|
197
|
-
id: number;
|
198
|
-
icon: string;
|
199
|
-
} | undefined;
|
200
|
-
campaignStatus: {
|
201
|
-
error: string;
|
202
|
-
details: Prisma.JsonValue;
|
203
|
-
status: import("../../../../database/api/.generated").$Enums.RunStatus;
|
204
|
-
campaignId: string;
|
205
|
-
computedUntil: bigint;
|
206
|
-
processingStarted: bigint;
|
207
|
-
};
|
208
|
-
creatorAddress: string;
|
209
|
-
Creator: {
|
210
|
-
tags: string[];
|
211
|
-
address: string;
|
212
|
-
creatorId: string | null;
|
213
|
-
};
|
214
|
-
type: string;
|
215
|
-
id: string;
|
216
|
-
subType: number | null;
|
217
|
-
startTimestamp: bigint;
|
218
|
-
endTimestamp: bigint;
|
219
|
-
computeChainId: number;
|
220
|
-
distributionChainId: number;
|
221
|
-
campaignId: string;
|
222
|
-
rewardTokenId: string;
|
223
|
-
amount: string;
|
224
|
-
opportunityId: string;
|
225
|
-
}[];
|
226
175
|
id: string;
|
227
176
|
depositUrl: string | undefined;
|
228
177
|
tokens: ({
|
@@ -318,57 +267,6 @@ export declare abstract class OpportunityService {
|
|
318
267
|
amount: bigint;
|
319
268
|
}[];
|
320
269
|
};
|
321
|
-
campaigns: {
|
322
|
-
params: any;
|
323
|
-
chain: {
|
324
|
-
name: string;
|
325
|
-
id: number;
|
326
|
-
icon: string;
|
327
|
-
};
|
328
|
-
rewardToken: {
|
329
|
-
symbol: string;
|
330
|
-
name: string | null;
|
331
|
-
id: string;
|
332
|
-
icon: string;
|
333
|
-
chainId: number;
|
334
|
-
address: string;
|
335
|
-
decimals: number;
|
336
|
-
verified: boolean;
|
337
|
-
isTest: boolean;
|
338
|
-
} & {
|
339
|
-
price?: number | null | undefined;
|
340
|
-
};
|
341
|
-
distributionChain: {
|
342
|
-
name: string;
|
343
|
-
id: number;
|
344
|
-
icon: string;
|
345
|
-
} | undefined;
|
346
|
-
campaignStatus: {
|
347
|
-
error: string;
|
348
|
-
details: Prisma.JsonValue;
|
349
|
-
status: import("../../../../database/api/.generated").$Enums.RunStatus;
|
350
|
-
campaignId: string;
|
351
|
-
computedUntil: bigint;
|
352
|
-
processingStarted: bigint;
|
353
|
-
};
|
354
|
-
creatorAddress: string;
|
355
|
-
Creator: {
|
356
|
-
tags: string[];
|
357
|
-
address: string;
|
358
|
-
creatorId: string | null;
|
359
|
-
};
|
360
|
-
type: string;
|
361
|
-
id: string;
|
362
|
-
subType: number | null;
|
363
|
-
startTimestamp: bigint;
|
364
|
-
endTimestamp: bigint;
|
365
|
-
computeChainId: number;
|
366
|
-
distributionChainId: number;
|
367
|
-
campaignId: string;
|
368
|
-
rewardTokenId: string;
|
369
|
-
amount: string;
|
370
|
-
opportunityId: string;
|
371
|
-
}[];
|
372
270
|
id: string;
|
373
271
|
depositUrl: string | undefined;
|
374
272
|
tokens: ({
|
@@ -464,57 +362,6 @@ export declare abstract class OpportunityService {
|
|
464
362
|
amount: bigint;
|
465
363
|
}[];
|
466
364
|
};
|
467
|
-
campaigns: {
|
468
|
-
params: any;
|
469
|
-
chain: {
|
470
|
-
name: string;
|
471
|
-
id: number;
|
472
|
-
icon: string;
|
473
|
-
};
|
474
|
-
rewardToken: {
|
475
|
-
symbol: string;
|
476
|
-
name: string | null;
|
477
|
-
id: string;
|
478
|
-
icon: string;
|
479
|
-
chainId: number;
|
480
|
-
address: string;
|
481
|
-
decimals: number;
|
482
|
-
verified: boolean;
|
483
|
-
isTest: boolean;
|
484
|
-
} & {
|
485
|
-
price?: number | null | undefined;
|
486
|
-
};
|
487
|
-
distributionChain: {
|
488
|
-
name: string;
|
489
|
-
id: number;
|
490
|
-
icon: string;
|
491
|
-
} | undefined;
|
492
|
-
campaignStatus: {
|
493
|
-
error: string;
|
494
|
-
details: Prisma.JsonValue;
|
495
|
-
status: import("../../../../database/api/.generated").$Enums.RunStatus;
|
496
|
-
campaignId: string;
|
497
|
-
computedUntil: bigint;
|
498
|
-
processingStarted: bigint;
|
499
|
-
};
|
500
|
-
creatorAddress: string;
|
501
|
-
Creator: {
|
502
|
-
tags: string[];
|
503
|
-
address: string;
|
504
|
-
creatorId: string | null;
|
505
|
-
};
|
506
|
-
type: string;
|
507
|
-
id: string;
|
508
|
-
subType: number | null;
|
509
|
-
startTimestamp: bigint;
|
510
|
-
endTimestamp: bigint;
|
511
|
-
computeChainId: number;
|
512
|
-
distributionChainId: number;
|
513
|
-
campaignId: string;
|
514
|
-
rewardTokenId: string;
|
515
|
-
amount: string;
|
516
|
-
opportunityId: string;
|
517
|
-
}[];
|
518
365
|
id: string;
|
519
366
|
depositUrl: string | undefined;
|
520
367
|
tokens: ({
|
@@ -658,57 +505,6 @@ export declare abstract class OpportunityService {
|
|
658
505
|
amount: bigint;
|
659
506
|
}[];
|
660
507
|
};
|
661
|
-
campaigns: {
|
662
|
-
params: any;
|
663
|
-
chain: {
|
664
|
-
name: string;
|
665
|
-
id: number;
|
666
|
-
icon: string;
|
667
|
-
};
|
668
|
-
rewardToken: {
|
669
|
-
symbol: string;
|
670
|
-
name: string | null;
|
671
|
-
id: string;
|
672
|
-
icon: string;
|
673
|
-
chainId: number;
|
674
|
-
address: string;
|
675
|
-
decimals: number;
|
676
|
-
verified: boolean;
|
677
|
-
isTest: boolean;
|
678
|
-
} & {
|
679
|
-
price?: number | null | undefined;
|
680
|
-
};
|
681
|
-
distributionChain: {
|
682
|
-
name: string;
|
683
|
-
id: number;
|
684
|
-
icon: string;
|
685
|
-
} | undefined;
|
686
|
-
campaignStatus: {
|
687
|
-
error: string;
|
688
|
-
details: Prisma.JsonValue;
|
689
|
-
status: import("../../../../database/api/.generated").$Enums.RunStatus;
|
690
|
-
campaignId: string;
|
691
|
-
computedUntil: bigint;
|
692
|
-
processingStarted: bigint;
|
693
|
-
};
|
694
|
-
creatorAddress: string;
|
695
|
-
Creator: {
|
696
|
-
tags: string[];
|
697
|
-
address: string;
|
698
|
-
creatorId: string | null;
|
699
|
-
};
|
700
|
-
type: string;
|
701
|
-
id: string;
|
702
|
-
subType: number | null;
|
703
|
-
startTimestamp: bigint;
|
704
|
-
endTimestamp: bigint;
|
705
|
-
computeChainId: number;
|
706
|
-
distributionChainId: number;
|
707
|
-
campaignId: string;
|
708
|
-
rewardTokenId: string;
|
709
|
-
amount: string;
|
710
|
-
opportunityId: string;
|
711
|
-
}[];
|
712
508
|
id: string;
|
713
509
|
depositUrl: string | undefined;
|
714
510
|
tokens: ({
|
@@ -28,7 +28,7 @@ import { getMorphoMetadata } from "./subservices/getMorphoMetadata.service";
|
|
28
28
|
import { getRadiantMetadata } from "./subservices/getRadiantMetadata.service";
|
29
29
|
import { getSiloMetadata } from "./subservices/getSiloMetadata.service";
|
30
30
|
import { getUniswapV4Metadata } from "./subservices/getUniswapV4Metadata.service";
|
31
|
-
import {
|
31
|
+
import { getVestMetadata } from "./subservices/getVestMetadata.service";
|
32
32
|
export class OpportunityService {
|
33
33
|
static hashId(opportunity) {
|
34
34
|
return Bun.hash(`${opportunity.chainId}${opportunity.type}${opportunity.identifier}`).toString();
|
@@ -87,7 +87,7 @@ export class OpportunityService {
|
|
87
87
|
case "EIGENLAYER":
|
88
88
|
return getEigenLayerMetadata(chainId, campaignParams);
|
89
89
|
case "VEST":
|
90
|
-
return
|
90
|
+
return getVestMetadata(chainId, campaignParams);
|
91
91
|
case "EULER":
|
92
92
|
return getEulerMetadata(chainId, campaign.campaignId, campaign.subType, campaign.rewardTokenAddress, campaign.amount, campaignParams);
|
93
93
|
case "HYPERDRIVELOGPROCESSOR":
|
@@ -299,7 +299,7 @@ export class OpportunityService {
|
|
299
299
|
}
|
300
300
|
static formatResponse(opportunity) {
|
301
301
|
const { DailyRewardsRecords, AprRecords, TvlRecords, Campaigns, ...opp } = opportunity;
|
302
|
-
|
302
|
+
const formated = {
|
303
303
|
...OpportunityService.formatResponseBase(opp),
|
304
304
|
apr: opp.status === "LIVE" ? opp.apr : 0,
|
305
305
|
aprRecord: opp.status === "LIVE"
|
@@ -333,9 +333,11 @@ export class OpportunityService {
|
|
333
333
|
};
|
334
334
|
}),
|
335
335
|
}))?.[0] ?? undefined,
|
336
|
-
campaigns: Campaigns?.map(c => CampaignService.format(c)),
|
337
336
|
//TODO: change this to accomodate all return types
|
338
337
|
};
|
338
|
+
if (Campaigns)
|
339
|
+
Object.assign(formated, { campaigns: Campaigns.map(c => CampaignService.format(c)) });
|
340
|
+
return formated;
|
339
341
|
}
|
340
342
|
static formatResponseBase(opportunity) {
|
341
343
|
let { mainProtocolId, id, Tokens, Chain, Protocols, MainProtocol, ...opp } = opportunity;
|
@@ -1,3 +1,3 @@
|
|
1
1
|
import type { ChainId, EigenLayerCampaign } from "@sdk";
|
2
2
|
import type { OpportunityMetadata } from "../opportunity.model";
|
3
|
-
export declare const
|
3
|
+
export declare const getVestMetadata: (chainId: ChainId, params: EigenLayerCampaign["campaignParameters"]) => Promise<OpportunityMetadata>;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { VEST_TOKEN } from "../../../../libs/campaigns/campaignTypes/VestDynamicData";
|
2
2
|
import { OpportunityAction } from "../../../../../database/api/.generated";
|
3
|
-
export const
|
3
|
+
export const getVestMetadata = async (chainId, params) => {
|
4
4
|
return {
|
5
5
|
action: OpportunityAction.LEND,
|
6
6
|
name: ["Vest", "supply", "treasury"].join(" "),
|
@@ -1,3 +1,10 @@
|
|
1
|
-
|
1
|
+
import { initChainService } from "../chain";
|
2
|
+
import { ProtocolRepository } from "./protocol.repository";
|
3
|
+
import { ProtocolService } from "./protocol.service";
|
2
4
|
export * from "./protocol.model";
|
3
5
|
export * from "./protocol.service";
|
6
|
+
export const initProtocolService = (dbClient) => {
|
7
|
+
const repository = new ProtocolRepository(dbClient);
|
8
|
+
const chainService = initChainService(dbClient);
|
9
|
+
return new ProtocolService(repository, chainService);
|
10
|
+
};
|
@@ -28,18 +28,8 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
|
|
28
28
|
};
|
29
29
|
headers: unknown;
|
30
30
|
response: {
|
31
|
-
|
32
|
-
|
33
|
-
url: string;
|
34
|
-
description: string;
|
35
|
-
id: string;
|
36
|
-
tags: string[];
|
37
|
-
icon: string;
|
38
|
-
} & {
|
39
|
-
dailyRewards?: number | undefined;
|
40
|
-
numberOfLiveCampaigns?: number | undefined;
|
41
|
-
opportunityLiveTags?: string[] | undefined;
|
42
|
-
})[];
|
31
|
+
[x: string]: any;
|
32
|
+
200: any;
|
43
33
|
};
|
44
34
|
};
|
45
35
|
};
|
@@ -53,7 +43,8 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
|
|
53
43
|
query: unknown;
|
54
44
|
headers: unknown;
|
55
45
|
response: {
|
56
|
-
|
46
|
+
[x: string]: any;
|
47
|
+
200: any;
|
57
48
|
};
|
58
49
|
};
|
59
50
|
};
|
@@ -69,17 +60,8 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
|
|
69
60
|
query: unknown;
|
70
61
|
headers: unknown;
|
71
62
|
response: {
|
72
|
-
|
73
|
-
|
74
|
-
url: string;
|
75
|
-
description: string;
|
76
|
-
id: string;
|
77
|
-
tags: string[];
|
78
|
-
icon: string;
|
79
|
-
dailyRewards?: number | undefined;
|
80
|
-
numberOfLiveCampaigns?: number | undefined;
|
81
|
-
opportunityLiveTags?: string[] | undefined;
|
82
|
-
} | null;
|
63
|
+
[x: string]: any;
|
64
|
+
200: any;
|
83
65
|
};
|
84
66
|
};
|
85
67
|
};
|
@@ -102,14 +84,8 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
|
|
102
84
|
authorization: string;
|
103
85
|
};
|
104
86
|
response: {
|
105
|
-
|
106
|
-
|
107
|
-
url: string;
|
108
|
-
description: string;
|
109
|
-
id: string;
|
110
|
-
tags: string[];
|
111
|
-
icon: string;
|
112
|
-
};
|
87
|
+
[x: string]: any;
|
88
|
+
200: any;
|
113
89
|
};
|
114
90
|
};
|
115
91
|
};
|
@@ -132,14 +108,8 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
|
|
132
108
|
authorization: string;
|
133
109
|
};
|
134
110
|
response: {
|
135
|
-
|
136
|
-
|
137
|
-
url: string;
|
138
|
-
description: string;
|
139
|
-
id: string;
|
140
|
-
tags: string[];
|
141
|
-
icon: string;
|
142
|
-
};
|
111
|
+
[x: string]: any;
|
112
|
+
200: any;
|
143
113
|
};
|
144
114
|
};
|
145
115
|
};
|
@@ -1,28 +1,30 @@
|
|
1
1
|
import { AuthorizationHeadersDto, BackOfficeGuard } from "../../../guards/BackOffice.guard";
|
2
|
+
import { apiDbClient } from "../../../utils/prisma";
|
2
3
|
import Elysia, { t } from "elysia";
|
4
|
+
import { initProtocolService } from ".";
|
3
5
|
import { CreateProtocolDto, GetProtocolsQueryDto, ProtocolIdDto, ProtocolResourceDto, UpdateProtocolDto, } from "./protocol.model";
|
4
|
-
|
6
|
+
const protocolService = initProtocolService(apiDbClient);
|
5
7
|
// ─── Protocols Controller ────────────────────────────────────────────────────
|
6
8
|
export const ProtocolController = new Elysia({ prefix: "/protocols", detail: { tags: ["Protocols"] } })
|
7
9
|
// ─── Get Many Protocols ──────────────────────────────────────────────
|
8
|
-
.get("/", async ({ query }) => await
|
10
|
+
.get("/", async ({ query }) => await protocolService.findMany(query), {
|
9
11
|
query: GetProtocolsQueryDto,
|
10
12
|
response: t.Array(ProtocolResourceDto),
|
11
13
|
detail: { description: "List protocols supported and integrated by Merkl." },
|
12
14
|
})
|
13
|
-
// ─── Count Protocols
|
14
|
-
.get("/count", async ({ query }) => await
|
15
|
+
// ─── Count Protocols ─────────────────────────────────────────────────
|
16
|
+
.get("/count", async ({ query }) => await protocolService.countMany(query), {
|
15
17
|
detail: { description: "Get the number of protocols correspoinding to the query." },
|
16
18
|
})
|
17
|
-
// ─── Get A Protocol By Its Id
|
19
|
+
// ─── Get A Protocol By Its Id Or Name ────────────────────────────────
|
18
20
|
.get("/:id", async ({ params }) => {
|
19
|
-
const fromId = await
|
21
|
+
const fromId = await protocolService.getFromId(params.id);
|
20
22
|
if (fromId)
|
21
23
|
return fromId;
|
22
|
-
return await
|
24
|
+
return await protocolService.getFromName(params.id);
|
23
25
|
}, { detail: { hide: true } })
|
24
26
|
// ─── Update A Protocol ───────────────────────────────────────────────
|
25
|
-
.patch("/:id", async ({ params, body }) => await
|
27
|
+
.patch("/:id", async ({ params, body }) => await protocolService.update(params.id, body), {
|
26
28
|
params: ProtocolIdDto,
|
27
29
|
body: UpdateProtocolDto,
|
28
30
|
headers: AuthorizationHeadersDto,
|
@@ -30,7 +32,7 @@ export const ProtocolController = new Elysia({ prefix: "/protocols", detail: { t
|
|
30
32
|
detail: { hide: true },
|
31
33
|
})
|
32
34
|
// ─── Create A Protocol ───────────────────────────────────────────────
|
33
|
-
.post("/", async ({ body }) => await
|
35
|
+
.post("/", async ({ body }) => await protocolService.create(body), {
|
34
36
|
body: CreateProtocolDto,
|
35
37
|
headers: AuthorizationHeadersDto,
|
36
38
|
beforeHandle: BackOfficeGuard,
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import type { CreateProtocolModel, GetProtocolsQueryModel, Protocol, ProtocolId, UpdateProtocolModel } from "./protocol.model";
|
2
2
|
export declare abstract class ProtocolService {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
findMany(query: GetProtocolsQueryModel): Promise<Protocol["model"][]>;
|
4
|
+
countMany(query: GetProtocolsQueryModel): Promise<number>;
|
5
|
+
getFromId(id: ProtocolId | string): Promise<Protocol["model"] | null>;
|
6
|
+
getFromName(name: string): Promise<Protocol["model"] | null>;
|
7
|
+
create(data: CreateProtocolModel): Promise<{
|
8
8
|
name: string;
|
9
9
|
url: string;
|
10
10
|
description: string;
|
@@ -12,7 +12,7 @@ export declare abstract class ProtocolService {
|
|
12
12
|
tags: string[];
|
13
13
|
icon: string;
|
14
14
|
}>;
|
15
|
-
|
15
|
+
update(id: string, data: UpdateProtocolModel): Promise<{
|
16
16
|
name: string;
|
17
17
|
url: string;
|
18
18
|
description: string;
|
@@ -20,5 +20,5 @@ export declare abstract class ProtocolService {
|
|
20
20
|
tags: string[];
|
21
21
|
icon: string;
|
22
22
|
}>;
|
23
|
-
|
23
|
+
changeLogoUrls(): Promise<void>;
|
24
24
|
}
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import { ChainService } from "../chain/chain.service";
|
2
1
|
import { TokenService } from "../token/token.service";
|
3
2
|
import { log } from "../../../utils/logger";
|
3
|
+
import { ChainService } from "../chain";
|
4
4
|
import { ProtocolRepository } from "./protocol.repository";
|
5
5
|
// ─── Protocols Services ──────────────────────────────────────────────────────
|
6
6
|
export class ProtocolService {
|
7
|
-
|
7
|
+
async findMany(query) {
|
8
8
|
const protocols = await ProtocolRepository.findMany(query);
|
9
9
|
const enrichedProtocols = protocols.map(({ MainOpportunities, ...protocol }) => ({
|
10
10
|
...protocol,
|
@@ -14,33 +14,33 @@ export class ProtocolService {
|
|
14
14
|
}));
|
15
15
|
return enrichedProtocols;
|
16
16
|
}
|
17
|
-
|
17
|
+
async countMany(query) {
|
18
18
|
return ProtocolRepository.countMany(query);
|
19
19
|
}
|
20
|
-
|
20
|
+
async getFromId(id) {
|
21
21
|
return ProtocolRepository.read(id);
|
22
22
|
}
|
23
23
|
// Todo : Should be a findfirst by name here
|
24
|
-
|
24
|
+
async getFromName(name) {
|
25
25
|
return (await ProtocolRepository.findManyByName(name))[0];
|
26
26
|
}
|
27
|
-
|
27
|
+
async create(data) {
|
28
28
|
return await ProtocolRepository.create(data);
|
29
29
|
}
|
30
|
-
|
30
|
+
async update(id, data) {
|
31
31
|
// let iconUri = data.icon;
|
32
32
|
// if (data.iconFile) {
|
33
33
|
// iconUri = await BucketService.upload("merkl-assets", `/protocols/${id}`, data.iconFile.stream(), true);
|
34
34
|
// }
|
35
35
|
return await ProtocolRepository.update(id, data);
|
36
36
|
}
|
37
|
-
|
37
|
+
async changeLogoUrls() {
|
38
38
|
const oldUrl = "https://storage.googleapis.com/merkl-assets/";
|
39
39
|
const newUrl = "https://raw.githubusercontent.com/AngleProtocol/angle-token-list/main/src/assets/";
|
40
|
-
const protocols = await
|
40
|
+
const protocols = await this.findMany({ items: 10_000 });
|
41
41
|
for (const protocol of protocols) {
|
42
42
|
if (protocol.icon.includes(oldUrl)) {
|
43
|
-
await
|
43
|
+
await this.update(protocol.id, { icon: protocol.icon.replace(oldUrl, newUrl) });
|
44
44
|
log.info(`Updated protocol ${protocol.id} icon`);
|
45
45
|
}
|
46
46
|
}
|
@@ -13,7 +13,7 @@ export declare abstract class RewardService {
|
|
13
13
|
* @param breakdown straight from db
|
14
14
|
* @returns a RewardBreakdown model
|
15
15
|
*/
|
16
|
-
static formatBreakdown(breakdown: Awaited<ReturnType<typeof RewardRepository
|
16
|
+
static formatBreakdown(breakdown: Awaited<ReturnType<(typeof RewardRepository)["getByRecipient"]>>[number]["Breakdown"][number]): {
|
17
17
|
campaignId: string;
|
18
18
|
opportunity: {
|
19
19
|
Chain: {
|
@@ -75,7 +75,7 @@ export declare abstract class RewardService {
|
|
75
75
|
* @param reward straight from db
|
76
76
|
* @returns a Reward model
|
77
77
|
*/
|
78
|
-
static format(rewards: Awaited<ReturnType<typeof RewardRepository
|
78
|
+
static format(rewards: Awaited<ReturnType<(typeof RewardRepository)["getByRecipient"]>>): {
|
79
79
|
token: {
|
80
80
|
symbol: string;
|
81
81
|
name: string | null;
|
@@ -260,7 +260,7 @@ export declare abstract class RewardService {
|
|
260
260
|
* @param rewards return type for most of the rewards functions
|
261
261
|
* @returns rewards with updated breakdowns, including the opportunity they belong to
|
262
262
|
*/
|
263
|
-
static splitRewardsBreakdownByOpportunity(rewards: Awaited<ReturnType<typeof RewardService
|
263
|
+
static splitRewardsBreakdownByOpportunity(rewards: Awaited<ReturnType<(typeof RewardService)["getUserRewardsByChain"]>>): (Omit<{
|
264
264
|
chain: Chain;
|
265
265
|
rewards: Awaited<ReturnType<(typeof RewardService)["format"]>>;
|
266
266
|
}, "rewards"> & {
|
@@ -351,7 +351,7 @@ export declare abstract class RewardService {
|
|
351
351
|
})[];
|
352
352
|
distributor: string;
|
353
353
|
})[];
|
354
|
-
static removeOpportunityFromRewardBreakdown(rewards: Awaited<ReturnType<typeof RewardService
|
354
|
+
static removeOpportunityFromRewardBreakdown(rewards: Awaited<ReturnType<(typeof RewardService)["getUserRewardsByChain"]>>): (Omit<{
|
355
355
|
chain: Chain;
|
356
356
|
rewards: Awaited<ReturnType<(typeof RewardService)["format"]>>;
|
357
357
|
}, "rewards"> & {
|
@@ -443,7 +443,7 @@ export declare abstract class RewardService {
|
|
443
443
|
})[];
|
444
444
|
})[];
|
445
445
|
static findManyRootsOnChain(chainId: ChainId): Promise<string[]>;
|
446
|
-
static checkLastClaim(chainId: number, user: string, roots: CacheKeys["CurrentRoot"]["returns"], rewards: Awaited<ReturnType<typeof RewardService
|
446
|
+
static checkLastClaim(chainId: number, user: string, roots: CacheKeys["CurrentRoot"]["returns"], rewards: Awaited<ReturnType<(typeof RewardService)["getByRecipient"]>>): Promise<({
|
447
447
|
RewardToken: {
|
448
448
|
symbol: string;
|
449
449
|
name: string | null;
|
@@ -305,23 +305,22 @@ export class RewardService {
|
|
305
305
|
if (typesWithoutApr.includes(type))
|
306
306
|
return { timestamp, total: 0, breakdowns: [] };
|
307
307
|
const breakdowns = [];
|
308
|
-
for (const { amount, rewardToken
|
308
|
+
for (const { amount, rewardToken, chainId, startTimestamp: start, endTimestamp: end, campaignId } of dynamicData) {
|
309
309
|
if (end < moment().unix())
|
310
310
|
continue;
|
311
|
-
const timespan =
|
311
|
+
const timespan = Number(end - start);
|
312
312
|
const isWithinTimespan = moment().unix() > start && moment().unix() < end;
|
313
313
|
const dayspan = Math.max(1, Math.floor(timespan / DAY));
|
314
314
|
const dailyAmount = isWithinTimespan ? BigInt(amount) / BigInt(dayspan) : BigInt(0);
|
315
315
|
const campaignIdInDb = CampaignService.hashId({ campaignId, distributionChain: chainId });
|
316
|
-
const
|
316
|
+
const tokenToAmount = new Map();
|
317
|
+
tokenToAmount.set(rewardToken, dailyAmount);
|
318
|
+
const campaignDailyValue = await TokenService.getValueByTokenId(tokenToAmount);
|
317
319
|
breakdowns.push({
|
318
320
|
campaignId: campaignIdInDb,
|
319
321
|
value: campaignDailyValue,
|
320
322
|
amount: dailyAmount,
|
321
|
-
token: await TokenService.findUniqueOrThrow(
|
322
|
-
address,
|
323
|
-
chainId,
|
324
|
-
}),
|
323
|
+
token: await TokenService.findUniqueOrThrow(rewardToken),
|
325
324
|
});
|
326
325
|
}
|
327
326
|
return {
|