Skip to content

feat: dynamic eventFilters for wildcard handlers (cross-contract address sharing) #1201

@cristianizzo

Description

@cristianizzo

Summary

For wildcard handlers (e.g. ERC20.Transfer, ERC721.Transfer), allow eventFilters to be a function whose addresses argument comes from a different contract's dynamically-registered set — so HyperSync can pre-filter at the source instead of every event reaching the handler.

Use case

Indexing every Aragon DAO across Ethereum mainnet plus tracking each DAO's treasury (every ERC-20 / ERC-721 transfer where from or to is a DAO).

DAOs are discovered dynamically via DAORegistered and registered with:

indexer.onEvent({ contract: "DAORegistry", event: "DAORegistered" }, async ({ event, context }) => {
  context.chain.DAO.add(event.params.dao);
});

Treasury currently uses a wildcard ERC20.Transfer handler that filters at handler-time:

indexer.onEvent(
  { contract: "ERC20", event: "Transfer", wildcard: true },
  async ({ event, context }) => {
    const [fromDao, toDao] = await Promise.all([
      context.Dao.get(daoId(event.chainId, event.params.from)),
      context.Dao.get(daoId(event.chainId, event.params.to)),
    ]);
    if (!fromDao && !toDao) return;
    // ...record Transaction + update Asset balance
  },
);

Every Transfer on every ERC-20 in Ethereum history reaches this handler just to drop the vast majority via the Dao.get early-return.

Desired API

eventFilters as a function on a wildcard handler, with addresses populated from the dynamically-registered set of another contract:

indexer.onEvent(
  {
    contract: "ERC20",
    event: "Transfer",
    wildcard: true,
    eventFilters: ({ addresses }) => [
      { from: addresses },   // transfers FROM a DAO
      { to:   addresses },   // OR to a DAO
    ],
    // optional: name the contract whose registered addresses feed `addresses`
    eventFiltersAddressSource: "DAO",
  },
  async ({ event, context }) => { /* same as today, but only DAO-touching transfers reach here */ },
);

ERC20.Transfer.eventFilters already accepts { from?, to? } in the typed surface (.envio/types.d.ts); the missing piece is letting the function form work on wildcard handlers and pointing it at another contract's address registry.

Open questions

  1. How should the cross-contract address source be expressed? An explicit field like eventFiltersAddressSource: "DAO", or a different mechanism?
  2. Any preview / alpha branch we can test against with a real Ethereum-mainnet workload?

Happy to validate a preview build against our indexer if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions