@merkl/api 0.20.167 → 0.20.168
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/index.js +1 -1
- package/dist/src/eden/index.d.ts +4619 -3442
- package/dist/src/index.d.ts +516 -111
- package/dist/src/jobs/update-analytics.js +79 -75
- package/dist/src/modules/v4/campaign/campaign.controller.d.ts +25 -0
- package/dist/src/modules/v4/campaign/campaign.controller.js +8 -1
- package/dist/src/modules/v4/campaign/campaign.repository.d.ts +16 -0
- package/dist/src/modules/v4/campaign/campaign.repository.js +18 -0
- package/dist/src/modules/v4/campaign/campaign.service.d.ts +10 -0
- package/dist/src/modules/v4/campaign/campaign.service.js +7 -0
- package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +538 -158
- package/dist/src/modules/v4/opportunity/opportunity.controller.js +6 -0
- package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +0 -20
- package/dist/src/modules/v4/opportunity/opportunity.repository.js +10 -2
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +13 -18
- package/dist/src/modules/v4/opportunity/opportunity.service.js +61 -0
- package/dist/src/modules/v4/reward/reward.controller.js +1 -1
- package/dist/src/modules/v4/reward/reward.service.d.ts +1 -7
- package/dist/src/modules/v4/reward/reward.service.js +1 -1
- package/dist/src/modules/v4/router.d.ts +516 -111
- package/dist/src/modules/v4/token/token.controller.js +6 -1
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -84,6 +84,12 @@ export const OpportunityController = new Elysia({
|
|
84
84
|
},
|
85
85
|
detail: { description: "Get the count of opportunities corresponding to the query." },
|
86
86
|
response: { 200: t.Number() },
|
87
|
+
})
|
88
|
+
.get("/bins/apr", async ({ query }) => await OpportunityService.getAprBins(query), {
|
89
|
+
query: GetOpportunitiesQueryDto,
|
90
|
+
})
|
91
|
+
.get("/bins/tvl", async ({ query }) => await OpportunityService.getTvlBins(query), {
|
92
|
+
query: GetOpportunitiesQueryDto,
|
87
93
|
})
|
88
94
|
// ─── Get An Opportunity By Id ────────────────────────────────────────
|
89
95
|
.get("/:id", async ({ params, query }) => {
|
@@ -131,10 +131,8 @@ export declare abstract class OpportunityRepository {
|
|
131
131
|
TvlRecords: ({
|
132
132
|
TvlBreakdown: {
|
133
133
|
type: import("@db/api").$Enums.TvlType;
|
134
|
-
id: string;
|
135
134
|
identifier: string;
|
136
135
|
value: number;
|
137
|
-
tvlRecordId: string;
|
138
136
|
}[];
|
139
137
|
} & {
|
140
138
|
total: number;
|
@@ -145,10 +143,8 @@ export declare abstract class OpportunityRepository {
|
|
145
143
|
AprRecords: ({
|
146
144
|
AprBreakdown: {
|
147
145
|
type: import("@db/api").$Enums.AprType;
|
148
|
-
id: string;
|
149
146
|
identifier: string;
|
150
147
|
value: number;
|
151
|
-
aprRecordId: string;
|
152
148
|
}[];
|
153
149
|
} & {
|
154
150
|
id: string;
|
@@ -281,10 +277,8 @@ export declare abstract class OpportunityRepository {
|
|
281
277
|
TvlRecords: ({
|
282
278
|
TvlBreakdown: {
|
283
279
|
type: import("@db/api").$Enums.TvlType;
|
284
|
-
id: string;
|
285
280
|
identifier: string;
|
286
281
|
value: number;
|
287
|
-
tvlRecordId: string;
|
288
282
|
}[];
|
289
283
|
} & {
|
290
284
|
total: number;
|
@@ -295,10 +289,8 @@ export declare abstract class OpportunityRepository {
|
|
295
289
|
AprRecords: ({
|
296
290
|
AprBreakdown: {
|
297
291
|
type: import("@db/api").$Enums.AprType;
|
298
|
-
id: string;
|
299
292
|
identifier: string;
|
300
293
|
value: number;
|
301
|
-
aprRecordId: string;
|
302
294
|
}[];
|
303
295
|
} & {
|
304
296
|
id: string;
|
@@ -490,10 +482,8 @@ export declare abstract class OpportunityRepository {
|
|
490
482
|
TvlRecords: ({
|
491
483
|
TvlBreakdown: {
|
492
484
|
type: import("@db/api").$Enums.TvlType;
|
493
|
-
id: string;
|
494
485
|
identifier: string;
|
495
486
|
value: number;
|
496
|
-
tvlRecordId: string;
|
497
487
|
}[];
|
498
488
|
} & {
|
499
489
|
total: number;
|
@@ -504,10 +494,8 @@ export declare abstract class OpportunityRepository {
|
|
504
494
|
AprRecords: ({
|
505
495
|
AprBreakdown: {
|
506
496
|
type: import("@db/api").$Enums.AprType;
|
507
|
-
id: string;
|
508
497
|
identifier: string;
|
509
498
|
value: number;
|
510
|
-
aprRecordId: string;
|
511
499
|
}[];
|
512
500
|
} & {
|
513
501
|
id: string;
|
@@ -647,10 +635,8 @@ export declare abstract class OpportunityRepository {
|
|
647
635
|
TvlRecords: ({
|
648
636
|
TvlBreakdown: {
|
649
637
|
type: import("@db/api").$Enums.TvlType;
|
650
|
-
id: string;
|
651
638
|
identifier: string;
|
652
639
|
value: number;
|
653
|
-
tvlRecordId: string;
|
654
640
|
}[];
|
655
641
|
} & {
|
656
642
|
total: number;
|
@@ -661,10 +647,8 @@ export declare abstract class OpportunityRepository {
|
|
661
647
|
AprRecords: ({
|
662
648
|
AprBreakdown: {
|
663
649
|
type: import("@db/api").$Enums.AprType;
|
664
|
-
id: string;
|
665
650
|
identifier: string;
|
666
651
|
value: number;
|
667
|
-
aprRecordId: string;
|
668
652
|
}[];
|
669
653
|
} & {
|
670
654
|
id: string;
|
@@ -858,10 +842,8 @@ export declare abstract class OpportunityRepository {
|
|
858
842
|
TvlRecords: ({
|
859
843
|
TvlBreakdown: {
|
860
844
|
type: import("@db/api").$Enums.TvlType;
|
861
|
-
id: string;
|
862
845
|
identifier: string;
|
863
846
|
value: number;
|
864
|
-
tvlRecordId: string;
|
865
847
|
}[];
|
866
848
|
} & {
|
867
849
|
total: number;
|
@@ -872,10 +854,8 @@ export declare abstract class OpportunityRepository {
|
|
872
854
|
AprRecords: ({
|
873
855
|
AprBreakdown: {
|
874
856
|
type: import("@db/api").$Enums.AprType;
|
875
|
-
id: string;
|
876
857
|
identifier: string;
|
877
858
|
value: number;
|
878
|
-
aprRecordId: string;
|
879
859
|
}[];
|
880
860
|
} & {
|
881
861
|
id: string;
|
@@ -111,8 +111,16 @@ export class OpportunityRepository {
|
|
111
111
|
}
|
112
112
|
static #getRecordInclusion(withTest = true, withPoints = true) {
|
113
113
|
return {
|
114
|
-
AprRecords: {
|
115
|
-
|
114
|
+
AprRecords: {
|
115
|
+
take: 1,
|
116
|
+
orderBy: { timestamp: "desc" },
|
117
|
+
include: { AprBreakdown: { select: { identifier: true, type: true, value: true } } },
|
118
|
+
},
|
119
|
+
TvlRecords: {
|
120
|
+
take: 1,
|
121
|
+
orderBy: { timestamp: "desc" },
|
122
|
+
include: { TvlBreakdown: { select: { identifier: true, type: true, value: true } } },
|
123
|
+
},
|
116
124
|
DailyRewardsRecords: {
|
117
125
|
take: 1,
|
118
126
|
orderBy: { timestamp: "desc" },
|
@@ -8,6 +8,19 @@ import { OpportunityRepository } from "./opportunity.repository";
|
|
8
8
|
export declare abstract class OpportunityService {
|
9
9
|
#private;
|
10
10
|
static hashId(opportunity: OpportunityUnique): string;
|
11
|
+
static getAprBins(query: GetOpportunitiesQueryModel): Promise<{
|
12
|
+
min: number;
|
13
|
+
max: number;
|
14
|
+
overThreshold: number;
|
15
|
+
binWidth: number;
|
16
|
+
bins: any[];
|
17
|
+
}>;
|
18
|
+
static getTvlBins(query: GetOpportunitiesQueryModel): Promise<{
|
19
|
+
min: number;
|
20
|
+
max: number;
|
21
|
+
binWidth: number;
|
22
|
+
bins: any[];
|
23
|
+
}>;
|
11
24
|
static override(id: string, data: OpportunityOverrideModel): Promise<{
|
12
25
|
status: import("@db/api").$Enums.Status;
|
13
26
|
type: string;
|
@@ -625,16 +638,12 @@ export declare abstract class OpportunityService {
|
|
625
638
|
cumulated: number;
|
626
639
|
timestamp: bigint;
|
627
640
|
breakdowns: ({
|
628
|
-
id: string;
|
629
641
|
value: number;
|
630
|
-
aprRecordId: string;
|
631
642
|
distributionType: import("@db/api").$Enums.DistributionType;
|
632
643
|
identifier: string;
|
633
644
|
type: "CAMPAIGN";
|
634
645
|
} | {
|
635
|
-
id: string;
|
636
646
|
value: number;
|
637
|
-
aprRecordId: string;
|
638
647
|
identifier: string;
|
639
648
|
type: import("@db/api").$Enums.AprType;
|
640
649
|
})[];
|
@@ -645,10 +654,8 @@ export declare abstract class OpportunityService {
|
|
645
654
|
timestamp: bigint;
|
646
655
|
breakdowns: {
|
647
656
|
type: import("@db/api").$Enums.TvlType;
|
648
|
-
id: string;
|
649
657
|
identifier: string;
|
650
658
|
value: number;
|
651
|
-
tvlRecordId: string;
|
652
659
|
}[];
|
653
660
|
};
|
654
661
|
rewardsRecord: {
|
@@ -815,16 +822,12 @@ export declare abstract class OpportunityService {
|
|
815
822
|
cumulated: number;
|
816
823
|
timestamp: bigint;
|
817
824
|
breakdowns: ({
|
818
|
-
id: string;
|
819
825
|
value: number;
|
820
|
-
aprRecordId: string;
|
821
826
|
distributionType: import("@db/api").$Enums.DistributionType;
|
822
827
|
identifier: string;
|
823
828
|
type: "CAMPAIGN";
|
824
829
|
} | {
|
825
|
-
id: string;
|
826
830
|
value: number;
|
827
|
-
aprRecordId: string;
|
828
831
|
identifier: string;
|
829
832
|
type: import("@db/api").$Enums.AprType;
|
830
833
|
})[];
|
@@ -835,10 +838,8 @@ export declare abstract class OpportunityService {
|
|
835
838
|
timestamp: bigint;
|
836
839
|
breakdowns: {
|
837
840
|
type: import("@db/api").$Enums.TvlType;
|
838
|
-
id: string;
|
839
841
|
identifier: string;
|
840
842
|
value: number;
|
841
|
-
tvlRecordId: string;
|
842
843
|
}[];
|
843
844
|
};
|
844
845
|
rewardsRecord: {
|
@@ -998,16 +999,12 @@ export declare abstract class OpportunityService {
|
|
998
999
|
cumulated: number;
|
999
1000
|
timestamp: bigint;
|
1000
1001
|
breakdowns: ({
|
1001
|
-
id: string;
|
1002
1002
|
value: number;
|
1003
|
-
aprRecordId: string;
|
1004
1003
|
distributionType: import("@db/api").$Enums.DistributionType;
|
1005
1004
|
identifier: string;
|
1006
1005
|
type: "CAMPAIGN";
|
1007
1006
|
} | {
|
1008
|
-
id: string;
|
1009
1007
|
value: number;
|
1010
|
-
aprRecordId: string;
|
1011
1008
|
identifier: string;
|
1012
1009
|
type: import("@db/api").$Enums.AprType;
|
1013
1010
|
})[];
|
@@ -1018,10 +1015,8 @@ export declare abstract class OpportunityService {
|
|
1018
1015
|
timestamp: bigint;
|
1019
1016
|
breakdowns: {
|
1020
1017
|
type: import("@db/api").$Enums.TvlType;
|
1021
|
-
id: string;
|
1022
1018
|
identifier: string;
|
1023
1019
|
value: number;
|
1024
|
-
tvlRecordId: string;
|
1025
1020
|
}[];
|
1026
1021
|
};
|
1027
1022
|
rewardsRecord: {
|
@@ -17,6 +17,67 @@ export class OpportunityService {
|
|
17
17
|
static hashId(opportunity) {
|
18
18
|
return Bun.hash(`${opportunity.chainId}${opportunity.type}${opportunity.identifier}`).toString();
|
19
19
|
}
|
20
|
+
static async getAprBins(query) {
|
21
|
+
const BINS_COUNT = 20;
|
22
|
+
const opportunities = await OpportunityRepository.findMany({
|
23
|
+
...query,
|
24
|
+
status: "LIVE",
|
25
|
+
sort: "apr",
|
26
|
+
order: "asc",
|
27
|
+
items: 0,
|
28
|
+
});
|
29
|
+
const mid = Math.floor(opportunities.length / 2);
|
30
|
+
const median = opportunities.length % 2 !== 0
|
31
|
+
? opportunities[mid].apr
|
32
|
+
: (opportunities[mid - 1].apr + opportunities[mid].apr) / 2;
|
33
|
+
const threshold = 5 * median;
|
34
|
+
if (opportunities.length < 2)
|
35
|
+
throw new Error("Not enough opportunities");
|
36
|
+
const maxAprUnderThreshold = opportunities.filter(o => o.apr <= threshold).at(-1)?.apr ?? 0;
|
37
|
+
const minAprAbove0 = opportunities.find(o => o.apr > 0)?.apr ?? 0;
|
38
|
+
const binWidth = (maxAprUnderThreshold - minAprAbove0) / BINS_COUNT;
|
39
|
+
const bins = new Array(BINS_COUNT);
|
40
|
+
for (let i = 0; i < BINS_COUNT; i++)
|
41
|
+
bins[i] = 0;
|
42
|
+
let overThreshold = 0;
|
43
|
+
for (const opportunity of opportunities) {
|
44
|
+
if (opportunity.apr > 0 && opportunity.apr < threshold)
|
45
|
+
bins[Math.min(Math.floor(opportunity.apr / binWidth), BINS_COUNT - 1)]++;
|
46
|
+
else
|
47
|
+
overThreshold++;
|
48
|
+
}
|
49
|
+
return {
|
50
|
+
min: opportunities[0].apr,
|
51
|
+
max: opportunities[opportunities.length - 1].apr,
|
52
|
+
overThreshold,
|
53
|
+
binWidth,
|
54
|
+
bins,
|
55
|
+
};
|
56
|
+
}
|
57
|
+
static async getTvlBins(query) {
|
58
|
+
const BINS_COUNT = 20;
|
59
|
+
const opportunities = await OpportunityRepository.findMany({
|
60
|
+
...query,
|
61
|
+
status: "LIVE,SOON",
|
62
|
+
sort: "tvl",
|
63
|
+
order: "asc",
|
64
|
+
items: 0,
|
65
|
+
});
|
66
|
+
if (opportunities.length < 2)
|
67
|
+
throw new Error("Not enough opportunities");
|
68
|
+
const binWidth = (opportunities[opportunities.length - 1].tvl - opportunities[0].tvl) / BINS_COUNT;
|
69
|
+
const bins = new Array(BINS_COUNT);
|
70
|
+
for (let i = 0; i < BINS_COUNT; i++)
|
71
|
+
bins[i] = 0;
|
72
|
+
for (const opportunity of opportunities)
|
73
|
+
bins[Math.min(Math.floor(opportunity.tvl / binWidth), BINS_COUNT - 1)]++;
|
74
|
+
return {
|
75
|
+
min: opportunities[0].tvl,
|
76
|
+
max: opportunities[opportunities.length - 1].tvl,
|
77
|
+
binWidth,
|
78
|
+
bins,
|
79
|
+
};
|
80
|
+
}
|
20
81
|
static async override(id, data) {
|
21
82
|
const opportunity = await OpportunityRepository.findUniqueOrThrow(id);
|
22
83
|
const overrides = opportunity.manualOverrides ?? [];
|
@@ -129,6 +129,6 @@ export const RewardController = new Elysia({ prefix: "/rewards", detail: { tags:
|
|
129
129
|
detail: { hide: true },
|
130
130
|
})
|
131
131
|
.get("/total/distributed", async ({ query }) => await RewardService.getTotalDistributed(query.since.getTime() / 1000))
|
132
|
-
.get("/total/distributed/by-chains", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.
|
132
|
+
.get("/total/distributed/by-chains", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByChain, query.since.getTime() / 1000))
|
133
133
|
.get("/total/distributed/by-types", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, query.since.getTime() / 1000))
|
134
134
|
.get("/total/distributed/by-protocols", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, query.since.getTime() / 1000));
|
@@ -14,16 +14,12 @@ export declare abstract class RewardService {
|
|
14
14
|
cumulated: number;
|
15
15
|
timestamp: bigint;
|
16
16
|
breakdowns: ({
|
17
|
-
id: string;
|
18
17
|
value: number;
|
19
|
-
aprRecordId: string;
|
20
18
|
distributionType: import("@db/api").$Enums.DistributionType;
|
21
19
|
identifier: string;
|
22
20
|
type: "CAMPAIGN";
|
23
21
|
} | {
|
24
|
-
id: string;
|
25
22
|
value: number;
|
26
|
-
aprRecordId: string;
|
27
23
|
identifier: string;
|
28
24
|
type: import("@db/api").$Enums.AprType;
|
29
25
|
})[];
|
@@ -34,10 +30,8 @@ export declare abstract class RewardService {
|
|
34
30
|
timestamp: bigint;
|
35
31
|
breakdowns: {
|
36
32
|
type: import("@db/api").$Enums.TvlType;
|
37
|
-
id: string;
|
38
33
|
identifier: string;
|
39
34
|
value: number;
|
40
|
-
tvlRecordId: string;
|
41
35
|
}[];
|
42
36
|
};
|
43
37
|
rewardsRecord: {
|
@@ -192,7 +186,7 @@ export declare abstract class RewardService {
|
|
192
186
|
dailyRewards: number;
|
193
187
|
}, number>>;
|
194
188
|
static getTotalDistributed(since: number): Promise<number>;
|
195
|
-
static
|
189
|
+
static getTotalDistributedByChain(since: number): Promise<any>;
|
196
190
|
static getTotalDistributedByProtocol(since: number): Promise<any>;
|
197
191
|
static getTotalDistributedByType(since: number): Promise<any>;
|
198
192
|
/**
|
@@ -44,7 +44,7 @@ export class RewardService {
|
|
44
44
|
const oppToDailyRewards = await RewardService.getTotalDistributedByOpportunities(since);
|
45
45
|
return oppToDailyRewards.values().reduce((prev, curr) => prev + curr, 0);
|
46
46
|
}
|
47
|
-
static async
|
47
|
+
static async getTotalDistributedByChain(since) {
|
48
48
|
const oppToDailyRewards = await RewardService.getTotalDistributedByOpportunities(since);
|
49
49
|
const chainsToDailyRewards = new Map();
|
50
50
|
for (const [opp, dr] of oppToDailyRewards.entries()) {
|