import type { ChainKey, TokensResponse } from '@lifi/sdk'; import { ChainId } from '../types/base.js'; import { ChainType } from '../utils/chainType.js'; import type { Token } from '../types/token.js'; import axios from 'axios'; export const getTonTokens = async (): Promise => { const tonToken = await fetch( 'https://tokens.swap.coffee/api/v1/tokens/1/tokens', ); let tonData = await tonToken.json(); tonData = tonData.map((token: any) => ({ chainId: ChainId.TON, address: token.address, symbol: token.symbol, name: token.name, decimals: token.decimals, priceUSD: token.price_usd, coinKey: token.external_id, logoURI: token.image, isVerified: token.trust_score === 100, })); return tonData; }; export const getMoveTokens = async (): Promise => { const response = await axios .get('https://api.getnimbus.io/swap/sui-coins') .then((res) => res?.data?.data); const moveData = response?.map((token: any) => ({ chainId: ChainId.MOVE, address: token.type, symbol: token.symbol, name: token.name, decimals: token.decimals, priceUSD: token.derivedPriceInUSD, coinKey: token.type, logoURI: token.iconUrl, isVerified: token.isVerified, })); return moveData; }; export const getEclipseTokens = async (): Promise => { const response = await axios .get('https://stats-api-eclipse.mainnet.orca.so/api/tokens?limit=3000') .then((res) => res?.data?.data); const eclipseData = response ?.map((token: any) => ({ chainId: ChainId.ECLIPSE, address: token.address, symbol: token?.metadata?.symbol, name: token?.metadata?.name, decimals: token.decimals, priceUSD: token?.price, coinKey: token.tokenProgram, logoURI: token?.metadata?.image, isVerified: token.trust_score === 1, })) ?.filter((item: any) => item.priceUSD); return eclipseData; }; export type TokensRequest = { chains?: (ChainId | ChainKey)[]; chainTypes?: ChainType[]; }; /** * Get all known tokens. * @param params - The configuration of the requested tokens * @param options - Request options * @returns The tokens that are available on the requested chains */ export const getTokens = async ( params?: TokensRequest, ): Promise => { if (params) { Object.keys(params).forEach( (key) => !params[key as keyof TokensRequest] && delete params[key as keyof TokensRequest], ); } try { let tonTokens: TokensResponse = { tokens: {} }; let moveTokens: TokensResponse = { tokens: {} }; let eclipseTokens: TokensResponse = { tokens: {} }; let otherTokens: TokensResponse = { tokens: {} }; // get TON tokens list if ( params?.chainTypes?.includes(ChainType.TVM) && params?.chains?.includes(ChainId.TON) ) { const tonData = await getTonTokens(); tonTokens = { ...tonTokens, tokens: { ...tonTokens.tokens, // @ts-ignore [ChainId.TON]: tonData, }, }; } // get MOVE tokens list if ( params?.chainTypes?.includes(ChainType.MVM) && params?.chains?.includes(ChainId.MOVE) ) { const moveData = await getMoveTokens(); moveTokens = { ...moveTokens, tokens: { ...moveTokens.tokens, // @ts-ignore [ChainId.MOVE]: moveData, }, }; } // get Eclipse tokens list if ( params?.chainTypes?.includes(ChainType.ECLIPSE) && params?.chains?.includes(ChainId.ECLIPSE) ) { const eclipseData = await getEclipseTokens(); eclipseTokens = { ...eclipseTokens, tokens: { ...eclipseTokens.tokens, // @ts-ignore [ChainId.ECLIPSE]: eclipseData, }, }; } const filteredParams: any = params ? { ...params, chains: params?.chains ?.filter( (chain) => ![ChainId.TON, ChainId.MOVE, ChainId.ECLIPSE].includes( chain as any, ), ) .filter(Boolean), chainTypes: params?.chainTypes ?.filter( (type) => ![ChainType.TVM, ChainType.MVM, ChainType.ECLIPSE].includes( type, ), ) .filter(Boolean), } : {}; if ( filteredParams?.chainTypes?.length !== 0 && filteredParams?.chains?.length !== 0 ) { const response = await fetch( `https://li.quest/v1/tokens?${new URLSearchParams(filteredParams as Record)}`, ); otherTokens = await response.json(); } return { tokens: { ...tonTokens.tokens, ...moveTokens.tokens, ...eclipseTokens.tokens, ...otherTokens.tokens, }, }; } catch (e) { console.error('getTokens error', e); throw new Error('Failed to fetch tokens'); } };