Dashboard : Top 10 Ethereum Token Pairs
The following tutorial helps build a Top 10 Ethereum Tokens Dashboard with Next JS and Bitquery APIs that fetches and displays the Top 10 Token Pairs in last 1 hour on Ethereum mainnet in desceneding order of number of transactions.
Video Tutorial of the project
Github Repository
Github Code Repository - Repository Link
Prerequisites
- Node.js and npm installed on your system.
- Bitquery Account with OAuth token (follow instructions here).
- Git installed on your pc.
Code Walkthrough
Data Fetching
We are going to fetch our dashboard data using these 3 files -
1. data.js file -
We are using Bitquery API and made this getData
utility function which will fetch top 10 Token Pairs according to the transactions happened in them in last 1 hour.
Query used here gives the top pair addresses, tokens in them, total transactions, total buys, total sells, price in usd of the token ( at last 1 hour timestamp, past 5 min timestamp and current timestamp). We will use these prices to get Price change in our page.js
file.
You can test the saved query on ide here.
import axios from "axios";
// Function to fetch trade data
const getData = async () => {
// Get the current UTC time and subtract one hour and five minutes
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();
const min5backtimestamp = new Date(Date.now() - 5 * 60 * 1000).toISOString();
let data = JSON.stringify({
query: `
query MyQuery($oneHourAgo: DateTime, $min5backtimestamp: DateTime) {
EVM(network: eth, dataset: realtime) {
DEXTradeByTokens(
orderBy: {descendingByField: "total_trades"}
limit: {count: 10}
where: {
Block: {Time: {since: $oneHourAgo}},
Trade: {Side: {Currency: {SmartContract: {is: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"}}}},
TransactionStatus: {Success: true}
}
) {
Trade {
hour1: PriceInUSD(minimum: Block_Time)
min5: PriceInUSD(minimum: Block_Time, if: { Block: { Time: { after: $min5backtimestamp } } })
end: PriceInUSD(maximum: Block_Time)
Currency {
Name
Symbol
}
Side {
Currency {
Name
Symbol
}
}
Dex {
ProtocolName
ProtocolFamily
ProtocolVersion
SmartContract
}
}
total_trades: count
totalbuys: count(if: {Trade: {Side: {Type: {is: sell}}}})
totalsells: count(if: {Trade: {Side: {Type: {is: buy}}}})
total_traded_volume: sum(of: Trade_Side_AmountInUSD)
}
}
}
`,
variables: { oneHourAgo, min5backtimestamp },
});
let config = {
method: "post",
maxBodyLength: Infinity,
url: "https://streaming.bitquery.io/graphql",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "BQY7em4KPZ9CMvjl4aUUOPf2hqEBIHF1",
Authorization: process.env.NEXT_PUBLIC_BITQUERY_TOKEN,
},
data: data,
};
let response = await axios.request(config);
return response.data.data.EVM.DEXTradeByTokens;
};
export default getData;
2. liquidity.js file -
We are using Bitquery API here and have made this utility function getLiquidityData
to get current liquidity
and initial liquidity
of a particular pool. We are going to pass the 10 pool addresses to getLiquidityData
we are going to get when we call getData
in page.js
and get the initial and current liquidities for the top 10 pools.
You can test the saved query on ide here.
// liquidityData.js
import axios from "axios";
const getLiquidityData = async (poolAddresses) => {
let data = JSON.stringify({
query: `
query MyQuery ($poolAddresses: [String!]){
EVM(dataset: combined, network: eth) {
Initial_liquidity: Transfers(
limitBy:{by:Transfer_Receiver count:2}
orderBy: {ascending: Block_Time}
where: {Transfer: {Receiver: {in: $poolAddresses }}, TransactionStatus: {Success: true}}
) {
Transaction {
Hash
}
Transfer {
Receiver
Amount
Currency {
SmartContract
Name
Symbol
}
}
}
Current_liquidity: BalanceUpdates(
where: {BalanceUpdate: {Address: {in: $poolAddresses}}}
orderBy: {descendingByField: "balance"}
) {
Currency {
Name
SmartContract
Symbol
}
balance: sum(of: BalanceUpdate_Amount, selectWhere: {gt: "0"})
BalanceUpdate {
Address
}
}
}
}
`,
variables: { poolAddresses },
});
let config = {
method: "post",
maxBodyLength: Infinity,
url: "https://streaming.bitquery.io/graphql",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "BQYD4KszrYRIhb3cjIylKVLILgZfV0Ai",
Authorization: process.env.NEXT_PUBLIC_BITQUERY_TOKEN,
},
data: data,
};
let response = await axios.request(config);
return response.data.data.EVM;
};
export default getLiquidityData;
3. wethPrice.js file -
We used Bitquery API here to get the latest USD price of WETH
token as it will help us in converting Amount of WETH to USD Amount in current liquidity.
You can test the saved query on ide here.
import axios from "axios";
const getPrice = async () => {
let data = JSON.stringify({
query: `
query MyQuery{
EVM(network: eth, dataset: realtime) {
DEXTradeByTokens(
limit: {count: 1}
orderBy: {descending: Block_Time}
where: {Trade: {Currency: {SmartContract: {is: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"}}, Side: {Currency: {SmartContract: {is: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"}}}}, TransactionStatus: {Success: true}}
){
Trade{
PriceInUSD
}
}
}
}
`,
variables: {},
});
let config = {
method: "post",
maxBodyLength: Infinity,
url: "https://streaming.bitquery.io/graphql",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "BQYD4KszrYRIhb3cjIylKVLILgZfV0Ai",
Authorization: process.env.NEXT_PUBLIC_BITQUERY_TOKEN,
},
data: data,
};
let response = await axios.request(config);
return response.data.data.EVM.DEXTradeByTokens;
};
export default getPrice;
Dashboard frontend
page.js file
The page.js
file is a React component that serves as the main page for displaying the top 10 Ethereum token pairs traded in the last hour. It uses Bitquery APIs to fetch and display various data, including trade information, token prices, and liquidity data.
1. Imports
The component imports necessary dependencies, including React, hooks (useState
, useEffect
), and three functions (getData
, getPrice
, getLiquidityData
) used to fetch trade details, weth price, and liquidity data, respectively.
2. State Management
It uses the useState
hook to manage several states, such as trades
, liquidityData
, currentPage
, and price
.
3. Component Structure
a. State Initialization:
trades
: Stores the trade data.liquidityData
: Stores initial and current liquidity data.currentPage
: Keeps track of the current page number for pagination.price
: Stores the price data.
b. Data Fetching with useEffect
:
- The first
useEffect
fetches trade and price data usinggetData
andgetPrice
functions and sets thetrades
andprice
states. - The second
useEffect
fetches liquidity data once thetrades
data is available. It extracts pool addresses from the trades and fetches corresponding liquidity data using thegetLiquidityData
function.
c. Utility Functions:
truncateAddress(address)
: Truncates a given address for display purposes.calculatePriceChange(endPrice, hour1Price, min5Price)
: Calculates the percentage change in price over the last hour and the last 5 minutes.formatInitialLiquidity(liquidityList)
: Formats the initial liquidity for display, showing both token amounts.formatCurrentLiquidity(liquidityList, rowCurrencySymbol, currentPrice)
: Formats the current liquidity in USD based on the token amounts and prices.
d. Rendering:
- The component displays a table with information about the top 10 Ethereum pairs, including token pair, price, DEX, smart contract address, price change, total traded volume, transaction count, initial liquidity, and current liquidity.
- It uses the
currentTrades
variable to slice the trades array for pagination and display the trades of the current page.
e. Export:
- The component is exported as the default export of the file.
4. Key Components in the Table
- Token Pair: Displays the symbol of the trading pair.
- Price: Shows the current price in USD.
- DEX: The decentralized exchange where the pair is traded.
- Pair Smart Contract: A link to the smart contract address on the Bitquery explorer.
- Price Change (1 Hour and 5 Min): Displays the percentage price change in the last hour and last 5 minutes.
- Total Traded Volume: The total volume traded for the pair.
- Txns: The number of transactions, including buys and sells.
- Initial Liquidity: The initial liquidity provided in the pool.
- Current Liquidity: The current liquidity in USD.