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 :
Parameter Type Required Description
blockchainstring Optional Filter 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
Field Type Description
idnumber Internal token ID (for API calls requiring tokenId) symbolstring Token symbol (e.g., “USDC”, “USDT”, “SOL”) namestring Full token name decimalsnumber Number of decimal places (6 for USDC, 9 for SOL) blockchainstring Blockchain name (“SOLANA”, “ETHEREUM”, etc.) mintAddressstring Token mint/contract address on blockchain iconUrlstring URL 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...
// 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
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?
Handle Missing Tokens Gracefully
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'
}
];
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 :
Public /api/tokens endpoint
Blockchain filter parameter
Icon URL support
Cache-friendly headers
API key authentication
Support
Questions about supported tokens or adding new tokens?