Skip to main content
Tron is a supported Intents chain (chain ID 728126428, CAIP-2 tron:728126428). Tron runs an EVM-compatible VM, so inside the protocol the order looks identical to EVM — the same StandardOrder and MandateOutput structs, the same 20-byte addresses left-padded to bytes32. The differences are at the edges: how you encode addresses at the HTTP boundary, which contract addresses you talk to, which settlement types exist, and how you submit the origin transaction. This page is a delta reference — for each concern, what EVM does and what Tron does instead.
For general (non-Intents) Tron support across LI.FI products, see the Tron ecosystem page.

At a glance

ConcernEVMTron
Recommended quote endpointPOST /quote/request (EIP-7930)POST /api/v1/integrator/quote/request (native addresses)
Address format — requests0x hex (or EIP-7930)base58 T… (CAIP-2 chain); 0x 20-byte hex also accepted
Address format — responses0x hexbase58 T…
Settlement typesEscrow and CompactEscrow only
Order open pathOn-chain open or gasless POST /orders/submitOn-chain open only
Contract addressesDeterministic 0x0000…, identical across EVM chainsUnique base58, Tron-specific (see below)
Submission libraryethers / viemTronWeb (TriggerSmartContract envelope)
Origin fee unitgas (wei / gwei)feeLimit in SUN (1 TRX = 1e6 SUN)
Cross-chain oraclePolymerPolymer (Tron PolymerOracle)

For Tron, use the V1 integrator quote endpoint. It accepts a CAIP-2 chain plus the native address, so you pass Tron addresses as base58 (T…) and get them back as base58 — no EIP-7930 hand-encoding. POST /api/v1/integrator/quote/request (optional header X-Integrator-Key).
curl -X POST 'https://order.li.fi/api/v1/integrator/quote/request' \
  -H 'Content-Type: application/json' \
  -d '{
    "user": { "chain": "tron:728126428", "address": "TYYUrA6nV1EYxQqo7RiBJh6roFq4mtiBLT" },
    "intent": {
      "intentType": "oif-swap",
      "inputs": [{
        "chain": "tron:728126428",
        "user": "TYYUrA6nV1EYxQqo7RiBJh6roFq4mtiBLT",
        "asset": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
        "amount": "10000000"
      }],
      "outputs": [{
        "chain": "eip155:8453",
        "receiver": "0x841F63697cFa0e3B54c4D42b3d679F07F7F2485f",
        "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "amount": null
      }],
      "swapType": "exact-input"
    },
    "supportedTypes": ["oif-user-open-v0"]
  }'
supportedTypes on the V1 endpoint is the order-type string ["oif-user-open-v0"] (the same for EVM and Tron). This is not the settlement-type vocabulary (oif-escrow-v0 / oif-resource-lock-v0) used by the main POST /quote/request endpoint — don’t mix them.
The response renders Tron addresses back as base58. The origin transaction for a Tron-origin order is returned under order.openIntentTx:
{
  "quotes": [{
    "order": {
      "openIntentTx": {
        "chain": "tron:728126428",
        "to": "TXmVLCXzrhzmeCfchDPTmFF6Qe7rg3H7Kk", // InputSettler (base58)
        "data": "0x7515fd56…",                       // ABI calldata (selector + args)
        "feeLimit": "150000000"                       // SUN cap (≈150 TRX)
      }
    },
    "preview": {
      "inputs":  [{ "user": "TYYUrA6nV1EYxQqo7RiBJh6roFq4mtiBLT", "asset": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "amount": "10000000" }],
      "outputs": [{ "receiver": "0x841F63697cFa0e3B54c4D42b3d679F07F7F2485f", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "amount": "9986765" }]
    }
  }]
}
The reverse direction (EVM → Tron) works the same way — put the Tron leg in outputs with chain: "tron:728126428" and base58 addresses. If you instead use the main POST /quote/request endpoint (EIP-7930), the interoperable address must encode the tron CAIP-2 namespace and embed the 20-byte form of the Tron address (see Address format). Prefer the V1 endpoint or build EIP-7930 with the interoperable-addresses library rather than hand-encoding it.

Address format at the boundary

A Tron base58 address (T…) is a 0x41 version byte plus the 20-byte account, wrapped in base58check. The protocol only ever sees the 20-byte account — the 0x41 version byte and the base58 checksum exist only in the human-facing envelope.
  • V1 endpoint: pass base58 (T…). 0x-prefixed 20-byte hex is also accepted. Responses always render base58.
  • Main endpoint (EIP-7930): the embedded address is the 20-byte form (base58 decoded, 0x41 + checksum stripped).
  • On-chain / in the order struct: 20-byte hex, left-padded to bytes32 — exactly like EVM.
Convert between the two forms with bs58check:
import bs58check from 'bs58check';

const TRON_VERSION_BYTE = 0x41;

// Tron base58 (T…) -> 20-byte hex used in the protocol / order struct
function tronBase58ToHex20(address: string): `0x${string}` {
  const decoded = bs58check.decode(address); // 21 bytes: 0x41 + 20-byte account
  const body = decoded.slice(1);             // drop the 0x41 version byte
  return ('0x' +
    Array.from(body, (b) => b.toString(16).padStart(2, '0')).join('')
  ) as `0x${string}`;
}

// 20-byte hex -> Tron base58 (T…)
function hex20ToTronBase58(hex: string): string {
  const body = Uint8Array.from(
    hex.replace(/^0x/, '').match(/.{1,2}/g)!.map((b) => parseInt(b, 16)),
  );
  const payload = new Uint8Array(21);
  payload[0] = TRON_VERSION_BYTE;
  payload.set(body, 1);
  return bs58check.encode(payload);
}

// TXmVLCXzrhzmeCfchDPTmFF6Qe7rg3H7Kk <-> 0xef1b684567bfcbabb19d01a84bc3f218081b1536

Wire format is identical to EVM

Once an address is in 20-byte hex form, nothing downstream changes. The StandardOrder and MandateOutput structs, the bytes32 left-padding (tokenId/oracle/settler/token/recipient), and the calldata encoding are the same on Tron as on EVM. The 0x41 version byte never appears on-chain. If your EVM order-construction code already produces the correct struct, the only change for Tron is converting addresses at the boundary and submitting via TronWeb.

Settlement: Escrow only

Tron supports only the Escrow input settler. There is no Compact / The Compact / resource-lock flow on Tron. Consequences:
  • On the main POST /quote/request endpoint, request ["oif-escrow-v0"] only — never oif-resource-lock-v0.
  • The Compact Orders guide does not apply to Tron.

Opening orders: on-chain only

Tron orders are opened on-chain by calling the Escrow input settler directly with the openIntentTx from the quote. The order server and solvers detect the resulting on-chain event automatically. POST /orders/submit (off-chain / gasless submission) is EVM-only — there is no gasless Tron path.

Contract addresses

These are not the deterministic 0x0000… addresses used on EVM chains. Tron has no keyless CREATE2 factory, so the deployments live at unique, Tron-specific addresses.
The “same address across all supported chains” statement elsewhere in these docs applies to EVM chains only. Do not send funds to the EVM 0x0000… addresses on Tron — they do not exist there.
ContractBase58 (Tron)Hex (20-byte)
InputSettler (Escrow)TXmVLCXzrhzmeCfchDPTmFF6Qe7rg3H7Kk0xef1b684567bfcbabb19d01a84bc3f218081b1536
OutputSettlerTHWDD3umarircbqo8jXxVazbpJnE25VjhN0x52a5f2a94125ef11673f86104e2ce3f86ece2c25
PolymerOracleTCeNWukZUoTSrgWZEMpn9X8C5NtV8Rsy6c0x1d586aa1bd8ea3fda890057bad5a7d373886dbc1

On-chain submission (TVM)

The quote’s openIntentTx.data is full ABI calldata (function selector + arguments) as a 0x-hex string — it is not a ready-to-broadcast EVM transaction. A Tron client must wrap it in a TriggerSmartContract envelope, which is TAPOS-bound (it references a recent block via ref_block_* / expiration), then sign and broadcast it.
  • openIntentTx.to is the settler base58 address.
  • openIntentTx.feeLimit is a cap on energy spend in SUN, not an estimate.
  • Token approvals use TRC-20 (not ERC-20).
import { TronWeb } from 'tronweb';

const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io' /*, privateKey */ });
const { to, data, feeLimit } = quote.order.openIntentTx;

// 1. Approve the InputSettler to pull the TRC-20 input (e.g. USDT)
//    via the token contract's `approve(spender, amount)`.

// 2. Submit the open() calldata wrapped in a TriggerSmartContract envelope.
const tx = await tronWeb.transactionBuilder.triggerSmartContract(
  to,                       // settler (base58)
  '',                       // selector empty: full calldata is supplied via `input`
  { feeLimit, input: data.replace(/^0x/, '') },
  [],
  tronWeb.defaultAddress.base58,
);
const signed = await tronWeb.trx.sign(tx.transaction);
await tronWeb.trx.sendRawTransaction(signed);
After the order opens, track it the same way as an EVM order via the order status API.

Oracle

For cross-chain Tron outputs, the order uses Polymer; MandateOutput.oracle is the bytes32 of the Tron PolymerOracle (TCeNWukZUoTSrgWZEMpn9X8C5NtV8Rsy6c). For same-chain (Tron → Tron) intents, the OutputSettler acts as the oracle path, as described in Same-chain intents. See Oracle Systems for how Polymer proofs work.

For solvers

Filling a Tron output works like an EVM fill — call fillOrderOutputs on the Tron OutputSettler — with one Tron specifics:
  • Submit via TronWeb, decoding addresses with the 20-byte rule above.
See Filling Orders for the general fill flow.

Next Steps

Request a Quote

Quote endpoints, exact-input/output, and interoperable addresses

Create and Submit Orders

Construct a StandardOrder and open it on-chain

Oracle Systems

Polymer and the other verification systems

Filling Orders

How solvers deliver outputs