From fddad131a27d44bd923dab5a36f29baf0125fb8d Mon Sep 17 00:00:00 2001 From: Lawrence Forman Date: Fri, 26 Apr 2019 20:48:45 -0400 Subject: [PATCH] In `@0x/base-contract`: Expose `txHashPromise` in `PromiseWithTransactionHash`. In `@0x/abi-gen-templates`: Update `awaitTransactionSuccessAsync()` partial to expose `txHashPromise`. --- .../abi-gen-templates/partials/tx.handlebars | 28 +++++++++++-------- packages/base-contract/src/index.ts | 12 ++++---- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/packages/abi-gen-templates/partials/tx.handlebars b/packages/abi-gen-templates/partials/tx.handlebars index a8c205ac93..0a834ca223 100644 --- a/packages/abi-gen-templates/partials/tx.handlebars +++ b/packages/abi-gen-templates/partials/tx.handlebars @@ -25,7 +25,7 @@ public {{this.tsName}} = { const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults); return txHash; }, - async awaitTransactionSuccessAsync( + awaitTransactionSuccessAsync( {{> typed_params inputs=inputs}} {{#this.payable}} txData?: Partial | number, @@ -36,26 +36,30 @@ public {{this.tsName}} = { pollingIntervalMs?: number, timeoutMs?: number, ): PromiseWithTransactionHash { - // `txData` is optional, so it might be set to `pollingIntervalMs`. + // `txData` may be omitted on its own, so it might be set to `pollingIntervalMs`. if (typeof(txData) === 'number') { pollingIntervalMs = txData; timeoutMs = pollingIntervalMs; txData = {}; } + // const self = this as any as {{contractName}}Contract; {{#if inputs}} - const txHash = await self.{{this.tsName}}.sendTransactionAsync({{> params input=inputs}}, txData); + const txHashPromise = self.{{this.tsName}}.sendTransactionAsync({{> params input=inputs}}, txData); {{else}} - const txHash = await self.{{this.tsName}}.sendTransactionAsync(txData); + const txHashPromise = self.{{this.tsName}}.sendTransactionAsync(txData); {{/if}} - // tslint:disable-next-line: no-unnecessary-type-assertion - const receiptPromise = self._web3Wrapper.awaitTransactionSuccessAsync( - txHash, - pollingIntervalMs, - timeoutMs, - ) as any as PromiseWithTransactionHash; - receiptPromise.txHash = txHash; - return receiptPromise; + return new PromiseWithTransactionHash( + txHashPromise, + (async (): Promise => { + // When the transaction hash resolves, wait for it to be mined. + return self._web3Wrapper.awaitTransactionSuccessAsync( + await txHashPromise, + pollingIntervalMs, + timeoutMs, + ); + })(), + ); }, async estimateGasAsync( {{> typed_params inputs=inputs}} diff --git a/packages/base-contract/src/index.ts b/packages/base-contract/src/index.ts index ff6c7074a4..84a8e79313 100644 --- a/packages/base-contract/src/index.ts +++ b/packages/base-contract/src/index.ts @@ -26,14 +26,16 @@ export interface AbiEncoderByFunctionSignature { * Not used by BaseContract, but generated contracts will return it in * `awaitTransactionSuccessAsync()`. * Maybe there's a better place for this. - * If you're wondering why this class is not simpler, it's to get around - * Typescript/ES5 transpiling issues. */ export class PromiseWithTransactionHash implements PromiseLike { - public txHash: string = ''; + public readonly txHashPromise: Promise; private readonly _promise: Promise; - constructor(handler: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void) { - this._promise = new Promise(handler); + constructor( + txHashPromise: Promise, + promise: Promise, + ) { + this.txHashPromise = txHashPromise; + this._promise = promise; } public then( onFulfilled?: (v: T) => TResult | PromiseLike,