From 936eac9591a0b57cb373f0ebaaa30591d3976124 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Tue, 28 Sep 2021 17:35:58 +0530 Subject: [PATCH] Add GQL mutations support --- packages/codegen/src/generate-code.ts | 2 +- packages/codegen/src/indexer.ts | 3 ++- packages/codegen/src/schema.ts | 19 +++++++++++++++++++ .../src/templates/indexer-template.handlebars | 7 +++++++ .../templates/resolvers-template.handlebars | 7 +++++++ packages/codegen/src/visitor.ts | 4 ++-- 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/codegen/src/generate-code.ts b/packages/codegen/src/generate-code.ts index b7e57d3f..adf400d5 100644 --- a/packages/codegen/src/generate-code.ts +++ b/packages/codegen/src/generate-code.ts @@ -146,7 +146,7 @@ function generateWatcher (data: string, visitor: Visitor, argv: any) { outStream = outputDir ? fs.createWriteStream(path.join(outputDir, 'src/indexer.ts')) : process.stdout; - visitor.exportIndexer(outStream, inputFileName); + visitor.exportIndexer(outStream, inputFileName, argv['contract-name']); outStream = outputDir ? fs.createWriteStream(path.join(outputDir, 'src/server.ts')) diff --git a/packages/codegen/src/indexer.ts b/packages/codegen/src/indexer.ts index 7f309c7e..37e41ff7 100644 --- a/packages/codegen/src/indexer.ts +++ b/packages/codegen/src/indexer.ts @@ -86,11 +86,12 @@ export class Indexer { * @param outStream A writable output stream to write the indexer file to. * @param inputFileName Input contract file name to be passed to the template. */ - exportIndexer (outStream: Writable, inputFileName: string): void { + exportIndexer (outStream: Writable, inputFileName: string, contractName: string): void { const template = Handlebars.compile(this._templateString); const obj = { inputFileName, + contractName, queries: this._queries, constants: { MODE_ETH_CALL, diff --git a/packages/codegen/src/schema.ts b/packages/codegen/src/schema.ts index 1b691ae9..06063102 100644 --- a/packages/codegen/src/schema.ts +++ b/packages/codegen/src/schema.ts @@ -94,6 +94,9 @@ export class Schema { * @returns GraphQLSchema object. */ buildSchema (): GraphQLSchema { + // Add a mutation for watching a contract. + this._addWatchContractMutation(); + return this._composer.buildSchema(); } @@ -239,6 +242,22 @@ export class Schema { }); } + /** + * Adds a watchContract mutation to the schema. + */ + _addWatchContractMutation (): void { + // Add a mutation to the schema composer. + this._composer.Mutation.addFields({ + watchContract: { + type: 'Boolean!', + args: { + contractAddress: 'String!', + startingBlock: 'Int' + } + } + }); + } + /** * Adds an 'Event' union (if doesn't exist) to the schema. Adds the specified event to the 'Event' union. * @param event Event type name to add to the union. diff --git a/packages/codegen/src/templates/indexer-template.handlebars b/packages/codegen/src/templates/indexer-template.handlebars index 86564a89..eb4f9f61 100644 --- a/packages/codegen/src/templates/indexer-template.handlebars +++ b/packages/codegen/src/templates/indexer-template.handlebars @@ -203,6 +203,13 @@ export class Indexer { return { eventName, eventInfo }; } + async watchContract (address: string, startingBlock: number): Promise { + // Always use the checksum address (https://docs.ethers.io/v5/api/utils/address/#utils-getAddress). + await this._db.saveContract(ethers.utils.getAddress(address), '{{contractName}}', startingBlock); + + return true; + } + async getEventsByFilter (blockHash: string, contract: string, name: string | null): Promise> { return this._baseIndexer.getEventsByFilter(blockHash, contract, name); } diff --git a/packages/codegen/src/templates/resolvers-template.handlebars b/packages/codegen/src/templates/resolvers-template.handlebars index 81ecee1b..56e979d3 100644 --- a/packages/codegen/src/templates/resolvers-template.handlebars +++ b/packages/codegen/src/templates/resolvers-template.handlebars @@ -33,6 +33,13 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch } }, + Mutation: { + watchContract: (_: any, { contractAddress, startingBlock = 1 }: { contractAddress: string, startingBlock: number }): Promise => { + log('watchContract', contractAddress, startingBlock); + return indexer.watchContract(contractAddress, startingBlock); + } + }, + Query: { {{#each queries}} {{this.name}}: (_: any, { blockHash, contractAddress diff --git a/packages/codegen/src/visitor.ts b/packages/codegen/src/visitor.ts index ed70c0cf..5bae0a00 100644 --- a/packages/codegen/src/visitor.ts +++ b/packages/codegen/src/visitor.ts @@ -115,8 +115,8 @@ export class Visitor { * @param outStream A writable output stream to write the indexer file to. * @param inputFileName Input contract file name to be passed to the template. */ - exportIndexer (outStream: Writable, inputFileName: string): void { - this._indexer.exportIndexer(outStream, inputFileName); + exportIndexer (outStream: Writable, inputFileName: string, contractName: string): void { + this._indexer.exportIndexer(outStream, inputFileName, contractName); } /**