Crypto Portfolio Tracker Using Web3
๐ฏ What You’ll Build
A web app that:
Connects to a user's wallet (e.g., MetaMask)
Fetches their token balances (ETH and ERC-20s)
Displays a portfolio summary in USD
Optionally includes price data from APIs like CoinGecko
๐ ️ Tech Stack
Layer Tools
Frontend React.js (or Vanilla JS)
Blockchain Access Web3.js or Ethers.js
Wallet Integration MetaMask
Token Prices CoinGecko API
Optional Backend Node.js/Express (optional for caching, auth, etc.)
๐ง Step 1: Set Up the Project
npx create-react-app crypto-portfolio-tracker
cd crypto-portfolio-tracker
npm install ethers axios
๐ Step 2: Connect to MetaMask Wallet
import { ethers } from 'ethers';
export const connectWallet = async () => {
if (!window.ethereum) {
alert("Install MetaMask!");
return null;
}
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
const signer = provider.getSigner();
const address = await signer.getAddress();
return { provider, signer, address };
};
๐ผ Step 3: Get ETH Balance
export const getEthBalance = async (provider, address) => {
const balance = await provider.getBalance(address);
return ethers.utils.formatEther(balance); // in ETH
};
๐ช Step 4: Get ERC-20 Token Balances
To fetch token balances, you’ll need:
The token contract address
The token’s ABI (ERC-20 standard ABI)
getTokenBalance.js
const erc20ABI = [
"function balanceOf(address owner) view returns (uint256)",
"function decimals() view returns (uint8)",
"function symbol() view returns (string)"
];
export const getTokenBalance = async (provider, tokenAddress, userAddress) => {
const token = new ethers.Contract(tokenAddress, erc20ABI, provider);
const [balance, decimals, symbol] = await Promise.all([
token.balanceOf(userAddress),
token.decimals(),
token.symbol()
]);
return {
symbol,
balance: Number(ethers.utils.formatUnits(balance, decimals)),
};
};
Example token addresses (Ethereum Mainnet):
USDC: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eb48
DAI: 0x6B175474E89094C44Da98b954EedeAC495271d0F
LINK: 0x514910771AF9Ca656af840dff83E8264EcF986CA
๐ Step 5: Get Token Prices from CoinGecko
import axios from 'axios';
export const getPrices = async (symbols = ['ethereum', 'usd-coin', 'dai']) => {
const ids = symbols.join(',');
const response = await axios.get(`https://api.coingecko.com/api/v3/simple/price?ids=${ids}&vs_currencies=usd`);
return response.data;
};
You can map ERC-20 token symbols to their CoinGecko IDs.
๐ฅ️ Step 6: Build the UI (React Example)
import React, { useState, useEffect } from 'react';
import { connectWallet, getEthBalance } from './web3/connect';
import { getTokenBalance } from './web3/getTokenBalance';
import { getPrices } from './api/getPrices';
const tokenList = [
{ symbol: 'USDC', address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eb48', coingeckoId: 'usd-coin' },
{ symbol: 'DAI', address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', coingeckoId: 'dai' }
];
function Portfolio() {
const [address, setAddress] = useState('');
const [provider, setProvider] = useState(null);
const [portfolio, setPortfolio] = useState([]);
const [prices, setPrices] = useState({});
const loadPortfolio = async () => {
const { provider, address } = await connectWallet();
setProvider(provider);
setAddress(address);
const eth = await getEthBalance(provider, address);
const tokens = await Promise.all(tokenList.map(token =>
getTokenBalance(provider, token.address, address)
));
const priceData = await getPrices(['ethereum', ...tokenList.map(t => t.coingeckoId)]);
setPrices(priceData);
setPortfolio([
{ symbol: 'ETH', balance: parseFloat(eth), price: priceData.ethereum.usd },
...tokens.map((token, i) => ({
...token,
price: priceData[tokenList[i].coingeckoId].usd
}))
]);
};
useEffect(() => {
loadPortfolio();
}, []);
return (
<div>
<h1>Crypto Portfolio Tracker</h1>
<p><strong>Wallet:</strong> {address}</p>
<table>
<thead>
<tr>
<th>Asset</th>
<th>Balance</th>
<th>Price (USD)</th>
<th>Value (USD)</th>
</tr>
</thead>
<tbody>
{portfolio.map(token => (
<tr key={token.symbol}>
<td>{token.symbol}</td>
<td>{token.balance.toFixed(4)}</td>
<td>${token.price.toFixed(2)}</td>
<td>${(token.balance * token.price).toFixed(2)}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default Portfolio;
๐ Optional Features
Add charts with Chart.js
Support multiple wallets (via WalletConnect or Web3Modal)
Cache token metadata with local storage
Add real-time updates using websockets (e.g., via Alchemy)
✅ Summary
Feature Status
Connect to wallet ✅
Fetch ETH & token balances ✅
Get real-time USD values ✅
Calculate portfolio value ✅
Display in a clean UI ✅
Learn Blockchain Course in Hyderabad
Read More
Decentralized Chat App on IPFS
Launching Your Own Token with ERC-20
Comments
Post a Comment