Ponder: EVM Data Indexing Framework

0.16.6 · active · verified Tue Apr 21

Ponder is an open-source TypeScript framework designed for indexing data from EVM-compatible blockchains. It provides tools to define a database schema, write indexing functions to process on-chain events, and then query the indexed data via automatically generated GraphQL or SQL APIs. The current stable version is 0.16.6, with frequent patch releases indicating active development. Ponder differentiates itself by offering a powerful local development server with hot reloading, end-to-end type safety, support for Postgres, and the ability to index data from multiple chains within a single application. It aims to provide a robust, performant alternative to traditional subgraph indexing solutions, optimized for application developers who require custom backend logic and greater control over their data infrastructure.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to set up a Ponder project, configure chains and contracts, define a database schema, and write an indexing function to process Ethereum events and persist them to a database.

import { createConfig } from "ponder";
import { BaseRegistrarAbi } from "./abis/BaseRegistrar"; // Assuming ABI is local
import { ponder } from "ponder:registry";
import schema from "ponder:schema";

// 1. Initialize a new Ponder project (run in terminal):
// npm init ponder@latest
// cd my-ponder-project

// 2. Start the development server (run in project directory):
// npm run dev

// 3. Define Ponder configuration in ponder.config.ts
export default createConfig({
  chains: {
    mainnet: {
      id: 1,
      rpc: process.env.MAINNET_RPC_URL ?? "https://eth-mainnet.g.alchemy.com/v2/YOUR_ALCHEMY_KEY", // Replace with your actual RPC URL
    },
  },
  contracts: {
    BaseRegistrar: {
      abi: BaseRegistrarAbi,
      chain: "mainnet",
      address: "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",
      startBlock: 9380410,
    },
  },
});

// 4. Define your schema in ponder.schema.ts
export const ensName = schema.onchainTable("ens_name", (t) => ({
  name: t.string().primaryKey(),
  owner: t.string().notNull(),
  registeredAt: t.int().notNull(),
}));

// 5. Write indexing functions in src/BaseRegistrar.ts
ponder.on("BaseRegistrar:NameRegistered", async ({ event, context }) => {
  const { name, owner } = event.params;

  await context.db.insert(schema.ensName).values({
    name: name,
    owner: owner,
    registeredAt: Number(event.block.timestamp),
  });
});

view raw JSON →