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

NFT Marketplace Clone Step-by-Step

Create a Personal Blockchain on Python

Comments

Popular posts from this blog

Entry-Level Cybersecurity Jobs You Can Apply For Today

Understanding Snowflake Editions: Standard, Enterprise, Business Critical

Installing Tosca: Step-by-Step Guide for Beginners