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:
- The Graph Protocol documentation: https://thegraph.com/docs/en/
- Assemblyscript documentation: https://www.assemblyscript.org/introduction.html
- The Graph Academy has some great resources on subgraph best practices: https://thegraph.academy/developers/defining-a-subgraph/
- The Graph discord server is a great source of information and debugging help. It can act like StackOverflow for subgraph development: https://discord.com/channels/438038660412342282
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:https://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
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
.
├── 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)*
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.
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.
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
- 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