Skip to content

DistributedCollective/sov-protocol-subgraphs

Repository files navigation

Template Subgraph

This is a template subgraph that can be used to create a new subgraph. It contains everything you need to get started using a subgraph, as well as generic documentation.

README Contents:

External documentation

Setup

To run locally:

  • clone repo
  • Run npm install
  • Add a .env.dev file in the root of the project. Copy the contents of .env.example into this file (you can change the password to your own password if you wish)
  • Run npm run prepare:testnet. This will create the docker-compose.yml file and the subgraph.yaml file from the template files.
  • Run npm run dev:up. This will run docker compose up -d and pass in your environment file.
  • Run npm run codegen. This will generate the ./generated folder with types and contract objects.
  • Run npm run build to generate the build folder
  • Run npm run create-local to start running the graph node locally
  • Run npm run deploy-local to deploy the contents of the build folder locally
  • Go to http://localhost:8000/subgraphs/name/DistributedCollective/subgraph-template/graphql to see the iGraphQL GUI for your local subgraph

Once your subgraph is running, you can edit the mappings file, or follow the subgraph docs to edit the schema and add new data sources to your subgraph: https://thegraph.com/docs/en/developing/creating-a-subgraph/#the-subgraph-manifest

Scaffolding

When adding a new abi to the subgraph, you can auto-generate the subgraph.yaml and initial mapping file by running a scaffold script:

  • npm run scaffold -- -fp <ABI_FILE_PATH> -gm -gs -a <CONTRACT_ADDRESS> This will generate a mapping file in ./src with the name of the abi, a schema file in ./schema with an entity for each event, and a datasource in the subgraph.template.yml.

    Be aware that you will still need to add a startBlock to the new data source.

  • npm run scaffold -- --help for more options

File structure

.
├── abi                    # Contract abis as json file
├── *build                 # (generated by npm run build)*
├── config                 # Addresses, start blocks and config for mainnet and testnet
├── *generated             # (generated by npm run codegen)*
├── scripts                # Scripts for any set-up and file generation required for production
├── src            
   ├──entities             # Logic for creating and modifying entities
   ├──mappings             # Logic for handling events - calls entity functions
├──utils                   # Helper files for use in development
├──.env.example
├──.env
├──docker-compose.template.yml
├──*docker-compose.yml     # (generated by npm run prepare:RSK:testnet)*
├──package.json
├──README.md
├──schema.graphql  # Defines the database and graphql api schema
├──subgraph.template.yaml  # Subgraph manifest - defines which contracts and events to listen for
└──*subgraph.yaml          # (generated by npm run prepare:RSK:testnet)*

Entities directory

While it is not necessary to use the entities directory, it can make the code cleaner and more readable to separate out interactions with different entities. The entity file can act like a model, defining how a given entity can be interacted with.

The mappings files are called directly when a certain event is emitted, and act more like controller files. The mapping file may create or update multiple different entities by calling the exported functions from the relevant entity file.

In this example, when a Transfer event (defined in subgraph.yaml) is emitted, the handleTransfer function is called in src/mappings/ERC20, which calls the calls the createAndReturnTransaction function from the src/entities/Transaction file to create a Transaction entity.

See the Zero Subgraph for more examples.

Testing

Matchstick

There is a unit testing framework specifically for The Graph called Matchstick.

It is not implemented in this repo, but has improved a lot in the past 6 months and may be worth trying.

Debugging

A few tips for debugging subgraphs:

  • Remember that Assemblyscript is not Typescript. If your code does not build, it may be because it requires stricter type checking, or because you are trying to use a Typescript language feature not supported by Assemblyscript.
  • Search the logs for the name of the event handler you are trying to debug using docker logs [ GRAPH_NODE_INSTANCE ] 2>&1 | grep [ EVENT_HANDLER_NAME ]
  • Running the subgraph locally will create a local Postgres instance. Have a look at what is actually being saved in the database - is the entity not being save at all? Is it being created and then modified unexpectedly?
  • The Postgres database will create a new row every time and entity is updated in a new block. This will give you a good idea of how that entity is modified over time by certain events.
  • Make sure you know what outputs you are expecting from an entity at certain blocks. You can do this by contract calls to check state, or by manually working out what values you would expect after certain events

Useful info

  • The subgraph mappings files are written in AssemblyScript, not Typescript. AssemblyScript docs can be found here: https://www.assemblyscript.org/. Pay particular attention to the difference in the equality operator - === compares referencess, == compares values.
  • If you are having issues with postgres, try deleting the data/ directory from the subgraph root