Skip to main content

Prerequisite

Getting started

  1. Log in to Ormi and go to your dashboard.
  2. From the dashboard, create an API key.
0xGraph graph init
Note: Keep this page open, we’ll need the API key later to deploy a subgraph.

Install Graph CLI

On your local machine, run the following in your terminal:
npm install -g @graphprotocol/graph-cli

Create a directory for your subgraph

mkdir katana-blocks
cd katana-blocks
We’ll call the folder katana-blocks in this example.

Initialize Node project

Run bash in the directory folder
npm init -y

Install dependencies

npm install --save-dev @graphprotocol/graph-ts
npm install --save-dev assemblyscript

Create the required files

You will need:
  • subgraph.yaml
  • schema.graphql
  • mappings/blocks.ts
  • abis/Dummy.json

subgraph.yaml

specVersion: 0.0.5
description: Blocks indexer for Katana
schema:
  file: ./schema.graphql

dataSources:
  # We declare a contract data source so we can attach a blockHandler.
  # The "Dummy" ABI is unused but required by the manifest when kind=ethereum/contract.
  - kind: ethereum/contract
    name: KatanaBlocks
    network: katana
    source:
      address: "0x0000000000000000000000000000000000000000"  # not used
      abi: Dummy
      startBlock: 1
    mapping:
      kind: ethereum/events
      apiVersion: 0.0.7
      language: wasm/assemblyscript
      entities:
        - Block
      abis:
        - name: Dummy
          file: ./abis/Dummy.json
      # This is the key: run our handler every block
      blockHandlers:
        - handler: handleBlock
      file: ./mappings/blocks.ts
Note: Dummy.json is required because every data source must include at least one ABI, even if unused. Just put [] inside it.

schema.graphql

type Block @entity(immutable: true) {
  id: ID!            # we will use the block number as the ID
  number: BigInt!
  timestamp: BigInt!
  hash: Bytes!
  parentHash: Bytes!
}

Mapping files in typescript

import { Block as BlockEntity } from "../generated/schema";
import { ethereum } from "@graphprotocol/graph-ts";

export function handleBlock(block: ethereum.Block): void {
  // Use block number as the stable ID
  let id = block.number.toString();

  let entity = new BlockEntity(id);
  entity.number = block.number;
  entity.timestamp = block.timestamp;
  entity.hash = block.hash;
  entity.parentHash = block.parentHash;
  entity.save();
}

Directory layout

katana-blocks/
├─ abis/
│  └─ Dummy.json          
├─ mappings/
│  └─ blocks.ts
├─ schema.graphql
└─ subgraph.yaml
You’ll also see node_modules/ after installing dependencies - that’s expected.

Build the subgraph

Generate types:
graph codegen
0xGraph graph init
Now run:
graph build
0xGraph graph init

Deploy the Subgraph to Ormi 0xGraph

Return to your API key from the dashboard. Replace graph-name and API key with your actual values
graph deploy <graph-name> --node  https://subgraph.api.ormilabs.com/deploy --ipfs https://subgraph.api.ormilabs.com/ipfs --deploy-key <API key>
0xGraph graph init

Track sync status

You can check syncing in the dashboard by going to the Subgraphs tab:
0xGraph graph init

Query Katana blocks

Click on the button where the red arrow is pointing.
0xGraph graph init
Once synced, click the GraphQL endpoint link in the dashboard.
0xGraph graph init

Sample query

Run this query to fetch the latest 5 blocks
{
  blocks(first: 5) {
    id
    number
    timestamp
    parentHash
  }
}
0xGraph graph init

Done!

You now have a live subgraph indexing Katana blocks through Ormi’s 0xGraph.

Next steps

I