Skip to main content

Documentation Index

Fetch the complete documentation index at: https://beta.docs.sqd.dev/llms.txt

Use this file to discover all available pages before exploring further.

Use the factory pattern when you need to index events from contracts that are deployed dynamically by a known factory contract — for example, Uniswap V3 pools created by the UniswapV3Factory.
The examples below use typegen-generated ABI modules. See Specifying events for how to generate them from a JSON ABI.

Basic factory

Track events from contracts created by a factory. The factory() helper discovers child contracts from the factory’s creation events and maintains the address list in a local SQLite database.
import { evmPortalStream, evmDecoder, factory, factorySqliteDatabase } from "@subsquid/pipes/evm";
import { createTarget } from "@subsquid/pipes";
import * as factoryAbi from "./abi/uniswap-v3-factory";
import * as poolAbi from "./abi/uniswap-v3-pool";

await evmPortalStream({
  portal: "https://portal.sqd.dev/datasets/ethereum-mainnet",
  outputs: evmDecoder({
    range: { from: 12369621 },
    contracts: factory({
      address: "0x1f98431c8ad98523631ae4a59f267346ea31f984",
      event: factoryAbi.events.PoolCreated,
      parameter: "pool",
      database: factorySqliteDatabase({ path: "./uniswap-v3-pools.sqlite" }),
    }),
    events: { swap: poolAbi.events.Swap },
  }),
}).pipeTo(createTarget({
  write: async ({ logger, read }) => {
    for await (const { data } of read()) {
      logger.info(`Parsed ${data.swap.length} swaps`);
    }
  },
}));

Filtering factory events

To narrow which child contracts are tracked, pass an event object with a params field. Only creation events matching the specified parameter values are stored — unmatched contracts are ignored at both the portal and the local database level.
contracts: factory({
  address: "0x1f98431c8ad98523631ae4a59f267346ea31f984",
  event: {
    event: factoryAbi.events.PoolCreated,
    params: {
      token0: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // WETH
    },
  },
  parameter: "pool",
  database: factorySqliteDatabase({ path: "./uniswap-v3-weth-pools.sqlite" }),
})
Filter rules:
  • Only indexed parameters can be used for filtering.
  • Multiple parameters are combined with AND logic.
  • Passing an array of values for a parameter matches any of them (OR logic).
  • Address matching is case-insensitive.

Including factory event data

DecodedEvent<T, F> carries a .factory field with the creation event. Use it when you need to include factory context (e.g. pool token addresses) alongside each decoded event.

Multiple factories

Pass separate evmDecoder outputs to track contracts from different factory addresses in a single pipeline.

Pre-indexing factory Experimental

Pre-populate the factory database before the main pipeline to ensure all historical child contracts are known before live indexing begins.
This is an experimental feature. The pre-indexing request is limited and this approach won’t work for thousands of addresses.