Unleashing the Power of Messari Standardized Subgraphs: Querying Multiple DeFi Exchanges Simultaneously
May 15th, 2024

Final repo of this blog.


If you’re diving into the world of decentralized finance (DeFi), you know how important it is to get accurate and comprehensive data. But what if we could get this data not just from one DeFi protocol, but from dozens all at once?

That’s where Messari’s standardized subgraphs come in.

These standardized subgraphs let us query multiple exchanges with a single query, essentially asking the same question of many different DeFi communities all at the same time! Imagine being able to track the Total Value Locked (TVL) across dozens of different protocols or analyzing trade volumes and user metrics - all with a single query!

In this post, we’ll walk you through the advantages of using Messari standardized subgraphs, show you how to query multiple exchanges, and even give you some creative queries to try out. Let’s get started!

Why Messari Standardized Subgraphs Are Awesome

  1. Consistent Data Structure: Messari's subgraphs stick to a consistent schema, making it super easy to write queries that work across different exchanges. No more tweaking queries for each platform!

  2. Comprehensive Insights: By querying multiple exchanges at once, you can get a complete view of the DeFi landscape. This is perfect for comparing TVL, spotting market trends, and finding new opportunities.

  3. Efficient and Fast: Standardized subgraphs let you fetch data from various sources in one go. This saves time and cuts down on the hassle of handling multiple data sources.

How to Query Multiple Exchanges: A Step-by-Step Guide

Step 1: Find Messari Subgraphs that Index Exchanges

Go to subgraphs.messari.io and find the Exchanges category. All subgraphs under each category have the same standardized schema for us to query (Exchanges, erc721, Governance, etc).

We will query Messari’s Curve Finance subgraph and their SushiSwap subgraph, however if we wanted to we could send this query to nearly 40(!) Messari-standard Exchange subgraphs. Every Messari Exchange subgraph uses this schema, which will make designing queries simple!

Step 2: Design a Query and Test in the Subgraph’s Playground

Let’s find the TVL of both Curve Finance and SushiSwap on August 20th, 2023.

After analyzing the subgraph’s schema, as well as finding the UNIX timestamp for that specific date, here is our GraphQL query:

{
  dailySnapshot8_20_23: financialsDailySnapshots(
	where: {timestamp_gte: 1629417600, timestamp_lt: 1629504000},
  ) {
	totalValueLockedUSD
  }
}

We can run this query in each subgraph’s playground and see both are returning data:

But now, how do we build this in programmatically into our dapp?

Step 3: Set Up Our Project

First things first, make sure you have Node.js installed. Then, set up a new project:

mkdir messari-subgraphs
cd messari-subgraphs
npm init -y

Step 4: Gather Subgraph Endpoints

Create a file named app.js and gather both subgraph’s endpoints by pressing the Query button on each of their dashboards.

Save the endpoints as an array inside of a getTVLs() function:

//app.js	

async function getTVLs() {
        const urls = [
		{
			url: "https://gateway.thegraph.com/api/<API_KEY>/subgraphs/id/GAGwGKc4ArNKKq9eFTcwgd1UGymvqhTier9Npqo1YvZB",
			name: "Curve Finance",
		},
		{
			url: "https://gateway.thegraph.com/api/<API_KEY>/subgraphs/id/7h1x51fyT5KigAhXd8sdE3kzzxQDJxxz1y66LTFiC3mS",
			name: "SushiSwap",
		},
	];
};

Step 5: Gather API Key

Go to Subgraph Studio and set up an API Key, then drop the API key into the endpoints:

//app.js

async function getTVLs() {
  const urls = [
	  	{
			url:     "https://gateway.thegraph.com/api/0ab7a83b03a36ac8a536cd8fa19a8ad4/subgraphs/id/GAGwGKc4ArNKKq9eFTcwgd1UGymvqhTier9Npqo1YvZB",
			name: "Curve Finance",
		},
		{
			url: "https://gateway.thegraph.com/api/0ab7a83b03a36ac8a536cd8fa19a8ad4/subgraphs/id/7h1x51fyT5KigAhXd8sdE3kzzxQDJxxz1y66LTFiC3mS",
			name: "SushiSwap",
		},
	];
};

Step 6: Programmatically Send Query to Endpoints

Next, we will create an array of POST requests to fetch the Total Value Locked (TVL) data for August 20th, 2023, from multiple subgraphs:

//app.js

const requests = urls.map((entry) =>
		fetch(entry.url, {
			method: "POST",
			headers: {
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				query: `
					{
						dailySnapshot8_20_23: financialsDailySnapshots(
							where: { timestamp_gte: 1629417600, timestamp_lt: 1629504000 }
						) {
							totalValueLockedUSD
						}
					}
				`,
			}),
		})
	);

	const results = await Promise.all(requests);
	const tvls = await Promise.all(results.map((result) => result.json()));

By using the map function on the urls array, we ensure that each subgraph endpoint is queried with the same GraphQL query.

Step 7: Display The Returned Data

Now that we've fetched the data from multiple subgraphs, the next step is to display it on our webpage. We will take the data returned from the subgraphs and dynamically create HTML elements to show this information.

  1. Get the Data Container:

    • First, we need to select the HTML element where we will display our data. This element should have the ID data-container.
  2. Iterate Over the Results:

    • We loop through the array of TVL results, and for each result, we create a new HTML div element to display the data.
  3. Create HTML Elements:

    • Inside this loop, we create elements for the exchange name and the TVL, and then append these elements to the data-container.

Here is the final app.js file:

async function getTVLs() {
	const urls = [
		{
			url: "https://gateway.thegraph.com/api/0ab7a83b03a36ac8a536cd8fa19a8ad4/subgraphs/id/GAGwGKc4ArNKKq9eFTcwgd1UGymvqhTier9Npqo1YvZB",
			name: "Curve Finance",
		},
		{
			url: "https://gateway.thegraph.com/api/0ab7a83b03a36ac8a536cd8fa19a8ad4/subgraphs/id/7h1x51fyT5KigAhXd8sdE3kzzxQDJxxz1y66LTFiC3mS",
			name: "SushiSwap",
		},
	];

	const requests = urls.map((entry) =>
		fetch(entry.url, {
			method: "POST",
			headers: {
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				query: `
					{
						dailySnapshot8_20_23: financialsDailySnapshots(
							where: { timestamp_gte: 1629417600, timestamp_lt: 1629504000 }
						) {
							totalValueLockedUSD
						}
					}
				`,
			}),
		})
	);

	const results = await Promise.all(requests);
	const tvls = await Promise.all(results.map((result) => result.json()));

	const dataContainer = document.getElementById("data-container");
	tvls.forEach((feed, index) => {
		const platformName = urls[index].name;
		const feedData = feed.data.dailySnapshot8_20_23;
		feedData.forEach((snapshot) => {
			const snapshotElement = document.createElement("div");
			snapshotElement.innerHTML = `
				<h3>${platformName}</h3>
				<p>Total Value Locked USD: ${snapshot.totalValueLockedUSD}</p>
				<hr>
			`;
			dataContainer.appendChild(snapshotElement);
		});
	});
}

getTVLs();

Step 8: Create the HTML File

Create an HTML file to display the results:

// index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>TVL on Aug 20th, 2023</title>
		<link rel="stylesheet" href="styles.css" />
		<link
			href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,300;1,300&display=swap"
			rel="stylesheet"
		/>
	</head>
	<body class="container">
		<h1>TVL on Aug 20th, 2023</h1>
		<div id="data-container"></div>
		<script type="text/javascript" src="app.js"></script>
	</body>
</html>

Step 9: Add Some Style

Create a CSS file (styles.css) to make everything look nice:

// styles.css

body {
	font-family: "Raleway", sans-serif;
	background-color: #f4f4f9;
	color: #333;
	margin: 0;
	padding: 20px;
}

.container {
	max-width: 800px;
	margin: auto;
	padding: 20px;
	background-color: #ffffff;
	box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

h1 {
	color: #0a4870;
	text-align: center;
}

div#data-container {
	margin-top: 20px;
}

div#data-container > div {
	padding: 10px;
	border-bottom: 1px solid #eee;
}

h3 {
	color: #0a4870;
	margin: 0 0 5px 0;
}

p {
	margin: 5px 0;
}

hr {
	margin-top: 10px;
	border: none;
	height: 1px;
	background-color: #eee;
}

More Creative Queries for Exchange Subgraphs

Once you’ve got the basic setup down, you can start writing more interesting queries to get even more insights about many DeFi protocols. Here are a few ideas:

Number of Daily Active Users Between Jan 1st, 2021 and Feb 1st, 2021

query DailyActiveUsers {
  usageMetricsDailySnapshots(
    where: {timestamp_gt: "1609480861", timestamp_lt: "1612159261"}
  ) {
    dailyActiveUsers
    timestamp
  }
}

Daily Trading Volume, Daily Revenue, and TVL Over the Past 10 Days

{
  financialsDailySnapshots(
    first: 10
    orderBy: timestamp
    orderDirection: desc
  ) {
    timestamp
    dailyVolumeUSD
    dailyTotalRevenueUSD
    totalValueLockedUSD
  }
}

By querying these standardized subgraphs, you can gather valuable insights across multiple exchanges efficiently, helping you stay ahead in the fast-paced DeFi landscape. Happy querying!

Marcus Rein

Developer Relations and Success

Edge & Node - Working on The Graph

Subscribe to madavre.eth
Receive the latest updates directly to your inbox.
Nft graphic
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from madavre.eth

Skeleton

Skeleton

Skeleton