diff --git a/website/pages/en/cookbook/_meta.js b/website/pages/en/cookbook/_meta.js index f8b5035ddb55..d1e9e050cef0 100644 --- a/website/pages/en/cookbook/_meta.js +++ b/website/pages/en/cookbook/_meta.js @@ -1,4 +1,5 @@ export default { + 'subgraph-composition': '', 'subgraph-debug-forking': '', near: '', cosmos: '', diff --git a/website/pages/en/cookbook/subgraph-composition.mdx b/website/pages/en/cookbook/subgraph-composition.mdx new file mode 100644 index 000000000000..76adb2e64a5c --- /dev/null +++ b/website/pages/en/cookbook/subgraph-composition.mdx @@ -0,0 +1,127 @@ +--- +title: Subgraph Composition with Sushiswap v3 and Base +--- + +Leverage subgraph composition to create a base subgraph containing core data and build additional subgraphs on top. + +> - If you're building a subgraph from scratch, subgraph composition is built into the CLI, and you can deploy with [Subgraph Studio](https://thegraph.com/studio/). +> - You can use existing subgraphs, but they must be redeployed with a new spec version, which doesn't require you to write new code. However, you may want to restructure your subgraph to split out the logic as you move to a composable subgraph world. + +## Overview + +### Benefits of Composition + +Subgraph composition is a powerful feature for scaling, allowing you to: + +- Unlock the reuse of existing data +- Speed up your subgraph's syncing speed +- Handle errors and optimize the resync +- Enhance your subgraph development to effortlessly scale + +## Setup + +This guide uses the Sushiswap v3 subgraph on Base chain. + +### Tools Needed + +The setup involves two subgraphs: + +1. **Source Subgraph**: Tracks event data as entities. +2. **Dependent Subgraph**: Uses the source subgraph as a data source. + +You can find these in the `source` and `dependent` directories. + +- The **source subgraph** is a basic event-tracking subgraph that records events emitted by relevant contracts. +- The **dependent subgraph** references the source subgraph as a data source, using the entities from the source as triggers. + +While the source subgraph is a standard subgraph, the dependent subgraph utilizes the subgraph composition feature. + +### Source Subgraph + +The source subgraph tracks events from the Sushiswap v3 subgraph on the Base chain. This subgraph's configuration file is in the `source/subgraph.yaml`. + +### Dependent Subgraph + +The dependent subgraph is in the `dependent/subgraph.yaml`, which specifies the source subgraph as a data source. This subgraph uses entities from the source to trigger specific actions based on changes to those entities. + +## Get Started + +The following is a how-to-guide on using one subgraph as a data source for another. + +### Step 1. Set Up Your Source Subgraph + +To set the source subgraph as a data source in the dependent subgraph, include the following in `subgraph.yaml`: + +```yaml +specVersion: 1.3.0 +schema: + file: ./schema.graphql +dataSources: + - kind: subgraph + name: Factory + network: base + source: + address: 'QmdXu8byAFCGSDWsB5gMQjWr6GUvEVB7S1hemfxNuomerz' + startBlock: 82522 +``` + +Here, `source.address` refers to the Deployment ID of the source subgraph, and `startBlock` specifies the block from which indexing should begin. + +### Step 2. Define Handlers in Dependent Subgraph + +Below is an example of defining handlers in the dependent subgraph: + +```typescript +export function handleInitialize(trigger: EntityTrigger): void { + if (trigger.operation === EntityOp.Create) { + let entity = trigger.data + let poolAddressParam = Address.fromBytes(entity.poolAddress) + + // Update pool sqrt price and tick + let pool = Pool.load(poolAddressParam.toHexString()) as Pool + pool.sqrtPrice = entity.sqrtPriceX96 + pool.tick = BigInt.fromI32(entity.tick) + pool.save() + + // Update token prices + let token0 = Token.load(pool.token0) as Token + let token1 = Token.load(pool.token1) as Token + + // Update ETH price in USD + let bundle = Bundle.load('1') as Bundle + bundle.ethPriceUSD = getEthPriceInUSD() + bundle.save() + + updatePoolDayData(entity) + updatePoolHourData(entity) + + // Update derived ETH price for tokens + token0.derivedETH = findEthPerToken(token0) + token1.derivedETH = findEthPerToken(token1) + token0.save() + token1.save() + } +} +``` + +In this example, the `handleInitialize` function is triggered when a new `Initialize` entity is created in the source subgraph, passed as `EntityTrigger`. The handler updates the pool and token entities based on data from the new `Initialize` entity. + +`EntityTrigger` has three fields: + +1. `operation`: Specifies the operation type, which can be `Create`, `Modify`, or `Remove`. +2. `type`: Indicates the entity type. +3. `data`: Contains the entity data. + +Developers can then determine specific actions for the entity data based on the operation type. + +## Key Takeaways + +- Use this powerful tool to scale your subgraph development and reuse existing data. +- The setup includes creating a base source subgraph and referencing it in a dependent subgraph. +- You define handlers in the dependent subgraph to perform actions based on changes in the source subgraph's entities. + +This approach promotes modularity and scalability, enhancing both development and maintenance efficiency. + +## Additional Resources + +To use other advance features in your subgraph check out [subgraph advance features](/developing/creating/advanced/) and the [subgraph composition repo](https://github.com/incrypto32/subgraph-composition-sample-subgraph).