@0x/contracts-test-utils: Add TransactionHelper class.

`@0x/contracts-test-utils`: Add `decodeReceiptLogs()` to `LogDecoder`
class.
This commit is contained in:
Lawrence Forman
2019-08-05 22:22:37 -04:00
parent b6dfc791d4
commit 0eff19f0ff
3 changed files with 67 additions and 3 deletions

View File

@@ -26,6 +26,7 @@ export { addressUtils } from './address_utils';
export { OrderFactory } from './order_factory';
export { bytes32Values, testCombinatoriallyWithReferenceFunc, uint256Values } from './combinatorial_utils';
export { TransactionFactory } from './transaction_factory';
export { MutatorContractFunction, TransactionHelper } from './transaction_helper';
export { testWithReferenceFuncAsync } from './test_with_reference';
export { hexConcat, hexRandom } from './hex_utils';
export {

View File

@@ -7,6 +7,7 @@ import {
LogEntry,
LogWithDecodedArgs,
RawLog,
TransactionReceipt,
TransactionReceiptWithDecodedLogs,
} from 'ethereum-types';
import * as _ from 'lodash';
@@ -44,8 +45,14 @@ export class LogDecoder {
return logWithDecodedArgsOrLog;
}
public async getTxWithDecodedLogsAsync(txHash: string): Promise<TransactionReceiptWithDecodedLogs> {
const tx = await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
tx.logs = _.map(tx.logs, log => this.decodeLogOrThrow(log));
return tx;
const receipt = await this._web3Wrapper.awaitTransactionSuccessAsync(
txHash,
constants.AWAIT_TRANSACTION_MINED_MS,
);
return this.decodeReceiptLogs(receipt);
}
public decodeReceiptLogs(receipt: TransactionReceipt): TransactionReceiptWithDecodedLogs {
const decodedLogs = receipt.logs.map(log => this.decodeLogOrThrow(log));
return _.merge({}, receipt, { logs: decodedLogs });
}
}

View File

@@ -0,0 +1,56 @@
import { Web3Wrapper } from '@0x/web3-wrapper';
import { ContractArtifact, TransactionReceipt } from 'ethereum-types';
import { LogDecoder } from './log_decoder';
type AsyncFunction<TArgs extends any[], TResult> = (...args: TArgs) => Promise<TResult>;
interface ContractArtifacts {
[contractName: string]: ContractArtifact;
}
export interface MutatorContractFunction<
TCallAsyncArgs extends any[],
TAwaitTransactionSuccessAsyncArgs extends any[],
TCallAsyncResult
> {
callAsync: AsyncFunction<TCallAsyncArgs, TCallAsyncResult>;
sendTransactionAsync: AsyncFunction<TAwaitTransactionSuccessAsyncArgs, string>;
}
/**
* Helper class for performing non-constant contract functions calls.
*/
export class TransactionHelper {
public readonly logDecoder: LogDecoder;
constructor(web3Wrapper: Web3Wrapper, artifacts: ContractArtifacts) {
this.logDecoder = new LogDecoder(web3Wrapper, artifacts);
}
/**
* Call a non-constant contract function `contractFunction`, passing `args`.
* This will first perform an 'eth_call' (read-only) call in order to
* retrieve the return value, then a 'sendTransaction' to actually modify
* the state. Returns a tuple of the return value amd receipt, with decoded
* logs.
*/
public async getResultAndReceiptAsync<
TCallAsyncArgs extends any[],
TAwaitTransactionSuccessAsyncArgs extends any[],
TCallAsyncResult
>(
contractFunction: MutatorContractFunction<TCallAsyncArgs, TAwaitTransactionSuccessAsyncArgs, TCallAsyncResult>,
// tslint:disable-next-line: trailing-comma
...args: TAwaitTransactionSuccessAsyncArgs
): Promise<[TCallAsyncResult, TransactionReceipt]> {
// HACK(dorothy-zbornak): We take advantage of the general rule that
// the parameters for `callAsync()` are a subset of the
// parameters for `sendTransactionAsync()`.
const result = await contractFunction.callAsync(...((args as any) as TCallAsyncArgs));
const receipt = await this.logDecoder.getTxWithDecodedLogsAsync(
await contractFunction.sendTransactionAsync(...args),
);
return [result, receipt];
}
}