Skip to main content

Architecture

Preparations

In order to start indexing all whitelisted Lockup contracts we need a genesis event. With Sablier Lockup, there is no factory pattern so we couldn't rely on a data source contract. The next best things for a "genesis" point was to rely on the first event triggered by the earliest registered onchain contract

To reduce the number of dependencies required to kickstart a subgraph, we chose to rely on this approach instead of implementing a separate registry contract. Therefore, when setting up a deployment, you'll need to follow a few rules.

packages/constants/.../sepolia.ts
export let chainId = 11155111;
export let chain = "sepolia";
export let startBlock = 4067889;

/** Rule: keep addresses lowercased */

/**
* Keep aliases unique and always in sync with the frontend
* @example export let linear = [[address1, alias1, version1], [address2, alias2, version2]]
*/

export let linear: string[][] = [
["0xd4300c5bc0b9e27c73ebabdc747ba990b1b570db", "LL", "V20"],
["0x7a43f8a888fa15e68c103e18b0439eb1e98e4301", "LL2", "V21"],
];

export let dynamic: string[][] = [
["0x421e1e7a53ff360f70a2d02037ee394fa474e035", "LD", "V20"],
["0xc9940ad8f43aad8e8f33a4d5dbbf0a8f7ff4429a", "LD2", "V21"],
];

/** PRBProxy registry */
export let registry = "0x584009E9eDe26e212182c9745F5c000191296a78";

/**
* The initializer contract is used to trigger the indexing of all other contracts.
* It should be a linear contract, the oldest/first one deployed on this chain.
* ↪ 🚨 On any new chain, please create a Lockup Linear stream to kick-off the indexing flow
*/

export let initializer = linear[0][0];

Configurations

Using this data, we'll call the yarn deploy:<chain_name> script. In turn it will:

  1. [Chain] Lock onto a specified chain
  2. [Setup] Clean artifacts and older files
  3. [Template] Convert TS files into JS for mustache to use in the next step
  4. [Template] Use mustache to create a specific subgraph.yaml (from subgraph.template.yaml) using the selected chain's details
  5. [Template] Duplicate the selected chain's configuration file as the "current" env.ts (for possible imports directly in Assembly Script)
  6. [Codegen] Run codegen using the files prepared above, as well as the handlers implementation
  7. [Deploy] Deploy the code to the endpoint selected based on the specified chain

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 Lockup Linear and Dynamic ABIs to contain multiple events with the same name, but different signatures (due to event parameters).

Luckily, because of this issue in graph-tooling, event names will be de-duplicated using a numbering scheme (e.g. a duplicated Event will become Event, Event1, ...).