Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usemina.co/llms.txt

Use this file to discover all available pages before exploring further.

The Token Service provides functions for fetching and caching token information across supported chains. It uses the LI.FI API with built-in caching (30 minute TTL).

Exports

import {
  getTokens,
  getBridgeableTokens,
  getDestinationTokens,
  getTokenByAddress,
  invalidateTokenCache,
  createTokenCache,
  TokenCache,
  NATIVE_TOKEN_ADDRESS,
  HYPEREVM_USDC,
  HYPEREVM_HYPE,
} from '@mina-bridge/sdk/services/token';

Functions

getTokens(chainId, cache?)

Fetch all available tokens for a specific chain.
async function getTokens(
  chainId: number,
  cache?: TokenCache
): Promise<TokensResponse>
ParameterTypeRequiredDescription
chainIdnumberYesChain ID to fetch tokens for
cacheTokenCacheNoOptional cache instance
Returns: TokensResponse
PropertyTypeDescription
tokensToken[]Array of tokens on the chain
isStalebooleanWhether data is from stale cache
cachedAtnumber | nullTimestamp when data was cached
chainIdnumberChain ID for these tokens
Throws: TokenFetchError if API fails and no cache available. Example:
// Get Ethereum tokens
const response = await getTokens(1);
console.log(`Found ${response.tokens.length} tokens on Ethereum`);

// Find specific tokens
const usdc = response.tokens.find(t => t.symbol === 'USDC');
const weth = response.tokens.find(t => t.symbol === 'WETH');

console.log(`USDC: ${usdc?.address}`);
console.log(`WETH: ${weth?.address}`);

getBridgeableTokens(chainId, toChainId?, cache?)

Get tokens that can be bridged from a specific chain to HyperEVM.
async function getBridgeableTokens(
  chainId: number,
  toChainId?: number,
  cache?: TokenCache
): Promise<Token[]>
ParameterTypeDefaultDescription
chainIdnumber-Source chain ID
toChainIdnumber999Destination chain ID (HyperEVM)
cacheTokenCache-Optional cache instance
Example:
// Get bridgeable tokens from Arbitrum
const tokens = await getBridgeableTokens(42161);

console.log(`${tokens.length} tokens can bridge from Arbitrum to HyperEVM`);

// Common bridgeable tokens
const stablecoins = tokens.filter(t =>
  ['USDC', 'USDT', 'DAI'].includes(t.symbol)
);
console.log('Stablecoins:', stablecoins.map(t => t.symbol));

getDestinationTokens()

Get tokens available on HyperEVM destination.
function getDestinationTokens(): Token[]
Returns: Array containing USDC and HYPE tokens on HyperEVM. Example:
const destTokens = getDestinationTokens();

destTokens.forEach(token => {
  console.log(`${token.symbol}: ${token.address}`);
});
// Output:
// USDC: 0xb88339cb7199b77e23db6e890353e22632ba630f
// HYPE: 0x0000000000000000000000000000000000000000

getTokenByAddress(chainId, tokenAddress, cache?)

Get a specific token by its address.
async function getTokenByAddress(
  chainId: number,
  tokenAddress: string,
  cache?: TokenCache
): Promise<Token | undefined>
ParameterTypeRequiredDescription
chainIdnumberYesChain ID
tokenAddressstringYesToken contract address
cacheTokenCacheNoOptional cache instance
Example:
// Get USDC on Ethereum
const usdc = await getTokenByAddress(
  1,
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
);

if (usdc) {
  console.log(`Found: ${usdc.name}`);      // "USD Coin"
  console.log(`Symbol: ${usdc.symbol}`);   // "USDC"
  console.log(`Decimals: ${usdc.decimals}`); // 6
  console.log(`Price: $${usdc.priceUsd}`);
}

// Get native ETH
import { NATIVE_TOKEN_ADDRESS } from '@mina-bridge/sdk';

const eth = await getTokenByAddress(1, NATIVE_TOKEN_ADDRESS);
console.log(eth?.symbol); // "ETH"

invalidateTokenCache(chainId?, cache?)

Manually invalidate the token cache.
function invalidateTokenCache(
  chainId?: number,
  cache?: TokenCache
): void
ParameterTypeDescription
chainIdnumberOptional chain ID to invalidate (invalidates all if not provided)
cacheTokenCacheOptional cache instance
Example:
// Invalidate all token caches
invalidateTokenCache();

// Invalidate only Ethereum tokens
invalidateTokenCache(1);

// With custom cache
const myCache = createTokenCache();
invalidateTokenCache(42161, myCache);

createTokenCache()

Factory function to create a new cache instance.
function createTokenCache(): TokenCache
Example:
const cache = createTokenCache();

// Use isolated cache
const tokens = await getTokens(1, cache);

Types

TokensResponse

interface TokensResponse {
  /** Array of token data */
  tokens: Token[];
  /** Whether the data is from stale cache */
  isStale: boolean;
  /** Timestamp when data was cached (null if fresh from API) */
  cachedAt: number | null;
  /** Chain ID for these tokens */
  chainId: number;
}

Token

interface Token {
  /** Token contract address (or native token address) */
  address: string;
  /** Token symbol (e.g., "USDC") */
  symbol: string;
  /** Token name (e.g., "USD Coin") */
  name: string;
  /** Token decimals (e.g., 6 for USDC) */
  decimals: number;
  /** URL to token logo image */
  logoUrl: string;
  /** Current USD price (optional) */
  priceUsd?: number;
  /** Chain ID this token is on */
  chainId: number;
}

TokenFetchError

class TokenFetchError extends Error {
  readonly code: 'TOKEN_FETCH_FAILED';
  readonly chainId: number;
  readonly recoveryAction: 'retry';
  readonly cachedAvailable: boolean;
}

Constants

NATIVE_TOKEN_ADDRESS

Address used to represent native tokens (ETH, MATIC, etc.).
const NATIVE_TOKEN_ADDRESS = '0x0000000000000000000000000000000000000000';

HYPEREVM_USDC

Pre-defined USDC token on HyperEVM.
const HYPEREVM_USDC: Token = {
  address: '0xb88339cb7199b77e23db6e890353e22632ba630f',
  symbol: 'USDC',
  name: 'USD Coin',
  decimals: 6,
  logoUrl: 'https://static.debank.com/image/coin/logo_url/usdc/e87790bfe0b3f2ea855dc29069b38818.png',
  chainId: 999,
};

HYPEREVM_HYPE

Pre-defined HYPE native token on HyperEVM.
const HYPEREVM_HYPE: Token = {
  address: '0x0000000000000000000000000000000000000000',
  symbol: 'HYPE',
  name: 'HYPE',
  decimals: 18,
  logoUrl: 'https://app.hyperliquid.xyz/icons/hyperliquid-logo.svg',
  chainId: 999,
};

TokenCache Class

The TokenCache class manages caching for token data with a 30-minute TTL.

Methods

class TokenCache {
  /** Get cached tokens for a chain if not expired */
  getTokens(chainId: number): {
    data: Token[];
    isStale: boolean;
    cachedAt: number;
  } | null;

  /** Store tokens in cache for a chain */
  setTokens(chainId: number, tokens: Token[]): void;

  /** Get cached bridgeable token addresses for a route */
  getBridgeableAddresses(
    fromChainId: number,
    toChainId: number
  ): string[] | null;

  /** Store bridgeable token addresses */
  setBridgeableAddresses(
    fromChainId: number,
    toChainId: number,
    addresses: string[]
  ): void;

  /** Invalidate cache for a specific chain or all chains */
  invalidate(chainId?: number): void;

  /** Check if cached tokens exist for a chain (even if expired) */
  hasCachedTokens(chainId: number): boolean;

  /** Get tokens even if expired (for fallback) */
  getTokensStale(chainId: number): {
    data: Token[];
    cachedAt: number;
  } | null;
}

Example Usage

const cache = createTokenCache();

// First request - fetches from API
const response1 = await getTokens(1, cache);
console.log('Token count:', response1.tokens.length);

// Second request - uses cache
const response2 = await getTokens(1, cache);
console.log('From cache:', response2.cachedAt !== null);

// Invalidate specific chain
cache.invalidate(1);

// Invalidate all
cache.invalidate();

Common Patterns

async function getPopularTokens(chainId: number): Promise<Token[]> {
  const popularSymbols = ['USDC', 'USDT', 'ETH', 'WETH', 'WBTC', 'DAI'];
  const { tokens } = await getTokens(chainId);

  return tokens.filter(token =>
    popularSymbols.includes(token.symbol.toUpperCase())
  );
}

Find Token by Symbol

async function findToken(
  chainId: number,
  symbol: string
): Promise<Token | undefined> {
  const { tokens } = await getTokens(chainId);
  return tokens.find(t =>
    t.symbol.toUpperCase() === symbol.toUpperCase()
  );
}

// Usage
const usdc = await findToken(1, 'USDC');

Get Stablecoins

async function getStablecoins(chainId: number): Promise<Token[]> {
  const stableSymbols = ['USDC', 'USDT', 'DAI', 'BUSD', 'FRAX'];
  const { tokens } = await getTokens(chainId);

  return tokens.filter(token =>
    stableSymbols.includes(token.symbol.toUpperCase())
  );
}