> ## Documentation Index
> Fetch the complete documentation index at: https://docs.peaq.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Subsquid

**Indexers** provide an easy solution to query on-chain data. They process smart contract events in the background and store them in a database, which you can query using GraphQL.
This enables efficient access to all smart contract events and allows for filtering the data as needed.

## Prerequisites

* **Node.js 20.x or later** is installed.
* **Docker** is installed, and you have basic knowledge of using it.

## Instructions

### Install Subquid

**Create a Squid:** Follow the instructions for [creating a Squid](https://docs.sqd.dev/squid-cli/installation/).

* During setup, create a new Squid with a name of your choice. This will be used later.

### Create the Indexer

#### Initialize the JavaScript environment

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npm init
```

#### Install required packages

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
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
```

#### Add `tsconfig.json`

Create a `tsconfig.json` file in your project root with the following configuration:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
{
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "lib",
    "module": "commonjs",
    "target": "es2020",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
```

#### Define the schema

Create a `schema.graphql` file and define the database schema. For example:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
type Transfer @entity {
  id: ID!
  from: String! @index
  to: String! @index
  value: BigInt!
}
```

This schema represents the structure of the events you want to store in your database.

#### Generate TypeORM entities

Run the following command to generate TypeORM entities based on the schema:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npx squid-typeorm-codegen
```

#### Create a `.env` file

Define the database credentials in a `.env` file:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
DB_NAME=peaq
DB_PORT=23798
```

#### Create `docker-compose.yaml`

Create a `docker-compose.yaml` file to set up a PostgreSQL database:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
version: "3"
services:
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: "${DB_NAME}"
      POSTGRES_PASSWORD: postgres
    ports:
      - "${DB_PORT}:5432"
```

Start the database container:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
docker compose up -d
```

#### Compile TypeORM classes

Compile the generated TypeORM classes:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npx tsc
```

#### Generate and apply migrations

* Generate the migration file:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npx squid-typeorm-migration generate
```

* Apply the migration:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npx squid-typeorm-migration apply
```

### Tie the code together

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

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
import { EvmBatchProcessor } from '@subsquid/evm-processor';
import { TypeormDatabase } from '@subsquid/typeorm-store';
import { DataStoredEvent } from './model';

const DataStoredEventTopic = '0x9455957c3b77d1d4ed071e2b469dd77e37fc5dfd3b4d44dc8a997cc97c7b3d49';
const CONTRACT_ADDRESS = '0xdbdac2ef52681230f996624a5fa2624b06972671';

const processor = new EvmBatchProcessor()
  .setRpcEndpoint({
    url: 'https://rpcpc1-qa.agung.peaq.network',
  })
  .setFinalityConfirmation(5)
  .setBlockRange({ from: 3564900 })
  .addLog({
    address: [CONTRACT_ADDRESS]
  })
  .setFields({
    log: {
      transactionHash: true,
    },
  });

const db = new TypeormDatabase();

processor.run(db, async (ctx) => {
  const events: DataStoredEvent[] = [];
  for (let block of ctx.blocks) {
    for (let log of block.logs) {
      if (log.topics[0] === DataStoredEventTopic) {
        const data = BigInt(log.data);
        console.log("ID: ", log.id);
        console.log("DATA: ", data);
        console.log("BLOCK_NUMBER: ", block.header.height);
        console.log("TX_HASH: ", log.block.hash);

        events.push(new DataStoredEvent({
          id: log.id,
          data: Number(data),
          blockNumber: block.header.height,
          transactionHash: log.block.hash,
        }));
      }
    }
  }
  await ctx.store.insert(events);
});
```

### Compile and start the processor

* Compile the code:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npx tsc
```

* Start the processor:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
node -r dotenv/config lib/main.js
```

### Start the GraphQL server

In a separate terminal, start the GraphQL server:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npx squid-graphql-server
```
