The Mina SDK includes a built-in caching layer for chains, tokens, balances, and quotes. This reduces API calls, improves performance, and provides fallback data when the network is unavailable.
const mina = new Mina({ integrator: 'my-app' });// Invalidate all chain datamina.invalidateChainCache();// Invalidate token data (all chains or specific chain)mina.invalidateTokenCache(); // All chainsmina.invalidateTokenCache(1); // Ethereum only// Invalidate balance data (all addresses or specific address)mina.invalidateBalanceCache(); // All addressesmina.invalidateBalanceCache('0x...'); // Specific address// Invalidate quote cachemina.invalidateQuoteCache();
Many SDK responses include an isStale flag that indicates whether the data came from an expired cache (used as a fallback when the API is unavailable).
Copy
// Chains with metadataconst { chains, isStale, cachedAt } = await mina.getChainsWithMetadata();if (isStale) { console.warn('Using stale chain data from', new Date(cachedAt)); // Consider retrying or showing a warning to users}
Chains
Tokens
Balances
Copy
const { chains, isStale, cachedAt } = await mina.getChainsWithMetadata();if (isStale) { // Data is from expired cache (API was unavailable) console.warn('Chain data may be outdated');}
Copy
const { tokens, isStale, cachedAt } = await mina.getTokensWithMetadata(1);if (isStale) { // Token list may be outdated console.warn('Token data may be outdated');}
Copy
const { balance, isStale, cachedAt } = await mina.getBalanceWithMetadata( 1, '0xA0b86...', '0x...');if (isStale) { // Balance may not reflect recent transactions console.warn('Balance data may be outdated');}
When isStale is true, the data may not reflect recent changes. Always inform users when displaying stale data, especially for balance and quote information.
By default, standalone functions use a shared default cache. For isolation (e.g., in server environments with multiple tenants), create separate cache instances:
The Mina client automatically creates its own isolated cache instances. Each new Mina() call has separate caches, preventing cross-contamination between client instances.
Concurrent requests for the same balance are deduplicated:
Copy
// These three calls result in only ONE API requestconst [balance1, balance2, balance3] = await Promise.all([ mina.getBalance(1, '0x...token', '0x...wallet'), mina.getBalance(1, '0x...token', '0x...wallet'), mina.getBalance(1, '0x...token', '0x...wallet'),]);
Rapid balance requests are debounced with a 300ms window (BALANCE_DEBOUNCE_MS) to prevent API flooding:
Copy
// Rapid calls are automatically debouncedfor (let i = 0; i < 10; i++) { mina.getBalance(1, tokenAddress, walletAddress);}// Only a few actual API calls are made
import { Mina } from '@siphoyawe/mina-sdk';const mina = new Mina({ integrator: 'my-app' });async function initializeApp() { // Pre-warm caches in parallel await Promise.all([ mina.getChains(), mina.getChainsByRoutes(), // Chains with routes to HyperEVM ]); console.log('Cache warmed, app ready');}initializeApp();