Add assertions to abi-gen templates and fix tests

This commit is contained in:
Fabio Berger 2019-05-20 13:33:53 +01:00
parent 6226aa0b23
commit 84d38ea878
15 changed files with 164 additions and 45 deletions

View File

@ -596,6 +596,9 @@ describe('ERC1155Proxy', () => {
const shouldRejectTransfer = true; const shouldRejectTransfer = true;
await erc1155Receiver.setRejectTransferFlag.awaitTransactionSuccessAsync( await erc1155Receiver.setRejectTransferFlag.awaitTransactionSuccessAsync(
shouldRejectTransfer, shouldRejectTransfer,
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS, constants.AWAIT_TRANSACTION_MINED_MS,
); );
// setup test parameters // setup test parameters

View File

@ -199,6 +199,9 @@ describe('Asset Transfer Proxies', () => {
await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync( await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
fromAddress, fromAddress,
constants.INITIAL_ERC20_BALANCE, constants.INITIAL_ERC20_BALANCE,
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS, constants.AWAIT_TRANSACTION_MINED_MS,
); );
await noReturnErc20Token.approve.awaitTransactionSuccessAsync( await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
@ -210,6 +213,9 @@ describe('Asset Transfer Proxies', () => {
await multipleReturnErc20Token.setBalance.awaitTransactionSuccessAsync( await multipleReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
fromAddress, fromAddress,
constants.INITIAL_ERC20_BALANCE, constants.INITIAL_ERC20_BALANCE,
{
from: owner,
},
constants.AWAIT_TRANSACTION_MINED_MS, constants.AWAIT_TRANSACTION_MINED_MS,
); );
await multipleReturnErc20Token.approve.awaitTransactionSuccessAsync( await multipleReturnErc20Token.approve.awaitTransactionSuccessAsync(

View File

@ -1,4 +1,12 @@
[ [
{
"version": "2.2.0",
"changes": [
{
"note": "add parameter assertions to methods"
}
]
},
{ {
"version": "2.1.0", "version": "2.1.0",
"changes": [ "changes": [

View File

@ -2,6 +2,7 @@
// tslint:disable:no-unused-variable // tslint:disable:no-unused-variable
// tslint:disable:no-unbound-method // tslint:disable:no-unbound-method
import { BaseContract, PromiseWithTransactionHash } from '@0x/base-contract'; import { BaseContract, PromiseWithTransactionHash } from '@0x/base-contract';
import { schemas } from '@0x/json-schemas';
import { import {
BlockParam, BlockParam,
BlockParamLiteral, BlockParamLiteral,
@ -18,6 +19,7 @@ import {
import { BigNumber, classUtils, logUtils, providerUtils } from '@0x/utils'; import { BigNumber, classUtils, logUtils, providerUtils } from '@0x/utils';
import { SimpleContractArtifact } from '@0x/types'; import { SimpleContractArtifact } from '@0x/types';
import { Web3Wrapper } from '@0x/web3-wrapper'; import { Web3Wrapper } from '@0x/web3-wrapper';
import { assert } from '@0x/assert';
import * as ethers from 'ethers'; import * as ethers from 'ethers';
// tslint:enable:no-unused-variable // tslint:enable:no-unused-variable
@ -57,6 +59,11 @@ export class {{contractName}}Contract extends BaseContract {
txDefaults: Partial<TxData>, txDefaults: Partial<TxData>,
{{> typed_params inputs=ctor.inputs}} {{> typed_params inputs=ctor.inputs}}
): Promise<{{contractName}}Contract> { ): Promise<{{contractName}}Contract> {
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
schemas.numberSchema,
schemas.jsNumber,
]);
if (artifact.compilerOutput === undefined) { if (artifact.compilerOutput === undefined) {
throw new Error('Compiler output not found in the artifact file'); throw new Error('Compiler output not found in the artifact file');
} }
@ -72,6 +79,12 @@ export class {{contractName}}Contract extends BaseContract {
txDefaults: Partial<TxData>, txDefaults: Partial<TxData>,
{{> typed_params inputs=ctor.inputs}} {{> typed_params inputs=ctor.inputs}}
): Promise<{{contractName}}Contract> { ): Promise<{{contractName}}Contract> {
assert.isString('bytecode', bytecode);
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
schemas.addressSchema,
schemas.numberSchema,
schemas.jsNumber,
]);
const provider = providerUtils.standardizeOrThrow(supportedProvider); const provider = providerUtils.standardizeOrThrow(supportedProvider);
const constructorAbi = BaseContract._lookupConstructorAbi(abi); const constructorAbi = BaseContract._lookupConstructorAbi(abi);
[{{> params inputs=ctor.inputs}}] = BaseContract._formatABIDataItemList( [{{> params inputs=ctor.inputs}}] = BaseContract._formatABIDataItemList(

View File

@ -3,6 +3,17 @@ async callAsync(
callData: Partial<CallData> = {}, callData: Partial<CallData> = {},
defaultBlock?: BlockParam, defaultBlock?: BlockParam,
): Promise<{{> return_type outputs=outputs}}> { ): Promise<{{> return_type outputs=outputs}}> {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [
schemas.addressSchema,
schemas.numberSchema,
schemas.jsNumber,
]);
if (defaultBlock !== undefined) {
assert.isBlockParam('defaultBlock', defaultBlock);
}
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const encodedData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]); const encodedData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]);
const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync(

View File

@ -1,19 +1,18 @@
public {{this.tsName}} = { public {{this.tsName}} = {
async sendTransactionAsync( async sendTransactionAsync(
{{> typed_params inputs=inputs}} {{> typed_params inputs=inputs}}
{{#this.payable}} txData?: Partial<TxData> | undefined,
txData: Partial<TxDataPayable> = {},
{{/this.payable}}
{{^this.payable}}
txData: Partial<TxData> = {},
{{/this.payable}}
): Promise<string> { ): Promise<string> {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const encodedData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]); const encodedData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]);
const passedInTxData = txData === undefined ? {} : txData;
const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync(
{ {
to: self.address, to: self.address,
...txData, ...passedInTxData,
data: encodedData, data: encodedData,
}, },
self._web3Wrapper.getContractDefaults(), self._web3Wrapper.getContractDefaults(),
@ -27,22 +26,13 @@ public {{this.tsName}} = {
}, },
awaitTransactionSuccessAsync( awaitTransactionSuccessAsync(
{{> typed_params inputs=inputs}} {{> typed_params inputs=inputs}}
{{#this.payable}} txData?: Partial<TxData>,
txData?: Partial<TxDataPayable> | number,
{{/this.payable}}
{{^this.payable}}
txData?: Partial<TxData> | number,
{{/this.payable}}
pollingIntervalMs?: number, pollingIntervalMs?: number,
timeoutMs?: number, timeoutMs?: number,
): PromiseWithTransactionHash<TransactionReceiptWithDecodedLogs> { ): PromiseWithTransactionHash<TransactionReceiptWithDecodedLogs> {
// `txData` may be omitted on its own, so it might be set to `pollingIntervalMs`. {{#each inputs}}
if (typeof(txData) === 'number') { {{#assertionType name type}}{{/assertionType}}
pollingIntervalMs = txData; {{/each}}
timeoutMs = pollingIntervalMs;
txData = {};
}
//
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
{{#if inputs}} {{#if inputs}}
const txHashPromise = self.{{this.tsName}}.sendTransactionAsync({{> params input=inputs}}, txData); const txHashPromise = self.{{this.tsName}}.sendTransactionAsync({{> params input=inputs}}, txData);
@ -63,14 +53,18 @@ public {{this.tsName}} = {
}, },
async estimateGasAsync( async estimateGasAsync(
{{> typed_params inputs=inputs}} {{> typed_params inputs=inputs}}
txData: Partial<TxData> = {}, txData?: Partial<TxData> | undefined,
): Promise<number> { ): Promise<number> {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const encodedData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]); const encodedData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]);
const passedInTxData = txData === undefined ? {} : txData;
const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync( const txDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync(
{ {
to: self.address, to: self.address,
...txData, ...passedInTxData,
data: encodedData, data: encodedData,
}, },
self._web3Wrapper.getContractDefaults(), self._web3Wrapper.getContractDefaults(),
@ -81,6 +75,9 @@ public {{this.tsName}} = {
getABIEncodedTransactionData( getABIEncodedTransactionData(
{{> typed_params inputs=inputs}} {{> typed_params inputs=inputs}}
): string { ): string {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
const self = this as any as {{contractName}}Contract; const self = this as any as {{contractName}}Contract;
const abiEncodedTransactionData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]); const abiEncodedTransactionData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> params inputs=inputs}}]);
return abiEncodedTransactionData; return abiEncodedTransactionData;

View File

@ -1,4 +1,12 @@
[ [
{
"version": "4.4.0",
"changes": [
{
"note": "Update wrappers to include parameter assertions"
}
]
},
{ {
"version": "4.3.0", "version": "4.3.0",
"changes": [ "changes": [

View File

@ -68,6 +68,7 @@ function registerPartials(partialsGlob: string): void {
} }
Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend)); Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend));
Handlebars.registerHelper('assertionType', utils.solTypeToAssertion.bind(utils));
Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend)); Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend));
if (args.partials) { if (args.partials) {
registerPartials(args.partials); registerPartials(args.partials);

View File

@ -7,6 +7,40 @@ import toSnakeCase = require('to-snake-case');
import { ContractsBackend, ParamKind } from './types'; import { ContractsBackend, ParamKind } from './types';
export const utils = { export const utils = {
solTypeToAssertion(solName: string, solType: string): string {
const trailingArrayRegex = /\[\d*\]$/;
if (solType.match(trailingArrayRegex)) {
const assertion = `assert.isArray('${solName}', ${solName});`;
return assertion;
} else {
const solTypeRegexToTsType = [
{
regex: '^u?int(8|16|32)?$',
assertion: '', // TODO(fabio): Create a combined assertion for `number|bigNumber`?
},
{ regex: '^string$', assertion: `assert.isString('${solName}', ${solName});` },
{ regex: '^address$', assertion: `assert.isString('${solName}', ${solName});` },
{ regex: '^bool$', assertion: `assert.isBoolean('${solName}', ${solName});` },
{ regex: '^u?int\\d*$', assertion: `assert.isBigNumber('${solName}', ${solName});` },
{ regex: '^bytes\\d*$', assertion: `assert.isString('${solName}', ${solName});` },
];
for (const regexAndTxType of solTypeRegexToTsType) {
const { regex, assertion } = regexAndTxType;
if (solType.match(regex)) {
return assertion;
}
}
const TUPLE_TYPE_REGEX = '^tuple$';
if (solType.match(TUPLE_TYPE_REGEX)) {
// Omit assertions for complex types for now
// TODO(fabio): Figure out an elegant way to map complex types to JSON-schemas and
// add a schema assertion for that type here.
const assertion = '';
return assertion;
}
throw new Error(`Unknown Solidity type found: ${solType}`);
}
},
solTypeToTsType(paramKind: ParamKind, backend: ContractsBackend, solType: string, components?: DataItem[]): string { solTypeToTsType(paramKind: ParamKind, backend: ContractsBackend, solType: string, components?: DataItem[]): string {
const trailingArrayRegex = /\[\d*\]$/; const trailingArrayRegex = /\[\d*\]$/;
if (solType.match(trailingArrayRegex)) { if (solType.match(trailingArrayRegex)) {

View File

@ -1,4 +1,12 @@
[ [
{
"version": "2.1.0",
"changes": [
{
"note": "Add new assertions: `isArray`, `isBlockParam`"
}
]
},
{ {
"timestamp": 1557507213, "timestamp": 1557507213,
"version": "2.0.10", "version": "2.0.10",

View File

@ -87,6 +87,20 @@ Validation errors: ${validationResult.errors.join(', ')}`;
const isValidUri = validUrl.isUri(value) !== undefined; const isValidUri = validUrl.isUri(value) !== undefined;
assert.assert(isValidUri, assert.typeAssertionMessage(variableName, 'uri', value)); assert.assert(isValidUri, assert.typeAssertionMessage(variableName, 'uri', value));
}, },
isBlockParam(variableName: string, value: any): void {
if (Number.isInteger(value) && value >= 0) {
return;
}
if (value === 'earliest' || value === 'latest' || value === 'pending') {
return;
}
throw new Error(assert.typeAssertionMessage(variableName, 'BlockParam', value));
},
isArray(variableName: string, value: any): void {
if (!Array.isArray(value)) {
throw new Error(assert.typeAssertionMessage(variableName, 'Array', value));
}
},
assert(condition: boolean, message: string): void { assert(condition: boolean, message: string): void {
if (!condition) { if (!condition) {
throw new Error(message); throw new Error(message);

View File

@ -43,6 +43,8 @@
"dependencies": { "dependencies": {
"@0x/typescript-typings": "^4.2.2", "@0x/typescript-typings": "^4.2.2",
"@0x/utils": "^4.3.3", "@0x/utils": "^4.3.3",
"@0x/assert": "^2.0.10",
"@0x/json-schemas": "^3.0.10",
"@0x/web3-wrapper": "^6.0.6", "@0x/web3-wrapper": "^6.0.6",
"ethereum-types": "^2.1.2", "ethereum-types": "^2.1.2",
"ethers": "~4.0.4", "ethers": "~4.0.4",

View File

@ -1,8 +1,11 @@
import { AbiEncoder, abiUtils, BigNumber } from '@0x/utils'; import { assert } from '@0x/assert';
import { schemas } from '@0x/json-schemas';
import { AbiEncoder, abiUtils, BigNumber, providerUtils } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper'; import { Web3Wrapper } from '@0x/web3-wrapper';
import { import {
AbiDefinition, AbiDefinition,
AbiType, AbiType,
CallData,
ConstructorAbi, ConstructorAbi,
ContractAbi, ContractAbi,
DataItem, DataItem,
@ -89,7 +92,7 @@ export class BaseContract {
} }
protected static async _applyDefaultsToTxDataAsync<T extends Partial<TxData | TxDataPayable>>( protected static async _applyDefaultsToTxDataAsync<T extends Partial<TxData | TxDataPayable>>(
txData: T, txData: T,
txDefaults: Partial<TxData>, txDefaults: Partial<TxData> | undefined,
estimateGasAsync?: (txData: T) => Promise<number>, estimateGasAsync?: (txData: T) => Promise<number>,
): Promise<TxData> { ): Promise<TxData> {
// Gas amount sourced with the following priorities: // Gas amount sourced with the following priorities:
@ -97,8 +100,9 @@ export class BaseContract {
// 2. Global config passed in at library instantiation // 2. Global config passed in at library instantiation
// 3. Gas estimate calculation + safety margin // 3. Gas estimate calculation + safety margin
const removeUndefinedProperties = _.pickBy.bind(_); const removeUndefinedProperties = _.pickBy.bind(_);
const finalTxDefaults: Partial<TxData> = txDefaults || {};
const txDataWithDefaults = { const txDataWithDefaults = {
...removeUndefinedProperties(txDefaults), ...removeUndefinedProperties(finalTxDefaults),
...removeUndefinedProperties(txData), ...removeUndefinedProperties(txData),
}; };
if (txDataWithDefaults.gas === undefined && estimateGasAsync !== undefined) { if (txDataWithDefaults.gas === undefined && estimateGasAsync !== undefined) {
@ -177,10 +181,20 @@ export class BaseContract {
abi: ContractAbi, abi: ContractAbi,
address: string, address: string,
supportedProvider: SupportedProvider, supportedProvider: SupportedProvider,
txDefaults?: Partial<TxData>, callAndTxnDefaults?: Partial<CallData>,
) { ) {
assert.isString('contractName', contractName);
assert.isETHAddressHex('address', address);
const provider = providerUtils.standardizeOrThrow(supportedProvider);
if (callAndTxnDefaults !== undefined) {
assert.doesConformToSchema('callAndTxnDefaults', callAndTxnDefaults, schemas.callDataSchema, [
schemas.addressSchema,
schemas.numberSchema,
schemas.jsNumber,
]);
}
this.contractName = contractName; this.contractName = contractName;
this._web3Wrapper = new Web3Wrapper(supportedProvider, txDefaults); this._web3Wrapper = new Web3Wrapper(provider, callAndTxnDefaults);
this.abi = abi; this.abi = abi;
this.address = address; this.address = address;
const methodAbis = this.abi.filter( const methodAbis = this.abi.filter(

View File

@ -92,7 +92,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const exchangeContract = await this._getExchangeContractAsync(); const exchangeContract = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const assetProxy = await exchangeContract.getAssetProxy.callAsync(proxyId, txData, methodOpts.defaultBlock); const assetProxy = await exchangeContract.getAssetProxy.callAsync(proxyId, txData, methodOpts.defaultBlock);
return assetProxy; return assetProxy;
} }
@ -107,7 +107,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const exchangeContract = await this._getExchangeContractAsync(); const exchangeContract = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const filledTakerAssetAmountInBaseUnits = await exchangeContract.filled.callAsync( const filledTakerAssetAmountInBaseUnits = await exchangeContract.filled.callAsync(
orderHash, orderHash,
txData, txData,
@ -124,7 +124,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const exchangeContract = await this._getExchangeContractAsync(); const exchangeContract = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const version = await exchangeContract.VERSION.callAsync(txData, methodOpts.defaultBlock); const version = await exchangeContract.VERSION.callAsync(txData, methodOpts.defaultBlock);
return version; return version;
} }
@ -146,7 +146,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const exchangeContract = await this._getExchangeContractAsync(); const exchangeContract = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const orderEpoch = await exchangeContract.orderEpoch.callAsync( const orderEpoch = await exchangeContract.orderEpoch.callAsync(
makerAddress, makerAddress,
senderAddress, senderAddress,
@ -166,7 +166,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const exchangeContract = await this._getExchangeContractAsync(); const exchangeContract = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const isCancelled = await exchangeContract.cancelled.callAsync(orderHash, txData, methodOpts.defaultBlock); const isCancelled = await exchangeContract.cancelled.callAsync(orderHash, txData, methodOpts.defaultBlock);
return isCancelled; return isCancelled;
} }
@ -836,7 +836,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.isHexString('signature', signature); assert.isHexString('signature', signature);
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const exchangeInstance = await this._getExchangeContractAsync(); const exchangeInstance = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const isValidSignature = await exchangeInstance.isValidSignature.callAsync( const isValidSignature = await exchangeInstance.isValidSignature.callAsync(
hash, hash,
signerAddress, signerAddress,
@ -867,7 +867,7 @@ export class ExchangeWrapper extends ContractWrapper {
const normalizedSignerAddress = signerAddress.toLowerCase(); const normalizedSignerAddress = signerAddress.toLowerCase();
const normalizedValidatorAddress = validatorAddress.toLowerCase(); const normalizedValidatorAddress = validatorAddress.toLowerCase();
const exchangeInstance = await this._getExchangeContractAsync(); const exchangeInstance = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const isValidSignature = await exchangeInstance.allowedValidators.callAsync( const isValidSignature = await exchangeInstance.allowedValidators.callAsync(
normalizedSignerAddress, normalizedSignerAddress,
normalizedValidatorAddress, normalizedValidatorAddress,
@ -892,7 +892,7 @@ export class ExchangeWrapper extends ContractWrapper {
} }
const exchangeInstance = await this._getExchangeContractAsync(); const exchangeInstance = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const isPreSigned = await exchangeInstance.preSigned.callAsync( const isPreSigned = await exchangeInstance.preSigned.callAsync(
hash, hash,
signerAddress, signerAddress,
@ -915,7 +915,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
} }
const exchangeInstance = await this._getExchangeContractAsync(); const exchangeInstance = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const isExecuted = await exchangeInstance.transactions.callAsync( const isExecuted = await exchangeInstance.transactions.callAsync(
transactionHash, transactionHash,
txData, txData,
@ -936,7 +936,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
} }
const exchangeInstance = await this._getExchangeContractAsync(); const exchangeInstance = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const orderInfo = await exchangeInstance.getOrderInfo.callAsync(order, txData, methodOpts.defaultBlock); const orderInfo = await exchangeInstance.getOrderInfo.callAsync(order, txData, methodOpts.defaultBlock);
return orderInfo; return orderInfo;
} }
@ -956,7 +956,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema); assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
} }
const exchangeInstance = await this._getExchangeContractAsync(); const exchangeInstance = await this._getExchangeContractAsync();
const txData = {}; const txData = undefined;
const ordersInfo = await exchangeInstance.getOrdersInfo.callAsync(orders, txData, methodOpts.defaultBlock); const ordersInfo = await exchangeInstance.getOrdersInfo.callAsync(orders, txData, methodOpts.defaultBlock);
return ordersInfo; return ordersInfo;
} }

View File

@ -55,7 +55,7 @@ export class Web3Wrapper {
private _provider: ZeroExProvider; private _provider: ZeroExProvider;
// Raw provider passed in. Do not use. Only here to return the unmodified provider passed in via `getProvider()` // Raw provider passed in. Do not use. Only here to return the unmodified provider passed in via `getProvider()`
private readonly _supportedProvider: SupportedProvider; private readonly _supportedProvider: SupportedProvider;
private readonly _txDefaults: Partial<TxData>; private readonly _callAndTxnDefaults: Partial<CallData> | undefined;
private _jsonRpcRequestId: number; private _jsonRpcRequestId: number;
/** /**
* Check if an address is a valid Ethereum address * Check if an address is a valid Ethereum address
@ -147,22 +147,22 @@ export class Web3Wrapper {
* Instantiates a new Web3Wrapper. * Instantiates a new Web3Wrapper.
* @param provider The Web3 provider instance you would like the Web3Wrapper to use for interacting with * @param provider The Web3 provider instance you would like the Web3Wrapper to use for interacting with
* the backing Ethereum node. * the backing Ethereum node.
* @param txDefaults Override TxData defaults sent with RPC requests to the backing Ethereum node. * @param callAndTxnDefaults Override Call and Txn Data defaults sent with RPC requests to the backing Ethereum node.
* @return An instance of the Web3Wrapper class. * @return An instance of the Web3Wrapper class.
*/ */
constructor(supportedProvider: SupportedProvider, txDefaults?: Partial<TxData>) { constructor(supportedProvider: SupportedProvider, callAndTxnDefaults: Partial<CallData> = {}) {
this.abiDecoder = new AbiDecoder([]); this.abiDecoder = new AbiDecoder([]);
this._supportedProvider = supportedProvider; this._supportedProvider = supportedProvider;
this._provider = providerUtils.standardizeOrThrow(supportedProvider); this._provider = providerUtils.standardizeOrThrow(supportedProvider);
this._txDefaults = txDefaults || {}; this._callAndTxnDefaults = callAndTxnDefaults;
this._jsonRpcRequestId = 1; this._jsonRpcRequestId = 1;
} }
/** /**
* Get the contract defaults set to the Web3Wrapper instance * Get the contract defaults set to the Web3Wrapper instance
* @return TxData defaults (e.g gas, gasPrice, nonce, etc...) * @return CallAndTxnData defaults (e.g gas, gasPrice, nonce, etc...)
*/ */
public getContractDefaults(): Partial<TxData> { public getContractDefaults(): Partial<CallData> | undefined {
return this._txDefaults; return this._callAndTxnDefaults;
} }
/** /**
* Retrieve the Web3 provider * Retrieve the Web3 provider