wallet/undelegateresource
Reclaim previously delegated bandwidth or energy resources from another account.
Endpoint
POST /wallet/undelegateresource
Parameters
Required Parameters
Parameter | Type | Description |
---|---|---|
owner_address | string | Account address that delegated resources (base58) |
receiver_address | string | Account that received delegated resources (base58) |
balance | number | Amount to undelegate in SUN (1 TRX = 1,000,000 SUN) |
resource | string | Resource type: "BANDWIDTH" or "ENERGY" |
Optional Parameters
Parameter | Type | Description |
---|---|---|
permission_id | number | Permission ID for multi-signature (default: 0) |
visible | boolean | Return base58 addresses (default: false returns hex) |
Response
Returns unsigned transaction containing the undelegation operation. Transaction must be signed and broadcast.
Response Fields
txID
- Transaction hashraw_data
- Transaction raw datacontract
- Undelegation contract detailsexpiration
- Transaction expiration timestamptimestamp
- Transaction creation timestamp
visible
- Address format indicator
Important Notes
Undelegation Rules
- Lock Period Check: Cannot undelegate if resources are locked
- Immediate Effect: Resources return to owner immediately after confirmation
- Partial Undelegation: Can undelegate portions of delegated amount
- Resource Availability: Reclaimed resources are immediately available to owner
- No Waiting Period: Unlike unstaking, undelegation has no waiting period
Key Differences from Unstaking
- Undelegation: Returns delegated resources to owner (immediate)
- Unstaking: Converts staked TRX back to liquid (14-day wait)
Implementation Examples
- JavaScript
- Python
- cURL
class TronUndelegationManager {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = `https://api-tron-mainnet.n.dwellir.com/${apiKey}`;
}
// Create undelegation transaction
async undelegateResources(ownerAddress, receiverAddress, amountTRX, resourceType) {
const response = await fetch(`${this.baseUrl}/wallet/undelegateresource`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
owner_address: ownerAddress,
receiver_address: receiverAddress,
balance: amountTRX * 1000000, // Convert TRX to SUN
resource: resourceType,
visible: true
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Undelegation failed: ${error.message || response.statusText}`);
}
return response.json();
}
// Get all active delegations from owner
async getActiveDelegations(ownerAddress) {
const response = await fetch(`${this.baseUrl}/wallet/getdelegatedresourceaccountindex`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
value: ownerAddress,
visible: true
})
});
const index = await response.json();
const delegations = [];
if (index.toAccounts) {
for (const receiverAddress of index.toAccounts) {
const detail = await this.getDelegationDetail(ownerAddress, receiverAddress);
delegations.push({
receiver: receiverAddress,
...this.parseDelegationDetail(detail)
});
}
}
return delegations;
}
// Get delegation detail between two accounts
async getDelegationDetail(fromAddress, toAddress) {
const response = await fetch(`${this.baseUrl}/wallet/getdelegatedresource`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fromAddress: fromAddress,
toAddress: toAddress,
visible: true
})
});
return response.json();
}
// Parse delegation details
parseDelegationDetail(detail) {
const delegatedResource = detail.delegatedResource || [];
let energyDelegated = 0;
let bandwidthDelegated = 0;
let energyExpireTime = null;
let bandwidthExpireTime = null;
for (const resource of delegatedResource) {
if (resource.frozen_balance_for_energy) {
energyDelegated = resource.frozen_balance_for_energy / 1000000; // Convert to TRX
energyExpireTime = resource.expire_time_for_energy
? new Date(resource.expire_time_for_energy)
: null;
}
if (resource.frozen_balance_for_bandwidth) {
bandwidthDelegated = resource.frozen_balance_for_bandwidth / 1000000; // Convert to TRX
bandwidthExpireTime = resource.expire_time_for_bandwidth
? new Date(resource.expire_time_for_bandwidth)
: null;
}
}
return {
energy: {
amount: energyDelegated,
locked: energyExpireTime && energyExpireTime > new Date(),
expireTime: energyExpireTime
},
bandwidth: {
amount: bandwidthDelegated,
locked: bandwidthExpireTime && bandwidthExpireTime > new Date(),
expireTime: bandwidthExpireTime
}
};
}
// Check if undelegation is possible
async canUndelegate(ownerAddress, receiverAddress, resourceType) {
const detail = await this.getDelegationDetail(ownerAddress, receiverAddress);
const parsed = this.parseDelegationDetail(detail);
const resource = resourceType.toLowerCase();
const delegation = parsed[resource];
if (!delegation || delegation.amount === 0) {
return {
canUndelegate: false,
reason: 'No resources delegated',
amount: 0
};
}
if (delegation.locked) {
const remainingTime = delegation.expireTime - new Date();
const days = Math.ceil(remainingTime / (1000 * 60 * 60 * 24));
return {
canUndelegate: false,
reason: `Resources locked for ${days} more days`,
amount: delegation.amount,
unlockTime: delegation.expireTime
};
}
return {
canUndelegate: true,
amount: delegation.amount,
reason: 'Ready to undelegate'
};
}
// Batch undelegate from multiple receivers
async batchUndelegate(ownerAddress, undelegations) {
const results = [];
for (const undelegation of undelegations) {
try {
// Check if can undelegate first
const check = await this.canUndelegate(
ownerAddress,
undelegation.receiver,
undelegation.resource
);
if (!check.canUndelegate) {
results.push({
success: false,
receiver: undelegation.receiver,
resource: undelegation.resource,
reason: check.reason
});
continue;
}
// Proceed with undelegation
const tx = await this.undelegateResources(
ownerAddress,
undelegation.receiver,
undelegation.amount || check.amount,
undelegation.resource
);
results.push({
success: true,
receiver: undelegation.receiver,
resource: undelegation.resource,
amount: undelegation.amount || check.amount,
txID: tx.txID,
transaction: tx
});
} catch (error) {
results.push({
success: false,
receiver: undelegation.receiver,
resource: undelegation.resource,
error: error.message
});
}
}
return results;
}
// Reclaim all unlocked delegations
async reclaimAllUnlocked(ownerAddress) {
const delegations = await this.getActiveDelegations(ownerAddress);
const toReclaim = [];
for (const delegation of delegations) {
// Check energy delegation
if (delegation.energy.amount > 0 && !delegation.energy.locked) {
toReclaim.push({
receiver: delegation.receiver,
resource: 'ENERGY',
amount: delegation.energy.amount
});
}
// Check bandwidth delegation
if (delegation.bandwidth.amount > 0 && !delegation.bandwidth.locked) {
toReclaim.push({
receiver: delegation.receiver,
resource: 'BANDWIDTH',
amount: delegation.bandwidth.amount
});
}
}
if (toReclaim.length === 0) {
return {
message: 'No unlocked delegations to reclaim',
transactions: []
};
}
const results = await this.batchUndelegate(ownerAddress, toReclaim);
return {
message: `Reclaiming ${toReclaim.length} delegations`,
transactions: results
};
}
}
// Resource optimization strategies
class ResourceOptimizer {
constructor(manager) {
this.manager = manager;
}
// Analyze delegation efficiency
async analyzeDelegationEfficiency(ownerAddress) {
const delegations = await this.manager.getActiveDelegations(ownerAddress);
const analysis = [];
for (const delegation of delegations) {
// Get receiver's current resource usage
const resourceResponse = await fetch(
`${this.manager.baseUrl}/wallet/getaccountresource`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
address: delegation.receiver,
visible: true
})
}
);
const resources = await resourceResponse.json();
// Calculate efficiency metrics
const energyEfficiency = resources.EnergyUsed
? (resources.EnergyUsed / resources.EnergyLimit) * 100
: 0;
const bandwidthEfficiency = resources.NetUsed
? (resources.NetUsed / resources.NetLimit) * 100
: 0;
analysis.push({
receiver: delegation.receiver,
energy: {
delegated: delegation.energy.amount,
efficiency: energyEfficiency.toFixed(2) + '%',
recommendation: energyEfficiency < 50
? 'Consider reducing delegation'
: 'Delegation well utilized'
},
bandwidth: {
delegated: delegation.bandwidth.amount,
efficiency: bandwidthEfficiency.toFixed(2) + '%',
recommendation: bandwidthEfficiency < 50
? 'Consider reducing delegation'
: 'Delegation well utilized'
}
});
}
return analysis;
}
// Optimize delegations by reclaiming underutilized resources
async optimizeDelegations(ownerAddress, utilizationThreshold = 30) {
const analysis = await this.analyzeDelegationEfficiency(ownerAddress);
const toReclaim = [];
for (const item of analysis) {
// Check energy utilization
const energyUtilization = parseFloat(item.energy.efficiency);
if (energyUtilization < utilizationThreshold && item.energy.delegated > 0) {
// Calculate amount to reclaim (keep some buffer)
const reclaimAmount = item.energy.delegated * (1 - energyUtilization / 100) * 0.8;
toReclaim.push({
receiver: item.receiver,
resource: 'ENERGY',
amount: Math.floor(reclaimAmount),
reason: `Low utilization: ${item.energy.efficiency}`
});
}
// Check bandwidth utilization
const bandwidthUtilization = parseFloat(item.bandwidth.efficiency);
if (bandwidthUtilization < utilizationThreshold && item.bandwidth.delegated > 0) {
// Calculate amount to reclaim
const reclaimAmount = item.bandwidth.delegated * (1 - bandwidthUtilization / 100) * 0.8;
toReclaim.push({
receiver: item.receiver,
resource: 'BANDWIDTH',
amount: Math.floor(reclaimAmount),
reason: `Low utilization: ${item.bandwidth.efficiency}`
});
}
}
if (toReclaim.length === 0) {
return {
message: 'All delegations are efficiently utilized',
optimizations: []
};
}
const results = await this.manager.batchUndelegate(ownerAddress, toReclaim);
return {
message: `Optimizing ${toReclaim.length} inefficient delegations`,
optimizations: results
};
}
}
// Example usage
async function manageUndelegation() {
const manager = new TronUndelegationManager('YOUR_API_KEY');
const optimizer = new ResourceOptimizer(manager);
try {
// 1. Simple undelegation
console.log('=== Simple Undelegation ===');
const simpleTx = await manager.undelegateResources(
'TOwnerAddress...',
'TReceiverAddress...',
1000, // 1000 TRX
'ENERGY'
);
console.log('Transaction ID:', simpleTx.txID);
// 2. Check if can undelegate
console.log('\n=== Checking Undelegation Status ===');
const canUndelegate = await manager.canUndelegate(
'TOwnerAddress...',
'TReceiverAddress...',
'ENERGY'
);
console.log('Can undelegate:', canUndelegate);
// 3. Get all active delegations
console.log('\n=== Active Delegations ===');
const activeDelegations = await manager.getActiveDelegations('TOwnerAddress...');
for (const delegation of activeDelegations) {
console.log(`To ${delegation.receiver}:`);
console.log(` Energy: ${delegation.energy.amount} TRX (${delegation.energy.locked ? 'LOCKED' : 'UNLOCKED'})`);
console.log(` Bandwidth: ${delegation.bandwidth.amount} TRX (${delegation.bandwidth.locked ? 'LOCKED' : 'UNLOCKED'})`);
}
// 4. Reclaim all unlocked delegations
console.log('\n=== Reclaiming All Unlocked ===');
const reclaimResults = await manager.reclaimAllUnlocked('TOwnerAddress...');
console.log(reclaimResults.message);
for (const tx of reclaimResults.transactions) {
if (tx.success) {
console.log(`✓ Reclaimed ${tx.amount} TRX ${tx.resource} from ${tx.receiver}`);
} else {
console.log(`✗ Failed to reclaim from ${tx.receiver}: ${tx.reason || tx.error}`);
}
}
// 5. Optimize delegations
console.log('\n=== Delegation Optimization ===');
const optimization = await optimizer.optimizeDelegations('TOwnerAddress...', 30);
console.log(optimization.message);
for (const opt of optimization.optimizations) {
if (opt.success) {
console.log(`✓ Optimized: Reclaimed ${opt.amount} TRX ${opt.resource} from ${opt.receiver}`);
} else {
console.log(`✗ Could not optimize ${opt.receiver}: ${opt.reason}`);
}
}
} catch (error) {
console.error('Undelegation error:', error);
}
}
import requests
import json
from datetime import datetime
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
@dataclass
class UndelegationRequest:
receiver: str
resource: str
amount: Optional[float] = None # If None, undelegate all
class TronUndelegationManager:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = f"https://api-tron-mainnet.n.dwellir.com/{api_key}"
def undelegate_resources(
self,
owner_address: str,
receiver_address: str,
amount_trx: float,
resource: str
) -> Dict:
"""Create an undelegation transaction"""
response = requests.post(
f"{self.base_url}/wallet/undelegateresource",
json={
"owner_address": owner_address,
"receiver_address": receiver_address,
"balance": int(amount_trx * 1_000_000), # Convert to SUN
"resource": resource,
"visible": True
}
)
response.raise_for_status()
return response.json()
def get_delegation_index(self, owner_address: str) -> List[str]:
"""Get list of accounts that have received delegations"""
response = requests.post(
f"{self.base_url}/wallet/getdelegatedresourceaccountindex",
json={
"value": owner_address,
"visible": True
}
)
response.raise_for_status()
data = response.json()
return data.get('toAccounts', [])
def get_delegation_detail(
self,
from_address: str,
to_address: str
) -> Tuple[Dict, Dict]:
"""Get detailed delegation info between accounts"""
response = requests.post(
f"{self.base_url}/wallet/getdelegatedresource",
json={
"fromAddress": from_address,
"toAddress": to_address,
"visible": True
}
)
response.raise_for_status()
data = response.json()
delegated_resources = data.get('delegatedResource', [])
energy_info = {'amount': 0, 'locked': False, 'expire_time': None}
bandwidth_info = {'amount': 0, 'locked': False, 'expire_time': None}
for resource in delegated_resources:
if 'frozen_balance_for_energy' in resource:
energy_info['amount'] = resource['frozen_balance_for_energy'] / 1_000_000
if 'expire_time_for_energy' in resource:
expire_time = datetime.fromtimestamp(resource['expire_time_for_energy'] / 1000)
energy_info['locked'] = expire_time > datetime.now()
energy_info['expire_time'] = expire_time
if 'frozen_balance_for_bandwidth' in resource:
bandwidth_info['amount'] = resource['frozen_balance_for_bandwidth'] / 1_000_000
if 'expire_time_for_bandwidth' in resource:
expire_time = datetime.fromtimestamp(resource['expire_time_for_bandwidth'] / 1000)
bandwidth_info['locked'] = expire_time > datetime.now()
bandwidth_info['expire_time'] = expire_time
return energy_info, bandwidth_info
def check_undelegation_status(
self,
owner_address: str,
receiver_address: str,
resource: str
) -> Dict:
"""Check if undelegation is possible"""
energy_info, bandwidth_info = self.get_delegation_detail(
owner_address,
receiver_address
)
info = energy_info if resource == "ENERGY" else bandwidth_info
if info['amount'] == 0:
return {
'can_undelegate': False,
'reason': f'No {resource} delegated to this address',
'amount': 0
}
if info['locked']:
days_remaining = (info['expire_time'] - datetime.now()).days
return {
'can_undelegate': False,
'reason': f'Locked for {days_remaining} more days',
'amount': info['amount'],
'unlock_time': info['expire_time']
}
return {
'can_undelegate': True,
'reason': 'Ready to undelegate',
'amount': info['amount']
}
def get_all_delegations(self, owner_address: str) -> List[Dict]:
"""Get all active delegations with details"""
receivers = self.get_delegation_index(owner_address)
delegations = []
for receiver in receivers:
energy_info, bandwidth_info = self.get_delegation_detail(
owner_address,
receiver
)
delegations.append({
'receiver': receiver,
'energy': energy_info,
'bandwidth': bandwidth_info,
'total_delegated': energy_info['amount'] + bandwidth_info['amount']
})
return delegations
def batch_undelegate(
self,
owner_address: str,
requests: List[UndelegationRequest]
) -> List[Dict]:
"""Execute multiple undelegations"""
results = []
for req in requests:
try:
# Check status first
status = self.check_undelegation_status(
owner_address,
req.receiver,
req.resource
)
if not status['can_undelegate']:
results.append({
'success': False,
'receiver': req.receiver,
'resource': req.resource,
'reason': status['reason']
})
continue
# Determine amount
amount = req.amount if req.amount else status['amount']
# Execute undelegation
tx = self.undelegate_resources(
owner_address,
req.receiver,
amount,
req.resource
)
results.append({
'success': True,
'receiver': req.receiver,
'resource': req.resource,
'amount': amount,
'txID': tx['txID']
})
except Exception as e:
results.append({
'success': False,
'receiver': req.receiver,
'resource': req.resource,
'error': str(e)
})
return results
def reclaim_all_unlocked(self, owner_address: str) -> Dict:
"""Reclaim all unlocked delegations"""
delegations = self.get_all_delegations(owner_address)
requests = []
for delegation in delegations:
# Check energy
if delegation['energy']['amount'] > 0 and not delegation['energy']['locked']:
requests.append(UndelegationRequest(
receiver=delegation['receiver'],
resource='ENERGY',
amount=delegation['energy']['amount']
))
# Check bandwidth
if delegation['bandwidth']['amount'] > 0 and not delegation['bandwidth']['locked']:
requests.append(UndelegationRequest(
receiver=delegation['receiver'],
resource='BANDWIDTH',
amount=delegation['bandwidth']['amount']
))
if not requests:
return {
'message': 'No unlocked delegations to reclaim',
'total_reclaimed': 0,
'transactions': []
}
results = self.batch_undelegate(owner_address, requests)
total_reclaimed = sum(
r['amount'] for r in results if r['success']
)
return {
'message': f'Reclaimed {len(requests)} delegations',
'total_reclaimed': total_reclaimed,
'transactions': results
}
class DelegationAnalyzer:
"""Analyze and optimize delegation efficiency"""
def __init__(self, manager: TronUndelegationManager):
self.manager = manager
def analyze_utilization(
self,
owner_address: str
) -> List[Dict]:
"""Analyze delegation utilization rates"""
delegations = self.manager.get_all_delegations(owner_address)
analysis = []
for delegation in delegations:
# Get receiver's resource usage
response = requests.post(
f"{self.manager.base_url}/wallet/getaccountresource",
json={
"address": delegation['receiver'],
"visible": True
}
)
resources = response.json()
# Calculate utilization
energy_used = resources.get('EnergyUsed', 0)
energy_limit = resources.get('EnergyLimit', 0)
net_used = resources.get('NetUsed', 0)
net_limit = resources.get('NetLimit', 0)
energy_utilization = (energy_used / energy_limit * 100) if energy_limit > 0 else 0
bandwidth_utilization = (net_used / net_limit * 100) if net_limit > 0 else 0
analysis.append({
'receiver': delegation['receiver'],
'energy': {
'delegated_trx': delegation['energy']['amount'],
'utilization': f"{energy_utilization:.1f}%",
'utilization_rate': energy_utilization,
'locked': delegation['energy']['locked']
},
'bandwidth': {
'delegated_trx': delegation['bandwidth']['amount'],
'utilization': f"{bandwidth_utilization:.1f}%",
'utilization_rate': bandwidth_utilization,
'locked': delegation['bandwidth']['locked']
}
})
return analysis
def recommend_optimizations(
self,
owner_address: str,
min_utilization: float = 30.0
) -> List[Dict]:
"""Recommend delegations to reclaim based on utilization"""
analysis = self.analyze_utilization(owner_address)
recommendations = []
for item in analysis:
# Energy recommendations
if (item['energy']['delegated_trx'] > 0 and
item['energy']['utilization_rate'] < min_utilization and
not item['energy']['locked']):
recommendations.append({
'action': 'RECLAIM',
'receiver': item['receiver'],
'resource': 'ENERGY',
'amount': item['energy']['delegated_trx'],
'reason': f"Low utilization: {item['energy']['utilization']}",
'potential_savings': item['energy']['delegated_trx']
})
# Bandwidth recommendations
if (item['bandwidth']['delegated_trx'] > 0 and
item['bandwidth']['utilization_rate'] < min_utilization and
not item['bandwidth']['locked']):
recommendations.append({
'action': 'RECLAIM',
'receiver': item['receiver'],
'resource': 'BANDWIDTH',
'amount': item['bandwidth']['delegated_trx'],
'reason': f"Low utilization: {item['bandwidth']['utilization']}",
'potential_savings': item['bandwidth']['delegated_trx']
})
total_savings = sum(r['potential_savings'] for r in recommendations)
return {
'recommendations': recommendations,
'total_potential_savings': total_savings,
'summary': f"Can reclaim {total_savings:.2f} TRX from {len(recommendations)} inefficient delegations"
}
# Example usage
def main():
manager = TronUndelegationManager('YOUR_API_KEY')
analyzer = DelegationAnalyzer(manager)
owner_address = 'TOwnerAddress...'
# 1. View all delegations
print("=== Current Delegations ===")
delegations = manager.get_all_delegations(owner_address)
for d in delegations:
print(f"\nTo: {d['receiver']}")
print(f" Energy: {d['energy']['amount']:.2f} TRX",
"(LOCKED)" if d['energy']['locked'] else "(UNLOCKED)")
print(f" Bandwidth: {d['bandwidth']['amount']:.2f} TRX",
"(LOCKED)" if d['bandwidth']['locked'] else "(UNLOCKED)")
print(f" Total: {d['total_delegated']:.2f} TRX")
# 2. Check specific undelegation
print("\n=== Undelegation Status Check ===")
status = manager.check_undelegation_status(
owner_address,
'TReceiverAddress...',
'ENERGY'
)
print(f"Can undelegate: {status['can_undelegate']}")
print(f"Reason: {status['reason']}")
print(f"Amount available: {status['amount']:.2f} TRX")
# 3. Analyze utilization
print("\n=== Delegation Utilization Analysis ===")
utilization = analyzer.analyze_utilization(owner_address)
for u in utilization:
print(f"\n{u['receiver']}:")
print(f" Energy: {u['energy']['delegated_trx']:.2f} TRX @ {u['energy']['utilization']} usage")
print(f" Bandwidth: {u['bandwidth']['delegated_trx']:.2f} TRX @ {u['bandwidth']['utilization']} usage")
# 4. Get optimization recommendations
print("\n=== Optimization Recommendations ===")
recommendations = analyzer.recommend_optimizations(owner_address, 30.0)
print(recommendations['summary'])
for rec in recommendations['recommendations']:
print(f"\n • {rec['action']}: {rec['resource']} from {rec['receiver']}")
print(f" Amount: {rec['amount']:.2f} TRX")
print(f" Reason: {rec['reason']}")
# 5. Reclaim all unlocked
print("\n=== Reclaiming Unlocked Delegations ===")
reclaim_result = manager.reclaim_all_unlocked(owner_address)
print(reclaim_result['message'])
print(f"Total reclaimed: {reclaim_result['total_reclaimed']:.2f} TRX")
for tx in reclaim_result['transactions']:
if tx['success']:
print(f" ✓ {tx['resource']} from {tx['receiver']}: {tx['amount']:.2f} TRX")
else:
print(f" ✗ {tx['resource']} from {tx['receiver']}: {tx.get('reason', tx.get('error'))}")
if __name__ == "__main__":
main()
# Basic undelegation of energy
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/undelegateresource \
-H "Content-Type: application/json" \
-d '{
"owner_address": "TOwnerAddress...",
"receiver_address": "TReceiverAddress...",
"balance": 1000000000,
"resource": "ENERGY",
"visible": true
}'
# Undelegate bandwidth
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/undelegateresource \
-H "Content-Type: application/json" \
-d '{
"owner_address": "TOwnerAddress...",
"receiver_address": "TReceiverAddress...",
"balance": 500000000,
"resource": "BANDWIDTH",
"visible": true
}'
# Check delegation index (to find all delegations)
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/getdelegatedresourceaccountindex \
-H "Content-Type: application/json" \
-d '{
"value": "TOwnerAddress...",
"visible": true
}'
# Get specific delegation details
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/getdelegatedresource \
-H "Content-Type: application/json" \
-d '{
"fromAddress": "TOwnerAddress...",
"toAddress": "TReceiverAddress...",
"visible": true
}'
# Check receiver's resource usage (to analyze efficiency)
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/getaccountresource \
-H "Content-Type: application/json" \
-d '{
"address": "TReceiverAddress...",
"visible": true
}'
Example Response
{
"visible": true,
"txID": "a9f4d3c2b1e8a7d6c5e4f3b2a1d9c8e7f6b5a4d3c2e1f9a8b7c6d5e4f3a2b1c8",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"owner_address": "TOwnerAddress...",
"receiver_address": "TReceiverAddress...",
"balance": 1000000000,
"resource": "ENERGY"
},
"type_url": "type.googleapis.com/protocol.UnDelegateResourceContract"
},
"type": "UnDelegateResourceContract"
}
],
"ref_block_bytes": "7c6d",
"ref_block_hash": "5e4f9b8a7c6d5e3f",
"expiration": 1702456849000,
"timestamp": 1702456789000
}
}
Undelegation Process Flow
graph LR
A[Delegated Resources] --> B{Check Lock Status}
B -->|Locked| C[Wait for Unlock]
B -->|Unlocked| D[Initiate Undelegation]
C --> D
D --> E[Sign Transaction]
E --> F[Broadcast]
F --> G[Resources Returned to Owner]
style A fill:#2196F3
style B fill:#FF9800
style G fill:#4CAF50
Best Practices
1. Check Lock Status First
// Always check before attempting undelegation
const status = await checkUndelegationStatus(owner, receiver, resource);
if (!status.canUndelegate) {
console.log(`Cannot undelegate: ${status.reason}`);
return;
}
2. Monitor Utilization
- Regularly check delegation efficiency
- Reclaim underutilized resources
- Redistribute based on actual needs
3. Batch Operations
- Group multiple undelegations together
- Reduces transaction costs
- Easier to manage
4. Grace Period Management
- Track lock expiration dates
- Set reminders for locked delegations
- Plan undelegations in advance
Common Errors
Error | Description | Solution |
---|---|---|
No delegation found | No resources delegated to receiver | Check delegation status first |
Delegation is locked | Resources are locked for period | Wait for lock period to expire |
Insufficient delegated balance | Trying to undelegate more than delegated | Check current delegation amount |
Invalid resource type | Must be BANDWIDTH or ENERGY | Use correct resource string |
Use Cases
- Resource Reallocation: Move resources to more active users
- Cost Optimization: Reclaim resources from inactive accounts
- Emergency Recovery: Quickly reclaim resources when needed
- Delegation Cleanup: Remove old or unnecessary delegations
- Efficiency Management: Optimize resource distribution based on usage
Related Methods
- wallet/delegateresource - Delegate resources to others
- wallet/freezebalancev2 - Stake TRX for resources
- wallet/unfreezebalancev2 - Unstake TRX resources