@merkl/api 0.20.99 → 0.20.101

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.
@@ -2,7 +2,6 @@ import { TokenService } from "@/modules/v4/token/token.service";
2
2
  import { decodeCall } from "@/utils/decodeCalls";
3
3
  import { createCall } from "@/utils/encodeCalls";
4
4
  import { generateCardName } from "@/utils/generateCardName";
5
- import { generateIcons } from "@/utils/generateIcons";
6
5
  import { BN2Number } from "@sdk";
7
6
  import { tokenTypeToProtocolAndAction } from "./helpers/tokenType";
8
7
  export var Round;
@@ -186,7 +185,6 @@ export class GenericProcessor {
186
185
  calls: [],
187
186
  typeInfo: {
188
187
  ...outputInfo,
189
- icons: generateIcons(type, typeInfo, campaign),
190
188
  },
191
189
  });
192
190
  }
@@ -195,7 +193,6 @@ export class GenericProcessor {
195
193
  calls: [],
196
194
  typeInfo: {
197
195
  ...outputInfo,
198
- icons: generateIcons(type, typeInfo, campaign),
199
196
  },
200
197
  };
201
198
  }
@@ -54,7 +54,7 @@ export const CampaignTestController = new Elysia({
54
54
  // @dev Starts from the engine db to debug opportunity creation failing and preventing the api db to be filled
55
55
  .post("/metadata", async ({ body }) => {
56
56
  const engineCampaign = CampaignService.createFakeCampaignEngine(body);
57
- return await OpportunityService.createFromCampaign(engineCampaign, false, false);
57
+ return await OpportunityService.createFromCampaign(engineCampaign, false, true);
58
58
  }, {
59
59
  body: CampaignConfigMinimal,
60
60
  })
@@ -69,7 +69,7 @@ export const CampaignTestController = new Elysia({
69
69
  ]);
70
70
  if (!engineCampaigns.length)
71
71
  throw new NotFoundError("CampaignEnum not found in engine db");
72
- return await OpportunityService.createFromCampaign(engineCampaigns[0], false, false);
72
+ return await OpportunityService.createFromCampaign(engineCampaigns[0], false, true);
73
73
  }, {
74
74
  query: CampaignUniqueDto,
75
75
  }));
@@ -78,13 +78,13 @@ export class DynamicDataService {
78
78
  const dailyAmount = isWithinTimespan ? BigInt(record.campaign.amount) / BigInt(dayspan) : BigInt(0);
79
79
  let token;
80
80
  try {
81
- token = await TokenService.findUniqueOrThrow({ address: rewardToken, chainId });
81
+ token = await TokenService.findUniqueOrThrow({ address: rewardToken, chainId: record.campaign.chainId });
82
82
  }
83
83
  catch {
84
- await TokenService.findManyOrCreate([{ address: rewardToken, chainId }]);
85
- token = await TokenService.findUniqueOrThrow({ address: rewardToken, chainId });
84
+ await TokenService.findManyOrCreate([{ address: rewardToken, chainId: record.campaign.chainId }]);
85
+ token = await TokenService.findUniqueOrThrow({ address: rewardToken, chainId: record.campaign.chainId });
86
86
  }
87
- const campaignDailyValue = await TokenService.getValueByTokenId(TokenService.hashId({ address: rewardToken, chainId }), dailyAmount);
87
+ const campaignDailyValue = await TokenService.getValueByTokenId(TokenService.hashId({ address: rewardToken, chainId: record.campaign.chainId }), dailyAmount);
88
88
  dailyRewards.total += campaignDailyValue;
89
89
  if (campaignDailyValue > 0) {
90
90
  dailyRewards.breakdowns.push({
@@ -106,6 +106,8 @@ export class DynamicDataService {
106
106
  else {
107
107
  aprCampaignValue = (campaignDailyValue * 365 * 100) / record.tvl;
108
108
  }
109
+ if (aprCampaignValue === Number.POSITIVE_INFINITY)
110
+ aprCampaignValue = 10_001;
109
111
  if (aprCampaignValue > 0) {
110
112
  apr.cumulated += aprCampaignValue;
111
113
  apr.breakdowns.push({
@@ -116,7 +118,7 @@ export class DynamicDataService {
116
118
  }
117
119
  }
118
120
  catch (_err) {
119
- log.warn(`token ${rewardToken} not found`);
121
+ log.error("failed to calculate daily rewards", _err);
120
122
  }
121
123
  }
122
124
  updates.push({
@@ -5,6 +5,7 @@ import { CampaignService } from "@/modules/v4/campaign";
5
5
  import { CampaignRepository } from "@/modules/v4/campaign/campaign.repository";
6
6
  import { TokenService } from "@/modules/v4/token/token.service";
7
7
  import { UserService } from "@/modules/v4/user/user.service";
8
+ import { log } from "@/utils/logger";
8
9
  import { Status } from "@db/api";
9
10
  import { Campaign as CampaignEnum } from "@sdk";
10
11
  import moment from "moment";
@@ -55,6 +56,8 @@ export class OpportunityService {
55
56
  */
56
57
  static async createFromCampaign(campaign, upsert = false, dryRun = false) {
57
58
  const campaignType = CampaignService.getTypeFromV3(campaign.type);
59
+ if (dryRun)
60
+ log.info(`opportunity creation dry run for ${campaign.campaignId} of type ${campaignType}`);
58
61
  const metadata = await OpportunityService.#getMetadata(campaign);
59
62
  const tags = [...((await UserService.findUnique(campaign.creator))?.tags ?? []), ...(campaign?.tags ?? [])];
60
63
  const opportunityId = OpportunityService.hashId({
@@ -8,7 +8,7 @@ import { log } from "@/utils/logger";
8
8
  import { throwOnInvalidRequiredAddress, throwOnUnsupportedChainId } from "@/utils/throw";
9
9
  import { apiDbClient } from "@db";
10
10
  import { Prisma } from "@db/api";
11
- import { ChainInteractionService, DistributionCreatorService, NETWORK_LABELS, bigIntToNumber, } from "@sdk";
11
+ import { ChainInteractionService, DistributionCreatorService, NETWORK_LABELS, NULL_ADDRESS, bigIntToNumber, } from "@sdk";
12
12
  import { getAddress, parseUnits } from "viem";
13
13
  import { CacheService } from "../cache";
14
14
  import { TTLPresets } from "../cache/cache.model";
@@ -77,7 +77,13 @@ export class TokenService {
77
77
  return TokenService.fetchBalances(chainId, userAddress, allTokens);
78
78
  }
79
79
  static async fetchOnChain(token) {
80
- const onchainData = await TokenRepository.getTokenInfo(token);
80
+ const onchainData = token.address === NULL_ADDRESS
81
+ ? {
82
+ name: `${NETWORK_LABELS[token.chainId]} Native Token`,
83
+ symbol: `${NETWORK_LABELS[token.chainId]} Native Token`,
84
+ decimals: 18,
85
+ }
86
+ : await TokenRepository.getTokenInfo(token);
81
87
  try {
82
88
  // biome-ignore lint/suspicious/noControlCharactersInRegex: <explanation>
83
89
  onchainData.name = Buffer.from(onchainData.name.replace(/\u0000/g, ""), "utf-8").toString("utf-8");
@@ -234,15 +240,18 @@ export class TokenService {
234
240
  return await TokenRepository.findUniqueOrThrow(id);
235
241
  }
236
242
  catch (err) {
237
- if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2025") {
238
- return TokenService.format(await TokenService.fillAndCreate({
239
- ...token,
240
- verified: false,
241
- icon: "",
242
- }));
243
+ try {
244
+ if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2025") {
245
+ return TokenService.format(await TokenService.fillAndCreate({
246
+ ...token,
247
+ verified: false,
248
+ icon: "",
249
+ }));
250
+ }
243
251
  }
252
+ catch { }
253
+ throw new HttpError(`Failed to fetch or create token ${token.address} on chain ${token.chainId}.`);
244
254
  }
245
- throw new HttpError(`Failed to fetch or create token ${token.address} on chain ${token.chainId}.`);
246
255
  }));
247
256
  }
248
257
  static async getValidRewardTokens(chainId) {