DEV Community

Raven Arts
Raven Arts

Posted on

Create a Simple Transaction Indexer on Juneo Supernet Using Squid SDK

In this tutorial, we will create a simple transaction indexer on the Juneo Supernet using the Squid SDK.

Before we begin, some of you might be wondering: What is Juneo Supernet, and what is Squid SDK?

  • Juneo Supernet is a blockchain ecosystem built upon the Snowman++ consensus protocol, a highly scalable and efficient version of the Avalanche consensus. It provides a permissionless platform for deploying decentralized applications (dApps) and custom blockchains.

  • Squid SDK is a developer toolkit for building data indexers on blockchain networks. It streamlines the process of extracting, processing, and querying on-chain data for applications like analytics dashboards, DeFi platforms, and dApps.

Let's dive in!

Prerequisites

  • Docker (for running PostgreSQL)
  • Node.js 20

Steps to Build the Indexer

1. Initialize the Project

Create a new folder and initialize a new project:

npm init
Enter fullscreen mode Exit fullscreen mode

2. Install Required Packages

Run the following commands to install the necessary dependencies:

npm i dotenv typeorm @subsquid/evm-processor @subsquid/typeorm-store @subsquid/typeorm-migration @subsquid/graphql-server @subsquid/evm-abi
npm i typescript @subsquid/typeorm-codegen @subsquid/evm-typegen --save-dev
Enter fullscreen mode Exit fullscreen mode

3. Add a Minimal tsconfig.json

Create a tsconfig.json file:

{
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "lib",
    "module": "commonjs",
    "target": "es2020",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Create a Simple GraphQL Schema

Create a schema.graphql file with the following content:

type Transaction @entity {
  id: ID!
  from: String! @index
  to: String! @index
  value: BigInt!
}
Enter fullscreen mode Exit fullscreen mode

5. Generate TypeORM Model Entity

Run the following command to generate TypeORM models based on your schema:

npx squid-typeorm-codegen
Enter fullscreen mode Exit fullscreen mode

6. Set Up the Database

Create a .env file:

DB_NAME=squid
DB_PORT=23798
Enter fullscreen mode Exit fullscreen mode

Create a docker-compose.yaml file:

version: "3"
services:
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: "${DB_NAME}"
      POSTGRES_PASSWORD: postgres
    ports:
      - "${DB_PORT}:5432"
Enter fullscreen mode Exit fullscreen mode

Run the database container:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

7. Generate and Apply Migrations

Compile the TypeORM classes:

npx tsc
Enter fullscreen mode Exit fullscreen mode

Generate the migration file:

npx squid-typeorm-migration generate
Enter fullscreen mode Exit fullscreen mode

Apply the migration:

npx squid-typeorm-migration apply
Enter fullscreen mode Exit fullscreen mode

8. Create the Main Script

Create src/main.ts and add the following code:

import { EvmBatchProcessor } from '@subsquid/evm-processor';
import { TypeormDatabase } from '@subsquid/typeorm-store';
import { Transaction } from './model';

const ADDRESS = 'TARGET_ADDRESS EG 0x912312321hjahd123'.toLowerCase();

const processor = new EvmBatchProcessor()
    .setRpcEndpoint('https://rpc.socotra-testnet.network/ext/bc/JUNE/rpc')
    .setBlockRange({
        from: 9_083_000
    })
    .setFinalityConfirmation(75)
    .addTransaction({
        from: [ADDRESS],
        traces: true,
    })
    .addTransaction({
        to: [ADDRESS],
    })
    .setFields({
        transaction: {
            from: true,
            to: true,
            value: true,
            hash: true,
        }
    });

processor.run(new TypeormDatabase(), async (ctx) => {
    const txs: Transaction[] = [];
    for (let c of ctx.blocks) {
        for (let txn of c.transactions) {
            const tx = txn as any;
            if (tx.to === ADDRESS || tx.from === ADDRESS) {
                txs.push(new Transaction({
                    id: tx.hash,
                    from: tx.from,
                    to: tx.to,
                    value: tx.value,
                    hash: tx.hash,
                }));
            }
        }
    }

    await ctx.store.insert(txs);
});
Enter fullscreen mode Exit fullscreen mode

9. Compile and Run the Indexer

Compile the code:

npx tsc
Enter fullscreen mode Exit fullscreen mode

Run the indexer:

node -r dotenv/config lib/main.js
Enter fullscreen mode Exit fullscreen mode

10. Check the Results

Use a database management tool like Navicat or TablePlus to verify the stored transactions.

Example :

Image description

And that's it! Your simple transaction indexer is ready. Thank you for reading!

Top comments (0)