mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 20:36:19 +00:00
Generate schema from ABI when using subgraph path (#101)
This commit is contained in:
parent
a267058d51
commit
561c2c9066
@ -23,6 +23,7 @@
|
|||||||
```yaml
|
```yaml
|
||||||
# Example config.yaml
|
# Example config.yaml
|
||||||
# Contracts to watch (required).
|
# Contracts to watch (required).
|
||||||
|
# Can pass empty array ([]) when using subgraphPath.
|
||||||
contracts:
|
contracts:
|
||||||
# Contract name.
|
# Contract name.
|
||||||
- name: Example
|
- name: Example
|
||||||
@ -34,8 +35,8 @@
|
|||||||
# Output folder path (logs output using `stdout` if not provided).
|
# Output folder path (logs output using `stdout` if not provided).
|
||||||
outputFolder: ../test-watcher
|
outputFolder: ../test-watcher
|
||||||
|
|
||||||
# Code generation mode [eth_call | storage | all | none] (default: all).
|
# Code generation mode [eth_call | storage | all | none] (default: none).
|
||||||
mode: all
|
mode: none
|
||||||
|
|
||||||
# Kind of watcher [lazy | active] (default: active).
|
# Kind of watcher [lazy | active] (default: active).
|
||||||
kind: active
|
kind: active
|
||||||
@ -47,6 +48,7 @@
|
|||||||
flatten: true
|
flatten: true
|
||||||
|
|
||||||
# Path to the subgraph build (optional).
|
# Path to the subgraph build (optional).
|
||||||
|
# Can set empty contracts array when using subgraphPath.
|
||||||
subgraphPath: ../graph-node/test/subgraph/example1/build
|
subgraphPath: ../graph-node/test/subgraph/example1/build
|
||||||
|
|
||||||
# NOTE: When passed an *URL* as contract path, it is assumed that it points to an already flattened contract file.
|
# NOTE: When passed an *URL* as contract path, it is assumed that it points to an already flattened contract file.
|
||||||
@ -149,7 +151,7 @@
|
|||||||
```bash
|
```bash
|
||||||
yarn checkpoint --address <contract-address> --block-hash [block-hash]
|
yarn checkpoint --address <contract-address> --block-hash [block-hash]
|
||||||
```
|
```
|
||||||
|
|
||||||
* To reset the watcher to a previous block number:
|
* To reset the watcher to a previous block number:
|
||||||
|
|
||||||
* Reset state:
|
* Reset state:
|
||||||
@ -175,7 +177,7 @@
|
|||||||
```bash
|
```bash
|
||||||
yarn import-state --import-file <import-file-path>
|
yarn import-state --import-file <import-file-path>
|
||||||
```
|
```
|
||||||
|
|
||||||
* To inspect a CID:
|
* To inspect a CID:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -3,16 +3,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import solc from 'solc';
|
import solc from 'solc';
|
||||||
import { Writable } from 'stream';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles the given contract using solc and writes the resultant artifacts to a file.
|
* Compiles the given contract using solc and returns resultant artifacts.
|
||||||
* @param outStream A writable output stream to write the artifacts file to.
|
|
||||||
* @param contractContent Contents of the contract file to be compiled.
|
* @param contractContent Contents of the contract file to be compiled.
|
||||||
* @param contractFileName Input contract file name.
|
* @param contractFileName Input contract file name.
|
||||||
* @param contractName Name of the main contract in the contract file.
|
* @param contractName Name of the main contract in the contract file.
|
||||||
*/
|
*/
|
||||||
export function exportArtifacts (outStream: Writable, contractContent: string, contractFileName: string, contractName: string): void {
|
export function generateArtifacts (contractContent: string, contractFileName: string, contractName: string): { abi: any[], storageLayout: any } {
|
||||||
const input: any = {
|
const input: any = {
|
||||||
language: 'Solidity',
|
language: 'Solidity',
|
||||||
sources: {},
|
sources: {},
|
||||||
@ -30,6 +28,5 @@ export function exportArtifacts (outStream: Writable, contractContent: string, c
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get artifacts for the required contract.
|
// Get artifacts for the required contract.
|
||||||
const output = JSON.parse(solc.compile(JSON.stringify(input))).contracts[contractFileName][contractName];
|
return JSON.parse(solc.compile(JSON.stringify(input))).contracts[contractFileName][contractName];
|
||||||
outStream.write(JSON.stringify(output, null, 2));
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import { MODE_ETH_CALL, MODE_STORAGE, MODE_ALL, MODE_NONE, DEFAULT_PORT } from '
|
|||||||
import { Visitor } from './visitor';
|
import { Visitor } from './visitor';
|
||||||
import { exportServer } from './server';
|
import { exportServer } from './server';
|
||||||
import { exportConfig } from './config';
|
import { exportConfig } from './config';
|
||||||
import { exportArtifacts } from './artifacts';
|
import { generateArtifacts } from './artifacts';
|
||||||
import { exportPackage } from './package';
|
import { exportPackage } from './package';
|
||||||
import { exportTSConfig } from './tsconfig';
|
import { exportTSConfig } from './tsconfig';
|
||||||
import { exportReadme } from './readme';
|
import { exportReadme } from './readme';
|
||||||
@ -35,7 +35,7 @@ import { exportCheckpoint } from './checkpoint';
|
|||||||
import { exportState } from './export-state';
|
import { exportState } from './export-state';
|
||||||
import { importState } from './import-state';
|
import { importState } from './import-state';
|
||||||
import { exportInspectCID } from './inspect-cid';
|
import { exportInspectCID } from './inspect-cid';
|
||||||
import { getContractKindList } from './utils/subgraph';
|
import { getSubgraphConfig } from './utils/subgraph';
|
||||||
|
|
||||||
const main = async (): Promise<void> => {
|
const main = async (): Promise<void> => {
|
||||||
const argv = await yargs(hideBin(process.argv))
|
const argv = await yargs(hideBin(process.argv))
|
||||||
@ -50,25 +50,48 @@ const main = async (): Promise<void> => {
|
|||||||
const config = getConfig(path.resolve(argv['config-file']));
|
const config = getConfig(path.resolve(argv['config-file']));
|
||||||
|
|
||||||
// Create an array of flattened contract strings.
|
// Create an array of flattened contract strings.
|
||||||
const contracts: any = [];
|
const contracts: any[] = [];
|
||||||
|
|
||||||
for (const contract of config.contracts) {
|
for (const contract of config.contracts) {
|
||||||
const inputFile = contract.path;
|
const { path: inputFile, abiPath, name, kind } = contract;
|
||||||
assert(typeof inputFile === 'string', 'Contract input file path should be a string');
|
|
||||||
|
|
||||||
let contractString;
|
const contractData: any = {
|
||||||
|
contractName: name,
|
||||||
|
contractKind: kind
|
||||||
|
};
|
||||||
|
|
||||||
if (inputFile.startsWith('http')) {
|
if (abiPath) {
|
||||||
// Assume flattened file in case of URL.
|
const abiString = fs.readFileSync(path.resolve(abiPath)).toString();
|
||||||
const response = await fetch(inputFile);
|
contractData.contractAbi = JSON.parse(abiString);
|
||||||
contractString = await response.text();
|
|
||||||
} else {
|
|
||||||
contractString = config.flatten
|
|
||||||
? await flatten(path.resolve(inputFile))
|
|
||||||
: fs.readFileSync(path.resolve(inputFile)).toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contracts.push({ contractString, contractName: contract.name, contractKind: contract.kind });
|
if (inputFile) {
|
||||||
|
assert(typeof inputFile === 'string', 'Contract input file path should be a string');
|
||||||
|
|
||||||
|
if (inputFile.startsWith('http')) {
|
||||||
|
// Assume flattened file in case of URL.
|
||||||
|
const response = await fetch(inputFile);
|
||||||
|
contractData.contractString = await response.text();
|
||||||
|
} else {
|
||||||
|
contractData.contractString = config.flatten
|
||||||
|
? await flatten(path.resolve(inputFile))
|
||||||
|
: fs.readFileSync(path.resolve(inputFile)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate artifacts from contract.
|
||||||
|
const inputFileName = path.basename(inputFile, '.sol');
|
||||||
|
|
||||||
|
const { abi, storageLayout } = generateArtifacts(
|
||||||
|
contractData.contractString,
|
||||||
|
`${inputFileName}.sol`,
|
||||||
|
contractData.contractName
|
||||||
|
);
|
||||||
|
|
||||||
|
contractData.contractAbi = abi;
|
||||||
|
contractData.contractStorageLayout = storageLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
contracts.push(contractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const visitor = new Visitor();
|
const visitor = new Visitor();
|
||||||
@ -79,7 +102,6 @@ const main = async (): Promise<void> => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function parseAndVisit (visitor: Visitor, contracts: any[], mode: string) {
|
function parseAndVisit (visitor: Visitor, contracts: any[], mode: string) {
|
||||||
const eventDefinitionVisitor = visitor.eventDefinitionVisitor.bind(visitor);
|
|
||||||
let functionDefinitionVisitor;
|
let functionDefinitionVisitor;
|
||||||
let stateVariableDeclarationVisitor;
|
let stateVariableDeclarationVisitor;
|
||||||
|
|
||||||
@ -94,19 +116,21 @@ function parseAndVisit (visitor: Visitor, contracts: any[], mode: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const contract of contracts) {
|
for (const contract of contracts) {
|
||||||
// Get the abstract syntax tree for the flattened contract.
|
|
||||||
const ast = parse(contract.contractString);
|
|
||||||
|
|
||||||
// Filter out library nodes.
|
|
||||||
ast.children = ast.children.filter(child => !(child.type === 'ContractDefinition' && child.kind === 'library'));
|
|
||||||
|
|
||||||
visitor.setContract(contract.contractName, contract.contractKind);
|
visitor.setContract(contract.contractName, contract.contractKind);
|
||||||
|
visitor.parseEvents(contract.contractAbi);
|
||||||
|
|
||||||
visit(ast, {
|
if (contract.contractString) {
|
||||||
FunctionDefinition: functionDefinitionVisitor,
|
// Get the abstract syntax tree for the flattened contract.
|
||||||
StateVariableDeclaration: stateVariableDeclarationVisitor,
|
const ast = parse(contract.contractString);
|
||||||
EventDefinition: eventDefinitionVisitor
|
|
||||||
});
|
// Filter out library nodes.
|
||||||
|
ast.children = ast.children.filter(child => !(child.type === 'ContractDefinition' && child.kind === 'library'));
|
||||||
|
|
||||||
|
visit(ast, {
|
||||||
|
StateVariableDeclaration: stateVariableDeclarationVisitor,
|
||||||
|
FunctionDefinition: functionDefinitionVisitor
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,19 +157,12 @@ function generateWatcher (visitor: Visitor, contracts: any[], config: any) {
|
|||||||
let outStream: Writable;
|
let outStream: Writable;
|
||||||
|
|
||||||
// Export artifacts for the contracts.
|
// Export artifacts for the contracts.
|
||||||
config.contracts.forEach((contract: any, index: number) => {
|
contracts.forEach((contract: any) => {
|
||||||
const inputFileName = path.basename(contract.path, '.sol');
|
|
||||||
|
|
||||||
outStream = outputDir
|
outStream = outputDir
|
||||||
? fs.createWriteStream(path.join(outputDir, 'src/artifacts/', `${contract.name}.json`))
|
? fs.createWriteStream(path.join(outputDir, 'src/artifacts/', `${contract.contractName}.json`))
|
||||||
: process.stdout;
|
: process.stdout;
|
||||||
|
|
||||||
exportArtifacts(
|
outStream.write(JSON.stringify({ abi: contract.contractAbi, storageLayout: contract.contractStorageLayout }, null, 2));
|
||||||
outStream,
|
|
||||||
contracts[index].contractString,
|
|
||||||
`${inputFileName}.sol`,
|
|
||||||
contract.name
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register the handlebar helpers to be used in the templates.
|
// Register the handlebar helpers to be used in the templates.
|
||||||
@ -166,7 +183,7 @@ function generateWatcher (visitor: Visitor, contracts: any[], config: any) {
|
|||||||
outStream = outputDir
|
outStream = outputDir
|
||||||
? fs.createWriteStream(path.join(outputDir, 'src/indexer.ts'))
|
? fs.createWriteStream(path.join(outputDir, 'src/indexer.ts'))
|
||||||
: process.stdout;
|
: process.stdout;
|
||||||
visitor.exportIndexer(outStream, config.contracts);
|
visitor.exportIndexer(outStream, contracts);
|
||||||
|
|
||||||
outStream = outputDir
|
outStream = outputDir
|
||||||
? fs.createWriteStream(path.join(outputDir, 'src/server.ts'))
|
? fs.createWriteStream(path.join(outputDir, 'src/server.ts'))
|
||||||
@ -304,31 +321,38 @@ function getConfig (configFile: string): any {
|
|||||||
assert(typeof inputConfig.port === 'number', 'Invalid watcher server port');
|
assert(typeof inputConfig.port === 'number', 'Invalid watcher server port');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that every input contract kind is present in the subgraph config.
|
|
||||||
let subgraphPath;
|
|
||||||
|
|
||||||
if (inputConfig.subgraphPath) {
|
|
||||||
// Resolve path.
|
|
||||||
subgraphPath = inputConfig.subgraphPath.replace(/^~/, os.homedir());
|
|
||||||
|
|
||||||
const subgraphKinds: string[] = getContractKindList(subgraphPath);
|
|
||||||
const inputKinds: string[] = inputConfig.contracts.map((contract: any) => contract.kind);
|
|
||||||
|
|
||||||
assert(
|
|
||||||
inputKinds.every((inputKind: string) => subgraphKinds.includes(inputKind)),
|
|
||||||
'Input contract kind not available in the subgraph.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputFlatten = inputConfig.flatten;
|
|
||||||
const flatten = (inputFlatten === undefined || inputFlatten === null) ? true : inputFlatten;
|
|
||||||
|
|
||||||
// Resolve paths.
|
// Resolve paths.
|
||||||
const contracts = inputConfig.contracts.map((contract: any) => {
|
const contracts = inputConfig.contracts.map((contract: any) => {
|
||||||
contract.path = contract.path.replace(/^~/, os.homedir());
|
contract.path = contract.path.replace(/^~/, os.homedir());
|
||||||
return contract;
|
return contract;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let subgraphPath: any;
|
||||||
|
let subgraphConfig;
|
||||||
|
|
||||||
|
if (inputConfig.subgraphPath) {
|
||||||
|
// Resolve path.
|
||||||
|
subgraphPath = inputConfig.subgraphPath.replace(/^~/, os.homedir());
|
||||||
|
subgraphConfig = getSubgraphConfig(subgraphPath);
|
||||||
|
|
||||||
|
// Add contracts missing for dataSources in subgraph config.
|
||||||
|
subgraphConfig.dataSources.forEach((dataSource: any) => {
|
||||||
|
if (!contracts.some((contract: any) => contract.kind === dataSource.name)) {
|
||||||
|
const abi = dataSource.mapping.abis.find((abi: any) => abi.name === dataSource.source.abi);
|
||||||
|
const abiPath = path.resolve(subgraphPath, abi.file);
|
||||||
|
|
||||||
|
contracts.push({
|
||||||
|
name: dataSource.name,
|
||||||
|
kind: dataSource.name,
|
||||||
|
abiPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputFlatten = inputConfig.flatten;
|
||||||
|
const flatten = (inputFlatten === undefined || inputFlatten === null) ? true : inputFlatten;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
contracts,
|
contracts,
|
||||||
outputFolder: inputConfig.outputFolder,
|
outputFolder: inputConfig.outputFolder,
|
||||||
@ -336,7 +360,8 @@ function getConfig (configFile: string): any {
|
|||||||
kind: inputConfig.kind || KIND_ACTIVE,
|
kind: inputConfig.kind || KIND_ACTIVE,
|
||||||
port: inputConfig.port || DEFAULT_PORT,
|
port: inputConfig.port || DEFAULT_PORT,
|
||||||
flatten,
|
flatten,
|
||||||
subgraphPath
|
subgraphPath,
|
||||||
|
subgraphConfig
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ import {
|
|||||||
import { GraphWatcher } from '@vulcanize/graph-node';
|
import { GraphWatcher } from '@vulcanize/graph-node';
|
||||||
|
|
||||||
{{#each contracts as | contract |}}
|
{{#each contracts as | contract |}}
|
||||||
import {{contract.name}}Artifacts from './artifacts/{{contract.name}}.json';
|
import {{contract.contractName}}Artifacts from './artifacts/{{contract.contractName}}.json';
|
||||||
{{/each}}
|
{{/each}}
|
||||||
import { Database } from './database';
|
import { Database } from './database';
|
||||||
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks';
|
||||||
@ -49,7 +49,7 @@ import { {{subgraphEntity.className}} } from './entity/{{subgraphEntity.classNam
|
|||||||
const log = debug('vulcanize:indexer');
|
const log = debug('vulcanize:indexer');
|
||||||
|
|
||||||
{{#each contracts as | contract |}}
|
{{#each contracts as | contract |}}
|
||||||
const KIND_{{capitalize contract.name}} = '{{contract.kind}}';
|
const KIND_{{capitalize contract.contractName}} = '{{contract.contractKind}}';
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{#each uniqueEvents as | event |}}
|
{{#each uniqueEvents as | event |}}
|
||||||
@ -131,15 +131,22 @@ export class Indexer implements IndexerInterface {
|
|||||||
this._contractMap = new Map();
|
this._contractMap = new Map();
|
||||||
|
|
||||||
{{#each contracts as | contract |}}
|
{{#each contracts as | contract |}}
|
||||||
const { abi: {{contract.name}}ABI, storageLayout: {{contract.name}}StorageLayout } = {{contract.name}}Artifacts;
|
const {
|
||||||
assert({{contract.name}}ABI);
|
abi: {{contract.contractName}}ABI,
|
||||||
assert({{contract.name}}StorageLayout);
|
{{#if contract.contractStorageLayout}}
|
||||||
|
storageLayout: {{contract.contractName}}StorageLayout
|
||||||
|
{{/if}}
|
||||||
|
} = {{contract.contractName}}Artifacts;
|
||||||
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#each contracts as | contract |}}
|
{{#each contracts as | contract |}}
|
||||||
this._abiMap.set(KIND_{{capitalize contract.name}}, {{contract.name}}ABI);
|
assert({{contract.contractName}}ABI);
|
||||||
this._storageLayoutMap.set(KIND_{{capitalize contract.name}}, {{contract.name}}StorageLayout);
|
this._abiMap.set(KIND_{{capitalize contract.contractName}}, {{contract.contractName}}ABI);
|
||||||
this._contractMap.set(KIND_{{capitalize contract.name}}, new ethers.utils.Interface({{contract.name}}ABI));
|
{{#if contract.contractStorageLayout}}
|
||||||
|
assert({{contract.contractName}}StorageLayout);
|
||||||
|
this._storageLayoutMap.set(KIND_{{capitalize contract.contractName}}, {{contract.contractName}}StorageLayout);
|
||||||
|
{{/if}}
|
||||||
|
this._contractMap.set(KIND_{{capitalize contract.contractName}}, new ethers.utils.Interface({{contract.contractName}}ABI));
|
||||||
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
this._entityTypesMap = new Map();
|
this._entityTypesMap = new Map();
|
||||||
@ -434,8 +441,8 @@ export class Indexer implements IndexerInterface {
|
|||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
{{#each contracts as | contract |}}
|
{{#each contracts as | contract |}}
|
||||||
case KIND_{{capitalize contract.name}}: {
|
case KIND_{{capitalize contract.contractName}}: {
|
||||||
({ eventName, eventInfo } = this.parse{{contract.name}}Event(logDescription));
|
({ eventName, eventInfo } = this.parse{{contract.contractName}}Event(logDescription));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -450,13 +457,13 @@ export class Indexer implements IndexerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{#each contracts as | contract |}}
|
{{#each contracts as | contract |}}
|
||||||
parse{{contract.name}}Event (logDescription: ethers.utils.LogDescription): { eventName: string, eventInfo: any } {
|
parse{{contract.contractName}}Event (logDescription: ethers.utils.LogDescription): { eventName: string, eventInfo: any } {
|
||||||
let eventName = UNKNOWN_EVENT_NAME;
|
let eventName = UNKNOWN_EVENT_NAME;
|
||||||
let eventInfo = {};
|
let eventInfo = {};
|
||||||
|
|
||||||
switch (logDescription.name) {
|
switch (logDescription.name) {
|
||||||
{{#each ../events as | event |}}
|
{{#each ../events as | event |}}
|
||||||
{{#if (compare contract.kind event.kind)}}
|
{{#if (compare contract.contractKind event.kind)}}
|
||||||
case {{capitalize event.name}}_EVENT: {
|
case {{capitalize event.name}}_EVENT: {
|
||||||
eventName = logDescription.name;
|
eventName = logDescription.name;
|
||||||
{{#if event.params}}
|
{{#if event.params}}
|
||||||
|
@ -45,17 +45,11 @@ export function getFieldType (typeNode: any): { typeName: string, array: boolean
|
|||||||
return { typeName: typeNode.name.value, array: false, nullable: true };
|
return { typeName: typeNode.name.value, array: false, nullable: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getContractKindList (subgraphPath: string): string[] {
|
export function getSubgraphConfig (subgraphPath: string): any {
|
||||||
const subgraphConfigPath = path.join(path.resolve(subgraphPath), '/subgraph.yaml');
|
const subgraphConfigPath = path.join(path.resolve(subgraphPath), '/subgraph.yaml');
|
||||||
|
|
||||||
assert(fs.existsSync(subgraphConfigPath), `Subgraph config file not found at ${subgraphConfigPath}`);
|
assert(fs.existsSync(subgraphConfigPath), `Subgraph config file not found at ${subgraphConfigPath}`);
|
||||||
const subgraph = yaml.load(fs.readFileSync(subgraphConfigPath, 'utf8')) as any;
|
return yaml.load(fs.readFileSync(subgraphConfigPath, 'utf8')) as any;
|
||||||
|
|
||||||
const contractKinds: string[] = subgraph.dataSources.map((dataSource: any) => {
|
|
||||||
return dataSource.name;
|
|
||||||
});
|
|
||||||
|
|
||||||
return contractKinds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseType (typeNode: any): any {
|
function parseType (typeNode: any): any {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import { Writable } from 'stream';
|
import { Writable } from 'stream';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import { utils } from 'ethers';
|
||||||
|
|
||||||
import { Database } from './database';
|
import { Database } from './database';
|
||||||
import { Entity } from './entity';
|
import { Entity } from './entity';
|
||||||
@ -125,19 +126,22 @@ export class Visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor function for event definitions.
|
* Function to parse event definitions.
|
||||||
* @param node ASTNode for an event definition.
|
* @param abi Contract ABI.
|
||||||
*/
|
*/
|
||||||
eventDefinitionVisitor (node: any): void {
|
parseEvents (abi: any): void {
|
||||||
const name = node.name;
|
const contractInterface = new utils.Interface(abi);
|
||||||
const params = node.parameters.map((item: any) => {
|
|
||||||
return { name: item.name, type: item.typeName.name };
|
Object.values(contractInterface.events).forEach(event => {
|
||||||
|
const params = event.inputs.map(input => {
|
||||||
|
return { name: input.name, type: input.type };
|
||||||
|
});
|
||||||
|
|
||||||
|
this._schema.addEventType(event.name, params);
|
||||||
|
|
||||||
|
assert(this._contract);
|
||||||
|
this._indexer.addEvent(event.name, params, this._contract.kind);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._schema.addEventType(name, params);
|
|
||||||
|
|
||||||
assert(this._contract);
|
|
||||||
this._indexer.addEvent(name, params, this._contract.kind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
visitSubgraph (subgraphPath?: string): void {
|
visitSubgraph (subgraphPath?: string): void {
|
||||||
|
Loading…
Reference in New Issue
Block a user