@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
@@ -57,56 +57,11 @@ const main = async () => {
|
|
57
57
|
}, {});
|
58
58
|
const now = new Date();
|
59
59
|
const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 0, 0, 0, 0)).getTime() / 1000;
|
60
|
-
const firstDayOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1,
|
61
|
-
0, // 0 hours
|
62
|
-
0, // 0 minutes
|
63
|
-
0, // 0 seconds
|
64
|
-
0 // 0 milliseconds
|
65
|
-
)).getTime() / 1000;
|
60
|
+
const firstDayOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1, 0, 0, 0, 0)).getTime() / 1000;
|
66
61
|
const promises = [
|
67
|
-
// ─── Rewards
|
68
|
-
|
69
|
-
|
70
|
-
const promises = [];
|
71
|
-
// ─── Check If Page Already Exists ────────────────────
|
72
|
-
for (const type of Object.keys(result)) {
|
73
|
-
const page = currentMonthPages.find(page => "properties" in page &&
|
74
|
-
page.properties.Types.title[0].text.content === type);
|
75
|
-
// ─── If Page Exists, Update It ───────────────
|
76
|
-
if (page) {
|
77
|
-
promises.push(notion.pages.update({
|
78
|
-
page_id: page.id,
|
79
|
-
properties: {
|
80
|
-
Rewards: {
|
81
|
-
type: "number",
|
82
|
-
number: result[type],
|
83
|
-
},
|
84
|
-
To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
|
85
|
-
},
|
86
|
-
}));
|
87
|
-
// ─── Else, Create It ─────────────────
|
88
|
-
}
|
89
|
-
else {
|
90
|
-
promises.push(notion.pages.create({
|
91
|
-
parent: { type: "database_id", database_id: MONTHLY_REWARDS_BY_TYPES_DATABASE_ID },
|
92
|
-
properties: {
|
93
|
-
Types: {
|
94
|
-
type: "title",
|
95
|
-
title: [{ type: "text", text: { content: type } }],
|
96
|
-
},
|
97
|
-
Rewards: { type: "number", number: result[type] },
|
98
|
-
From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
|
99
|
-
To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
|
100
|
-
},
|
101
|
-
}));
|
102
|
-
}
|
103
|
-
}
|
104
|
-
// ─── Run All The Promises In Parallel ────────────────
|
105
|
-
await Promise.all(promises);
|
106
|
-
log.info("Total Distributed by Types data pushed to Notion successfully");
|
107
|
-
}),
|
108
|
-
// ─── Rewards By Chains ───────────────────────────────────────
|
109
|
-
CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChains, firstDayOfMonth).then(async (result) => {
|
62
|
+
// ─── Monthly Rewards ─────────────────────────────────────────────────────────
|
63
|
+
// ─── By Chains ───────────────────────────────────────────────
|
64
|
+
CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChain, firstDayOfMonth).then(async (result) => {
|
110
65
|
const currentMonthPages = await getPagesOfTheMonth(MONTHLY_REWARDS_BY_CHAINS_DATABASE_ID);
|
111
66
|
const promises = [];
|
112
67
|
for (const chain of Object.keys(result)) {
|
@@ -143,7 +98,7 @@ const main = async () => {
|
|
143
98
|
await Promise.all(promises);
|
144
99
|
log.info("Total Distributed by Chains data pushed to Notion successfully");
|
145
100
|
}),
|
146
|
-
// ───
|
101
|
+
// ─── By Protocols ────────────────────────────────────────────
|
147
102
|
CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, firstDayOfMonth).then(async (result) => {
|
148
103
|
const currentMonthPages = await getPagesOfTheMonth(MONTHLY_REWARDS_BY_PROTOCOLS_DATABASE_ID);
|
149
104
|
const promises = [];
|
@@ -181,44 +136,50 @@ const main = async () => {
|
|
181
136
|
await Promise.all(promises);
|
182
137
|
log.info("Total Distributed by Protocols data pushed to Notion successfully");
|
183
138
|
}),
|
184
|
-
// ───
|
185
|
-
CacheService.set(TTLPresets.DAY_1, RewardService.
|
186
|
-
const
|
139
|
+
// ─── By Types ────────────────────────────────────────────────
|
140
|
+
CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, firstDayOfMonth).then(async (result) => {
|
141
|
+
const currentMonthPages = await getPagesOfTheMonth(MONTHLY_REWARDS_BY_TYPES_DATABASE_ID);
|
187
142
|
const promises = [];
|
188
|
-
|
189
|
-
|
190
|
-
|
143
|
+
// ─── Check If Page Already Exists ────────────────────
|
144
|
+
for (const type of Object.keys(result)) {
|
145
|
+
const page = currentMonthPages.find(page => "properties" in page &&
|
146
|
+
page.properties.Types.title[0].text.content === type);
|
147
|
+
// ─── If Page Exists, Update It ───────────────
|
191
148
|
if (page) {
|
192
149
|
promises.push(notion.pages.update({
|
193
150
|
page_id: page.id,
|
194
151
|
properties: {
|
195
152
|
Rewards: {
|
196
153
|
type: "number",
|
197
|
-
number: result[
|
154
|
+
number: result[type],
|
198
155
|
},
|
199
|
-
|
156
|
+
To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
|
200
157
|
},
|
201
158
|
}));
|
159
|
+
// ─── Else, Create It ─────────────────
|
202
160
|
}
|
203
161
|
else {
|
204
162
|
promises.push(notion.pages.create({
|
205
|
-
parent: { type: "database_id", database_id:
|
163
|
+
parent: { type: "database_id", database_id: MONTHLY_REWARDS_BY_TYPES_DATABASE_ID },
|
206
164
|
properties: {
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
type: "date",
|
211
|
-
date: { start: now.toISOString().split("T")[0] },
|
165
|
+
Types: {
|
166
|
+
type: "title",
|
167
|
+
title: [{ type: "text", text: { content: type } }],
|
212
168
|
},
|
169
|
+
Rewards: { type: "number", number: result[type] },
|
170
|
+
From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
|
171
|
+
To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
|
213
172
|
},
|
214
173
|
}));
|
215
174
|
}
|
216
175
|
}
|
176
|
+
// ─── Run All The Promises In Parallel ────────────────
|
217
177
|
await Promise.all(promises);
|
218
|
-
log.info("Total Distributed by
|
178
|
+
log.info("Total Distributed by Types data pushed to Notion successfully");
|
219
179
|
}),
|
180
|
+
// ─── Daily Rewards ───────────────────────────────────────────────────────────
|
220
181
|
// ─── By Chains ───────────────────────────────────────────────
|
221
|
-
CacheService.set(TTLPresets.DAY_1, RewardService.
|
182
|
+
CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChain, today).then(async (result) => {
|
222
183
|
const pagesOfTheDay = await getPagesOfTheDay(DAILY_REWARDS_BY_CHAINS_DATABASE_ID);
|
223
184
|
const promises = [];
|
224
185
|
for (const chain of Object.keys(result)) {
|
@@ -254,7 +215,43 @@ const main = async () => {
|
|
254
215
|
await Promise.all(promises);
|
255
216
|
log.info("Total Distributed by Chains data pushed to Notion successfully");
|
256
217
|
}),
|
257
|
-
// ───
|
218
|
+
// ─── By Protocols ────────────────────────────────────────────
|
219
|
+
CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, today).then(async (result) => {
|
220
|
+
const pagesOfTheDay = await getPagesOfTheDay(DAILY_REWARDS_BY_PROTOCOLS_DATABASE_ID);
|
221
|
+
const promises = [];
|
222
|
+
for (const protocol of Object.keys(result)) {
|
223
|
+
const page = pagesOfTheDay.find(page => "properties" in page &&
|
224
|
+
page.properties.Protocols.title[0].text.content === protocol);
|
225
|
+
if (page) {
|
226
|
+
promises.push(notion.pages.update({
|
227
|
+
page_id: page.id,
|
228
|
+
properties: {
|
229
|
+
Rewards: {
|
230
|
+
type: "number",
|
231
|
+
number: result[page.properties.Protocols.title[0].text.content],
|
232
|
+
},
|
233
|
+
Date: { type: "date", date: { start: now.toISOString().split("T")[0] } },
|
234
|
+
},
|
235
|
+
}));
|
236
|
+
}
|
237
|
+
else {
|
238
|
+
promises.push(notion.pages.create({
|
239
|
+
parent: { type: "database_id", database_id: DAILY_REWARDS_BY_PROTOCOLS_DATABASE_ID },
|
240
|
+
properties: {
|
241
|
+
Protocols: { type: "title", title: [{ type: "text", text: { content: protocol } }] },
|
242
|
+
Rewards: { type: "number", number: result[protocol] },
|
243
|
+
Date: {
|
244
|
+
type: "date",
|
245
|
+
date: { start: now.toISOString().split("T")[0] },
|
246
|
+
},
|
247
|
+
},
|
248
|
+
}));
|
249
|
+
}
|
250
|
+
}
|
251
|
+
await Promise.all(promises);
|
252
|
+
log.info("Total Distributed by Protocols data pushed to Notion successfully");
|
253
|
+
}),
|
254
|
+
// ─── By Types ────────────────────────────────────────────────
|
258
255
|
CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, today).then(async (result) => {
|
259
256
|
const currentMonthPages = await getPagesOfTheDay(DAILY_REWARDS_BY_TYPES_DATABASE_ID);
|
260
257
|
const promises = [];
|
@@ -294,7 +291,8 @@ const main = async () => {
|
|
294
291
|
await Promise.all(promises);
|
295
292
|
log.info("Total Distributed by Types data pushed to Notion successfully");
|
296
293
|
}),
|
297
|
-
// ─── Campaigns
|
294
|
+
// ─── Monthly New Campaigns ───────────────────────────────────────────────────
|
295
|
+
// ─── By Chains ───────────────────────────────────────────────
|
298
296
|
CacheService.set(TTLPresets.DAY_1, CampaignService.countByChains, {
|
299
297
|
createdAfter: new Date(firstDayOfMonth * 1000),
|
300
298
|
}).then(async (result) => {
|
@@ -337,7 +335,7 @@ const main = async () => {
|
|
337
335
|
await Promise.all(promises);
|
338
336
|
log.info("Campaigns by Chains data pushed to Notion successfully");
|
339
337
|
}),
|
340
|
-
// ───
|
338
|
+
// ─── By Protocols ────────────────────────────────────────────
|
341
339
|
CacheService.set(TTLPresets.DAY_1, CampaignService.countByProtocols, {
|
342
340
|
createdAfter: new Date(firstDayOfMonth * 1000),
|
343
341
|
}).then(async (result) => {
|
@@ -376,7 +374,7 @@ const main = async () => {
|
|
376
374
|
await Promise.all(promises);
|
377
375
|
log.info("Campaigns by Protocols data pushed to Notion successfully");
|
378
376
|
}),
|
379
|
-
// ───
|
377
|
+
// ─── By Types ────────────────────────────────────────────────
|
380
378
|
CacheService.set(TTLPresets.DAY_1, CampaignService.countByTypes, {
|
381
379
|
createdAfter: new Date(firstDayOfMonth * 1000),
|
382
380
|
}).then(async (result) => {
|
@@ -418,7 +416,8 @@ const main = async () => {
|
|
418
416
|
await Promise.all(promises);
|
419
417
|
log.info("Campaigns by Types data pushed to Notion successfully");
|
420
418
|
}),
|
421
|
-
// ─── Daily Campaigns
|
419
|
+
// ─── Daily New Campaigns ─────────────────────────────────────────────────────
|
420
|
+
// ─── By Chains ───────────────────────────────────────────────
|
422
421
|
CacheService.set(TTLPresets.DAY_1, CampaignService.countByChains, {
|
423
422
|
createdAfter: new Date(today * 1000),
|
424
423
|
}).then(async (result) => {
|
@@ -457,7 +456,7 @@ const main = async () => {
|
|
457
456
|
await Promise.all(promises);
|
458
457
|
log.info("Campaigns by Chains data pushed to Notion successfully");
|
459
458
|
}),
|
460
|
-
// ───
|
459
|
+
// ─── By Protocols ────────────────────────────────────────────
|
461
460
|
CacheService.set(TTLPresets.DAY_1, CampaignService.countByProtocols, {
|
462
461
|
createdAfter: new Date(today * 1000),
|
463
462
|
}).then(async (result) => {
|
@@ -495,7 +494,7 @@ const main = async () => {
|
|
495
494
|
await Promise.all(promises);
|
496
495
|
log.info("Campaigns by Protocols data pushed to Notion successfully");
|
497
496
|
}),
|
498
|
-
// ───
|
497
|
+
// ─── By Types ────────────────────────────────────────────────
|
499
498
|
CacheService.set(TTLPresets.DAY_1, CampaignService.countByTypes, {
|
500
499
|
createdAfter: new Date(today * 1000),
|
501
500
|
}).then(async (result) => {
|
@@ -534,10 +533,15 @@ const main = async () => {
|
|
534
533
|
log.info("Campaigns by Types data pushed to Notion successfully");
|
535
534
|
}),
|
536
535
|
];
|
537
|
-
await Promise.
|
536
|
+
return await Promise.allSettled(promises);
|
538
537
|
};
|
539
538
|
main()
|
540
|
-
.then(
|
539
|
+
.then(results => {
|
540
|
+
const rejected = results.find(result => result.status === "rejected");
|
541
|
+
if (rejected)
|
542
|
+
throw new Error(`One or more promises were rejected: ${JSON.stringify(rejected.reason)}`);
|
543
|
+
process.exit(0);
|
544
|
+
})
|
541
545
|
.catch(err => {
|
542
546
|
console.error(err);
|
543
547
|
process.exit(1);
|
@@ -441,6 +441,31 @@ export declare const CampaignController: Elysia<"/campaigns", false, {
|
|
441
441
|
};
|
442
442
|
};
|
443
443
|
};
|
444
|
+
} & {
|
445
|
+
":id": {
|
446
|
+
timeseries: {
|
447
|
+
get: {
|
448
|
+
body: unknown;
|
449
|
+
params: {
|
450
|
+
id: string;
|
451
|
+
};
|
452
|
+
query: unknown;
|
453
|
+
headers: unknown;
|
454
|
+
response: {
|
455
|
+
200: {
|
456
|
+
tvlRecords: {
|
457
|
+
total: number;
|
458
|
+
timestamp: bigint;
|
459
|
+
}[];
|
460
|
+
aprRecords: {
|
461
|
+
timestamp: bigint;
|
462
|
+
cumulated: number;
|
463
|
+
}[];
|
464
|
+
};
|
465
|
+
};
|
466
|
+
};
|
467
|
+
};
|
468
|
+
};
|
444
469
|
} & {
|
445
470
|
"campaigns-to-process": {
|
446
471
|
index: {
|
@@ -3,6 +3,7 @@ import { BackOfficeGuard } from "@/guards/BackOffice.guard";
|
|
3
3
|
import { AuthorizationHeadersDto, EngineGuard } from "@/guards/Engine.guard";
|
4
4
|
import { CacheService } from "@/modules/v4/cache/cache.service";
|
5
5
|
import { ChainUniqueDto } from "@/modules/v4/chain/chain.model";
|
6
|
+
import { log } from "@/utils/logger";
|
6
7
|
import { Campaign } from "@sdk";
|
7
8
|
import Elysia, { t } from "elysia";
|
8
9
|
import { throwOnUnsupportedChainId } from "src/utils/throw";
|
@@ -84,7 +85,7 @@ export const CampaignController = new Elysia({ prefix: "/campaigns", detail: { t
|
|
84
85
|
return CampaignService.format(await CampaignService.findUniqueOrThrow({ distributionChain: +distributionChain, campaignId }));
|
85
86
|
}
|
86
87
|
catch (err) {
|
87
|
-
|
88
|
+
log.error(`Error getting campaign: ${params.id}`, err);
|
88
89
|
throw new NotFoundError("Campaign not found.");
|
89
90
|
}
|
90
91
|
}, {
|
@@ -94,6 +95,12 @@ export const CampaignController = new Elysia({ prefix: "/campaigns", detail: { t
|
|
94
95
|
description: `**Retrieve A Campaign**
|
95
96
|
<p>This endpoint enables you to retrieve a campaign by providing its unique identifier.</p>`,
|
96
97
|
},
|
98
|
+
})
|
99
|
+
.get("/:id/timeseries", async ({ params }) => {
|
100
|
+
if (!params.id.includes("-"))
|
101
|
+
return await CampaignService.getTimeSeries(params.id);
|
102
|
+
const [distributionChain, campaignId] = params.id.split("-");
|
103
|
+
return await CampaignService.getTimeSeries({ distributionChain: +distributionChain, campaignId });
|
97
104
|
})
|
98
105
|
.group("/campaigns-to-process", app => {
|
99
106
|
return (app
|
@@ -775,4 +775,20 @@ export declare abstract class CampaignRepository {
|
|
775
775
|
manualOverrides: import("@db/api").$Enums.CampaignManualOverride[];
|
776
776
|
createdAt: Date;
|
777
777
|
}>;
|
778
|
+
static getTvlRecords(campaign: {
|
779
|
+
opportunityId: string;
|
780
|
+
startTimestamp: bigint;
|
781
|
+
endTimestamp: bigint;
|
782
|
+
}): Promise<{
|
783
|
+
total: number;
|
784
|
+
timestamp: bigint;
|
785
|
+
}[]>;
|
786
|
+
static getAprRecords(campaign: {
|
787
|
+
opportunityId: string;
|
788
|
+
startTimestamp: bigint;
|
789
|
+
endTimestamp: bigint;
|
790
|
+
}): Promise<{
|
791
|
+
timestamp: bigint;
|
792
|
+
cumulated: number;
|
793
|
+
}[]>;
|
778
794
|
}
|
@@ -449,4 +449,22 @@ export class CampaignRepository {
|
|
449
449
|
};
|
450
450
|
return await apiDbClient.campaign.update({ where: { id }, data: updateData });
|
451
451
|
}
|
452
|
+
static async getTvlRecords(campaign) {
|
453
|
+
return await apiDbClient.tVLRecord.findMany({
|
454
|
+
where: {
|
455
|
+
opportunityId: campaign.opportunityId,
|
456
|
+
timestamp: { gte: campaign.startTimestamp, lte: campaign.endTimestamp },
|
457
|
+
},
|
458
|
+
select: { timestamp: true, total: true },
|
459
|
+
});
|
460
|
+
}
|
461
|
+
static async getAprRecords(campaign) {
|
462
|
+
return await apiDbClient.aprRecord.findMany({
|
463
|
+
where: {
|
464
|
+
opportunityId: campaign.opportunityId,
|
465
|
+
timestamp: { gte: campaign.startTimestamp, lte: campaign.endTimestamp },
|
466
|
+
},
|
467
|
+
select: { timestamp: true, cumulated: true },
|
468
|
+
});
|
469
|
+
}
|
452
470
|
}
|
@@ -914,4 +914,14 @@ export declare abstract class CampaignService {
|
|
914
914
|
endTimestamp: any;
|
915
915
|
params: string;
|
916
916
|
};
|
917
|
+
static getTimeSeries(campaignId: CampaignUnique | string): Promise<{
|
918
|
+
tvlRecords: {
|
919
|
+
total: number;
|
920
|
+
timestamp: bigint;
|
921
|
+
}[];
|
922
|
+
aprRecords: {
|
923
|
+
timestamp: bigint;
|
924
|
+
cumulated: number;
|
925
|
+
}[];
|
926
|
+
}>;
|
917
927
|
}
|
@@ -384,4 +384,11 @@ export class CampaignService {
|
|
384
384
|
params: JSON.stringify(fakeCampaign.campaignParameters),
|
385
385
|
};
|
386
386
|
}
|
387
|
+
static async getTimeSeries(campaignId) {
|
388
|
+
const id = typeof campaignId === "string" ? campaignId : CampaignService.hashId(campaignId);
|
389
|
+
const campaign = await CampaignRepository.findUniqueOrThrow(id, false);
|
390
|
+
const tvlRecords = await CampaignRepository.getTvlRecords(campaign);
|
391
|
+
const aprRecords = await CampaignRepository.getAprRecords(campaign);
|
392
|
+
return { tvlRecords, aprRecords };
|
393
|
+
}
|
387
394
|
}
|