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<boolean> {
+    // 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<Array<Event>> {
     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<boolean> => {
+        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);
   }
 
   /**