aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contract-wrappers
diff options
context:
space:
mode:
authorJacob Evans <jacob@dekz.net>2018-08-17 11:03:07 +0800
committerJacob Evans <jacob@dekz.net>2018-08-18 07:32:29 +0800
commit1c68057999ad9cb8be5018bffeeb6c1e45e645ad (patch)
treed6eae448d703f75c8c2527d5b988bb408d48d8f9 /packages/contract-wrappers
parent36668f94090fa5c35f636f6b7ba597fcb89c068d (diff)
downloaddexon-0x-contracts-1c68057999ad9cb8be5018bffeeb6c1e45e645ad.tar
dexon-0x-contracts-1c68057999ad9cb8be5018bffeeb6c1e45e645ad.tar.gz
dexon-0x-contracts-1c68057999ad9cb8be5018bffeeb6c1e45e645ad.tar.bz2
dexon-0x-contracts-1c68057999ad9cb8be5018bffeeb6c1e45e645ad.tar.lz
dexon-0x-contracts-1c68057999ad9cb8be5018bffeeb6c1e45e645ad.tar.xz
dexon-0x-contracts-1c68057999ad9cb8be5018bffeeb6c1e45e645ad.tar.zst
dexon-0x-contracts-1c68057999ad9cb8be5018bffeeb6c1e45e645ad.zip
Rename to Transaction Encoder.
Add tests for all encoding methods.
Diffstat (limited to 'packages/contract-wrappers')
-rw-r--r--packages/contract-wrappers/CHANGELOG.json9
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts11
-rw-r--r--packages/contract-wrappers/src/utils/execute_transaction_encoder.ts124
-rw-r--r--packages/contract-wrappers/src/utils/transaction_encoder.ts293
-rw-r--r--packages/contract-wrappers/test/execute_transaction_encoder_test.ts113
-rw-r--r--packages/contract-wrappers/test/transaction_encoder_test.ts211
6 files changed, 521 insertions, 240 deletions
diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json
index fdf779338..d50043b0d 100644
--- a/packages/contract-wrappers/CHANGELOG.json
+++ b/packages/contract-wrappers/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "version": "1.0.1-rc.4",
+ "changes": [
+ {
+ "pr": 975,
+ "note": "Added Transaction Encoder for use with 0x Exchange executeTransaction"
+ }
+ ]
+ },
+ {
"version": "1.0.1-rc.3",
"changes": [
{
diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
index 12d6a8fd3..5a4b40547 100644
--- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
@@ -21,7 +21,7 @@ import {
} from '../types';
import { assert } from '../utils/assert';
import { decorators } from '../utils/decorators';
-import { ExecuteTransactionEncoder } from '../utils/execute_transaction_encoder';
+import { TransactionEncoder } from '../utils/transaction_encoder';
import { ContractWrapper } from './contract_wrapper';
import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated/exchange';
@@ -1098,9 +1098,14 @@ export class ExchangeWrapper extends ContractWrapper {
const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxTokenAddress);
return zrxAssetData;
}
- public async executeTransactionEncoderAsync(): Promise<ExecuteTransactionEncoder> {
+ /**
+ * Returns a Transaction Encoder. Transaction messages exist for the purpose of calling methods on the Exchange contract
+ * in the context of another address.
+ * @return TransactionEncoder
+ */
+ public async transactionEncoderAsync(): Promise<TransactionEncoder> {
const exchangeInstance = await this._getExchangeContractAsync();
- const encoder = new ExecuteTransactionEncoder(exchangeInstance);
+ const encoder = new TransactionEncoder(exchangeInstance);
return encoder;
}
// tslint:disable:no-unused-variable
diff --git a/packages/contract-wrappers/src/utils/execute_transaction_encoder.ts b/packages/contract-wrappers/src/utils/execute_transaction_encoder.ts
deleted file mode 100644
index 9c941c550..000000000
--- a/packages/contract-wrappers/src/utils/execute_transaction_encoder.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { schemas } from '@0xproject/json-schemas';
-import { EIP712Schema, EIP712Types, EIP712Utils } from '@0xproject/order-utils';
-import { Order, SignedOrder } from '@0xproject/types';
-import { BigNumber } from '@0xproject/utils';
-import _ = require('lodash');
-
-import { ExchangeContract } from '../contract_wrappers/generated/exchange';
-
-import { assert } from './assert';
-
-const EIP712_ZEROEX_TRANSACTION_SCHEMA: EIP712Schema = {
- name: 'ZeroExTransaction',
- parameters: [
- { name: 'salt', type: EIP712Types.Uint256 },
- { name: 'signerAddress', type: EIP712Types.Address },
- { name: 'data', type: EIP712Types.Bytes },
- ],
-};
-
-export class ExecuteTransactionEncoder {
- private _exchangeInstance: ExchangeContract;
- constructor(exchangeInstance: ExchangeContract) {
- this._exchangeInstance = exchangeInstance;
- }
- public getExecuteTransactionHex(data: string, salt: BigNumber, signerAddress: string): string {
- const exchangeAddress = this._exchangeInstance.address;
- const executeTransactionData = {
- salt,
- signerAddress,
- data,
- };
- const executeTransactionHashBuff = EIP712Utils.structHash(
- EIP712_ZEROEX_TRANSACTION_SCHEMA,
- executeTransactionData,
- );
- const eip721MessageBuffer = EIP712Utils.createEIP712Message(executeTransactionHashBuff, exchangeAddress);
- const messageHex = `0x${eip721MessageBuffer.toString('hex')}`;
- return messageHex;
- }
- public fillOrder(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string {
- assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
- assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
- const abiEncodedData = this._exchangeInstance.fillOrder.getABIEncodedTransactionData(
- signedOrder,
- takerAssetFillAmount,
- signedOrder.signature,
- );
- return abiEncodedData;
- }
- public fillOrderNoThrow(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string {
- assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
- assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
- const abiEncodedData = this._exchangeInstance.fillOrderNoThrow.getABIEncodedTransactionData(
- signedOrder,
- takerAssetFillAmount,
- signedOrder.signature,
- );
- return abiEncodedData;
- }
- public fillOrKillOrder(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string {
- assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
- assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
- const abiEncodedData = this._exchangeInstance.fillOrKillOrder.getABIEncodedTransactionData(
- signedOrder,
- takerAssetFillAmount,
- signedOrder.signature,
- );
- return abiEncodedData;
- }
- public cancelOrdersUpTo(targetOrderEpoch: BigNumber): string {
- assert.isBigNumber('targetOrderEpoch', targetOrderEpoch);
- const abiEncodedData = this._exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(targetOrderEpoch);
- return abiEncodedData;
- }
- public cancelOrder(order: Order | SignedOrder): string {
- assert.doesConformToSchema('order', order, schemas.orderSchema);
- const abiEncodedData = this._exchangeInstance.cancelOrder.getABIEncodedTransactionData(order);
- return abiEncodedData;
- }
- public marketSellOrders(signedOrders: SignedOrder[], takerAssetFillAmount: BigNumber): string {
- assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
- assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount);
- const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
- const abiEncodedData = this._exchangeInstance.marketSellOrders.getABIEncodedTransactionData(
- signedOrders,
- takerAssetFillAmount,
- signatures,
- );
- return abiEncodedData;
- }
- public marketSellOrdersNoThrow(signedOrders: SignedOrder[], takerAssetFillAmount: BigNumber): string {
- assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
- assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount);
- const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
- const abiEncodedData = this._exchangeInstance.marketSellOrdersNoThrow.getABIEncodedTransactionData(
- signedOrders,
- takerAssetFillAmount,
- signatures,
- );
- return abiEncodedData;
- }
- public marketBuyOrders(signedOrders: SignedOrder[], makerAssetFillAmount: BigNumber): string {
- assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
- assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount);
- const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
- const abiEncodedData = this._exchangeInstance.marketBuyOrders.getABIEncodedTransactionData(
- signedOrders,
- makerAssetFillAmount,
- signatures,
- );
- return abiEncodedData;
- }
- public marketBuyOrdersNoThrow(signedOrders: SignedOrder[], makerAssetFillAmount: BigNumber): string {
- assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
- assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount);
- const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
- const abiEncodedData = this._exchangeInstance.marketBuyOrdersNoThrow.getABIEncodedTransactionData(
- signedOrders,
- makerAssetFillAmount,
- signatures,
- );
- return abiEncodedData;
- }
-}
diff --git a/packages/contract-wrappers/src/utils/transaction_encoder.ts b/packages/contract-wrappers/src/utils/transaction_encoder.ts
new file mode 100644
index 000000000..5c2a94b74
--- /dev/null
+++ b/packages/contract-wrappers/src/utils/transaction_encoder.ts
@@ -0,0 +1,293 @@
+import { schemas } from '@0xproject/json-schemas';
+import { EIP712Schema, EIP712Types, EIP712Utils } from '@0xproject/order-utils';
+import { Order, SignedOrder } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import _ = require('lodash');
+
+import { ExchangeContract } from '../contract_wrappers/generated/exchange';
+
+import { assert } from './assert';
+
+const EIP712_ZEROEX_TRANSACTION_SCHEMA: EIP712Schema = {
+ name: 'ZeroExTransaction',
+ parameters: [
+ { name: 'salt', type: EIP712Types.Uint256 },
+ { name: 'signerAddress', type: EIP712Types.Address },
+ { name: 'data', type: EIP712Types.Bytes },
+ ],
+};
+
+/**
+ * Transaction Encoder. Transaction messages exist for the purpose of calling methods on the Exchange contract
+ * in the context of another address. For example, UserA can encode and sign a fillOrder transaction and UserB
+ * can submit this to the blockchain. The Exchange context executes as if UserA had directly submitted this transaction.
+ */
+export class TransactionEncoder {
+ private _exchangeInstance: ExchangeContract;
+ constructor(exchangeInstance: ExchangeContract) {
+ this._exchangeInstance = exchangeInstance;
+ }
+ /**
+ * Encodes the transaction data for use with the Exchange contract.
+ * @param data The ABI Encoded 0x Exchange method. I.e fillOrder
+ * @param salt A random value to provide uniqueness and prevent replay attacks.
+ * @param signerAddress The address which will sign this transaction.
+ * @return An unsigned hex encoded transaction for use in 0x Exchange executeTransaction.
+ */
+ public getTransactionHex(data: string, salt: BigNumber, signerAddress: string): string {
+ const exchangeAddress = this._getExchangeContract().address;
+ const executeTransactionData = {
+ salt,
+ signerAddress,
+ data,
+ };
+ const executeTransactionHashBuff = EIP712Utils.structHash(
+ EIP712_ZEROEX_TRANSACTION_SCHEMA,
+ executeTransactionData,
+ );
+ const eip721MessageBuffer = EIP712Utils.createEIP712Message(executeTransactionHashBuff, exchangeAddress);
+ const messageHex = `0x${eip721MessageBuffer.toString('hex')}`;
+ return messageHex;
+ }
+ /**
+ * Encodes a fillOrder transaction.
+ * @param signedOrder An object that conforms to the SignedOrder interface.
+ * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
+ * @return Hex encoded abi of the function call.
+ */
+ public fillOrderTx(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string {
+ assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+ assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
+ const abiEncodedData = this._getExchangeContract().fillOrder.getABIEncodedTransactionData(
+ signedOrder,
+ takerAssetFillAmount,
+ signedOrder.signature,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a fillOrderNoThrow transaction.
+ * @param signedOrder An object that conforms to the SignedOrder interface.
+ * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
+ * @return Hex encoded abi of the function call.
+ */
+ public fillOrderNoThrowTx(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string {
+ assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+ assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
+ const abiEncodedData = this._getExchangeContract().fillOrderNoThrow.getABIEncodedTransactionData(
+ signedOrder,
+ takerAssetFillAmount,
+ signedOrder.signature,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a fillOrKillOrder transaction.
+ * @param signedOrder An object that conforms to the SignedOrder interface.
+ * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
+ * @return Hex encoded abi of the function call.
+ */
+ public fillOrKillOrderTx(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string {
+ assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+ assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
+ const abiEncodedData = this._getExchangeContract().fillOrKillOrder.getABIEncodedTransactionData(
+ signedOrder,
+ takerAssetFillAmount,
+ signedOrder.signature,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a batchFillOrders transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
+ * @return Hex encoded abi of the function call.
+ */
+ public batchFillOrdersTx(signedOrders: SignedOrder[], takerAssetFillAmounts: BigNumber[]): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ _.forEach(takerAssetFillAmounts, takerAssetFillAmount =>
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount),
+ );
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const abiEncodedData = this._getExchangeContract().batchFillOrders.getABIEncodedTransactionData(
+ signedOrders,
+ takerAssetFillAmounts,
+ signatures,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a batchFillOrKillOrders transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
+ * @return Hex encoded abi of the function call.
+ */
+ public batchFillOrKillOrdersTx(signedOrders: SignedOrder[], takerAssetFillAmounts: BigNumber[]): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ _.forEach(takerAssetFillAmounts, takerAssetFillAmount =>
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount),
+ );
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const abiEncodedData = this._getExchangeContract().batchFillOrKillOrders.getABIEncodedTransactionData(
+ signedOrders,
+ takerAssetFillAmounts,
+ signatures,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a batchFillOrdersNoThrow transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
+ * @return Hex encoded abi of the function call.
+ */
+ public batchFillOrdersNoThrowTx(signedOrders: SignedOrder[], takerAssetFillAmounts: BigNumber[]): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ _.forEach(takerAssetFillAmounts, takerAssetFillAmount =>
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount),
+ );
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const abiEncodedData = this._getExchangeContract().batchFillOrdersNoThrow.getABIEncodedTransactionData(
+ signedOrders,
+ takerAssetFillAmounts,
+ signatures,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a batchCancelOrders transaction.
+ * @param signedOrders An array of orders to cancel.
+ * @return Hex encoded abi of the function call.
+ */
+ public batchCancelOrdersTx(signedOrders: SignedOrder[]): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ const abiEncodedData = this._getExchangeContract().batchCancelOrders.getABIEncodedTransactionData(signedOrders);
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a cancelOrdersUpTo transaction.
+ * @param targetOrderEpoch Target order epoch.
+ * @return Hex encoded abi of the function call.
+ */
+ public cancelOrdersUpToTx(targetOrderEpoch: BigNumber): string {
+ assert.isBigNumber('targetOrderEpoch', targetOrderEpoch);
+ const abiEncodedData = this._getExchangeContract().cancelOrdersUpTo.getABIEncodedTransactionData(
+ targetOrderEpoch,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a cancelOrder transaction.
+ * @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel.
+ * @return Hex encoded abi of the function call.
+ */
+ public cancelOrderTx(order: Order | SignedOrder): string {
+ assert.doesConformToSchema('order', order, schemas.orderSchema);
+ const abiEncodedData = this._getExchangeContract().cancelOrder.getABIEncodedTransactionData(order);
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a marketSellOrders transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmount Taker asset fill amount.
+ * @return Hex encoded abi of the function call.
+ */
+ public marketSellOrdersTx(signedOrders: SignedOrder[], takerAssetFillAmount: BigNumber): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount);
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const abiEncodedData = this._getExchangeContract().marketSellOrders.getABIEncodedTransactionData(
+ signedOrders,
+ takerAssetFillAmount,
+ signatures,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a marketSellOrdersNoThrow transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmount Taker asset fill amount.
+ * @return Hex encoded abi of the function call.
+ */
+ public marketSellOrdersNoThrowTx(signedOrders: SignedOrder[], takerAssetFillAmount: BigNumber): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount);
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const abiEncodedData = this._getExchangeContract().marketSellOrdersNoThrow.getABIEncodedTransactionData(
+ signedOrders,
+ takerAssetFillAmount,
+ signatures,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a maketBuyOrders transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param makerAssetFillAmount Maker asset fill amount.
+ * @return Hex encoded abi of the function call.
+ */
+ public marketBuyOrdersTx(signedOrders: SignedOrder[], makerAssetFillAmount: BigNumber): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount);
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const abiEncodedData = this._getExchangeContract().marketBuyOrders.getABIEncodedTransactionData(
+ signedOrders,
+ makerAssetFillAmount,
+ signatures,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a maketBuyOrdersNoThrow transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param makerAssetFillAmount Maker asset fill amount.
+ * @return Hex encoded abi of the function call.
+ */
+ public marketBuyOrdersNoThrowTx(signedOrders: SignedOrder[], makerAssetFillAmount: BigNumber): string {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount);
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const abiEncodedData = this._getExchangeContract().marketBuyOrdersNoThrow.getABIEncodedTransactionData(
+ signedOrders,
+ makerAssetFillAmount,
+ signatures,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a preSign transaction.
+ * @param hash Hash to pre-sign
+ * @param signerAddress Address that should have signed the given hash.
+ * @param signature Proof that the hash has been signed by signer.
+ * @return Hex encoded abi of the function call.
+ */
+ public preSignTx(hash: string, signerAddress: string, signature: string): string {
+ assert.isHexString('hash', hash);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ assert.isHexString('signature', signature);
+ const abiEncodedData = this._getExchangeContract().preSign.getABIEncodedTransactionData(
+ hash,
+ signerAddress,
+ signature,
+ );
+ return abiEncodedData;
+ }
+ /**
+ * Encodes a setSignatureValidatorApproval transaction.
+ * @param validatorAddress Validator contract address.
+ * @param isApproved Boolean value to set approval to.
+ * @return Hex encoded abi of the function call.
+ */
+ public setSignatureValidatorApprovalTx(validatorAddress: string, isApproved: boolean): string {
+ assert.isETHAddressHex('validatorAddress', validatorAddress);
+ assert.isBoolean('isApproved', isApproved);
+ const abiEncodedData = this._getExchangeContract().setSignatureValidatorApproval.getABIEncodedTransactionData(
+ validatorAddress,
+ isApproved,
+ );
+ return abiEncodedData;
+ }
+ private _getExchangeContract(): ExchangeContract {
+ return this._exchangeInstance;
+ }
+}
diff --git a/packages/contract-wrappers/test/execute_transaction_encoder_test.ts b/packages/contract-wrappers/test/execute_transaction_encoder_test.ts
deleted file mode 100644
index 13635dfb8..000000000
--- a/packages/contract-wrappers/test/execute_transaction_encoder_test.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { FillScenarios } from '@0xproject/fill-scenarios';
-import { assetDataUtils, ecSignOrderHashAsync, generatePseudoRandomSalt } from '@0xproject/order-utils';
-import { SignedOrder, SignerType } from '@0xproject/types';
-import { BigNumber } from '@0xproject/utils';
-import * as chai from 'chai';
-import 'mocha';
-
-import { ContractWrappers } from '../src';
-
-import { chaiSetup } from './utils/chai_setup';
-import { constants } from './utils/constants';
-import { tokenUtils } from './utils/token_utils';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-describe('ExecuteTransactionEncoder', () => {
- let contractWrappers: ContractWrappers;
- let userAddresses: string[];
- let zrxTokenAddress: string;
- let fillScenarios: FillScenarios;
- let exchangeContractAddress: string;
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let senderAddress: string;
- let takerAddress: string;
- let makerAssetData: string;
- let takerAssetData: string;
- let feeRecipient: string;
- let txHash: string;
- const fillableAmount = new BigNumber(5);
- const takerTokenFillAmount = new BigNumber(5);
- let signedOrder: SignedOrder;
- let anotherSignedOrder: SignedOrder;
- const config = {
- networkId: constants.TESTRPC_NETWORK_ID,
- blockPollingIntervalMs: 0,
- };
- before(async () => {
- await blockchainLifecycle.startAsync();
- contractWrappers = new ContractWrappers(provider, config);
- exchangeContractAddress = contractWrappers.exchange.getContractAddress();
- userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- zrxTokenAddress = tokenUtils.getProtocolTokenAddress();
- fillScenarios = new FillScenarios(
- provider,
- userAddresses,
- zrxTokenAddress,
- exchangeContractAddress,
- contractWrappers.erc20Proxy.getContractAddress(),
- contractWrappers.erc721Proxy.getContractAddress(),
- );
- [coinbase, makerAddress, takerAddress, feeRecipient, senderAddress] = userAddresses;
- [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
- [makerAssetData, takerAssetData] = [
- assetDataUtils.encodeERC20AssetData(makerTokenAddress),
- assetDataUtils.encodeERC20AssetData(takerTokenAddress),
- ];
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- });
- after(async () => {
- await blockchainLifecycle.revertAsync();
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('encoder', () => {
- describe('#fillOrderAsync', () => {
- it('should fill a valid order', async () => {
- const encoder = await contractWrappers.exchange.executeTransactionEncoderAsync();
- const salt = generatePseudoRandomSalt();
- const signerAddress = takerAddress;
- const data = encoder.fillOrder(signedOrder, takerTokenFillAmount);
- const encodedTransaction = encoder.getExecuteTransactionHex(data, salt, signerAddress);
- const signature = await ecSignOrderHashAsync(
- provider,
- encodedTransaction,
- signerAddress,
- SignerType.Default,
- );
- txHash = await contractWrappers.exchange.executeTransactionAsync(
- salt,
- signerAddress,
- data,
- signature,
- senderAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
- });
- });
- });
-});
diff --git a/packages/contract-wrappers/test/transaction_encoder_test.ts b/packages/contract-wrappers/test/transaction_encoder_test.ts
new file mode 100644
index 000000000..10222dbc1
--- /dev/null
+++ b/packages/contract-wrappers/test/transaction_encoder_test.ts
@@ -0,0 +1,211 @@
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { FillScenarios } from '@0xproject/fill-scenarios';
+import { assetDataUtils, ecSignOrderHashAsync, generatePseudoRandomSalt, orderHashUtils } from '@0xproject/order-utils';
+import { SignedOrder, SignerType } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import 'mocha';
+
+import { ContractWrappers } from '../src';
+import { TransactionEncoder } from '../src/utils/transaction_encoder';
+
+import { constants } from './utils/constants';
+import { tokenUtils } from './utils/token_utils';
+import { provider, web3Wrapper } from './utils/web3_wrapper';
+
+const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+
+describe('TransactionEncoder', () => {
+ let contractWrappers: ContractWrappers;
+ let userAddresses: string[];
+ let fillScenarios: FillScenarios;
+ let exchangeContractAddress: string;
+ let makerTokenAddress: string;
+ let takerTokenAddress: string;
+ let coinbase: string;
+ let makerAddress: string;
+ let senderAddress: string;
+ let takerAddress: string;
+ let makerAssetData: string;
+ let takerAssetData: string;
+ let txHash: string;
+ const fillableAmount = new BigNumber(5);
+ const takerTokenFillAmount = new BigNumber(5);
+ let signedOrder: SignedOrder;
+ const config = {
+ networkId: constants.TESTRPC_NETWORK_ID,
+ blockPollingIntervalMs: 0,
+ };
+ before(async () => {
+ await blockchainLifecycle.startAsync();
+ contractWrappers = new ContractWrappers(provider, config);
+ exchangeContractAddress = contractWrappers.exchange.getContractAddress();
+ userAddresses = await web3Wrapper.getAvailableAddressesAsync();
+ const zrxTokenAddress = tokenUtils.getProtocolTokenAddress();
+ fillScenarios = new FillScenarios(
+ provider,
+ userAddresses,
+ zrxTokenAddress,
+ exchangeContractAddress,
+ contractWrappers.erc20Proxy.getContractAddress(),
+ contractWrappers.erc721Proxy.getContractAddress(),
+ );
+ [coinbase, makerAddress, takerAddress, senderAddress] = userAddresses;
+ [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
+ [makerAssetData, takerAssetData] = [
+ assetDataUtils.encodeERC20AssetData(makerTokenAddress),
+ assetDataUtils.encodeERC20AssetData(takerTokenAddress),
+ ];
+ signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerAssetData,
+ takerAssetData,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ );
+ });
+ after(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ beforeEach(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ afterEach(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ describe('encode and executeTransaction', () => {
+ const executeTransactionOrThrowAsync = async (
+ encoder: TransactionEncoder,
+ data: string,
+ signerAddress: string = takerAddress,
+ ): Promise<void> => {
+ const salt = generatePseudoRandomSalt();
+ const encodedTransaction = encoder.getTransactionHex(data, salt, signerAddress);
+ const signature = await ecSignOrderHashAsync(
+ provider,
+ encodedTransaction,
+ signerAddress,
+ SignerType.Default,
+ );
+ txHash = await contractWrappers.exchange.executeTransactionAsync(
+ salt,
+ signerAddress,
+ data,
+ signature,
+ senderAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ };
+ describe('#fillOrderTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.fillOrderTx(signedOrder, takerTokenFillAmount);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#fillOrderNoThrowTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.fillOrderNoThrowTx(signedOrder, takerTokenFillAmount);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#fillOrKillOrderTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.fillOrKillOrderTx(signedOrder, takerTokenFillAmount);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#marketSellOrdersTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.marketSellOrdersTx([signedOrder], takerTokenFillAmount);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#marketSellOrdersNoThrowTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.marketSellOrdersNoThrowTx([signedOrder], takerTokenFillAmount);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#marketBuyOrdersTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.marketBuyOrdersTx([signedOrder], fillableAmount);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#marketBuyOrdersNoThrowTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.marketBuyOrdersNoThrowTx([signedOrder], fillableAmount);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#preSignTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const signature = signedOrder.signature;
+ const data = encoder.preSignTx(orderHash, makerAddress, signature);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#setSignatureValidatorApprovalTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const isApproved = true;
+ const data = encoder.setSignatureValidatorApprovalTx(senderAddress, isApproved);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#batchFillOrdersTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.batchFillOrdersTx([signedOrder], [takerTokenFillAmount]);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#batchFillOrKillOrdersTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.batchFillOrKillOrdersTx([signedOrder], [takerTokenFillAmount]);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#batchFillOrdersNoThrowTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.batchFillOrdersNoThrowTx([signedOrder], [takerTokenFillAmount]);
+ await executeTransactionOrThrowAsync(encoder, data);
+ });
+ });
+ describe('#batchCancelOrdersTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.batchCancelOrdersTx([signedOrder]);
+ const signerAddress = makerAddress;
+ await executeTransactionOrThrowAsync(encoder, data, signerAddress);
+ });
+ });
+ describe('#cancelOrderTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const data = encoder.cancelOrderTx(signedOrder);
+ const signerAddress = makerAddress;
+ await executeTransactionOrThrowAsync(encoder, data, signerAddress);
+ });
+ });
+ describe('#cancelOrdersUpToTx', () => {
+ it('should successfully execute the transaction', async () => {
+ const encoder = await contractWrappers.exchange.transactionEncoderAsync();
+ const targetEpoch = signedOrder.salt;
+ const data = encoder.cancelOrdersUpToTx(targetEpoch);
+ const signerAddress = makerAddress;
+ await executeTransactionOrThrowAsync(encoder, data, signerAddress);
+ });
+ });
+ });
+});