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 100+ 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:

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)

Prerequisite

  • Basic familiarity with React

  • Some HTML/CSS knowledge

  • Fetching data using APIs

Step 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

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

REACT_APP_APIKEY='ckey_8bdxxxxxxxxxxxxxxxxxxxxxxxxxx99'

npm start

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

Step 2: Fetching the transaction summary data:

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

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

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

JavaScript
// 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])

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

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

Step 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.

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
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

Hitting npm start and heading over the the browser…

We get the above component! You can also click through the various chains to see the wallet’s transaction summary on those chains. Very neat.

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 Get transaction summary for address 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!

If you haven’t already, get your FREE API key today and give it a spin!


Like this how-to guide? Give it a RT on Twitter.

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

);