@merkl/api 0.18.6 → 0.18.7
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 +0 -35
- package/dist/src/factories/opportunityMetadata/implementations/Ajna.js +1 -1
- package/dist/src/factories/opportunityMetadata/implementations/Badger.js +1 -1
- package/dist/src/index.d.ts +0 -7
- package/dist/src/modules/v4/campaign/campaign.repository.js +1 -1
- package/dist/src/modules/v4/enso/enso.service.js +5 -5
- package/dist/src/modules/v4/kyberzap/kyberzap.service.js +5 -5
- package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +0 -7
- package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +0 -7
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +0 -28
- package/dist/src/modules/v4/opportunity/opportunity.service.js +1 -1
- package/dist/src/modules/v4/price/price.repository.js +1 -1
- package/dist/src/modules/v4/reward/reward.service.js +1 -1
- package/dist/src/modules/v4/router.d.ts +0 -7
- package/dist/src/modules/v4/token/token.repository.d.ts +2 -0
- package/dist/src/modules/v4/token/token.repository.js +13 -0
- package/dist/src/modules/v4/token/token.service.d.ts +23 -42
- package/dist/src/modules/v4/token/token.service.js +39 -31
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/src/eden/index.d.ts
CHANGED
@@ -616,13 +616,6 @@ declare const eden: {
|
|
616
616
|
price?: number | null | undefined;
|
617
617
|
})[];
|
618
618
|
chain: {
|
619
|
-
Explorer: {
|
620
|
-
id: string;
|
621
|
-
type: import("@db/api").$Enums.ExplorerType;
|
622
|
-
url: string;
|
623
|
-
chainId: number;
|
624
|
-
}[];
|
625
|
-
} & {
|
626
619
|
id: number;
|
627
620
|
name: string;
|
628
621
|
icon: string;
|
@@ -4075,13 +4068,6 @@ declare const eden: {
|
|
4075
4068
|
price?: number | null | undefined;
|
4076
4069
|
})[];
|
4077
4070
|
chain: {
|
4078
|
-
Explorer: {
|
4079
|
-
id: string;
|
4080
|
-
type: import("@db/api").$Enums.ExplorerType;
|
4081
|
-
url: string;
|
4082
|
-
chainId: number;
|
4083
|
-
}[];
|
4084
|
-
} & {
|
4085
4071
|
id: number;
|
4086
4072
|
name: string;
|
4087
4073
|
icon: string;
|
@@ -8000,13 +7986,6 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
8000
7986
|
price?: number | null | undefined;
|
8001
7987
|
})[];
|
8002
7988
|
chain: {
|
8003
|
-
Explorer: {
|
8004
|
-
id: string;
|
8005
|
-
type: import("@db/api").$Enums.ExplorerType;
|
8006
|
-
url: string;
|
8007
|
-
chainId: number;
|
8008
|
-
}[];
|
8009
|
-
} & {
|
8010
7989
|
id: number;
|
8011
7990
|
name: string;
|
8012
7991
|
icon: string;
|
@@ -13291,13 +13270,6 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
13291
13270
|
price?: number | null | undefined;
|
13292
13271
|
})[];
|
13293
13272
|
chain: {
|
13294
|
-
Explorer: {
|
13295
|
-
id: string;
|
13296
|
-
type: import("@db/api").$Enums.ExplorerType;
|
13297
|
-
url: string;
|
13298
|
-
chainId: number;
|
13299
|
-
}[];
|
13300
|
-
} & {
|
13301
13273
|
id: number;
|
13302
13274
|
name: string;
|
13303
13275
|
icon: string;
|
@@ -16750,13 +16722,6 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
|
|
16750
16722
|
price?: number | null | undefined;
|
16751
16723
|
})[];
|
16752
16724
|
chain: {
|
16753
|
-
Explorer: {
|
16754
|
-
id: string;
|
16755
|
-
type: import("@db/api").$Enums.ExplorerType;
|
16756
|
-
url: string;
|
16757
|
-
chainId: number;
|
16758
|
-
}[];
|
16759
|
-
} & {
|
16760
16725
|
id: number;
|
16761
16726
|
name: string;
|
16762
16727
|
icon: string;
|
@@ -3,7 +3,7 @@ import { OpportunityAction } from "@db/api";
|
|
3
3
|
export class AjnaMetadata {
|
4
4
|
async build(computeChainId, params, subType) {
|
5
5
|
try {
|
6
|
-
const [collateral, quote] = await TokenService.
|
6
|
+
const [collateral, quote] = await TokenService.findManyOrCreate([
|
7
7
|
{
|
8
8
|
chainId: computeChainId,
|
9
9
|
address: params.collateralToken,
|
@@ -3,7 +3,7 @@ import { OpportunityAction } from "@db/api";
|
|
3
3
|
export class BadgerMetadata {
|
4
4
|
async build(computeChainId, params) {
|
5
5
|
try {
|
6
|
-
const [token] = await TokenService.
|
6
|
+
const [token] = await TokenService.findManyOrCreate([{ chainId: computeChainId, address: params.targetToken }]);
|
7
7
|
if (!token)
|
8
8
|
throw new Error("Failed to fetch tokens");
|
9
9
|
return {
|
package/dist/src/index.d.ts
CHANGED
@@ -408,13 +408,6 @@ declare const app: Elysia<"", false, {
|
|
408
408
|
price?: number | null | undefined;
|
409
409
|
})[];
|
410
410
|
chain: {
|
411
|
-
Explorer: {
|
412
|
-
id: string;
|
413
|
-
type: import("@db/api").$Enums.ExplorerType;
|
414
|
-
url: string;
|
415
|
-
chainId: number;
|
416
|
-
}[];
|
417
|
-
} & {
|
418
411
|
id: number;
|
419
412
|
name: string;
|
420
413
|
icon: string;
|
@@ -183,7 +183,7 @@ export class CampaignRepository {
|
|
183
183
|
static async upsert(campaign) {
|
184
184
|
const campaignType = CampaignService.getTypeFromV3(campaign.type);
|
185
185
|
try {
|
186
|
-
const [rewardToken] = await TokenService.
|
186
|
+
const [rewardToken] = await TokenService.findManyOrCreate([
|
187
187
|
{ chainId: campaign.chainId, address: campaign.rewardTokenAddress },
|
188
188
|
]);
|
189
189
|
if (!rewardToken) {
|
@@ -51,8 +51,8 @@ export class EnsoService {
|
|
51
51
|
return await Promise.all(route.map(async (r) => {
|
52
52
|
switch (r.action) {
|
53
53
|
case "deposit": {
|
54
|
-
const tokensIn = await TokenService.
|
55
|
-
const [tokenOut] = await TokenService.
|
54
|
+
const tokensIn = await TokenService.findManyOrCreate(r.tokenIn.map(t => ({ address: t, chainId })));
|
55
|
+
const [tokenOut] = await TokenService.findManyOrCreate(r.tokenOut.map(t => ({ address: t, chainId })));
|
56
56
|
return {
|
57
57
|
action: "deposit",
|
58
58
|
tokens: tokensIn.filter(a => !!a),
|
@@ -60,8 +60,8 @@ export class EnsoService {
|
|
60
60
|
};
|
61
61
|
}
|
62
62
|
case "swap": {
|
63
|
-
const [from] = await TokenService.
|
64
|
-
const [to] = await TokenService.
|
63
|
+
const [from] = await TokenService.findManyOrCreate(r.tokenIn.map(t => ({ address: t, chainId })));
|
64
|
+
const [to] = await TokenService.findManyOrCreate(r.tokenOut.map(t => ({ address: t, chainId })));
|
65
65
|
return { action: "swap", from: from, to: to };
|
66
66
|
}
|
67
67
|
}
|
@@ -106,7 +106,7 @@ export class EnsoService {
|
|
106
106
|
amountIn: [fromTokenAmount.toString()],
|
107
107
|
slippage: options.slippage?.toString(),
|
108
108
|
});
|
109
|
-
const [LpToken] = await TokenService.
|
109
|
+
const [LpToken] = await TokenService.findManyOrCreate([{ address: identifier, chainId }]);
|
110
110
|
const depositValue = await TokenService.getValue([{ ...LpToken, amount: BigInt(quote.amountOut) }]);
|
111
111
|
const actions = await EnsoService.getActions(chainId, quote.route, BigInt(quote.amountOut));
|
112
112
|
return { transaction: tx, depositValue: depositValue, actions };
|
@@ -54,7 +54,7 @@ export class KyberZapService {
|
|
54
54
|
const actions = [];
|
55
55
|
const processors = {
|
56
56
|
ACTION_TYPE_PROTOCOL_FEE: async ({ protocolFee: { tokens: zapTokens } }) => {
|
57
|
-
const tokens = await TokenService.
|
57
|
+
const tokens = await TokenService.findManyOrCreate(zapTokens.map(({ address }) => ({ address, chainId })));
|
58
58
|
return [
|
59
59
|
{
|
60
60
|
action: "fee",
|
@@ -65,7 +65,7 @@ export class KyberZapService {
|
|
65
65
|
ACTION_TYPE_AGGREGATOR_SWAP: async ({ aggregatorSwap: { swaps } }) => {
|
66
66
|
const swapActions = [];
|
67
67
|
for (const { tokenIn, tokenOut } of swaps) {
|
68
|
-
const [from, to] = await TokenService.
|
68
|
+
const [from, to] = await TokenService.findManyOrCreate([
|
69
69
|
{ address: tokenIn.address, chainId },
|
70
70
|
{ address: tokenOut.address, chainId },
|
71
71
|
]);
|
@@ -80,7 +80,7 @@ export class KyberZapService {
|
|
80
80
|
ACTION_TYPE_POOL_SWAP: async ({ poolSwap: { swaps } }) => {
|
81
81
|
const swapActions = [];
|
82
82
|
for (const { tokenIn, tokenOut } of swaps) {
|
83
|
-
const [from, to] = await TokenService.
|
83
|
+
const [from, to] = await TokenService.findManyOrCreate([
|
84
84
|
{ address: tokenIn.address, chainId },
|
85
85
|
{ address: tokenOut.address, chainId },
|
86
86
|
]);
|
@@ -93,7 +93,7 @@ export class KyberZapService {
|
|
93
93
|
return swapActions;
|
94
94
|
},
|
95
95
|
ACTION_TYPE_ADD_LIQUIDITY: async ({ addLiquidity: { tokens: zapTokens } }) => {
|
96
|
-
const tokens = await TokenService.
|
96
|
+
const tokens = await TokenService.findManyOrCreate(zapTokens.map(({ address }) => ({ address, chainId })));
|
97
97
|
return [
|
98
98
|
{
|
99
99
|
action: "deposit",
|
@@ -124,7 +124,7 @@ export class KyberZapService {
|
|
124
124
|
chainId,
|
125
125
|
});
|
126
126
|
const actions = await KyberZapService.getActions(chainId, route.zapDetails.actions);
|
127
|
-
const [tokenIn] = await TokenService.
|
127
|
+
const [tokenIn] = await TokenService.findManyOrCreate([{ address: fromTokenAddress, chainId }]);
|
128
128
|
const deposit = actions.findLast(({ action }) => action === "deposit");
|
129
129
|
const tokenInValue = await TokenService.getValue([{ ...tokenIn, amount: fromTokenAmount }]);
|
130
130
|
const depositValue = await TokenService.getValue(deposit.tokens);
|
@@ -263,13 +263,6 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
|
|
263
263
|
price?: number | null | undefined;
|
264
264
|
})[];
|
265
265
|
chain: {
|
266
|
-
Explorer: {
|
267
|
-
id: string;
|
268
|
-
type: import("@db/api").$Enums.ExplorerType;
|
269
|
-
url: string;
|
270
|
-
chainId: number;
|
271
|
-
}[];
|
272
|
-
} & {
|
273
266
|
id: number;
|
274
267
|
name: string;
|
275
268
|
icon: string;
|
@@ -175,13 +175,6 @@ export declare abstract class OpportunityRepository {
|
|
175
175
|
}) | null>;
|
176
176
|
static findUniqueOrThrow(id: string, withTest?: boolean, withCampaigns?: boolean): Promise<{
|
177
177
|
Chain: {
|
178
|
-
Explorer: {
|
179
|
-
id: string;
|
180
|
-
type: import("@db/api").$Enums.ExplorerType;
|
181
|
-
url: string;
|
182
|
-
chainId: number;
|
183
|
-
}[];
|
184
|
-
} & {
|
185
178
|
id: number;
|
186
179
|
name: string;
|
187
180
|
icon: string;
|
@@ -551,13 +551,6 @@ export declare abstract class OpportunityService {
|
|
551
551
|
price?: number | null | undefined;
|
552
552
|
})[];
|
553
553
|
chain: {
|
554
|
-
Explorer: {
|
555
|
-
id: string;
|
556
|
-
type: import("@db/api").$Enums.ExplorerType;
|
557
|
-
url: string;
|
558
|
-
chainId: number;
|
559
|
-
}[];
|
560
|
-
} & {
|
561
554
|
id: number;
|
562
555
|
name: string;
|
563
556
|
icon: string;
|
@@ -723,13 +716,6 @@ export declare abstract class OpportunityService {
|
|
723
716
|
price?: number | null | undefined;
|
724
717
|
})[];
|
725
718
|
chain: {
|
726
|
-
Explorer: {
|
727
|
-
id: string;
|
728
|
-
type: import("@db/api").$Enums.ExplorerType;
|
729
|
-
url: string;
|
730
|
-
chainId: number;
|
731
|
-
}[];
|
732
|
-
} & {
|
733
719
|
id: number;
|
734
720
|
name: string;
|
735
721
|
icon: string;
|
@@ -891,13 +877,6 @@ export declare abstract class OpportunityService {
|
|
891
877
|
price?: number | null | undefined;
|
892
878
|
})[];
|
893
879
|
chain: {
|
894
|
-
Explorer: {
|
895
|
-
id: string;
|
896
|
-
type: import("@db/api").$Enums.ExplorerType;
|
897
|
-
url: string;
|
898
|
-
chainId: number;
|
899
|
-
}[];
|
900
|
-
} & {
|
901
880
|
id: number;
|
902
881
|
name: string;
|
903
882
|
icon: string;
|
@@ -938,13 +917,6 @@ export declare abstract class OpportunityService {
|
|
938
917
|
price?: number | null | undefined;
|
939
918
|
})[];
|
940
919
|
chain: {
|
941
|
-
Explorer: {
|
942
|
-
id: string;
|
943
|
-
type: import("@db/api").$Enums.ExplorerType;
|
944
|
-
url: string;
|
945
|
-
chainId: number;
|
946
|
-
}[];
|
947
|
-
} & {
|
948
920
|
id: number;
|
949
921
|
name: string;
|
950
922
|
icon: string;
|
@@ -69,7 +69,7 @@ export class OpportunityService {
|
|
69
69
|
identifier: campaign.opportunityIdentifier,
|
70
70
|
type: campaignType,
|
71
71
|
});
|
72
|
-
const tokens = (await TokenService.
|
72
|
+
const tokens = (await TokenService.findManyOrCreate(metadata.tokens)).filter(t => t !== undefined);
|
73
73
|
const params = JSON.parse(campaign.params);
|
74
74
|
const now = moment().unix();
|
75
75
|
const opportunity = {
|
@@ -321,7 +321,7 @@ export class RewardService {
|
|
321
321
|
token = await TokenService.findUniqueOrThrow({ address: rewardToken, chainId });
|
322
322
|
}
|
323
323
|
catch {
|
324
|
-
await TokenService.
|
324
|
+
await TokenService.findManyOrCreate([{ address: rewardToken, chainId }]);
|
325
325
|
token = await TokenService.findUniqueOrThrow({ address: rewardToken, chainId });
|
326
326
|
}
|
327
327
|
const campaignDailyValue = await TokenService.getValueByTokenId(tokenToAmount);
|
@@ -278,13 +278,6 @@ export declare const v4: Elysia<"/v4", false, {
|
|
278
278
|
price?: number | null | undefined;
|
279
279
|
})[];
|
280
280
|
chain: {
|
281
|
-
Explorer: {
|
282
|
-
id: string;
|
283
|
-
type: import("@db/api").$Enums.ExplorerType;
|
284
|
-
url: string;
|
285
|
-
chainId: number;
|
286
|
-
}[];
|
287
|
-
} & {
|
288
281
|
id: number;
|
289
282
|
name: string;
|
290
283
|
icon: string;
|
@@ -77,6 +77,8 @@ export declare abstract class TokenRepository {
|
|
77
77
|
* @param chainId
|
78
78
|
*/
|
79
79
|
static updateAddressPrices(address: string, price: number, chainId?: number): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
|
80
|
+
static updateMissingIconsPerSymbol(symbol: string, icon: string): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
|
81
|
+
static fetchIconFromCoingeckoTicker(coingeckoTicker: string): Promise<any>;
|
80
82
|
static findChains(): Promise<Record<string, ChainId>>;
|
81
83
|
/**
|
82
84
|
* create a token on database
|
@@ -2,6 +2,7 @@ import { getTokenInfo } from "@/libs/tokens/tokenInfo";
|
|
2
2
|
import { executeSimple } from "@/utils/execute";
|
3
3
|
import { apiDbClient } from "@/utils/prisma";
|
4
4
|
import { NETWORK_LABELS } from "@sdk";
|
5
|
+
import axios from "axios";
|
5
6
|
export class TokenRepository {
|
6
7
|
static #transformQueryToPrismaFilters(query) {
|
7
8
|
const ids = query.id ? query.id.map(id => ({ id })) : [];
|
@@ -129,6 +130,18 @@ export class TokenRepository {
|
|
129
130
|
},
|
130
131
|
});
|
131
132
|
}
|
133
|
+
static async updateMissingIconsPerSymbol(symbol, icon) {
|
134
|
+
return await apiDbClient.token.updateMany({
|
135
|
+
data: { icon },
|
136
|
+
where: {
|
137
|
+
symbol: symbol,
|
138
|
+
icon: "",
|
139
|
+
},
|
140
|
+
});
|
141
|
+
}
|
142
|
+
static async fetchIconFromCoingeckoTicker(coingeckoTicker) {
|
143
|
+
return (await axios.get(`https://api.coingecko.com/api/v3/coins/${coingeckoTicker}`)).data.image.small;
|
144
|
+
}
|
132
145
|
static async findChains() {
|
133
146
|
const tokens = await apiDbClient.token.findMany({
|
134
147
|
select: { chainId: true, id: true },
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { Pricer } from "@/utils/pricer";
|
2
2
|
import { type ChainId } from "@sdk";
|
3
|
-
import type { NotionWebhookModel } from "./token.model";
|
4
|
-
import type {
|
3
|
+
import type { CreateTokenModel, NotionWebhookModel } from "./token.model";
|
4
|
+
import type { GetTokenQueryModel, Token, TokenModel, TokenUnique, UpdateTokenModel } from "./token.model";
|
5
5
|
import { TokenRepository } from "./token.repository";
|
6
6
|
export declare abstract class TokenService {
|
7
7
|
static hashId(token: TokenUnique): string;
|
@@ -92,44 +92,6 @@ export declare abstract class TokenService {
|
|
92
92
|
* @param excludeAddresses to not update symbols that defined using addresses
|
93
93
|
*/
|
94
94
|
static updatePrices(pricer: Pricer): Promise<void>;
|
95
|
-
/**
|
96
|
-
* Create token on database
|
97
|
-
* @param chainId
|
98
|
-
* @param address
|
99
|
-
*/
|
100
|
-
static create(token: Omit<Token["model"], "id">): Promise<({
|
101
|
-
symbol: string;
|
102
|
-
id: string;
|
103
|
-
name: string | null;
|
104
|
-
icon: string;
|
105
|
-
chainId: number;
|
106
|
-
address: string;
|
107
|
-
decimals: number;
|
108
|
-
verified: boolean;
|
109
|
-
isTest: boolean;
|
110
|
-
isNative: boolean;
|
111
|
-
} & {
|
112
|
-
price?: number | null | undefined;
|
113
|
-
}) | undefined>;
|
114
|
-
/**
|
115
|
-
* Fetches symbol, address, decimals and creates token on database
|
116
|
-
* @param chainId
|
117
|
-
* @param address
|
118
|
-
*/
|
119
|
-
static fillAndCreate(token: CreateTokenModel): Promise<({
|
120
|
-
symbol: string;
|
121
|
-
id: string;
|
122
|
-
name: string | null;
|
123
|
-
icon: string;
|
124
|
-
chainId: number;
|
125
|
-
address: string;
|
126
|
-
decimals: number;
|
127
|
-
verified: boolean;
|
128
|
-
isTest: boolean;
|
129
|
-
isNative: boolean;
|
130
|
-
} & {
|
131
|
-
price?: number | null | undefined;
|
132
|
-
}) | undefined>;
|
133
95
|
/**
|
134
96
|
* Read token from database
|
135
97
|
* @param chainId
|
@@ -206,7 +168,7 @@ export declare abstract class TokenService {
|
|
206
168
|
* @param chainId
|
207
169
|
* @param address
|
208
170
|
*/
|
209
|
-
static
|
171
|
+
static findManyOrCreate(tokens: TokenModel[]): Promise<(Token["model"] | undefined)[]>;
|
210
172
|
static getValidRewardTokens(chainId: number): Promise<{
|
211
173
|
minimumAmountPerHour: any;
|
212
174
|
symbol: string;
|
@@ -251,9 +213,28 @@ export declare abstract class TokenService {
|
|
251
213
|
price: number | null;
|
252
214
|
}>;
|
253
215
|
/**
|
216
|
+
* Fetches symbol, address, decimals and creates token on database
|
217
|
+
* @param chainId
|
218
|
+
* @param address
|
219
|
+
*/
|
220
|
+
static fillAndCreate(token: CreateTokenModel): Promise<({
|
221
|
+
symbol: string;
|
222
|
+
id: string;
|
223
|
+
name: string | null;
|
224
|
+
icon: string;
|
225
|
+
chainId: number;
|
226
|
+
address: string;
|
227
|
+
decimals: number;
|
228
|
+
verified: boolean;
|
229
|
+
isTest: boolean;
|
230
|
+
isNative: boolean;
|
231
|
+
} & {
|
232
|
+
price?: number | null | undefined;
|
233
|
+
}) | undefined>;
|
234
|
+
/**
|
235
|
+
* @deprecated Should be useless now that the token list is not used anymore
|
254
236
|
* Get all tokens from https://github.com/AngleProtocol/angle-token-list and override icons from it
|
255
237
|
* TODO: use the bucket
|
256
|
-
* @deprecated Should be useless now that the token list is not used anymore
|
257
238
|
*/
|
258
239
|
static fillTokenAndIconsFromTokenList(): Promise<void>;
|
259
240
|
}
|
@@ -51,7 +51,7 @@ export class TokenService {
|
|
51
51
|
* Fetches tokens and include balances
|
52
52
|
*/
|
53
53
|
static async fetchTokensAndBalances(chainId, userAddress, addresses) {
|
54
|
-
const tokens = await TokenService.
|
54
|
+
const tokens = await TokenService.findManyOrCreate(addresses?.map(address => ({ chainId, address })));
|
55
55
|
return TokenService.fetchBalances(chainId, userAddress, tokens.filter(t => t !== undefined));
|
56
56
|
}
|
57
57
|
/**
|
@@ -63,7 +63,7 @@ export class TokenService {
|
|
63
63
|
const verifiedTokens = await TokenService.findMany({ chainId: chainId, verified: true });
|
64
64
|
const nativeTokens = await TokenService.findMany({ chainId: chainId, isNative: true });
|
65
65
|
const additionalTokens = !!additionalTokenAddresses?.length
|
66
|
-
? await TokenService.
|
66
|
+
? await TokenService.findManyOrCreate(additionalTokenAddresses?.map(address => ({ chainId, address })))
|
67
67
|
: [];
|
68
68
|
const allTokens = verifiedTokens
|
69
69
|
.concat(additionalTokens.filter(t => t !== undefined))
|
@@ -85,9 +85,26 @@ export class TokenService {
|
|
85
85
|
// 2 - Find tokens with missing logos
|
86
86
|
const missingIcons = await TokenService.findMany({ missingIcons: true });
|
87
87
|
// 3 - Do the intersection of both
|
88
|
-
priceSources = priceSources.filter(p => missingIcons.find(t => t.symbol === p.symbol
|
88
|
+
priceSources = priceSources.filter(p => !!missingIcons.find(t => t.symbol === p.symbol));
|
89
89
|
log.info(`found ${priceSources.length} tokens with missing icons on coingecko.`);
|
90
90
|
// 4 - Loop through each and try to get the icon
|
91
|
+
for (const priceSource of priceSources) {
|
92
|
+
const coingeckoTicker = priceSource.args?.ticker;
|
93
|
+
if (!!coingeckoTicker) {
|
94
|
+
try {
|
95
|
+
const icon = await TokenRepository.fetchIconFromCoingeckoTicker(coingeckoTicker);
|
96
|
+
if (icon.length > 0) {
|
97
|
+
const res = await TokenRepository.updateMissingIconsPerSymbol(priceSource.symbol, icon);
|
98
|
+
log.info(`updated ${res.count} tokens with icon ${icon} ${priceSource.symbol}`);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
catch (e) {
|
102
|
+
console.error(e);
|
103
|
+
}
|
104
|
+
// Avoid rate limits, wait 1 min
|
105
|
+
await new Promise(resolve => setTimeout(resolve, 60_000));
|
106
|
+
}
|
107
|
+
}
|
91
108
|
}
|
92
109
|
static async fetchManyOnChain(chainId, addresses) {
|
93
110
|
const tokens = {};
|
@@ -137,30 +154,6 @@ export class TokenService {
|
|
137
154
|
await TokenService.updateAddressPrices(address, price);
|
138
155
|
}
|
139
156
|
}
|
140
|
-
/**
|
141
|
-
* Create token on database
|
142
|
-
* @param chainId
|
143
|
-
* @param address
|
144
|
-
*/
|
145
|
-
static async create(token) {
|
146
|
-
const id = TokenService.hashId(token);
|
147
|
-
return TokenRepository.upsert({ ...token, id });
|
148
|
-
}
|
149
|
-
/**
|
150
|
-
* Fetches symbol, address, decimals and creates token on database
|
151
|
-
* @param chainId
|
152
|
-
* @param address
|
153
|
-
*/
|
154
|
-
static async fillAndCreate(token) {
|
155
|
-
try {
|
156
|
-
const id = TokenService.hashId(token);
|
157
|
-
const filledData = await TokenService.fetchOnChain({ address: token.address, chainId: token.chainId });
|
158
|
-
return await TokenRepository.upsert({ ...filledData, ...token, id });
|
159
|
-
}
|
160
|
-
catch (e) {
|
161
|
-
console.error(e);
|
162
|
-
}
|
163
|
-
}
|
164
157
|
/**
|
165
158
|
* Read token from database
|
166
159
|
* @param chainId
|
@@ -190,7 +183,7 @@ export class TokenService {
|
|
190
183
|
* @returns the cumulated dollar value of all tokens
|
191
184
|
*/
|
192
185
|
static async getValue(tokenAmounts) {
|
193
|
-
const tokens = await TokenService.
|
186
|
+
const tokens = await TokenService.findManyOrCreate(tokenAmounts.map(({ address, chainId }) => ({ address, chainId })));
|
194
187
|
return tokenAmounts.reduce((sum, { amount, address, chainId }) => {
|
195
188
|
const token = tokens
|
196
189
|
.filter(t => t !== undefined)
|
@@ -228,7 +221,7 @@ export class TokenService {
|
|
228
221
|
* @param chainId
|
229
222
|
* @param address
|
230
223
|
*/
|
231
|
-
static async
|
224
|
+
static async findManyOrCreate(tokens) {
|
232
225
|
return await Promise.all(tokens.map(async (token) => {
|
233
226
|
const id = TokenService.hashId(token);
|
234
227
|
try {
|
@@ -276,7 +269,7 @@ export class TokenService {
|
|
276
269
|
const isVerified = properties.Verified.checkbox;
|
277
270
|
const coingeckoApiId = properties["CoinGecko API ID"].rich_text[0].plain_text;
|
278
271
|
const byteArray = await iconFile.bytes();
|
279
|
-
const [token] = await TokenService.
|
272
|
+
const [token] = await TokenService.findManyOrCreate([
|
280
273
|
{
|
281
274
|
chainId,
|
282
275
|
address,
|
@@ -316,9 +309,24 @@ export class TokenService {
|
|
316
309
|
});
|
317
310
|
}
|
318
311
|
/**
|
312
|
+
* Fetches symbol, address, decimals and creates token on database
|
313
|
+
* @param chainId
|
314
|
+
* @param address
|
315
|
+
*/
|
316
|
+
static async fillAndCreate(token) {
|
317
|
+
try {
|
318
|
+
const id = TokenService.hashId(token);
|
319
|
+
const filledData = await TokenService.fetchOnChain({ address: token.address, chainId: token.chainId });
|
320
|
+
return await TokenRepository.upsert({ ...filledData, ...token, id });
|
321
|
+
}
|
322
|
+
catch (e) {
|
323
|
+
console.error(e);
|
324
|
+
}
|
325
|
+
}
|
326
|
+
/**
|
327
|
+
* @deprecated Should be useless now that the token list is not used anymore
|
319
328
|
* Get all tokens from https://github.com/AngleProtocol/angle-token-list and override icons from it
|
320
329
|
* TODO: use the bucket
|
321
|
-
* @deprecated Should be useless now that the token list is not used anymore
|
322
330
|
*/
|
323
331
|
static async fillTokenAndIconsFromTokenList() {
|
324
332
|
const tokenList = await getTokensListWithCache();
|