Send ERC20 and TRC20 Token Transfers
To send an ERC20, BEP20 or TRC20 token with Chaingateway, you post the sender, the recipient, the amount and the token’s contract address to the token endpoint of the chain, together with the wallet password or private key. A token transfer is a smart contract call, so the sender also needs the chain’s native coin to pay the fee: ETH, BNB, MATIC or TRX. The response returns the transaction hash.
For the API token, see Quickstart. On Ethereum, BNB Smart Chain and Polygon, the sending address must have been created with the Chaingateway API or imported into it. Otherwise the signing step fails. Create Addresses shows how to create one.
Which endpoint sends a token on which chain?
Section titled “Which endpoint sends a token on which chain?”Each chain has its own token endpoint, named after the token standard. The body is the same on all EVM chains.
| Blockchain | API route | Standard |
|---|---|---|
| Ethereum | /api/v2/ethereum/transactions/erc20 | ERC-20 |
| Binance Smart Chain | /api/v2/bsc/transactions/bep20 | BEP20 |
| Polygon | /api/v2/polygon/transactions/erc20 | ERC-20 |
| Arbitrum | /api/v2/arbitrum/transactions/erc20 | ERC-20 |
| Tron | /api/v2/tron/transactions/trc20 | TRC20 |
| Solana | /api/v2/solana/transactions/SPL | SPL |
To run the request on a test network, add the header X-Network: testnet. The testnets are listed under Supported Networks. Bitcoin has no token endpoint.
How do I send an ERC20 or BEP20 token?
Section titled “How do I send an ERC20 or BEP20 token?”Post the following fields to the route of your chain. The example sends an ERC20 token on Ethereum.
from: the sender’s address.to: the recipient’s address.amount: the amount of tokens to send.contractaddress: the contract address of the token.password: the wallet password, required whenprivatekeyis not present.privatekey: the private key of the sender, for addresses created without a password.
gas, gasprice, maxPriorityFeePerGas, maxFeePerGas and nonce are optional.
curl --request POST \ --url https://app.chaingateway.io/api/v2/ethereum/transactions/erc20 \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_TOKEN' \ --data '{ "from": "0xYourSenderAddress", "to": "0xRecipientAddress", "amount": 100, "contractaddress": "0xTokenContractAddress", "password": "YourPassword" }'const axios = require('axios');
const url = 'https://app.chaingateway.io/api/v2/ethereum/transactions/erc20';const payload = { from: '0xYourSenderAddress', to: '0xRecipientAddress', amount: 100, contractaddress: '0xTokenContractAddress', password: 'YourPassword'};const headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_API_TOKEN'};
axios.post(url, payload, { headers }) .then(response => { console.log(response.data); }) .catch(error => { console.error(error.response?.data ?? error); });import requests
url = "https://app.chaingateway.io/api/v2/ethereum/transactions/erc20"payload = { "from": "0xYourSenderAddress", "to": "0xRecipientAddress", "amount": 100, "contractaddress": "0xTokenContractAddress", "password": "YourPassword"}headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_API_TOKEN'}
response = requests.post(url, json=payload, headers=headers)print(response.json())<?phprequire 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();$response = $client->post('https://app.chaingateway.io/api/v2/ethereum/transactions/erc20', [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'Bearer YOUR_API_TOKEN', ], 'json' => [ 'from' => '0xYourSenderAddress', 'to' => '0xRecipientAddress', 'amount' => 100, 'contractaddress' => '0xTokenContractAddress', 'password' => 'YourPassword' ]]);
echo $response->getBody();The code returns the transaction hash:
{ "status": 201, "ok": true, "message": "Succesfully created", "data": { "txid": "0x73344d178812d4919e9002c560781f288030edf72ece88823ef1c377dfb71f27" }}How do I send a TRC20 token?
Section titled “How do I send a TRC20 token?”The TRC20 request works almost like the ERC20 one. The route is /api/v2/tron/transactions/trc20, the addresses are Tron addresses, and you sign with password or privatekey. The OpenAPI file lists from, to, contractaddress and amount as required. The example uses the private key of an address that was created without a password.
curl --request POST \ --url https://app.chaingateway.io/api/v2/tron/transactions/trc20 \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_TOKEN' \ --data '{ "from": "TYourSenderAddress", "to": "TRecipientAddress", "amount": 100, "contractaddress": "TTokenContractAddress", "privatekey": "YourPrivateKey"}'Create TRC20 Token Transactions walks through the whole TRC20 flow, including reading the contract and the self-signing endpoints.
How do I check a token balance before I send?
Section titled “How do I check a token balance before I send?”Read the balance first, so that you do not send a transaction that will fail. On EVM chains, GET /api/v2/ethereum/balances/{address}/erc20/{contract_address} returns the balance of one token. GET /api/v2/ethereum/balances/{address}/erc20 lists the token balances of a wallet. On BNB Smart Chain the segment is bep20, and on Tron it is GET /api/v2/tron/balances/{address}/trc20/{contract_address}. GET /api/v2/ethereum/erc20/{contract_address} returns the contract information of a token.
Why does my token transfer fail?
Section titled “Why does my token transfer fail?”Most failures are one of three causes, and each has a different message.
- A wrong password returns status 401 with
Wrong password provided. - A missing or malformed field returns status 422 with
Data validation failedand the field name inerrors. - A sender without enough native coin returns status 422 with the node’s message, for example
insufficient funds for gas * price + value. On Tron the equivalent isbalance is not sufficient.
The last cause surprises people who hold only tokens: the fee is paid in ETH, BNB, MATIC or TRX, never in the token. Read the Ethereum gas documentation for the fee model on EVM chains and TRON’s resource model for energy and bandwidth. If your TRON addresses hold tokens but no TRX, Sponsor TRC20 Fees lists the options.
How do I send an NFT?
Section titled “How do I send an NFT?”NFT transfers use the ERC721 endpoints, for example POST /api/v2/ethereum/transactions/erc721. The body has the same signing fields as above, but instead of amount it takes tokenId, the id of the NFT. from, contractaddress, to and tokenId are required. GET /api/v2/ethereum/nfts/{contract_address}/owner/{token_id} returns the current owner, and .../uri/{token_id} returns the token URI. The standard is defined in EIP-721.
Sources
Section titled “Sources”- EIP-20: Token Standard defines
transferandbalanceOffor ERC-20 tokens. - TRC20 protocol interface in the TRON developer documentation.
- Gas and fees in the Ethereum developer documentation.