KIP Protocol Developer Guide
  • Introduction
    • High-level Architecture
  • Features
    • Assets Tokenization
    • Monetization
    • Friendly User Experience
    • Integration Flexibility
    • Security and Sovereignty
    • Fraud and Scam Protection
  • How to Build DeAI Products Using KIP
    • App Makers
    • Model Trainers
    • Dataset Owners
    • Users
  • Developer Guide
    • Standard APIs
      • User - App
      • App - Generation Model
      • App - Embedding Model
      • App - Dataset
    • KIP Ecosystem Core Contracts
      • KIP Management
      • KIP Identification
      • KIP Registration
      • KIP Service
    • Account Abstraction
      • Particle Network
    • Fetch Blockchain Data
      • Using RPC Node
        • RPC Node Providers
          • Alchemy
          • Infura
        • Fetch Data Example
      • Using Subgraph
        • Deploy Subgraph
        • Query using Subgraph
    • KIP Checker Node Execution Guide
      • Checker Node Guide
Powered by GitBook
On this page
  1. Developer Guide
  2. Fetch Blockchain Data
  3. Using Subgraph

Query using Subgraph

PreviousDeploy SubgraphNextKIP Checker Node Execution Guide

Last updated 10 months ago

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

Contracts:

  • Mock KIPToken Contract:

    • Retrieve the current balance of an account

    • Retrieve the allowance amount that an account has granted to a spender

Prerequisites:

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

  • 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'
    }
  ]
0x4b565A132347064Ca7F1eDC9489a00b3E68431dd
here