Deploy a Subgraph Using The Graph and Hedera JSON-RPC Relay
Last updated
Last updated
In this tutorial, you'll learn how to create and deploy a subgraph using The Graph protocol. By indexing specific network data using user-defined data structures called "subgraphs," developers can easily query the indexed data through a GraphQL API, creating robust backends for dApps. Subgraphs simplify the process of obtaining blockchain/network data for developers building dApps. This approach removes the complexities of interacting directly with the network, allowing developers to focus on building. Although Hedera supports subgraphs, its hosted service is currently unavailable, so we'll need to set up and run a local graph node to deploy our subgraph.
By the end of this tutorial, you'll be able to configure a mirror node, query data from your subgraph using the GraphQL API, and integrate it into your dApp. You'll also have a better understanding of how to define custom data schemas, indexing rules, and queries for your subgraph, allowing you to tailor it to your specific use case.
Note: While it is possible to present and interact with HTS tokens in a similar manner as ERC-20/721 tokens, the network is presently unable to capture all the expected ERC-20/721 event logs. In other words, if ERC-like operations are conducted on HTS tokens, not all of them will be captured in smart contract event logging.
Basic understanding of JavaScript and NPM installed.
Basic understanding of subgraphs and the Graph CLI installed.
The deployed Greeter smart contract address from the Hardhat tutorial.
The start block number of when the Greeter smart contract was first deployed.
Docker >= v20.10.x
installed and open on your machine. Run docker -v
in your terminal to check the version you have installed.
Open a terminal window and navigate to the directory where you want your subgraph project stored. Clone the hedera-subgraph-example
repo, change directories, and install dependencies:
Rename the subgraph.template.yaml
file to subgraph.yaml
before moving on to the next step. The subgraph project structure should look something like this:
In the testnet.json
file, under the config
folder, replace the startBlock
and Greeter
fields with your start block number and contract address. The JSON file should look something like this:
In this step, you will use the Greeter
contract from the Hardhat tutorial as an example subgraph, to configure four main project files: the subgraph manifest, GraphQL schema, event mappings, and Docker compose configuration. The manifest specifies which events the subgraph will listen for, while mappings map each event emitted by the smart contract into entities that can be indexed.
The subgraph manifest (subgraph.yaml
) contains important information about your subgraph, such as its name, description, and data sources. To specify the data sources your subgraph will index, you need to define the dataSources
field in the manifest. It's also recommended to add the start block number to the startBlock
property to reduce the indexing time. Here's a guide on how to find the start block number.
Add your deployed Greeter public smart contract address to the address
property.
Add your start block number of the deployed contract in the startBlock
property.
The eventHandlers
field specifies how each mapping connects to various event triggers. Whenever an event defined in this section is emitted from your contract, the corresponding mapping function designated as the handler will be executed.
The GraphQL schema (schema.graphql
) defines the structure of the data you want to index in your subgraph. You will need to specify the entity properties that you want to index. For this example, the schema defines a GraphQL entity type called "Greeting" with two entity fields: id
and currentGreeting
.
The mappings.ts
file maps events emitted by your smart contract into entities that can be indexed by a subgraph. It uses AssemblyScript to connect the events to the data schema. AssemblyScript types for entities and events can be generated in the terminal (by running the codegen
command) and imported into the mappings file. This allows easy access to the event object's properties in the code editor.
To connect a local graph node to a remote network, such as testnet, mainnet, or previewnet, use a docker-compose setup. The API endpoint that connects the graph node to the network is specified within the environment
object of the docker-compose.yaml
file here. Add the API endpoint URL in the ethereum
field in the environment
object. For this tutorial, we will use the Hashio Testnet instance of the Hedera JSON-RPC relay, but any JSON-RPC provider supported by the community can be used.
This is what the ethereum
field should look like after you enter your API endpoint URL:
Note: For more info on how to set up an indexer, check out T_he Graph_ docs and the official graph-node GitHub repository. For a full subgraph project example, check out this repo.
In this step, you will create the subgraph and deploy it to your local graph node. If everything runs without errors, your terminal should resemble the console check at the end of each subsection.
To start your local graph node, have the Docker engine running before executing the below command in your project directory:
In the same directory, run the following command to generate AssemblyScript types for entities and events:
You should have a new folder named generated
in your project directory. This is what your updated subgraph project structure should look like:
To create and deploy your subgraph to your local graph node, run:
When you run the deploy-local
command, your console will prompt you to provide a Version Label
. Enter any version number you'd like. This is just a way to keep track of different versions of your subgraph. For instance, if you started with version v0.0.1 today, but then made some changes and wanted to deploy an upgraded version, you bump up the version number to v0.0.2.
For example: ✔ Version Label (e.g. v0.0.1) · v0.0.1
Once the node finishes indexing, you can access the GraphQL API at: http://localhost:8000/subgraphs/name/Greeter
Follow the steps below to execute the query and fetch the indexed data from the subgraph's entities:
Enter the following GraphQL query into the left column of the playground (see Step 1 in the screenshot below):
Execute the query by clicking on the play button at the top of the playground (see Step 2 in the screenshot below).
The query returns the indexed data from the subgraph's entities on the right column of the playground (see Step 3 in the screenshot below):