@merkl/api 0.18.13 → 0.19.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.
Files changed (56) hide show
  1. package/dist/src/backgroundJobs/index.js +0 -4
  2. package/dist/src/cache/index.d.ts +9 -0
  3. package/dist/src/cache/index.js +12 -3
  4. package/dist/src/eden/index.d.ts +25 -0
  5. package/dist/src/index.d.ts +5 -0
  6. package/dist/src/jobs/set-dungeon-keeper.js +82 -0
  7. package/dist/src/jobs/update-dynamic-data.d.ts +1 -0
  8. package/dist/src/jobs/update-uniswap-v4-pools.d.ts +1 -0
  9. package/dist/src/jobs/update-uniswap-v4-pools.js +14 -0
  10. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/xU308Processor.d.ts +2 -2
  11. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/xU308Processor.js +9 -9
  12. package/dist/src/libs/staticCampaigns.d.ts +5 -0
  13. package/dist/src/libs/staticCampaigns.js +5 -0
  14. package/dist/src/modules/v4/claims/claims.service.js +1 -2
  15. package/dist/src/modules/v4/enso/enso.service.js +2 -2
  16. package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +5 -0
  17. package/dist/src/modules/v4/opportunity/opportunity.model.d.ts +1 -0
  18. package/dist/src/modules/v4/opportunity/opportunity.model.js +3 -0
  19. package/dist/src/modules/v4/opportunity/opportunity.repository.js +8 -2
  20. package/dist/src/modules/v4/programPayload/programPayload.repository.js +3 -9
  21. package/dist/src/modules/v4/router.d.ts +5 -0
  22. package/dist/src/modules/v4/status/status.service.js +4 -2
  23. package/dist/src/modules/v4/token/token.service.js +10 -1
  24. package/dist/src/modules/v4/uniswapV4/uniswapV4.model.d.ts +9 -0
  25. package/dist/src/modules/v4/uniswapV4/uniswapV4.repository.d.ts +11 -0
  26. package/dist/src/modules/v4/uniswapV4/uniswapV4.repository.js +10 -0
  27. package/dist/src/modules/v4/uniswapV4/uniswapV4.service.d.ts +2 -0
  28. package/dist/src/modules/v4/uniswapV4/uniswapV4.service.js +175 -1
  29. package/dist/src/utils/prices/priceService.js +1 -1
  30. package/dist/src/utils/prices/services/erc4626Service.js +1 -1
  31. package/dist/src/utils/throw.d.ts +18 -1
  32. package/dist/src/utils/throw.js +17 -0
  33. package/dist/tsconfig.package.tsbuildinfo +1 -1
  34. package/package.json +10 -8
  35. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.controller.d.ts +0 -34
  36. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.controller.js +0 -8
  37. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.model.d.ts +0 -0
  38. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.model.js +0 -1
  39. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.repository.d.ts +0 -5
  40. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.repository.js +0 -71
  41. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.service.d.ts +0 -3
  42. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.service.js +0 -15
  43. /package/dist/src/jobs/{etl/dynamic-data.d.ts → dynamic-data.d.ts} +0 -0
  44. /package/dist/src/jobs/{etl/dynamic-data.js → dynamic-data.js} +0 -0
  45. /package/dist/src/jobs/{etl/pendings.d.ts → pendings.d.ts} +0 -0
  46. /package/dist/src/jobs/{etl/pendings.js → pendings.js} +0 -0
  47. /package/dist/src/jobs/{etl/prices.d.ts → prices.d.ts} +0 -0
  48. /package/dist/src/jobs/{etl/prices.js → prices.js} +0 -0
  49. /package/dist/src/jobs/{etl/reward-breakdowns.d.ts → reward-breakdowns.d.ts} +0 -0
  50. /package/dist/src/jobs/{etl/reward-breakdowns.js → reward-breakdowns.js} +0 -0
  51. /package/dist/src/jobs/{etl/rewards.d.ts → rewards.d.ts} +0 -0
  52. /package/dist/src/jobs/{etl/rewards.js → rewards.js} +0 -0
  53. /package/dist/src/jobs/{etl/update-dynamic-data.d.ts → set-dungeon-keeper.d.ts} +0 -0
  54. /package/dist/src/jobs/{etl/update-dynamic-data.js → update-dynamic-data.js} +0 -0
  55. /package/dist/src/jobs/{etl/update-euler-vaults.d.ts → update-euler-vaults.d.ts} +0 -0
  56. /package/dist/src/jobs/{etl/update-euler-vaults.js → update-euler-vaults.js} +0 -0
@@ -137,6 +137,7 @@ export declare const v4: Elysia<"/v4", false, {
137
137
  chainId?: string | undefined;
138
138
  mainProtocolId?: string | undefined;
139
139
  campaigns?: boolean | undefined;
140
+ rewardTokenSymbol?: string | undefined;
140
141
  order?: string | undefined;
141
142
  test?: boolean | undefined;
142
143
  minimumTvl?: number | undefined;
@@ -329,6 +330,7 @@ export declare const v4: Elysia<"/v4", false, {
329
330
  chainId?: string | undefined;
330
331
  mainProtocolId?: string | undefined;
331
332
  campaigns?: boolean | undefined;
333
+ rewardTokenSymbol?: string | undefined;
332
334
  order?: string | undefined;
333
335
  test?: boolean | undefined;
334
336
  minimumTvl?: number | undefined;
@@ -816,6 +818,7 @@ export declare const v4: Elysia<"/v4", false, {
816
818
  chainId?: string | undefined;
817
819
  mainProtocolId?: string | undefined;
818
820
  campaigns?: boolean | undefined;
821
+ rewardTokenSymbol?: string | undefined;
819
822
  order?: string | undefined;
820
823
  test?: boolean | undefined;
821
824
  minimumTvl?: number | undefined;
@@ -855,6 +858,7 @@ export declare const v4: Elysia<"/v4", false, {
855
858
  chainId?: string | undefined;
856
859
  mainProtocolId?: string | undefined;
857
860
  campaigns?: boolean | undefined;
861
+ rewardTokenSymbol?: string | undefined;
858
862
  order?: string | undefined;
859
863
  test?: boolean | undefined;
860
864
  minimumTvl?: number | undefined;
@@ -895,6 +899,7 @@ export declare const v4: Elysia<"/v4", false, {
895
899
  chainId?: string | undefined;
896
900
  mainProtocolId?: string | undefined;
897
901
  campaigns?: boolean | undefined;
902
+ rewardTokenSymbol?: string | undefined;
898
903
  order?: string | undefined;
899
904
  test?: boolean | undefined;
900
905
  minimumTvl?: number | undefined;
@@ -98,8 +98,10 @@ export class StatusService {
98
98
  const res = {};
99
99
  for (const [index, chainIdString] of Object.keys(merklRoots).entries()) {
100
100
  const chainId = Number.parseInt(chainIdString);
101
- const delayedCampaigns = delayedCampaignArray[index].status === "rejected" ? [] : delayedCampaignArray[index].value;
102
- const liveCampaigns = liveCampaignArray[index].status === "rejected" ? 0 : liveCampaignArray[index].value;
101
+ const delayedCampaignResult = delayedCampaignArray[index];
102
+ const liveCampaignResult = liveCampaignArray[index];
103
+ const delayedCampaigns = delayedCampaignResult.status === "rejected" ? [] : delayedCampaignResult.value;
104
+ const liveCampaigns = liveCampaignResult.status === "rejected" ? 0 : liveCampaignResult.value;
103
105
  if (!registry(chainId)?.Merkl?.DistributionCreator || !registry(chainId)?.Merkl?.Distributor) {
104
106
  log.warn(`Missing registry for ${NETWORK_LABELS[chainId]}`);
105
107
  continue;
@@ -76,7 +76,15 @@ export class TokenService {
76
76
  chainId: token.chainId,
77
77
  address: token.address,
78
78
  icon: "",
79
- ...Object.assign({ name: "unknown", decimals: 18, symbol: "UNKNOWN", verified: false, isTest: false, isNative: false }, onchainData),
79
+ ...Object.assign({
80
+ name: "unknown",
81
+ decimals: 18,
82
+ symbol: "UNKNOWN",
83
+ verified: false,
84
+ isTest: false,
85
+ isPoint: false,
86
+ isNative: false,
87
+ }, onchainData),
80
88
  };
81
89
  }
82
90
  static async tryToFillWithCoingeckoIcons() {
@@ -344,6 +352,7 @@ export class TokenService {
344
352
  decimals: token.decimals,
345
353
  icon: token.logoURI,
346
354
  isTest: false,
355
+ isPoint: false,
347
356
  isNative: false,
348
357
  });
349
358
  log.local(`Token created: ${res?.symbol} on ${NETWORK_LABELS[Number.parseInt(chain)]}`);
@@ -1,3 +1,6 @@
1
+ import type { apiDbClient } from "@db";
2
+ import type { Prisma } from "@db/api";
3
+ import type { MerklChainId, UniswapV4PoolType } from "@sdk";
1
4
  export declare const UniswapV4PoolsDto: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TObject<{
2
5
  poolKey: import("@sinclair/typebox").TObject<{
3
6
  currency0: import("@sinclair/typebox").TString;
@@ -12,4 +15,10 @@ export declare const UniswapV4PoolsDto: import("@sinclair/typebox").TRecord<impo
12
15
  symbolCurrency0: import("@sinclair/typebox").TString;
13
16
  symbolCurrency1: import("@sinclair/typebox").TString;
14
17
  }>>;
18
+ export type UniswapV4PoolsReturnType = {
19
+ [chainId in MerklChainId]?: {
20
+ [poolId: string]: UniswapV4PoolType;
21
+ };
22
+ };
15
23
  export type UniswapV4PoolsEntity = typeof UniswapV4PoolsDto.static;
24
+ export type LoggedCreateBody = Prisma.Args<typeof apiDbClient.logged, "createMany">["data"];
@@ -1,2 +1,13 @@
1
+ import type { LoggedCreateBody } from "./uniswapV4.model";
1
2
  export declare abstract class UniswapV4Repository {
3
+ static getStoredPools(): Promise<{
4
+ id: string;
5
+ type: import("@db/api").$Enums.LoggedEntityType;
6
+ address: string | null;
7
+ chainId: number;
8
+ fetchAtBlock: number;
9
+ caughtFromAddress: string;
10
+ entityData: import("database/api/.generated/runtime/library").JsonValue;
11
+ }[]>;
12
+ static createMany(data: LoggedCreateBody): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
2
13
  }
@@ -1,2 +1,12 @@
1
+ import { apiDbClient } from "@db";
2
+ import { LoggedEntityType } from "@db/api";
1
3
  export class UniswapV4Repository {
4
+ static async getStoredPools() {
5
+ return await apiDbClient.logged.findMany({
6
+ where: { type: LoggedEntityType.UNISWAP_V4 },
7
+ });
8
+ }
9
+ static async createMany(data) {
10
+ return await apiDbClient.logged.createMany({ data });
11
+ }
2
12
  }
@@ -1,4 +1,5 @@
1
1
  import { type MerklChainId } from "@sdk";
2
+ import type { UniswapV4PoolsReturnType } from "./uniswapV4.model";
2
3
  export declare const PoolManagerInterface: any;
3
4
  export declare abstract class UniswapV4Service {
4
5
  static getPoolsByChain(chainId: MerklChainId): Promise<{
@@ -17,4 +18,5 @@ export declare abstract class UniswapV4Service {
17
18
  symbolCurrency1: string;
18
19
  };
19
20
  }>;
21
+ static getPools(): Promise<UniswapV4PoolsReturnType>;
20
22
  }
@@ -1,8 +1,11 @@
1
1
  import { safeFetchLogs } from "@/libs/campaigns/utils/fetchLogs";
2
2
  import { batchMulticallCallWithRetry } from "@/utils/generic";
3
+ import { log } from "@/utils/logger";
3
4
  import { providers } from "@/utils/providers";
4
- import { ERC20Interface, UniswapV4PoolManager__factory } from "@sdk";
5
+ import { LoggedEntityType } from "@db/api";
6
+ import { ChainInteractionService, ERC20Interface, NETWORK_LABELS, NULL_ADDRESS, UniswapV4Addresses, UniswapV4PoolManagerInterface, UniswapV4PoolManager__factory, getContractCreationBlock, } from "@sdk";
5
7
  import { utils } from "ethers";
8
+ import { UniswapV4Repository } from "./uniswapV4.repository";
6
9
  export const PoolManagerInterface = UniswapV4PoolManager__factory.createInterface();
7
10
  export class UniswapV4Service {
8
11
  static async getPoolsByChain(chainId) {
@@ -70,4 +73,175 @@ export class UniswapV4Service {
70
73
  }
71
74
  return res;
72
75
  }
76
+ static async getPools() {
77
+ const UNIV4_CHAINIDS = Object.keys(UniswapV4Addresses).map((x) => Number(x));
78
+ const pools = {};
79
+ // 0_ Fetch all euler vaults from database
80
+ const storedPools = await UniswapV4Repository.getStoredPools();
81
+ const res = await Promise.all(UNIV4_CHAINIDS.map(async (chainId) => {
82
+ chainId = chainId;
83
+ const perChainIdRes = {};
84
+ const poolManagerAddress = UniswapV4Addresses[chainId]?.PoolManager ?? NULL_ADDRESS;
85
+ const jsonRPCprovider = providers[chainId];
86
+ try {
87
+ // 1_ Get latest euler vaults from chain
88
+ const storedPoolsPerChain = storedPools.filter(pool => pool.chainId === chainId);
89
+ log.info(`found ${storedPoolsPerChain.length} already stored pools on ${NETWORK_LABELS[chainId]}`);
90
+ let fromBlock;
91
+ if (storedPoolsPerChain.length > 0) {
92
+ fromBlock = Math.max(...storedPoolsPerChain.map(x => x.fetchAtBlock)) + 1;
93
+ }
94
+ else {
95
+ fromBlock = await getContractCreationBlock(poolManagerAddress, jsonRPCprovider);
96
+ }
97
+ const toBlock = await jsonRPCprovider.getBlockNumber();
98
+ const logs = await safeFetchLogs(chainId, // TODO: rm type enforcing
99
+ [UniswapV4PoolManagerInterface.getEventTopic("Initialize")], [poolManagerAddress], fromBlock, toBlock
100
+ // fromBlock + 10_000
101
+ );
102
+ const decodedPools = await Promise.all(logs.map(async (log) => {
103
+ const [id, currency0, currency1, fee, tickSpacing, hooks] = UniswapV4PoolManagerInterface.decodeEventLog("Initialize", log.data, log.topics);
104
+ // Respect typing
105
+ return {
106
+ poolId: id,
107
+ chainId: chainId,
108
+ currency0: currency0,
109
+ currency1: currency1,
110
+ tickSpacing: tickSpacing,
111
+ lpFee: fee,
112
+ hooks: hooks,
113
+ fetchedAtBlock: Number(log.blockNumber),
114
+ };
115
+ }));
116
+ log.local(`fetched ${decodedPools.length} pool(s) on ${NETWORK_LABELS[chainId] ?? "Sepolia"} between blocks ${fromBlock} and ${toBlock}`);
117
+ /** Extra calls batch to get the collateral addresses */
118
+ const resCurrencies = await ChainInteractionService(chainId).fetchState(decodedPools.flatMap(pool => {
119
+ return [
120
+ {
121
+ allowFailure: true,
122
+ callData: ERC20Interface.encodeFunctionData("symbol"),
123
+ target: pool.currency0,
124
+ },
125
+ {
126
+ allowFailure: true,
127
+ callData: ERC20Interface.encodeFunctionData("decimals"),
128
+ target: pool.currency0,
129
+ },
130
+ {
131
+ allowFailure: true,
132
+ callData: ERC20Interface.encodeFunctionData("symbol"),
133
+ target: pool.currency1,
134
+ },
135
+ {
136
+ allowFailure: true,
137
+ callData: ERC20Interface.encodeFunctionData("decimals"),
138
+ target: pool.currency1,
139
+ },
140
+ ].filter(x => x.target !== NULL_ADDRESS);
141
+ }));
142
+ let index = 0;
143
+ for (const pool of decodedPools) {
144
+ let symbolCurrency0 = "UNKNOWN";
145
+ let decimalsCurrency0 = 18;
146
+ if (pool.currency0 !== NULL_ADDRESS) {
147
+ try {
148
+ symbolCurrency0 = ERC20Interface.decodeFunctionResult("symbol", resCurrencies[index].returnData)[0];
149
+ if (symbolCurrency0.includes("/") || symbolCurrency0.includes("\u0000")) {
150
+ symbolCurrency0 = "INVALID";
151
+ }
152
+ decimalsCurrency0 = ERC20Interface.decodeFunctionResult("decimals", resCurrencies[index + 1].returnData)[0];
153
+ }
154
+ catch {
155
+ log.error("getUniswapV4Pools", `issue when fetching symbol / decimals for currency0 ${pool.currency0} of pool ${pool.poolId} on ${NETWORK_LABELS[chainId]}`);
156
+ }
157
+ }
158
+ else {
159
+ symbolCurrency0 = "ETH";
160
+ decimalsCurrency0 = 18;
161
+ index -= 2;
162
+ }
163
+ let symbolCurrency1 = "UNKNOWN";
164
+ let decimalsCurrency1 = 18;
165
+ if (pool.currency1 !== NULL_ADDRESS) {
166
+ try {
167
+ symbolCurrency1 = ERC20Interface.decodeFunctionResult("symbol", resCurrencies[index + 2].returnData)[0];
168
+ if (symbolCurrency1.includes("/") || symbolCurrency1.includes("\u0000")) {
169
+ symbolCurrency1 = "INVALID";
170
+ }
171
+ decimalsCurrency1 = ERC20Interface.decodeFunctionResult("decimals", resCurrencies[index + 3].returnData)[0];
172
+ }
173
+ catch {
174
+ log.error("getUniswapV4Pools", `issue when fetching symbol / decimals for currency1 ${pool.currency1} of pool ${pool.poolId} on ${NETWORK_LABELS[chainId]}`);
175
+ }
176
+ }
177
+ else {
178
+ symbolCurrency1 = "ETH";
179
+ decimalsCurrency1 = 18;
180
+ index -= 2;
181
+ }
182
+ const id = pool.poolId;
183
+ perChainIdRes[id ?? "unknownKey"] = {
184
+ chainId: pool.chainId,
185
+ currency0: pool.currency0,
186
+ currency1: pool.currency1,
187
+ decimalsCurrency0,
188
+ decimalsCurrency1,
189
+ hooks: pool.hooks,
190
+ fetchedAtBlock: pool.fetchedAtBlock,
191
+ lpFee: pool.lpFee,
192
+ poolId: id,
193
+ poolKey: pool.poolKey,
194
+ symbolCurrency0,
195
+ symbolCurrency1,
196
+ tickSpacing: pool.tickSpacing,
197
+ };
198
+ index += 4;
199
+ }
200
+ }
201
+ catch (e) {
202
+ log.error(`issue when fetching UniswapV4 pools on ${NETWORK_LABELS[chainId]}`, e);
203
+ }
204
+ return perChainIdRes;
205
+ }));
206
+ UNIV4_CHAINIDS.forEach((chainId, i) => {
207
+ if (!!res[i])
208
+ pools[chainId] = res[i];
209
+ });
210
+ // Update the API database
211
+ const tableData = Object.values(pools).flatMap(pools => Object.values(pools));
212
+ for (const chainId of UNIV4_CHAINIDS) {
213
+ if (tableData.filter(p => p.chainId === chainId).length > 0) {
214
+ try {
215
+ await UniswapV4Repository.createMany(tableData
216
+ .filter(point => point.chainId === chainId)
217
+ .map(pool => ({
218
+ fetchAtBlock: pool.fetchedAtBlock,
219
+ caughtFromAddress: UniswapV4Addresses[pool.chainId]?.PoolManager ?? NULL_ADDRESS,
220
+ chainId: pool.chainId,
221
+ entityData: pool,
222
+ id: Bun.hash(`${pool.poolId}-${pool.chainId}`).toString(),
223
+ type: LoggedEntityType.UNISWAP_V4,
224
+ })));
225
+ log.info(`✅ successfully saved vaults to API database ('Logged' table) on ${NETWORK_LABELS[chainId]}`);
226
+ }
227
+ catch (e) {
228
+ log.error("getUniswapV4Pools/LoggedTableUpdate", e);
229
+ throw new Error(`Error while saving UniV4 pools to API database ('Logged' table) on ${NETWORK_LABELS[chainId]}`);
230
+ }
231
+ }
232
+ }
233
+ log.info(`✅ successfully fetched ${tableData.length} new pool(s) on UniswapV4`);
234
+ // _ Merge previoulsy stored pools with newly fetched ones
235
+ // TODO optimize this part
236
+ if (storedPools.length > 0) {
237
+ for (const pool of storedPools) {
238
+ const chainId = pool.chainId;
239
+ if (!pools[chainId])
240
+ pools[chainId] = {};
241
+ pools[chainId][pool.entityData.poolId] = pool.entityData;
242
+ }
243
+ }
244
+ log.info("👋 exiting getUniswapV4Pools");
245
+ return pools;
246
+ }
73
247
  }
@@ -26,7 +26,7 @@ export default class PriceService {
26
26
  });
27
27
  };
28
28
  async fetchPrices() {
29
- const tokenPriceSources = await PriceSourceService.findManyPriceSources();
29
+ const tokenPriceSources = await PriceSourceService.findManyPriceSources({});
30
30
  /**
31
31
  * @description Factory pricer's call to get prices from different sources
32
32
  */
@@ -22,7 +22,7 @@ export default class ERC4626Service {
22
22
  return res;
23
23
  });
24
24
  const resolvedPrices = await Promise.all(pricePromises);
25
- return resolvedPrices.flat().filter(price => price !== undefined);
25
+ return resolvedPrices.flat().filter(price => price !== undefined && price !== null);
26
26
  }
27
27
  async priceCalculation(rate, vaultToken) {
28
28
  try {
@@ -1,4 +1,21 @@
1
1
  import { type ChainId } from "@sdk";
2
+ /**
3
+ * Use this function to throw an error if the address is invalid
4
+ * and normalize the address to its checksum version
5
+ *
6
+ * @dev Usage: params.address = throwOnInvalidAddress(params.address);
7
+ */
2
8
  export declare const throwOnInvalidRequiredAddress: (address: string) => string;
3
- export declare const throwOnInvalidAddress: (address: string) => string | undefined;
9
+ /**
10
+ * Use this function to throw an error if the address is invalid
11
+ * and normalize the address to its checksum version
12
+ *
13
+ * Address can be null or undefined
14
+ *
15
+ * @dev Usage: params.address = throwOnInvalidAddress(params.address);
16
+ */
17
+ export declare const throwOnInvalidAddress: (address: string | undefined) => string | undefined;
18
+ /**
19
+ * Use this function to throw an error if the chainId is not supported by Merkl
20
+ */
4
21
  export declare const throwOnUnsupportedChainId: (chainId: ChainId) => void;
@@ -1,6 +1,12 @@
1
1
  import { isSupportedChain } from "@sdk";
2
2
  import { utils } from "ethers";
3
3
  import { InvalidParameter, UnsupportedNetwork } from "./error";
4
+ /**
5
+ * Use this function to throw an error if the address is invalid
6
+ * and normalize the address to its checksum version
7
+ *
8
+ * @dev Usage: params.address = throwOnInvalidAddress(params.address);
9
+ */
4
10
  export const throwOnInvalidRequiredAddress = (address) => {
5
11
  try {
6
12
  if (!address)
@@ -11,6 +17,14 @@ export const throwOnInvalidRequiredAddress = (address) => {
11
17
  throw new InvalidParameter(`Address ${address} is invalid`);
12
18
  }
13
19
  };
20
+ /**
21
+ * Use this function to throw an error if the address is invalid
22
+ * and normalize the address to its checksum version
23
+ *
24
+ * Address can be null or undefined
25
+ *
26
+ * @dev Usage: params.address = throwOnInvalidAddress(params.address);
27
+ */
14
28
  export const throwOnInvalidAddress = (address) => {
15
29
  try {
16
30
  if (!address)
@@ -21,6 +35,9 @@ export const throwOnInvalidAddress = (address) => {
21
35
  throw new InvalidParameter(`Address ${address} is invalid`);
22
36
  }
23
37
  };
38
+ /**
39
+ * Use this function to throw an error if the chainId is not supported by Merkl
40
+ */
24
41
  export const throwOnUnsupportedChainId = (chainId) => {
25
42
  if (chainId && !isSupportedChain(chainId, "merkl"))
26
43
  throw new UnsupportedNetwork(chainId);