Developer Documentation
1. Overview
GasFree aims to provide users with a TRC-20/ERC-20 transfer solution that does not require a native token to pay for transaction gas fees. It specifically includes four roles: GasFree accounts, Service-Providers, wallets, and users, as shown in Figure 1. below.

Figure 1. GasFree Framework
GasFree Account: Generated according to a specific algorithm. Its permissions are controlled by the user's EOA (Externally Owned Account) address. The user can sign a signature to authorize GasFree transfer of this account.
Service-Provider: The GasFree service-provider is responsible for collecting users' GasFree transfer authorizations, submitting them to the blockchain, and paying the Gas fees on behalf of the users. The Service-Provider may charge a certain handling fee after the transaction is completed.
Wallet: After connecting to the GasFree service, the wallet provides end-users with interface functions such as fund inquiry for GasFree accounts and signature for transfer authorization.
2. Authorization Process
Integrating GasFree into the wallet involves processes such as constructing transfer authorization, signing the transfer authorization, and the provider submitting the authorization to the blockchain on behalf of the user. For detailed information about the Provider API interface, please refer to Section 5 of this document. After the integration, the main interaction process is as follows:
Prerequisite:
-
The Service-Provider supports GasFree transfers for multiple types of tokens. Call
/api/v1/config/token/all
to obtain the list of supported tokens. - When a token that the Provider does not currently support is transferred into a GasFree account, the user uses the withdrawal page provided by GasFree official to withdraw the token to their EOA (Externally Owned Account) address. The link to the withdrawal page is: https://gasfree.io/withdraw
-
GasFree supports multiple Service-Providers. Just make a call to
/api/v1/config/provider/all
to obtain the list of available Service-Providers. -
The GasFree account is in an inactive state by default. An inactive GasFree account will be automatically
activated during the first GasFree transfer. When activating the GasFree account, an additional
activation fee
will be charged. For subsequent GasFree transfer authorizations, only thetransfer fee
will be charged.
Preparation:
-
When a user conducts a GasFree transfer authorization, first call
/api/v1/address/{accountAddress}
to query his/her GasFree account info, including status, balance, and current nonce. Based on this info, construct a GasFree transfer authorization.
Sign authorization:
- The signature algorithm for GasFree transfer authorization is designed to support subsequent upgrades of the signature algorithm. The signature algorithm of the current version is compatible with the EIP712 specification. For the specific signature algorithm of the authorization, please refer to Section 3.2.
Submit authorization:
-
Use
/api/v1/gasfree/submit
to send the signed GasFree transfer authorization to the Service-Provider.
Handling of provider response:
- After receiving the GasFree transfer authorization submitted by the user, the provider will conduct a verification and immediately return the verification result to the wallet. The wallet should handle the response from the Provider:
-
If successful, notify the user the authorization verification has passed, and include a globally unique
authorization
traceId
. Subsequently, the on-chain status of this authorization can be tracked based on thistraceId
. - If failed, notify the user of the failure, stating that the authorization has been discarded and this request will not trigger an actual transaction on the blockchain.
Monitoring of the transfer authorization:
-
Call
/api/v1/gasfree/{tranceId}
to query the status of the GasFree transfer authorization.
3. Signature Algorithm and Provider Endpoint
3.1 Parameters
The GasFree transfer authorization involves the following parameters. Their values on the TRON mainnet and the Nile testnet are shown in Table 1.
Parameter | TRON - mainnet | TRON - Nile testnet |
---|---|---|
chainId | 728126428 | 3448148188 |
verifyingContract | TFFAMQLZybALaLb4uxHA9RBE7pxhUAjF3U | THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc |
Table 1. GasFree Transfer Authorization Parameters
3.2 Authorization Construction and Signature
General structure
MessageDomain:
const Permit712MessageDomain = {
name: 'GasFreeController',
version: 'V1.0.0',
chainId: 3448148188, // tronWeb.toDecimal('0xcd8690dc'),
verifyingContract: 'THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc'
}
name
: 'GasFreeController', fixed valueversion
: 'V1.0.0', fixed valuechainId
: chainId in decimal, please refer to Section 3.1verifyingContract
: GasFreeController contract address, please refer to Section 3.1
MessageTypes: fixed value
const Permit712MessageTypes = {
PermitTransfer: [
{ name: 'token', type: 'address' },
{ name: 'serviceProvider', type: 'address' },
{ name: 'user', type: 'address' },
{ name: 'receiver', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'maxFee', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
{ name: 'version', type: 'uint256' },
{ name: 'nonce', type: 'uint256' }
]
};
Message body:
const message = {
token: 'TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf',
serviceProvider: 'TKtWbdzEq5ss9vTS9kwRhBp5mXmBfBns3E',
user: 'THvMiWQeVPGEMuBtAnuKn2QpuSjqjrGQGu',
receiver: 'TMDKznuDWaZwfZHcM61FVFstyYNmK6Njk1',
value: '90000000',
maxFee: '20000000',
deadline: '1728638679',
version: 1,
nonce: 0
};
Field description:
token
: address of transferring tokenserviceProvider
: address of Service-Provideruser
: user's EOA address, not GasFree addressreceiver
: recipient address of the transfervalue
: amount of the transfer, like 90 USDT equals 90 * 10^6maxFee
: maximum fee limit (transfer fee + activation fee), the smallest unit; for example, 20 USDT equals 20 * 10^6deadline
: expiration timestamp of the transfer, the unit is seconds; for example, Date.now() / 1000version
: version of the signature, the current version is 1nonce
: nonce value of the transfer authorization; for example, 0
Sign with Wallet
Using the above structure, you can call the TRON wallet to sign the TIP-712 Message, which will provide the
required sig
parameter.
const signature = await window.tron.tronWeb.trx._signTypedData(
Permit712MessageDomain,
Permit712MessageTypes,
message
); // remove 0x
3.3 Provider Endpoint
Wallets/users can interact with the Provider through the following endpoint, including submitting GasFree transfer authorizations, querying subsequent statuses, etc. They can also withdraw tokens that are not yet supported by the Providers to the user's EOA (Externally Owned Account) address.
- Services – TRON - Mainnet: https://open.gasfree.io/tron/
- TRON - Nile testnet: https://open-test.gasfree.io/nile/
- GasFree website: https://gasfree.io | https://test.gasfree.io
- Assets Withdrawal: https://gasfree.io/withdraw | https://test.gasfree.io/withdraw
Note: Currently, GasFree only provides services in the TRON network and can be extended to Ethereum and various EVM-compatible chains in the future.
4. Notes
- It is not recommended that the testnet environment be provided to
users.
The GasFree environment on the TRON testnet is only available for developer teams to conduct testing and debugging during integration.
It is strongly recommended to close the entrance to the GasFree test environment for ordinary users after the official launch to prevent users from filling in the wrong recipient addresses and incurring asset losses.
- It is recommended to conduct balance and status verification before submitting transfer
authorization.
For details, please refer to the definition of GasFree account interface.
Unless otherwise specified, all references to asset balances and amounts in this document are in the smallest unit.
5. APIs
API Authentication
After applying for access to the GasFree project, the access party will receive a pair of keys: API Key and API Secret. This key pair is used to sign API requests. Please make sure to keep the API Secret properly. The GasFree server verifies the requests, and the signature information is transmitted through the HTTP header.
Please submit your API Key and API Secret applications here.
HTTP header definition:
{
"Timestamp": 1731912286, // unit: second
"Authorization": "ApiKey {api_key}:{signature}"
}
API Signature and Authentication
Construct the string to be signed: including the request method, request path, and timestamp.
Calculate the signature: Use the HMAC-SHA256 algorithm and the API secret to perform a hash operation on the
string to be signed, and then perform base64 encoding on the result.
Add the signature to the request header.
Example:
import hmac
import hashlib
import base64
import time
import requests
API_KEY = 'YOUR_API_KEY'
API_SECRET = 'YOUR_API_SECRET'
method = 'GET'
path = '/api/v1/config/token/all'
timestamp = int(time.time())
message = f'{method}{path}{timestamp}'
signature = base64.b64encode(
hmac.new(
API_SECRET.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).digest()
).decode('utf-8')
url = 'https://test-nile.gasfree.io' + path
headers = {
'Timestamp': f'{timestamp}',
'Authorization': f'ApiKey {API_KEY}:{signature}'
}
response = requests.get(url, headers=headers)
print(response.json())
API Format Definition
When the service runs normally, the HTTP code returned by the API is 200
. Parameter errors or
runtime errors are reflected in the HTTP body.
The code
field indicates the status: 200 means normal, 400 indicates failure due to input error,
and 500 indicates failure due to runtime error.
{
"code": 200,
"reason": null,
"message": "",
"data": ""
}
Error return example:
{
"code": 400,
"reason": "GasFreeAddressNotFoundException",
"message": "123",
"data": null
}
Successful return example:
{
"code": 200,
"reason": null,
"message": null,
"data": {
"tokens": [
{
"tokenAddress": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf",
"createdAt": "2024-09-10T09:46:24.801+00:00",
"updatedAt": "2024-09-11T06:57:10.244+00:00",
"activateFee": 10000000,
"transferFee": 10000000,
"supported": true,
"symbol": "USDT",
"decimal": 6
}
]
}
}
GET /api/v1/config/token/all
Get the contract list of all supported tokens.
Request parameters: None
Return: tokens
, containing the contract list of all supported tokens.
Field description:
tokenAddress
: token contract addressactivateFee
: the activation handling fee paid in the transfer token, measured in the smallest unit of that token; this value can be adjusted according to actual circumstances later.transferFee
: the transfer fee, paid in the transfer currency, measured in the smallest unit of that token; this value can be adjusted according to actual circumstances later.symbol
: token namedecimal
: token precision
Return example:
{
"code": 200,
"reason": null,
"message": null,
"data": {
"tokens": [
{
"tokenAddress": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf",
"createdAt": "2024-10-09T08:14:12.560+00:00",
"updatedAt": "2024-10-09T08:14:12.560+00:00",
"activateFee": 10000000, // stands for 10 USDT
"transferFee": 10000000, // stands for 10 USDT
"supported": true,
"symbol": "USDT",
"decimal": 6
}
]
}
}
GET /api/v1/config/provider/all
Get the list of all supported service providers.
Request parameters: None
Return: providers
, containing the list of all available Service-Providers.
Field description:
address
: address of the Service-Providername
: Provider’s nameicon
: Provider’s iconwebsite
: Provider’s websiteconfig
: system parameters of the ProvidermaxPendingTransfer
: the maximum number of transfer authorizations waiting to be on-chain that users are allowed to submit; if the number exceeds this limit, an error will be reported upon submission, and users must wait until the previous transfer authorizations are successfully on-chain before they can continue to send new ones. (Currently, only one transfer authorization in the "pending" status is supported for the same account.)minDeadlineDuration
: the minimum deadline interval; transfer authorizations with a deadline less than this value from the current time will be rejected; the unit is seconds.maxDeadlineDuration
: the maximum deadline interval; transfer authorizations with a deadline more than this value from the current time will be rejected; the unit is seconds.defaultDeadlineDuration
: default deadline interval, recommended.
Return example:
{
"code": 200,
"reason": null,
"message": null,
"data": {
"providers": [
{
"address": "TQ6qStrS2ZJ96gieZJC8AurTxwqJETmjfp",
"name": "Provider-1",
"icon": "",
"website": "",
"config": {
"maxPendingTransfer": 1,
"minDeadlineDuration": 60,
"maxDeadlineDuration": 600,
"defaultDeadlineDuration": 180
}
}
]
}
}
GET /api/v1/address/{accountAddress}
Query the relevant information of the user's GasFree account, including whether it is activated, the nonce value, the supported tokens, and assets.
Query the latest assets of the GasFree account on-chain. Combine the “frozen” value provided by this interface to limit the maximum transfer-out amount of users. Otherwise, it may lead to submission failures or transfer failures.
Request parameters:
accountAddress
: user's EOA address
Return: Asset info of the user's GasFree account.
Field description:
accountAddress
: user’s EOA addressgasFreeAddress
: user's GasFree account addressactive
: activation status of the GasFree accountnonce
: the recommended nonce value for the next GasFree transfer; since there may be transfer authorizations waiting to be on-chain, the nonce on the chain may not necessarily be applicable; the back end will provide the recommended nonce value by comprehensively considering the situations on the chain and in the queue.allow_submit
: whether users are currently allowed to continue submitting transfer authorizationassets
: details of the assets that users are processing through the GasFree service provider.tokenAddress
: token contract addresstokenSymbol
: token nameactivateFee
: the activation handling fee for this token, measured in the smallest unit of that tokentransferFee
: the transfer fee for this token, measured in the smallest unit of that tokendecimal
: precision of the tokenfrozen
: current amount of the GasFree transfer in progress, including the fees
Return example:
{
"code": 200,
"reason": null,
"message": null,
"data": {
"accountAddress": "TKtWbdzEq5ss9vTS9kwRhBp5mXmBfBns3E",
"gasFreeAddress": "TLGVf7MRsLG7XxBkJKy8wnCVcDnAeXYNCb",
"active": true,
"nonce": 1,
"allow_submit": false,
"assets": [
{
"tokenAddress": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf",
"tokenSymbol": "USDT",
"activateFee": 10000000,
"transferFee": 10000000,
"decimal": 6,
"frozen": 0
}
]
}
}
POST /api/v1/gasfree/submit
Initiate a GasFree transfer authorization.
Request parameters:
token
: address of the token for transferprovider
: address of the service-provideruser
: user's EOA address, not the GasFree addressreceiver
: recipient address of the transfervalue
: amount for the transfermaxFee
: the maximum fee limit (transfer fee + activation fee)deadline
: expiration timestamp of this transfer, in secondsversion
: signature version of transfer authorizationnonce
: nonce value of this transfer authorizationsig
: user's signature of the GasFree transfer authorization
Request example:
{
"token": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf",
"provider": "TCETRh3aED4kdkaYQY7CcxeTJtrQvwBpNT",
"user": "TKtWbdzEq5ss9vTS9kwRhBp5mXmBfBns3E",
"receiver": "TEkj3ndMVEmFLYaFrATMwMjBRZ1EAZkucT",
"value": 100000,
"maxFee": 1000000,
"deadline": 1728638679,
"version": 1,
"nonce": 9,
"sig": "9dfd3638e03af56bc93fa619e20e1e743f6b5c0d9a49bd340a94e27f6d6a6413618cc8481b9d5816a793982d8047daa0badbade02f92814e78a9894efd9877341b"
}
Return: Basic information of this GasFree transfer authorization.
Field description:
id
: traceId of GasFree transfer authorization, not the transactionIdaccountAddress
: user's EOA addressgasFreeAddress
: user's GasFree account addressproviderAddress
: address of the service-providertargetAddress
: recipient addresstokenAddress
: contract address of the transferred tokenamount
: amount of the transfermaxFee
: maximum fee limitsignature
: user's signatureversion
: signature version of transfer authorizationnonce
: nonce value specified for the transferexpiredAt
: expiration time of this transferstate
: current state of this transfer, with the following values: WAITING, INPROGRESS, CONFIRMING, SUCCEED, FAILEDestimatedActivateFee
: estimated activation feeestimatedTransferFee
: estimated transfer fee
Return example:
{
"code": 200,
"reasone": null,
"message": null,
"data": {
"id": "6ab4c27c-f66b-4328-b40f-ffdc6cf1ca60",
"createdAt": "2024-09-10T08:11:50.822+00:00",
"updatedAt": "2024-09-10T08:11:50.822+00:00",
"accountAddress": "TKtWbdzEq5ss9vTS9kwRhBp5mXmBfBns3E",
"gasFreeAddress": "TLGVf7MRsLG7XxBkJKy8wnCVcDnAeXYNCb",
"providerAddress": "TQ6qStrS2ZJ96gieZJC8AurTxwqJETmjfp",
"targetAddress": "TQ6qStrS2ZJ96gieZJC8AurTxwqJETmjfp",
"tokenAddress": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf",
"amount": 1000000,
"maxFee": 1000000,
"signature": "f5bb43b90a5295759819edb029a1c2d6cd50acc9bd4283fd73c4be16fe163d154ec4f06fd70c8d63cc2ff2346ea1c86abf019da944fb62eb28fe0a8f6e12e1931c",
"nonce": 0,
"expiredAt": "2024-09-11T08:05:08.000+00:00",
"state": "WAITING",
"estimatedActivateFee": 1000,
"estimatedTransferFee": 300
}
}
Error example:
{
"code": 400,
"reason": "DeadlineExceededException",
"message": "deadline exceeded",
"data": null
}
Error types:
ProviderAddressNotMatchException
: Provider’s address does not matchDeadlineExceededException
: authorization is expiredInvalidSignatureException
: signature is incorrectUnsupportedTokenException
: token transferred is not supportedTooManyPendingTransferException
: there are too many pending transfer authorizationsVersionNotSupportedException
: signature version of transfer authorization is not supportedNonceNotMatchException
: nonce does not matchMaxFeeExceededException
: estimated fee exceeds the limit of the maximum feeInsufficientBalanceException
: insufficient balance
GET /api/v1/gasfree/{traceId}
Query the details of a specified GasFree transfer authorization.
Request parameters:
traceId
: id of the GasFree transfer authorization; a path parameter.
Return: Detailed info on the GasFree transfer authorization.
Field description:
id
: traceId of the GasFree transfer authorization recorded, not the transactionId.createdAt
: creation time of the transfer authorization.accountAddress
: user's EOA address.gasFreeAddress
: user's GasFree account address.providerAddress
: service-provider address.targetAddress
: recipient address.nonce
: nonce value of the GasFree transfer authorization.tokenAddress
: contract address of the token transferred.amount
: amount actually transferred to the recipient's address.expiredAt
: expiration time of this transfer.state
: current state of this transfer (WAITING, INPROGRESS, CONFIRMING, SUCCEED, FAILED).estimatedActivateFee
: estimated activation fee.estimatedTransferFee
: estimated transfer fee.estimatedTotalFee
: estimated activation fee plus estimated transfer fee.estimatedTotalCost
: estimated amount that the user needs to pay, including the total fee and the transfer amount.txnHash
: transactionId of the corresponding transaction on-chain.txnBlockNum
: block height of the corresponding transaction on-chain.txnBlockTimestamp
: timestamp of the block containing the corresponding transaction, in milliseconds.txnState
: state of the corresponding on-chain transaction (INIT, NOT_ON_CHAIN, ON_CHAIN, SOLIDITY, ON_CHAIN_FAILED).txnActivateFee
: actual activation fee consumed.txnTransferFee
: actual transfer fee consumed.txnTotalFee
: actual total fee consumed.txnAmount
: actual transferred amount to the recipient address.txnTotalCost
: actual amount paid by the user, including the total fee and the transferred amount.
Note: All fields related to the transaction will be empty if the query is made either before the transfer authorization is submitted to the chain or the verification before submitting fails.