coingecko-tokens
Version:
Aggregated list of Token Lists from CoinGecko
78 lines (59 loc) • 2.52 kB
text/typescript
import { ethers as _ethers } from 'ethers';
import { schema, TokenList, TokenInfo } from '@uniswap/token-lists';
import { TokenList as TokenList2 } from './types';
import { ajv } from './ajv';
export const ethers = (globalThis as { ethers?: typeof _ethers })?.ethers || _ethers;
export const tokenListValidator = ajv.compile<TokenList>(schema);
export const tokenValidator = (() => {
const tokenSchema = JSON.parse(JSON.stringify(schema));
delete tokenSchema.type;
delete tokenSchema.properties;
delete tokenSchema.required;
tokenSchema['$id'] = 'Uniswap Token Schema';
tokenSchema['$ref'] = '#/definitions/TokenInfo';
return ajv.compile<TokenInfo>(tokenSchema);
})();
// Rebuild tokenlist in case if remote list is incorrect ( in case of coingecko )
export async function rebuildTokenList(url: string | undefined, tokenList: TokenList) {
const newList = JSON.parse(JSON.stringify(tokenList));
if (newList.tokens.length > 1) {
newList.tokens.length = 1;
}
if (!tokenListValidator(newList)) {
throw new Error(`${url} validation failed: ${JSON.stringify(tokenListValidator.errors, null, 2)}`);
}
(newList as TokenList2).tokens = tokenList.tokens
// Filter out invalid token objects (sometimes happen with coingecko lists)
.filter((token) => {
return tokenValidator(token);
})
// Format token addresses to checksummed format
.map((token) => {
(token as { address: string }).address = ethers.getAddress(token.address);
return token;
});
// Double check list
if (!tokenListValidator(newList)) {
throw new Error(`${url} validation failed: ${JSON.stringify(tokenListValidator.errors, null, 2)}`);
}
return newList as unknown as TokenList;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function getTokenList(url: string, fetchParams?: any): Promise<TokenList> {
const resp = await fetch(url, {
...(fetchParams || {}),
method: 'GET',
signal: fetchParams?.signal || AbortSignal.timeout(60 * 1000),
});
if (!resp.ok) {
throw new Error(resp.statusText);
}
const list = (await resp.json()) as TokenList;
if (fetchParams?.rebuildList) {
return rebuildTokenList(url, list);
}
if (!tokenListValidator(list)) {
throw new Error(`${url} validation failed: ${JSON.stringify(tokenListValidator.errors, null, 2)}`);
}
return list;
}