mirror of
https://github.com/cerc-io/watcher-ts
synced 2026-09-08 00:44:06 +00:00
Handle array and struct type event params in codegen (#150)
* Handle array and struct type event params * Refactor parse event in watcher indexer code
This commit is contained in:
@@ -8,7 +8,6 @@ import assert from 'assert';
|
||||
import Handlebars from 'handlebars';
|
||||
import { Writable } from 'stream';
|
||||
import _ from 'lodash';
|
||||
import { utils } from 'ethers';
|
||||
|
||||
import { getTsForSol } from './utils/type-mappings';
|
||||
import { Param } from './utils/types';
|
||||
@@ -83,31 +82,6 @@ export class Indexer {
|
||||
this._queries.push(queryObject);
|
||||
}
|
||||
|
||||
addEvent (name: string, params: Array<utils.ParamType>, contractKind: string): void {
|
||||
// Check if the event is already added.
|
||||
if (this._events.some(event => event.name === name && event.kind === contractKind)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eventObject = {
|
||||
name,
|
||||
params: params.map((param) => {
|
||||
const tsParamType = getTsForSol(param.type);
|
||||
assert(tsParamType);
|
||||
const isReferenceType = param.type === 'string' || param.type === 'bytes' || param.baseType === 'tuple' || param.baseType === 'array';
|
||||
|
||||
return {
|
||||
...param,
|
||||
type: tsParamType,
|
||||
isIndexedReferenceType: param.indexed && isReferenceType
|
||||
};
|
||||
}),
|
||||
kind: contractKind
|
||||
};
|
||||
|
||||
this._events.push(eventObject);
|
||||
}
|
||||
|
||||
addSubgraphEntities (subgraphSchemaDocument: any): void {
|
||||
// Add subgraph entities for creating the relations and entity types maps in the indexer.
|
||||
const subgraphTypeDefs = subgraphSchemaDocument.definitions;
|
||||
@@ -180,8 +154,6 @@ export class Indexer {
|
||||
exportIndexer (outStream: Writable, contracts: any[]): void {
|
||||
const template = Handlebars.compile(this._templateString);
|
||||
|
||||
const eventNames = this._events.map((event: any) => event.name);
|
||||
|
||||
const obj = {
|
||||
contracts,
|
||||
queries: this._queries,
|
||||
@@ -189,9 +161,7 @@ export class Indexer {
|
||||
constants: {
|
||||
MODE_ETH_CALL,
|
||||
MODE_STORAGE
|
||||
},
|
||||
events: this._events,
|
||||
uniqueEvents: new Set(eventNames)
|
||||
}
|
||||
};
|
||||
|
||||
const indexer = template(obj);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import assert from 'assert';
|
||||
import { GraphQLSchema, parse, printSchema, print } from 'graphql';
|
||||
import { SchemaComposer } from 'graphql-compose';
|
||||
import { ObjectTypeComposer, ObjectTypeComposerDefinition, ObjectTypeComposerFieldConfigMapDefinition, SchemaComposer } from 'graphql-compose';
|
||||
import { Writable } from 'stream';
|
||||
import { utils } from 'ethers';
|
||||
|
||||
@@ -76,27 +76,7 @@ export class Schema {
|
||||
return;
|
||||
}
|
||||
|
||||
const typeObject: any = {};
|
||||
typeObject.name = name;
|
||||
typeObject.fields = {};
|
||||
|
||||
if (params.length > 0) {
|
||||
typeObject.fields = params.reduce((acc, curr) => {
|
||||
const tsCurrType = getTsForSol(curr.type);
|
||||
assert(tsCurrType, `ts type for sol type ${curr.type} for ${curr.name} not found`);
|
||||
acc[curr.name] = `${getGqlForTs(tsCurrType)}!`;
|
||||
return acc;
|
||||
}, typeObject.fields);
|
||||
} else {
|
||||
// Types must define one or more fields.
|
||||
typeObject.fields = {
|
||||
dummy: 'String'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a type composer to add the required type in the schema composer.
|
||||
this._composer.createObjectTC(typeObject);
|
||||
|
||||
this._createObjectType(name, params);
|
||||
this._events.push(name);
|
||||
this._addToEventUnion(name);
|
||||
|
||||
@@ -459,4 +439,53 @@ export class Schema {
|
||||
// Add the new fields to the current type.
|
||||
eventTC.addFields(newFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create GraphQL schmea object type.
|
||||
* @param name
|
||||
* @param params
|
||||
*/
|
||||
_createObjectType (name: string, params: Array<utils.ParamType>): ObjectTypeComposer {
|
||||
const typeObject: ObjectTypeComposerDefinition<any, any> = { name };
|
||||
|
||||
if (params.length > 0) {
|
||||
typeObject.fields = params.reduce((acc: ObjectTypeComposerFieldConfigMapDefinition<any, any>, curr) => {
|
||||
acc[curr.name] = this._getObjectTypeField(curr);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
} else {
|
||||
// Types must define one or more fields.
|
||||
typeObject.fields = {
|
||||
dummy: 'String'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a type composer to add the required type in the schema composer.
|
||||
return this._composer.createObjectTC(typeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type of field in GraphQL schema for object types.
|
||||
* @param param
|
||||
*/
|
||||
_getObjectTypeField (param: utils.ParamType): ObjectTypeComposer | string | any[] {
|
||||
if (param.indexed && ['string', 'bytes', 'tuple', 'array'].includes(param.baseType)) {
|
||||
// Check for indexed reference type event params.
|
||||
param = utils.ParamType.fromObject({ type: 'bytes32', name: param.name });
|
||||
}
|
||||
|
||||
if (param.baseType === 'tuple') {
|
||||
const typeName = param.name.charAt(0).toUpperCase() + param.name.slice(1);
|
||||
return this._createObjectType(typeName, param.components);
|
||||
}
|
||||
|
||||
if (param.baseType === 'array') {
|
||||
return [this._getObjectTypeField(param.arrayChildren)];
|
||||
}
|
||||
|
||||
const tsCurrType = getTsForSol(param.type);
|
||||
assert(tsCurrType, `ts type for sol type ${param.type} for ${param.name} not found`);
|
||||
return `${getGqlForTs(tsCurrType)}!`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,7 +421,6 @@ export class Indexer implements IPLDIndexerInterface {
|
||||
}
|
||||
|
||||
{{/if}}
|
||||
|
||||
async triggerIndexingOnEvent (event: Event): Promise<void> {
|
||||
const resultEvent = this.getResultEvent(event);
|
||||
|
||||
@@ -450,9 +449,6 @@ export class Indexer implements IPLDIndexerInterface {
|
||||
}
|
||||
|
||||
parseEventNameAndArgs (kind: string, logObj: any): any {
|
||||
let eventName = UNKNOWN_EVENT_NAME;
|
||||
let eventInfo = {};
|
||||
|
||||
const { topics, data } = logObj;
|
||||
|
||||
const contract = this._contractMap.get(kind);
|
||||
@@ -460,15 +456,7 @@ export class Indexer implements IPLDIndexerInterface {
|
||||
|
||||
const logDescription = contract.parseLog({ data, topics });
|
||||
|
||||
switch (kind) {
|
||||
{{#each contracts as | contract |}}
|
||||
case KIND_{{capitalize contract.contractName}}: {
|
||||
({ eventName, eventInfo } = this.parse{{contract.contractName}}Event(logDescription));
|
||||
|
||||
break;
|
||||
}
|
||||
{{/each}}
|
||||
}
|
||||
const { eventName, eventInfo } = this._baseIndexer.parseEvent(logDescription)
|
||||
|
||||
return {
|
||||
eventName,
|
||||
@@ -477,45 +465,6 @@ export class Indexer implements IPLDIndexerInterface {
|
||||
};
|
||||
}
|
||||
|
||||
{{#each contracts as | contract |}}
|
||||
parse{{contract.contractName}}Event (logDescription: ethers.utils.LogDescription): { eventName: string, eventInfo: any } {
|
||||
let eventName = UNKNOWN_EVENT_NAME;
|
||||
let eventInfo = {};
|
||||
|
||||
switch (logDescription.name) {
|
||||
{{#each ../events as | event |}}
|
||||
{{#if (compare contract.contractKind event.kind)}}
|
||||
case {{capitalize event.name}}_EVENT: {
|
||||
eventName = logDescription.name;
|
||||
{{#if event.params}}
|
||||
const [{{#each event.params~}} {{this.name}} {{~#unless @last}}, {{/unless}} {{~/each}}] = logDescription.args;
|
||||
{{/if}}
|
||||
eventInfo = {
|
||||
{{#each event.params}}
|
||||
{{#if (compare this.type 'bigint')}}
|
||||
{{this.name}}: BigInt({{this.name}}.toString())
|
||||
{{~else if this.isIndexedReferenceType}}
|
||||
{{this.name}}: {{this.name}}.hash
|
||||
{{~else}}
|
||||
{{this.name}}
|
||||
{{~/if}}
|
||||
{{~#unless @last}},{{/unless}}
|
||||
{{/each}}
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
}
|
||||
|
||||
return {
|
||||
eventName,
|
||||
eventInfo
|
||||
};
|
||||
}
|
||||
|
||||
{{/each}}
|
||||
async getIPLDStatus (): Promise<IpldStatus | undefined> {
|
||||
return this._db.getIPLDStatus();
|
||||
}
|
||||
|
||||
@@ -138,9 +138,6 @@ export class Visitor {
|
||||
|
||||
Object.values(contractInterface.events).forEach(event => {
|
||||
this._schema.addEventType(event.name, event.inputs);
|
||||
|
||||
assert(this._contract);
|
||||
this._indexer.addEvent(event.name, event.inputs, this._contract.kind);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user