⚠️Blast API (blastapi.io) ends Oct 31. Migrate to Dwellir and skip Alchemy's expensive compute units.
Switch Today →
Skip to main content

wallet/freezebalancev2

Resource Management V2

Dwellir's TRON infrastructure supports the latest Stake 2.0 mechanism for efficient resource management. Stake TRX to get bandwidth/energy while earning rewards and voting rights.

Start staking TRX →

Freeze (stake) TRX balance to obtain bandwidth or energy resources using the Stake 2.0 mechanism. Staked TRX earns rewards and provides voting power for Super Representatives.

Use Cases

wallet/freezebalancev2 is essential for:

  • Resource Acquisition - Get bandwidth for transactions
  • Energy Generation - Power smart contract interactions
  • Reward Earning - Earn staking rewards (~4-7% APR)
  • Governance Participation - Gain voting power for SRs
  • DApp Operations - Ensure smooth contract execution

Parameters

ParameterTypeRequiredDescription
owner_addressstringYesAddress staking TRX (Base58 or Hex)
frozen_balancenumberYesAmount to stake in SUN (1 TRX = 1,000,000 SUN)
resourcestringYesResource type: "BANDWIDTH" or "ENERGY"
visiblebooleanNoUse Base58 format (default: true)
permission_idnumberNoPermission ID for multi-sig accounts

Request Example

{
"owner_address": "TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN",
"frozen_balance": 10000000000,
"resource": "ENERGY",
"visible": true
}

Response Fields

FieldTypeDescription
txidstringTransaction ID
visiblebooleanAddress format used
raw_dataobjectTransaction raw data
raw_data.contractarrayContract details
raw_data.ref_block_bytesstringReference block bytes
raw_data.ref_block_hashstringReference block hash
raw_data.expirationnumberTransaction expiration time
raw_data.timestampnumberTransaction timestamp

Implementation Examples

const TronWeb = require('tronweb');

class TronStakingManager {
constructor(apiKey, privateKey = null) {
this.apiUrl = `https://api-tron-mainnet.n.dwellir.com/${apiKey}`;
this.headers = { 'Content-Type': 'application/json' };
this.privateKey = privateKey;

// Initialize TronWeb for signing if private key provided
if (privateKey) {
this.tronWeb = new TronWeb({
fullHost: this.apiUrl,
privateKey: privateKey
});
}
}

// Create freeze balance v2 transaction
async createFreezeV2Transaction(address, amountTRX, resource = 'ENERGY') {
const amountSUN = amountTRX * 1_000_000; // Convert TRX to SUN

const response = await fetch(`${this.apiUrl}/wallet/freezebalancev2`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
owner_address: address,
frozen_balance: amountSUN,
resource: resource.toUpperCase(),
visible: true
})
});

if (!response.ok) {
throw new Error(`Freeze transaction failed: ${response.statusText}`);
}

return await response.json();
}

// Sign and broadcast transaction
async stakeAndBroadcast(address, amountTRX, resource = 'ENERGY') {
if (!this.privateKey) {
throw new Error('Private key required for signing');
}

// Create transaction
const transaction = await this.createFreezeV2Transaction(address, amountTRX, resource);

// Sign transaction
const signedTx = await this.tronWeb.trx.sign(transaction);

// Broadcast transaction
const result = await this.broadcastTransaction(signedTx);

return {
txid: result.txid,
success: result.result,
resource: resource,
amountTRX: amountTRX,
message: result.message || 'Transaction broadcast successfully'
};
}

async broadcastTransaction(signedTransaction) {
const response = await fetch(`${this.apiUrl}/wallet/broadcasttransaction`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(signedTransaction)
});

return await response.json();
}

// Calculate optimal stake amount
async calculateOptimalStake(address, dailyOperations = 100) {
// Get current account resources
const accountResource = await this.getAccountResource(address);

// Estimate required resources
const bandwidthPerTx = 250; // Average bandwidth per transaction
const energyPerContract = 50000; // Average energy per contract call

const dailyBandwidth = dailyOperations * bandwidthPerTx;
const dailyEnergy = dailyOperations * energyPerContract;

// Calculate TRX needed (approximate)
const trxForBandwidth = Math.ceil(dailyBandwidth / 1000); // ~1000 bandwidth per TRX
const trxForEnergy = Math.ceil(dailyEnergy / 280); // ~280 energy per TRX

return {
recommended: {
bandwidth: trxForBandwidth,
energy: trxForEnergy
},
current: {
bandwidth: accountResource.freeNetLimit || 0,
energy: accountResource.EnergyLimit || 0
},
dailyRequirement: {
bandwidth: dailyBandwidth,
energy: dailyEnergy
}
};
}

async getAccountResource(address) {
const response = await fetch(`${this.apiUrl}/wallet/getaccountresource`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
address: address,
visible: true
})
});

return await response.json();
}

// Batch stake for multiple resources
async stakeForResources(address, bandwidthTRX, energyTRX) {
const results = [];

if (bandwidthTRX > 0) {
try {
const bandwidthResult = await this.stakeAndBroadcast(
address,
bandwidthTRX,
'BANDWIDTH'
);
results.push({
type: 'BANDWIDTH',
success: true,
...bandwidthResult
});
} catch (error) {
results.push({
type: 'BANDWIDTH',
success: false,
error: error.message
});
}
}

if (energyTRX > 0) {
// Wait 3 seconds between transactions
await new Promise(resolve => setTimeout(resolve, 3000));

try {
const energyResult = await this.stakeAndBroadcast(
address,
energyTRX,
'ENERGY'
);
results.push({
type: 'ENERGY',
success: true,
...energyResult
});
} catch (error) {
results.push({
type: 'ENERGY',
success: false,
error: error.message
});
}
}

return results;
}

// Estimate staking rewards
estimateStakingRewards(amountTRX, durationDays = 365) {
const annualAPR = 0.05; // Approximate 5% APR
const dailyRate = annualAPR / 365;
const rewards = amountTRX * dailyRate * durationDays;

return {
amountStaked: amountTRX,
duration: durationDays,
estimatedRewards: rewards.toFixed(6),
apr: (annualAPR * 100).toFixed(2) + '%',
daily: (amountTRX * dailyRate).toFixed(6),
monthly: (amountTRX * dailyRate * 30).toFixed(6),
yearly: (amountTRX * annualAPR).toFixed(6)
};
}
}

// Resource Calculator
class ResourceCalculator {
constructor() {
this.rates = {
bandwidth: {
perTRX: 1000, // Approximate bandwidth per TRX
perTransaction: 250 // Average bandwidth per transaction
},
energy: {
perTRX: 280, // Approximate energy per TRX
perContractCall: 50000 // Average energy per smart contract call
}
};
}

calculateRequiredTRX(resourceType, amount) {
if (resourceType === 'BANDWIDTH') {
return Math.ceil(amount / this.rates.bandwidth.perTRX);
} else if (resourceType === 'ENERGY') {
return Math.ceil(amount / this.rates.energy.perTRX);
}
throw new Error('Invalid resource type');
}

estimateResourcesFromTRX(trxAmount, resourceType) {
if (resourceType === 'BANDWIDTH') {
return {
bandwidth: trxAmount * this.rates.bandwidth.perTRX,
transactions: Math.floor(
(trxAmount * this.rates.bandwidth.perTRX) /
this.rates.bandwidth.perTransaction
)
};
} else if (resourceType === 'ENERGY') {
return {
energy: trxAmount * this.rates.energy.perTRX,
contractCalls: Math.floor(
(trxAmount * this.rates.energy.perTRX) /
this.rates.energy.perContractCall
)
};
}
throw new Error('Invalid resource type');
}

getRecommendation(dailyTransactions, dailyContractCalls) {
const bandwidthNeeded = dailyTransactions * this.rates.bandwidth.perTransaction;
const energyNeeded = dailyContractCalls * this.rates.energy.perContractCall;

return {
bandwidth: {
required: bandwidthNeeded,
trxToStake: this.calculateRequiredTRX('BANDWIDTH', bandwidthNeeded),
dailyTransactions: dailyTransactions
},
energy: {
required: energyNeeded,
trxToStake: this.calculateRequiredTRX('ENERGY', energyNeeded),
dailyContractCalls: dailyContractCalls
},
total: {
trxRequired:
this.calculateRequiredTRX('BANDWIDTH', bandwidthNeeded) +
this.calculateRequiredTRX('ENERGY', energyNeeded)
}
};
}
}

// Usage examples
(async () => {
const staking = new TronStakingManager('YOUR_API_KEY', 'YOUR_PRIVATE_KEY');
const calculator = new ResourceCalculator();

try {
// Calculate resources needed
const recommendation = calculator.getRecommendation(
100, // Daily transactions
50 // Daily smart contract calls
);
console.log('Resource Recommendation:', recommendation);

// Estimate rewards
const rewards = staking.estimateStakingRewards(10000, 365);
console.log('Staking Rewards Estimate:', rewards);

// Calculate optimal stake
const optimal = await staking.calculateOptimalStake(
'TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN',
100
);
console.log('Optimal Stake:', optimal);

// Stake TRX for energy
const stakeResult = await staking.stakeAndBroadcast(
'TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN',
1000, // 1000 TRX
'ENERGY'
);
console.log('Stake Result:', stakeResult);

// Batch stake for both resources
const batchResult = await staking.stakeForResources(
'TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN',
500, // 500 TRX for bandwidth
1000 // 1000 TRX for energy
);
console.log('Batch Stake Results:', batchResult);

} catch (error) {
console.error('Error:', error);
}
})();

Response Example

Successful Response

{
"visible": true,
"txID": "7a2e5c8f9b3d1a4e6f8c2b5d9e1a3f7c4b8d2e6a9c3f5b8d1e4a7c9f2b5d8e",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"owner_address": "TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN",
"frozen_balance": 10000000000,
"resource": "ENERGY"
},
"type_url": "type.googleapis.com/protocol.FreezeBalanceV2Contract"
},
"type": "FreezeBalanceV2Contract"
}
],
"ref_block_bytes": "7ac7",
"ref_block_hash": "4d9bb8f8c9c59ac3",
"expiration": 1702456849000,
"timestamp": 1702456789000,
"fee_limit": 1000000000
},
"raw_data_hex": "0a0207ac722..."
}

Common Use Cases

1. Auto-Staking System

class AutoStakingSystem {
constructor(apiKey) {
this.staking = new TronStakingManager(apiKey);
this.minBalance = 1000; // Minimum TRX to keep unstaked
}

async autoStake(address, keepBalance = 1000) {
// Get current balance
const account = await this.getAccount(address);
const availableTRX = (account.balance / 1_000_000) - keepBalance;

if (availableTRX <= 0) {
return { message: 'Insufficient balance for staking' };
}

// Split 30% bandwidth, 70% energy (typical DApp usage)
const bandwidthTRX = Math.floor(availableTRX * 0.3);
const energyTRX = Math.floor(availableTRX * 0.7);

return await this.staking.stakeForResources(
address,
bandwidthTRX,
energyTRX
);
}
}

2. Resource Optimization

async function optimizeResources(address) {
const resources = await getAccountResource(address);

// Check utilization
const bandwidthUtil = resources.freeNetUsed / resources.freeNetLimit;
const energyUtil = resources.EnergyUsed / resources.EnergyLimit;

const recommendations = [];

if (bandwidthUtil > 0.8) {
recommendations.push({
action: 'STAKE',
resource: 'BANDWIDTH',
reason: 'High bandwidth utilization',
suggestedTRX: 1000
});
}

if (energyUtil > 0.8) {
recommendations.push({
action: 'STAKE',
resource: 'ENERGY',
reason: 'High energy utilization',
suggestedTRX: 5000
});
}

return recommendations;
}

3. Staking Pool Management

class StakingPool {
async distributeStakes(participants, totalTRX) {
const stakes = [];

for (const participant of participants) {
const share = (participant.contribution / 100) * totalTRX;

stakes.push({
address: participant.address,
amount: share,
resource: participant.preferredResource || 'ENERGY'
});
}

return this.executeStakes(stakes);
}
}

Resource Calculation

ResourceRateUsage
Bandwidth~1,000 per TRXRegular transactions
Energy~280 per TRXSmart contract calls
Voting Power1 vote per TRXSR voting

Staking Recommendations by Use Case

Use CaseBandwidth (TRX)Energy (TRX)Total
Basic Wallet1000100
DeFi User5005,0005,500
DApp Developer1,00020,00021,000
Exchange10,00050,00060,000

Error Handling

Error CodeDescriptionSolution
INVALID_RESOURCEInvalid resource typeUse "BANDWIDTH" or "ENERGY"
INSUFFICIENT_BALANCENot enough TRXCheck balance before staking
ACCOUNT_NOT_FOUNDAddress doesn't existVerify address validity
TAPOS_ERRORTransaction expiredRecreate with fresh block reference
async function safeStake(address, amount, resource) {
try {
// Check balance first
const account = await getAccount(address);
const balance = account.balance / 1_000_000;

if (balance < amount) {
throw new Error(`Insufficient balance: ${balance} TRX available`);
}

// Validate resource type
if (!['BANDWIDTH', 'ENERGY'].includes(resource)) {
throw new Error(`Invalid resource: ${resource}`);
}

// Create and return transaction
return await createFreezeTransaction(address, amount, resource);

} catch (error) {
console.error('Staking error:', error);
return {
success: false,
error: error.message
};
}
}

Best Practices

  1. Keep Reserve - Always keep 50-100 TRX unstaked for fees
  2. Balance Resources - Monitor usage and adjust stakes accordingly
  3. Batch Operations - Stake for both resources in one session
  4. Monitor Rewards - Track staking rewards and compound regularly
  5. Plan Unstaking - Remember 14-day waiting period for unstaking

Notes

  • Lock Period: Staked TRX has a minimum 14-day lock period
  • Rewards: Staking rewards are distributed every 6 hours
  • Voting Power: Staked TRX provides voting power for Super Representatives
  • Resource Recovery: Bandwidth recovers 24 hours, energy recovers based on consumption

Need help? Contact support or visit our TRON documentation.