Query using Subgraph

This section will guide you through querying contract state data from the blockchain using a deployed Subgraph.

Contracts:

Prerequisites:

  • Deployed Subgraph on Alchemy. If not, please follow the instructions [here].

  • NodeJS: version v20.14.0 or v20.15.0.

  • Package Manager: yarn or npm.

Query Example

Folder Structure:

query-subgraph
├── package.json
├── src
   ├── main.ts
   └── query.ts
└── tsconfig.json

Let's get started:

  1. Create a project folder:

mkdir query-subgraph && cd query-subgraph
  1. Create package.json and install dependencies:

  • Create package.json

  touch package.json && open package.json
  • Add the following content to package.json:

  {
    "name": "query-subgraph",
    "version": "1.0.0"
  }
  • Install dependencies:

  yarn add @types/node dotenv typescript axios graphql graphql-tag
  # or
  npm install --save-dev @types/node dotenv typescript axios graphql graphql-tag
  1. Create tsconfig.json:

  • Create the file:

  touch tsconfig.json && open tsconfig.json
  • Add the following content to tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "resolveJsonModule": true
  },
  "include": ["src"]
}
  1. Create .env file:

  • Create the file:

  touch .env && open .env
  • Add the following content to .env:

# You can get the endpoint once you have completed deploying a subgraph onto Alchemy
# Please check your Alchemy Dashboard to retrieve the endpoint
END_POINT=YOUR_ENDPOINT
  1. Create a script to query from the Alchemy Subgraph:

  • Create a script file:

mkdir src && cd src
touch query.ts && open query.ts
  • Add the following code to the query.ts script:

import axios from "axios";
import { gql } from "graphql-tag";
import * as dotenv from "dotenv";
dotenv.config();

const END_POINT = process.env.END_POINT as string;

const GET_ACCOUNT_BALANCE = gql`
  query GetAccountBalance($account: ID!) {
    account(id: $account) {
      id
      balance
    }
  }
`;

const GET_ALLOWANCE_QUERY = `
  query GetAllowance($account: Bytes!, $spender: Bytes!) {
    approvals(where: { owner: $account, spender: $spender }) {
      id
      owner
      spender
      value
    }
  }
`;

export async function getAccountBalance(account: string) {
  const response = await axios.post(END_POINT, {
    query: GET_ACCOUNT_BALANCE.loc?.source.body,
    variables: { account },
  });

  const result = response.data;
  if (result.errors) {
    throw new Error(
      result.errors.map((error: any) => error.message).join(", ")
    );
  }

  return result.data.account;
}

export async function getAllowance(account: string, spender: string) {
  const response = await axios.post(END_POINT, {
    query: GET_ALLOWANCE_QUERY,
    variables: {
      account,
      spender,
    },
  });

  const result = response.data;
  if (result.errors) {
    throw new Error(
      result.errors.map((error: any) => error.message).join(", ")
    );
  }
  return result.data.approvals;
}
  1. Create main.ts to test the setup:

  • Create the file:

touch main.ts && open main.ts
  • Add the code into main.ts:

import { getAccountBalance, getAllowance } from "./query";

async function main() {
  const account = "0x31003C2D5685c7D28D7174c3255307Eb9a0f3015"; // Replace with your actual address
  const info = await getAccountBalance(account.toLowerCase());
  console.log("Account Info: ", info);

  const spender = "0x87a7A0223D6F96B3DECaAf3666d5c550b36fEfEe"; // Replace with your actual address
  const approvals = await getAllowance(
    account.toLowerCase(),
    spender.toLowerCase()
  );
  console.log("Approvals: ", approvals);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });
  1. Run the test:

  cd .. && npx ts-node src/main.ts
  • After running, you should see output similar to the following:

  Account Info:  {
    id: '0x31003c2d5685c7d28d7174c3255307eb9a0f3015',
    balance: '100880000000000000000420'
  }
  Approvals:  [
    {
      id: '0xcb3b4d2a7f03778547b90602d21a78887660ee2df73029cae2b6c63a00245ff80b000000',
      owner: '0x31003c2d5685c7d28d7174c3255307eb9a0f3015',
      spender: '0x87a7a0223d6f96b3decaaf3666d5c550b36fefee',
      value: '100000000000000000000'
    }
  ]

Last updated