@merkl/api 0.20.18 → 0.20.20

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.
@@ -39,8 +39,6 @@ async function computeEventBasedPoolTVLFromMostRecentStateSave(chainId, campaign
39
39
  // Bucket service
40
40
  let tvl = 0;
41
41
  try {
42
- if (bucketName === undefined)
43
- console.log("EVENT_BASED:", states);
44
42
  const bucket = new BucketService("merkl-production-states", "merkl-production");
45
43
  const storedStates = JSON.parse(await bucket.pull(fileName));
46
44
  for (const [_, { value, params: _params }] of Object.entries(storedStates)) {
@@ -32,19 +32,17 @@ async function computeUniV4PoolTVLFromMostRecentStateSave(chainId, poolID, price
32
32
  stateSave = mostRecentStateSave.state;
33
33
  blockNumber = mostRecentStateSave?.blockNumber;
34
34
  states = stateSave.states;
35
- // const globalState = stateSave.globalState as { tick: number; liquidity: string };
36
35
  }
37
- catch (e) {
36
+ catch {
38
37
  log.warn(`merklDynamic data - failed to read a recent state of pool ${poolID} on ${NETWORK_LABELS[chainId]}`);
38
+ return { tvl: 0, amount0: 0, amount1: 0, blockNumber: blockNumber ?? 0 };
39
39
  }
40
- const { fileName, bucketName } = states;
40
+ const { fileName } = states;
41
41
  // Bucket service
42
42
  let tvl = 0;
43
43
  let amount0 = 0;
44
44
  let amount1 = 0;
45
45
  try {
46
- if (bucketName === undefined)
47
- console.log("UNIV4", states);
48
46
  const bucket = new BucketService("merkl-production-states", "merkl-production");
49
47
  const storedStates = JSON.parse(await bucket.pull(fileName));
50
48
  for (const [_, { value, params: _params }] of Object.entries(storedStates)) {
@@ -53,8 +51,7 @@ async function computeUniV4PoolTVLFromMostRecentStateSave(chainId, poolID, price
53
51
  }
54
52
  tvl = amount0 * (priceCurrency0 ?? 0) + amount1 * (priceCurrency1 ?? 0);
55
53
  }
56
- catch (e) {
57
- console.log(e);
54
+ catch {
58
55
  log.warn(`merklDynamic data - failed to decode state of pool ${poolID} on ${NETWORK_LABELS[chainId]}`);
59
56
  }
60
57
  return { tvl, amount0, amount1, blockNumber: blockNumber };
@@ -156,7 +156,7 @@ export async function getEulerV2Vaults(chainId) {
156
156
  const aux = EulerEVKInterface.decodeEventLog("EVaultCreated", log.data, log.topics);
157
157
  const name = (await EulerVault__factory.connect(log.address, providers[chainId]).name()).split(" ");
158
158
  const vaultName = (await fetchEulerVaultName(getAddress(log.address), chainId)) ?? name[name.length - 1];
159
- /** Respect the previous typing */
159
+ /** Match previous typing */
160
160
  return {
161
161
  address: log.address.toString(),
162
162
  asset: aux[1].toString(),
@@ -167,8 +167,8 @@ export async function getEulerV2Vaults(chainId) {
167
167
  };
168
168
  }
169
169
  catch {
170
- logger.warn(`issue when fetching data on ${NETWORK_LABELS[chainId]} for vault ${log.address}`);
171
- process.exit(1);
170
+ logger.error(`issue when fetching data on ${NETWORK_LABELS[chainId]} for vault ${log.address}`);
171
+ return {};
172
172
  }
173
173
  }));
174
174
  log.info(`fetched ${decodedVaults.length} vaults(s) on ${NETWORK_LABELS[chainId]} between blocks ${fromBlock} and ${toBlock}`);
@@ -12,9 +12,14 @@ export class MorphoMetadata {
12
12
  { name: `Lend ${morphoParams.symbolBorrowToken} on ${market}`, action: OpportunityAction.LEND },
13
13
  ];
14
14
  const subtype = subtypes[subType];
15
+ const tokens = [{ chainId: computeChainId, address: params.targetToken }];
16
+ if (subType === MorphoSubCampaignType.META) {
17
+ const typedParams = params;
18
+ tokens.push({ chainId: computeChainId, address: typedParams.underlyingToken });
19
+ }
15
20
  return {
16
21
  action: subtype.action,
17
- tokens: [{ chainId: computeChainId, address: params.targetToken }],
22
+ tokens,
18
23
  name: subtype.name,
19
24
  mainProtocol: (computeChainId === ChainId.POLYGON ? "compound" : "morpho"),
20
25
  depositUrl: MorphoMetadata.generateUrl(computeChainId, params, morphoParams, subType),
@@ -1 +1 @@
1
- export declare const main: () => Promise<void>;
1
+ export declare const main: () => Promise<never>;
@@ -233,5 +233,6 @@ export const main = async () => {
233
233
  if (failed === 0) {
234
234
  await file.delete();
235
235
  }
236
+ process.exit(0);
236
237
  };
237
238
  main();
@@ -1,5 +1,6 @@
1
1
  import { Redis } from "@/cache";
2
2
  import { getEulerV2Vaults, updateEulerVaultsCollatInDatabase } from "@/engine/dynamicData/utils/getEulerV2Vaults";
3
+ import { logger } from "@/utils/logger";
3
4
  (async () => {
4
5
  await Redis.safeSet("EulerV2Vaults", await getEulerV2Vaults());
5
6
  try {
@@ -9,5 +10,6 @@ import { getEulerV2Vaults, updateEulerVaultsCollatInDatabase } from "@/engine/dy
9
10
  console.error(e);
10
11
  process.exit(1);
11
12
  }
13
+ logger.info("✅ Euler update exited successfully");
12
14
  process.exit(0);
13
15
  })();
@@ -1,5 +1,4 @@
1
- import type { DynamicDataBuilder } from "@/engine/dynamicData/interface";
2
- import { Campaign, type CampaignParameters, type ChainId } from "@sdk";
1
+ import { Campaign, type CampaignDynamicData, type CampaignParameters, type ChainId } from "@sdk";
3
2
  import { Campaign as CampaignEnum } from "@sdk";
4
3
  export declare class DynamicDataService {
5
4
  static queryERC20DynamicData(chainId: ChainId, tokenAddress: string, decimals?: number): Promise<{
@@ -10,7 +9,7 @@ export declare class DynamicDataService {
10
9
  priceTargetToken: number;
11
10
  type: string;
12
11
  }>;
13
- static getDynamicData(campaigns: CampaignParameters<CampaignEnum>[], type: Campaign, chainId: number): Promise<DynamicDataBuilder<typeof type>[]>;
12
+ static getDynamicData(campaigns: CampaignParameters<CampaignEnum>[], type: Campaign, chainId: number): Promise<CampaignDynamicData<CampaignEnum>[]>;
14
13
  static updateForCampaignType(campaigns: CampaignParameters<CampaignEnum>[], type: Campaign, dryRun?: boolean): Promise<unknown[]>;
15
14
  static updateForCampaigns(campaigns: CampaignParameters<CampaignEnum>[], dryRun?: boolean): Promise<unknown[]>;
16
15
  }
@@ -53,36 +53,34 @@ export class DynamicDataService {
53
53
  };
54
54
  }
55
55
  static async getDynamicData(campaigns, type, chainId) {
56
+ // Base case: empty input
57
+ if (campaigns.length === 0)
58
+ return [];
56
59
  try {
57
- const dynamicData = await dynamicDataBuilderFactory(typeof type === "number" ? type : Campaign[type]).build(chainId, campaigns);
58
- return dynamicData;
60
+ const campaignType = typeof type === "number" ? type : Campaign[type];
61
+ return await dynamicDataBuilderFactory(campaignType).build(chainId, campaigns);
59
62
  }
60
- catch (_err) {
61
- console.log("Failed to get dynamic data");
62
- const firstHalf = campaigns.splice(0, Math.ceil(campaigns.length / 2));
63
- console.log("firstHalf", firstHalf);
64
- const secondHalf = campaigns;
65
- if (firstHalf.length > 1 || secondHalf.length > 1)
66
- return [
67
- ...(await DynamicDataService.getDynamicData(firstHalf, type, chainId)),
68
- ...(await DynamicDataService.getDynamicData(secondHalf, type, chainId)),
69
- ];
70
- if (firstHalf.length <= 1)
71
- console.error(`Failed to get dynamic data for ${firstHalf[0]}`);
72
- if (secondHalf.length <= 1)
73
- console.error(`Failed to get dynamic data for ${secondHalf[0]}`);
74
- return [];
63
+ catch (error) {
64
+ // Base case: single failing campaign
65
+ if (campaigns.length === 1) {
66
+ log.error(`Permanent failure for campaign ${campaigns[0].campaignId}`, error);
67
+ return [];
68
+ }
69
+ // Recursive binary split
70
+ const mid = Math.ceil(campaigns.length / 2);
71
+ const [firstResults, secondResults] = await Promise.all([
72
+ // Process first half with error propagation
73
+ DynamicDataService.getDynamicData(campaigns.slice(0, mid), type, chainId),
74
+ // Process second half with error propagation
75
+ DynamicDataService.getDynamicData(campaigns.slice(mid), type, chainId),
76
+ ]);
77
+ return [...firstResults, ...secondResults];
75
78
  }
76
79
  }
77
80
  static async updateForCampaignType(campaigns, type, dryRun = false) {
78
81
  const chainId = campaigns[0].computeChainId;
79
82
  const dynamicDataArray = [];
80
- const dynamicData = await dynamicDataBuilderFactory(typeof type === "number" ? type : Campaign[type]).build(chainId, campaigns);
81
- // const dynamicData = await DynamicDataService.getDynamicData(
82
- // campaigns,
83
- // typeof type === "number" ? type : Campaign[type as keyof typeof Campaign],
84
- // chainId
85
- // );
83
+ const dynamicData = await DynamicDataService.getDynamicData(campaigns, typeof type === "number" ? type : Campaign[type], chainId);
86
84
  const oppMap = {};
87
85
  for (const data of dynamicData) {
88
86
  if (!!data) {
@@ -123,6 +121,7 @@ export class DynamicDataService {
123
121
  }
124
122
  dynamicDataArray.push(bigintToString({ campaignId: Object.values(entry[1])[0].campaignId, apr, tvl, dailyRewards }));
125
123
  }
124
+ log.info(`[${CampaignEnum[type]}] Updated ${dynamicData.length}/${campaigns.length} campaigns`);
126
125
  return dynamicDataArray;
127
126
  }
128
127
  static async updateForCampaigns(campaigns, dryRun = false) {
@@ -136,7 +135,6 @@ export class DynamicDataService {
136
135
  const dynamicDataArray = [];
137
136
  for (const [campaignType, campaigns] of campaignTypeToCampaigns.entries()) {
138
137
  try {
139
- log.info(`updating dynamic data for ${campaigns.length} campaigns of type ${CampaignEnum[campaignType]}`);
140
138
  try {
141
139
  dynamicDataArray.push(await DynamicDataService.updateForCampaignType(campaigns, campaignType, dryRun));
142
140
  }