βSubquery
Subquery - Queryloop

An individual API created using blockchain data is a subquery. Subqueries are deployed to a Queryloop Node using the Queryloop CLI after being queried using the QL query language. Indexers process subqueries and make them accessible for use by subquery consumers once they have been launched and published to The Queryloop's decentralized network.
Creating Subquery in Queryloop
A subquery retrieves information from a blockchain, modifies it, and stores it so that QL can quickly access it.

The subquery definition consists of a few files:
subquery.yaml
: a YAML file containing the subquery manifestschema.queryql
: a QL schema that defines what data is stored for your subquery, and how to query it via QLAssemblyScript Mappings
: AssemblyScript code that translates from the event data to the entities defined in your schema (e.g.mapping.ts
in this tutorial)
Install the Queryloop CLI
The Queryloop CLI is written in JavaScript, and you will need to install either yarn
or npm
to use it; it is assumed that you have yarn in what follows.
Once you have yarn
, install the Queryloop CLI by running
Install with yarn:
yarn global add @queryloopprotocol/query loop-cli
Install with npm:
npm install -g @queryloopprotocol/queryloop-cli
Once installed, the graph init
command can be used to set up a new subquery project, either from an existing contract or from an example subquery. This command can be used to create a subquery on the subquery Studio by passing in query init --product subquery-studio
. If you already have a smart contract deployed to your preferred network, bootstrapping a new subquery from that contract can be a good way to get started.
From An Existing Contract
The following command creates a subquery that indexes all events of an existing contract. It attempts to fetch the contract ABI from Bscscan/Etherscan and falls back to requesting a local file path. If any of the optional arguments are missing, it takes you through an interactive form.
queryloop init \ --product subquery-studio --from-contract <CONTRACT_ADDRESS> \ [--network <ETHEREUM_NETWORK>] \ [--abi <FILE>] \ <SUBQUERY_SLUG> [<DIRECTORY>]
The <SUBQUERY_SLUG>
is the ID of your subquery in Subquery Studio.
The Subquery Manifest
The manifest subquery of the subquery. The smart contracts that your subquery indexes, the events from these contracts to pay attention to, and the mapping between event data and entities that Queryloop Node saves and makes available for querying are all defined in yaml. You can get the whole specification for subquery manifests here.
For example subquery, subquery.yaml
is:
spec version: 0.0.4
description: Gravatar for Ethereum
repository: https://github.com/queryloopprotocol/queryloop-tooling
schema:
file: ./schema.queryloopql
dataSources:
- kind: ethereum/contract
name: Gravity
network: mainnet
source:
address: '0x2E645469f354BB4F5c8827944645929361cf77eC'
abi: Gravity
startBlock: 6175244
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Gravity
file: ./abis/Gravity.json
eventHandlers:
- event: NewGravatar(uint256,address,string,string)
handler: handleNewGravatar
- event: UpdatedGravatar(uint256,address,string,string)
handler: handleUpdatedGravatar
callHandlers:
- function: createGravatar(string,string)
handler: handleCreateGravatar
blockHandlers:
- handler: handleBlock
- handler: handleBlockWithCall
filter:
kind: call
file: ./src/mapping.ts
The important entries to update for the manifest are
description
: a human-readable description of what the subquery is. This description is displayed by the Queryloop Explorer when the subquery is deployed to the Hosted Service.repository
: the URL of the repository where the subquery manifest can be found. This is also displayed by The Queryloop Explorer.features
: a list of all used feature names.dataSources.source
: the address of the smart contract the subquery sources, and the ABI of the smart contract to use. The address is optional; omitting it allows us to index matching events from all contracts.data sources.source.startBlock
: the optional number of the block that the data source starts indexing from. In most cases, we suggest using the block in which the contract was created.dataSources.mapping.entities
: the entities that the data source writes to the store. The schema for each entity is defined in the schema.queryloopql file.dataSources.mapping.abis
: one or more named ABI files for the source contract as well as any other smart contracts that you interact with from within the mappings.dataSources.mapping.eventHandlers
: lists the smart contract events this subquery reacts to and the handlers in the mappingβ./src/mapping.ts in the exampleβthat transform these events into entities in the store.dataSources.mapping.callHandlers
: lists the smart contract functions this subquery reacts to and handlers in the mapping that transforms the inputs and outputs to function calls into entities in the store.dataSources.mapping.blockHandlers
: lists the blocks this subquery reacts to and handlers in the mapping to run when a block is appended to the chain. Without a filter, the block handler will be run every block. An optional call filter can be provided by adding afilter
field withkind: call
to the handler. This will only run the handler if the block contains at least one call to the data source contract.
Last updated