Skip to Content

Tron Vault swaps

Initiating a Vault Swap on Tron works differently from EVM chains. Rather than calling the Chainflip Vault smart contract, it is a direct transfer of assets to the Chainflip Vault address, with the encoded swap parameters attached as a note on the transaction. This approach makes Vault swaps cheaper and removes the need to do token approvals for TRC-20 tokens, such as USDT.

The Vault contract addresses can be found in Testnet addresses and Mainnet addresses. Tron Vault Swaps follow the same pattern mentioned in the Vault Swaps introduction:

  1. Request the swap parameter encoding.
  2. Use the return values to build a Tron transaction.
  3. Sign and broadcast the transaction to the Tron network.

Vault Swaps are the recommended way to initiate swaps on Tron. They are cheaper for the user because it doesn’t require a fetch transaction by the protocol, removing the ingress fee.

Swap Parameter Encoding via Broker API

1. Request the encoded parameters via RPC

The request uses the same broker_request_swap_parameter_encoding RPC as other chains, with "chain": "Tron" in both source_asset and extra_parameters. Refund addresses must be valid Tron addresses.

Example request swapping native TRX:

curl -H "Content-Type: application/json" -d '{ "id": 1, "jsonrpc": "2.0", "method": "broker_request_swap_parameter_encoding", "params": { "source_asset": { "chain": "Tron", "asset": "TRX" }, "destination_asset": { "chain": "Bitcoin", "asset": "BTC" }, "destination_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "broker_commission": 0, "extra_parameters": { "chain": "Tron", "input_amount": "0x3b9aca00", "refund_parameters": { "retry_duration": 10, "refund_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g", "min_price": "0x0" } } } }' http://my-broker-api:9944

Example response for a native TRX swap:

{ "jsonrpc": "2.0", "result": { "chain": "Tron", "calldata": "0x", "value": "0x3b9aca00", "to": "0x814f36c1bbfd8aabec86273f0d61521e0c2d5287", "note": "0x010068bf29d88fd78713..." }, "id": 1 }

Example request swapping USDT (TRC20):

curl -H "Content-Type: application/json" -d '{ "id": 1, "jsonrpc": "2.0", "method": "broker_request_swap_parameter_encoding", "params": { "source_asset": { "chain": "Tron", "asset": "USDT" }, "destination_asset": { "chain": "Ethereum", "asset": "ETH" }, "destination_address": "0xcf0871027a5f984403aEfD2fb22831D4bEBc11Ef", "broker_commission": 0, "extra_parameters": { "chain": "Tron", "input_amount": "0x989680", "refund_parameters": { "retry_duration": 10, "refund_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g", "min_price": "0x0" } } } }' http://my-broker-api:9944

Example response when the source asset is USDT (TRC20). Note the inclusion of source_token_address and the token transfer calldata:

{ "jsonrpc": "2.0", "result": { "chain": "Tron", "calldata": "0xa9059cbb...", "value": "0x0", "to": "0x814f36c1bbfd8aabec86273f0d61521e0c2d5287", "note": "0x0100...", "source_token_address": "0xa24205e83c1805fcdae7a93db837dc6a0b843340" }, "id": 1 }

2. Construct the Transaction

The response fields differ slightly from EVM:

FieldDescription
calldataFor TRC20 swaps: ABI-encoded transfer(address,uint256) call. For native TRX swaps: "0x" (unused).
valueAmount of TRX to send in sun (1 TRX = 1,000,000 sun). Always "0x0" for TRC20 swaps.
toString-encoded destination address. For TRX: the Chainflip Vault. For TRC20: the token contract address.
noteHex-encoded swap parameters to attach as a note on the transaction. This is what identifies the transaction to Chainflip.
source_token_address(Optional) String-encoded TRC20 token contract address. Present only for TRC20 swaps.

The transaction construction differs depending on whether you are swapping native TRX or a TRC20 token. For this example, the TronWeb library is used.

Native TRX swap:

const senderAddress = /* user address */; let transaction = await tronWeb.transactionBuilder.sendTrx( to, Number(value), // value is already in sun senderAddress, ); // Attach swap parameters as note transaction = await tronWeb.transactionBuilder.addUpdateData( transaction, note.substring(2), // strip leading 0x 'hex', );

TRC20 (USDT) swap:

const senderAddress = /* user address */; const result = await tronWeb.transactionBuilder.triggerSmartContract( source_token_address, 'transfer(address,uint256)', { feeLimit: 100_000_000 }, [ { type: 'address', value: to }, { type: 'uint256', value: tokenAmount }, // amount in token's smallest unit ], senderAddress, ); let transaction = result.transaction; // Attach swap parameters as note transaction = await tronWeb.transactionBuilder.addUpdateData( transaction, note.substring(2), // strip leading 0x 'hex', );

3. Sign and Send

Sign the transaction with the sender’s private key and broadcast it to the network:

const signedTx = await tronWeb.trx.sign(transaction, privateKey); const broadcast = await tronWeb.trx.sendRawTransaction(signedTx); const txHash = '0x' + broadcast.txid;

Full Example

A complete TypeScript example using TronWeb:

import TronWeb from 'tronweb'; const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io', privateKey: 'your-private-key', }); // Step 1: Request encoded parameters const response = await fetch('http://my-broker-api:9944', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 1, jsonrpc: '2.0', method: 'broker_request_swap_parameter_encoding', params: { source_asset: { chain: 'Tron', asset: 'TRX' }, destination_asset: { chain: 'Bitcoin', asset: 'BTC' }, destination_address: 'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq', broker_commission: 10, extra_parameters: { chain: 'Tron', input_amount: '0x3b9aca00', refund_parameters: { retry_duration: 10, refund_address: senderAddress, min_price: '0x0', }, }, }, }), }); const { result: vaultSwapDetails } = await response.json() as { result: { chain: 'Tron'; calldata: string; value: string; to: string; note: string; source_token_address?: string; }; }; // Step 2: Build the transaction let transaction = await tronWeb.transactionBuilder.sendTrx( vaultSwapDetails.to, Number(vaultSwapDetails.value), senderAddress, ); // Attach swap parameters as note transaction = await tronWeb.transactionBuilder.addUpdateData( transaction, vaultSwapDetails.note.substring(2), 'hex', ); // Step 3: Sign and broadcast const signedTx = await tronWeb.trx.sign(transaction, 'your-private-key'); const broadcast = await tronWeb.trx.sendRawTransaction(signedTx); console.log('Transaction ID:', '0x' + broadcast.txid);
Last updated on