suix_getTotalSupply
Returns the total circulating supply of a specified coin type on the Sui network.
Overview​
The suix_getTotalSupply
method provides essential information about the total circulating supply of any coin type on Sui. This method is crucial for tokenomics analysis, market cap calculations, DeFi protocols, analytics platforms, and any application that needs to understand the monetary supply of tokens within the Sui ecosystem.
Parameters​
Parameter | Type | Required | Description |
---|---|---|---|
coinType | string | Yes | The 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 the total supply information for the specified coin type.
Field | Type | Description |
---|---|---|
value | string | Total supply in the smallest unit (raw amount) |
Supply Calculation​
- The returned value represents the total circulating supply
- Values are returned in the smallest unit (e.g., MIST for SUI)
- Use suix_getCoinMetadata to get decimal places for proper formatting
- Supply reflects all minted coins minus any burned coins
Code Examples​
- cURL
- JavaScript
- Python
# Get SUI total supply
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "suix_getTotalSupply",
"params": [
"0x2::sui::SUI"
],
"id": 1
}'
# Get USDC total supply
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "suix_getTotalSupply",
"params": [
"0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC"
],
"id": 1
}'
# Get custom token total supply
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "suix_getTotalSupply",
"params": [
"0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT"
],
"id": 1
}'
import { SuiClient } from '@mysten/sui.js/client';
const client = new SuiClient({
url: 'https://sui-mainnet.dwellir.com/YOUR_API_KEY'
});
// Get total supply for a single coin type
async function getTotalSupply(coinType) {
try {
const supply = await client.getTotalSupply({ coinType });
console.log(`Total supply for ${coinType}:`);
console.log(`Raw value: ${supply.value}`);
return supply;
} catch (error) {
console.error(`Failed to get supply for ${coinType}:`, error);
return null;
}
}
// Get formatted total supply with metadata
async function getFormattedTotalSupply(coinType) {
try {
const [supply, metadata] = await Promise.all([
client.getTotalSupply({ coinType }),
client.getCoinMetadata({ coinType })
]);
const formattedSupply = Number(supply.value) / Math.pow(10, metadata.decimals);
return {
coinType: coinType,
symbol: metadata.symbol,
name: metadata.name,
rawSupply: supply.value,
formattedSupply: formattedSupply,
displaySupply: `${formattedSupply.toLocaleString()} ${metadata.symbol}`,
decimals: metadata.decimals
};
} catch (error) {
console.error(`Failed to get formatted supply for ${coinType}:`, error);
return null;
}
}
// Get supply for multiple coins
async function getMultipleTotalSupplies(coinTypes) {
const supplyPromises = coinTypes.map(async (coinType) => {
try {
const formattedSupply = await getFormattedTotalSupply(coinType);
return { coinType, data: formattedSupply, error: null };
} catch (error) {
return { coinType, data: null, error: error.message };
}
});
const results = await Promise.all(supplyPromises);
return results.reduce((acc, result) => {
acc[result.coinType] = result.data || { error: result.error };
return acc;
}, {});
}
// Supply analytics dashboard
async function createSupplyDashboard(coinTypes) {
const allSupplies = await getMultipleTotalSupplies(coinTypes);
const dashboard = {
totalCoinsAnalyzed: coinTypes.length,
successfulQueries: 0,
failedQueries: 0,
supplyRanking: [],
supplyCategories: {
mega: [], // > 1B tokens
large: [], // 100M - 1B tokens
medium: [], // 1M - 100M tokens
small: [], // < 1M tokens
unknown: [] // Failed to fetch
},
totalMarketSupply: 0 // Sum of all supplies (in SUI equivalent, simplified)
};
for (const [coinType, supplyData] of Object.entries(allSupplies)) {
if (supplyData.error) {
dashboard.failedQueries++;
dashboard.supplyCategories.unknown.push({
coinType,
error: supplyData.error
});
continue;
}
dashboard.successfulQueries++;
const supply = supplyData.formattedSupply;
const supplyInfo = {
coinType: coinType,
symbol: supplyData.symbol,
name: supplyData.name,
supply: supply,
displaySupply: supplyData.displaySupply
};
dashboard.supplyRanking.push(supplyInfo);
// Categorize by supply size
if (supply >= 1_000_000_000) {
dashboard.supplyCategories.mega.push(supplyInfo);
} else if (supply >= 100_000_000) {
dashboard.supplyCategories.large.push(supplyInfo);
} else if (supply >= 1_000_000) {
dashboard.supplyCategories.medium.push(supplyInfo);
} else {
dashboard.supplyCategories.small.push(supplyInfo);
}
// Add to total market supply (simplified calculation)
if (supplyData.symbol === 'SUI') {
dashboard.totalMarketSupply += supply;
}
}
// Sort ranking by supply
dashboard.supplyRanking.sort((a, b) => b.supply - a.supply);
return dashboard;
}
// Market cap calculator (would need price feeds)
async function calculateMarketCaps(coinTypes, priceData = {}) {
const supplies = await getMultipleTotalSupplies(coinTypes);
const marketCaps = [];
for (const [coinType, supplyData] of Object.entries(supplies)) {
if (supplyData.error || !priceData[coinType]) continue;
const marketCap = supplyData.formattedSupply * priceData[coinType].usd;
marketCaps.push({
coinType: coinType,
symbol: supplyData.symbol,
supply: supplyData.formattedSupply,
price: priceData[coinType].usd,
marketCap: marketCap,
displayMarketCap: `$${marketCap.toLocaleString()}`
});
}
return marketCaps.sort((a, b) => b.marketCap - a.marketCap);
}
// Supply change tracker
class SupplyTracker {
constructor(client) {
this.client = client;
this.previousSupplies = new Map();
this.supplyHistory = new Map();
}
async trackSupply(coinType) {
const current = await getTotalSupply(coinType);
if (!current) {
return { error: 'Failed to fetch supply' };
}
const currentSupply = current.value;
const previousSupply = this.previousSupplies.get(coinType);
const change = {
coinType: coinType,
currentSupply: currentSupply,
previousSupply: previousSupply || currentSupply,
absoluteChange: previousSupply ?
(BigInt(currentSupply) - BigInt(previousSupply)).toString() : '0',
timestamp: Date.now()
};
// Calculate percentage change
if (previousSupply && previousSupply !== '0') {
const changePercent =
(Number(change.absoluteChange) / Number(previousSupply)) * 100;
change.percentageChange = changePercent;
}
// Update tracking
this.previousSupplies.set(coinType, currentSupply);
if (!this.supplyHistory.has(coinType)) {
this.supplyHistory.set(coinType, []);
}
const history = this.supplyHistory.get(coinType);
history.push(change);
// Keep only last 100 entries
if (history.length > 100) {
history.shift();
}
return change;
}
async trackMultipleSupplies(coinTypes) {
const results = {};
for (const coinType of coinTypes) {
results[coinType] = await this.trackSupply(coinType);
}
return results;
}
getSupplyHistory(coinType) {
return this.supplyHistory.get(coinType) || [];
}
getSupplyTrend(coinType, periods = 10) {
const history = this.getSupplyHistory(coinType);
if (history.length < 2) {
return { trend: 'insufficient_data' };
}
const recentHistory = history.slice(-periods);
const changes = recentHistory.map(h => Number(h.absoluteChange || 0));
const totalChange = changes.reduce((sum, change) => sum + change, 0);
const avgChange = totalChange / changes.length;
return {
trend: avgChange > 0 ? 'increasing' : avgChange < 0 ? 'decreasing' : 'stable',
averageChange: avgChange,
totalChange: totalChange,
periods: recentHistory.length
};
}
async startMonitoring(coinTypes, intervalMs = 60000) {
console.log(`Starting supply monitoring for ${coinTypes.length} coins`);
const monitor = async () => {
try {
const changes = await this.trackMultipleSupplies(coinTypes);
// Report significant changes
for (const [coinType, change] of Object.entries(changes)) {
if (change.error) continue;
if (change.absoluteChange && change.absoluteChange !== '0') {
console.log(`📊 Supply change for ${coinType}:`);
console.log(` Previous: ${change.previousSupply}`);
console.log(` Current: ${change.currentSupply}`);
console.log(` Change: ${change.absoluteChange}`);
if (change.percentageChange) {
console.log(` Change %: ${change.percentageChange.toFixed(4)}%`);
}
}
}
} catch (error) {
console.error('Error in supply monitoring:', error);
}
};
// Initial check
await monitor();
const intervalId = setInterval(monitor, intervalMs);
return () => {
clearInterval(intervalId);
console.log('Supply monitoring stopped');
};
}
}
// DeFi protocol supply analysis
async function analyzeDeFiProtocolSupply(protocolTokens) {
const supplyAnalysis = {
protocol: 'Unknown Protocol',
totalTokenTypes: protocolTokens.length,
totalSupplyValue: 0,
tokenBreakdown: [],
supplyConcentration: {
dominantToken: null,
concentrationRatio: 0
}
};
const supplies = await getMultipleTotalSupplies(protocolTokens);
for (const [coinType, supplyData] of Object.entries(supplies)) {
if (supplyData.error) continue;
const tokenInfo = {
coinType: coinType,
symbol: supplyData.symbol,
supply: supplyData.formattedSupply,
displaySupply: supplyData.displaySupply,
// Would need price feeds for actual value
estimatedValue: supplyData.formattedSupply // Placeholder
};
supplyAnalysis.tokenBreakdown.push(tokenInfo);
supplyAnalysis.totalSupplyValue += tokenInfo.estimatedValue;
}
// Find dominant token
if (supplyAnalysis.tokenBreakdown.length > 0) {
const sortedTokens = [...supplyAnalysis.tokenBreakdown]
.sort((a, b) => b.estimatedValue - a.estimatedValue);
supplyAnalysis.supplyConcentration.dominantToken = sortedTokens[0];
supplyAnalysis.supplyConcentration.concentrationRatio =
sortedTokens[0].estimatedValue / supplyAnalysis.totalSupplyValue;
}
return supplyAnalysis;
}
// Usage examples
const commonCoinTypes = [
'0x2::sui::SUI',
'0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',
'0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT'
];
// Get SUI supply
const suiSupply = await getTotalSupply('0x2::sui::SUI');
console.log('SUI Total Supply (raw):', suiSupply?.value);
// Get formatted supply with metadata
const formattedSupply = await getFormattedTotalSupply('0x2::sui::SUI');
console.log('SUI Formatted Supply:', formattedSupply?.displaySupply);
// Create supply dashboard
const dashboard = await createSupplyDashboard(commonCoinTypes);
console.log('Supply Dashboard:', dashboard);
// Track supply changes
const tracker = new SupplyTracker(client);
const supplyChange = await tracker.trackSupply('0x2::sui::SUI');
console.log('Supply Change:', supplyChange);
// Monitor supplies
const stopMonitoring = await tracker.startMonitoring(commonCoinTypes, 30000);
// Stop monitoring after 5 minutes
setTimeout(stopMonitoring, 5 * 60 * 1000);
import requests
import json
from typing import Dict, List, Any, Optional, Union
from decimal import Decimal, getcontext
from dataclasses import dataclass, field
import time
from collections import defaultdict
import asyncio
# Set high precision for decimal calculations
getcontext().prec = 50
@dataclass
class SupplyInfo:
coin_type: str
raw_supply: str
formatted_supply: float
symbol: str
name: str
decimals: int
display_supply: str
@dataclass
class SupplyChange:
coin_type: str
current_supply: str
previous_supply: Optional[str]
absolute_change: str
percentage_change: Optional[float]
timestamp: float
class SuiTotalSupplyClient:
def __init__(self, rpc_url: str):
self.rpc_url = rpc_url
self.supply_cache = {}
self.metadata_cache = {}
def get_total_supply(self, coin_type: str) -> Optional[Dict[str, str]]:
"""Get total supply for a specific coin type"""
payload = {
"jsonrpc": "2.0",
"method": "suix_getTotalSupply",
"params": [coin_type],
"id": 1
}
try:
response = requests.post(
self.rpc_url,
headers={'Content-Type': 'application/json'},
data=json.dumps(payload),
timeout=30
)
result = response.json()
if 'error' in result:
print(f"RPC Error for {coin_type}: {result['error']}")
return None
return result['result']
except Exception as e:
print(f"Error fetching supply for {coin_type}: {e}")
return None
def get_coin_metadata(self, coin_type: str) -> Optional[Dict[str, Any]]:
"""Get metadata for a coin type (cached)"""
if coin_type in self.metadata_cache:
return self.metadata_cache[coin_type]
payload = {
"jsonrpc": "2.0",
"method": "suix_getCoinMetadata",
"params": [coin_type],
"id": 1
}
try:
response = requests.post(
self.rpc_url,
headers={'Content-Type': 'application/json'},
data=json.dumps(payload),
timeout=30
)
result = response.json()
if 'error' in result:
return None
metadata = result['result']
self.metadata_cache[coin_type] = metadata
return metadata
except Exception as e:
print(f"Error fetching metadata for {coin_type}: {e}")
return None
def get_formatted_total_supply(self, coin_type: str) -> Optional[SupplyInfo]:
"""Get formatted total supply with metadata"""
supply_data = self.get_total_supply(coin_type)
metadata = self.get_coin_metadata(coin_type)
if not supply_data or not metadata:
return None
raw_supply = supply_data['value']
decimals = metadata['decimals']
# Use Decimal for precise calculations
raw_decimal = Decimal(raw_supply)
divisor = Decimal(10) ** decimals
formatted_supply = float(raw_decimal / divisor)
return SupplyInfo(
coin_type=coin_type,
raw_supply=raw_supply,
formatted_supply=formatted_supply,
symbol=metadata['symbol'],
name=metadata['name'],
decimals=decimals,
display_supply=f"{formatted_supply:,.4f} {metadata['symbol']}"
)
def get_multiple_total_supplies(self, coin_types: List[str]) -> Dict[str, Optional[SupplyInfo]]:
"""Get total supplies for multiple coin types"""
results = {}
for coin_type in coin_types:
results[coin_type] = self.get_formatted_total_supply(coin_type)
return results
def create_supply_dashboard(self, coin_types: List[str]) -> Dict[str, Any]:
"""Create comprehensive supply dashboard"""
all_supplies = self.get_multiple_total_supplies(coin_types)
dashboard = {
'total_coins_analyzed': len(coin_types),
'successful_queries': 0,
'failed_queries': 0,
'supply_ranking': [],
'supply_categories': {
'mega': [], # > 1B tokens
'large': [], # 100M - 1B tokens
'medium': [], # 1M - 100M tokens
'small': [], # < 1M tokens
'unknown': [] # Failed to fetch
},
'statistics': {
'total_combined_supply': 0,
'average_supply': 0,
'median_supply': 0,
'max_supply': 0,
'min_supply': float('inf')
}
}
valid_supplies = []
for coin_type, supply_info in all_supplies.items():
if not supply_info:
dashboard['failed_queries'] += 1
dashboard['supply_categories']['unknown'].append({
'coin_type': coin_type,
'error': 'Failed to fetch supply or metadata'
})
continue
dashboard['successful_queries'] += 1
valid_supplies.append(supply_info.formatted_supply)
supply_entry = {
'coin_type': coin_type,
'symbol': supply_info.symbol,
'name': supply_info.name,
'supply': supply_info.formatted_supply,
'display_supply': supply_info.display_supply,
'raw_supply': supply_info.raw_supply
}
dashboard['supply_ranking'].append(supply_entry)
# Categorize by supply size
supply = supply_info.formatted_supply
if supply >= 1_000_000_000:
dashboard['supply_categories']['mega'].append(supply_entry)
elif supply >= 100_000_000:
dashboard['supply_categories']['large'].append(supply_entry)
elif supply >= 1_000_000:
dashboard['supply_categories']['medium'].append(supply_entry)
else:
dashboard['supply_categories']['small'].append(supply_entry)
# Update statistics
dashboard['statistics']['total_combined_supply'] += supply
dashboard['statistics']['max_supply'] = max(
dashboard['statistics']['max_supply'], supply
)
dashboard['statistics']['min_supply'] = min(
dashboard['statistics']['min_supply'], supply
)
# Sort ranking by supply
dashboard['supply_ranking'].sort(key=lambda x: x['supply'], reverse=True)
# Calculate final statistics
if valid_supplies:
dashboard['statistics']['average_supply'] = (
dashboard['statistics']['total_combined_supply'] / len(valid_supplies)
)
sorted_supplies = sorted(valid_supplies)
mid = len(sorted_supplies) // 2
if len(sorted_supplies) % 2 == 0:
dashboard['statistics']['median_supply'] = (
sorted_supplies[mid-1] + sorted_supplies[mid]
) / 2
else:
dashboard['statistics']['median_supply'] = sorted_supplies[mid]
if dashboard['statistics']['min_supply'] == float('inf'):
dashboard['statistics']['min_supply'] = 0
return dashboard
def calculate_market_caps(
self,
coin_types: List[str],
price_data: Dict[str, float]
) -> List[Dict[str, Any]]:
"""Calculate market caps using supply and price data"""
supplies = self.get_multiple_total_supplies(coin_types)
market_caps = []
for coin_type, supply_info in supplies.items():
if not supply_info or coin_type not in price_data:
continue
price = price_data[coin_type]
market_cap = supply_info.formatted_supply * price
market_caps.append({
'coin_type': coin_type,
'symbol': supply_info.symbol,
'name': supply_info.name,
'supply': supply_info.formatted_supply,
'price': price,
'market_cap': market_cap,
'display_market_cap': f"${market_cap:,.2f}",
'display_supply': supply_info.display_supply
})
return sorted(market_caps, key=lambda x: x['market_cap'], reverse=True)
class SupplyTracker:
"""Track supply changes over time"""
def __init__(self, client: SuiTotalSupplyClient):
self.client = client
self.previous_supplies: Dict[str, str] = {}
self.supply_history: Dict[str, List[SupplyChange]] = defaultdict(list)
def track_supply(self, coin_type: str) -> SupplyChange:
"""Track supply change for a single coin"""
current_data = self.client.get_total_supply(coin_type)
if not current_data:
return SupplyChange(
coin_type=coin_type,
current_supply="0",
previous_supply=None,
absolute_change="0",
percentage_change=None,
timestamp=time.time()
)
current_supply = current_data['value']
previous_supply = self.previous_supplies.get(coin_type)
# Calculate absolute change
if previous_supply:
absolute_change = str(int(current_supply) - int(previous_supply))
else:
absolute_change = "0"
# Calculate percentage change
percentage_change = None
if previous_supply and int(previous_supply) > 0 and absolute_change != "0":
percentage_change = (int(absolute_change) / int(previous_supply)) * 100
change = SupplyChange(
coin_type=coin_type,
current_supply=current_supply,
previous_supply=previous_supply,
absolute_change=absolute_change,
percentage_change=percentage_change,
timestamp=time.time()
)
# Update tracking
self.previous_supplies[coin_type] = current_supply
self.supply_history[coin_type].append(change)
# Keep only last 100 entries
if len(self.supply_history[coin_type]) > 100:
self.supply_history[coin_type].pop(0)
return change
def track_multiple_supplies(self, coin_types: List[str]) -> Dict[str, SupplyChange]:
"""Track supply changes for multiple coins"""
results = {}
for coin_type in coin_types:
results[coin_type] = self.track_supply(coin_type)
return results
def get_supply_history(self, coin_type: str) -> List[SupplyChange]:
"""Get supply history for a coin"""
return self.supply_history.get(coin_type, [])
def get_supply_trend(self, coin_type: str, periods: int = 10) -> Dict[str, Any]:
"""Analyze supply trend over recent periods"""
history = self.get_supply_history(coin_type)
if len(history) < 2:
return {'trend': 'insufficient_data'}
recent_history = history[-periods:] if len(history) >= periods else history
changes = [int(h.absolute_change) for h in recent_history if h.absolute_change != "0"]
if not changes:
return {'trend': 'stable', 'periods': len(recent_history)}
total_change = sum(changes)
avg_change = total_change / len(changes)
trend = 'increasing' if avg_change > 0 else 'decreasing' if avg_change < 0 else 'stable'
return {
'trend': trend,
'average_change': avg_change,
'total_change': total_change,
'periods': len(recent_history),
'significant_changes': len(changes)
}
def monitor_supplies(
self,
coin_types: List[str],
interval_seconds: int = 60,
duration_minutes: int = 60
):
"""Monitor supply changes for specified duration"""
start_time = time.time()
end_time = start_time + (duration_minutes * 60)
print(f"Starting supply monitoring for {len(coin_types)} coins")
print(f"Duration: {duration_minutes} minutes, Interval: {interval_seconds}s")
while time.time() < end_time:
try:
changes = self.track_multiple_supplies(coin_types)
# Report significant changes
for coin_type, change in changes.items():
if change.absolute_change and int(change.absolute_change) != 0:
print(f"\n📊 Supply change for {coin_type}:")
print(f" Previous: {change.previous_supply}")
print(f" Current: {change.current_supply}")
print(f" Change: {change.absolute_change}")
if change.percentage_change:
print(f" Change %: {change.percentage_change:.6f}%")
time.sleep(interval_seconds)
except Exception as e:
print(f"Error in supply monitoring: {e}")
time.sleep(interval_seconds)
print("\nSupply monitoring completed")
# Return final summary
return {
coin_type: {
'final_supply': self.previous_supplies.get(coin_type, '0'),
'total_periods': len(self.supply_history.get(coin_type, [])),
'trend': self.get_supply_trend(coin_type)
}
for coin_type in coin_types
}
class SupplyAnalyzer:
"""Advanced supply analysis tools"""
def __init__(self, client: SuiTotalSupplyClient):
self.client = client
def analyze_defi_protocol_supplies(self, protocol_tokens: List[str]) -> Dict[str, Any]:
"""Analyze supply distribution for DeFi protocol tokens"""
supplies = self.client.get_multiple_total_supplies(protocol_tokens)
analysis = {
'protocol_name': 'DeFi Protocol',
'total_token_types': len(protocol_tokens),
'active_tokens': 0,
'total_supply_value': 0,
'token_breakdown': [],
'supply_concentration': {
'dominant_token': None,
'concentration_ratio': 0,
'hhi_index': 0 # Herfindahl-Hirschman Index
},
'supply_distribution': {
'top_10_percent': 0,
'top_50_percent': 0,
'gini_coefficient': 0 # Simplified calculation
}
}
valid_supplies = []
for coin_type, supply_info in supplies.items():
if not supply_info:
continue
analysis['active_tokens'] += 1
token_info = {
'coin_type': coin_type,
'symbol': supply_info.symbol,
'name': supply_info.name,
'supply': supply_info.formatted_supply,
'display_supply': supply_info.display_supply,
'raw_supply': supply_info.raw_supply
}
analysis['token_breakdown'].append(token_info)
analysis['total_supply_value'] += supply_info.formatted_supply
valid_supplies.append(supply_info.formatted_supply)
if valid_supplies:
# Sort by supply descending
analysis['token_breakdown'].sort(key=lambda x: x['supply'], reverse=True)
valid_supplies.sort(reverse=True)
# Calculate concentration metrics
total_supply = sum(valid_supplies)
if total_supply > 0:
# Dominant token
analysis['supply_concentration']['dominant_token'] = analysis['token_breakdown'][0]
analysis['supply_concentration']['concentration_ratio'] = (
valid_supplies[0] / total_supply
)
# HHI Index (sum of squared market shares)
hhi = sum((supply / total_supply) ** 2 for supply in valid_supplies)
analysis['supply_concentration']['hhi_index'] = hhi
# Top percentiles
top_10_count = max(1, len(valid_supplies) // 10)
analysis['supply_distribution']['top_10_percent'] = (
sum(valid_supplies[:top_10_count]) / total_supply
)
top_50_count = max(1, len(valid_supplies) // 2)
analysis['supply_distribution']['top_50_percent'] = (
sum(valid_supplies[:top_50_count]) / total_supply
)
return analysis
def compare_supplies(self, coin_types: List[str]) -> Dict[str, Any]:
"""Compare supplies across multiple coin types"""
supplies = self.client.get_multiple_total_supplies(coin_types)
comparison = {
'coin_count': len(coin_types),
'successful_fetches': 0,
'supply_ratios': {},
'rankings': {
'by_supply': [],
'by_symbol': [],
'by_decimals': []
},
'outliers': {
'highest_supply': None,
'lowest_supply': None,
'most_decimals': None,
'least_decimals': None
}
}
valid_supplies = []
for coin_type, supply_info in supplies.items():
if not supply_info:
continue
comparison['successful_fetches'] += 1
valid_supplies.append(supply_info)
supply_data = {
'coin_type': coin_type,
'symbol': supply_info.symbol,
'supply': supply_info.formatted_supply,
'decimals': supply_info.decimals,
'display_supply': supply_info.display_supply
}
comparison['rankings']['by_supply'].append(supply_data)
comparison['rankings']['by_symbol'].append(supply_data)
comparison['rankings']['by_decimals'].append(supply_data)
# Sort rankings
comparison['rankings']['by_supply'].sort(key=lambda x: x['supply'], reverse=True)
comparison['rankings']['by_symbol'].sort(key=lambda x: x['symbol'])
comparison['rankings']['by_decimals'].sort(key=lambda x: x['decimals'], reverse=True)
# Find outliers
if valid_supplies:
by_supply = sorted(valid_supplies, key=lambda x: x.formatted_supply, reverse=True)
by_decimals = sorted(valid_supplies, key=lambda x: x.decimals, reverse=True)
comparison['outliers']['highest_supply'] = {
'symbol': by_supply[0].symbol,
'supply': by_supply[0].formatted_supply,
'display': by_supply[0].display_supply
}
comparison['outliers']['lowest_supply'] = {
'symbol': by_supply[-1].symbol,
'supply': by_supply[-1].formatted_supply,
'display': by_supply[-1].display_supply
}
comparison['outliers']['most_decimals'] = {
'symbol': by_decimals[0].symbol,
'decimals': by_decimals[0].decimals
}
comparison['outliers']['least_decimals'] = {
'symbol': by_decimals[-1].symbol,
'decimals': by_decimals[-1].decimals
}
# Calculate supply ratios (each coin vs first coin)
base_supply = by_supply[0].formatted_supply
for supply_info in valid_supplies:
ratio = supply_info.formatted_supply / base_supply
comparison['supply_ratios'][supply_info.symbol] = ratio
return comparison
# Usage examples
client = SuiTotalSupplyClient('https://sui-mainnet.dwellir.com/YOUR_API_KEY')
# Example 1: Get SUI total supply
sui_supply = client.get_total_supply('0x2::sui::SUI')
if sui_supply:
print(f"SUI Total Supply (raw): {sui_supply['value']}")
# Example 2: Get formatted supply with metadata
formatted_supply = client.get_formatted_total_supply('0x2::sui::SUI')
if formatted_supply:
print(f"SUI Supply: {formatted_supply.display_supply}")
# Example 3: Create supply dashboard
coin_types = [
'0x2::sui::SUI',
'0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',
'0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT'
]
dashboard = client.create_supply_dashboard(coin_types)
print(f"\nSupply Dashboard:")
print(f"Total coins analyzed: {dashboard['total_coins_analyzed']}")
print(f"Successful queries: {dashboard['successful_queries']}")
print(f"Average supply: {dashboard['statistics']['average_supply']:,.2f}")
print(f"\nTop supplies:")
for token in dashboard['supply_ranking'][:3]:
print(f" {token['symbol']}: {token['display_supply']}")
# Example 4: Track supply changes
tracker = SupplyTracker(client)
supply_change = tracker.track_supply('0x2::sui::SUI')
print(f"\nSupply tracking for SUI:")
print(f"Current: {supply_change.current_supply}")
print(f"Change: {supply_change.absolute_change}")
# Example 5: Analyze protocol supplies
analyzer = SupplyAnalyzer(client)
protocol_analysis = analyzer.analyze_defi_protocol_supplies(coin_types)
print(f"\nProtocol Analysis:")
print(f"Active tokens: {protocol_analysis['active_tokens']}")
print(f"Total supply value: {protocol_analysis['total_supply_value']:,.2f}")
dominant = protocol_analysis['supply_concentration']['dominant_token']
if dominant:
print(f"Dominant token: {dominant['symbol']} ({dominant['display_supply']})")
Response Example​
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"value": "10000000000000000000"
}
}
Formatted Example (with metadata)​
For SUI with 9 decimals, the raw value 10000000000000000000
represents:
- Formatted: 10,000,000,000 SUI
- Display: 10,000,000,000.0000 SUI
Common Use Cases​
1. Market Cap Calculations​
async function calculateMarketCap(coinType, priceUSD) {
const [supply, metadata] = await Promise.all([
getTotalSupply(coinType),
client.getCoinMetadata({ coinType })
]);
const formattedSupply = Number(supply.value) / Math.pow(10, metadata.decimals);
const marketCap = formattedSupply * priceUSD;
return {
coinType: coinType,
symbol: metadata.symbol,
supply: formattedSupply,
price: priceUSD,
marketCap: marketCap,
formattedMarketCap: `$${marketCap.toLocaleString()}`
};
}
2. Tokenomics Analysis​
async function analyzeTokenomics(coinType) {
const supply = await getFormattedTotalSupply(coinType);
if (!supply) return null;
// Analyze supply characteristics
const analysis = {
symbol: supply.symbol,
totalSupply: supply.formattedSupply,
supplyCategory: categorizeSupply(supply.formattedSupply),
inflationRisk: assessInflationRisk(supply.formattedSupply),
liquidityIndicator: calculateLiquidityIndicator(supply.formattedSupply),
scarcityScore: calculateScarcityScore(supply.formattedSupply)
};
return analysis;
}
function categorizeSupply(supply) {
if (supply >= 1_000_000_000_000) return 'Ultra High Supply';
if (supply >= 100_000_000_000) return 'Very High Supply';
if (supply >= 1_000_000_000) return 'High Supply';
if (supply >= 100_000_000) return 'Medium-High Supply';
if (supply >= 1_000_000) return 'Medium Supply';
if (supply >= 100_000) return 'Low-Medium Supply';
if (supply >= 10_000) return 'Low Supply';
return 'Very Low Supply';
}
3. DeFi Protocol Monitoring​
async function monitorProtocolSupplies(protocolTokens, callback) {
const tracker = new SupplyTracker(client);
setInterval(async () => {
const changes = await tracker.trackMultipleSupplies(protocolTokens);
const significantChanges = Object.entries(changes).filter(
([, change]) => Math.abs(Number(change.absoluteChange)) > 0
);
if (significantChanges.length > 0) {
callback({
timestamp: new Date().toISOString(),
changes: significantChanges.map(([coinType, change]) => ({
coinType,
change: change.absoluteChange,
percentage: change.percentageChange
}))
});
}
}, 30000); // Check every 30 seconds
}
4. Portfolio Value Calculator​
async function calculatePortfolioValue(holdings, prices) {
const totalValue = {
totalUSD: 0,
breakdown: []
};
for (const holding of holdings) {
const supply = await getFormattedTotalSupply(holding.coinType);
const price = prices[holding.coinType] || 0;
if (supply && price > 0) {
const holdingPercentage = Number(holding.balance) /
Math.pow(10, supply.decimals) / supply.formattedSupply * 100;
const holdingValue = (Number(holding.balance) /
Math.pow(10, supply.decimals)) * price;
totalValue.breakdown.push({
symbol: supply.symbol,
holdings: Number(holding.balance) / Math.pow(10, supply.decimals),
percentage: holdingPercentage,
value: holdingValue,
totalSupply: supply.formattedSupply
});
totalValue.totalUSD += holdingValue;
}
}
return totalValue;
}
Best Practices​
1. Supply Data Caching​
// Cache supply data with reasonable TTL since it changes infrequently
const supplyCache = new Map();
const SUPPLY_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getCachedTotalSupply(coinType) {
const cached = supplyCache.get(coinType);
if (cached && Date.now() - cached.timestamp < SUPPLY_CACHE_TTL) {
return cached.data;
}
const supply = await getTotalSupply(coinType);
if (supply) {
supplyCache.set(coinType, {
data: supply,
timestamp: Date.now()
});
}
return supply;
}
2. Precision Handling​
// Use BigInt for precise supply calculations
function calculateSupplyRatio(supply1, supply2) {
const s1 = BigInt(supply1);
const s2 = BigInt(supply2);
if (s2 === BigInt(0)) return null;
// Calculate ratio with high precision
const ratio = (s1 * BigInt(10000)) / s2; // 4 decimal places
return Number(ratio) / 10000;
}
3. Error Handling​
async function safeGetTotalSupply(coinType) {
try {
const supply = await getTotalSupply(coinType);
if (!supply || !supply.value) {
return {
success: false,
error: 'No supply data available'
};
}
return {
success: true,
data: supply
};
} catch (error) {
return {
success: false,
error: error.message,
retry: !error.message.includes('not found')
};
}
}
Supply Interpretation​
Understanding Supply Values​
- Raw Values: Always returned in smallest unit (e.g., MIST for SUI)
- Total vs Circulating: This method returns total circulating supply
- Burned Tokens: Burned tokens are automatically subtracted from supply
- Minting Events: New minting increases the total supply immediately
Supply Categories​
- Deflationary: Supply decreases over time through burning
- Inflationary: Supply increases through ongoing minting
- Fixed: Supply is capped and cannot increase
- Elastic: Supply adjusts based on market conditions
Related Methods​
- suix_getCoinMetadata - Get coin metadata for formatting
- suix_getBalance - Query individual balances
- suix_getCoins - Get coin objects
Notes​
- Supply can change due to minting, burning, or staking operations
- Values are real-time and reflect the current blockchain state
- Use metadata to properly format supply values for display
- Large numbers may require BigInt handling in JavaScript
- Monitor changes for tokens with dynamic supply models
Need help? Contact our support team or check the Sui documentation.