UNPKG

solana-token-list

Version:

Homebrew Solana Token Registry with Coingecko data

186 lines (158 loc) 4.62 kB
import axios from 'axios'; import tokenlist from '../tokens/solana.tokenlist.json'; export enum ENV { MainnetBeta = 101, Testnet = 102, Devnet = 103, } export interface TokenList { readonly name: string; readonly logoURI: string; readonly tags: { [tag: string]: TagDetails }; readonly timestamp: string; readonly tokens: TokenInfo[]; } export interface TagDetails { readonly name: string; readonly description: string; } export interface TokenExtensions { readonly website?: string; readonly bridgeContract?: string; readonly assetContract?: string; readonly address?: string; readonly explorer?: string; readonly twitter?: string; readonly github?: string; readonly medium?: string; readonly tgann?: string; readonly tggroup?: string; readonly discord?: string; readonly serumV3Usdt?: string; readonly serumV3Usdc?: string; readonly coingeckoId?: string; readonly imageUrl?: string; readonly description?: string; } export interface TokenInfo { readonly chainId: number; readonly address: string; readonly name: string; readonly decimals: number; readonly symbol: string; readonly logoURI?: string; readonly tags?: string[]; readonly extensions?: TokenExtensions; } export type TokenInfoMap = Map<string, TokenInfo>; export const CLUSTER_SLUGS: { [id: string]: ENV } = { 'mainnet-beta': ENV.MainnetBeta, testnet: ENV.Testnet, devnet: ENV.Devnet, }; export class GitHubTokenListResolutionStrategy { repositories = [ 'https://raw.githubusercontent.com/JuanRdBO/solana-token-list/main/src/tokens/solana.tokenlist.json', ]; resolve = () => { return queryJsonFiles(this.repositories); }; } export class CDNTokenListResolutionStrategy { repositories = [ 'https://cdn.jsdelivr.net/gh/JuanRdBO/solana-token-list@latest/src/tokens/solana.tokenlist.json', ]; resolve = () => { return queryJsonFiles(this.repositories); }; } // export class SolanaTokenListResolutionStrategy { // repositories = ["https://token-list.solana.com/solana.tokenlist.json"]; // resolve = () => { // return queryJsonFiles(this.repositories); // }; // } const queryJsonFiles = async (files: string[]) => { const responses: TokenList[] = (await Promise.all( files.map(async (repo) => { try { const config = { headers: { 'Accept-Encoding': '*', }, }; const response = (await axios.get(repo, config))?.data as TokenList; return response; } catch { console.info( `@solana/token-registry: falling back to static repository.` ); return tokenlist; } }) )) as TokenList[]; return responses .map((tokenlist: TokenList) => tokenlist.tokens || []) .reduce((acc, arr) => (acc as TokenInfo[]).concat(arr), []); }; export enum Strategy { GitHub = 'GitHub', Static = 'Static', // Solana = "Solana", CDN = 'CDN', } export class StaticTokenListResolutionStrategy { resolve = () => { // @ts-ignore return tokenlist.tokens || []; }; } export class TokenListProvider { static strategies = { [Strategy.GitHub]: new GitHubTokenListResolutionStrategy(), [Strategy.Static]: new StaticTokenListResolutionStrategy(), // [Strategy.Solana]: new SolanaTokenListResolutionStrategy(), [Strategy.CDN]: new CDNTokenListResolutionStrategy(), }; resolve = async ( strategy: Strategy = Strategy.CDN ): Promise<TokenListContainer> => { return new TokenListContainer( await TokenListProvider.strategies[strategy].resolve() ); }; } export class TokenListContainer { constructor(private tokenList: TokenInfo[]) {} filterByTag = (tag: string) => { return new TokenListContainer( this.tokenList.filter((item) => (item.tags || []).includes(tag)) ); }; filterByChainId = (chainId: number | ENV) => { return new TokenListContainer( this.tokenList.filter((item) => item.chainId === chainId) ); }; excludeByChainId = (chainId: number | ENV) => { return new TokenListContainer( this.tokenList.filter((item) => item.chainId !== chainId) ); }; excludeByTag = (tag: string) => { return new TokenListContainer( this.tokenList.filter((item) => !(item.tags || []).includes(tag)) ); }; filterByClusterSlug = (slug: string) => { if (slug in CLUSTER_SLUGS) { return this.filterByChainId(CLUSTER_SLUGS[slug]); } throw new Error( `Unknown slug: ${slug}, please use one of ${Object.keys(CLUSTER_SLUGS)}` ); }; getList = () => { return this.tokenList; }; }