deposit. You rehearse on testnet first, then run the same script on mainnet.
What you’ll build
A viem script that sends 11 USDT from BOT Chain to your own address. By default it bridges from BOT Chain testnet to BSC testnet. WithNETWORK=mainnet it bridges from BOT Chain mainnet to BNB Smart Chain.
11 USDT is just above the 10 USDT minimum read on 2026-10-02 on both networks. The fee is 1 USDT at that size, so 10 USDT arrives.
Prerequisites
- The
bot-defiproject from Wrap BOT, with a testnet key in.env. - At least 11 testnet USDT and a little tBOT for gas. Testnet USDT can’t be minted by the public, so swap tBOT for it on BDEX V2.
- For the mainnet run, a separate mainnet wallet holding the USDT you want to send plus a little BOT for gas.
- You’ve read Limits and fees and the Bridge overview.
Steps
1
Add the recipient to .env
Add these lines to your testnet
.env. On testnet you can send to your own address, since the same key controls it on BSC testnet..env
2
Write the script
bridge-out.ts
3
Understand each part
- The checks stop the script before it spends anything if the bridge is paused or the amount is outside the limits. The limits are whole USDT, so they’re converted to base units first.
- The fee estimate uses the same rule as Limits and fees. The fee comes out of the amount, so the recipient gets
amount - fee. - The approval is for exactly
amount. The router pulls the full amount from your wallet duringdeposit. Avoid unlimited approvals. deposit(destinationChainId, resourceId, recipient, amount)takes the amount in BOT Chain units (6 decimals) for every destination, including BNB Smart Chain. The function is payable, but you send no BOT with it for USDT.simulateContractruns the call first, so a revert costs nothing.NETWORKpicks the chain, addresses and destination together, so a testnet run can never reach a mainnet contract.
4
Run it on testnet
5
Run it on mainnet
Only after the testnet run has arrived. Create a separate env file so you never send mainnet transactions by accident:Add
.env.mainnet
.env.mainnet to .gitignore. Never commit or share it. Then run:Verify it worked
Output from a testnet run on 2026-10-02:Output
- Copy the deposit transaction hash and follow it with Track a bridge transfer. Use
botChainin that script for a mainnet transfer. - When the status is
delivered, check the recipient’s USDT balance on BscScan testnet or BscScan. The amount shows with 18 decimals there.
delivered within a minute, and the recipient’s balance on BSC testnet went up by 10000000000000000000, which is 10 USDT with 18 decimals. In an earlier run the same day, the gateway on BSC testnet released the USDT 38 seconds after the deposit block. Mainnet timing isn’t documented.
Troubleshooting
Amount must be between ...
Amount must be between ...
Your
AMOUNT is outside the live limits. Read them with the script in Limits and fees.The simulation reverts
The simulation reverts
Check the approval succeeded, your USDT balance covers the amount, and the destination chain ID is supported on the network you’re using. Testnet supports 97, 11155111 and 3448148188. Mainnet supports 56, 1 and 728126428.
The transfer stays pending
The transfer stays pending
See Track a bridge transfer. If it doesn’t move, contact BOT Chain with the deposit hash.
I sent to the wrong address
I sent to the wrong address
A delivered transfer can’t be reversed. Always test with a small amount first.
Next steps
Track a transfer
Follow your deposit to arrival.
Contract addresses
Routers, gateways and the resource ID.