suix_getReferenceGasPrice
Returns the current reference gas price on the Sui network in MIST units.
Overview​
The suix_getReferenceGasPrice
method provides the current reference gas price used for transaction fee calculations on the Sui network. This price is set by the validator consensus and represents the minimum gas price that validators are willing to accept for transaction processing. Understanding the reference gas price is crucial for transaction cost estimation, gas optimization, and building cost-effective applications on Sui.
Parameters​
This method takes no parameters.
Returns​
Returns the current reference gas price as a string representing the price in MIST units.
Field | Type | Description |
---|---|---|
result | string | Reference gas price in MIST (1 SUI = 1,000,000,000 MIST) |
Gas Price Units​
- MIST: The smallest unit of SUI (10^-9 SUI)
- Reference Price: Base price for gas calculations
- Actual Cost: Transaction cost = Gas Units × Gas Price
- Dynamic Pricing: Gas price can fluctuate based on network demand
Code Examples​
- cURL
- JavaScript
- Python
# Get current reference gas price
curl -X POST https://sui-mainnet.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "suix_getReferenceGasPrice",
"params": [],
"id": 1
}'
import { SuiClient } from '@mysten/sui.js/client';
const client = new SuiClient({
url: 'https://sui-mainnet.dwellir.com/YOUR_API_KEY'
});
// Get current reference gas price
async function getReferenceGasPrice() {
try {
const gasPrice = await client.getReferenceGasPrice();
console.log('Reference Gas Price:', gasPrice, 'MIST');
console.log('In SUI:', Number(gasPrice) / 1_000_000_000);
return gasPrice;
} catch (error) {
console.error('Failed to get reference gas price:', error);
return null;
}
}
// Gas price tracker with historical data
class GasPriceTracker {
constructor(client) {
this.client = client;
this.priceHistory = [];
this.alerts = [];
}
async trackGasPrice() {
try {
const currentPrice = await this.client.getReferenceGasPrice();
const timestamp = Date.now();
const priceData = {
price: currentPrice,
priceMIST: Number(currentPrice),
priceSUI: Number(currentPrice) / 1_000_000_000,
timestamp: timestamp,
date: new Date(timestamp).toISOString()
};
this.priceHistory.push(priceData);
// Keep only last 100 entries
if (this.priceHistory.length > 100) {
this.priceHistory.shift();
}
// Check for alerts
this.checkPriceAlerts(priceData);
return priceData;
} catch (error) {
console.error('Error tracking gas price:', error);
return null;
}
}
checkPriceAlerts(currentPrice) {
if (this.priceHistory.length < 2) return;
const previousPrice = this.priceHistory[this.priceHistory.length - 2];
const changePercent = ((currentPrice.priceMIST - previousPrice.priceMIST) / previousPrice.priceMIST) * 100;
// Alert on significant changes
if (Math.abs(changePercent) >= 10) { // 10% change threshold
const alert = {
type: changePercent > 0 ? 'PRICE_INCREASE' : 'PRICE_DECREASE',
changePercent: changePercent,
previousPrice: previousPrice.priceMIST,
currentPrice: currentPrice.priceMIST,
timestamp: currentPrice.timestamp,
message: `Gas price ${changePercent > 0 ? 'increased' : 'decreased'} by ${Math.abs(changePercent).toFixed(2)}%`
};
this.alerts.push(alert);
console.warn(`🚨 Gas Price Alert: ${alert.message}`);
}
}
getStatistics() {
if (this.priceHistory.length === 0) {
return { error: 'No price data available' };
}
const prices = this.priceHistory.map(p => p.priceMIST);
const sorted = [...prices].sort((a, b) => a - b);
const stats = {
current: prices[prices.length - 1],
min: Math.min(...prices),
max: Math.max(...prices),
average: prices.reduce((sum, p) => sum + p, 0) / prices.length,
median: sorted[Math.floor(sorted.length / 2)],
volatility: this.calculateVolatility(prices),
dataPoints: prices.length,
timeSpan: this.priceHistory.length > 1 ? {
start: this.priceHistory[0].date,
end: this.priceHistory[this.priceHistory.length - 1].date
} : null
};
return stats;
}
calculateVolatility(prices) {
if (prices.length < 2) return 0;
const changes = [];
for (let i = 1; i < prices.length; i++) {
const change = (prices[i] - prices[i - 1]) / prices[i - 1];
changes.push(change);
}
const mean = changes.reduce((sum, c) => sum + c, 0) / changes.length;
const variance = changes.reduce((sum, c) => sum + Math.pow(c - mean, 2), 0) / changes.length;
return Math.sqrt(variance);
}
async startMonitoring(intervalMinutes = 5) {
console.log(`📊 Starting gas price monitoring (every ${intervalMinutes} minutes)`);
// Initial reading
await this.trackGasPrice();
const intervalId = setInterval(async () => {
const priceData = await this.trackGasPrice();
if (priceData) {
console.log(`Gas Price: ${priceData.priceSUI.toFixed(9)} SUI (${priceData.priceMIST} MIST)`);
}
}, intervalMinutes * 60 * 1000);
return () => {
clearInterval(intervalId);
console.log('Gas price monitoring stopped');
};
}
}
// Transaction cost calculator
class TransactionCostCalculator {
constructor(client) {
this.client = client;
this.cachedGasPrice = null;
this.cacheTime = 0;
this.cacheTimeout = 60000; // 1 minute cache
}
async getGasPrice(useCache = true) {
const now = Date.now();
if (useCache && this.cachedGasPrice && (now - this.cacheTime) < this.cacheTimeout) {
return this.cachedGasPrice;
}
const gasPrice = await this.client.getReferenceGasPrice();
this.cachedGasPrice = gasPrice;
this.cacheTime = now;
return gasPrice;
}
async estimateTransactionCost(gasUnits, gasPrice = null) {
if (!gasPrice) {
gasPrice = await this.getGasPrice();
}
const cost = BigInt(gasUnits) * BigInt(gasPrice);
return {
gasUnits: gasUnits,
gasPrice: gasPrice,
totalCostMIST: cost.toString(),
totalCostSUI: Number(cost) / 1_000_000_000,
breakdown: {
computation: cost,
storage: BigInt(0), // Would need to be calculated separately
total: cost
}
};
}
async estimateMultipleTransactions(transactions) {
const gasPrice = await this.getGasPrice();
const estimates = [];
let totalCost = BigInt(0);
for (const tx of transactions) {
const estimate = await this.estimateTransactionCost(tx.gasUnits, gasPrice);
estimate.transactionType = tx.type || 'Unknown';
estimate.description = tx.description || '';
estimates.push(estimate);
totalCost += BigInt(estimate.totalCostMIST);
}
return {
gasPrice: gasPrice,
transactions: estimates,
summary: {
totalTransactions: transactions.length,
totalCostMIST: totalCost.toString(),
totalCostSUI: Number(totalCost) / 1_000_000_000,
averageCostSUI: Number(totalCost) / 1_000_000_000 / transactions.length
}
};
}
async calculateOptimalGasPrice(urgencyLevel = 'normal') {
const referencePrice = await this.getGasPrice();
const referencePriceMIST = Number(referencePrice);
let multiplier;
switch (urgencyLevel.toLowerCase()) {
case 'low':
multiplier = 1.0; // Use reference price
break;
case 'normal':
multiplier = 1.1; // 10% above reference
break;
case 'high':
multiplier = 1.25; // 25% above reference
break;
case 'urgent':
multiplier = 1.5; // 50% above reference
break;
default:
multiplier = 1.1;
}
const optimalPrice = Math.ceil(referencePriceMIST * multiplier);
return {
referencePrice: referencePriceMIST,
optimalPrice: optimalPrice,
multiplier: multiplier,
urgencyLevel: urgencyLevel,
premiumPercent: ((multiplier - 1) * 100).toFixed(1)
};
}
}
// Gas optimization analyzer
class GasOptimizationAnalyzer {
constructor(client) {
this.client = client;
}
async analyzeGasUsage(transactionHistory) {
const currentGasPrice = await this.client.getReferenceGasPrice();
const analysis = {
currentGasPrice: Number(currentGasPrice),
totalTransactions: transactionHistory.length,
totalGasUsed: 0,
totalCostPaid: 0,
averageGasPerTx: 0,
averageCostPerTx: 0,
costByType: {},
optimization: {
potentialSavings: 0,
recommendations: []
}
};
// Analyze transaction patterns
transactionHistory.forEach(tx => {
const gasUsed = tx.gasUsed || 0;
const gasPaid = tx.totalGasCost || 0;
const txType = tx.type || 'unknown';
analysis.totalGasUsed += gasUsed;
analysis.totalCostPaid += gasPaid;
if (!analysis.costByType[txType]) {
analysis.costByType[txType] = {
count: 0,
totalGas: 0,
totalCost: 0,
averageGas: 0,
averageCost: 0
};
}
analysis.costByType[txType].count++;
analysis.costByType[txType].totalGas += gasUsed;
analysis.costByType[txType].totalCost += gasPaid;
});
// Calculate averages
if (analysis.totalTransactions > 0) {
analysis.averageGasPerTx = analysis.totalGasUsed / analysis.totalTransactions;
analysis.averageCostPerTx = analysis.totalCostPaid / analysis.totalTransactions;
}
// Calculate type-specific averages
Object.values(analysis.costByType).forEach(typeData => {
if (typeData.count > 0) {
typeData.averageGas = typeData.totalGas / typeData.count;
typeData.averageCost = typeData.totalCost / typeData.count;
}
});
// Generate optimization recommendations
this.generateOptimizationRecommendations(analysis);
return analysis;
}
generateOptimizationRecommendations(analysis) {
const recommendations = [];
// Check for high-cost transaction types
Object.entries(analysis.costByType).forEach(([type, data]) => {
if (data.averageCost > analysis.averageCostPerTx * 1.5) {
recommendations.push({
type: 'HIGH_COST_OPERATIONS',
priority: 'MEDIUM',
message: `${type} transactions cost ${(data.averageCost / analysis.averageCostPerTx).toFixed(1)}x more than average`,
suggestion: `Consider batching ${type} operations or optimizing contract calls`
});
}
});
// Check for frequent small transactions
const smallTxCount = Object.values(analysis.costByType).reduce((count, data) => {
return count + (data.averageCost < analysis.averageCostPerTx * 0.5 ? data.count : 0);
}, 0);
if (smallTxCount > analysis.totalTransactions * 0.3) {
recommendations.push({
type: 'TRANSACTION_BATCHING',
priority: 'HIGH',
message: `${((smallTxCount / analysis.totalTransactions) * 100).toFixed(1)}% of transactions are small-cost operations`,
suggestion: 'Consider batching multiple operations into single transactions'
});
}
// Check gas price efficiency
if (analysis.averageCostPerTx > analysis.currentGasPrice * analysis.averageGasPerTx * 1.2) {
recommendations.push({
type: 'GAS_PRICE_OPTIMIZATION',
priority: 'LOW',
message: 'Historical gas prices suggest you may be overpaying for transactions',
suggestion: 'Consider using lower gas prices for non-urgent transactions'
});
}
analysis.optimization.recommendations = recommendations;
}
}
// Usage examples
// Basic gas price checking
const gasPrice = await getReferenceGasPrice();
console.log(`Current gas price: ${gasPrice} MIST`);
// Gas price monitoring
const tracker = new GasPriceTracker(client);
await tracker.trackGasPrice();
console.log('Gas Price Statistics:');
const stats = tracker.getStatistics();
console.log(`Current: ${stats.current} MIST`);
console.log(`Average: ${stats.average.toFixed(2)} MIST`);
console.log(`Min/Max: ${stats.min} - ${stats.max} MIST`);
console.log(`Volatility: ${(stats.volatility * 100).toFixed(2)}%`);
// Start monitoring (uncomment to run continuously)
// const stopMonitoring = await tracker.startMonitoring(5); // Check every 5 minutes
// Transaction cost estimation
const calculator = new TransactionCostCalculator(client);
// Estimate cost for a single transaction
const transferCost = await calculator.estimateTransactionCost(1000000); // 1M gas units
console.log('\nTransfer Cost Estimate:');
console.log(`Gas Units: ${transferCost.gasUnits}`);
console.log(`Gas Price: ${transferCost.gasPrice} MIST`);
console.log(`Total Cost: ${transferCost.totalCostSUI.toFixed(9)} SUI`);
// Estimate costs for multiple transaction types
const transactions = [
{ type: 'Transfer', gasUnits: 1000000, description: 'Simple SUI transfer' },
{ type: 'Smart Contract Call', gasUnits: 2500000, description: 'DeFi swap operation' },
{ type: 'NFT Mint', gasUnits: 1800000, description: 'Mint NFT token' },
{ type: 'Staking', gasUnits: 1200000, description: 'Delegate to validator' }
];
const multiEstimate = await calculator.estimateMultipleTransactions(transactions);
console.log('\nMultiple Transaction Cost Estimates:');
console.log(`Total Cost: ${multiEstimate.summary.totalCostSUI.toFixed(6)} SUI`);
console.log(`Average per TX: ${multiEstimate.summary.averageCostSUI.toFixed(6)} SUI`);
multiEstimate.transactions.forEach((tx, index) => {
console.log(`${index + 1}. ${tx.transactionType}: ${tx.totalCostSUI.toFixed(6)} SUI`);
});
// Optimal gas price calculation
const urgencyLevels = ['low', 'normal', 'high', 'urgent'];
console.log('\nOptimal Gas Prices by Urgency:');
for (const level of urgencyLevels) {
const optimal = await calculator.calculateOptimalGasPrice(level);
console.log(`${level.toUpperCase()}: ${optimal.optimalPrice} MIST (+${optimal.premiumPercent}%)`);
}
import requests
import json
import time
import statistics
from typing import List, Dict, Any, Optional
from dataclasses import dataclass
import math
@dataclass
class GasPriceData:
price: str
price_mist: int
price_sui: float
timestamp: float
date: str
class SuiGasPriceClient:
def __init__(self, rpc_url: str):
self.rpc_url = rpc_url
def get_reference_gas_price(self) -> Optional[str]:
"""Get current reference gas price"""
payload = {
"jsonrpc": "2.0",
"method": "suix_getReferenceGasPrice",
"params": [],
"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: {result['error']}")
return None
return result['result']
except Exception as e:
print(f"Error fetching gas price: {e}")
return None
class GasPriceTracker:
def __init__(self, client: SuiGasPriceClient):
self.client = client
self.price_history = []
self.alerts = []
self.max_history = 100
def track_gas_price(self) -> Optional[GasPriceData]:
"""Track current gas price and add to history"""
current_price = self.client.get_reference_gas_price()
if not current_price:
return None
timestamp = time.time()
price_data = GasPriceData(
price=current_price,
price_mist=int(current_price),
price_sui=int(current_price) / 1_000_000_000,
timestamp=timestamp,
date=time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime(timestamp))
)
self.price_history.append(price_data)
# Keep only last max_history entries
if len(self.price_history) > self.max_history:
self.price_history.pop(0)
# Check for price alerts
self._check_price_alerts(price_data)
return price_data
def _check_price_alerts(self, current_price: GasPriceData):
"""Check for significant price changes"""
if len(self.price_history) < 2:
return
previous_price = self.price_history[-2]
change_percent = ((current_price.price_mist - previous_price.price_mist) /
previous_price.price_mist) * 100
# Alert on significant changes (10% threshold)
if abs(change_percent) >= 10:
alert = {
'type': 'PRICE_INCREASE' if change_percent > 0 else 'PRICE_DECREASE',
'change_percent': change_percent,
'previous_price': previous_price.price_mist,
'current_price': current_price.price_mist,
'timestamp': current_price.timestamp,
'message': f"Gas price {'increased' if change_percent > 0 else 'decreased'} by {abs(change_percent):.2f}%"
}
self.alerts.append(alert)
print(f"🚨 Gas Price Alert: {alert['message']}")
def get_statistics(self) -> Dict[str, Any]:
"""Calculate statistics from price history"""
if not self.price_history:
return {'error': 'No price data available'}
prices = [p.price_mist for p in self.price_history]
stats = {
'current': prices[-1],
'min': min(prices),
'max': max(prices),
'average': statistics.mean(prices),
'median': statistics.median(prices),
'volatility': self._calculate_volatility(prices),
'data_points': len(prices),
'time_span': {
'start': self.price_history[0].date,
'end': self.price_history[-1].date
} if len(self.price_history) > 1 else None
}
return stats
def _calculate_volatility(self, prices: List[int]) -> float:
"""Calculate price volatility"""
if len(prices) < 2:
return 0.0
changes = []
for i in range(1, len(prices)):
change = (prices[i] - prices[i-1]) / prices[i-1]
changes.append(change)
return statistics.stdev(changes) if changes else 0.0
def start_monitoring(self, interval_minutes: int = 5, duration_hours: int = 24):
"""Start monitoring gas prices for a specified duration"""
print(f"📊 Starting gas price monitoring (every {interval_minutes} minutes)")
start_time = time.time()
end_time = start_time + (duration_hours * 3600)
# Initial reading
price_data = self.track_gas_price()
if price_data:
print(f"Initial gas price: {price_data.price_sui:.9f} SUI ({price_data.price_mist} MIST)")
while time.time() < end_time:
time.sleep(interval_minutes * 60)
price_data = self.track_gas_price()
if price_data:
print(f"Gas Price: {price_data.price_sui:.9f} SUI ({price_data.price_mist} MIST)")
print("Gas price monitoring completed")
return self.get_statistics()
class TransactionCostCalculator:
def __init__(self, client: SuiGasPriceClient):
self.client = client
self.cached_gas_price = None
self.cache_time = 0
self.cache_timeout = 60 # 60 seconds cache
def get_gas_price(self, use_cache: bool = True) -> Optional[str]:
"""Get gas price with optional caching"""
current_time = time.time()
if (use_cache and self.cached_gas_price and
(current_time - self.cache_time) < self.cache_timeout):
return self.cached_gas_price
gas_price = self.client.get_reference_gas_price()
if gas_price:
self.cached_gas_price = gas_price
self.cache_time = current_time
return gas_price
def estimate_transaction_cost(self, gas_units: int, gas_price: Optional[str] = None) -> Dict[str, Any]:
"""Estimate cost for a transaction"""
if gas_price is None:
gas_price = self.get_gas_price()
if not gas_price:
return {'error': 'Could not retrieve gas price'}
cost = gas_units * int(gas_price)
return {
'gas_units': gas_units,
'gas_price': gas_price,
'gas_price_mist': int(gas_price),
'total_cost_mist': cost,
'total_cost_sui': cost / 1_000_000_000,
'breakdown': {
'computation': cost,
'storage': 0, # Would need separate calculation
'total': cost
}
}
def estimate_multiple_transactions(self, transactions: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Estimate costs for multiple transactions"""
gas_price = self.get_gas_price()
if not gas_price:
return {'error': 'Could not retrieve gas price'}
estimates = []
total_cost = 0
for tx in transactions:
gas_units = tx.get('gas_units', 0)
estimate = self.estimate_transaction_cost(gas_units, gas_price)
if 'error' in estimate:
continue
estimate['transaction_type'] = tx.get('type', 'Unknown')
estimate['description'] = tx.get('description', '')
estimates.append(estimate)
total_cost += estimate['total_cost_mist']
return {
'gas_price': gas_price,
'transactions': estimates,
'summary': {
'total_transactions': len(estimates),
'total_cost_mist': total_cost,
'total_cost_sui': total_cost / 1_000_000_000,
'average_cost_sui': (total_cost / 1_000_000_000 / len(estimates)) if estimates else 0
}
}
def calculate_optimal_gas_price(self, urgency_level: str = 'normal') -> Dict[str, Any]:
"""Calculate optimal gas price based on urgency level"""
reference_price = self.get_gas_price()
if not reference_price:
return {'error': 'Could not retrieve reference price'}
reference_price_mist = int(reference_price)
multiplier_map = {
'low': 1.0,
'normal': 1.1,
'high': 1.25,
'urgent': 1.5
}
multiplier = multiplier_map.get(urgency_level.lower(), 1.1)
optimal_price = math.ceil(reference_price_mist * multiplier)
return {
'reference_price': reference_price_mist,
'optimal_price': optimal_price,
'multiplier': multiplier,
'urgency_level': urgency_level,
'premium_percent': f"{((multiplier - 1) * 100):.1f}%"
}
class GasOptimizationAnalyzer:
def __init__(self, client: SuiGasPriceClient):
self.client = client
def analyze_gas_usage(self, transaction_history: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Analyze historical gas usage and provide optimization insights"""
current_gas_price = self.client.get_reference_gas_price()
if not current_gas_price:
return {'error': 'Could not retrieve current gas price'}
analysis = {
'current_gas_price': int(current_gas_price),
'total_transactions': len(transaction_history),
'total_gas_used': 0,
'total_cost_paid': 0,
'average_gas_per_tx': 0,
'average_cost_per_tx': 0,
'cost_by_type': {},
'optimization': {
'potential_savings': 0,
'recommendations': []
}
}
# Process transaction history
for tx in transaction_history:
gas_used = tx.get('gas_used', 0)
gas_cost = tx.get('total_gas_cost', 0)
tx_type = tx.get('type', 'unknown')
analysis['total_gas_used'] += gas_used
analysis['total_cost_paid'] += gas_cost
if tx_type not in analysis['cost_by_type']:
analysis['cost_by_type'][tx_type] = {
'count': 0,
'total_gas': 0,
'total_cost': 0,
'average_gas': 0,
'average_cost': 0
}
type_data = analysis['cost_by_type'][tx_type]
type_data['count'] += 1
type_data['total_gas'] += gas_used
type_data['total_cost'] += gas_cost
# Calculate averages
if analysis['total_transactions'] > 0:
analysis['average_gas_per_tx'] = analysis['total_gas_used'] / analysis['total_transactions']
analysis['average_cost_per_tx'] = analysis['total_cost_paid'] / analysis['total_transactions']
# Calculate type-specific averages
for type_data in analysis['cost_by_type'].values():
if type_data['count'] > 0:
type_data['average_gas'] = type_data['total_gas'] / type_data['count']
type_data['average_cost'] = type_data['total_cost'] / type_data['count']
# Generate optimization recommendations
self._generate_optimization_recommendations(analysis)
return analysis
def _generate_optimization_recommendations(self, analysis: Dict[str, Any]):
"""Generate optimization recommendations based on analysis"""
recommendations = []
# Check for high-cost transaction types
for tx_type, data in analysis['cost_by_type'].items():
if (data['average_cost'] > analysis['average_cost_per_tx'] * 1.5 and
analysis['average_cost_per_tx'] > 0):
recommendations.append({
'type': 'HIGH_COST_OPERATIONS',
'priority': 'MEDIUM',
'message': f"{tx_type} transactions cost {data['average_cost'] / analysis['average_cost_per_tx']:.1f}x more than average",
'suggestion': f"Consider batching {tx_type} operations or optimizing contract calls"
})
# Check for frequent small transactions
small_tx_count = sum(1 for data in analysis['cost_by_type'].values()
if data['average_cost'] < analysis['average_cost_per_tx'] * 0.5)
if small_tx_count > analysis['total_transactions'] * 0.3:
recommendations.append({
'type': 'TRANSACTION_BATCHING',
'priority': 'HIGH',
'message': f"{(small_tx_count / analysis['total_transactions'] * 100):.1f}% of transactions are small-cost operations",
'suggestion': 'Consider batching multiple operations into single transactions'
})
# Check gas price efficiency
expected_cost = analysis['current_gas_price'] * analysis['average_gas_per_tx']
if analysis['average_cost_per_tx'] > expected_cost * 1.2:
recommendations.append({
'type': 'GAS_PRICE_OPTIMIZATION',
'priority': 'LOW',
'message': 'Historical gas prices suggest you may be overpaying for transactions',
'suggestion': 'Consider using lower gas prices for non-urgent transactions'
})
analysis['optimization']['recommendations'] = recommendations
# Usage examples
client = SuiGasPriceClient('https://sui-mainnet.dwellir.com/YOUR_API_KEY')
# Example 1: Get current gas price
print("Getting current gas price...")
gas_price = client.get_reference_gas_price()
if gas_price:
price_mist = int(gas_price)
price_sui = price_mist / 1_000_000_000
print(f"Current Gas Price: {price_mist} MIST")
print(f"Current Gas Price: {price_sui:.9f} SUI")
else:
print("Failed to get gas price")
# Example 2: Gas price tracking
print("\nTracking gas price...")
tracker = GasPriceTracker(client)
# Track a few data points
for i in range(3):
price_data = tracker.track_gas_price()
if price_data:
print(f"Tracked: {price_data.price_sui:.9f} SUI at {price_data.date}")
time.sleep(1) # Wait 1 second between readings
# Get statistics
stats = tracker.get_statistics()
if 'error' not in stats:
print(f"\nPrice Statistics:")
print(f" Current: {stats['current']} MIST")
print(f" Average: {stats['average']:.2f} MIST")
print(f" Min/Max: {stats['min']} - {stats['max']} MIST")
print(f" Volatility: {stats['volatility'] * 100:.2f}%")
print(f" Data Points: {stats['data_points']}")
# Example 3: Transaction cost estimation
print("\nCalculating transaction costs...")
calculator = TransactionCostCalculator(client)
# Single transaction estimate
transfer_estimate = calculator.estimate_transaction_cost(1000000) # 1M gas units
if 'error' not in transfer_estimate:
print(f"Transfer Cost Estimate:")
print(f" Gas Units: {transfer_estimate['gas_units']:,}")
print(f" Gas Price: {transfer_estimate['gas_price_mist']:,} MIST")
print(f" Total Cost: {transfer_estimate['total_cost_sui']:.9f} SUI")
# Multiple transactions estimate
transactions = [
{'type': 'Transfer', 'gas_units': 1000000, 'description': 'Simple SUI transfer'},
{'type': 'Smart Contract Call', 'gas_units': 2500000, 'description': 'DeFi swap operation'},
{'type': 'NFT Mint', 'gas_units': 1800000, 'description': 'Mint NFT token'},
{'type': 'Staking', 'gas_units': 1200000, 'description': 'Delegate to validator'}
]
multi_estimate = calculator.estimate_multiple_transactions(transactions)
if 'error' not in multi_estimate:
print(f"\nMultiple Transaction Cost Estimates:")
print(f" Total Cost: {multi_estimate['summary']['total_cost_sui']:.6f} SUI")
print(f" Average per TX: {multi_estimate['summary']['average_cost_sui']:.6f} SUI")
for i, tx in enumerate(multi_estimate['transactions'], 1):
print(f" {i}. {tx['transaction_type']}: {tx['total_cost_sui']:.6f} SUI")
# Example 4: Optimal gas price calculation
print(f"\nOptimal Gas Prices by Urgency Level:")
urgency_levels = ['low', 'normal', 'high', 'urgent']
for level in urgency_levels:
optimal = calculator.calculate_optimal_gas_price(level)
if 'error' not in optimal:
print(f" {level.upper()}: {optimal['optimal_price']:,} MIST (+{optimal['premium_percent']})")
# Example 5: Gas usage analysis
print(f"\nAnalyzing gas usage patterns...")
# Sample transaction history
sample_history = [
{'type': 'transfer', 'gas_used': 1000000, 'total_gas_cost': 1000000000},
{'type': 'defi_swap', 'gas_used': 2500000, 'total_gas_cost': 2750000000},
{'type': 'transfer', 'gas_used': 1100000, 'total_gas_cost': 1100000000},
{'type': 'nft_mint', 'gas_used': 1800000, 'total_gas_cost': 1980000000},
{'type': 'transfer', 'gas_used': 950000, 'total_gas_cost': 950000000},
{'type': 'staking', 'gas_used': 1200000, 'total_gas_cost': 1320000000}
]
analyzer = GasOptimizationAnalyzer(client)
analysis = analyzer.analyze_gas_usage(sample_history)
if 'error' not in analysis:
print(f"Gas Usage Analysis:")
print(f" Total Transactions: {analysis['total_transactions']}")
print(f" Total Gas Used: {analysis['total_gas_used']:,}")
print(f" Average Gas per TX: {analysis['average_gas_per_tx']:,.0f}")
print(f" Average Cost per TX: {analysis['average_cost_per_tx'] / 1_000_000_000:.6f} SUI")
print(f"\nCost by Transaction Type:")
for tx_type, data in analysis['cost_by_type'].items():
avg_cost_sui = data['average_cost'] / 1_000_000_000
print(f" {tx_type}: {data['count']} txs, avg {avg_cost_sui:.6f} SUI")
print(f"\nOptimization Recommendations:")
if analysis['optimization']['recommendations']:
for i, rec in enumerate(analysis['optimization']['recommendations'], 1):
print(f" {i}. [{rec['priority']}] {rec['message']}")
print(f" Suggestion: {rec['suggestion']}")
else:
print(" No optimization recommendations - gas usage looks efficient!")
# Example 6: Start continuous monitoring (commented out for demo)
# print("\nStarting continuous monitoring for 1 hour...")
# final_stats = tracker.start_monitoring(interval_minutes=5, duration_hours=1)
# print("Monitoring completed. Final statistics:")
# print(json.dumps(final_stats, indent=2))
Response Example​
{
"jsonrpc": "2.0",
"id": 1,
"result": "1000"
}
Common Use Cases​
Gas Price Monitoring System​
class GasPriceMonitoringSystem {
constructor(client) {
this.client = client;
this.priceHistory = [];
this.subscribers = [];
this.thresholds = {
lowPrice: 800,
highPrice: 1500,
priceChangePercent: 15
};
}
async startMonitoring(interval = 60000) { // 1 minute default
setInterval(async () => {
try {
const gasPrice = await this.client.getReferenceGasPrice();
const priceData = {
price: Number(gasPrice),
timestamp: Date.now(),
date: new Date().toISOString()
};
this.priceHistory.push(priceData);
// Keep only last 24 hours
const dayAgo = Date.now() - (24 * 60 * 60 * 1000);
this.priceHistory = this.priceHistory.filter(p => p.timestamp > dayAgo);
// Check for alerts
this.checkAlerts(priceData);
// Notify subscribers
this.notifySubscribers('PRICE_UPDATE', priceData);
} catch (error) {
console.error('Error monitoring gas price:', error);
}
}, interval);
}
checkAlerts(currentPrice) {
const alerts = [];
// Check absolute price thresholds
if (currentPrice.price <= this.thresholds.lowPrice) {
alerts.push({
type: 'LOW_PRICE',
message: `Gas price is unusually low: ${currentPrice.price} MIST`,
recommendation: 'Good time for non-urgent transactions'
});
}
if (currentPrice.price >= this.thresholds.highPrice) {
alerts.push({
type: 'HIGH_PRICE',
message: `Gas price is high: ${currentPrice.price} MIST`,
recommendation: 'Consider delaying non-urgent transactions'
});
}
// Check price change alerts
if (this.priceHistory.length >= 2) {
const previousPrice = this.priceHistory[this.priceHistory.length - 2];
const changePercent = ((currentPrice.price - previousPrice.price) / previousPrice.price) * 100;
if (Math.abs(changePercent) >= this.thresholds.priceChangePercent) {
alerts.push({
type: changePercent > 0 ? 'PRICE_SPIKE' : 'PRICE_DROP',
message: `Gas price ${changePercent > 0 ? 'increased' : 'decreased'} by ${Math.abs(changePercent).toFixed(1)}%`,
changePercent: changePercent,
previousPrice: previousPrice.price,
currentPrice: currentPrice.price
});
}
}
// Notify subscribers about alerts
alerts.forEach(alert => {
this.notifySubscribers('ALERT', alert);
});
}
subscribe(callback) {
this.subscribers.push(callback);
return () => {
const index = this.subscribers.indexOf(callback);
if (index > -1) {
this.subscribers.splice(index, 1);
}
};
}
notifySubscribers(type, data) {
this.subscribers.forEach(callback => {
try {
callback(type, data);
} catch (error) {
console.error('Error notifying subscriber:', error);
}
});
}
}
Dynamic Gas Price Strategy​
class DynamicGasPriceStrategy {
constructor(client) {
this.client = client;
this.priceCache = new Map();
this.strategyConfig = {
conservative: { multiplier: 1.0, maxPrice: 1200 },
normal: { multiplier: 1.1, maxPrice: 1500 },
aggressive: { multiplier: 1.3, maxPrice: 2000 },
urgent: { multiplier: 1.5, maxPrice: 3000 }
};
}
async getOptimalGasPrice(strategy = 'normal', transactionType = 'general') {
const basePrice = await this.client.getReferenceGasPrice();
const basePriceMIST = Number(basePrice);
const config = this.strategyConfig[strategy] || this.strategyConfig.normal;
let optimalPrice = Math.ceil(basePriceMIST * config.multiplier);
// Apply transaction-specific adjustments
const typeMultiplier = this.getTypeMultiplier(transactionType);
optimalPrice = Math.ceil(optimalPrice * typeMultiplier);
// Cap at maximum price
optimalPrice = Math.min(optimalPrice, config.maxPrice);
// Ensure minimum viable price
optimalPrice = Math.max(optimalPrice, basePriceMIST);
return {
basePrice: basePriceMIST,
optimalPrice: optimalPrice,
strategy: strategy,
transactionType: transactionType,
multiplier: optimalPrice / basePriceMIST,
premiumPercent: ((optimalPrice - basePriceMIST) / basePriceMIST * 100).toFixed(1)
};
}
getTypeMultiplier(transactionType) {
const typeMultipliers = {
'transfer': 1.0,
'defi_swap': 1.2,
'nft_mint': 1.1,
'staking': 1.05,
'governance': 1.15,
'contract_deployment': 1.3,
'batch_operation': 1.25
};
return typeMultipliers[transactionType] || 1.0;
}
}
Gas Cost Budgeting Tool​
class GasCostBudgeter {
constructor(client) {
this.client = client;
this.monthlyBudget = 0;
this.currentSpending = 0;
this.plannedTransactions = [];
}
setMonthlyBudget(budgetSUI) {
this.monthlyBudget = budgetSUI * 1_000_000_000; // Convert to MIST
console.log(`Monthly gas budget set to ${budgetSUI} SUI`);
}
async planTransaction(type, gasUnits, urgency = 'normal') {
const gasPrice = await this.client.getReferenceGasPrice();
const strategy = new DynamicGasPriceStrategy(this.client);
const optimalPricing = await strategy.getOptimalGasPrice(urgency, type);
const estimatedCost = gasUnits * optimalPricing.optimalPrice;
const transaction = {
id: Date.now() + Math.random(),
type: type,
gasUnits: gasUnits,
urgency: urgency,
estimatedCost: estimatedCost,
estimatedCostSUI: estimatedCost / 1_000_000_000,
optimalGasPrice: optimalPricing.optimalPrice,
plannedAt: Date.now()
};
this.plannedTransactions.push(transaction);
return transaction;
}
getBudgetStatus() {
const totalPlanned = this.plannedTransactions.reduce(
(sum, tx) => sum + tx.estimatedCost, 0
);
const remaining = this.monthlyBudget - this.currentSpending - totalPlanned;
const utilizationPercent = ((this.currentSpending + totalPlanned) / this.monthlyBudget) * 100;
return {
monthlyBudgetSUI: this.monthlyBudget / 1_000_000_000,
currentSpendingSUI: this.currentSpending / 1_000_000_000,
plannedSpendingSUI: totalPlanned / 1_000_000_000,
remainingBudgetSUI: remaining / 1_000_000_000,
utilizationPercent: utilizationPercent,
plannedTransactions: this.plannedTransactions.length,
budgetStatus: utilizationPercent > 100 ? 'OVER_BUDGET' :
utilizationPercent > 80 ? 'BUDGET_WARNING' : 'BUDGET_OK'
};
}
async optimizePlannedTransactions() {
const optimizations = [];
for (const tx of this.plannedTransactions) {
const currentGasPrice = await this.client.getReferenceGasPrice();
const newEstimatedCost = tx.gasUnits * Number(currentGasPrice);
if (newEstimatedCost < tx.estimatedCost * 0.9) { // 10% savings
optimizations.push({
transactionId: tx.id,
type: tx.type,
currentEstimate: tx.estimatedCost,
newEstimate: newEstimatedCost,
savings: tx.estimatedCost - newEstimatedCost,
savingsPercent: ((tx.estimatedCost - newEstimatedCost) / tx.estimatedCost * 100).toFixed(1)
});
}
}
return optimizations;
}
}
Performance Optimization​
Gas Price Caching Strategy​
class GasPriceCacheManager {
constructor(client) {
this.client = client;
this.cache = new Map();
this.defaultTTL = 30000; // 30 seconds
this.maxCacheSize = 100;
}
async getGasPrice(useCache = true, ttl = this.defaultTTL) {
const cacheKey = 'reference_gas_price';
if (useCache) {
const cached = this.cache.get(cacheKey);
if (cached && (Date.now() - cached.timestamp) < ttl) {
return cached.value;
}
}
const gasPrice = await this.client.getReferenceGasPrice();
if (gasPrice) {
this.cache.set(cacheKey, {
value: gasPrice,
timestamp: Date.now()
});
// Clean cache if too large
if (this.cache.size > this.maxCacheSize) {
const oldest = Math.min(...Array.from(this.cache.values()).map(v => v.timestamp));
for (const [key, value] of this.cache.entries()) {
if (value.timestamp === oldest) {
this.cache.delete(key);
break;
}
}
}
}
return gasPrice;
}
clearCache() {
this.cache.clear();
}
getCacheStats() {
return {
size: this.cache.size,
maxSize: this.maxCacheSize,
entries: Array.from(this.cache.entries()).map(([key, value]) => ({
key,
age: Date.now() - value.timestamp,
value: value.value
}))
};
}
}
Error Handling​
async function safeGetReferenceGasPrice(client, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const gasPrice = await client.getReferenceGasPrice();
if (!gasPrice) {
throw new Error('No gas price returned');
}
// Validate gas price is reasonable
const gasPriceMIST = Number(gasPrice);
if (gasPriceMIST < 100 || gasPriceMIST > 10000) { // Reasonable bounds
console.warn(`Unusual gas price detected: ${gasPriceMIST} MIST`);
}
return { success: true, gasPrice: gasPrice };
} catch (error) {
console.warn(`Gas price query attempt ${attempt} failed:`, error.message);
if (attempt === maxRetries) {
return {
success: false,
error: error.message,
fallbackPrice: '1000' // Fallback to reasonable default
};
}
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}
Best Practices​
- Cache Gas Prices: Cache gas price for short periods to reduce RPC calls
- Monitor Price Changes: Set up alerts for significant gas price changes
- Use Appropriate Urgency: Don't overpay for gas unless transaction is urgent
- Budget Management: Track gas spending to avoid unexpected costs
- Batch Operations: Combine multiple operations to reduce per-transaction overhead
- Timing Optimization: Execute non-urgent transactions during low-price periods
Related Methods​
- sui_dryRunTransactionBlock - Estimate gas usage before execution
- sui_executeTransactionBlock - Execute transactions with gas
- suix_getLatestSuiSystemState - Get system state including gas information
Need help? Contact our support team or check the Sui documentation.