WDK logoWDK documentation

Bridge Tokens

EVM-to-EVM bridging, quotes, fee caps, and optional OFT or endpoint overrides.

This guide covers prerequisites, how to run a standard EVM-to-EVM bridge, quote bridge fees, override OFT routing, and set bridgeMaxFee on the protocol.

Prerequisites

Complete Get Started: an account from new WalletAccountEvm(seed, path, config?) and a bridge from new Usdt0ProtocolEvm(account, config?). The source chain RPC must match the account network.

Before calling bridge(), approve the source-chain bridge spender for the token and amount you want to bridge. If you pass oftContractAddress, use the same address as the approval spender.

For placeholder values such as USDT0_OFT_ADDRESS, use the current token and bridge contract addresses from the USDT0 deployments. For the route mapping used by the WDK package, see the package src/config.js, especially oftContract, legacyMeshContract, and xautOftContract.

Run a standard EVM-to-EVM bridge

You can move USD₮ on the source chain toward another EVM chain by calling bridge() with targetChain, recipient, token, and amount (token base units). Amount 1000000n is 1 USD₮ when the token uses 6 decimals.

Standard EVM bridge
const USDT_TOKEN_ADDRESS = '0xdac17f958d2ee523a2206206994597c13d831ec7'
const USDT0_OFT_ADDRESS = process.env.USDT0_OFT_ADDRESS
const amount = 1000000n

await account.approve({
  token: USDT_TOKEN_ADDRESS,
  spender: USDT0_OFT_ADDRESS,
  amount
})

const result = await bridgeProtocol.bridge({
  targetChain: 'arbitrum',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  token: USDT_TOKEN_ADDRESS,
  amount,
  oftContractAddress: USDT0_OFT_ADDRESS
})

console.log('Bridge transaction hash:', result.hash)
console.log('Total fee:', result.fee, 'wei')
console.log('Bridge fee:', result.bridgeFee, 'wei')

bridge() does not approve token allowance for you. Use a bounded approval for the bridge amount rather than an unlimited allowance.

Quote bridge fees

You can estimate gas and protocol fees without sending transactions using quoteBridge():

Quote before bridging
const quote = await bridgeProtocol.quoteBridge({
  targetChain: 'polygon',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  token: '0xdac17f958d2ee523a2206206994597c13d831ec7',
  amount: 1000000n
})

console.log('Estimated fee:', quote.fee, 'wei')
console.log('Bridge fee:', quote.bridgeFee, 'wei')

Compare quote.fee and quote.bridgeFee to your risk limits before calling bridge().

Some providers estimate the bridge transaction during quoteBridge(). If the estimate fails because allowance is missing, approve the same token, spender, and amount before quoting.

Override OFT contract and destination endpoint

You can point bridge() at a specific OFT contract and LayerZero destination endpoint ID when auto-resolution is not enough. Supply values from your deployment or integration configuration (environment variables shown for illustration):

Custom OFT and dstEid on bridge
const USDT_TOKEN_ADDRESS = '0xdac17f958d2ee523a2206206994597c13d831ec7'
const USDT0_OFT_ADDRESS = process.env.USDT0_OFT_ADDRESS
const amount = 1000000n

await account.approve({
  token: USDT_TOKEN_ADDRESS,
  spender: USDT0_OFT_ADDRESS,
  amount
})

const result = await bridgeProtocol.bridge({
  targetChain: 'arbitrum',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  token: USDT_TOKEN_ADDRESS,
  amount,
  oftContractAddress: USDT0_OFT_ADDRESS,
  dstEid: Number(process.env.CUSTOM_DST_EID)
})

console.log('Bridge transaction hash:', result.hash)

You can obtain matching fee estimates with quoteBridge() using the same oftContractAddress and dstEid fields:

Quote with OFT overrides
const customQuote = await bridgeProtocol.quoteBridge({
  targetChain: 'arbitrum',
  recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  token: '0xdac17f958d2ee523a2206206994597c13d831ec7',
  amount: 1000000n,
  oftContractAddress: process.env.USDT0_OFT_ADDRESS,
  dstEid: Number(process.env.CUSTOM_DST_EID)
})

console.log('Custom route quote fee:', customQuote.fee, 'wei')

Invalid pairings of oftContractAddress and dstEid fail at execution time. Validate addresses and endpoint IDs against LayerZero and your token deployment.

Cap fees with bridgeMaxFee

You can pass bridgeMaxFee into the new Usdt0ProtocolEvm(account, config?) constructor so bridge() rejects operations whose cost exceeds the cap:

Protocol-level bridgeMaxFee
import Usdt0ProtocolEvm from '@tetherto/wdk-protocol-bridge-usdt0-evm'

const cappedBridge = new Usdt0ProtocolEvm(account, {
  bridgeMaxFee: 1000000000000000n
})

If the quote exceeds bridgeMaxFee, bridge() throws (for example when the message includes Exceeded maximum fee). ERC-4337 accounts can also pass bridgeMaxFee in the second argument to bridge(); see Bridge with ERC-4337.

Next Steps

Bridge to Solana, TON, or TRON in Bridge cross-ecosystem, or switch to a smart account in Bridge with ERC-4337.

On this page