Introduction
Ever wondered how to track your token balances across multiple chains in one place? In this tutorial, we'll build a Multichain Portfolio Tracker using Etherscan API V2. By the end, you'll have a simple tool that fetches token and native balances effortlessly.
What You Need
Before we begin, make sure you have:
✅ Node.js installed
✅ An Etherscan API key → Get one here
Step 1: Setting Up the Project
1.1 Initialize the Project
First, create a new project folder and initialize a Node.js project:
mkdir multichain-portfolio && cd multichain-portfolio
npm init -y
1.2 Create Essential Files
Now, create the required files:
touch multichain.js
1.3 Define Constants
At the top of multichain.js
, define these constants:
const API_KEY = "your-api-key";
const CHAINS = [1, 10, 56, 137, 5000, 42161, 43114, 8453, 324, 1101];
API_KEY
: Replace this with your Etherscan API key.CHAINS
: An array of chain IDs representing various blockchains. Each number corresponds to a specific blockchain, the full list of supported chain IDs can be found here.
1.4 Fetch Token Balances
Create a function to get token balances:
async function getTokenBalances(address, chainId) {
const url = `https://api.etherscan.io/v2/api?
chainid=${chainId}
&module=account
&action=addresstokenbalance
&address=${address}
&page=1
&offset=5000
&apikey=${API_KEY}`;
const response = await fetch(url);
const data = await response.json();
if (data.status !== "1") return [];
return data.result.map(token => ({
name: token.TokenName,
symbol: token.TokenSymbol,
balance: (parseFloat(token.TokenQuantity) / Math.pow(10, token.TokenDivisor)).toFixed(4)
}));
}
✅ What This Function Does:
- Constructs the API request URL.
- Fetches the response and parses it as JSON.
- Returns an array of tokens with formatted balances. The balance is calculated by dividing the
TokenQuantity
by10
raised to the power ofTokenDivisor
to account for decimal places, and it's formatted to 4 decimal places.
1.5 Fetch Native Currency Balance
Create another function to get the native currency balance (e.g., ETH on Ethereum):
async function getNativeBalance(address, chainId) {
const url = `https://api.etherscan.io/v2/api?
chainid=${chainId}
&module=account
&action=balance
&address=${address}
&tag=latest
&apikey=${API_KEY}`;
const response = await fetch(url);
const data = await response.json();
if (data.status !== "1") return "0";
return (parseFloat(data.result) / Math.pow(10, 18)).toFixed(4);
}
🔍 Key Takeaways:
- Uses Etherscan's API to fetch the balance.
- Converts the response into a human-readable format (ETH has 18 decimals). The balance is divided by
10
to the power of 18 to adjust for the standard decimal places in Ethereum-based native currencies. The balance is then formatted to 4 decimal places.
1.6 Define the Portfolio Function
We'll create a function that fetches balances across all chains:
async function getPortfolio(address) {
let portfolio = {};
for (const chain of CHAINS) {
const nativeBalance = await getNativeBalance(address, chain);
const tokenBalances = await getTokenBalances(address, chain);
portfolio[chain] = { nativeBalance, tokens: tokenBalances };
}
return portfolio;
}
🔹 What Happens Here:
- Loops through each blockchain in
CHAINS
. - Retrieves native balance and token balances.
- Stores the results in an object with the chain ID as the key.
1.7 Running the Script in the CLI
(async () => {
const address = process.argv[2]; // Take address from CLI input
if (!address) {
console.error("❌ Please provide a wallet address.");
process.exit(1);
}
console.log(`🔍 Fetching portfolio for: ${address}\n`);
try {
const portfolio = await getPortfolio(address);
console.log(JSON.stringify(portfolio, null, 2)); // Pretty-print the result
} catch (error) {
console.error("⚠️ Error fetching portfolio:", error);
}
})();
🌟 How It Works:
- Takes a wallet address from the command line.
- Checks if an address is provided; exits if missing.
- Calls
getPortfolio(address)
to fetch balances. - Prints the portfolio data in a formatted JSON output.
- Handles errors and logs them to the terminal.
Step 2: Run the Script
To run the script, use:
node multichain.js 0xYourWalletAddress

If everything works, you should see the native and token balances from each of the 10 chains printed in your terminal:

🎉 Congrats! You've built a Multichain Portfolio Tracker from scratch! 🚀
Next, you can create a frontend that allows users to enter an address and fetch multichain portfolio data:
- Create an interactive webpage to input addresses.
- Fetch and display portfolio data dynamically.
- Customize the frontend with additional flair (charts, styling, etc.).

You can also expand the multichain portfolio tracker by covering more chain ids and display price data from crypto price data aggregators.