APIs used:
  • Get transaction summary for address  

Product update alert! 😀 🔥

We have recently released a brand new endpoint that allows you to quickly gain high-level insights into a wallet or smart contract address across 200+ chains that we support.

Introducing the Get transaction summary for address endpoint:

Get transaction summary for address

GET/v1/{chainName}/address/{walletAddress}/transactions_summary/

Commonly used to fetch the earliest and latest transactions, and the transaction count for a wallet. Calculate the age of the wallet and the time it has been idle and quickly gain insights into their engagement with web3.

For all the Web3 wallet/portfolio tracker devs out there, why is this useful?

Well, this endpoint enables you to get a wallet’s total transaction count, first transaction, and last transaction, without having to query the entire transaction history of a wallet. Previously, such aggregated data was not easy to come by. To get the transaction count, for instance, you’d have to fetch all the actual transactions of a user and then sum them up. Now, you can get the summarized data with just 1 API call - no wastage! With this data, you can quickly figure out important aspects of user behavior: such as how active a user is on a particular chain, how long they’ve been around, or even which chain they’ve been the most active on.

Can’t wait to get your hands dirty and give it a go? In this guide, we’ll do just that. Expanding upon the multi-chain portfolio tracker (COMING SOON) that we’ve built in the previous part, we’ll add a feature to return the wallet’s transaction summary:

And because we can essentially select which chain we’d want to see, this immediately becomes a multi-chain wallet activity viewer.

If you want to run the project locally and check out the code yourself, you can do the following:

Bash
git clone https://github.com/xiaogit00/building-wallets.git
cd building-wallets
npm i
git checkout part7-multichain-wallet-activity-end
npm start

Just be sure to add your API key in a .env file, like so:

REACT_APP_APIKEY='ckey_8bdxxxxxxxxxxxxxxxxxxxxxxxxxx99'

Otherwise, stick around to follow along with the rest of this tutorial.

Ready? Let’s begin.

(Estimated time to follow along: 10mins)

Prerequisites

  • Basic familiarity with React.

  • Some HTML/CSS knowledge.

  • Fetching data using APIs.

Tutorial: Building a Multi-Chain Wallet Activity Summary

1

Initialize the Project

Run the following commands to download the template we’ll use for this guide:

git clone https://github.com/xiaogit00/building-wallets.git
cd building-wallets
npm i
git checkout part7-multichain-wallet-activity
1.1

Then, be sure to add your API key in a .env file, like so:

REACT_APP_APIKEY='ckey_8bdxxxxxxxxxxxxxxxxxxxxxxxxxx99'
1.2

Then, run:

npm start
1.3

Heading to http://localhost:3000 on your browser, you will be able to see this:

2

Fetching the Transaction Summary Data

First, let’s render the <WalletSummary /> component in App.js, supplying it with the following props:

// App.js
<WalletSummary 
	walletAddress={walletAddress} 
	chainId={selectedChainId} 
	chains={chains}
/>
2.1

Then, within WalletSummary.js, fetch the user’s transaction summary data in an effect hook:

Heading over to localhost:3000, you should be able to see your data in the dev console.

Congratulations, you’ve successfully fetched the wallet’s data.


// WalletSummary.js
const WalletSummary = ({ walletAddress, chainId, chains }) => {

    const [txnSummaryData, setTxnSummaryData] = useState(null)
    const [loading, setLoading] = useState(false)
    const txnSummaryEndpoint = `https://api.covalenthq.com/v1/${chainId}/address/${walletAddress}/transactions_summary/`
    const apiKey = process.env.REACT_APP_APIKEY
    
    
    useEffect(() => {
        setLoading(true)
        fetch(txnSummaryEndpoint, {method: 'GET', headers: {
          "Authorization": `Basic ${btoa(apiKey + ':')}`
        }})
          .then(res => res.json())
          .then(res => {
            console.log(res.data.items)
            setTxnSummaryData(res.data.items)
            setLoading(false)
          })
      }, [txnSummaryEndpoint, apiKey])
3

Rendering the Data in the Right Places

The next step is really simple. All you need to do is to render the data in the right places in the template! Go ahead and give it a try yourself.

Along the way, I’ve utilized some helper functions within utils.js to get the data rendered in the way I want:

  1. truncateEthAddress helps render a shortened Eth address

  2. blockExplorerURLs helps us map the selected chainId to the block explorer URL, useful for helping generate the base URL for the links to the block explorers of different chains.

Apart from that, nothing fancy.

3.1

Given it a go? Here’s what the final components WalletSummary and TransactionSummary look like:

JavaScript

//WalletSummary.js
import '../App.css';
import { truncateEthAddress } from '../utils';
import { useEffect, useState } from 'react';
import { blockExplorerURLs } from '../utils';
import { Spin } from 'antd';
import TransactionSummary from './TransactionSummary';

const WalletSummary = ({ walletAddress, chainId, chains }) => {

    const [txnSummaryData, setTxnSummaryData] = useState(null)
    const [loading, setLoading] = useState(false)
    const txnSummaryEndpoint = `https://api.covalenthq.com/v1/${chainId}/address/${walletAddress}/transactions_summary/`
    const apiKey = process.env.REACT_APP_APIKEY
    const copyText = () => {
        navigator.clipboard.writeText(walletAddress)
        
    }

    const foundChain = blockExplorerURLs.find(item => item.chainId[0] === Number(chainId))
    const blockExplorerURL = foundChain.url
    const selectedChainLogo = chains.find(item => Number(item.chain_id) === Number(chainId)).logo_url
    
    useEffect(() => {
        setLoading(true)
        fetch(txnSummaryEndpoint, {method: 'GET', headers: {
          "Authorization": `Basic ${btoa(apiKey + ':')}`
        }})
          .then(res => res.json())
          .then(res => {
            console.log(res.data.items)
            setTxnSummaryData(res.data.items)
            setLoading(false)
          })
      }, [txnSummaryEndpoint, apiKey])
    

    
    return(
        <>
        <div className='walletSummaryContainer'>
            <div className='userProfile'>
                <div><img className='profilePic' src="<https://res.cloudinary.com/dl4murstw/image/upload/v1685502715/user_3_sprzkr.png>" alt="profile" height="80px"/> </div>
                <div className='address'>{truncateEthAddress(walletAddress)} 
                <img src="<https://res.cloudinary.com/dl4murstw/image/upload/v1685502645/copy_prfttd.png>" alt="copy" height="12px" onClick={copyText} className='copyText'/>
                </div>
            </div>

            <div className='txnSummaryContainer'>
                <div className='textElem'>Activity</div>
                {loading
                ?<div className='spinner'><Spin /></div> 
                : <TransactionSummary 
                    chainLogo={selectedChainLogo} 
                    txnSummaryData={txnSummaryData}
                    blockExplorerURL={blockExplorerURL}
                    />
                }
            </div>
        </div>
    </>
    )
}

export default WalletSummary
3.2
JavaScript
//TransactionSummary.js
const TransactionSummary = ({ chainLogo, txnSummaryData, blockExplorerURL }) => {

    var options = {
        year: "numeric",
        month: "short",
        day: "numeric"
    }
    if (txnSummaryData) {
        return(
            <>
                <div className='txnCount'>
                            <div><img src={chainLogo} alt="chain" height="24px" className='chainLogo'/></div>
                            <div>{txnSummaryData[0].total_count} transactions </div>
                        </div>
    
                        <div className='buttonsRow'>
                            <a href={blockExplorerURL + "tx/" + txnSummaryData[0].latest_transaction.tx_hash} target="_blank" rel="noreferrer" className='link'>
                                <div className='buttons'>Latest Tx:&nbsp;  
                                    {new Date(txnSummaryData[0].latest_transaction.block_signed_at).toLocaleDateString('en', options)}&nbsp;
                                    <img src="<https://res.cloudinary.com/dl4murstw/image/upload/v1668603285/external-link_kl6vf5.png>" alt="link" height="8px"/>
                                </div>
                            </a>
    
                            <a href={blockExplorerURL + "tx/" + txnSummaryData[0].latest_transaction.tx_hash} target="_blank" rel="noreferrer" className='link'>
                                <div className='buttons'>Earliest Tx:&nbsp;
                                    {new Date(txnSummaryData[0].earliest_transaction.block_signed_at).toLocaleDateString('en', options)}&nbsp;
                                    <img src="<https://res.cloudinary.com/dl4murstw/image/upload/v1668603285/external-link_kl6vf5.png>" alt="link" height="8px"/>
                                </div>
                            </a>
                        </div>
            </>
        )
    }
    
}

export default TransactionSummary
3.3

Hit npm start and head over to the browser. You should see this component! You can also click through the various chains to see the wallet’s transaction summary on those chains. Very neat.

3.4

Again, to check out the end state if you have not followed along, simply run the following:

git checkout part7-multichain-wallet-activity-end
npm start

All in a Day’s Work

Congratulations. You’ve successfully managed to build a new feature into the multi-chain portfolio tracker by using Covalent’s endpoint. Hopefully you can see how such a tool is very useful for providing quick insights into wallet behavior, as well as how easy it is to integrate this into your Web3 wallet/portfolio tracker. Happy buidling!

Not fulfilling what you need? Reach out to us and let us know how to improve this endpoint.