WDK logoWDK documentation
TRONStandard TRONGuides

Transfer TRC20 Tokens

Transfer TRC20 tokens and estimate transfer fees on Tron.

This guide explains how to transfer TRC20 tokens, estimate transfer fees, approve a bounded allowance, and validate inputs before executing.

Transfer Tokens

You can send TRC20 tokens to a recipient address using account.transfer():

Transfer TRC20 Tokens
const transferResult = await account.transfer({
  token: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', // USDt
  recipient: 'TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH',
  amount: 1000000 // Amount in TRC20's base units
})
console.log('Transfer hash:', transferResult.hash)
console.log('Transfer fee:', transferResult.fee, 'sun')

Estimate Transfer Fees

You can get a fee estimate before executing the transfer using account.quoteTransfer():

Quote Token Transfer
const transferQuote = await account.quoteTransfer({
  token: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', // USDt
  recipient: 'TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH',
  amount: 1000000
})
console.log('Transfer fee estimate:', transferQuote.fee, 'sun')

The quote uses current chain parameters, the sender's available resources, and the TRC20 contract simulation result. It charges only the missing energy after available energy is considered, then adds any bandwidth cost.

Approve a Bounded Allowance

To authorize a contract to spend USD₮ or another TRC20 token, read the current allowance first and submit an approval only when the bounded value needs to change. approve() replaces the allowance for the token and spender pair; it does not add to the current value. Avoid unnecessary unlimited approvals.

approve() signs and broadcasts a TRC20 contract call. Verify the token and spender addresses and choose the smallest amount required for the intended use. When changing a nonzero allowance to another nonzero value, reset it to 0 and wait for successful finality before setting the new value; otherwise a spender can race the allowance change. Revoke the allowance after use when it is no longer needed.

Read, reset, and change a bounded USDt allowance
const token = process.env.TRON_TOKEN_ADDRESS
const spender = process.env.TRON_SPENDER_ADDRESS

if (!token || !spender) {
  throw new Error('Set TRON_TOKEN_ADDRESS and TRON_SPENDER_ADDRESS before approving')
}

const desiredAllowance = 1_000_000n // USDt base units; choose for the intended use
const currentAllowance = await account.getAllowance(token, spender)
console.log('Current allowance:', currentAllowance)

async function waitForSuccessfulApproval(account, approval) {
  const receipt = await account.waitForTransaction(approval.hash, {
    target: 'final'
  })

  if (receipt.success !== true) {
    throw new Error(`Approval ${approval.hash} did not execute successfully`)
  }
}

if (currentAllowance !== desiredAllowance) {
  if (currentAllowance !== 0n && desiredAllowance !== 0n) {
    const reset = await account.approve({
      token,
      spender,
      amount: 0n
    })
    await waitForSuccessfulApproval(account, reset)
  }

  const approval = await account.approve({
    token,
    spender,
    amount: desiredAllowance
  })
  await waitForSuccessfulApproval(account, approval)

  console.log('Approval transaction:', approval.hash)
  console.log('Approval fee:', approval.fee, 'sun')
}

Transfer with Validation

Validate addresses and check balances before transferring to catch errors early:

  1. Use account.getTokenBalance() to verify sufficient funds.
  2. Use account.quoteTransfer() to confirm fees.
  3. Execute the transfer with account.transfer():
Validated TRC20 Transfer
async function transferTRC20WithValidation(account, trc20Address, recipient, amount) {
  if (!trc20Address.startsWith('T') || trc20Address.length !== 34) {
    throw new Error('Invalid TRC20 contract address')
  }

  if (!recipient.startsWith('T') || recipient.length !== 34) {
    throw new Error('Invalid recipient address')
  }

  const balance = await account.getTokenBalance(trc20Address)
  if (balance < amount) {
    throw new Error('Insufficient TRC20 token balance')
  }

  const quote = await account.quoteTransfer({
    token: trc20Address,
    recipient,
    amount
  })
  console.log('Transfer fee estimate (sun):', quote.fee)

  const result = await account.transfer({
    token: trc20Address,
    recipient,
    amount
  })
  console.log('Transfer completed:', result.hash)
  console.log('Fee paid (sun):', result.fee)

  return result
}

Next Steps

Learn how to sign and verify messages with your Tron account.

On this page