Migrate Subgraph
If you have an existing subgraph project that you want to migrate to the Blockflow system, follow this guide to ensure a smooth transition.
Configuring the studio.yaml file
Start by comparing your existing subgraph.yaml
file with the studio.yaml
file used in the Blockflow system. Both files serve as the entry point for configuring the subgraph, but the structure and naming conventions may differ.
subgraph.yaml
specVersion: 0.0.2
description: ERC20 Subgraph
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: ERC20
network: mainnet
source:
abi: ERC20
startBlock: 0
mapping:
kind: ethereum/events
apiVersion: 0.0.4
language: wasm/assemblyscript
entities:
- Account
- Token
- TokenApproval
- TokenBalance
abis:
- name: ERC20
file: ./abis/ERC20.json
eventHandlers:
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
file: ./src/mapping.ts
studio.yaml
name: cli-demo
description: a project to showcase cli working
startBlock: latest
userId: XXXXXXXX-XXXX-XXXX-XXXXXXXX-XXXXXXXX
projectId: XXXXXXXX-XXXX-XXXX-XXXXXXXX-XXXXXXXX
network: Ethereum
user: Jane-doe
schema:
file: ./studio.schema.ts
execution: parallel
Resources:
- Name: usdt
Abi: src/abis/usdt.json
Type: contract/event
Address: "0xdAC17F958D2ee523a2206206994597C13D831ec7"
Triggers:
- Event: Transfer(address indexed,address indexed,uint256)
Handler: src/handlers/usdt/Transfer.TransferHandler
Comparing the Schema
Next, compare your existing schema.graphql
file with the studio.schema.ts
file used in the Blockflow system. While the schema.graphql
file uses the GraphQL Schema Definition Language (SDL), the studio.schema.ts
file utilizes TypeScript interfaces to define the data model and entities.
Ensure that all entities and their fields are correctly mapped between the two schema files. You may need to make adjustments to the studio.schema.ts
file to ensure compatibility with the Blockflow system.
schema.graphql
type Transfer @entity {
id: ID!
to: String!
from: String!
amount: String!
}
studio.schema.ts
export interface Transfer {
id: String;
from_address: string;
to_address: string;
amount: Number;
}
During the migration process, it's important to note that the conversion between types and interfaces should be handled correctly:
Types to Interfaces: Any object types defined in the
schema.graphql
file should be converted to TypeScript interfaces in thestudio.schema.ts
file.Interfaces to Types: Conversely, any interfaces defined in the
schema.graphql
file should be converted to TypeScript types in thestudio.schema.ts
file.
schema.graphql
type Transfer {
id: ID!
from: Bytes!
to: Bytes!
value: BigInt!
}
interface Account {
id: ID!
balance: BigInt!
}
studio.schema.ts
export interface Transfer {
id: String;
from: string;
to: string;
value: Number;
}
type Account = {
id: String;
balance: Number;
}
Transforming Mapping Handlers
In the Blockflow system, each handler function for a specific trigger (event or function) must be written in a separate file. This file structure aligns with the configuration defined in the studio.yaml
file, where each trigger is listed with its corresponding handler file path.
Syntax Changes
When migrating from an existing subgraph to the Blockflow system, there are a few syntax changes you'll need to make in your handler functions:
Retrieving and Creating Entities:
In the subgraph, you use the
.load()
function to retrieve entities.In blockflow, you should use a combination of
findOne
andcreate
functions.First, use
findOne
to check if an entity with the given criteria exists. If it does, you can update and save the existing entity.If
findOne
returnsnull
, meaning the entity does not exist, you can use thecreate
function to create a new entity instance.
subgraph syntax
let transfer = new Transfer(entityId); //to create new entity
let transfer = Transfer.load(entityId); //to load existing entity
blockflow syntax
let entity: ITransfer = await transferDB.create({id: entityId}); //to create
let entity: ITransfer = await transferDB.findOne({id: entityId}); //to load
Saving Entities:
In the Blockflow system, there is a minor difference in the syntax for saving entities.
Instead of using
entity.save()
directly, you should use thesave
function returned by thebind
function.The
save
function takes the entity instance as an argument.
subgraph syntax
transfer.save();
blockflow syntax
await transferDB.save(entity);