Quickstart
Send your first gasless USDT transfer on testnet in about 5 minutes.
You will send 1 test USDT from a wallet that holds no TRX. Tronergy pays the network cost from your free sandbox credit.
You need Node.js 18+ (or Python 3.9+) and a TRON Shasta testnet wallet with some test USDT.
Create an API key
- Sign up or log in at apiv2.tronergy.io.
- Open API keys and click Create.
- Copy the key. It is shown only once.
export TRONERGY_API_KEY="omk_live_..."
export SENDER_PRIVATE_KEY="your-shasta-test-wallet-private-key"Use the sandbox
You do not need to set anything up. Every request runs in sandbox unless you say otherwise. Sandbox uses the TRON Shasta testnet and comes with free test credit.
The sandbox test USDT contract is TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs (6 decimals). See Sandbox.
Install the signing library
You only need it to sign. Tronergy builds and broadcasts.
npm install tronwebCopy the script
The script does four things: build the transfer, sign it, execute it, and wait for the result. Replace SENDER and RECIPIENT with your addresses.
import { randomUUID } from 'node:crypto'
import { TronWeb } from 'tronweb'
const API = 'https://apiv2.tronergy.io/api'
const HEADERS = { 'content-type': 'application/json', 'x-api-key': process.env.TRONERGY_API_KEY }
const SENDER = 'TXyz...' // your Shasta wallet, holds test USDT, no TRX
const RECIPIENT = 'TAbc...' // any TRON address
const USDT = 'TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs'
async function call(path, body) {
const res = await fetch(`${API}${path}`, {
method: body ? 'POST' : 'GET',
headers: HEADERS,
body: body ? JSON.stringify(body) : undefined,
})
const json = await res.json()
if (!json.ok) throw new Error(`${res.status} ${json.error}: ${json.message ?? ''}`)
return json
}
// 1. Build an unsigned USDT transfer
const built = await call('/chain_relayers/portal/construct-tx', {
chain: 'tron',
mode: 'sponsored_broadcast',
senderAddress: SENDER,
contractAddress: USDT,
functionSelector: 'transfer(address,uint256)',
parameter: [
{ type: 'address', value: RECIPIENT },
{ type: 'uint256', value: '1000000' }, // 1 USDT
],
})
// 2. Sign it
const tronWeb = new TronWeb({ fullHost: 'https://api.shasta.trongrid.io' })
const signedTx = await tronWeb.trx.sign(built.unsignedTxs[0].tx, process.env.SENDER_PRIVATE_KEY)
// 3. Execute
const { operationId } = await call('/chain_relayers/portal/execute', {
chain: 'tron',
mode: 'sponsored_broadcast',
idempotencyKey: randomUUID(),
payload: { signed_tx: signedTx },
})
console.log('Operation', operationId)
// 4. Wait for the result
const FINAL = ['completed', 'failed', 'voided', 'expired']
let operation
do {
await new Promise((resolve) => setTimeout(resolve, 2000))
operation = (await call(`/chain_relayers/portal/operations/${operationId}`)).operation
console.log(operation.status)
} while (!FINAL.includes(operation.status))
if (operation.status === 'completed') {
console.log(`https://shasta.tronscan.org/#/transaction/${operation.txHash}`)
} else {
console.error(operation.errorCode, operation.errorMessage)
}Run it
node send.mjsYou should see the status move to completed within a few seconds. Open the Tronscan link: the USDT moved, and the sender's TRX balance did not change.
Sign and execute soon after you build. The transaction from construct-tx lives about 5 minutes. After that, execute returns TX_EXPIRED and you build a new one.
Go live
- Fund your live balance with TRX.
- Use mainnet addresses and the mainnet USDT contract
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t. - Add
"environment": "live"to every request.