Skip to content

Sponsor TRC20 Fees: TronFuel, Paymaster

Fee sponsoring means that a third party pays the energy and bandwidth a TRON transaction consumes, so the sending wallet does not need TRX. We recommend TronFuel for this. The Chaingateway Paymaster did the same job inside the API and is deprecated: existing integrations keep working, but new integrations should not use it.

Options for sending TRC20 tokens from an address without TRX: rent energy with TronFuel, stake TRX and delegate resources, or use the deprecated Paymaster TRC20 transfer from an address withoutTRX fails with status 422, balance is notsufficient Recommended: TronFuel rents energy, a separate service Alternative: stake and delegate POST /api/v2/tron/freeze and /delegate Deprecated: Paymaster endpoints only for existing integrations
Pick the second or third option for new integrations.

Why can a TRON wallet with tokens but no TRX not send them?

Section titled “Why can a TRON wallet with tokens but no TRX not send them?”

A TRC20 transfer is a smart contract call. TRON charges energy and bandwidth for it, and an address pays for those resources either by burning TRX or by using resources it has staked or been delegated. The token itself never pays.

That produces a situation every TRON integration runs into sooner or later. A customer deposits USDT into a freshly created address. The address now holds tokens and nothing else. Sending those tokens onwards fails with status 422 and the message balance is not sufficient, because there is no TRX to cover the resource cost. Funding every deposit address with TRX in advance works, but it ties up TRX in addresses that may never be used.

Sponsoring the fee solves this from the other side. A third party pays the resource cost, and the wallet sends its tokens without ever holding TRX.

What should I use instead of the Paymaster?

Section titled “What should I use instead of the Paymaster?”

TronFuel is what we recommend for this today. It rents energy in bulk from stakers rather than burning TRX, which is where the saving compared with a plain burn comes from. The background is written up in TRC-20 Transaction Fees on TRON Explained.

TronFuel is a separate service. It has no endpoint inside the Chaingateway API, so nothing in this documentation describes how to call it. Follow the link above for its own documentation.

The Chaingateway Paymaster did the same job inside the API: it covered bandwidth and energy so a wallet did not need TRX before sending TRC20 tokens, and it billed the cost against a credit balance on your account.

The service is deprecated. Integrations that already call the Paymaster endpoints keep working, and the endpoints are documented below for that reason. Do not build new integrations on them.

EndpointPurpose
POST /api/v2/tron/paymasterCreate a sponsored transaction request
GET /api/v2/tron/paymasterList your requests and their status
GET /api/v2/tron/paymaster/{id}Read one request
POST /api/v2/tron/paymaster/estimateEstimate energy, bandwidth and fee
GET /api/v2/tron/paymaster/balanceRead your remaining credit balance

How much energy and bandwidth a transaction needs depends on the transaction type and on the contract it calls, so the amount is not fixed. POST /api/v2/tron/paymaster/estimate takes the same body as the request itself and returns what the transaction would cost.

Terminal window
curl --request POST\
--url https://app.chaingateway.io/api/v2/tron/paymaster/estimate\
--header 'Accept: application/json'\
--header 'Content-Type: application/json'\
--header 'Authorization: Bearer YOUR_API_TOKEN'\
--data '{
"type": "TRC20",
"from": "TLkkCeNdJKPNUwucdro84WjswkzM62LCTH",
"to": "TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp",
"contractaddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"amount": "1"
}'
{
"status": 200,
"ok": true,
"message": "Successfully estimated the fees",
"data": {
"energy_consumption": 32000,
"bandwidth_consumption": 368,
"paymaster_fee": 0.15
}
}

The fee is deducted from the credit balance once the request settles. A balance that does not cover it makes the request fail. GET /api/v2/tron/paymaster/balance returns what is left.

type accepts TRX, TRC10, TRC20 and TRC721. Together with from, to and amount it is required. For TRC20 and TRC721 you also pass contractaddress, for TRC721 and TRC10 the tokenid. Signing works as everywhere else in the API: password for a password-protected Chaingateway address, privatekey otherwise. An optional callback_url receives the result.

Terminal window
curl --request POST\
--url https://app.chaingateway.io/api/v2/tron/paymaster\
--header 'Accept: application/json'\
--header 'Content-Type: application/json'\
--header 'Authorization: Bearer YOUR_API_TOKEN'\
--data '{
"type": "TRC20",
"from": "TLkkCeNdJKPNUwucdro84WjswkzM62LCTH",
"to": "TUwmZghA7u2GxGxKaxM1mkCmsTF4wHs4vp",
"contractaddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"amount": "1",
"password": "test123",
"callback_url": "https://example.com/callback"
}'

The answer is not a transaction hash but the id of the request:

{
"status": 200,
"ok": true,
"message": "Successfully created paymaster request",
"data": {
"id": "9c72d676-8180-4cd2-a406-f0f1cd097506"
}
}

Poll GET /api/v2/tron/paymaster/{id} with that id, or list every request with GET /api/v2/tron/paymaster. The status field moves through pending while the request waits, processing while the transaction is on its way, and completed once it settled. A failure reads failed - [reason], with the reason spelled out after the dash. The resulting transaction hash appears in the record once the transaction is done.

{
"id": "9cfbfcaf-68b2-47e9-bf55-5b6b4875e84d",
"type": "TRC20",
"from": "THG9nncwASg3ub5rvVquocAHwwQbnKZxpH",
"to": "TPUjdnMrS7XDUFp5W6zgh4QDCW34nXa2x1",
"contract_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"amount": "200",
"token_id": null,
"transaction_hash": "80a223e0cb20ef692fbd23d3cbaf3cc1dfa2b9667aaef70c7da8ca8f707ec28b",
"status": "success",
"used_credits": "2.178413",
"callback_url": "https://api.chaingateway.io/receiver/webhooks/tron",
"created_at": "2024-09-11T15:28:57.000000Z"
}

Can I stake TRX instead of paying per transaction?

Section titled “Can I stake TRX instead of paying per transaction?”

If the TRX is yours anyway, you can stake it once and reuse the resources instead of paying per transaction. POST /api/v2/tron/freeze stakes TRX for energy or bandwidth, POST /api/v2/tron/delegate hands those resources to another address, and POST /api/v2/tron/undelegate and POST /api/v2/tron/unfreeze reverse both steps. A single staked address can supply the deposit addresses behind it, which is the pattern that fits a payment flow with many receiving addresses.

The four staking endpoints share one body shape. The fields address, amount and resource are required, and resource is BANDWIDTH or ENERGY. delegate and undelegate add a required receiver. As everywhere in the API, you sign with password or privatekey.

Terminal window
curl --request POST\
--url https://app.chaingateway.io/api/v2/tron/freeze\
--header 'Accept: application/json'\
--header 'Content-Type: application/json'\
--header 'Authorization: Bearer YOUR_API_TOKEN'\
--data '{
"address": "TLkkCeNdJKPNUwucdro84WjswkzM62LCTH",
"amount": 100,
"resource": "ENERGY",
"password": "test123"
}'

A successful call returns data.result: true and the txid of the staking transaction. Two rules from the OpenAPI file apply to delegation: the balance has to be frozen before it can be delegated, and the receiver must differ from the owner address. A failed call returns status 422 with the node’s message, for example no frozenBalance(Energy) when you unfreeze more than you staked, or delegated Resource does not exist when you undelegate something that was never delegated. TRON’s resource model documents how staked TRX turns into energy and bandwidth.

The table compares the options by what they need and what they cost.

OptionWhat you needCost modelStatus
Fund each address with TRXTRX in every deposit addressTRX is burned per transactionworks, ties up TRX
TronFuelthe separate TronFuel service, outside the Chaingateway APIenergy is rented instead of burning TRXrecommended
Stake and delegateTRX that you can lockthe staked TRX supplies resources instead of being burnedworks
Paymastercredit balance on your Chaingateway accountfee deducted from the credit balancedeprecated

Check the TRX balance of an address with GET /api/v2/tron/balances/{address} before you send. An address without TRX and without delegated resources fails with the balance is not sufficient message from above.

Sending the transfer itself is covered in Create TRC20 Token Transactions.