For the complete documentation index, see llms.txt. This page is also available as Markdown.
🔧Fee Market Module with Dynamic Fees
This guide explains how to use the feemarket module to implement dynamic fee calculation for standard Cosmos SDK transactions on the cheqd network. The feemarket module provides real-time gas pricing based on network congestion and demand.
Note: Identity transactions (DIDs and DID-Linked Resources) have their own fixed pricing model and are not affected by the feemarket module's dynamic pricing.
Understanding Dynamic Fees
Dynamic fees adjust transaction costs based on network conditions:
High Network Activity: Gas prices increase to prioritize transactions
Low Network Activity: Gas prices decrease to reduce transaction costs
Real-time Pricing: Prices update continuously based on network demand
Gas Price Endpoints
You can fetch current gas prices directly from the cheqd network APIs:
Mainnet
GET https://api.cheqd.net/feemarket/v1/gas_price/ncheq
Testnet
GET https://api.cheqd.network/feemarket/v1/gas_price/ncheq
API Response Format
The API returns a decimal value that needs to be converted:
async function monitorFeeMarket() {
const { sdk } = await initializeSDKWithFeemarket();
const feemarketModule = new FeemarketModule(sdk.signer, sdk.querier);
console.log('📊 Monitoring fee market...');
const monitorInterval = setInterval(async () => {
try {
const gasPrice = await feemarketModule.generateSafeGasPriceByDenom('ncheq');
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] Gas Price: ${gasPrice.amount}${gasPrice.denom}`);
// Alert if price is unusually high
if (parseInt(gasPrice.amount) > 10000) {
console.warn('⚠️ High network congestion detected!');
console.log('💡 Consider waiting for lower fees or using fee abstraction');
}
} catch (error) {
console.error('Error monitoring fees:', error);
}
}, 30000); // Check every 30 seconds
// Stop monitoring after 5 minutes
setTimeout(() => {
clearInterval(monitorInterval);
console.log('📊 Fee monitoring stopped');
}, 300000);
}
async function robustTransactionWithDynamicFees(messages: any[], sender: string) {
const { sdk } = await initializeSDKWithFeemarket();
const feemarketModule = new FeemarketModule(sdk.signer, sdk.querier);
let retries = 3;
while (retries > 0) {
try {
// Get fresh gas price for each attempt
const gasPrice = await feemarketModule.generateSafeGasPriceByDenom('ncheq');
const estimatedGas = await estimateOptimalGas(messages, sender);
const fee = FeemarketModule.generateFeesFromGasPrice(gasPrice, sender, estimatedGas);
const result = await sdk.signer.signAndBroadcast(
sender,
messages,
fee,
'Transaction with retry logic'
);
if (result.code === 0) {
console.log('✅ Transaction successful!');
return result;
} else {
throw new Error(`Transaction failed: ${result.rawLog}`);
}
} catch (error) {
retries--;
console.warn(`⚠️ Attempt failed, ${retries} retries left:`, error);
if (retries > 0) {
// Wait before retry with exponential backoff
await new Promise(resolve => setTimeout(resolve, (4 - retries) * 1000));
} else {
throw error;
}
}
}
}
async function handleTransactionErrors(result: any) {
switch (result.code) {
case 5:
console.error('❌ Insufficient funds for gas');
console.log('💡 Add more tokens to your account');
break;
case 11:
console.error('❌ Out of gas');
console.log('💡 Increase gas limit or optimize transaction');
break;
case 32:
console.error('❌ Account not found');
console.log('💡 Verify account address and funding');
break;
default:
console.error(`❌ Transaction failed with code ${result.code}`);
console.log(`Raw log: ${result.rawLog}`);
}
}