@merkl/api 0.20.43 → 0.20.45

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.
@@ -1,9 +1,9 @@
1
- import { Campaign, type CampaignDynamicData } from "@sdk";
1
+ import { Campaign, type CampaignDynamicData, type MerklChainId } from "@sdk";
2
2
  export type CampaignsCacheUpdaterReturnType = {
3
3
  [type_mainParameter: string]: {
4
4
  [campaignId: string]: CampaignDynamicData<Campaign>;
5
5
  };
6
6
  };
7
- export declare const main: () => Promise<{
7
+ export declare const main: (chainId: MerklChainId) => Promise<{
8
8
  success: boolean;
9
9
  }>;
@@ -7,25 +7,15 @@ import { dynamicDataBuilderFactory } from "@/engine/dynamicData/factory";
7
7
  import { campaignsToOldFormat } from "@/libs/deprecated-merklv3";
8
8
  import { merklChainData } from "@/libs/merklChainData";
9
9
  import { staticCampaignWithCache } from "@/libs/staticCampaigns";
10
- import { InvalidParameter, UnsupportedNetwork } from "@/utils/error";
10
+ import { ChainService } from "@/modules/v4/chain/chain.service";
11
11
  import { log } from "@/utils/logger";
12
12
  import { ALL_CAMPAIGNS_FOR_CHAIN_AFTER } from "@/utils/queries/allCampaigns";
13
13
  import { engineDbClient } from "@db";
14
- import { Campaign, ChainId, NETWORK_LABELS, isSupportedChain, } from "@sdk";
14
+ import { Campaign, ChainId, NETWORK_LABELS, } from "@sdk";
15
15
  import moment from "moment";
16
16
  const queryCampaignTypes = process.env.CAMPAIGN_TYPES ? JSON.parse(process.env.CAMPAIGN_TYPES) : [];
17
17
  const highCampaignsChains = [ChainId.ARBITRUM, ChainId.POLYGON, ChainId.BLAST, ChainId.BASE];
18
- export const main = async () => {
19
- const rawChainId = process.env.CHAIN_ID;
20
- let chainId;
21
- if (typeof rawChainId === "string") {
22
- chainId = Number.parseInt(rawChainId);
23
- if (!isSupportedChain(chainId, "merkl"))
24
- throw new UnsupportedNetwork(chainId);
25
- }
26
- else {
27
- throw new InvalidParameter("Invalid chainId provided");
28
- }
18
+ export const main = async (chainId) => {
29
19
  let success = true;
30
20
  try {
31
21
  await Redis.safeSet(`MerklChainData_${chainId}`, await merklChainData(chainId));
@@ -135,7 +125,11 @@ export const main = async () => {
135
125
  }
136
126
  return { success };
137
127
  };
138
- main()
128
+ const chains = await ChainService.getSupportedIds();
129
+ const promises = [];
130
+ for (const chain of chains)
131
+ promises.push(main(chain));
132
+ await Promise.allSettled(promises)
139
133
  .then(success => (success ? process.exit(0) : process.exit(1)))
140
134
  .catch((err) => {
141
135
  console.error(err);
@@ -1,14 +1,14 @@
1
1
  import { CampaignService } from "@/modules/v4/campaign";
2
+ import { ChainService } from "@/modules/v4/chain/chain.service";
2
3
  import { DynamicDataService } from "@/modules/v4/dynamicData/dynamicData.service";
3
4
  import { OpportunityService } from "@/modules/v4/opportunity";
4
5
  import { Campaign as CampaignEnum } from "@sdk";
5
6
  import moment from "moment";
6
7
  // ─── Required Env Variables ──────────────────────────────────────────────────
7
- const chainId = Number(process.env.CHAIN_ID);
8
- if (!chainId)
9
- throw new Error("Environment variable CHAIN_ID is required.");
8
+ // const chainId = Number(process.env.CHAIN_ID);
9
+ // if (!chainId) throw new Error("Environment variable CHAIN_ID is required.");
10
10
  // ─── Update Dynamic Data (APR / TVL / Daily Rewards) ─────────────────────────
11
- const main = async () => {
11
+ const main = async (chainId) => {
12
12
  const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => {
13
13
  return {
14
14
  amount: c.amount,
@@ -58,11 +58,13 @@ const main = async () => {
58
58
  // 4. Update the status of the opportunities associated to live campaigns
59
59
  await OpportunityService.updateMany(liveOpportunityIds, { status: "LIVE" });
60
60
  };
61
- try {
62
- await main();
63
- process.exit(0);
64
- }
65
- catch (err) {
61
+ const chains = await ChainService.getSupportedIds();
62
+ const promises = [];
63
+ for (const chain of chains)
64
+ promises.push(main(chain));
65
+ await Promise.allSettled(promises)
66
+ .then(success => (success ? process.exit(0) : process.exit(1)))
67
+ .catch((err) => {
66
68
  console.error(err);
67
69
  process.exit(1);
68
- }
70
+ });
@@ -3,14 +3,13 @@ import { TTLPresets } from "@/modules/v4/cache/cache.model";
3
3
  import { ChainService } from "@/modules/v4/chain/chain.service";
4
4
  import { MerklRootRepository } from "@/modules/v4/merklRoot/merklRoot.repository";
5
5
  import { OpportunityService } from "@/modules/v4/opportunity";
6
- import { NETWORK_LABELS, log, withTimeout } from "@sdk";
6
+ import { NETWORK_LABELS, log } from "@sdk";
7
7
  const main = async () => {
8
8
  try {
9
9
  const chains = await ChainService.getSupportedIds();
10
10
  const promises = [];
11
11
  for (const chain of chains)
12
- promises.push(withTimeout(CacheService.set(TTLPresets.MIN_30, MerklRootRepository.fetch, chain).catch(_err => log.warn(`RPC calls cache update failed for ${NETWORK_LABELS[chain]}.`)), 60_000 // There is no reason for this call to take more than 60 sec
13
- ));
12
+ promises.push(MerklRootRepository.fetch(chain).catch(_err => log.warn(`RPC calls cache update failed for ${NETWORK_LABELS[chain]}.`)));
14
13
  await Promise.allSettled(promises);
15
14
  // ─── Refresh Cache For GET /opportunities ────
16
15
  await CacheService.set(TTLPresets.MIN_5, OpportunityService.findMany, { items: 25, page: 0 });
@@ -1,4 +1,4 @@
1
- import { type ChainId } from "@sdk";
1
+ import { type ChainId, DistributorService } from "@sdk";
2
2
  import type { CreateRootModel, RootByTimestampModel } from "./merklRoot.model";
3
3
  export declare class MerklRootRepository {
4
4
  static firstRoot(chainId: ChainId): Promise<{
@@ -13,13 +13,7 @@ export declare class MerklRootRepository {
13
13
  root: string;
14
14
  epoch: number;
15
15
  }[]>;
16
- static fetch(chainId: ChainId): Promise<{
17
- live: any;
18
- tree: any;
19
- lastTree: any;
20
- endOfDisputePeriod: any;
21
- disputer: any;
22
- }>;
16
+ static fetch(chainId: ChainId): Promise<Partial<Awaited<ReturnType<ReturnType<typeof DistributorService>["fetchUpdateData"]>>>>;
23
17
  static create(x: CreateRootModel): Promise<{
24
18
  chainId: number;
25
19
  timestamp: bigint;
@@ -1,5 +1,6 @@
1
+ import { log } from "@/utils/logger";
1
2
  import { apiDbClient } from "@db";
2
- import { DistributorService } from "@sdk";
3
+ import { DistributorService, NETWORK_LABELS, withTimeout } from "@sdk";
3
4
  export class MerklRootRepository {
4
5
  static async firstRoot(chainId) {
5
6
  return await apiDbClient.merklRoot.findFirst({
@@ -24,8 +25,21 @@ export class MerklRootRepository {
24
25
  return [res[0], res[1]];
25
26
  }
26
27
  static async fetch(chainId) {
27
- const { live, tree, lastTree, endOfDisputePeriod, disputer } = await DistributorService(chainId).fetchUpdateData();
28
- return { live, tree, lastTree, endOfDisputePeriod, disputer };
28
+ const RPC_CALL_TIMEOUT = 4_000;
29
+ try {
30
+ // Try fetching the data using a RPC
31
+ const { live, tree, lastTree, endOfDisputePeriod, disputer } = await withTimeout(DistributorService(chainId).fetchUpdateData(), RPC_CALL_TIMEOUT);
32
+ return { live, tree, lastTree, endOfDisputePeriod, disputer };
33
+ }
34
+ catch (e) {
35
+ // If the error is a timeout, log a warning and return a void object
36
+ if (e.message === `Timed out after ${RPC_CALL_TIMEOUT}ms`) {
37
+ const errorMessage = `fetching Merkle Root for chain ${NETWORK_LABELS[chainId]} timed out`;
38
+ log.warn(errorMessage);
39
+ return {};
40
+ }
41
+ throw e;
42
+ }
29
43
  }
30
44
  static async create(x) {
31
45
  return await apiDbClient.merklRoot.create({
@@ -13,19 +13,7 @@ export declare class MerklRootService {
13
13
  root: string;
14
14
  epoch: number;
15
15
  }[]>;
16
- /**
17
- * Fetch roots for the provided chain
18
- * @param chainId to fetch roots for
19
- * @returns object with live and last tree roots
20
- */
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
- }>;
16
+ static fetchFromCache(chainId: ChainId): Promise<any>;
29
17
  /**
30
18
  * Fetch all roots for the provided chains
31
19
  * @param chainIds to fetch roots for
@@ -1,6 +1,5 @@
1
- import { HttpError } from "@/errors";
2
1
  import { log } from "@/utils/logger";
3
- import { NETWORK_LABELS, withTimeout } from "@sdk";
2
+ import { NETWORK_LABELS } from "@sdk";
4
3
  import { CacheService } from "../cache";
5
4
  import { TTLPresets } from "../cache/cache.model";
6
5
  import { ChainService } from "../chain/chain.service";
@@ -12,36 +11,16 @@ export class MerklRootService {
12
11
  static async rootForTimestamp(x) {
13
12
  return await MerklRootRepository.rootForTimestamp(x);
14
13
  }
15
- /**
16
- * Fetch roots for the provided chain
17
- * @param chainId to fetch roots for
18
- * @returns object with live and last tree roots
19
- */
20
- static async fetch(chainId) {
21
- try {
22
- return await withTimeout(CacheService.wrap(TTLPresets.MIN_1, MerklRootRepository.fetch, chainId), 5_000);
23
- }
24
- catch (e) {
25
- if (e.message === "Timed out after 3000ms") {
26
- const errorMessage = `fetching Merkle Root for chain ${NETWORK_LABELS[chainId]} timed out`;
27
- log.warn(errorMessage);
28
- throw new Error(errorMessage);
29
- }
30
- throw e;
31
- }
32
- }
33
14
  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 ${NETWORK_LABELS[chainId]}.`, 500);
43
- return await MerklRootRepository.fetch(chainId);
15
+ let data = await CacheService.get(MerklRootRepository.fetch, [chainId]);
16
+ // If the data is null, it means the cache is empty
17
+ if (data === null) {
18
+ log.info(`cache is empty for Merkle Root on ${NETWORK_LABELS[chainId]}, using rpc...`);
19
+ data = await CacheService.wrap(TTLPresets.MIN_1, MerklRootRepository.fetch, chainId);
44
20
  }
21
+ if (data.lastTree === undefined)
22
+ throw `fetching Merkle Root on ${NETWORK_LABELS[chainId]} timed out`;
23
+ return data;
45
24
  }
46
25
  /**
47
26
  * Fetch all roots for the provided chains