WDK logoWDK documentation

Transfer Tokens

Transfer ERC-20 tokens with gasless transactions.

This guide explains how to transfer ERC-20 tokens, estimate transfer fees, set a maximum fee limit, select a nonce lane, and apply UserOperation gas overrides.

Transfer ERC-20 Tokens

You can transfer ERC-20 tokens using gasless transactions with account.transfer():

Transfer ERC-20 Tokens
const result = await account.transfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDt
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000 // 1 USDt (6 decimals)
})
console.log('Transfer UserOperation hash:', result.hash)
console.log('Transfer fee:', result.fee)

Estimate Transfer Fees

You can estimate the fee for a token transfer without executing it using account.quoteTransfer():

Estimate Transfer Fee
const quote = await account.quoteTransfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000
})
console.log('Estimated transfer fee:', quote.fee)

Transfer with Maximum Fee Limit

You can set a maximum fee for a specific transfer by passing a transferMaxFee in the config object to account.transfer():

Transfer with Fee Limit
const result = await account.transfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000
}, {
  transferMaxFee: 100000
})

If the estimated fee exceeds transferMaxFee, the transfer throws MaximumFeeExceededError. A fee equal to the cap is allowed.

Transfer in a Nonce Lane

transfer() follows the same beta.18 nonce-lane rules as sends. Use a stable named lane for an independent transfer stream, and wait for inclusion before reusing that lane:

Transfer In A Named Lane
const result = await account.transfer({
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  amount: 1000000
}, {
  nonceKey: 'token-payouts'
})

quoteTransfer() estimates the transfer but does not select or reserve a lane. A lane transfer rebuilds its UserOperation. The beta.20 runtime accepts lane fields per call, while the published per-call TypeScript declaration omits them; see Use Parallel Nonce Lanes.

Transfer with UserOperation Gas Overrides

In @tetherto/wdk-wallet-evm-erc-4337@1.0.0-beta.21, set UserOperation gas or EIP-1559 fee overrides directly on the options object passed to transfer() or quoteTransfer(), alongside token, recipient and amount. Set maxFeePerGas and maxPriorityFeePerGas together.

Set recipientAddress to the intended recipient's EVM address before quoting or sending.

Transfer with Gas Overrides
const transfer = {
  token: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  recipient: recipientAddress,
  amount: 1000000,
  callGasLimit: 90000n,
  verificationGasLimit: 120000n,
  maxFeePerGas: 30000000000n,
  maxPriorityFeePerGas: 2000000000n
}

const quote = await account.quoteTransfer(transfer)

const result = await account.transfer(transfer)

approve() accepts the same override fields on its options object.

Next Steps

Learn how to sign and verify messages.

On this page