mirror of
https://github.com/cerc-io/watcher-ts
synced 2026-09-07 16:34:06 +00:00
Generate GQL API for subgraph entities and auto-diff based on store set (#38)
* Add subgraph schema types to the generated schema * Add queries for subgraph entities * Add entity generation for subgraph entities * Call subgraph event handler in indexer * Refactor subgraph schema and entity generation * Add resolvers generation for subgraph entities * Get event signature in the event * Add NonNullType check for field type in entity generation * Auto-diff based on store set * Use contract address from data source in loader * Change subgraph-schema arg to subgraph-path arg
This commit is contained in:
@@ -40,7 +40,7 @@ export class Database {
|
||||
return this._baseDatabase.close();
|
||||
}
|
||||
|
||||
async getEntity (blockHash: string, entity: string, id: string): Promise<any> {
|
||||
async getEntity<Entity> (entity: (new () => Entity) | string, id: string, blockHash: string): Promise<Entity | undefined> {
|
||||
const queryRunner = this._conn.createQueryRunner();
|
||||
const repo = queryRunner.manager.getRepository(entity);
|
||||
const whereOptions: { [key: string]: any } = { id };
|
||||
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
ContractInterface
|
||||
} from 'ethers';
|
||||
|
||||
import { IndexerInterface } from '@vulcanize/util';
|
||||
|
||||
import { TypeId } from './types';
|
||||
import { Block, fromEthereumValue, toEthereumValue } from './utils';
|
||||
import { Database } from './database';
|
||||
@@ -36,7 +38,7 @@ export interface Context {
|
||||
}
|
||||
}
|
||||
|
||||
export const instantiate = async (database: Database, context: Context, filePath: string, data: GraphData = {}): Promise<loader.ResultObject & { exports: any }> => {
|
||||
export const instantiate = async (database: Database, indexer: IndexerInterface, context: Context, filePath: string, data: GraphData = {}): Promise<loader.ResultObject & { exports: any }> => {
|
||||
const { abis = {}, dataSource } = data;
|
||||
const buffer = await fs.readFile(filePath);
|
||||
const provider = getDefaultProvider(NETWORK_URL);
|
||||
@@ -48,7 +50,7 @@ export const instantiate = async (database: Database, context: Context, filePath
|
||||
const entityId = __getString(id);
|
||||
|
||||
assert(context.event.block);
|
||||
const entityData = await database.getEntity(context.event.block.blockHash, entityName, entityId);
|
||||
const entityData = await database.getEntity(entityName, entityId, context.event.block.blockHash);
|
||||
|
||||
if (!entityData) {
|
||||
return null;
|
||||
@@ -64,6 +66,19 @@ export const instantiate = async (database: Database, context: Context, filePath
|
||||
assert(context.event.block);
|
||||
const dbData = await database.fromGraphEntity(exports, context.event.block, entityName, entityInstance);
|
||||
await database.saveEntity(entityName, dbData);
|
||||
|
||||
// Remove blockNumber and blockHash from dbData for auto-diff.
|
||||
delete dbData.blockNumber;
|
||||
delete dbData.blockHash;
|
||||
|
||||
// Prepare the diff data.
|
||||
const diffData: any = { state: {} };
|
||||
diffData.state[entityName] = dbData;
|
||||
|
||||
// Create an auto-diff.
|
||||
assert(indexer.createDiffStaged);
|
||||
assert(dataSource?.address);
|
||||
await indexer.createDiffStaged(dataSource.address, context.event.block.blockHash, diffData);
|
||||
},
|
||||
|
||||
'typeConversion.stringToH160': () => {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
import path from 'path';
|
||||
@@ -10,6 +11,7 @@ import { ContractInterface, utils } from 'ethers';
|
||||
|
||||
import { ResultObject } from '@vulcanize/assemblyscript/lib/loader';
|
||||
import { EthClient } from '@vulcanize/ipld-eth-client';
|
||||
import { IndexerInterface } from '@vulcanize/util';
|
||||
|
||||
import { createEvent, getSubgraphConfig } from './utils';
|
||||
import { Context, instantiate } from './loader';
|
||||
@@ -24,6 +26,7 @@ interface DataSource {
|
||||
|
||||
export class GraphWatcher {
|
||||
_database: Database;
|
||||
_indexer?: IndexerInterface;
|
||||
_postgraphileClient: EthClient;
|
||||
_subgraphPath: string;
|
||||
_dataSources: any[] = [];
|
||||
@@ -67,8 +70,10 @@ export class GraphWatcher {
|
||||
|
||||
const filePath = path.join(this._subgraphPath, file);
|
||||
|
||||
assert(this._indexer);
|
||||
|
||||
return {
|
||||
instance: await instantiate(this._database, this._context, filePath, data),
|
||||
instance: await instantiate(this._database, this._indexer, this._context, filePath, data),
|
||||
contractInterface
|
||||
};
|
||||
}, {});
|
||||
@@ -144,7 +149,11 @@ export class GraphWatcher {
|
||||
await exports[eventHandler.handler](ethereumEvent);
|
||||
}
|
||||
|
||||
async getEntity (blockHash: string, entity: string, id: string): Promise<any> {
|
||||
return this._database.getEntity(blockHash, entity, id);
|
||||
setIndexer (indexer: IndexerInterface): void {
|
||||
this._indexer = indexer;
|
||||
}
|
||||
|
||||
async getEntity<Entity> (entity: new () => Entity, id: string, blockHash: string): Promise<Entity | undefined> {
|
||||
return this._database.getEntity(entity, id, blockHash);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user