DEV Community

Cover image for Building And Deploying A Subgraph (Part 2)
Adebayo Olamilekan
Adebayo Olamilekan

Posted on

Building And Deploying A Subgraph (Part 2)

Just like how fries can be eaten alone 🍟 or eaten together with either ketchup or mayonnaise, this tutorial is both 1) a standalone tutorial for deploying and querying a subgraph. 2) a continuation from my previous tutorial on building a savings dapp.

Table of contents

  1. Prerequisites
  2. Introduction
  3. Tips to know about subgraphs
  4. Initialize Subgraph
  5. Tweak Code and Deploy
  6. Querying Subgraph
  7. Conclusion

Prerequisites

To build, deploy, and query from a subgraph you will need the following essentials:

  • A deployed smart contract (whether verified or not),
  • a crypto wallet,
  • a subgraph studio account,
  • and a cup of coffee ☕.

Before we start building the subgraph project, ensure you have the following above, done? now take a sip 🍵 and let's start building.

Introduction

A subgraph according to The Graph (which is a decentralized protocol for indexing and querying blockchain data) is a custom API built on blockchain data. They are queried using the GraphQL query language and are deployed to a Graph Node using the Graph CLI.

In simpler terms, a subgraph is like a customizable API for easily querying and getting specific data from a blockchain using GraphQL.

To get started, we need to have a subgraph studio account, which is very easy to do in 2 simple steps;

  • Connect your wallet and
  • Sign a message, then you should have a page like this;

studio

Click on the Create a Subgraph button and enter a subgraph name. You have successfully created a subgraph. well-done!!

Tips to know about subgraphs

  1. Deleting a subgraph is not possible once it's created.
  2. Once a subgraph is created, the name cannot be changed.
  3. To enable faster and more easy querying of data from a subgraph, the contract associated with it should emit events.
  4. Subgraph mappings are written in AssemblyScript therefore using libraries like ether.js in the subgraph is not possible.

You can check out more of the tips or FAQs of a subgraph here

Initialize Subgraph

On the lower right side (you will have to scroll down) of your dashboard page of the subgraph you just created, steps on how to Initialize, Deploy and Build the subgraph are shown.

Iion

Following the steps;

  • We need to install the graph cli before a subgraph can be initialized.
npm install -g @graphprotocol/graph-cli

or

yarn global add @graphprotocol/graph-cli
Enter fullscreen mode Exit fullscreen mode
  • After the installation, run the below
graph init --studio <SUBGRAPH_NAME>
Enter fullscreen mode Exit fullscreen mode

Here you will be asked for the protocol, chain and other information of the contract you want to subgraph, following the last tutorial of writing, deploying and verifying our crypto-saves smart contract, these are the answers to the questions from the terminal:

  • Protocol: ethereum
  • Subgraph Slug: Crypto-Saves (or any name you want)
  • Directory to create the subgraph in: Crypto-Saves (or anywhere you want)
  • Ethereum Network: mumbai (the chain where the contract was deployed)
  • Contract Address: 0x4b1d98af1af713456c1fc86afed67b94c4648f6d (Contract Address)

Iption

instal

  • After you receive the Subgraph created message then run the next command;
graph auth --studio <DEPLOY_KEY>
cd <Name_of_subgraph>
Enter fullscreen mode Exit fullscreen mode
  • Using the events of the contract, the graph auto-generates the subgraph's code which needs little to no tweaking before deployment and publishing. The command below auto-generates the code and then builds it.
graph codegen && graph build
Enter fullscreen mode Exit fullscreen mode

n


Now take another sip of that coffee ☕

Tweak Code and Deploy

Navigate to the src folder in the subgraph root directory, then check the auto-generated file, the graph does splendid work and most times the file doesn't need tweaking and you can just deploy directly, but following my tutorial (Personal Crypto Savings Dapp) series, a little tweaking is needed.

Change the code in the schema.graphql file in the root directory to the following updated code:

type EtherLocked @entity(immutable: true) {
  id: ID!
  name: String! # string
  owner: Bytes! # address
  amount: BigInt! # uint256
  releaseTime: BigInt! # uint256
  lockType: String! 
  locked: Boolean
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

type EtherUnlocked @entity(immutable: true) {
  id: ID!
  name: String! # string
  owner: Bytes! # address
  amount: BigInt! # uint256
  locked: Boolean
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

type LockupTimeExtended @entity(immutable: true) {
  id: ID!
  name: String! # string
  owner: Bytes! # address
  releaseTime: BigInt! # uint256
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

type OwnershipTransferred @entity(immutable: true) {
  id: ID!
  previousOwner: Bytes! # address
  newOwner: Bytes! # address
  blockNumber: BigInt!
  blockTimestamp: BigInt!
  transactionHash: Bytes!
}

Enter fullscreen mode Exit fullscreen mode

Here I updated the schema and changed some types for better querying results. After this run:

graph codegen 
Enter fullscreen mode Exit fullscreen mode

This would update the generated folder with the new types and fields obtained from the update of the schema.graphql, to complete this we will need to change some things in a file under the src folder to:

import {
  EtherLocked as EtherLockedEvent,
  EtherUnlocked as EtherUnlockedEvent,
  LockupTimeExtended as LockupTimeExtendedEvent,
  OwnershipTransferred as OwnershipTransferredEvent,
} from "../generated/CryptoSaves/CryptoSaves";
import {
  EtherLocked,
  EtherUnlocked,
  LockupTimeExtended,
  OwnershipTransferred,
} from "../generated/schema";

export function handleEtherLocked(event: EtherLockedEvent): void {
  let entity = EtherLocked.load(event.params.id.toString());

  if (!entity) {
    entity = new EtherLocked(event.params.id.toString());
  }
  entity.name = event.params.name;
  entity.owner = event.params.owner;
  entity.amount = event.params.amount;
  entity.releaseTime = event.params.releaseTime;
  entity.lockType = event.params.lockType;
  entity.locked = true;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

export function handleEtherUnlocked(event: EtherUnlockedEvent): void {
  let entity = EtherLocked.load(event.params.id.toString());

  if (!entity) {
    return;
  }
  entity.locked = false;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

export function handleLockupTimeExtended(event: LockupTimeExtendedEvent): void {
  let entity = EtherLocked.load(event.params.id.toString());
  if (!entity) {
    return;
  }
  entity.releaseTime = event.params.releaseTime;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

export function handleOwnershipTransferred(
  event: OwnershipTransferredEvent
): void {
  let entity = new OwnershipTransferred(event.transaction.hash.toString());
  entity.previousOwner = event.params.previousOwner;
  entity.newOwner = event.params.newOwner;
  entity.blockNumber = event.block.number;
  entity.blockTimestamp = event.block.timestamp;
  entity.transactionHash = event.transaction.hash;

  entity.save();
}

Enter fullscreen mode Exit fullscreen mode

I am essentially doing another layer of checks before updating the fields after each event has been emitted.

Deploy

graph deploy --studio <SUBGRAPH_NAME>
Enter fullscreen mode Exit fullscreen mode

This deploys your subgraph to production, enabling querying from either the playground or in your front-end application.

on

Querying Subgraph

A subgraph can be queried from the frontend application or from the playground that the subgraph studio offers, which I find very helpful.

Imdescription

Just like in the image you can write queries on the left side of the playground and get results on the right part. An explorer tab is also on the right part; which auto-generates queries by just clicking on the desired parameters.

Frontend Application querying can be done in 3 different ways:

  1. Graph client
  2. Apollo client
  3. URQL

I prefer to use the Apollo client, and I will use this in the frontend aspect of the crypto savings dapp in my next tutorial.

Conclusion

Congratulations on making it to the end of this tutorial!🎉 You should now have a good understanding of what subgraphs are, why they are useful, and how to initialize, deploy, and query them. With this knowledge, you can begin creating your subgraphs to interact with various contracts and gain insights into their behavior. Run into a wall? ask away in the comments.

Its over

Top comments (0)