@merkl/api 0.20.102 → 0.20.104

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 (48) hide show
  1. package/dist/src/eden/index.d.ts +54 -36
  2. package/dist/src/engine/campaignTVL/factory.d.ts +1 -1
  3. package/dist/src/engine/campaignTVL/factory.js +9 -3
  4. package/dist/src/engine/campaignTVL/implementations/Erc20/Erc20SubType.d.ts +2 -0
  5. package/dist/src/engine/campaignTVL/implementations/Erc20/computeSubTypes.d.ts +2 -3
  6. package/dist/src/engine/campaignTVL/implementations/Erc20/computeSubTypes.js +117 -0
  7. package/dist/src/engine/campaignTVL/implementations/Erc20/factory.d.ts +3 -0
  8. package/dist/src/engine/campaignTVL/implementations/Erc20/factory.js +13 -0
  9. package/dist/src/engine/campaignTVL/implementations/Erc20/index.d.ts +2 -2
  10. package/dist/src/engine/campaignTVL/implementations/Erc20/index.js +20 -1
  11. package/dist/src/engine/dynamicData/implementations/Erc20.d.ts +1 -1
  12. package/dist/src/engine/dynamicData/implementations/Erc20.js +3 -9
  13. package/dist/src/engine/dynamicData/implementations/Radiant.js +2 -2
  14. package/dist/src/engine/erc20SubTypeProcessors/GenericProcessor.d.ts +1 -2
  15. package/dist/src/engine/erc20SubTypeProcessors/subtypesRound1.d.ts +1 -0
  16. package/dist/src/engine/erc20SubTypeProcessors/subtypesRound1.js +4 -4
  17. package/dist/src/engine/erc20SubTypeProcessors/subtypesRound2.d.ts +1 -2
  18. package/dist/src/engine/opportunityMetadata/factory.js +4 -2
  19. package/dist/src/engine/opportunityMetadata/implementations/ERCMultiToken.d.ts +14 -2
  20. package/dist/src/engine/opportunityMetadata/implementations/ERCMultiToken.js +52 -2
  21. package/dist/src/engine/opportunityMetadata/implementations/JsonAirdrop.d.ts +2 -2
  22. package/dist/src/index.d.ts +18 -12
  23. package/dist/src/modules/v4/campaign/campaign.service.d.ts +6 -0
  24. package/dist/src/modules/v4/campaign/campaign.service.js +9 -0
  25. package/dist/src/modules/v4/campaign/campaign.test.controller.d.ts +2 -2
  26. package/dist/src/modules/v4/campaign/campaign.test.controller.js +1 -1
  27. package/dist/src/modules/v4/computedValue/computedValue.controller.js +2 -1
  28. package/dist/src/modules/v4/computedValue/computedValue.service.d.ts +1 -1
  29. package/dist/src/modules/v4/computedValue/computedValue.service.js +5 -10
  30. package/dist/src/modules/v4/dynamicData/dynamicData.service.js +2 -2
  31. package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +7 -7
  32. package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +3 -3
  33. package/dist/src/modules/v4/programPayload/programPayload.controller.d.ts +1 -1
  34. package/dist/src/modules/v4/protocol/protocol.controller.d.ts +2 -2
  35. package/dist/src/modules/v4/protocol/protocol.model.d.ts +1 -1
  36. package/dist/src/modules/v4/protocol/protocol.model.js +1 -0
  37. package/dist/src/modules/v4/router.d.ts +18 -12
  38. package/dist/src/modules/v4/token/token.controller.d.ts +6 -0
  39. package/dist/src/modules/v4/token/token.controller.js +1 -1
  40. package/dist/src/modules/v4/token/token.model.d.ts +3 -0
  41. package/dist/src/modules/v4/token/token.model.js +3 -0
  42. package/dist/src/modules/v4/token/token.repository.js +47 -25
  43. package/dist/src/modules/v4/token/token.service.d.ts +27 -6
  44. package/dist/src/modules/v4/token/token.service.js +29 -79
  45. package/dist/tsconfig.package.tsbuildinfo +1 -1
  46. package/package.json +1 -1
  47. package/dist/src/modules/v4/computedValue/index.d.ts +0 -2
  48. package/dist/src/modules/v4/computedValue/index.js +0 -2
@@ -4,33 +4,55 @@ import axios from "axios";
4
4
  export class TokenRepository {
5
5
  static #transformQueryToPrismaFilters(query) {
6
6
  const ids = query.id ? query.id.map(id => ({ id })) : [];
7
+ const { page: _page, items: _items } = query;
8
+ const page = _page ? _page : 0;
9
+ const items = _items !== undefined ? _items : 100;
7
10
  return {
11
+ take: items === 0 ? undefined : items,
12
+ skip: page * items,
8
13
  where: {
9
- OR: query.symbol
10
- ? [
11
- { symbol: { equals: query.symbol, mode: "insensitive" } },
12
- { displaySymbol: { equals: query.symbol, mode: "insensitive" } },
13
- ...ids,
14
- ]
15
- : query.displaySymbol
16
- ? [
17
- {
18
- displaySymbol: "",
19
- symbol: { equals: query.displaySymbol, mode: "insensitive" },
20
- },
21
- { displaySymbol: { equals: query.displaySymbol, mode: "insensitive" } },
22
- ...ids,
23
- ]
24
- : ids.length
25
- ? [...ids]
26
- : undefined,
27
- address: query.address ? { equals: query.address, mode: "insensitive" } : undefined,
28
- chainId: query.chainId ? { equals: query.chainId } : undefined,
29
- name: query.name ? { contains: query.name, mode: "insensitive" } : undefined,
30
- verified: query.verified ? { equals: query.verified } : undefined,
31
- isTest: query.test ? { equals: query.test } : undefined,
32
- icon: query.missingIcons ? { equals: "" } : undefined,
33
- price: query.missingPrice ? { equals: null } : undefined,
14
+ AND: [
15
+ {
16
+ OR: query.symbol
17
+ ? [
18
+ { symbol: { equals: query.symbol, mode: "insensitive" } },
19
+ { displaySymbol: { equals: query.symbol, mode: "insensitive" } },
20
+ ...ids,
21
+ ]
22
+ : query.displaySymbol
23
+ ? [
24
+ {
25
+ displaySymbol: "",
26
+ symbol: { equals: query.displaySymbol, mode: "insensitive" },
27
+ },
28
+ { displaySymbol: { equals: query.displaySymbol, mode: "insensitive" } },
29
+ ...ids,
30
+ ]
31
+ : ids.length
32
+ ? [...ids]
33
+ : undefined,
34
+ address: query.address ? { equals: query.address, mode: "insensitive" } : undefined,
35
+ chainId: query.chainId ? { equals: query.chainId } : undefined,
36
+ name: query.name ? { contains: query.name, mode: "insensitive" } : undefined,
37
+ verified: query.verified ? { equals: query.verified } : undefined,
38
+ isTest: query.test ? { equals: query.test } : undefined,
39
+ icon: query.missingIcons ? { equals: "" } : undefined,
40
+ price: query.missingPrice ? { equals: null } : undefined,
41
+ },
42
+ !query.search
43
+ ? {}
44
+ : {
45
+ AND: query.search?.split(" ")?.map((keyword) => ({
46
+ OR: [
47
+ { id: { contains: keyword, mode: "insensitive" } },
48
+ { name: { contains: keyword, mode: "insensitive" } },
49
+ { symbol: { contains: keyword, mode: "insensitive" } },
50
+ { address: { contains: keyword, mode: "insensitive" } },
51
+ { Chain: { name: { contains: keyword, mode: "insensitive" } } },
52
+ ],
53
+ })),
54
+ },
55
+ ],
34
56
  },
35
57
  };
36
58
  }
@@ -114,6 +114,13 @@ export declare abstract class TokenService {
114
114
  } & {
115
115
  price?: number | null | undefined;
116
116
  }>;
117
+ /**
118
+ * Checks if two tokens are the same based on chainId/address combo
119
+ * @param a token
120
+ * @param b token
121
+ * @returns true if both tokens are the same
122
+ */
123
+ static isSame(a: Pick<Token["model"], "chainId" | "address">, b: Pick<Token["model"], "chainId" | "address">): Promise<boolean>;
117
124
  /**
118
125
  * Get the list of tokens satisfying the query
119
126
  * @param query
@@ -134,6 +141,26 @@ export declare abstract class TokenService {
134
141
  } & {
135
142
  price?: number | null | undefined;
136
143
  })[]>;
144
+ /**
145
+ * Get the list of tokens satisfying the query or fetch if chainId and address are provided
146
+ * @param query
147
+ * @returns A list of tokens
148
+ */
149
+ static findManyOrFetch(query: GetTokenQueryModel): Promise<({
150
+ symbol: string;
151
+ id: string;
152
+ name: string | null;
153
+ icon: string;
154
+ address: string;
155
+ chainId: number;
156
+ decimals: number;
157
+ verified: boolean;
158
+ isTest: boolean;
159
+ isPoint: boolean;
160
+ isNative: boolean;
161
+ } & {
162
+ price?: number | null | undefined;
163
+ })[]>;
137
164
  static getPrice(query: GetTokenQueryModel): Promise<number>;
138
165
  static findManyObjectPerAddress(query: GetTokenQueryModel): Promise<Record<string, {
139
166
  symbol: string;
@@ -256,10 +283,4 @@ export declare abstract class TokenService {
256
283
  isNative: boolean;
257
284
  price: number | null;
258
285
  }>;
259
- /**
260
- * @deprecated Should be useless now that the token list is not used anymore
261
- * Get all tokens from https://github.com/AngleProtocol/angle-token-list and override icons from it
262
- * TODO: use the bucket
263
- */
264
- static fillTokenAndIconsFromTokenList(): Promise<void>;
265
286
  }
@@ -1,18 +1,16 @@
1
1
  import { HttpError } from "@/errors";
2
- import { getTokensListWithCache } from "@/libs/getTokensList";
3
2
  import { getOnlyUserBalance } from "@/libs/tokens/balances";
4
3
  import { BucketService } from "@/modules/v4/bucket/bucket.service";
4
+ import { CacheService } from "@/modules/v4/cache";
5
+ import { TTLPresets } from "@/modules/v4/cache/cache.model";
6
+ import { CoingeckoService } from "@/modules/v4/coingecko/coingecko.service";
5
7
  import { IconService } from "@/modules/v4/icon/icon.service";
6
8
  import { PriceService } from "@/modules/v4/price/price.service";
7
9
  import { log } from "@/utils/logger";
8
10
  import { throwOnInvalidRequiredAddress, throwOnUnsupportedChainId } from "@/utils/throw";
9
- import { apiDbClient } from "@db";
10
11
  import { Prisma } from "@db/api";
11
12
  import { ChainInteractionService, DistributionCreatorService, NETWORK_LABELS, NULL_ADDRESS, bigIntToNumber, } from "@sdk";
12
- import { getAddress, parseUnits } from "viem";
13
- import { CacheService } from "../cache";
14
- import { TTLPresets } from "../cache/cache.model";
15
- import { CoingeckoService } from "../coingecko/coingecko.service";
13
+ import { getAddress, isAddress, parseUnits } from "viem";
16
14
  import { TokenRepository } from "./token.repository";
17
15
  export class TokenService {
18
16
  static hashId(token) {
@@ -165,6 +163,15 @@ export class TokenService {
165
163
  const id = typeof token === "string" ? token : TokenService.hashId(token);
166
164
  return await TokenRepository.findUniqueOrThrow(id);
167
165
  }
166
+ /**
167
+ * Checks if two tokens are the same based on chainId/address combo
168
+ * @param a token
169
+ * @param b token
170
+ * @returns true if both tokens are the same
171
+ */
172
+ static async isSame(a, b) {
173
+ return a.chainId === b.chainId && a.address?.toLowerCase() === b.address?.toLowerCase();
174
+ }
168
175
  /**
169
176
  * Get the list of tokens satisfying the query
170
177
  * @param query
@@ -173,6 +180,22 @@ export class TokenService {
173
180
  static async findMany(query) {
174
181
  return (await TokenRepository.findMany(query)).map(TokenService.format);
175
182
  }
183
+ /**
184
+ * Get the list of tokens satisfying the query or fetch if chainId and address are provided
185
+ * @param query
186
+ * @returns A list of tokens
187
+ */
188
+ static async findManyOrFetch(query) {
189
+ const foundTokens = (await TokenRepository.findMany(query)).map(TokenService.format);
190
+ const isTokenAddress = query.chainId && query.search && isAddress(query.search);
191
+ if (isTokenAddress &&
192
+ !foundTokens.some(t => TokenService.isSame(t, { chainId: query.chainId, address: query.search }))) {
193
+ const token = await TokenService.fetchOnChain({ chainId: query.chainId, address: query.search });
194
+ //Assigning a temporary id since token is not in the database
195
+ token && foundTokens.push({ ...token, id: `tmp-${token.chainId}-${token.address}` });
196
+ }
197
+ return foundTokens;
198
+ }
176
199
  static async getPrice(query) {
177
200
  const tokensFound = (await TokenRepository.findMany(query)).map(TokenService.format);
178
201
  if (tokensFound.length === 0) {
@@ -343,77 +366,4 @@ export class TokenService {
343
366
  }
344
367
  return await TokenRepository.upsert({ ...filledData, ...token, id });
345
368
  }
346
- /**
347
- * @deprecated Should be useless now that the token list is not used anymore
348
- * Get all tokens from https://github.com/AngleProtocol/angle-token-list and override icons from it
349
- * TODO: use the bucket
350
- */
351
- static async fillTokenAndIconsFromTokenList() {
352
- const tokenList = await getTokensListWithCache();
353
- for (const chain of Object.keys(tokenList)) {
354
- for (const [symbol, token] of Object.entries(tokenList[chain])) {
355
- if (!(await TokenRepository.findUnique(TokenService.hashId({ chainId: Number.parseInt(chain), address: token.address })))) {
356
- try {
357
- const res = await TokenRepository.create({
358
- id: TokenService.hashId({ chainId: Number.parseInt(chain), address: token.address }),
359
- chainId: Number.parseInt(chain),
360
- address: token.address,
361
- name: token.name,
362
- symbol: token.symbol,
363
- verified: true,
364
- decimals: token.decimals,
365
- icon: token.logoURI,
366
- isTest: false,
367
- isPoint: false,
368
- isNative: false,
369
- });
370
- log.local(`Token created: ${res?.symbol} on ${NETWORK_LABELS[Number.parseInt(chain)]}`);
371
- }
372
- catch (e) {
373
- console.error(e);
374
- }
375
- }
376
- try {
377
- await apiDbClient.token.update({
378
- data: {
379
- chainId: Number.parseInt(chain),
380
- address: token.address,
381
- name: token.name,
382
- symbol: token.symbol,
383
- verified: true,
384
- decimals: token.decimals,
385
- icon: token.logoURI,
386
- },
387
- where: {
388
- chainId_address: {
389
- chainId: Number.parseInt(chain),
390
- address: token.address,
391
- },
392
- },
393
- });
394
- }
395
- catch (e) {
396
- console.error(e);
397
- }
398
- try {
399
- const tokensWithSameSymbol = await apiDbClient.token.findMany({
400
- select: { chainId: true, address: true },
401
- where: { symbol: { equals: symbol, mode: "insensitive" } },
402
- });
403
- for (const dbToken of tokensWithSameSymbol) {
404
- await apiDbClient.token.update({
405
- data: { icon: token.logoURI },
406
- where: {
407
- chainId_address: {
408
- chainId: dbToken.chainId,
409
- address: dbToken.address,
410
- },
411
- },
412
- });
413
- }
414
- }
415
- catch (_err) { }
416
- }
417
- }
418
- }
419
369
  }