Skip to main content
Current Status: Token discovery API is planned for Q1 2025 but not yet available.
  • Service method exists internally (tokenService.getAvailableTokens())
  • Public API endpoint coming soon
Workaround: Reference supported tokens in the dashboard or contact support for the current token list.
This endpoint will allow you to discover available tokens programmatically, avoiding the need to hardcode token IDs or symbols in your application.

Planned Endpoint

GET /api/tokens

List all available tokens with metadata. Status: 🔜 Service exists, public endpoint coming soon Headers:
X-API-Key: rfk_live_xxxxxxxxxxxxx
Query Parameters:
ParameterTypeRequiredDescription
blockchainstringOptionalFilter by blockchain (e.g., “SOLANA”, “ETHEREUM”)
Planned Response:
[
  {
    "id": 3,
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "blockchain": "SOLANA",
    "mintAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "iconUrl": "https://example.com/tokens/usdc.png"
  },
  {
    "id": 5,
    "symbol": "USDT",
    "name": "Tether USD",
    "decimals": 6,
    "blockchain": "SOLANA",
    "mintAddress": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
    "iconUrl": "https://example.com/tokens/usdt.png"
  },
  {
    "id": 7,
    "symbol": "SOL",
    "name": "Solana",
    "decimals": 9,
    "blockchain": "SOLANA",
    "mintAddress": "So11111111111111111111111111111111111111112",
    "iconUrl": "https://example.com/tokens/sol.png"
  }
]

Response Fields

FieldTypeDescription
idnumberInternal token ID (for API calls requiring tokenId)
symbolstringToken symbol (e.g., “USDC”, “USDT”, “SOL”)
namestringFull token name
decimalsnumberNumber of decimal places (6 for USDC, 9 for SOL)
blockchainstringBlockchain name (“SOLANA”, “ETHEREUM”, etc.)
mintAddressstringToken mint/contract address on blockchain
iconUrlstringURL to token icon image (may be null)
All fields are required except iconUrl, which may be null if no icon is available.

Use Cases

Build Token Selector UI

// Fetch all available tokens once
const tokens = await fetch('/api/tokens', {
  headers: { 'X-API-Key': process.env.REBELFI_API_KEY }
}).then(r => r.json());

// Build dropdown/selector
const tokenOptions = tokens.map(token => ({
  value: token.symbol,
  label: `${token.symbol} - ${token.name}`,
  icon: token.iconUrl,
  decimals: token.decimals
}));

// User selects "USDC"
const selectedToken = tokens.find(t => t.symbol === 'USDC');
console.log('Decimals:', selectedToken.decimals); // 6
console.log('Mint:', selectedToken.mintAddress); // EPjF...

Cache Token Metadata

// Fetch tokens once and cache client-side
class TokenCache {
  private tokens: Map<string, Token> = new Map();
  private tokensById: Map<number, Token> = new Map();

  async initialize() {
    const tokens = await fetch('/api/tokens', {
      headers: { 'X-API-Key': process.env.REBELFI_API_KEY }
    }).then(r => r.json());

    tokens.forEach(token => {
      this.tokens.set(token.symbol, token);
      this.tokensById.set(token.id, token);
    });
  }

  getBySymbol(symbol: string) {
    return this.tokens.get(symbol);
  }

  getById(id: number) {
    return this.tokensById.get(id);
  }

  getDecimals(symbol: string) {
    return this.tokens.get(symbol)?.decimals;
  }
}

// Initialize once on app startup
const tokenCache = new TokenCache();
await tokenCache.initialize();

// Use throughout app
const usdcDecimals = tokenCache.getDecimals('USDC'); // 6
const usdcMint = tokenCache.getBySymbol('USDC')?.mintAddress;

Convert Between Base and Decimal Units

// Get token metadata
const usdc = await fetch('/api/tokens', {
  headers: { 'X-API-Key': process.env.REBELFI_API_KEY }
})
  .then(r => r.json())
  .then(tokens => tokens.find(t => t.symbol === 'USDC'));

// Convert decimal to base units
function toBaseUnits(decimalAmount: string, token: Token): string {
  const multiplier = Math.pow(10, token.decimals);
  return (parseFloat(decimalAmount) * multiplier).toString();
}

// Convert base to decimal
function toDecimalAmount(baseAmount: string, token: Token): string {
  const divisor = Math.pow(10, token.decimals);
  return (parseInt(baseAmount) / divisor).toFixed(token.decimals);
}

// Examples
const decimalAmount = "1.5"; // 1.5 USDC
const baseAmount = toBaseUnits(decimalAmount, usdc); // "1500000"

const baseInput = "2500000"; // From API
const decimal = toDecimalAmount(baseInput, usdc); // "2.500000"

Filter by Blockchain

// Get only Solana tokens
const solanaTokens = await fetch('/api/tokens?blockchain=SOLANA', {
  headers: { 'X-API-Key': process.env.REBELFI_API_KEY }
}).then(r => r.json());

console.log('Available Solana tokens:');
solanaTokens.forEach(token => {
  console.log(`  ${token.symbol} (${token.name})`);
});

Validate Token Before Operation

// Before creating an allocation, verify token is supported
async function validateToken(symbol: string): Promise<boolean> {
  const tokens = await fetch('/api/tokens', {
    headers: { 'X-API-Key': process.env.REBELFI_API_KEY }
  }).then(r => r.json());

  const token = tokens.find(t => t.symbol === symbol);

  if (!token) {
    const available = tokens.map(t => t.symbol).join(', ');
    throw new Error(
      `Token '${symbol}' not supported. Available tokens: ${available}`
    );
  }

  return true;
}

// Usage
try {
  await validateToken('USDC'); // OK
  await validateToken('XYZ'); // Throws error
} catch (error) {
  console.error(error.message);
}

Best Practices

Token metadata rarely changes. Fetch once on application startup and cache client-side.
// ✅ CORRECT - Fetch once, cache
const tokenCache = await fetch('/api/tokens').then(r => r.json());

// Use cached data
const usdcDecimals = tokenCache.find(t => t.symbol === 'USDC').decimals;

// ❌ WRONG - Fetching repeatedly
for (const position of positions) {
  const token = await fetch('/api/tokens').then(r => r.json());
  // Slow and wasteful!
}
For better readability, use token symbols in your application logic. Map to IDs only when required by specific API endpoints.
// ✅ CORRECT - Readable
const selectedToken = 'USDC';
const tokenData = tokenCache.get(selectedToken);

// ❌ LESS READABLE - Hardcoded IDs
const selectedTokenId = 3; // What token is this?
Not all tokens may be available on all blockchains. Always check for existence.
const token = tokens.find(t => t.symbol === symbol && t.blockchain === blockchain);

if (!token) {
  console.error(`${symbol} not available on ${blockchain}`);
  // Show user available alternatives
}
While tokens don’t change often, consider refreshing your cache daily or when your app starts.
// Refresh token cache daily
setInterval(async () => {
  await tokenCache.initialize();
  console.log('Token cache refreshed');
}, 24 * 60 * 60 * 1000); // 24 hours

Response Size

The token list is small (typically < 50 tokens) and can be cached aggressively:
  • Average size: ~5-10 KB
  • Typical count: 10-50 tokens
  • Update frequency: Rarely (new tokens added occasionally)
Caching Strategy:
  • Cache-Control: max-age=86400 (24 hours)
  • Store in localStorage/sessionStorage
  • Refresh on app initialization

Why Token Discovery Matters

Before (Without Token API)

// ❌ Hardcoded token data
const USDC_DECIMALS = 6;
const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";

// What if we add a new token?
// What if mint address changes?
// What about different blockchains?

After (With Token API)

// ✅ Dynamic token discovery
const tokens = await fetch('/api/tokens').then(r => r.json());
const usdc = tokens.find(t => t.symbol === 'USDC');

// Always up-to-date
// Works across blockchains
// No hardcoding

Integration with Other APIs

Creating Allocations

// Get token metadata
const tokens = await fetch('/api/tokens').then(r => r.json());
const usdc = tokens.find(t => t.symbol === 'USDC');

// Create allocation using symbol
const response = await fetch('/api/v1/allocations', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    opWalletId: 123,
    amount: "1000.00",
    asset: usdc.symbol  // Use symbol from token API
  })
});

Querying Positions

// Get positions
const positions = await fetch('/api/token-positions/op-wallet/123').then(r => r.json());

// Enrich with token metadata
const enrichedPositions = positions.map(position => {
  const token = tokenCache.get(position.token.symbol);
  return {
    ...position,
    decimals: token.decimals,
    mintAddress: token.mintAddress,
    iconUrl: token.iconUrl
  };
});

Current Workaround

Until the API endpoint is available:

Hardcode Common Tokens

// Temporary: Hardcode known tokens
const SUPPORTED_TOKENS = [
  {
    symbol: 'USDC',
    name: 'USD Coin',
    decimals: 6,
    blockchain: 'SOLANA',
    mintAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
  },
  {
    symbol: 'USDT',
    name: 'Tether USD',
    decimals: 6,
    blockchain: 'SOLANA',
    mintAddress: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'
  },
  {
    symbol: 'SOL',
    name: 'Solana',
    decimals: 9,
    blockchain: 'SOLANA',
    mintAddress: 'So11111111111111111111111111111111111111112'
  }
];

Contact Support

For the current list of supported tokens:
  • Email: support@rebelfi.io
  • Dashboard: View supported tokens in Wallets → Add Wallet → Token dropdown

Timeline

Q1 2025 Roadmap:
  • ✅ Service method implemented (tokenService.getAvailableTokens())
  • 🔜 Public API endpoint
  • 🔜 Blockchain filtering
  • 🔜 Token icon URLs
  • 🔜 API key authentication support
What’s Being Built:
  1. Public /api/tokens endpoint
  2. Blockchain filter parameter
  3. Icon URL support
  4. Cache-friendly headers
  5. API key authentication


Support

Questions about supported tokens or adding new tokens?
  • Email: support@rebelfi.io
  • Discord: Join our community
  • Dashboard: View current token list in the dashboard
  • Custom Tokens: Contact us to discuss adding support for additional tokens