Skip to content

Test Indexer - keep contract registrations between indexer.process runs#918

Merged
DZakh merged 3 commits intomainfrom
dz/test-indexer-for-factory-contracts
Jan 19, 2026
Merged

Test Indexer - keep contract registrations between indexer.process runs#918
DZakh merged 3 commits intomainfrom
dz/test-indexer-for-factory-contracts

Conversation

@DZakh
Copy link
Member

@DZakh DZakh commented Jan 16, 2026

Summary by CodeRabbit

  • New Features

    • Added a test that demonstrates indexer onboarding, dynamic contract registration, and event handling.
  • Refactor

    • Simplified source configuration by removing explicit contract lists from source constructors.
    • Streamlined example template: renamed metadata and reduced multi-chain/contract entries for clearer onboarding.
  • Documentation

    • Minor test-run instructions and wording updates to guidance files.

✏️ Tip: You can customize this high-level summary in your review settings.

@DZakh DZakh requested a review from JonoPrest January 16, 2026 14:28
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

TestIndexer now extracts dynamic contracts from DynamicContractRegistry entities, maps them to Internal.indexingContract, and threads a per-chain dynamicContractsByChain into makeInitialState. Separately, contracts was removed from HyperSyncSource/RpcSource public options and call sites; templates and tests were updated accordingly.

Changes

Cohort / File(s) Summary
Dynamic Contract Initialization
codegenerator/cli/npm/envio/src/TestIndexer.res
Added external castFromDcRegistry and toIndexingContract mapping; extended makeInitialState signature to accept dynamicContractsByChain: dict<array<Internal.indexingContract>>; extract dynamic contracts per chain from state.entities and pass aggregated dict into initial state creation.
Source Constructor Simplification
codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res, codegenerator/cli/npm/envio/src/sources/RpcSource.res
Removed contracts: array<Internal.evmContractConfig> from exported options types and from make function parameter destructuring; public constructor signatures no longer accept contracts.
Source Instantiation Updates
codegenerator/cli/npm/envio/src/sources/EvmChain.res
Removed contracts arguments from HyperSyncSource.make and RpcSource.make call sites in makeSources.
Template & Test Additions
codegenerator/cli/templates/static/factory_template/typescript/config.yaml, .../src/indexer.test.ts
Updated template metadata and pruned several chain/contract entries in config.yaml. Added indexer.test.ts which exercises dynamic contract registration and event processing using createTestIndexer().
Test & Scenario Adjustments
scenarios/test_codegen/... (Integration_ts_helpers.res, RpcSource_test.res, __mocks__/MockConfig.res)
Removed contracts field from RpcSource.make call sites and adjusted eventRouter construction in mocks/tests to match new RpcSource signature.

Sequence Diagram

sequenceDiagram
    participant TestIndexer
    participant Entities as State.entities
    participant DCR as DynamicContractRegistry
    participant Mapper as toIndexingContract
    participant Persistence as Persistence.initialState

    TestIndexer->>Entities: read entities
    Entities-->>DCR: locate DynamicContractRegistry.entity records
    loop per chain
        DCR->>Mapper: castFromDcRegistry + toIndexingContract
        Mapper-->>TestIndexer: Internal.indexingContract[]
    end
    TestIndexer->>TestIndexer: aggregate dynamicContractsByChain
    TestIndexer->>Persistence: makeInitialState(..., dynamicContractsByChain)
    Persistence-->>TestIndexer: initial state created with dynamic contracts
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • JonoPrest
  • JasoonS

Poem

🐰 I hopped through state and found a registry bright,
Mapped contracts by chain in the soft morning light,
Threaded them into state, one tiny tweak at a time,
Tests dance with Vitest to the new startup chime—
A joyful hop for indexing, quick and light! 🎋

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Test Indexer - keep contract registrations between indexer.process runs' directly describes the main feature: enabling contract registrations to persist across multiple indexer.process calls, which is the primary objective of the changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.



📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92c335b and 0935876.

📒 Files selected for processing (5)
  • .cursor/commands/test.md
  • AGENTS.md
  • scenarios/test_codegen/test/Integration_ts_helpers.res
  • scenarios/test_codegen/test/RpcSource_test.res
  • scenarios/test_codegen/test/__mocks__/MockConfig.res
💤 Files with no reviewable changes (3)
  • scenarios/test_codegen/test/mocks/MockConfig.res
  • scenarios/test_codegen/test/RpcSource_test.res
  • scenarios/test_codegen/test/Integration_ts_helpers.res
✅ Files skipped from review due to trivial changes (2)
  • AGENTS.md
  • .cursor/commands/test.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@codegenerator/cli/npm/envio/src/sources/RpcSource.res`:
- Around line 476-478: RpcSource.make's signature no longer accepts a contracts
field; update all test call sites (Integration_ts_helpers.res,
__mocks__/MockConfig.res, RpcSource_test.res) that still pass contracts (e.g.,
contracts: evmContracts or contracts: []) by removing that field from the
options object so calls match the RpcSource.make({sourceFor, syncConfig, url,
chain, eventRouter, allEventSignatures, lowercaseAddresses}) signature.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 167150b and 92c335b.

📒 Files selected for processing (6)
  • codegenerator/cli/npm/envio/src/TestIndexer.res
  • codegenerator/cli/npm/envio/src/sources/EvmChain.res
  • codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
  • codegenerator/cli/npm/envio/src/sources/RpcSource.res
  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
💤 Files with no reviewable changes (2)
  • codegenerator/cli/npm/envio/src/sources/EvmChain.res
  • codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{res,resi}

📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)

**/*.{res,resi}: Always use ReScript 11 documentation
Never suggest ReasonML syntax
Never use [| item |] to create an array. Use [ item ] instead
Must always use = for setting value to a field. Use := only for ref values created using ref function
Use records when working with structured data, and objects to conveniently pass payload data between functions
Never use %raw to access object fields if you know the type

Files:

  • codegenerator/cli/npm/envio/src/TestIndexer.res
  • codegenerator/cli/npm/envio/src/sources/RpcSource.res
**/{src,agents,lib}/**/*.{py,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Include error handling and fallback strategies in agent implementations

Files:

  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
**/*.{test.res,test.js,test.ts,test.tsx,spec.res,spec.js,spec.ts,spec.tsx}

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

**/*.{test.res,test.js,test.ts,test.tsx,spec.res,spec.js,spec.ts,spec.tsx}: Always use single assert to check the whole value instead of multiple asserts for every field
Prefer Public module API for testing

Files:

  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Migrate from TheGraph subgraph indexer to Envio HyperIndex by clearing boilerplate code, migrating the schema to Envio format, implementing proper business logic, and registering dynamic contracts. Maintain identical business logic to original subgraph.
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : For dynamically created contracts identified by lack of address in subgraph.yaml (templates), implement contract registration using `contractRegister` above the handler. Example: `Factory.PairCreated.contractRegister(({ event, context }) => { context.addPair(event.params.pair); });` Remove address field from dynamic contracts in config.yaml.
Learnt from: nikbhintade
Repo: enviodev/hyperindex PR: 822
File: codegenerator/cli/templates/static/multichain_indexer_template/typescript/src/EventHandlers.ts:10-18
Timestamp: 2025-11-19T05:36:33.975Z
Learning: The multichain_indexer_template in codegenerator/cli/templates/static/ is designed to demonstrate multichain indexing features. It intentionally uses minimal event parameters (e.g., only capturing the `pool` address from Uniswap V3 PoolCreated events) to keep the focus on multichain functionality rather than comprehensive event indexing.
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/effects/**/*.ts : For contract state fetching, migrate from TheGraph `.bind()` patterns to Effect API. Create effects that use viem's `readContract()` with proper ABI definitions. Implement error handling with fallback values. Support multichain by making RPC URLs dynamic based on event.chainId.
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2026-01-14T13:34:03.676Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.{ts,js,res,graphql,yaml} : Include HyperIndex documentation, example indexers (Uniswap v4 and Safe), and understand that HyperIndex is not a TheGraph subgraph
📚 Learning: 2025-11-19T05:36:33.975Z
Learnt from: nikbhintade
Repo: enviodev/hyperindex PR: 822
File: codegenerator/cli/templates/static/multichain_indexer_template/typescript/src/EventHandlers.ts:10-18
Timestamp: 2025-11-19T05:36:33.975Z
Learning: The multichain_indexer_template in codegenerator/cli/templates/static/ is designed to demonstrate multichain indexing features. It intentionally uses minimal event parameters (e.g., only capturing the `pool` address from Uniswap V3 PoolCreated events) to keep the focus on multichain functionality rather than comprehensive event indexing.

Applied to files:

  • codegenerator/cli/npm/envio/src/TestIndexer.res
  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:03.676Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2026-01-14T13:34:03.676Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.{ts,js,res,graphql,yaml} : Include HyperIndex documentation, example indexers (Uniswap v4 and Safe), and understand that HyperIndex is not a TheGraph subgraph

Applied to files:

  • codegenerator/cli/npm/envio/src/TestIndexer.res
  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Migrate from TheGraph subgraph indexer to Envio HyperIndex by clearing boilerplate code, migrating the schema to Envio format, implementing proper business logic, and registering dynamic contracts. Maintain identical business logic to original subgraph.

Applied to files:

  • codegenerator/cli/npm/envio/src/TestIndexer.res
  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : For dynamically created contracts identified by lack of address in subgraph.yaml (templates), implement contract registration using `contractRegister` above the handler. Example: `Factory.PairCreated.contractRegister(({ event, context }) => { context.addPair(event.params.pair); });` Remove address field from dynamic contracts in config.yaml.

Applied to files:

  • codegenerator/cli/npm/envio/src/TestIndexer.res
  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
  • codegenerator/cli/npm/envio/src/sources/RpcSource.res
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/config.yaml : For multichain indexing in config.yaml, ensure contract names are unique across all networks. Define contracts globally with handlers and events, then specify network-specific addresses only in network sections. Never duplicate contract definitions in network sections.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : Prefix all entity IDs with `event.chainId` for multichain support: `${event.chainId}-${originalId}`. Never hardcode `chainId = 1`, always use `event.chainId`. Update helper functions to accept `chainId` parameter. Use chain-specific Bundle IDs: `${chainId}-1`.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : Create directory structure matching the original subgraph exactly with contract-specific handler files (not single EventHandlers.ts). Use exact filenames from the original subgraph. Update config.yaml to point to contract-specific handler files instead of a single EventHandlers.ts.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/effects/**/*.ts : For contract state fetching, migrate from TheGraph `.bind()` patterns to Effect API. Create effects that use viem's `readContract()` with proper ABI definitions. Implement error handling with fallback values. Support multichain by making RPC URLs dynamic based on event.chainId.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/npm/envio/src/sources/RpcSource.res
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : Always use constants from the original subgraph instead of hardcoded addresses/values. Examples: `FACTORY_ADDRESS`, `ADDRESS_ZERO`, `ZERO_BI`, `ONE_BI`, `ZERO_BD`, `ONE_BD`. Maintain consistency with original subgraph's approach.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : Import entity types from `generated/src/db/Entities.gen` (e.g., `Pair_t`, `Token_t`) not from `generated` directly. Use exact field names from generated types. Ensure types you set in code match schema entity property types exactly.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/config.yaml
  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : In Step 6 (Final Migration Verification), perform systematic handler logic review one by one, comparing to subgraph implementation. Iterate multiple times on each handler until logic is correct. Run quality checks after each review iteration.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:03.676Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2026-01-14T13:34:03.676Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.{ts,js} : Always cast timestamps to BigInt using `BigInt(event.block.timestamp)` instead of using raw timestamps from events

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:03.676Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2026-01-14T13:34:03.676Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.{ts,js} : After any change to TypeScript files, run `pnpm tsc --noEmit` to ensure it compiles successfully

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
📚 Learning: 2026-01-14T13:34:33.837Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: codegenerator/cli/templates/static/shared/.cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2026-01-14T13:34:33.837Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/EventHandlers.ts : Clear all boilerplate logic from EventHandlers.ts when starting migration. Replace boilerplate with empty handlers containing TODO comments referencing the original subgraph location for implementation.

Applied to files:

  • codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (7)
codegenerator/cli/templates/static/factory_template/typescript/config.yaml (1)

2-3: Metadata rename looks consistent.

The updated name/description cleanly reflects the template’s focus.

codegenerator/cli/templates/static/factory_template/typescript/src/indexer.test.ts (2)

1-2: Public entrypoint usage for tests looks right.

Keeping tests wired through the generated entrypoint preserves the public‑API boundary. As per coding guidelines, ...


4-74: Good end‑to‑end coverage of dynamic registry persistence.

The two process calls validate registration carry‑over and swap handling on the registered pool.

codegenerator/cli/npm/envio/src/sources/RpcSource.res (1)

681-756: Event routing/decoding pipeline looks consistent.

Lowercasing before routing and filtering out non‑decoded events keeps the queue aligned with configured event filters.

codegenerator/cli/npm/envio/src/TestIndexer.res (3)

26-38: Registry → indexing contract mapping looks correct.

Using the registration block as both start and registration points matches dynamic contract semantics.


234-264: Initial state now carries dynamic contracts per chain.

Threading dynamicContracts into each chain state should preserve registrations across process runs.


366-393: Dynamic contract extraction before each run looks solid.

Building dynamicContractsByChain from persisted entities aligns with keeping registrations between runs.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Collaborator

@JonoPrest JonoPrest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

@DZakh DZakh enabled auto-merge (squash) January 19, 2026 09:08
@DZakh DZakh merged commit fb2cfd6 into main Jan 19, 2026
2 checks passed
@DZakh DZakh deleted the dz/test-indexer-for-factory-contracts branch January 19, 2026 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants