31
Building a Web3 App - Crypto Gas Tracker
Hello fellow humanoids. Blockchain has made it way one way or another in your life, if you have already dug deep in rabbit hole then you might know how expensive transaction fees can become on certain chains E.g: Ethereum.
Check out the app here : Crypto gas tracker

- Setup NextJS
- Get address from metamask
- Fetch transaction details
- Calculate Gas Fee
Lets go deep dive into each one and explore how it was implemented.
Next JS is a framework (built on-top of React JS) that allows us to create pre-rendered React websites. Follow this link to get yourself started on the setup
For this case we would be using metamask as our wallet. You can choose any as per your preference. Using Web3 apis we can connect to metamask and fetch the current network address of the user.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const getBlockchainInformation = async () => { | |
if (window.ethereum) { | |
console.log("Metamask"); | |
window.web3 = new Web3(window.ethereum); | |
await window.ethereum.enable(); | |
const ethereum = window.ethereum; | |
const walletAddress = ethereum.selectedAddress; | |
console.log("Wallet address", walletAddress); | |
} else if (window.web3) { | |
console.log("Update metamask"); | |
alert("Update metamask"); | |
} else { | |
console.log("Install metamask"); | |
alert("Install metamask"); | |
} | |
}; |
For fetching transactions we would be using Etherscan API to fetch the transaction details for the given address
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Client Side Code | |
const getTransactions = async (address) => { | |
const url = `/api/etherscan?address=${address}`; | |
const response = await fetch(url).then((resp) => resp.json()); | |
return response?.result ?? []; | |
}; | |
//Api route code | |
export default async function handler(req, res) { | |
// Run cors | |
await cors(req, res); | |
const query = req.query; | |
const etherscanApiKey= process.env.ETHERSCAN_API_KEY; | |
const url = `https://api.etherscan.io/api?module=account&action=txlist&address=${query?.address}&startblock=0&endblock=99999999&sort=asc&apikey=${etherscanApiKey}`; | |
const response = await fetch(url).then(resp => resp.json()); | |
res.json(response); | |
} |
As per the API response the fields gasUsed and gasPrice are used to get the total eth spent.
gasFee = gasUsed * gasPrice
Since ETHUSD pair price is very volatile, we would fetch the ETHUSD on the date of the transaction using Coingecko api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Client side | |
useEffect(() => { | |
const fn = async () => { | |
const transactions = | |
trnxs?.map(async (trnx) => { | |
const trnxDate = new Date(trnx.timeStamp * 1000); | |
let formatted_date = | |
trnxDate.getDate() + | |
"-" + | |
(trnxDate.getMonth() + 1) + | |
"-" + | |
trnxDate.getFullYear(); | |
const ethPriceHistoryUrl = `/api/coingecko-history?date=${formatted_date}`; | |
const historyData = await fetch(ethPriceHistoryUrl).then((resp) => | |
resp.json() | |
); | |
const ethUSD = historyData?.market_data?.current_price?.usd; | |
return { | |
...trnx, | |
gasFee: (trnx.gasPrice * trnx.gasUsed * ethUSD) / 1e18, | |
gasFeeEth: (trnx.gasPrice * trnx.gasUsed) / 1e18, | |
ethUSD: ethUSD, | |
}; | |
}) ?? []; | |
const values = await Promise.all(transactions); | |
setUpdatedTrnxs(values); | |
}; | |
fn(); | |
}, [trnxs]); | |
// Api route | |
export default async function handler(req, res) { | |
// Run cors | |
await cors(req, res); | |
const query = req.query; | |
const url = `https://api.coingecko.com/api/v3/coins/ethereum/history?date=${query?.date}`; | |
const response = await fetch(url).then(resp => resp.json()); | |
res.json(response); | |
} |
This app was made as part of learning Web3 apps. There might be bugs and enhancements on the way. Please feel free to provide feedback.
Stay safe and lend a hand to another :)
31