Skip to main content

suix_getCoinMetadata

Retrieves comprehensive metadata for any coin type on the Sui network, including name, symbol, decimal places, and display information.

Overview​

The suix_getCoinMetadata method is essential for applications that handle multiple coin types on Sui. It provides standardized metadata that enables proper formatting of coin balances, display of coin information in user interfaces, and integration with external systems. This method is crucial for wallets, DEX interfaces, portfolio trackers, and any application that needs to present coin information in a user-friendly format.

Parameters​

ParameterTypeRequiredDescription
coinTypestringYesThe coin type identifier in format: packageId::module::type

Coin Type Format​

The coin type follows the standard Sui format: packageId::module::type

Common examples:

  • SUI: 0x2::sui::SUI
  • USDC: 0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC
  • Custom tokens: 0xpackageId::module::COIN_NAME

Returns​

Returns an object containing comprehensive metadata about the specified coin type.

FieldTypeDescription
decimalsnumberNumber of decimal places for the coin
namestringFull name of the coin
symbolstringTrading symbol of the coin
descriptionstringDescription of the coin
iconUrlstringURL to the coin's icon image (optional)
idstringUnique identifier for the metadata object

Decimal Places​

The decimals field indicates how to format the coin balance:

  • SUI: 9 decimals (1 SUI = 1,000,000,000 MIST)
  • USDC: 6 decimals (1 USDC = 1,000,000 micro-USDC)
  • Custom tokens: Variable, as defined by the token creator

Code Examples​

# Get SUI metadata
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "suix_getCoinMetadata",
"params": [
"0x2::sui::SUI"
],
"id": 1
}'

# Get USDC metadata
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "suix_getCoinMetadata",
"params": [
"0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC"
],
"id": 1
}'

# Get custom token metadata
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "suix_getCoinMetadata",
"params": [
"0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT"
],
"id": 1
}'

Response Example​

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"decimals": 9,
"name": "Sui",
"symbol": "SUI",
"description": "The native token of the Sui blockchain",
"iconUrl": "https://sui.io/assets/sui-icon.png",
"id": "0x2::sui::SUI"
}
}

USDC Example Response​

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"decimals": 6,
"name": "USD Coin",
"symbol": "USDC",
"description": "A fully reserved digital dollar backed by short-term US Treasury bonds",
"iconUrl": "https://www.centre.io/images/usdc/usdc-icon-86x86.png",
"id": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC"
}
}

Common Use Cases​

1. Balance Formatting in Wallets​

async function displayWalletBalances(balances) {
const metadataCache = new CoinMetadataCache(client);

const formattedBalances = await Promise.all(
balances.map(async (balance) => {
const metadata = await metadataCache.getMetadata(balance.coinType);
const amount = Number(balance.totalBalance) / Math.pow(10, metadata.decimals);

return {
symbol: metadata.symbol,
name: metadata.name,
amount: amount.toFixed(4),
icon: metadata.iconUrl,
fiatValue: amount * (await getPriceUSD(balance.coinType)) // External price API
};
})
);

return formattedBalances.sort((a, b) => b.fiatValue - a.fiatValue);
}

2. DEX Interface Token Selection​

async function buildTokenList(supportedCoinTypes) {
const tokens = [];

for (const coinType of supportedCoinTypes) {
try {
const metadata = await getCoinMetadata(coinType);
tokens.push({
address: coinType,
symbol: metadata.symbol,
name: metadata.name,
decimals: metadata.decimals,
logoURI: metadata.iconUrl,
tags: inferTokenTags(metadata) // Custom logic
});
} catch (error) {
console.warn(`Failed to load metadata for ${coinType}:`, error);
}
}

return tokens.sort((a, b) => a.symbol.localeCompare(b.symbol));
}

function inferTokenTags(metadata) {
const tags = [];

if (metadata.symbol === 'SUI') tags.push('native');
if (['USDC', 'USDT', 'DAI'].includes(metadata.symbol)) tags.push('stablecoin');
if (metadata.description?.toLowerCase().includes('test')) tags.push('testnet');

return tags;
}

3. Cross-chain Bridge Interface​

async function prepareBridgeTransaction(fromCoinType, toCoinType, amount) {
const [fromMetadata, toMetadata] = await Promise.all([
getCoinMetadata(fromCoinType),
getCoinMetadata(toCoinType)
]);

// Normalize amounts for comparison
const fromAmount = Number(amount) / Math.pow(10, fromMetadata.decimals);
const expectedToAmount = fromAmount * await getExchangeRate(fromCoinType, toCoinType);
const toAmountRaw = Math.floor(expectedToAmount * Math.pow(10, toMetadata.decimals));

return {
fromToken: {
symbol: fromMetadata.symbol,
amount: fromAmount,
decimals: fromMetadata.decimals
},
toToken: {
symbol: toMetadata.symbol,
expectedAmount: expectedToAmount,
expectedAmountRaw: toAmountRaw.toString(),
decimals: toMetadata.decimals
},
bridgeFee: await calculateBridgeFee(fromCoinType, toCoinType, amount)
};
}

4. Analytics and Reporting​

async function generateTokenReport(coinTypes) {
const metadataList = await Promise.all(
coinTypes.map(async (coinType) => {
try {
return await getCoinMetadata(coinType);
} catch {
return null;
}
})
);

const validMetadata = metadataList.filter(Boolean);

const report = {
totalTokens: validMetadata.length,
byDecimals: {},
bySymbolLength: {},
hasIcons: validMetadata.filter(m => m.iconUrl).length,
commonSymbols: {},
longestName: '',
shortestName: ''
};

validMetadata.forEach(metadata => {
// Group by decimals
report.byDecimals[metadata.decimals] = (report.byDecimals[metadata.decimals] || 0) + 1;

// Group by symbol length
const symbolLen = metadata.symbol.length;
report.bySymbolLength[symbolLen] = (report.bySymbolLength[symbolLen] || 0) + 1;

// Track common symbols
report.commonSymbols[metadata.symbol] = (report.commonSymbols[metadata.symbol] || 0) + 1;

// Track name lengths
if (metadata.name.length > report.longestName.length) {
report.longestName = metadata.name;
}
if (!report.shortestName || metadata.name.length < report.shortestName.length) {
report.shortestName = metadata.name;
}
});

return report;
}

Best Practices​

1. Caching Strategy​

// Implement aggressive caching for metadata as it rarely changes
const metadataCache = new Map();
const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours

async function getCachedMetadata(coinType) {
const cached = metadataCache.get(coinType);

if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.metadata;
}

const metadata = await client.getCoinMetadata({ coinType });

metadataCache.set(coinType, {
metadata,
timestamp: Date.now()
});

return metadata;
}

2. Error Handling​

async function safeFormatBalance(coinType, balance) {
try {
const metadata = await getCoinMetadata(coinType);
const formatted = Number(balance) / Math.pow(10, metadata.decimals);

return {
success: true,
formatted: formatted,
display: `${formatted.toFixed(4)} ${metadata.symbol}`,
metadata: metadata
};
} catch (error) {
// Fallback for unknown tokens
return {
success: false,
formatted: Number(balance),
display: `${balance} UNKNOWN`,
error: error.message
};
}
}

3. Batch Loading​

// Load metadata for multiple tokens efficiently
async function preloadMetadata(coinTypes) {
const batchSize = 10;
const results = [];

for (let i = 0; i < coinTypes.length; i += batchSize) {
const batch = coinTypes.slice(i, i + batchSize);
const batchResults = await Promise.allSettled(
batch.map(coinType => getCoinMetadata(coinType))
);
results.push(...batchResults);

// Small delay to prevent overwhelming the RPC
if (i + batchSize < coinTypes.length) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}

return results;
}

Error Handling​

async function handleMetadataErrors(coinType) {
try {
const metadata = await client.getCoinMetadata({ coinType });
return { success: true, data: metadata };
} catch (error) {
if (error.message.includes('not found')) {
return {
success: false,
error: 'Coin type not found',
fallback: {
symbol: 'UNKNOWN',
name: 'Unknown Token',
decimals: 0
}
};
}

return {
success: false,
error: 'Network error',
retry: true
};
}
}

Notes​

  • Metadata is immutable once set for a coin type
  • Cache aggressively as metadata rarely changes
  • Handle missing metadata gracefully for unknown tokens
  • Use proper decimal precision to avoid floating point errors
  • Icon URLs may be external and should be validated before use

Need help? Contact our support team or check the Sui documentation.