Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

contracts

A global registry — every contract declared here is usable from any workflow, trigger, or step by name.

contracts:
  USDC:
    abi: ./abis/erc20.json
    addresses:                       # per-network map
      ethereum: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
      base: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
 
  Treasury:
    abi: ./abis/treasury.json
    network: ethereum                # single-network shorthand
    address: "0xDep..."
 
  AnyPool:
    abi: ./abis/univ3-pool.json
    factory:                         # every child the factory ever deployed
      contract: UniV3Factory
      event: PoolCreated
      network: ethereum
FieldDescription
abi✅ Path to the ABI json file, relative to the project directory — rflow abi fetch downloads the verified one for you
addressesPer-network map: network → address (or a list of addresses)
network + addressSingle-network shorthand; address also accepts a list
factoryFactory tracking — match every child deployed by a factory
index_eventsIndex these events for query: WITHOUT firing any workflow — see below

Use exactly one address form (addresses, network/address, or factory) — validation checks this and that every referenced network exists.

index_events — index-only analytics

index_events: indexes a contract's events into Postgres without any workflow firing — the historical dataset for query: steps and the query trigger:

contracts:
  USDC:
    abi: ./abis/erc20.json
    network: ethereum
    address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
    index_events: [Transfer, Approval]

Rows land in rflow_indexer_rflow_idx_<contract>.<event> (rflow_indexer_rflow_idx_usdc.transfer here — run rflow tables to see the live catalog). No runs, no claims, no cursors in the run journal — indexing only.

Honest limits:

  • Indexing starts at the current head when rflow start boots the indexer — there is no per-contract backfill knob yet. For deep history, point an event-trigger workflow (which owns start_block semantics) at the contract instead.
  • index_events on a factory:-tracked contract is not supported yet — rflow validate (and boot) errors.
  • Each event name must exist in the contract's ABI (validated); declaring an event some workflow also triggers on is fine but flagged as a warning — the rows are stored twice (once per table-naming family).

Factory tracking

factory: scopes a contract to every child a factory ever deployed — past and future. The classic use is DEX pools:

contracts:
  UniV3Factory:
    abi: ./abis/univ3-factory.json
    network: ethereum
    address: "0x1F98431c8aD98523631AE4a59f267346ea31F984"
  AnyPool:
    abi: ./abis/univ3-pool.json
    factory: { contract: UniV3Factory, event: PoolCreated, network: ethereum }

An event trigger on AnyPool fires for a Swap in any pool, including pools created after rflow started.

FieldDescription
contract✅ Name of the factory contract in this registry
event✅ The deployment event on the factory (e.g. PoolCreated)
network✅ Network to track the factory on

Using registry entries

  • Event triggers: trigger: { event: { contract: USDC, name: Transfer, ... } }
  • Read steps: read: { contract: USDC, function: "balanceOf(address)", ... }
  • Send steps: send_transaction: { contract: USDC, function: "transfer(address,uint256)", ... }
  • Expressions: ${{ contracts.Treasury.address }}

Send steps may also target a raw to: "0x..." address without a registry entry — the registry is for contracts you reference more than once or need ABIs for.