Skip to main content

Architecture

Preparations

The data flow applied to this indexer is identical to the one used in the lockup subgraph.

Similar to The Graph, we start by pre-configuring a set of contracts. While Envio's indexer doesn't have the same requirement of pre-configuring contracts to listen to, we'll keep this feature to ensure we can query against those entities, even if they'll be empty at start.

We'll ensure contracts have been initialized (see the watcher.ts helper) by making a call against the initializer at the start of each method. It should only come into play within the create handlers.

packages/constants/.../sepolia.ts
export let chainId = 11155111;
/** It uses the same structure as the configuration files of the subgraphs */
...

After setting up each chain, we'll aggregate configuration to feed into the config.yaml all at once, as Envio uses a multi-chain approach instead of establishing a separate endpoint for each indexed chain. Check packages/constants/.../bundles to see how this works. to

Configurations

Using this data, we'll call the pnpm run setup script. In turn it will:

  1. [Setup] Clean artifacts and older files
  2. [Template] Convert TS files into JS for mustache to use in the next step
  3. [Template] Use mustache to create a specific config.yaml (from config.template.mustache) using the aggregated chain details (from /constants/chains/index.ts)
  4. [Codegen] Run codegen using the files prepared above, as well as the handlers implementation

Running locally

In order to run things locally, you can use the pnpm dev command which does all the "configuration" steps as well as booting up the Envio dependencies and local node. Check the official Envio docs for more on this.

Multi-version support

Sablier is a fast moving protocol, with a new deployment every few months. Up to this point we can already see V2.0 and V2.1 supported by the client interface and integrators.

To offer a backwards compatible subgraph (between Sablier Core/ Sablier Periphery v2.0 and v2.x) we'll aggregate the ABIs of the two versions. This will cause the configuration file to contain similar events between different versions of Lockup contract.

Different from how we handle this for subgraphs, Lockup Linear, Lockup Dynamic and Lockup Tranched will be bundled under the same Lockup<Version> contract tracker config.yaml. Versions of the protocol will be tracked separately, which is why we have Lockup_V20 (v2.0) and Lockup_V21 (v2.1) in our configuration. Later on, inside the handler logic, we'll separate contracts by flavor.