@merkl/api 0.19.49 → 0.20.0
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/src/eden/index.d.ts +30 -10
- package/dist/src/index.d.ts +6 -2
- package/dist/src/jobs/reward-breakdowns.js +1 -1
- package/dist/src/jobs/update-rpc-calls-cache.d.ts +1 -0
- package/dist/src/jobs/update-rpc-calls-cache.js +20 -0
- package/dist/src/modules/v4/merklRoot/merklRoot.service.d.ts +7 -0
- package/dist/src/modules/v4/merklRoot/merklRoot.service.js +15 -1
- package/dist/src/modules/v4/reward/reward.service.js +9 -9
- package/dist/src/modules/v4/router.d.ts +6 -2
- package/dist/src/modules/v4/token/token.controller.d.ts +6 -2
- package/dist/src/modules/v4/token/token.model.d.ts +6 -2
- package/dist/src/modules/v4/token/token.model.js +6 -1
- package/dist/src/modules/v4/token/token.service.js +2 -1
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +2 -1
package/dist/src/eden/index.d.ts
CHANGED
@@ -1893,11 +1893,15 @@ declare const eden: {
|
|
1893
1893
|
data: {
|
1894
1894
|
properties: {
|
1895
1895
|
"Icon (Required)": {
|
1896
|
-
files: {
|
1896
|
+
files: ({
|
1897
1897
|
file: {
|
1898
1898
|
url: string;
|
1899
1899
|
};
|
1900
|
-
}
|
1900
|
+
} | {
|
1901
|
+
external: {
|
1902
|
+
url: string;
|
1903
|
+
};
|
1904
|
+
})[];
|
1901
1905
|
};
|
1902
1906
|
"Address (in checksum format) (Required)": {
|
1903
1907
|
rich_text: {
|
@@ -5631,11 +5635,15 @@ declare const eden: {
|
|
5631
5635
|
data: {
|
5632
5636
|
properties: {
|
5633
5637
|
"Icon (Required)": {
|
5634
|
-
files: {
|
5638
|
+
files: ({
|
5635
5639
|
file: {
|
5636
5640
|
url: string;
|
5637
5641
|
};
|
5638
|
-
}
|
5642
|
+
} | {
|
5643
|
+
external: {
|
5644
|
+
url: string;
|
5645
|
+
};
|
5646
|
+
})[];
|
5639
5647
|
};
|
5640
5648
|
"Address (in checksum format) (Required)": {
|
5641
5649
|
rich_text: {
|
@@ -10435,11 +10443,15 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
10435
10443
|
data: {
|
10436
10444
|
properties: {
|
10437
10445
|
"Icon (Required)": {
|
10438
|
-
files: {
|
10446
|
+
files: ({
|
10439
10447
|
file: {
|
10440
10448
|
url: string;
|
10441
10449
|
};
|
10442
|
-
}
|
10450
|
+
} | {
|
10451
|
+
external: {
|
10452
|
+
url: string;
|
10453
|
+
};
|
10454
|
+
})[];
|
10443
10455
|
};
|
10444
10456
|
"Address (in checksum format) (Required)": {
|
10445
10457
|
rich_text: {
|
@@ -15559,11 +15571,15 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
15559
15571
|
data: {
|
15560
15572
|
properties: {
|
15561
15573
|
"Icon (Required)": {
|
15562
|
-
files: {
|
15574
|
+
files: ({
|
15563
15575
|
file: {
|
15564
15576
|
url: string;
|
15565
15577
|
};
|
15566
|
-
}
|
15578
|
+
} | {
|
15579
|
+
external: {
|
15580
|
+
url: string;
|
15581
|
+
};
|
15582
|
+
})[];
|
15567
15583
|
};
|
15568
15584
|
"Address (in checksum format) (Required)": {
|
15569
15585
|
rich_text: {
|
@@ -19297,11 +19313,15 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
19297
19313
|
data: {
|
19298
19314
|
properties: {
|
19299
19315
|
"Icon (Required)": {
|
19300
|
-
files: {
|
19316
|
+
files: ({
|
19301
19317
|
file: {
|
19302
19318
|
url: string;
|
19303
19319
|
};
|
19304
|
-
}
|
19320
|
+
} | {
|
19321
|
+
external: {
|
19322
|
+
url: string;
|
19323
|
+
};
|
19324
|
+
})[];
|
19305
19325
|
};
|
19306
19326
|
"Address (in checksum format) (Required)": {
|
19307
19327
|
rich_text: {
|
package/dist/src/index.d.ts
CHANGED
@@ -2296,11 +2296,15 @@ declare const app: Elysia<"", false, {
|
|
2296
2296
|
data: {
|
2297
2297
|
properties: {
|
2298
2298
|
"Icon (Required)": {
|
2299
|
-
files: {
|
2299
|
+
files: ({
|
2300
2300
|
file: {
|
2301
2301
|
url: string;
|
2302
2302
|
};
|
2303
|
-
}
|
2303
|
+
} | {
|
2304
|
+
external: {
|
2305
|
+
url: string;
|
2306
|
+
};
|
2307
|
+
})[];
|
2304
2308
|
};
|
2305
2309
|
"Address (in checksum format) (Required)": {
|
2306
2310
|
rich_text: {
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { CacheService } from "@/modules/v4/cache";
|
2
|
+
import { TTLPresets } from "@/modules/v4/cache/cache.model";
|
3
|
+
import { ChainService } from "@/modules/v4/chain/chain.service";
|
4
|
+
import { MerklRootRepository } from "@/modules/v4/merklRoot/merklRoot.repository";
|
5
|
+
import { NETWORK_LABELS, log } from "@sdk";
|
6
|
+
const main = async () => {
|
7
|
+
try {
|
8
|
+
const chains = await ChainService.getSupportedIds();
|
9
|
+
const promises = [];
|
10
|
+
for (const chain of chains)
|
11
|
+
promises.push(CacheService.set(TTLPresets.MIN_10, MerklRootRepository.fetch, chain).catch(_err => log.warn(`RPC calls cache update failed for ${NETWORK_LABELS[chain]}.`)));
|
12
|
+
await Promise.allSettled(promises);
|
13
|
+
process.exit(0);
|
14
|
+
}
|
15
|
+
catch (err) {
|
16
|
+
console.error(err);
|
17
|
+
process.exit(1);
|
18
|
+
}
|
19
|
+
};
|
20
|
+
await main();
|
@@ -19,6 +19,13 @@ export declare class MerklRootService {
|
|
19
19
|
* @returns object with live and last tree roots
|
20
20
|
*/
|
21
21
|
static fetch(chainId: ChainId): Promise<any>;
|
22
|
+
static fetchFromCache(chainId: ChainId): Promise<{
|
23
|
+
live: any;
|
24
|
+
tree: any;
|
25
|
+
lastTree: any;
|
26
|
+
endOfDisputePeriod: any;
|
27
|
+
disputer: any;
|
28
|
+
}>;
|
22
29
|
/**
|
23
30
|
* Fetch all roots for the provided chains
|
24
31
|
* @param chainIds to fetch roots for
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { HttpError } from "@/errors";
|
1
2
|
import { log } from "@/utils/logger";
|
2
3
|
import { NETWORK_LABELS, withTimeout } from "@sdk";
|
3
4
|
import { CacheService } from "../cache";
|
@@ -29,6 +30,19 @@ export class MerklRootService {
|
|
29
30
|
throw e;
|
30
31
|
}
|
31
32
|
}
|
33
|
+
static async fetchFromCache(chainId) {
|
34
|
+
try {
|
35
|
+
const data = await CacheService.get(MerklRootRepository.fetch, [chainId]);
|
36
|
+
if (data === null)
|
37
|
+
throw new Error("DATA_NOT_FOUND");
|
38
|
+
return data;
|
39
|
+
}
|
40
|
+
catch (err) {
|
41
|
+
if (err && err instanceof Error && err.message === "DATA_NOT_FOUND")
|
42
|
+
throw new HttpError(`Failed to fetch data for chain ${chainId}.`, 500);
|
43
|
+
return await MerklRootRepository.fetch(chainId);
|
44
|
+
}
|
45
|
+
}
|
32
46
|
/**
|
33
47
|
* Fetch all roots for the provided chains
|
34
48
|
* @param chainIds to fetch roots for
|
@@ -38,7 +52,7 @@ export class MerklRootService {
|
|
38
52
|
return await CacheService.wrap(TTLPresets.MIN_1, async () => {
|
39
53
|
let ids = chainIds ?? (await ChainService.getIds());
|
40
54
|
/** Fetch current Merkle Roots */
|
41
|
-
const merkleRootsPromises = await Promise.allSettled(ids.map(chainId => MerklRootService.
|
55
|
+
const merkleRootsPromises = await Promise.allSettled(ids.map(chainId => MerklRootService.fetchFromCache(chainId)));
|
42
56
|
/** Filter out unsuccessful chainIds */
|
43
57
|
ids = ids.filter((_, index) => merkleRootsPromises[index].status === "fulfilled");
|
44
58
|
const roots = merkleRootsPromises
|
@@ -237,7 +237,7 @@ export class RewardService {
|
|
237
237
|
if (isBlacklisted)
|
238
238
|
return res;
|
239
239
|
/** Fetch current Merkle Roots */
|
240
|
-
const merkleRootsPromises = await Promise.allSettled(chainIds.map(chainId => MerklRootService.
|
240
|
+
const merkleRootsPromises = await Promise.allSettled(chainIds.map(chainId => MerklRootService.fetchFromCache(chainId)));
|
241
241
|
/** Filter out unsuccessful chainIds */
|
242
242
|
chainIds = chainIds.filter((_, index) => merkleRootsPromises[index].status === "fulfilled");
|
243
243
|
const merkleRoots = merkleRootsPromises
|
@@ -288,7 +288,7 @@ export class RewardService {
|
|
288
288
|
}
|
289
289
|
}
|
290
290
|
static async countOnChain(chainId) {
|
291
|
-
const roots = await MerklRootService.
|
291
|
+
const roots = await MerklRootService.fetchFromCache(chainId);
|
292
292
|
const promises = [
|
293
293
|
RewardRepository.countRewardAndBreakdownOnChain(chainId, roots.tree),
|
294
294
|
RewardRepository.countRewardAndBreakdownOnChain(chainId, roots.lastTree),
|
@@ -300,42 +300,42 @@ export class RewardService {
|
|
300
300
|
};
|
301
301
|
}
|
302
302
|
static async breakdownForCampaign(query) {
|
303
|
-
const root = await MerklRootService.
|
303
|
+
const root = await MerklRootService.fetchFromCache(query.chainId);
|
304
304
|
const id = CampaignService.hashId({ distributionChain: query.chainId, campaignId: query.campaignId });
|
305
305
|
return RewardRepository.breakdownForCampaign(root.live, id, query);
|
306
306
|
}
|
307
307
|
static async countForCampaign(query) {
|
308
|
-
const root = await MerklRootService.
|
308
|
+
const root = await MerklRootService.fetchFromCache(query.chainId);
|
309
309
|
const id = CampaignService.hashId({ distributionChain: query.chainId, campaignId: query.campaignId });
|
310
310
|
return RewardRepository.countForCampaign(id, root.live);
|
311
311
|
}
|
312
312
|
static async totalForCampaign(query) {
|
313
|
-
const root = await MerklRootService.
|
313
|
+
const root = await MerklRootService.fetchFromCache(query.chainId);
|
314
314
|
return RewardRepository.totalForCampaign(CampaignService.hashId({ distributionChain: query.chainId, campaignId: query.campaignId }), root.live);
|
315
315
|
}
|
316
316
|
static async breakdownForToken(query) {
|
317
317
|
return CacheService.wrap(TTLPresets.MIN_10, async (query) => {
|
318
|
-
const root = await MerklRootService.
|
318
|
+
const root = await MerklRootService.fetchFromCache(query.chainId);
|
319
319
|
const id = TokenService.hashId({ chainId: query.chainId, address: query.address });
|
320
320
|
return RewardRepository.breakdownForToken(root.live, id, query);
|
321
321
|
}, query);
|
322
322
|
}
|
323
323
|
static async countForToken(query) {
|
324
324
|
return CacheService.wrap(TTLPresets.MIN_10, async (query) => {
|
325
|
-
const root = await MerklRootService.
|
325
|
+
const root = await MerklRootService.fetchFromCache(query.chainId);
|
326
326
|
const id = TokenService.hashId({ chainId: query.chainId, address: query.address });
|
327
327
|
return RewardRepository.countForToken(id, root.live);
|
328
328
|
}, query);
|
329
329
|
}
|
330
330
|
static async totalForToken(query) {
|
331
331
|
return CacheService.wrap(TTLPresets.MIN_10, async (query) => {
|
332
|
-
const root = await MerklRootService.
|
332
|
+
const root = await MerklRootService.fetchFromCache(query.chainId);
|
333
333
|
const id = TokenService.hashId({ chainId: query.chainId, address: query.address });
|
334
334
|
return RewardRepository.totalForToken(id, root.live);
|
335
335
|
}, query);
|
336
336
|
}
|
337
337
|
static async getAmountAndClaimedForCampaigns(x) {
|
338
|
-
const currentRoot = await MerklRootService.
|
338
|
+
const currentRoot = await MerklRootService.fetchFromCache(x.chainId);
|
339
339
|
return await RewardRepository.getAmountAndClaimedForCampaigns(currentRoot.live, x);
|
340
340
|
}
|
341
341
|
static async getUnclaimed(x) {
|
@@ -2166,11 +2166,15 @@ export declare const v4: Elysia<"/v4", false, {
|
|
2166
2166
|
data: {
|
2167
2167
|
properties: {
|
2168
2168
|
"Icon (Required)": {
|
2169
|
-
files: {
|
2169
|
+
files: ({
|
2170
2170
|
file: {
|
2171
2171
|
url: string;
|
2172
2172
|
};
|
2173
|
-
}
|
2173
|
+
} | {
|
2174
|
+
external: {
|
2175
|
+
url: string;
|
2176
|
+
};
|
2177
|
+
})[];
|
2174
2178
|
};
|
2175
2179
|
"Address (in checksum format) (Required)": {
|
2176
2180
|
rich_text: {
|
@@ -293,11 +293,15 @@ export declare const TokenController: Elysia<"/tokens", false, {
|
|
293
293
|
data: {
|
294
294
|
properties: {
|
295
295
|
"Icon (Required)": {
|
296
|
-
files: {
|
296
|
+
files: ({
|
297
297
|
file: {
|
298
298
|
url: string;
|
299
299
|
};
|
300
|
-
}
|
300
|
+
} | {
|
301
|
+
external: {
|
302
|
+
url: string;
|
303
|
+
};
|
304
|
+
})[];
|
301
305
|
};
|
302
306
|
"Address (in checksum format) (Required)": {
|
303
307
|
rich_text: {
|
@@ -76,11 +76,15 @@ export declare const NotionWebhookDto: import("@sinclair/typebox").TObject<{
|
|
76
76
|
data: import("@sinclair/typebox").TObject<{
|
77
77
|
properties: import("@sinclair/typebox").TObject<{
|
78
78
|
"Icon (Required)": import("@sinclair/typebox").TObject<{
|
79
|
-
files: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
79
|
+
files: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
80
80
|
file: import("@sinclair/typebox").TObject<{
|
81
81
|
url: import("@sinclair/typebox").TString;
|
82
82
|
}>;
|
83
|
-
}
|
83
|
+
}>, import("@sinclair/typebox").TObject<{
|
84
|
+
external: import("@sinclair/typebox").TObject<{
|
85
|
+
url: import("@sinclair/typebox").TString;
|
86
|
+
}>;
|
87
|
+
}>]>>;
|
84
88
|
}>;
|
85
89
|
"Address (in checksum format) (Required)": import("@sinclair/typebox").TObject<{
|
86
90
|
rich_text: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
@@ -63,7 +63,12 @@ export const CreateTokenDto = t.Object({
|
|
63
63
|
export const NotionWebhookDto = t.Object({
|
64
64
|
data: t.Object({
|
65
65
|
properties: t.Object({
|
66
|
-
"Icon (Required)": t.Object({
|
66
|
+
"Icon (Required)": t.Object({
|
67
|
+
files: t.Array(t.Union([
|
68
|
+
t.Object({ file: t.Object({ url: t.String() }) }),
|
69
|
+
t.Object({ external: t.Object({ url: t.String() }) }),
|
70
|
+
])),
|
71
|
+
}),
|
67
72
|
"Address (in checksum format) (Required)": t.Object({
|
68
73
|
rich_text: t.Array(t.Object({ plain_text: t.String() })),
|
69
74
|
}),
|
@@ -290,7 +290,8 @@ export class TokenService {
|
|
290
290
|
const env = process.env.ENV === "prod" ? "production" : process.env.ENV;
|
291
291
|
const bucket = new BucketService(`merkl-${env}-tokens`, `angle-${env}-1`);
|
292
292
|
const properties = body.data.properties;
|
293
|
-
const
|
293
|
+
const file = properties["Icon (Required)"].files[0];
|
294
|
+
const icon = "external" in file ? file.external.url : file.file.url;
|
294
295
|
const iconFile = await fetch(icon);
|
295
296
|
const mimeType = iconFile.headers.get("content-type");
|
296
297
|
const extension = mimeType.split("/")[1].split("+")[0];
|