How to Get Token Balance for an Address
Learn how to get the balance of a single token being held by a specific contract address.
API Endpoint
This tutorial uses the alchemy_getTokenBalances endpoint.
If you just need the script for this tutorial refer to the below Recipe:
The token balances for a user address is a critical data point for almost any web3 use case - be it DeFi platforms, wallets, analytics, exchanges, and many others. A common use case would be displaying the balances as below in your wallet app.
To fetch this data you have 2 options:
- Fetch the Transaction History for the token’s contract, for example take USDT, which is millions of records. Then search through for your user’s address among those records (will take hours) and then show that to your user. Not to forget, do this indexing process every second forever to keep it updated for every user.
- OR just use Alchemy’s
getTokenBalances
endpoint.
If you’re like most web3 developers, you probably want to go for the second option!
How to query the token balance of an address
When querying the token balance for a user, you should have couple of key parameters on hand:
OwnerAddress
: This is the blockchain address that owns the tokens in question. Note that this is not the contract address of the token itself.tokenContractAddress
: An array of contract addresses of all the token’s you want the balances for. Or if you specify the stringerc20
it will include the entire set of erc20 tokens that the address has ever held.
Example: Get current USDT balance for an Address.
For this particular example we're going to fetch the USDT balance for address 0x00000000219ab540356cbb839cbe05303d7705fa
(fun fact: this address has the highest ETH balance among all addresses! )
No-Code Example
For a no-code view of the API request, check out the composer tool
Alchemy SDK (Recommended)
Step 1: Install Alchemy-SDK and create a file
Run the below commands in the command line
npm install alchemy-sdk
touch token-balances-from-alchemy-sdk.js
Step 2: Write the token balance querying script
Inside the token-balances-from-alchemy-sdk.js
file, paste the below code
// Setup: npm install alchemy-sdk
import { Alchemy, Network } from "alchemy-sdk";
const config = {
apiKey: "<-- ALCHEMY APP API KEY -->",
network: Network.ETH_MAINNET,
};
const alchemy = new Alchemy(config);
//Feel free to switch this wallet address with another address
const ownerAddress = "0x00000000219ab540356cbb839cbe05303d7705fa";
//The below token contract address corresponds to USDT
const tokenContractAddresses = ["0xdAC17F958D2ee523a2206206994597C13D831ec7"];
const data = await alchemy.core.getTokenBalances(
ownerAddress,
tokenContractAddresses
);
console.log("Token balance for Address");
console.log(data);
Step 3: Run the code to get the token balance with alchemy-web3.js
node token-balances-from-alchemy-sdk.js
You should see the below output
Token balance for Address
{
address: '0x00000000219ab540356cbb839cbe05303d7705fa',
tokenBalances: [
{
contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
tokenBalance: '4929853276',
error: null
}
]
}
Node-Fetch
Step 1: Create a node-fetch file
Run the below commands in the command line
touch token-balances-from-fetch.js
Step 2: Write the script for querying token balances!
Inside the token-balances-from-fetch.js
file, paste the below code
import fetch from 'node-fetch';
// Replace with your Alchemy API key:
const apiKey = "demo";
const fetchURL = `https://eth-mainnet.g.alchemy.com/v2/${apiKey}`;
// Replace with the wallet address you want to query:
const ownerAddr = "0x00000000219ab540356cbb839cbe05303d7705fa";
// Replace with the token contract address you want to query:
const tokenAddr = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
var raw = JSON.stringify({
"jsonrpc": "2.0",
"method": "alchemy_getTokenBalances",
"headers": {
"Content-Type": "application/json"
},
"params": [
`${ownerAddr}`,
[
`${tokenAddr}`,
]
],
"id": 42
});
var requestOptions = {
method: 'POST',
body: raw,
redirect: 'follow'
};
// Make the request and print the formatted response:
fetch(fetchURL, requestOptions)
.then(response => response.json())
.then(response => JSON.stringify(response, null, 2))
.then(result => console.log(result))
.catch(error => console.log('error', error));
Step 3: Run the code to get the token balance with Node-Fetch
node token-balances-from-fetch.js
You should see the below output
Token balance for Address
{
address: '0x00000000219ab540356cbb839cbe05303d7705fa',
tokenBalances: [
{
contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
tokenBalance: '4929853276',
error: null
}
]
}
Axios
Step 1: Install axios and create a file
Run the below commands in the command line
npm install axios
touch token-balances-from-axios.js
Step 2: Write the script to query token balances with Axios
Inside the token-balances-from-axios.js
file, paste the below code
import axios from 'axios';
// Replace with your Alchemy API key:
const apiKey = "demo";
const baseURL = `https://eth-mainnet.g.alchemy.com/v2/${apiKey}`;
// Replace with the wallet address you want to query:
const ownerAddr = "0x00000000219ab540356cbb839cbe05303d7705fa";
// Replace with the token contract address you want to query:
const tokenAddr = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
var data = JSON.stringify({
"jsonrpc": "2.0",
"method": "alchemy_getTokenBalances",
"params": [
`${ownerAddr}`,
[
`${tokenAddr}`
]
],
"id": 42
});
var config = {
method: 'post',
url: baseURL,
headers: {
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then(function (response) {
//This line converts the tokenBalance values from hex to decimal
response.data["result"]["tokenBalances"][0]["tokenBalance"] = parseInt(response.data["result"]["tokenBalances"][0]["tokenBalance"], 16);
console.log("Token balance for address\n", JSON.stringify(response.data.result, null, 2))
})
.catch(function (error) {
console.log(error);
});
Step 4: Run the code to get token balances with Axios
node token-balances-from-axios.js
You should see output like:
Token balance for Address
{
address: '0x00000000219ab540356cbb839cbe05303d7705fa',
tokenBalances: [
{
contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
tokenBalance: '4929853276',
error: null
}
]
}
In the above steps, you can replace the
ownerAddress
with any owner’s address and replacetokenContractAddresses
with an array of addresses, to get the right token balance!
How to process the API response
Now that we have made the query and can see the response, let's learn how to handle it.
If you feel like jumping ahead and grabbing some pre-built code, choose and pick a code from the below options that matches your preferred library.
Alchemy Web3 (Recommended)
The below linked Github script is for the Alchemy-Web3.js library and takes the output of the alchemy_getTokenBalances endpoint, joins it with the output of the alchemy_getTokenMetadata endpoint and returns a clean output "The balance of Token X is Y"
Node-Fetch
The below linked Github script uses Node-fetch and takes the output of the alchemy_getTokenBalances endpoint, joins it with the output of the alchemy_getTokenMetadata endpoint, and returns a clean output "The balance of Token X is Y"\
Axios
The below linked Github script uses Axios.js and takes the output of the alchemy_getTokenBalances endpoint, joins it with the output of the alchemy_getTokenMetadata endpoint and returns a clean output "The balance of Token X is Y"\
Raw API Response:
The usual result looks something like this
{
"address": "0x00000000219ab540356cbb839cbe05303d7705fa",
"tokenBalances": [
{
"contractAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"tokenBalance": 4929853276,
"error": null
}
]
}
Understanding the API Response:
Address
: The address of the owner for whom you want to pull the balance of the tokencontractAddress
: The contract address of the token in question. To pull the actual name of the token and other details, we will use another API alchemy_getTokenMetadatatokenBalance
: balance of the specificcontractAddress
for the owner addressaddress
The tokenBalance
in its raw form as returned by alchemy_getTokenBalances is the number in terms of the smallest unit of the token. In the code below, we do a bit of calculation to get the clear quantity of the token in decimal units.
The Calculation for
tokenBalance
The tokenBalance returned by the API is usually a number with several digits (in this case
4929853276
for USDT)
Every ERC20 token has a metadata information called "decimals" which denotes the divisibility of a token (ranges from 0 to 18). For USDT, the value of "decimals" is 6. The response returned by Alchemy's alchemy_getTokenBalances API is as below\
tokenBalance = no. of tokens (quantity) * Math.pow(10, 6)
Hence, the actual quantity of the USDT token, in this case, will be
4929853276/10^6 = 4,929.853276
The same operation needs to be done to obtain the actual quantity for any token. We show the calculation in the code below.
How to calculate & print the tokenName
and tokenBalance
tokenName
and tokenBalance
Two of the many different response objects you may be interested in parsing are: tokenName
and tokenBalance (in USD)
Whether we're querying via alchemy-web3
, axios
, or node-fetch
, we'll have to follow the below steps
1. Save the response of alchemy_getTokenBalances into a constant/variable
2. Get the Token name for the concerned Token Contract address alchemy_getTokenMetadata
3. Convert the tokenBalance into the correct units (using alchemy_getTokenMetadata
Let's walk through the below sample code that parses the returned JSON object.
/*
** Fetching the metadata for the token with Alchemy's getTokenMetadata API
*/
const metadata = await web3.alchemy.getTokenMetadata(
tokenContractAddresses[0]
);
//Forming the name of the token that comprises of the Name and the Symbol of the token
const tokenName = metadata.name + "(" + metadata.symbol + ")";
/* Calculating the tokenBalance in decimal. The "decimals" field in the token metadata on line 21 tells us
how many digits at the end of the tokenBalance in Line 17 are to the right of the decimal.
so we divide the Full tokenBalance with 10 to the power of the decimal value of the token
*/
const tokenBalance = data["tokenBalances"][0]["tokenBalance"]/Math.pow(10, metadata.decimals)
console.log("Token balance for", tokenName, "is", tokenBalance);
var metadata;
var metadataRaw = JSON.stringify({
"jsonrpc": "2.0",
"method": "alchemy_getTokenMetadata",
"headers": {
"Content-Type": "application/json"
},
"params": [
`${tokenAddr}`
],
"id": 42
});
var metadataRequestOptions = {
method: 'POST',
body: metadataRaw,
redirect: 'follow'
};
/*
** Fetching the metadata for the token with Alchemy's getTokenMetadata API
*/
fetch(fetchURL, metadataRequestOptions)
.then(response => response.json())
.then(response => {
metadata = response.result;
//Forming the name of the token that comprises of the Name and the Symbol of the token
const tokenName = metadata.name + "(" + metadata.symbol + ")";
/* Calculating the tokenBalance in decimal. The "decimals" field in the token metadata on line 21 tells us
how many digits at the end of the tokenBalance in Line 17 are to the right of the decimal.
so we divide the Full tokenBalance with 10 to the power of the decimal value of the token
*/
const tokenBalance = data["tokenBalances"][0]["tokenBalance"]/Math.pow(10, metadata.decimals)
console.log("Token balance for", tokenName, "is", tokenBalance);
})
.catch(error => console.log('error', error));
/*
** Fetching the metadata for the token with Alchemy's getTokenMetadata API
*/
var metadataParams = JSON.stringify({
"jsonrpc": "2.0",
"method": "alchemy_getTokenMetadata",
"params": [
`${tokenAddr}`
],
"id": 42
});
var metadataConfig = {
method: 'post',
url: baseURL,
headers: {
'Content-Type': 'application/json'
},
data : metadataParams
};
axios(metadataConfig)
.then(function (response) {
metadata = response.data.result;
//Forming the name of the token that comprises of the Name and the Symbol of the token
const tokenName = metadata.name + "(" + metadata.symbol + ")";
/* Calculating the tokenBalance in decimal. The "decimals" field in the token metadata on line 21 tells us
how many digits at the end of the tokenBalance in Line 17 are to the right of the decimal.
so we divide the full tokenBalance with 10 to the power of the decimal value of the token
*/
const tokenBalance = data["tokenBalances"][0]["tokenBalance"]/Math.pow(10, metadata.decimals)
console.log("Token balance for", tokenName, "is", tokenBalance);
})
The output that you would see from running the above code is
The token balance for Tether(USDT) is 4929.853276
With this, you're all set to fetch token balances from TokenAPI. This can also be extended to fetching the balance for multiple tokens by passing in an array of token addresses, or using the default list (see example here)!
If you enjoyed this tutorial for getting address transaction history on Ethereum, give us a tweet @AlchemyPlatform! (Or if you have any questions/feedback give the author @ankg404 a shoutout!)
Don't forget to join our Discord server to meet other blockchain devs, builders, and entrepreneurs! \
Updated about 2 years ago