@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.
- package/dist/src/eden/index.d.ts +54 -36
- package/dist/src/engine/campaignTVL/factory.d.ts +1 -1
- package/dist/src/engine/campaignTVL/factory.js +9 -3
- package/dist/src/engine/campaignTVL/implementations/Erc20/Erc20SubType.d.ts +2 -0
- package/dist/src/engine/campaignTVL/implementations/Erc20/computeSubTypes.d.ts +2 -3
- package/dist/src/engine/campaignTVL/implementations/Erc20/computeSubTypes.js +117 -0
- package/dist/src/engine/campaignTVL/implementations/Erc20/factory.d.ts +3 -0
- package/dist/src/engine/campaignTVL/implementations/Erc20/factory.js +13 -0
- package/dist/src/engine/campaignTVL/implementations/Erc20/index.d.ts +2 -2
- package/dist/src/engine/campaignTVL/implementations/Erc20/index.js +20 -1
- package/dist/src/engine/dynamicData/implementations/Erc20.d.ts +1 -1
- package/dist/src/engine/dynamicData/implementations/Erc20.js +3 -9
- package/dist/src/engine/dynamicData/implementations/Radiant.js +2 -2
- package/dist/src/engine/erc20SubTypeProcessors/GenericProcessor.d.ts +1 -2
- package/dist/src/engine/erc20SubTypeProcessors/subtypesRound1.d.ts +1 -0
- package/dist/src/engine/erc20SubTypeProcessors/subtypesRound1.js +4 -4
- package/dist/src/engine/erc20SubTypeProcessors/subtypesRound2.d.ts +1 -2
- package/dist/src/engine/opportunityMetadata/factory.js +4 -2
- package/dist/src/engine/opportunityMetadata/implementations/ERCMultiToken.d.ts +14 -2
- package/dist/src/engine/opportunityMetadata/implementations/ERCMultiToken.js +52 -2
- package/dist/src/engine/opportunityMetadata/implementations/JsonAirdrop.d.ts +2 -2
- package/dist/src/index.d.ts +18 -12
- package/dist/src/modules/v4/campaign/campaign.service.d.ts +6 -0
- package/dist/src/modules/v4/campaign/campaign.service.js +9 -0
- package/dist/src/modules/v4/campaign/campaign.test.controller.d.ts +2 -2
- package/dist/src/modules/v4/campaign/campaign.test.controller.js +1 -1
- package/dist/src/modules/v4/computedValue/computedValue.controller.js +2 -1
- package/dist/src/modules/v4/computedValue/computedValue.service.d.ts +1 -1
- package/dist/src/modules/v4/computedValue/computedValue.service.js +5 -10
- package/dist/src/modules/v4/dynamicData/dynamicData.service.js +2 -2
- package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +7 -7
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +3 -3
- package/dist/src/modules/v4/programPayload/programPayload.controller.d.ts +1 -1
- package/dist/src/modules/v4/protocol/protocol.controller.d.ts +2 -2
- package/dist/src/modules/v4/protocol/protocol.model.d.ts +1 -1
- package/dist/src/modules/v4/protocol/protocol.model.js +1 -0
- package/dist/src/modules/v4/router.d.ts +18 -12
- package/dist/src/modules/v4/token/token.controller.d.ts +6 -0
- package/dist/src/modules/v4/token/token.controller.js +1 -1
- package/dist/src/modules/v4/token/token.model.d.ts +3 -0
- package/dist/src/modules/v4/token/token.model.js +3 -0
- package/dist/src/modules/v4/token/token.repository.js +47 -25
- package/dist/src/modules/v4/token/token.service.d.ts +27 -6
- package/dist/src/modules/v4/token/token.service.js +29 -79
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/src/modules/v4/computedValue/index.d.ts +0 -2
- 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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
}
|