Create Ethereum and Tron Addresses
You create an address with one request: POST /api/v2/{chain}/addresses. If the body contains a password, Chaingateway stores the private key encrypted and the response returns only the address. Without a password, the response contains the private key. This tutorial shows both variants for Ethereum and Tron. The same requests work for BNB Smart Chain, Polygon and Arbitrum.
You need an API token for the calls below. Quickstart explains how to create one.
How do I create a password-protected address?
Section titled “How do I create a password-protected address?”Send the password field in the JSON body. For EVM chains Chaingateway creates a keystore, an encrypted file format for a private key that is described in the Web3 secret storage definition. The keystore is encrypted with your password. Whoever has only the keystore or only the password cannot access the address, and your transactions need the password instead of the private key.
The password is a value you choose. Chaingateway does not store it and cannot recover it. If you lose the password, you lose access to the address, so keep it in a password manager or a secrets store.
curl --request POST \ --url https://app.chaingateway.io/api/v2/ethereum/addresses \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_TOKEN' \ --data '{"password":"choose-a-strong-password"}'import requests
url = "https://app.chaingateway.io/api/v2/ethereum/addresses"payload = {"password": "choose-a-strong-password"}headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_API_TOKEN'}
response = requests.post(url, json=payload, headers=headers)print(response.json())const axios = require('axios');
const url = 'https://app.chaingateway.io/api/v2/ethereum/addresses';const payload = { password: 'choose-a-strong-password' };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); });<?phprequire 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();$response = $client->post('https://app.chaingateway.io/api/v2/ethereum/addresses', [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'Bearer YOUR_API_TOKEN', ], 'json' => ['password' => 'choose-a-strong-password']]);
echo $response->getBody();The response has status 201. The OpenAPI file spells the key of the address adderess:
{ "status": 201, "ok": true, "message": "Address created", "data": { "adderess": "0x7d3bC832A0860fD882FF4C2359e10268f4E5CCf8" }}How do I create an address without a password?
Section titled “How do I create an address without a password?”Leave the password out. The response then contains the private key, and every transaction from the address needs that key in a privatekey field. Use this mode only for single-use addresses, because a private key that travels in every request is easy to leak. The example creates a Tron address.
curl --request POST \ --url https://app.chaingateway.io/api/v2/tron/addresses \ --header 'Accept: application/json' \ --header 'Authorization: Bearer YOUR_API_TOKEN'import requests
url = "https://app.chaingateway.io/api/v2/tron/addresses"headers = { 'Accept': 'application/json', 'Authorization': 'Bearer YOUR_API_TOKEN'}
response = requests.post(url, headers=headers)print(response.json())const axios = require('axios');
const url = 'https://app.chaingateway.io/api/v2/tron/addresses';const headers = { 'Accept': 'application/json', 'Authorization': 'Bearer YOUR_API_TOKEN'};
axios.post(url, {}, { headers }) .then(response => { console.log(response.data); }) .catch(error => { console.error(error.response?.data ?? error); });<?phprequire 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();$response = $client->post('https://app.chaingateway.io/api/v2/tron/addresses', [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'Bearer YOUR_API_TOKEN', ]]);
echo $response->getBody();A Tron address that is created without a password returns the key material directly:
{ "status": 201, "ok": true, "message": "Address created", "data": { "privateKey": "59f1c6200e01a2ca9471411f10198bfa63678d0e87cc2ca30f9c4a68dee78edc", "publicKey": "040fe6e677442c36f7fdd5535ba3ff1cef0110d78363420f7e24b65298990e3467aed68b9a67e1396d84753db25b32a2fa3e1fc0a673f01638e9bcfab2d8f4ceb5", "hexAddress": "41a56a6505ffbee78eb916dd44f4846874deddaebd", "address": "TR3qx91smURF3R455V1ubqtoUsZbgqikfg" }}Store the privateKey together with the address in a secure place. The key in this example is a sample value, so never fund it. The Tron account documentation explains how the base58 address and the hex address relate.
What do I do after the address exists?
Section titled “What do I do after the address exists?”Read the balance, fund the address and then send from it. GET /api/v2/ethereum/balances/{address} returns the balance of the address as a string:
{ "status": 200, "ok": true, "message": "Balance fetched", "data": "0.000000000000000000"}A new address starts with a balance of zero. Send coins to it from a wallet you control, or from the testnet faucet of the chain when you work with X-Network: testnet. GET /api/v2/ethereum/addresses lists every address that you created and have not deleted. If you want a notification when funds arrive, create a webhook for the address. Sending funds out of the address is covered in Create Transactions.
Bitcoin and Solana differ. On Bitcoin you first create a wallet with POST /api/v2/bitcoin/wallets and then add addresses to it. On Solana POST /api/v2/solana/addresses creates the address. Wallet Management describes both.
Which errors can address creation return?
Section titled “Which errors can address creation return?”Address calls use the standard envelope with ok set to false on failure. A missing or invalid token returns status 401 with {"message":"Unauthenticated."}. A body that fails validation returns status 422 with Data validation failed and the field names in errors. When your plan’s address limit is used up, the API answers with status 422 and Your address limit exceeded. Please upgrade your plan. The OpenAPI file shows this message for Bitcoin wallets.
DELETE /api/v2/ethereum/addresses/{address} removes an address and lowers the number of addresses that count against your plan. Delete addresses that you no longer need, but export the private key first if the address may still hold funds.
How are addresses formatted on each chain?
Section titled “How are addresses formatted on each chain?”Ethereum and the other EVM chains use 20-byte addresses that are written as 40 hex characters with a 0x prefix. The Ethereum accounts documentation describes how an externally owned account is derived from a key pair. Tron addresses start with T and have 34 characters, which is the format the API validates with the pattern T[a-zA-Z0-9]{33}. The TRON account documentation is the primary reference for that format.