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

wallet/votewitnessaccount

Vote for Super Representatives using TRX voting power from frozen balance.

Endpoint

POST /wallet/votewitnessaccount

Parameters

Required Parameters

ParameterTypeDescription
owner_addressstringVoter's account address (base58)
votesarrayArray of vote objects with SR address and vote count

Vote Object Structure

FieldTypeDescription
vote_addressstringSuper Representative address
vote_countnumberNumber of votes to cast

Optional Parameters

ParameterTypeDescription
permission_idnumberPermission ID for multi-signature (default: 0)
visiblebooleanReturn base58 addresses (default: false returns hex)

Response

Returns unsigned transaction containing the voting operation. Transaction must be signed and broadcast.

Response Fields

  • txID - Transaction hash
  • raw_data - Transaction raw data
    • contract - Voting contract details
    • expiration - Transaction expiration timestamp
    • timestamp - Transaction creation timestamp
  • visible - Address format indicator

Important Notes

Voting Rules

  1. Voting Power: 1 frozen TRX = 1 vote
  2. Vote Distribution: Can split votes among multiple SRs
  3. Vote Persistence: Votes remain until changed or TRX unfrozen
  4. Immediate Effect: Votes count immediately after confirmation
  5. Rewards: Voting rewards distributed daily based on SR performance

Implementation Examples

// Vote for single SR
const response = await fetch('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
owner_address: 'TVoterAddress...',
votes: [
{
vote_address: 'TSRAddress...',
vote_count: 1000000 // 1M votes
}
],
visible: true
}),
});

const transaction = await response.json();
console.log('Vote transaction created:', transaction.txID);

// Vote for multiple SRs
const multiVoteResponse = await fetch('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
owner_address: 'TVoterAddress...',
votes: [
{
vote_address: 'TSR1Address...',
vote_count: 500000
},
{
vote_address: 'TSR2Address...',
vote_count: 300000
},
{
vote_address: 'TSR3Address...',
vote_count: 200000
}
],
visible: true
}),
});

const multiVoteTx = await multiVoteResponse.json();
console.log('Multi-vote transaction:', multiVoteTx.txID);

// Clear all votes (vote with empty array)
const clearVotesResponse = await fetch('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
owner_address: 'TVoterAddress...',
votes: [],
visible: true
}),
});

Example Response

{
"visible": true,
"txID": "f9e8d7c6b5a4e3d2c1b0a9f8e7d6c5b4a3d2c1e0f9e8d7c6b5a4e3d2c1b0a9f8",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"owner_address": "TVoterAddress...",
"votes": [
{
"vote_address": "TSRAddress...",
"vote_count": 1000000
}
]
},
"type_url": "type.googleapis.com/protocol.VoteWitnessContract"
},
"type": "VoteWitnessContract"
}
],
"ref_block_bytes": "8d7e",
"ref_block_hash": "6f5a9b8c7d6e5f4a",
"expiration": 1702456849000,
"timestamp": 1702456789000
}
}

Voting Strategies

class VotingStrategy {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = `https://api-tron-mainnet.n.dwellir.com/${apiKey}`;
}

// Get available voting power
async getVotingPower(address) {
const response = await fetch(`${this.baseUrl}/wallet/getaccount`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ address, visible: true })
});

const account = await response.json();
const frozenTRX = account.frozen?.[0]?.frozen_balance || 0;
return frozenTRX / 1000000; // Convert to TRX
}

// Calculate optimal vote distribution
async optimizeVotes(voterAddress, srAddresses, strategy = 'balanced') {
const votingPower = await this.getVotingPower(voterAddress);

if (strategy === 'balanced') {
// Equal distribution
const votePerSR = Math.floor(votingPower / srAddresses.length);
return srAddresses.map(sr => ({
vote_address: sr,
vote_count: votePerSR
}));
} else if (strategy === 'weighted') {
// Weighted by SR performance
const witnesses = await this.getWitnesses();
const selectedSRs = witnesses.filter(w => srAddresses.includes(w.address));

// Weight by reliability
const totalReliability = selectedSRs.reduce((sum, sr) => {
const reliability = sr.totalProduced / (sr.totalProduced + sr.totalMissed);
return sum + reliability;
}, 0);

return selectedSRs.map(sr => {
const reliability = sr.totalProduced / (sr.totalProduced + sr.totalMissed);
const weight = reliability / totalReliability;
return {
vote_address: sr.address,
vote_count: Math.floor(votingPower * weight)
};
});
}
}

// Get current votes
async getCurrentVotes(address) {
const response = await fetch(`${this.baseUrl}/wallet/getaccount`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ address, visible: true })
});

const account = await response.json();
return account.votes || [];
}

// Estimate voting rewards
async estimateRewards(voterAddress) {
const votes = await this.getCurrentVotes(voterAddress);
const witnesses = await this.getWitnesses();

let estimatedDaily = 0;

for (const vote of votes) {
const sr = witnesses.find(w => w.address === vote.vote_address);
if (sr && sr.brokerage) {
// SR shares (100 - brokerage)% of rewards with voters
const rewardShare = (100 - sr.brokerage) / 100;
const srDailyReward = 16 * 20 * 60 * 24; // 16 TRX per block
const voterShare = (vote.vote_count / sr.voteCount) * srDailyReward * rewardShare;
estimatedDaily += voterShare;
}
}

return {
daily: estimatedDaily,
monthly: estimatedDaily * 30,
yearly: estimatedDaily * 365,
apy: (estimatedDaily * 365 / (votes.reduce((sum, v) => sum + v.vote_count, 0) / 1000000)) * 100
};
}
}

// Example usage
async function manageVoting() {
const strategy = new VotingStrategy('YOUR_API_KEY');

// Check voting power
const power = await strategy.getVotingPower('TVoterAddress...');
console.log(`Available voting power: ${power} TRX`);

// Optimize vote distribution
const srList = ['TSR1...', 'TSR2...', 'TSR3...'];
const optimizedVotes = await strategy.optimizeVotes(
'TVoterAddress...',
srList,
'weighted'
);

console.log('Optimized vote distribution:', optimizedVotes);

// Estimate rewards
const rewards = await strategy.estimateRewards('TVoterAddress...');
console.log(`Estimated APY: ${rewards.apy.toFixed(2)}%`);
}

Best Practices

1. Research Before Voting

  • Check SR reliability (>99.5% uptime)
  • Review SR contributions to ecosystem
  • Verify reward distribution policies

2. Vote Management

  • Regularly review and update votes
  • Monitor SR performance changes
  • Rebalance votes based on performance

3. Security

  • Use multi-signature for large voting accounts
  • Verify SR addresses before voting
  • Keep voting transactions records

4. Optimization

  • Diversify votes across multiple reliable SRs
  • Consider both rewards and network health
  • Participate in governance discussions

Common Errors

ErrorDescriptionSolution
Insufficient frozen balanceNot enough voting powerFreeze more TRX first
Invalid witness addressSR address not foundVerify SR address from listwitnesses
Total votes exceed frozen balanceVotes > available powerReduce total vote count
Contract validate errorInvalid transaction formatCheck parameter structure

Use Cases

  • Governance Participation: Vote for network validators
  • Reward Earning: Earn passive income from voting
  • SR Support: Support specific Super Representatives
  • Network Decentralization: Distribute voting power
  • Strategic Voting: Optimize rewards through vote management