Move order utils to @0xproject/order-utils
This commit is contained in:
		@@ -1,4 +1,17 @@
 | 
				
			|||||||
[
 | 
					[
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "version": "0.38.0",
 | 
				
			||||||
 | 
					        "changes": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add `zeroEx.getProvider()`",
 | 
				
			||||||
 | 
					                "pr": 559
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Move `ZeroExError.InvalidSignature` to `@0xproject/order-utils` `OrderError.InvalidSignature`",
 | 
				
			||||||
 | 
					                "pr": 559
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        "version": "0.37.0",
 | 
					        "version": "0.37.0",
 | 
				
			||||||
        "changes": [
 | 
					        "changes": [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,6 +103,7 @@
 | 
				
			|||||||
        "@0xproject/types": "^0.6.1",
 | 
					        "@0xproject/types": "^0.6.1",
 | 
				
			||||||
        "@0xproject/typescript-typings": "^0.2.0",
 | 
					        "@0xproject/typescript-typings": "^0.2.0",
 | 
				
			||||||
        "@0xproject/utils": "^0.5.2",
 | 
					        "@0xproject/utils": "^0.5.2",
 | 
				
			||||||
 | 
					        "@0xproject/order-utils": "^0.0.1",
 | 
				
			||||||
        "@0xproject/web3-wrapper": "^0.6.1",
 | 
					        "@0xproject/web3-wrapper": "^0.6.1",
 | 
				
			||||||
        "bintrees": "^1.0.2",
 | 
					        "bintrees": "^1.0.2",
 | 
				
			||||||
        "bn.js": "^4.11.8",
 | 
					        "bn.js": "^4.11.8",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,12 @@
 | 
				
			|||||||
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
 | 
					import { schemas, SchemaValidator } from '@0xproject/json-schemas';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    assert,
 | 
				
			||||||
 | 
					    generatePseudoRandomSalt,
 | 
				
			||||||
 | 
					    getOrderHashHex,
 | 
				
			||||||
 | 
					    isValidOrderHash,
 | 
				
			||||||
 | 
					    isValidSignature,
 | 
				
			||||||
 | 
					    signOrderHashAsync,
 | 
				
			||||||
 | 
					} from '@0xproject/order-utils';
 | 
				
			||||||
import { ECSignature, Order, Provider, SignedOrder, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
 | 
					import { ECSignature, Order, Provider, SignedOrder, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
 | 
				
			||||||
import { AbiDecoder, BigNumber, intervalUtils } from '@0xproject/utils';
 | 
					import { AbiDecoder, BigNumber, intervalUtils } from '@0xproject/utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
@@ -16,10 +24,8 @@ import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
 | 
				
			|||||||
import { zeroExPrivateNetworkConfigSchema } from './schemas/zero_ex_private_network_config_schema';
 | 
					import { zeroExPrivateNetworkConfigSchema } from './schemas/zero_ex_private_network_config_schema';
 | 
				
			||||||
import { zeroExPublicNetworkConfigSchema } from './schemas/zero_ex_public_network_config_schema';
 | 
					import { zeroExPublicNetworkConfigSchema } from './schemas/zero_ex_public_network_config_schema';
 | 
				
			||||||
import { OrderStateWatcherConfig, ZeroExConfig, ZeroExError } from './types';
 | 
					import { OrderStateWatcherConfig, ZeroExConfig, ZeroExError } from './types';
 | 
				
			||||||
import { assert } from './utils/assert';
 | 
					 | 
				
			||||||
import { constants } from './utils/constants';
 | 
					import { constants } from './utils/constants';
 | 
				
			||||||
import { decorators } from './utils/decorators';
 | 
					import { decorators } from './utils/decorators';
 | 
				
			||||||
import { signatureUtils } from './utils/signature_utils';
 | 
					 | 
				
			||||||
import { utils } from './utils/utils';
 | 
					import { utils } from './utils/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -33,6 +39,36 @@ export class ZeroEx {
 | 
				
			|||||||
     * this constant for your convenience.
 | 
					     * this constant for your convenience.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static NULL_ADDRESS = constants.NULL_ADDRESS;
 | 
					    public static NULL_ADDRESS = constants.NULL_ADDRESS;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generates a pseudo-random 256-bit salt.
 | 
				
			||||||
 | 
					     * The salt can be included in a 0x order, ensuring that the order generates a unique orderHash
 | 
				
			||||||
 | 
					     * and will not collide with other outstanding orders that are identical in all other parameters.
 | 
				
			||||||
 | 
					     * @return  A pseudo-random 256-bit number that can be used as a salt.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static generatePseudoRandomSalt = generatePseudoRandomSalt;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Verifies that the elliptic curve signature `signature` was generated
 | 
				
			||||||
 | 
					     * by signing `data` with the private key corresponding to the `signerAddress` address.
 | 
				
			||||||
 | 
					     * @param   data          The hex encoded data signed by the supplied signature.
 | 
				
			||||||
 | 
					     * @param   signature     An object containing the elliptic curve signature parameters.
 | 
				
			||||||
 | 
					     * @param   signerAddress The hex encoded address that signed the data, producing the supplied signature.
 | 
				
			||||||
 | 
					     * @return  Whether the signature is valid for the supplied signerAddress and data.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static isValidSignature = isValidSignature;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Computes the orderHash for a supplied order.
 | 
				
			||||||
 | 
					     * @param   order   An object that conforms to the Order or SignedOrder interface definitions.
 | 
				
			||||||
 | 
					     * @return  The resulting orderHash from hashing the supplied order.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static getOrderHashHex = getOrderHashHex;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Checks if the supplied hex encoded order hash is valid.
 | 
				
			||||||
 | 
					     * Note: Valid means it has the expected format, not that an order with the orderHash exists.
 | 
				
			||||||
 | 
					     * Use this method when processing orderHashes submitted as user input.
 | 
				
			||||||
 | 
					     * @param   orderHash    Hex encoded orderHash.
 | 
				
			||||||
 | 
					     * @return  Whether the supplied orderHash has the expected format.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static isValidOrderHash = isValidOrderHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * An instance of the ExchangeWrapper class containing methods for interacting with the 0x Exchange smart contract.
 | 
					     * An instance of the ExchangeWrapper class containing methods for interacting with the 0x Exchange smart contract.
 | 
				
			||||||
@@ -58,52 +94,6 @@ export class ZeroEx {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public proxy: TokenTransferProxyWrapper;
 | 
					    public proxy: TokenTransferProxyWrapper;
 | 
				
			||||||
    private _web3Wrapper: Web3Wrapper;
 | 
					    private _web3Wrapper: Web3Wrapper;
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Verifies that the elliptic curve signature `signature` was generated
 | 
					 | 
				
			||||||
     * by signing `data` with the private key corresponding to the `signerAddress` address.
 | 
					 | 
				
			||||||
     * @param   data          The hex encoded data signed by the supplied signature.
 | 
					 | 
				
			||||||
     * @param   signature     An object containing the elliptic curve signature parameters.
 | 
					 | 
				
			||||||
     * @param   signerAddress The hex encoded address that signed the data, producing the supplied signature.
 | 
					 | 
				
			||||||
     * @return  Whether the signature is valid for the supplied signerAddress and data.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
 | 
					 | 
				
			||||||
        assert.isHexString('data', data);
 | 
					 | 
				
			||||||
        assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
 | 
					 | 
				
			||||||
        assert.isETHAddressHex('signerAddress', signerAddress);
 | 
					 | 
				
			||||||
        const normalizedSignerAddress = signerAddress.toLowerCase();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const isValidSignature = signatureUtils.isValidSignature(data, signature, normalizedSignerAddress);
 | 
					 | 
				
			||||||
        return isValidSignature;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Generates a pseudo-random 256-bit salt.
 | 
					 | 
				
			||||||
     * The salt can be included in a 0x order, ensuring that the order generates a unique orderHash
 | 
					 | 
				
			||||||
     * and will not collide with other outstanding orders that are identical in all other parameters.
 | 
					 | 
				
			||||||
     * @return  A pseudo-random 256-bit number that can be used as a salt.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static generatePseudoRandomSalt(): BigNumber {
 | 
					 | 
				
			||||||
        // BigNumber.random returns a pseudo-random number between 0 & 1 with a passed in number of decimal places.
 | 
					 | 
				
			||||||
        // Source: https://mikemcl.github.io/bignumber.js/#random
 | 
					 | 
				
			||||||
        const randomNumber = BigNumber.random(constants.MAX_DIGITS_IN_UNSIGNED_256_INT);
 | 
					 | 
				
			||||||
        const factor = new BigNumber(10).pow(constants.MAX_DIGITS_IN_UNSIGNED_256_INT - 1);
 | 
					 | 
				
			||||||
        const salt = randomNumber.times(factor).round();
 | 
					 | 
				
			||||||
        return salt;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Checks if the supplied hex encoded order hash is valid.
 | 
					 | 
				
			||||||
     * Note: Valid means it has the expected format, not that an order with the orderHash exists.
 | 
					 | 
				
			||||||
     * Use this method when processing orderHashes submitted as user input.
 | 
					 | 
				
			||||||
     * @param   orderHash    Hex encoded orderHash.
 | 
					 | 
				
			||||||
     * @return  Whether the supplied orderHash has the expected format.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static isValidOrderHash(orderHash: string): boolean {
 | 
					 | 
				
			||||||
        // Since this method can be called to check if any arbitrary string conforms to an orderHash's
 | 
					 | 
				
			||||||
        // format, we only assert that we were indeed passed a string.
 | 
					 | 
				
			||||||
        assert.isString('orderHash', orderHash);
 | 
					 | 
				
			||||||
        const schemaValidator = new SchemaValidator();
 | 
					 | 
				
			||||||
        const isValidOrderHash = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid;
 | 
					 | 
				
			||||||
        return isValidOrderHash;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * A unit amount is defined as the amount of a token above the specified decimal places (integer part).
 | 
					     * A unit amount is defined as the amount of a token above the specified decimal places (integer part).
 | 
				
			||||||
     * E.g: If a currency has 18 decimal places, 1e18 or one quintillion of the currency is equivalent
 | 
					     * E.g: If a currency has 18 decimal places, 1e18 or one quintillion of the currency is equivalent
 | 
				
			||||||
@@ -132,17 +122,6 @@ export class ZeroEx {
 | 
				
			|||||||
        const baseUnitAmount = Web3Wrapper.toBaseUnitAmount(amount, decimals);
 | 
					        const baseUnitAmount = Web3Wrapper.toBaseUnitAmount(amount, decimals);
 | 
				
			||||||
        return baseUnitAmount;
 | 
					        return baseUnitAmount;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Computes the orderHash for a supplied order.
 | 
					 | 
				
			||||||
     * @param   order   An object that conforms to the Order or SignedOrder interface definitions.
 | 
					 | 
				
			||||||
     * @return  The resulting orderHash from hashing the supplied order.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    @decorators.syncZeroExErrorHandler
 | 
					 | 
				
			||||||
    public static getOrderHashHex(order: Order | SignedOrder): string {
 | 
					 | 
				
			||||||
        assert.doesConformToSchema('order', order, schemas.orderSchema);
 | 
					 | 
				
			||||||
        const orderHashHex = utils.getOrderHashHex(order);
 | 
					 | 
				
			||||||
        return orderHashHex;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Instantiates a new ZeroEx instance that provides the public interface to the 0x.js library.
 | 
					     * Instantiates a new ZeroEx instance that provides the public interface to the 0x.js library.
 | 
				
			||||||
     * @param   provider    The Provider instance you would like the 0x.js library to use for interacting with
 | 
					     * @param   provider    The Provider instance you would like the 0x.js library to use for interacting with
 | 
				
			||||||
@@ -204,6 +183,12 @@ export class ZeroEx {
 | 
				
			|||||||
        (this.etherToken as any)._invalidateContractInstance();
 | 
					        (this.etherToken as any)._invalidateContractInstance();
 | 
				
			||||||
        (this.etherToken as any)._setNetworkId(networkId);
 | 
					        (this.etherToken as any)._setNetworkId(networkId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the provider instance currently used by 0x.js
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public getProvider(): Provider {
 | 
				
			||||||
 | 
					        return this._web3Wrapper.getProvider();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get user Ethereum addresses available through the supplied web3 provider available for sending transactions.
 | 
					     * Get user Ethereum addresses available through the supplied web3 provider available for sending transactions.
 | 
				
			||||||
     * @return  An array of available user Ethereum addresses.
 | 
					     * @return  An array of available user Ethereum addresses.
 | 
				
			||||||
@@ -229,41 +214,12 @@ export class ZeroEx {
 | 
				
			|||||||
        signerAddress: string,
 | 
					        signerAddress: string,
 | 
				
			||||||
        shouldAddPersonalMessagePrefix: boolean,
 | 
					        shouldAddPersonalMessagePrefix: boolean,
 | 
				
			||||||
    ): Promise<ECSignature> {
 | 
					    ): Promise<ECSignature> {
 | 
				
			||||||
        assert.isHexString('orderHash', orderHash);
 | 
					        return signOrderHashAsync(
 | 
				
			||||||
        await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
 | 
					            this._web3Wrapper.getProvider(),
 | 
				
			||||||
        const normalizedSignerAddress = signerAddress.toLowerCase();
 | 
					            orderHash,
 | 
				
			||||||
 | 
					            signerAddress,
 | 
				
			||||||
        let msgHashHex = orderHash;
 | 
					            shouldAddPersonalMessagePrefix,
 | 
				
			||||||
        if (shouldAddPersonalMessagePrefix) {
 | 
					        );
 | 
				
			||||||
            const orderHashBuff = ethUtil.toBuffer(orderHash);
 | 
					 | 
				
			||||||
            const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
 | 
					 | 
				
			||||||
            msgHashHex = ethUtil.bufferToHex(msgHashBuff);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const signature = await this._web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHashHex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // HACK: There is no consensus on whether the signatureHex string should be formatted as
 | 
					 | 
				
			||||||
        // v + r + s OR r + s + v, and different clients (even different versions of the same client)
 | 
					 | 
				
			||||||
        // return the signature params in different orders. In order to support all client implementations,
 | 
					 | 
				
			||||||
        // we parse the signature in both ways, and evaluate if either one is a valid signature.
 | 
					 | 
				
			||||||
        const validVParamValues = [27, 28];
 | 
					 | 
				
			||||||
        const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature);
 | 
					 | 
				
			||||||
        if (_.includes(validVParamValues, ecSignatureVRS.v)) {
 | 
					 | 
				
			||||||
            const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress);
 | 
					 | 
				
			||||||
            if (isValidVRSSignature) {
 | 
					 | 
				
			||||||
                return ecSignatureVRS;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature);
 | 
					 | 
				
			||||||
        if (_.includes(validVParamValues, ecSignatureRSV.v)) {
 | 
					 | 
				
			||||||
            const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress);
 | 
					 | 
				
			||||||
            if (isValidRSVSignature) {
 | 
					 | 
				
			||||||
                return ecSignatureRSV;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        throw new Error(ZeroExError.InvalidSignature);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Waits for a transaction to be mined and returns the transaction receipt.
 | 
					     * Waits for a transaction to be mined and returns the transaction receipt.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { schemas } from '@0xproject/json-schemas';
 | 
					import { schemas } from '@0xproject/json-schemas';
 | 
				
			||||||
 | 
					import { assert } from '@0xproject/order-utils';
 | 
				
			||||||
import { LogWithDecodedArgs } from '@0xproject/types';
 | 
					import { LogWithDecodedArgs } from '@0xproject/types';
 | 
				
			||||||
import { AbiDecoder, BigNumber } from '@0xproject/utils';
 | 
					import { AbiDecoder, BigNumber } from '@0xproject/utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
@@ -6,7 +7,6 @@ import * as _ from 'lodash';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { artifacts } from '../artifacts';
 | 
					import { artifacts } from '../artifacts';
 | 
				
			||||||
import { BlockRange, EventCallback, IndexedFilterValues, TransactionOpts, ZeroExError } from '../types';
 | 
					import { BlockRange, EventCallback, IndexedFilterValues, TransactionOpts, ZeroExError } from '../types';
 | 
				
			||||||
import { assert } from '../utils/assert';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ContractWrapper } from './contract_wrapper';
 | 
					import { ContractWrapper } from './contract_wrapper';
 | 
				
			||||||
import { EtherTokenContract, EtherTokenContractEventArgs, EtherTokenEvents } from './generated/ether_token';
 | 
					import { EtherTokenContract, EtherTokenContractEventArgs, EtherTokenEvents } from './generated/ether_token';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { schemas } from '@0xproject/json-schemas';
 | 
					import { schemas } from '@0xproject/json-schemas';
 | 
				
			||||||
 | 
					import { assert, getOrderHashHex } from '@0xproject/order-utils';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    BlockParamLiteral,
 | 
					    BlockParamLiteral,
 | 
				
			||||||
    DecodedLogArgs,
 | 
					    DecodedLogArgs,
 | 
				
			||||||
@@ -30,7 +31,6 @@ import {
 | 
				
			|||||||
    OrderValues,
 | 
					    OrderValues,
 | 
				
			||||||
    ValidateOrderFillableOpts,
 | 
					    ValidateOrderFillableOpts,
 | 
				
			||||||
} from '../types';
 | 
					} from '../types';
 | 
				
			||||||
import { assert } from '../utils/assert';
 | 
					 | 
				
			||||||
import { decorators } from '../utils/decorators';
 | 
					import { decorators } from '../utils/decorators';
 | 
				
			||||||
import { ExchangeTransferSimulator } from '../utils/exchange_transfer_simulator';
 | 
					import { ExchangeTransferSimulator } from '../utils/exchange_transfer_simulator';
 | 
				
			||||||
import { OrderStateUtils } from '../utils/order_state_utils';
 | 
					import { OrderStateUtils } from '../utils/order_state_utils';
 | 
				
			||||||
@@ -570,7 +570,7 @@ export class ExchangeWrapper extends ContractWrapper {
 | 
				
			|||||||
            ? SHOULD_VALIDATE_BY_DEFAULT
 | 
					            ? SHOULD_VALIDATE_BY_DEFAULT
 | 
				
			||||||
            : orderTransactionOpts.shouldValidate;
 | 
					            : orderTransactionOpts.shouldValidate;
 | 
				
			||||||
        if (shouldValidate) {
 | 
					        if (shouldValidate) {
 | 
				
			||||||
            const orderHash = utils.getOrderHashHex(order);
 | 
					            const orderHash = getOrderHashHex(order);
 | 
				
			||||||
            const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
 | 
					            const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
 | 
				
			||||||
            OrderValidationUtils.validateCancelOrderThrowIfInvalid(
 | 
					            OrderValidationUtils.validateCancelOrderThrowIfInvalid(
 | 
				
			||||||
                order,
 | 
					                order,
 | 
				
			||||||
@@ -629,7 +629,7 @@ export class ExchangeWrapper extends ContractWrapper {
 | 
				
			|||||||
            : orderTransactionOpts.shouldValidate;
 | 
					            : orderTransactionOpts.shouldValidate;
 | 
				
			||||||
        if (shouldValidate) {
 | 
					        if (shouldValidate) {
 | 
				
			||||||
            for (const orderCancellationRequest of orderCancellationRequests) {
 | 
					            for (const orderCancellationRequest of orderCancellationRequests) {
 | 
				
			||||||
                const orderHash = utils.getOrderHashHex(orderCancellationRequest.order);
 | 
					                const orderHash = getOrderHashHex(orderCancellationRequest.order);
 | 
				
			||||||
                const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
 | 
					                const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
 | 
				
			||||||
                OrderValidationUtils.validateCancelOrderThrowIfInvalid(
 | 
					                OrderValidationUtils.validateCancelOrderThrowIfInvalid(
 | 
				
			||||||
                    orderCancellationRequest.order,
 | 
					                    orderCancellationRequest.order,
 | 
				
			||||||
@@ -801,7 +801,7 @@ export class ExchangeWrapper extends ContractWrapper {
 | 
				
			|||||||
    ): Promise<void> {
 | 
					    ): Promise<void> {
 | 
				
			||||||
        assert.doesConformToSchema('order', order, schemas.orderSchema);
 | 
					        assert.doesConformToSchema('order', order, schemas.orderSchema);
 | 
				
			||||||
        assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
 | 
					        assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
 | 
				
			||||||
        const orderHash = utils.getOrderHashHex(order);
 | 
					        const orderHash = getOrderHashHex(order);
 | 
				
			||||||
        const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
 | 
					        const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
 | 
				
			||||||
        OrderValidationUtils.validateCancelOrderThrowIfInvalid(
 | 
					        OrderValidationUtils.validateCancelOrderThrowIfInvalid(
 | 
				
			||||||
            order,
 | 
					            order,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
 | 
					import { assert } from '@0xproject/order-utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { artifacts } from '../artifacts';
 | 
					import { artifacts } from '../artifacts';
 | 
				
			||||||
import { Token, TokenMetadata } from '../types';
 | 
					import { Token, TokenMetadata } from '../types';
 | 
				
			||||||
import { assert } from '../utils/assert';
 | 
					 | 
				
			||||||
import { constants } from '../utils/constants';
 | 
					import { constants } from '../utils/constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ContractWrapper } from './contract_wrapper';
 | 
					import { ContractWrapper } from './contract_wrapper';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
 | 
					import { assert } from '@0xproject/order-utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { artifacts } from '../artifacts';
 | 
					import { artifacts } from '../artifacts';
 | 
				
			||||||
import { assert } from '../utils/assert';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ContractWrapper } from './contract_wrapper';
 | 
					import { ContractWrapper } from './contract_wrapper';
 | 
				
			||||||
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
 | 
					import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { schemas } from '@0xproject/json-schemas';
 | 
					import { schemas } from '@0xproject/json-schemas';
 | 
				
			||||||
 | 
					import { assert } from '@0xproject/order-utils';
 | 
				
			||||||
import { LogWithDecodedArgs } from '@0xproject/types';
 | 
					import { LogWithDecodedArgs } from '@0xproject/types';
 | 
				
			||||||
import { AbiDecoder, BigNumber } from '@0xproject/utils';
 | 
					import { AbiDecoder, BigNumber } from '@0xproject/utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
@@ -6,7 +7,6 @@ import * as _ from 'lodash';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { artifacts } from '../artifacts';
 | 
					import { artifacts } from '../artifacts';
 | 
				
			||||||
import { BlockRange, EventCallback, IndexedFilterValues, MethodOpts, TransactionOpts, ZeroExError } from '../types';
 | 
					import { BlockRange, EventCallback, IndexedFilterValues, MethodOpts, TransactionOpts, ZeroExError } from '../types';
 | 
				
			||||||
import { assert } from '../utils/assert';
 | 
					 | 
				
			||||||
import { constants } from '../utils/constants';
 | 
					import { constants } from '../utils/constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ContractWrapper } from './contract_wrapper';
 | 
					import { ContractWrapper } from './contract_wrapper';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
 | 
					import { assert } from '@0xproject/order-utils';
 | 
				
			||||||
import { BlockParamLiteral, LogEntry } from '@0xproject/types';
 | 
					import { BlockParamLiteral, LogEntry } from '@0xproject/types';
 | 
				
			||||||
import { intervalUtils } from '@0xproject/utils';
 | 
					import { intervalUtils } from '@0xproject/utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { EventWatcherCallback, ZeroExError } from '../types';
 | 
					import { EventWatcherCallback, ZeroExError } from '../types';
 | 
				
			||||||
import { assert } from '../utils/assert';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
 | 
					const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { schemas } from '@0xproject/json-schemas';
 | 
					import { schemas } from '@0xproject/json-schemas';
 | 
				
			||||||
 | 
					import { assert } from '@0xproject/order-utils';
 | 
				
			||||||
import { BlockParamLiteral, LogWithDecodedArgs, SignedOrder } from '@0xproject/types';
 | 
					import { BlockParamLiteral, LogWithDecodedArgs, SignedOrder } from '@0xproject/types';
 | 
				
			||||||
import { AbiDecoder, intervalUtils } from '@0xproject/utils';
 | 
					import { AbiDecoder, intervalUtils } from '@0xproject/utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
@@ -33,7 +34,6 @@ import {
 | 
				
			|||||||
    OrderStateWatcherConfig,
 | 
					    OrderStateWatcherConfig,
 | 
				
			||||||
    ZeroExError,
 | 
					    ZeroExError,
 | 
				
			||||||
} from '../types';
 | 
					} from '../types';
 | 
				
			||||||
import { assert } from '../utils/assert';
 | 
					 | 
				
			||||||
import { OrderStateUtils } from '../utils/order_state_utils';
 | 
					import { OrderStateUtils } from '../utils/order_state_utils';
 | 
				
			||||||
import { utils } from '../utils/utils';
 | 
					import { utils } from '../utils/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,6 @@ export enum ZeroExError {
 | 
				
			|||||||
    TokenContractDoesNotExist = 'TOKEN_CONTRACT_DOES_NOT_EXIST',
 | 
					    TokenContractDoesNotExist = 'TOKEN_CONTRACT_DOES_NOT_EXIST',
 | 
				
			||||||
    UnhandledError = 'UNHANDLED_ERROR',
 | 
					    UnhandledError = 'UNHANDLED_ERROR',
 | 
				
			||||||
    UserHasNoAssociatedAddress = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
 | 
					    UserHasNoAssociatedAddress = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
 | 
				
			||||||
    InvalidSignature = 'INVALID_SIGNATURE',
 | 
					 | 
				
			||||||
    ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK',
 | 
					    ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK',
 | 
				
			||||||
    InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER',
 | 
					    InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER',
 | 
				
			||||||
    InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER',
 | 
					    InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,6 @@ import { BigNumber } from '@0xproject/utils';
 | 
				
			|||||||
export const constants = {
 | 
					export const constants = {
 | 
				
			||||||
    NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
 | 
					    NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
 | 
				
			||||||
    TESTRPC_NETWORK_ID: 50,
 | 
					    TESTRPC_NETWORK_ID: 50,
 | 
				
			||||||
    MAX_DIGITS_IN_UNSIGNED_256_INT: 78,
 | 
					 | 
				
			||||||
    INVALID_JUMP_PATTERN: 'invalid JUMP at',
 | 
					    INVALID_JUMP_PATTERN: 'invalid JUMP at',
 | 
				
			||||||
    OUT_OF_GAS_PATTERN: 'out of gas',
 | 
					    OUT_OF_GAS_PATTERN: 'out of gas',
 | 
				
			||||||
    INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
 | 
					    INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import { getOrderHashHex, OrderError } from '@0xproject/order-utils';
 | 
				
			||||||
import { Order, SignedOrder } from '@0xproject/types';
 | 
					import { Order, SignedOrder } from '@0xproject/types';
 | 
				
			||||||
import { BigNumber } from '@0xproject/utils';
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
@@ -113,7 +114,7 @@ export class OrderValidationUtils {
 | 
				
			|||||||
        zrxTokenAddress: string,
 | 
					        zrxTokenAddress: string,
 | 
				
			||||||
        expectedFillTakerTokenAmount?: BigNumber,
 | 
					        expectedFillTakerTokenAmount?: BigNumber,
 | 
				
			||||||
    ): Promise<void> {
 | 
					    ): Promise<void> {
 | 
				
			||||||
        const orderHash = utils.getOrderHashHex(signedOrder);
 | 
					        const orderHash = getOrderHashHex(signedOrder);
 | 
				
			||||||
        const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
 | 
					        const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
 | 
				
			||||||
        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
 | 
					        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
 | 
				
			||||||
            signedOrder.takerTokenAmount,
 | 
					            signedOrder.takerTokenAmount,
 | 
				
			||||||
@@ -142,9 +143,9 @@ export class OrderValidationUtils {
 | 
				
			|||||||
        if (fillTakerTokenAmount.eq(0)) {
 | 
					        if (fillTakerTokenAmount.eq(0)) {
 | 
				
			||||||
            throw new Error(ExchangeContractErrs.OrderFillAmountZero);
 | 
					            throw new Error(ExchangeContractErrs.OrderFillAmountZero);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const orderHash = utils.getOrderHashHex(signedOrder);
 | 
					        const orderHash = getOrderHashHex(signedOrder);
 | 
				
			||||||
        if (!ZeroEx.isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker)) {
 | 
					        if (!ZeroEx.isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker)) {
 | 
				
			||||||
            throw new Error(ZeroExError.InvalidSignature);
 | 
					            throw new Error(OrderError.InvalidSignature);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
 | 
					        const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
 | 
				
			||||||
        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
 | 
					        OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,45 +0,0 @@
 | 
				
			|||||||
import { ECSignature } from '@0xproject/types';
 | 
					 | 
				
			||||||
import * as ethUtil from 'ethereumjs-util';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const signatureUtils = {
 | 
					 | 
				
			||||||
    isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
 | 
					 | 
				
			||||||
        const dataBuff = ethUtil.toBuffer(data);
 | 
					 | 
				
			||||||
        const msgHashBuff = ethUtil.hashPersonalMessage(dataBuff);
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            const pubKey = ethUtil.ecrecover(
 | 
					 | 
				
			||||||
                msgHashBuff,
 | 
					 | 
				
			||||||
                signature.v,
 | 
					 | 
				
			||||||
                ethUtil.toBuffer(signature.r),
 | 
					 | 
				
			||||||
                ethUtil.toBuffer(signature.s),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
 | 
					 | 
				
			||||||
            return retrievedAddress === signerAddress;
 | 
					 | 
				
			||||||
        } catch (err) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    parseSignatureHexAsVRS(signatureHex: string): ECSignature {
 | 
					 | 
				
			||||||
        const signatureBuffer = ethUtil.toBuffer(signatureHex);
 | 
					 | 
				
			||||||
        let v = signatureBuffer[0];
 | 
					 | 
				
			||||||
        if (v < 27) {
 | 
					 | 
				
			||||||
            v += 27;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        const r = signatureBuffer.slice(1, 33);
 | 
					 | 
				
			||||||
        const s = signatureBuffer.slice(33, 65);
 | 
					 | 
				
			||||||
        const ecSignature: ECSignature = {
 | 
					 | 
				
			||||||
            v,
 | 
					 | 
				
			||||||
            r: ethUtil.bufferToHex(r),
 | 
					 | 
				
			||||||
            s: ethUtil.bufferToHex(s),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        return ecSignature;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    parseSignatureHexAsRSV(signatureHex: string): ECSignature {
 | 
					 | 
				
			||||||
        const { v, r, s } = ethUtil.fromRpcSig(signatureHex);
 | 
					 | 
				
			||||||
        const ecSignature: ECSignature = {
 | 
					 | 
				
			||||||
            v,
 | 
					 | 
				
			||||||
            r: ethUtil.bufferToHex(r),
 | 
					 | 
				
			||||||
            s: ethUtil.bufferToHex(s),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        return ecSignature;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,59 +1,9 @@
 | 
				
			|||||||
import { Order, SignedOrder, SolidityTypes } from '@0xproject/types';
 | 
					 | 
				
			||||||
import { BigNumber } from '@0xproject/utils';
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
import BN = require('bn.js');
 | 
					 | 
				
			||||||
import * as ethABI from 'ethereumjs-abi';
 | 
					 | 
				
			||||||
import * as ethUtil from 'ethereumjs-util';
 | 
					 | 
				
			||||||
import * as _ from 'lodash';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const utils = {
 | 
					export const utils = {
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Converts BigNumber instance to BN
 | 
					 | 
				
			||||||
     * The only reason we convert to BN is to remain compatible with `ethABI. soliditySHA3` that
 | 
					 | 
				
			||||||
     * expects values of Solidity type `uint` to be passed as type `BN`.
 | 
					 | 
				
			||||||
     * We do not use BN anywhere else in the codebase.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    bigNumberToBN(value: BigNumber) {
 | 
					 | 
				
			||||||
        return new BN(value.toString(), 10);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    spawnSwitchErr(name: string, value: any): Error {
 | 
					    spawnSwitchErr(name: string, value: any): Error {
 | 
				
			||||||
        return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
 | 
					        return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getOrderHashHex(order: Order | SignedOrder): string {
 | 
					 | 
				
			||||||
        const orderParts = [
 | 
					 | 
				
			||||||
            { value: order.exchangeContractAddress, type: SolidityTypes.Address },
 | 
					 | 
				
			||||||
            { value: order.maker, type: SolidityTypes.Address },
 | 
					 | 
				
			||||||
            { value: order.taker, type: SolidityTypes.Address },
 | 
					 | 
				
			||||||
            { value: order.makerTokenAddress, type: SolidityTypes.Address },
 | 
					 | 
				
			||||||
            { value: order.takerTokenAddress, type: SolidityTypes.Address },
 | 
					 | 
				
			||||||
            { value: order.feeRecipient, type: SolidityTypes.Address },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                value: utils.bigNumberToBN(order.makerTokenAmount),
 | 
					 | 
				
			||||||
                type: SolidityTypes.Uint256,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                value: utils.bigNumberToBN(order.takerTokenAmount),
 | 
					 | 
				
			||||||
                type: SolidityTypes.Uint256,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                value: utils.bigNumberToBN(order.makerFee),
 | 
					 | 
				
			||||||
                type: SolidityTypes.Uint256,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                value: utils.bigNumberToBN(order.takerFee),
 | 
					 | 
				
			||||||
                type: SolidityTypes.Uint256,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                value: utils.bigNumberToBN(order.expirationUnixTimestampSec),
 | 
					 | 
				
			||||||
                type: SolidityTypes.Uint256,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            { value: utils.bigNumberToBN(order.salt), type: SolidityTypes.Uint256 },
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
        const types = _.map(orderParts, o => o.type);
 | 
					 | 
				
			||||||
        const values = _.map(orderParts, o => o.value);
 | 
					 | 
				
			||||||
        const hashBuff = ethABI.soliditySHA3(types, values);
 | 
					 | 
				
			||||||
        const hashHex = ethUtil.bufferToHex(hashBuff);
 | 
					 | 
				
			||||||
        return hashHex;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    getCurrentUnixTimestampSec(): BigNumber {
 | 
					    getCurrentUnixTimestampSec(): BigNumber {
 | 
				
			||||||
        return new BigNumber(Date.now() / 1000).round();
 | 
					        return new BigNumber(Date.now() / 1000).round();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,6 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
 | 
				
			|||||||
chaiSetup.configure();
 | 
					chaiSetup.configure();
 | 
				
			||||||
const expect = chai.expect;
 | 
					const expect = chai.expect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('ZeroEx library', () => {
 | 
					describe('ZeroEx library', () => {
 | 
				
			||||||
    let zeroEx: ZeroEx;
 | 
					    let zeroEx: ZeroEx;
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
@@ -63,14 +61,12 @@ describe('ZeroEx library', () => {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
        const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
 | 
					        const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
 | 
				
			||||||
        it("should return false if the data doesn't pertain to the signature & address", async () => {
 | 
					        it("should return false if the data doesn't pertain to the signature & address", async () => {
 | 
				
			||||||
            expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
 | 
					 | 
				
			||||||
            return expect(
 | 
					            return expect(
 | 
				
			||||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
 | 
					                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
 | 
				
			||||||
            ).to.become(false);
 | 
					            ).to.become(false);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        it("should return false if the address doesn't pertain to the signature & data", async () => {
 | 
					        it("should return false if the address doesn't pertain to the signature & data", async () => {
 | 
				
			||||||
            const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
 | 
					            const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
 | 
				
			||||||
            expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
 | 
					 | 
				
			||||||
            return expect(
 | 
					            return expect(
 | 
				
			||||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
 | 
					                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
 | 
				
			||||||
                    dataHex,
 | 
					                    dataHex,
 | 
				
			||||||
@@ -81,45 +77,16 @@ describe('ZeroEx library', () => {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
        it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
 | 
					        it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
 | 
				
			||||||
            const wrongSignature = _.assign({}, signature, { v: 28 });
 | 
					            const wrongSignature = _.assign({}, signature, { v: 28 });
 | 
				
			||||||
            expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
 | 
					 | 
				
			||||||
            return expect(
 | 
					            return expect(
 | 
				
			||||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
 | 
					                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
 | 
				
			||||||
            ).to.become(false);
 | 
					            ).to.become(false);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        it('should return true if the signature does pertain to the dataHex & address', async () => {
 | 
					        it('should return true if the signature does pertain to the dataHex & address', async () => {
 | 
				
			||||||
            const isValidSignatureLocal = ZeroEx.isValidSignature(dataHex, signature, address);
 | 
					 | 
				
			||||||
            expect(isValidSignatureLocal).to.be.true();
 | 
					 | 
				
			||||||
            return expect(
 | 
					            return expect(
 | 
				
			||||||
                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
 | 
					                (zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
 | 
				
			||||||
            ).to.become(true);
 | 
					            ).to.become(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    describe('#generateSalt', () => {
 | 
					 | 
				
			||||||
        it('generates different salts', () => {
 | 
					 | 
				
			||||||
            const equal = ZeroEx.generatePseudoRandomSalt().eq(ZeroEx.generatePseudoRandomSalt());
 | 
					 | 
				
			||||||
            expect(equal).to.be.false();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('generates salt in range [0..2^256)', () => {
 | 
					 | 
				
			||||||
            const salt = ZeroEx.generatePseudoRandomSalt();
 | 
					 | 
				
			||||||
            expect(salt.greaterThanOrEqualTo(0)).to.be.true();
 | 
					 | 
				
			||||||
            const twoPow256 = new BigNumber(2).pow(256);
 | 
					 | 
				
			||||||
            expect(salt.lessThan(twoPow256)).to.be.true();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    describe('#isValidOrderHash', () => {
 | 
					 | 
				
			||||||
        it('returns false if the value is not a hex string', () => {
 | 
					 | 
				
			||||||
            const isValid = ZeroEx.isValidOrderHash('not a hex');
 | 
					 | 
				
			||||||
            expect(isValid).to.be.false();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('returns false if the length is wrong', () => {
 | 
					 | 
				
			||||||
            const isValid = ZeroEx.isValidOrderHash('0xdeadbeef');
 | 
					 | 
				
			||||||
            expect(isValid).to.be.false();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('returns true if order hash is correct', () => {
 | 
					 | 
				
			||||||
            const isValid = ZeroEx.isValidOrderHash('0x' + Array(65).join('0'));
 | 
					 | 
				
			||||||
            expect(isValid).to.be.true();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    describe('#toUnitAmount', () => {
 | 
					    describe('#toUnitAmount', () => {
 | 
				
			||||||
        it('should throw if invalid baseUnit amount supplied as argument', () => {
 | 
					        it('should throw if invalid baseUnit amount supplied as argument', () => {
 | 
				
			||||||
            const invalidBaseUnitAmount = new BigNumber(1000000000.4);
 | 
					            const invalidBaseUnitAmount = new BigNumber(1000000000.4);
 | 
				
			||||||
@@ -152,106 +119,6 @@ describe('ZeroEx library', () => {
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    describe('#getOrderHashHex', () => {
 | 
					 | 
				
			||||||
        const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
 | 
					 | 
				
			||||||
        const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b';
 | 
					 | 
				
			||||||
        const order: Order = {
 | 
					 | 
				
			||||||
            maker: constants.NULL_ADDRESS,
 | 
					 | 
				
			||||||
            taker: constants.NULL_ADDRESS,
 | 
					 | 
				
			||||||
            feeRecipient: constants.NULL_ADDRESS,
 | 
					 | 
				
			||||||
            makerTokenAddress: constants.NULL_ADDRESS,
 | 
					 | 
				
			||||||
            takerTokenAddress: constants.NULL_ADDRESS,
 | 
					 | 
				
			||||||
            exchangeContractAddress: fakeExchangeContractAddress,
 | 
					 | 
				
			||||||
            salt: new BigNumber(0),
 | 
					 | 
				
			||||||
            makerFee: new BigNumber(0),
 | 
					 | 
				
			||||||
            takerFee: new BigNumber(0),
 | 
					 | 
				
			||||||
            makerTokenAmount: new BigNumber(0),
 | 
					 | 
				
			||||||
            takerTokenAmount: new BigNumber(0),
 | 
					 | 
				
			||||||
            expirationUnixTimestampSec: new BigNumber(0),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        it('calculates the order hash', async () => {
 | 
					 | 
				
			||||||
            const orderHash = ZeroEx.getOrderHashHex(order);
 | 
					 | 
				
			||||||
            expect(orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('throws a readable error message if taker format is invalid', async () => {
 | 
					 | 
				
			||||||
            const orderWithInvalidtakerFormat = {
 | 
					 | 
				
			||||||
                ...order,
 | 
					 | 
				
			||||||
                taker: (null as any) as string,
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            const expectedErrorMessage =
 | 
					 | 
				
			||||||
                'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
 | 
					 | 
				
			||||||
            expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    describe('#signOrderHashAsync', () => {
 | 
					 | 
				
			||||||
        let stubs: Sinon.SinonStub[] = [];
 | 
					 | 
				
			||||||
        let makerAddress: string;
 | 
					 | 
				
			||||||
        before(async () => {
 | 
					 | 
				
			||||||
            const availableAddreses = await zeroEx.getAvailableAddressesAsync();
 | 
					 | 
				
			||||||
            makerAddress = availableAddreses[0];
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        afterEach(() => {
 | 
					 | 
				
			||||||
            // clean up any stubs after the test has completed
 | 
					 | 
				
			||||||
            _.each(stubs, s => s.restore());
 | 
					 | 
				
			||||||
            stubs = [];
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('Should return the correct ECSignature', async () => {
 | 
					 | 
				
			||||||
            const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
 | 
					 | 
				
			||||||
            const expectedECSignature = {
 | 
					 | 
				
			||||||
                v: 27,
 | 
					 | 
				
			||||||
                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
 | 
					 | 
				
			||||||
                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            const ecSignature = await zeroEx.signOrderHashAsync(
 | 
					 | 
				
			||||||
                orderHash,
 | 
					 | 
				
			||||||
                makerAddress,
 | 
					 | 
				
			||||||
                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
 | 
					 | 
				
			||||||
            const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
 | 
					 | 
				
			||||||
            const signature =
 | 
					 | 
				
			||||||
                '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
 | 
					 | 
				
			||||||
            const expectedECSignature = {
 | 
					 | 
				
			||||||
                v: 27,
 | 
					 | 
				
			||||||
                r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
 | 
					 | 
				
			||||||
                s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            stubs = [
 | 
					 | 
				
			||||||
                Sinon.stub((zeroEx as any)._web3Wrapper, 'signMessageAsync').returns(Promise.resolve(signature)),
 | 
					 | 
				
			||||||
                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const ecSignature = await zeroEx.signOrderHashAsync(
 | 
					 | 
				
			||||||
                orderHash,
 | 
					 | 
				
			||||||
                makerAddress,
 | 
					 | 
				
			||||||
                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
 | 
					 | 
				
			||||||
            const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
 | 
					 | 
				
			||||||
            const signature =
 | 
					 | 
				
			||||||
                '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
 | 
					 | 
				
			||||||
            const expectedECSignature = {
 | 
					 | 
				
			||||||
                v: 27,
 | 
					 | 
				
			||||||
                r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
 | 
					 | 
				
			||||||
                s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            stubs = [
 | 
					 | 
				
			||||||
                Sinon.stub((zeroEx as any)._web3Wrapper, 'signMessageAsync').returns(Promise.resolve(signature)),
 | 
					 | 
				
			||||||
                Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const ecSignature = await zeroEx.signOrderHashAsync(
 | 
					 | 
				
			||||||
                orderHash,
 | 
					 | 
				
			||||||
                makerAddress,
 | 
					 | 
				
			||||||
                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    describe('#awaitTransactionMinedAsync', () => {
 | 
					    describe('#awaitTransactionMinedAsync', () => {
 | 
				
			||||||
        beforeEach(async () => {
 | 
					        beforeEach(async () => {
 | 
				
			||||||
            await blockchainLifecycle.startAsync();
 | 
					            await blockchainLifecycle.startAsync();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,43 +0,0 @@
 | 
				
			|||||||
import { web3Factory } from '@0xproject/dev-utils';
 | 
					 | 
				
			||||||
import * as chai from 'chai';
 | 
					 | 
				
			||||||
import 'mocha';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { ZeroEx } from '../src';
 | 
					 | 
				
			||||||
import { assert } from '../src/utils/assert';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { constants } from './utils/constants';
 | 
					 | 
				
			||||||
import { provider } from './utils/web3_wrapper';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const expect = chai.expect;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('Assertion library', () => {
 | 
					 | 
				
			||||||
    const config = {
 | 
					 | 
				
			||||||
        networkId: constants.TESTRPC_NETWORK_ID,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const zeroEx = new ZeroEx(provider, config);
 | 
					 | 
				
			||||||
    describe('#isSenderAddressHexAsync', () => {
 | 
					 | 
				
			||||||
        it('throws when address is invalid', async () => {
 | 
					 | 
				
			||||||
            const address = '0xdeadbeef';
 | 
					 | 
				
			||||||
            const varName = 'address';
 | 
					 | 
				
			||||||
            return expect(
 | 
					 | 
				
			||||||
                assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
 | 
					 | 
				
			||||||
            ).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('throws when address is unavailable', async () => {
 | 
					 | 
				
			||||||
            const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
 | 
					 | 
				
			||||||
            const varName = 'address';
 | 
					 | 
				
			||||||
            return expect(
 | 
					 | 
				
			||||||
                assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
 | 
					 | 
				
			||||||
            ).to.be.rejectedWith(
 | 
					 | 
				
			||||||
                `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it("doesn't throw if address is available", async () => {
 | 
					 | 
				
			||||||
            const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
 | 
					 | 
				
			||||||
            const varName = 'address';
 | 
					 | 
				
			||||||
            return expect(
 | 
					 | 
				
			||||||
                assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
 | 
					 | 
				
			||||||
            ).to.become(undefined);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
 | 
					import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
 | 
				
			||||||
 | 
					import { OrderError } from '@0xproject/order-utils';
 | 
				
			||||||
import { BlockParamLiteral } from '@0xproject/types';
 | 
					import { BlockParamLiteral } from '@0xproject/types';
 | 
				
			||||||
import { BigNumber } from '@0xproject/utils';
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
import * as chai from 'chai';
 | 
					import * as chai from 'chai';
 | 
				
			||||||
@@ -169,7 +170,7 @@ describe('OrderValidation', () => {
 | 
				
			|||||||
            signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
 | 
					            signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
 | 
				
			||||||
            return expect(
 | 
					            return expect(
 | 
				
			||||||
                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
 | 
					                zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
 | 
				
			||||||
            ).to.be.rejectedWith(ZeroExError.InvalidSignature);
 | 
					            ).to.be.rejectedWith(OrderError.InvalidSignature);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        it('should throw when the order is fully filled or cancelled', async () => {
 | 
					        it('should throw when the order is fully filled or cancelled', async () => {
 | 
				
			||||||
            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
					            const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
 | 
					import { orderFactory } from '@0xproject/order-utils';
 | 
				
			||||||
import { BigNumber } from '@0xproject/utils';
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SignedOrder, Token, ZeroEx } from '../../src';
 | 
					import { SignedOrder, Token, ZeroEx } from '../../src';
 | 
				
			||||||
import { artifacts } from '../../src/artifacts';
 | 
					import { artifacts } from '../../src/artifacts';
 | 
				
			||||||
import { DummyTokenContract } from '../../src/contract_wrappers/generated/dummy_token';
 | 
					import { DummyTokenContract } from '../../src/contract_wrappers/generated/dummy_token';
 | 
				
			||||||
import { orderFactory } from '../utils/order_factory';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { constants } from './constants';
 | 
					import { constants } from './constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -164,7 +164,7 @@ export class FillScenarios {
 | 
				
			|||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const signedOrder = await orderFactory.createSignedOrderAsync(
 | 
					        const signedOrder = await orderFactory.createSignedOrderAsync(
 | 
				
			||||||
            this._zeroEx,
 | 
					            this._zeroEx.getProvider(),
 | 
				
			||||||
            makerAddress,
 | 
					            makerAddress,
 | 
				
			||||||
            takerAddress,
 | 
					            takerAddress,
 | 
				
			||||||
            makerFee,
 | 
					            makerFee,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,6 @@
 | 
				
			|||||||
import { devConstants, web3Factory } from '@0xproject/dev-utils';
 | 
					import { devConstants, web3Factory } from '@0xproject/dev-utils';
 | 
				
			||||||
import { Provider } from '@0xproject/types';
 | 
					import { Provider } from '@0xproject/types';
 | 
				
			||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
import * as Web3 from 'web3';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { constants } from './constants';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const web3 = web3Factory.create({ shouldUseInProcessGanache: true });
 | 
					const web3 = web3Factory.create({ shouldUseInProcessGanache: true });
 | 
				
			||||||
const provider: Provider = web3.currentProvider;
 | 
					const provider: Provider = web3.currentProvider;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								packages/order-utils/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								packages/order-utils/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					.*
 | 
				
			||||||
 | 
					yarn-error.log
 | 
				
			||||||
 | 
					/scripts/
 | 
				
			||||||
 | 
					/src/
 | 
				
			||||||
 | 
					tsconfig.json
 | 
				
			||||||
 | 
					/lib/monorepo_scripts/
 | 
				
			||||||
							
								
								
									
										1
									
								
								packages/order-utils/CHANGELOG.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/order-utils/CHANGELOG.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					[]
 | 
				
			||||||
							
								
								
									
										77
									
								
								packages/order-utils/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								packages/order-utils/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					## @0xproject/order-utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					0x order-related utilities for those developing on top of 0x protocol.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Read the [Documentation](https://0xproject.com/docs/order-utils).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn add @0xproject/order-utils
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```json
 | 
				
			||||||
 | 
					"compilerOptions": {
 | 
				
			||||||
 | 
					    "typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Install dependencies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn config set workspaces-experimental true
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then install dependencies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn install
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If this is your **first** time building this package, you must first build **all** packages within the monorepo. This is because packages that depend on other packages located inside this monorepo are symlinked when run from **within** the monorepo. This allows you to make changes across multiple packages without first publishing dependent packages to NPM. To build all packages, run the following from the monorepo root directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn lerna:rebuild
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Or continuously rebuild on change:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn dev
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also build this specific package by running the following from within its directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn build
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					or continuously rebuild on change:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn build:watch
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Clean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn clean
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn lint
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
							
								
								
									
										0
									
								
								packages/order-utils/coverage/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								packages/order-utils/coverage/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										76
									
								
								packages/order-utils/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								packages/order-utils/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "name": "@0xproject/order-utils",
 | 
				
			||||||
 | 
					    "version": "0.0.1",
 | 
				
			||||||
 | 
					    "description": "0x order utils",
 | 
				
			||||||
 | 
					    "main": "lib/src/index.js",
 | 
				
			||||||
 | 
					    "types": "lib/src/index.d.ts",
 | 
				
			||||||
 | 
					    "scripts": {
 | 
				
			||||||
 | 
					        "build:watch": "tsc -w",
 | 
				
			||||||
 | 
					        "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
 | 
				
			||||||
 | 
					        "test": "run-s clean build run_mocha",
 | 
				
			||||||
 | 
					        "test:circleci": "yarn test:coverage",
 | 
				
			||||||
 | 
					        "run_mocha": "mocha lib/test/**/*_test.js --bail --exit",
 | 
				
			||||||
 | 
					        "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
 | 
				
			||||||
 | 
					        "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
 | 
				
			||||||
 | 
					        "clean": "shx rm -rf lib scripts",
 | 
				
			||||||
 | 
					        "lint": "tslint --project .",
 | 
				
			||||||
 | 
					        "manual:postpublish": "yarn build; node ./scripts/postpublish.js",
 | 
				
			||||||
 | 
					        "docs:stage": "yarn build && node ./scripts/stage_docs.js",
 | 
				
			||||||
 | 
					        "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
 | 
				
			||||||
 | 
					        "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "config": {
 | 
				
			||||||
 | 
					        "postpublish": {
 | 
				
			||||||
 | 
					            "docPublishConfigs": {
 | 
				
			||||||
 | 
					                "extraFileIncludes": [
 | 
				
			||||||
 | 
					                    "../types/src/index.ts"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "s3BucketPath": "s3://doc-jsons/order-utils/",
 | 
				
			||||||
 | 
					                "s3StagingBucketPath": "s3://staging-doc-jsons/order-utils/"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "license": "Apache-2.0",
 | 
				
			||||||
 | 
					    "repository": {
 | 
				
			||||||
 | 
					        "type": "git",
 | 
				
			||||||
 | 
					        "url": "https://github.com/0xProject/0x-monorepo.git"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "bugs": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/0xProject/0x-monorepo/issues"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md",
 | 
				
			||||||
 | 
					    "devDependencies": {
 | 
				
			||||||
 | 
					        "@0xproject/monorepo-scripts": "^0.1.18",
 | 
				
			||||||
 | 
					        "@0xproject/dev-utils": "^0.3.6",
 | 
				
			||||||
 | 
					        "@0xproject/tslint-config": "^0.4.16",
 | 
				
			||||||
 | 
					        "@types/lodash": "4.14.104",
 | 
				
			||||||
 | 
					        "chai": "^4.0.1",
 | 
				
			||||||
 | 
					        "chai-as-promised": "^7.1.0",
 | 
				
			||||||
 | 
					        "chai-bignumber": "^2.0.1",
 | 
				
			||||||
 | 
					        "dirty-chai": "^2.0.1",
 | 
				
			||||||
 | 
					        "sinon": "^4.0.0",
 | 
				
			||||||
 | 
					        "mocha": "^4.0.1",
 | 
				
			||||||
 | 
					        "copyfiles": "^1.2.0",
 | 
				
			||||||
 | 
					        "npm-run-all": "^4.1.2",
 | 
				
			||||||
 | 
					        "typedoc": "0xProject/typedoc",
 | 
				
			||||||
 | 
					        "shx": "^0.2.2",
 | 
				
			||||||
 | 
					        "tslint": "5.8.0",
 | 
				
			||||||
 | 
					        "typescript": "2.7.1"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "dependencies": {
 | 
				
			||||||
 | 
					        "@0xproject/assert": "^0.2.7",
 | 
				
			||||||
 | 
					        "@0xproject/types": "^0.6.1",
 | 
				
			||||||
 | 
					        "@0xproject/json-schemas": "^0.7.21",
 | 
				
			||||||
 | 
					        "@0xproject/typescript-typings": "^0.2.0",
 | 
				
			||||||
 | 
					        "@0xproject/web3-wrapper": "^0.6.1",
 | 
				
			||||||
 | 
					        "@0xproject/utils": "^0.5.2",
 | 
				
			||||||
 | 
					        "@types/node": "^8.0.53",
 | 
				
			||||||
 | 
					        "bn.js": "^4.11.8",
 | 
				
			||||||
 | 
					        "lodash": "^4.17.4",
 | 
				
			||||||
 | 
					        "ethereumjs-abi": "^0.6.4",
 | 
				
			||||||
 | 
					        "ethereumjs-util": "^5.1.1"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "publishConfig": {
 | 
				
			||||||
 | 
					        "access": "public"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -8,13 +8,13 @@ import { BigNumber } from '@0xproject/utils';
 | 
				
			|||||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { signatureUtils } from '../utils/signature_utils';
 | 
					import { isValidSignature } from './signature_utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const assert = {
 | 
					export const assert = {
 | 
				
			||||||
    ...sharedAssert,
 | 
					    ...sharedAssert,
 | 
				
			||||||
    isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string) {
 | 
					    isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string) {
 | 
				
			||||||
        const isValidSignature = signatureUtils.isValidSignature(orderHash, ecSignature, signerAddress);
 | 
					        const isValid = isValidSignature(orderHash, ecSignature, signerAddress);
 | 
				
			||||||
        this.assert(isValidSignature, `Expected order with hash '${orderHash}' to have a valid signature`);
 | 
					        this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    async isSenderAddressAsync(
 | 
					    async isSenderAddressAsync(
 | 
				
			||||||
        variableName: string,
 | 
					        variableName: string,
 | 
				
			||||||
							
								
								
									
										3
									
								
								packages/order-utils/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/order-utils/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					export const constants = {
 | 
				
			||||||
 | 
					    NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										6
									
								
								packages/order-utils/src/globals.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								packages/order-utils/src/globals.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					declare module '*.json' {
 | 
				
			||||||
 | 
					    const json: any;
 | 
				
			||||||
 | 
					    /* tslint:disable */
 | 
				
			||||||
 | 
					    export default json;
 | 
				
			||||||
 | 
					    /* tslint:enable */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								packages/order-utils/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/order-utils/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					export { getOrderHashHex, isValidOrderHash } from './order_hash';
 | 
				
			||||||
 | 
					export { isValidSignature, signOrderHashAsync } from './signature_utils';
 | 
				
			||||||
 | 
					export { orderFactory } from './order_factory';
 | 
				
			||||||
 | 
					export { generatePseudoRandomSalt } from './salt';
 | 
				
			||||||
 | 
					export { assert } from './assert';
 | 
				
			||||||
 | 
					export { constants } from './constants';
 | 
				
			||||||
 | 
					export { OrderError } from './types';
 | 
				
			||||||
							
								
								
									
										8
									
								
								packages/order-utils/src/monorepo_scripts/postpublish.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/order-utils/src/monorepo_scripts/postpublish.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					import { postpublishUtils } from '@0xproject/monorepo-scripts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as packageJSON from '../package.json';
 | 
				
			||||||
 | 
					import * as tsConfigJSON from '../tsconfig.json';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const cwd = `${__dirname}/..`;
 | 
				
			||||||
 | 
					// tslint:disable-next-line:no-floating-promises
 | 
				
			||||||
 | 
					postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
 | 
				
			||||||
							
								
								
									
										8
									
								
								packages/order-utils/src/monorepo_scripts/stage_docs.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/order-utils/src/monorepo_scripts/stage_docs.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					import { postpublishUtils } from '@0xproject/monorepo-scripts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as packageJSON from '../package.json';
 | 
				
			||||||
 | 
					import * as tsConfigJSON from '../tsconfig.json';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const cwd = `${__dirname}/..`;
 | 
				
			||||||
 | 
					// tslint:disable-next-line:no-floating-promises
 | 
				
			||||||
 | 
					postpublishUtils.publishDocsToStagingAsync(packageJSON, tsConfigJSON, cwd);
 | 
				
			||||||
@@ -1,13 +1,16 @@
 | 
				
			|||||||
 | 
					import { Provider, SignedOrder } from '@0xproject/types';
 | 
				
			||||||
import { BigNumber } from '@0xproject/utils';
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SignedOrder, ZeroEx } from '../../src';
 | 
					import { getOrderHashHex } from './order_hash';
 | 
				
			||||||
 | 
					import { generatePseudoRandomSalt } from './salt';
 | 
				
			||||||
 | 
					import { signOrderHashAsync } from './signature_utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 | 
					const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const orderFactory = {
 | 
					export const orderFactory = {
 | 
				
			||||||
    async createSignedOrderAsync(
 | 
					    async createSignedOrderAsync(
 | 
				
			||||||
        zeroEx: ZeroEx,
 | 
					        provider: Provider,
 | 
				
			||||||
        maker: string,
 | 
					        maker: string,
 | 
				
			||||||
        taker: string,
 | 
					        taker: string,
 | 
				
			||||||
        makerFee: BigNumber,
 | 
					        makerFee: BigNumber,
 | 
				
			||||||
@@ -33,13 +36,13 @@ export const orderFactory = {
 | 
				
			|||||||
            takerTokenAmount,
 | 
					            takerTokenAmount,
 | 
				
			||||||
            makerTokenAddress,
 | 
					            makerTokenAddress,
 | 
				
			||||||
            takerTokenAddress,
 | 
					            takerTokenAddress,
 | 
				
			||||||
            salt: ZeroEx.generatePseudoRandomSalt(),
 | 
					            salt: generatePseudoRandomSalt(),
 | 
				
			||||||
            exchangeContractAddress,
 | 
					            exchangeContractAddress,
 | 
				
			||||||
            feeRecipient,
 | 
					            feeRecipient,
 | 
				
			||||||
            expirationUnixTimestampSec,
 | 
					            expirationUnixTimestampSec,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        const orderHash = ZeroEx.getOrderHashHex(order);
 | 
					        const orderHash = getOrderHashHex(order);
 | 
				
			||||||
        const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
 | 
					        const ecSignature = await signOrderHashAsync(provider, orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
 | 
				
			||||||
        const signedOrder: SignedOrder = _.assign(order, { ecSignature });
 | 
					        const signedOrder: SignedOrder = _.assign(order, { ecSignature });
 | 
				
			||||||
        return signedOrder;
 | 
					        return signedOrder;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
							
								
								
									
										89
									
								
								packages/order-utils/src/order_hash.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								packages/order-utils/src/order_hash.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					import { schemas, SchemaValidator } from '@0xproject/json-schemas';
 | 
				
			||||||
 | 
					import { Order, SignedOrder, SolidityTypes } from '@0xproject/types';
 | 
				
			||||||
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
 | 
					import BN = require('bn.js');
 | 
				
			||||||
 | 
					import * as ethABI from 'ethereumjs-abi';
 | 
				
			||||||
 | 
					import * as ethUtil from 'ethereumjs-util';
 | 
				
			||||||
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { assert } from './assert';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const INVALID_TAKER_FORMAT = 'instance.taker is not of a type(s) string';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Converts BigNumber instance to BN
 | 
				
			||||||
 | 
					 * The only reason we convert to BN is to remain compatible with `ethABI.soliditySHA3` that
 | 
				
			||||||
 | 
					 * expects values of Solidity type `uint` to be passed as type `BN`.
 | 
				
			||||||
 | 
					 * We do not use BN anywhere else in the codebase.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function bigNumberToBN(value: BigNumber) {
 | 
				
			||||||
 | 
					    return new BN(value.toString(), 10);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Computes the orderHash for a supplied order.
 | 
				
			||||||
 | 
					 * @param   order   An object that conforms to the Order or SignedOrder interface definitions.
 | 
				
			||||||
 | 
					 * @return  The resulting orderHash from hashing the supplied order.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function getOrderHashHex(order: Order | SignedOrder): string {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        assert.doesConformToSchema('order', order, schemas.orderSchema);
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					        if (_.includes(error.message, INVALID_TAKER_FORMAT)) {
 | 
				
			||||||
 | 
					            const errMsg =
 | 
				
			||||||
 | 
					                'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
 | 
				
			||||||
 | 
					            throw new Error(errMsg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        throw error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const orderParts = [
 | 
				
			||||||
 | 
					        { value: order.exchangeContractAddress, type: SolidityTypes.Address },
 | 
				
			||||||
 | 
					        { value: order.maker, type: SolidityTypes.Address },
 | 
				
			||||||
 | 
					        { value: order.taker, type: SolidityTypes.Address },
 | 
				
			||||||
 | 
					        { value: order.makerTokenAddress, type: SolidityTypes.Address },
 | 
				
			||||||
 | 
					        { value: order.takerTokenAddress, type: SolidityTypes.Address },
 | 
				
			||||||
 | 
					        { value: order.feeRecipient, type: SolidityTypes.Address },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            value: bigNumberToBN(order.makerTokenAmount),
 | 
				
			||||||
 | 
					            type: SolidityTypes.Uint256,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            value: bigNumberToBN(order.takerTokenAmount),
 | 
				
			||||||
 | 
					            type: SolidityTypes.Uint256,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            value: bigNumberToBN(order.makerFee),
 | 
				
			||||||
 | 
					            type: SolidityTypes.Uint256,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            value: bigNumberToBN(order.takerFee),
 | 
				
			||||||
 | 
					            type: SolidityTypes.Uint256,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            value: bigNumberToBN(order.expirationUnixTimestampSec),
 | 
				
			||||||
 | 
					            type: SolidityTypes.Uint256,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        { value: bigNumberToBN(order.salt), type: SolidityTypes.Uint256 },
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    const types = _.map(orderParts, o => o.type);
 | 
				
			||||||
 | 
					    const values = _.map(orderParts, o => o.value);
 | 
				
			||||||
 | 
					    const hashBuff = ethABI.soliditySHA3(types, values);
 | 
				
			||||||
 | 
					    const hashHex = ethUtil.bufferToHex(hashBuff);
 | 
				
			||||||
 | 
					    return hashHex;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Checks if the supplied hex encoded order hash is valid.
 | 
				
			||||||
 | 
					 * Note: Valid means it has the expected format, not that an order with the orderHash exists.
 | 
				
			||||||
 | 
					 * Use this method when processing orderHashes submitted as user input.
 | 
				
			||||||
 | 
					 * @param   orderHash    Hex encoded orderHash.
 | 
				
			||||||
 | 
					 * @return  Whether the supplied orderHash has the expected format.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function isValidOrderHash(orderHash: string): boolean {
 | 
				
			||||||
 | 
					    // Since this method can be called to check if any arbitrary string conforms to an orderHash's
 | 
				
			||||||
 | 
					    // format, we only assert that we were indeed passed a string.
 | 
				
			||||||
 | 
					    assert.isString('orderHash', orderHash);
 | 
				
			||||||
 | 
					    const schemaValidator = new SchemaValidator();
 | 
				
			||||||
 | 
					    const isValid = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid;
 | 
				
			||||||
 | 
					    return isValid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								packages/order-utils/src/salt.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								packages/order-utils/src/salt.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MAX_DIGITS_IN_UNSIGNED_256_INT = 78;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generates a pseudo-random 256-bit salt.
 | 
				
			||||||
 | 
					 * The salt can be included in a 0x order, ensuring that the order generates a unique orderHash
 | 
				
			||||||
 | 
					 * and will not collide with other outstanding orders that are identical in all other parameters.
 | 
				
			||||||
 | 
					 * @return  A pseudo-random 256-bit number that can be used as a salt.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function generatePseudoRandomSalt(): BigNumber {
 | 
				
			||||||
 | 
					    // BigNumber.random returns a pseudo-random number between 0 & 1 with a passed in number of decimal places.
 | 
				
			||||||
 | 
					    // Source: https://mikemcl.github.io/bignumber.js/#random
 | 
				
			||||||
 | 
					    const randomNumber = BigNumber.random(MAX_DIGITS_IN_UNSIGNED_256_INT);
 | 
				
			||||||
 | 
					    const factor = new BigNumber(10).pow(MAX_DIGITS_IN_UNSIGNED_256_INT - 1);
 | 
				
			||||||
 | 
					    const salt = randomNumber.times(factor).round();
 | 
				
			||||||
 | 
					    return salt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										119
									
								
								packages/order-utils/src/signature_utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								packages/order-utils/src/signature_utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					import { schemas } from '@0xproject/json-schemas';
 | 
				
			||||||
 | 
					import { ECSignature, Provider } from '@0xproject/types';
 | 
				
			||||||
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
 | 
					import * as ethUtil from 'ethereumjs-util';
 | 
				
			||||||
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { assert } from './assert';
 | 
				
			||||||
 | 
					import { OrderError } from './types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Verifies that the elliptic curve signature `signature` was generated
 | 
				
			||||||
 | 
					 * by signing `data` with the private key corresponding to the `signerAddress` address.
 | 
				
			||||||
 | 
					 * @param   data          The hex encoded data signed by the supplied signature.
 | 
				
			||||||
 | 
					 * @param   signature     An object containing the elliptic curve signature parameters.
 | 
				
			||||||
 | 
					 * @param   signerAddress The hex encoded address that signed the data, producing the supplied signature.
 | 
				
			||||||
 | 
					 * @return  Whether the signature is valid for the supplied signerAddress and data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
 | 
				
			||||||
 | 
					    assert.isHexString('data', data);
 | 
				
			||||||
 | 
					    assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
 | 
				
			||||||
 | 
					    assert.isETHAddressHex('signerAddress', signerAddress);
 | 
				
			||||||
 | 
					    const normalizedSignerAddress = signerAddress.toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const dataBuff = ethUtil.toBuffer(data);
 | 
				
			||||||
 | 
					    const msgHashBuff = ethUtil.hashPersonalMessage(dataBuff);
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        const pubKey = ethUtil.ecrecover(
 | 
				
			||||||
 | 
					            msgHashBuff,
 | 
				
			||||||
 | 
					            signature.v,
 | 
				
			||||||
 | 
					            ethUtil.toBuffer(signature.r),
 | 
				
			||||||
 | 
					            ethUtil.toBuffer(signature.s),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
 | 
				
			||||||
 | 
					        return retrievedAddress === signerAddress;
 | 
				
			||||||
 | 
					    } catch (err) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Signs an orderHash and returns it's elliptic curve signature.
 | 
				
			||||||
 | 
					 * This method currently supports TestRPC, Geth and Parity above and below V1.6.6
 | 
				
			||||||
 | 
					 * @param   orderHash       Hex encoded orderHash to sign.
 | 
				
			||||||
 | 
					 * @param   signerAddress   The hex encoded Ethereum address you wish to sign it with. This address
 | 
				
			||||||
 | 
					 *          must be available via the Provider supplied to 0x.js.
 | 
				
			||||||
 | 
					 * @param   shouldAddPersonalMessagePrefix  Some signers add the personal message prefix `\x19Ethereum Signed Message`
 | 
				
			||||||
 | 
					 *          themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
 | 
				
			||||||
 | 
					 *          (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
 | 
				
			||||||
 | 
					 *          before sending the request.
 | 
				
			||||||
 | 
					 * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export async function signOrderHashAsync(
 | 
				
			||||||
 | 
					    provider: Provider,
 | 
				
			||||||
 | 
					    orderHash: string,
 | 
				
			||||||
 | 
					    signerAddress: string,
 | 
				
			||||||
 | 
					    shouldAddPersonalMessagePrefix: boolean,
 | 
				
			||||||
 | 
					): Promise<ECSignature> {
 | 
				
			||||||
 | 
					    assert.isHexString('orderHash', orderHash);
 | 
				
			||||||
 | 
					    const web3Wrapper = new Web3Wrapper(provider);
 | 
				
			||||||
 | 
					    await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper);
 | 
				
			||||||
 | 
					    const normalizedSignerAddress = signerAddress.toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let msgHashHex = orderHash;
 | 
				
			||||||
 | 
					    if (shouldAddPersonalMessagePrefix) {
 | 
				
			||||||
 | 
					        const orderHashBuff = ethUtil.toBuffer(orderHash);
 | 
				
			||||||
 | 
					        const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
 | 
				
			||||||
 | 
					        msgHashHex = ethUtil.bufferToHex(msgHashBuff);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const signature = await web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHashHex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // HACK: There is no consensus on whether the signatureHex string should be formatted as
 | 
				
			||||||
 | 
					    // v + r + s OR r + s + v, and different clients (even different versions of the same client)
 | 
				
			||||||
 | 
					    // return the signature params in different orders. In order to support all client implementations,
 | 
				
			||||||
 | 
					    // we parse the signature in both ways, and evaluate if either one is a valid signature.
 | 
				
			||||||
 | 
					    const validVParamValues = [27, 28];
 | 
				
			||||||
 | 
					    const ecSignatureVRS = parseSignatureHexAsVRS(signature);
 | 
				
			||||||
 | 
					    if (_.includes(validVParamValues, ecSignatureVRS.v)) {
 | 
				
			||||||
 | 
					        const isValidVRSSignature = isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress);
 | 
				
			||||||
 | 
					        if (isValidVRSSignature) {
 | 
				
			||||||
 | 
					            return ecSignatureVRS;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ecSignatureRSV = parseSignatureHexAsRSV(signature);
 | 
				
			||||||
 | 
					    if (_.includes(validVParamValues, ecSignatureRSV.v)) {
 | 
				
			||||||
 | 
					        const isValidRSVSignature = isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress);
 | 
				
			||||||
 | 
					        if (isValidRSVSignature) {
 | 
				
			||||||
 | 
					            return ecSignatureRSV;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    throw new Error(OrderError.InvalidSignature);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function parseSignatureHexAsVRS(signatureHex: string): ECSignature {
 | 
				
			||||||
 | 
					    const signatureBuffer = ethUtil.toBuffer(signatureHex);
 | 
				
			||||||
 | 
					    let v = signatureBuffer[0];
 | 
				
			||||||
 | 
					    if (v < 27) {
 | 
				
			||||||
 | 
					        v += 27;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const r = signatureBuffer.slice(1, 33);
 | 
				
			||||||
 | 
					    const s = signatureBuffer.slice(33, 65);
 | 
				
			||||||
 | 
					    const ecSignature: ECSignature = {
 | 
				
			||||||
 | 
					        v,
 | 
				
			||||||
 | 
					        r: ethUtil.bufferToHex(r),
 | 
				
			||||||
 | 
					        s: ethUtil.bufferToHex(s),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    return ecSignature;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function parseSignatureHexAsRSV(signatureHex: string): ECSignature {
 | 
				
			||||||
 | 
					    const { v, r, s } = ethUtil.fromRpcSig(signatureHex);
 | 
				
			||||||
 | 
					    const ecSignature: ECSignature = {
 | 
				
			||||||
 | 
					        v,
 | 
				
			||||||
 | 
					        r: ethUtil.bufferToHex(r),
 | 
				
			||||||
 | 
					        s: ethUtil.bufferToHex(s),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    return ecSignature;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								packages/order-utils/src/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/order-utils/src/types.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					export enum OrderError {
 | 
				
			||||||
 | 
					    InvalidSignature = 'INVALID_SIGNATURE',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								packages/order-utils/test/assert_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								packages/order-utils/test/assert_test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					import { web3Factory } from '@0xproject/dev-utils';
 | 
				
			||||||
 | 
					import * as chai from 'chai';
 | 
				
			||||||
 | 
					import 'mocha';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { assert } from '../src/assert';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { chaiSetup } from './utils/chai_setup';
 | 
				
			||||||
 | 
					import { web3Wrapper } from './utils/web3_wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					chaiSetup.configure();
 | 
				
			||||||
 | 
					const expect = chai.expect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('Assertion library', () => {
 | 
				
			||||||
 | 
					    describe('#isSenderAddressHexAsync', () => {
 | 
				
			||||||
 | 
					        it('throws when address is invalid', async () => {
 | 
				
			||||||
 | 
					            const address = '0xdeadbeef';
 | 
				
			||||||
 | 
					            const varName = 'address';
 | 
				
			||||||
 | 
					            return expect(assert.isSenderAddressAsync(varName, address, web3Wrapper)).to.be.rejectedWith(
 | 
				
			||||||
 | 
					                `Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('throws when address is unavailable', async () => {
 | 
				
			||||||
 | 
					            const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
 | 
				
			||||||
 | 
					            const varName = 'address';
 | 
				
			||||||
 | 
					            return expect(assert.isSenderAddressAsync(varName, validUnrelatedAddress, web3Wrapper)).to.be.rejectedWith(
 | 
				
			||||||
 | 
					                `Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it("doesn't throw if address is available", async () => {
 | 
				
			||||||
 | 
					            const availableAddress = (await web3Wrapper.getAvailableAddressesAsync())[0];
 | 
				
			||||||
 | 
					            const varName = 'address';
 | 
				
			||||||
 | 
					            return expect(assert.isSenderAddressAsync(varName, availableAddress, web3Wrapper)).to.become(undefined);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										46
									
								
								packages/order-utils/test/order_hash_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								packages/order-utils/test/order_hash_test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					import { web3Factory } from '@0xproject/dev-utils';
 | 
				
			||||||
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
 | 
					import * as chai from 'chai';
 | 
				
			||||||
 | 
					import 'mocha';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { constants, getOrderHashHex } from '../src';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { chaiSetup } from './utils/chai_setup';
 | 
				
			||||||
 | 
					import { web3Wrapper } from './utils/web3_wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					chaiSetup.configure();
 | 
				
			||||||
 | 
					const expect = chai.expect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('Order hashing', () => {
 | 
				
			||||||
 | 
					    describe('#getOrderHashHex', () => {
 | 
				
			||||||
 | 
					        const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
 | 
				
			||||||
 | 
					        const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b';
 | 
				
			||||||
 | 
					        const order = {
 | 
				
			||||||
 | 
					            maker: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					            taker: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					            feeRecipient: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					            makerTokenAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					            takerTokenAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					            exchangeContractAddress: fakeExchangeContractAddress,
 | 
				
			||||||
 | 
					            salt: new BigNumber(0),
 | 
				
			||||||
 | 
					            makerFee: new BigNumber(0),
 | 
				
			||||||
 | 
					            takerFee: new BigNumber(0),
 | 
				
			||||||
 | 
					            makerTokenAmount: new BigNumber(0),
 | 
				
			||||||
 | 
					            takerTokenAmount: new BigNumber(0),
 | 
				
			||||||
 | 
					            expirationUnixTimestampSec: new BigNumber(0),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        it('calculates the order hash', async () => {
 | 
				
			||||||
 | 
					            const orderHash = getOrderHashHex(order);
 | 
				
			||||||
 | 
					            expect(orderHash).to.be.equal(expectedOrderHash);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('throws a readable error message if taker format is invalid', async () => {
 | 
				
			||||||
 | 
					            const orderWithInvalidtakerFormat = {
 | 
				
			||||||
 | 
					                ...order,
 | 
				
			||||||
 | 
					                taker: (null as any) as string,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            const expectedErrorMessage =
 | 
				
			||||||
 | 
					                'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
 | 
				
			||||||
 | 
					            expect(() => getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										157
									
								
								packages/order-utils/test/signature_utils_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								packages/order-utils/test/signature_utils_test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
				
			|||||||
 | 
					import { web3Factory } from '@0xproject/dev-utils';
 | 
				
			||||||
 | 
					import { JSONRPCErrorCallback, JSONRPCRequestPayload } from '@0xproject/types';
 | 
				
			||||||
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
 | 
					import * as chai from 'chai';
 | 
				
			||||||
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					import 'mocha';
 | 
				
			||||||
 | 
					import * as Sinon from 'sinon';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { generatePseudoRandomSalt, isValidOrderHash, isValidSignature, signOrderHashAsync } from '../src';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { chaiSetup } from './utils/chai_setup';
 | 
				
			||||||
 | 
					import { provider, web3Wrapper } from './utils/web3_wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					chaiSetup.configure();
 | 
				
			||||||
 | 
					const expect = chai.expect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('Signature utils', () => {
 | 
				
			||||||
 | 
					    describe('#isValidSignature', () => {
 | 
				
			||||||
 | 
					        // The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
 | 
				
			||||||
 | 
					        // the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
 | 
				
			||||||
 | 
					        const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
 | 
				
			||||||
 | 
					        const signature = {
 | 
				
			||||||
 | 
					            v: 27,
 | 
				
			||||||
 | 
					            r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
 | 
				
			||||||
 | 
					            s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
 | 
				
			||||||
 | 
					        it("should return false if the data doesn't pertain to the signature & address", async () => {
 | 
				
			||||||
 | 
					            expect(isValidSignature('0x0', signature, address)).to.be.false();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it("should return false if the address doesn't pertain to the signature & data", async () => {
 | 
				
			||||||
 | 
					            const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
 | 
				
			||||||
 | 
					            expect(isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
 | 
				
			||||||
 | 
					            const wrongSignature = _.assign({}, signature, { v: 28 });
 | 
				
			||||||
 | 
					            expect(isValidSignature(dataHex, wrongSignature, address)).to.be.false();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('should return true if the signature does pertain to the dataHex & address', async () => {
 | 
				
			||||||
 | 
					            const isValidSignatureLocal = isValidSignature(dataHex, signature, address);
 | 
				
			||||||
 | 
					            expect(isValidSignatureLocal).to.be.true();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    describe('#generateSalt', () => {
 | 
				
			||||||
 | 
					        it('generates different salts', () => {
 | 
				
			||||||
 | 
					            const equal = generatePseudoRandomSalt().eq(generatePseudoRandomSalt());
 | 
				
			||||||
 | 
					            expect(equal).to.be.false();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('generates salt in range [0..2^256)', () => {
 | 
				
			||||||
 | 
					            const salt = generatePseudoRandomSalt();
 | 
				
			||||||
 | 
					            expect(salt.greaterThanOrEqualTo(0)).to.be.true();
 | 
				
			||||||
 | 
					            const twoPow256 = new BigNumber(2).pow(256);
 | 
				
			||||||
 | 
					            expect(salt.lessThan(twoPow256)).to.be.true();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    describe('#isValidOrderHash', () => {
 | 
				
			||||||
 | 
					        it('returns false if the value is not a hex string', () => {
 | 
				
			||||||
 | 
					            const isValid = isValidOrderHash('not a hex');
 | 
				
			||||||
 | 
					            expect(isValid).to.be.false();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('returns false if the length is wrong', () => {
 | 
				
			||||||
 | 
					            const isValid = isValidOrderHash('0xdeadbeef');
 | 
				
			||||||
 | 
					            expect(isValid).to.be.false();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('returns true if order hash is correct', () => {
 | 
				
			||||||
 | 
					            const isValid = isValidOrderHash('0x' + Array(65).join('0'));
 | 
				
			||||||
 | 
					            expect(isValid).to.be.true();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    describe('#signOrderHashAsync', () => {
 | 
				
			||||||
 | 
					        let stubs: Sinon.SinonStub[] = [];
 | 
				
			||||||
 | 
					        let makerAddress: string;
 | 
				
			||||||
 | 
					        before(async () => {
 | 
				
			||||||
 | 
					            const availableAddreses = await web3Wrapper.getAvailableAddressesAsync();
 | 
				
			||||||
 | 
					            makerAddress = availableAddreses[0];
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        afterEach(() => {
 | 
				
			||||||
 | 
					            // clean up any stubs after the test has completed
 | 
				
			||||||
 | 
					            _.each(stubs, s => s.restore());
 | 
				
			||||||
 | 
					            stubs = [];
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('Should return the correct ECSignature', async () => {
 | 
				
			||||||
 | 
					            const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
 | 
				
			||||||
 | 
					            const expectedECSignature = {
 | 
				
			||||||
 | 
					                v: 27,
 | 
				
			||||||
 | 
					                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
 | 
				
			||||||
 | 
					                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            const ecSignature = await signOrderHashAsync(
 | 
				
			||||||
 | 
					                provider,
 | 
				
			||||||
 | 
					                orderHash,
 | 
				
			||||||
 | 
					                makerAddress,
 | 
				
			||||||
 | 
					                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
 | 
				
			||||||
 | 
					            const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
 | 
				
			||||||
 | 
					            const signature =
 | 
				
			||||||
 | 
					                '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
 | 
				
			||||||
 | 
					            const expectedECSignature = {
 | 
				
			||||||
 | 
					                v: 27,
 | 
				
			||||||
 | 
					                r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
 | 
				
			||||||
 | 
					                s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            stubs = [Sinon.stub('isValidSignature').returns(true)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const fakeProvider = {
 | 
				
			||||||
 | 
					                sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) {
 | 
				
			||||||
 | 
					                    if (payload.method === 'eth_sign') {
 | 
				
			||||||
 | 
					                        callback(null, { id: 42, jsonrpc: '2.0', result: signature });
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const ecSignature = await signOrderHashAsync(
 | 
				
			||||||
 | 
					                fakeProvider,
 | 
				
			||||||
 | 
					                orderHash,
 | 
				
			||||||
 | 
					                makerAddress,
 | 
				
			||||||
 | 
					                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
 | 
				
			||||||
 | 
					            const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
 | 
				
			||||||
 | 
					            const signature =
 | 
				
			||||||
 | 
					                '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
 | 
				
			||||||
 | 
					            const expectedECSignature = {
 | 
				
			||||||
 | 
					                v: 27,
 | 
				
			||||||
 | 
					                r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
 | 
				
			||||||
 | 
					                s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            stubs = [Sinon.stub('isValidSignature').returns(true)];
 | 
				
			||||||
 | 
					            const fakeProvider = {
 | 
				
			||||||
 | 
					                sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback) {
 | 
				
			||||||
 | 
					                    if (payload.method === 'eth_sign') {
 | 
				
			||||||
 | 
					                        callback(null, { id: 42, jsonrpc: '2.0', result: signature });
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] });
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const ecSignature = await signOrderHashAsync(
 | 
				
			||||||
 | 
					                fakeProvider,
 | 
				
			||||||
 | 
					                orderHash,
 | 
				
			||||||
 | 
					                makerAddress,
 | 
				
			||||||
 | 
					                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										13
									
								
								packages/order-utils/test/utils/chai_setup.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								packages/order-utils/test/utils/chai_setup.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import * as chai from 'chai';
 | 
				
			||||||
 | 
					import chaiAsPromised = require('chai-as-promised');
 | 
				
			||||||
 | 
					import ChaiBigNumber = require('chai-bignumber');
 | 
				
			||||||
 | 
					import * as dirtyChai from 'dirty-chai';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const chaiSetup = {
 | 
				
			||||||
 | 
					    configure() {
 | 
				
			||||||
 | 
					        chai.config.includeStack = true;
 | 
				
			||||||
 | 
					        chai.use(ChaiBigNumber());
 | 
				
			||||||
 | 
					        chai.use(dirtyChai);
 | 
				
			||||||
 | 
					        chai.use(chaiAsPromised);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										9
									
								
								packages/order-utils/test/utils/web3_wrapper.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								packages/order-utils/test/utils/web3_wrapper.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import { devConstants, web3Factory } from '@0xproject/dev-utils';
 | 
				
			||||||
 | 
					import { Provider } from '@0xproject/types';
 | 
				
			||||||
 | 
					import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const web3 = web3Factory.create({ shouldUseInProcessGanache: true });
 | 
				
			||||||
 | 
					const provider: Provider = web3.currentProvider;
 | 
				
			||||||
 | 
					const web3Wrapper = new Web3Wrapper(web3.currentProvider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { provider, web3Wrapper };
 | 
				
			||||||
							
								
								
									
										7
									
								
								packages/order-utils/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/order-utils/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "extends": "../../tsconfig",
 | 
				
			||||||
 | 
					    "compilerOptions": {
 | 
				
			||||||
 | 
					        "outDir": "lib"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "include": ["src/**/*", "test/**/*"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								packages/order-utils/tslint.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/order-utils/tslint.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "extends": ["@0xproject/tslint-config"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -94,6 +94,7 @@ export enum KindString {
 | 
				
			|||||||
    Method = 'Method',
 | 
					    Method = 'Method',
 | 
				
			||||||
    Interface = 'Interface',
 | 
					    Interface = 'Interface',
 | 
				
			||||||
    TypeAlias = 'Type alias',
 | 
					    TypeAlias = 'Type alias',
 | 
				
			||||||
 | 
					    ObjectLiteral = 'Object literal',
 | 
				
			||||||
    Variable = 'Variable',
 | 
					    Variable = 'Variable',
 | 
				
			||||||
    Function = 'Function',
 | 
					    Function = 'Function',
 | 
				
			||||||
    Enumeration = 'Enumeration',
 | 
					    Enumeration = 'Enumeration',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,10 +93,16 @@ export const typeDocUtils = {
 | 
				
			|||||||
                throw new Error('`react-docs` only supports projects with 1 exported class per file');
 | 
					                throw new Error('`react-docs` only supports projects with 1 exported class per file');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            const isClassExport = packageDefinitionWithMergedChildren.children[0].kindString === KindString.Class;
 | 
					            const isClassExport = packageDefinitionWithMergedChildren.children[0].kindString === KindString.Class;
 | 
				
			||||||
 | 
					            const isObjectLiteralExport =
 | 
				
			||||||
 | 
					                packageDefinitionWithMergedChildren.children[0].kindString === KindString.ObjectLiteral;
 | 
				
			||||||
            if (isClassExport) {
 | 
					            if (isClassExport) {
 | 
				
			||||||
                entities = packageDefinitionWithMergedChildren.children[0].children;
 | 
					                entities = packageDefinitionWithMergedChildren.children[0].children;
 | 
				
			||||||
                const commentObj = packageDefinitionWithMergedChildren.children[0].comment;
 | 
					                const commentObj = packageDefinitionWithMergedChildren.children[0].comment;
 | 
				
			||||||
                packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
 | 
					                packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
 | 
				
			||||||
 | 
					            } else if (isObjectLiteralExport) {
 | 
				
			||||||
 | 
					                entities = packageDefinitionWithMergedChildren.children[0].children;
 | 
				
			||||||
 | 
					                const commentObj = packageDefinitionWithMergedChildren.children[0].comment;
 | 
				
			||||||
 | 
					                packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                entities = packageDefinitionWithMergedChildren.children;
 | 
					                entities = packageDefinitionWithMergedChildren.children;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								packages/website/md/docs/order_utils/installation.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								packages/website/md/docs/order_utils/installation.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					**Install**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn add @0xproject/order-utils
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Import**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					import { createSignedOrderAsync } from '@0xproject/order-utils';
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					var createSignedOrderAsync = require('@0xproject/order-utils').createSignedOrderAsync;
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
							
								
								
									
										1
									
								
								packages/website/md/docs/order_utils/introduction.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/website/md/docs/order_utils/introduction.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					Welcome to the [@0xproject/order-utils](https://github.com/0xProject/0x-monorepo/tree/development/packages/order-utils) documentation! Order utils is a set of utils around creating, signing, validating 0x orders.
 | 
				
			||||||
							
								
								
									
										99
									
								
								packages/website/ts/containers/order_utils_documentation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								packages/website/ts/containers/order_utils_documentation.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					import { constants as docConstants, DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0xproject/react-docs';
 | 
				
			||||||
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					import * as React from 'react';
 | 
				
			||||||
 | 
					import { connect } from 'react-redux';
 | 
				
			||||||
 | 
					import { Dispatch } from 'redux';
 | 
				
			||||||
 | 
					import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page';
 | 
				
			||||||
 | 
					import { Dispatcher } from 'ts/redux/dispatcher';
 | 
				
			||||||
 | 
					import { State } from 'ts/redux/reducer';
 | 
				
			||||||
 | 
					import { DocPackages, Environments, WebsitePaths } from 'ts/types';
 | 
				
			||||||
 | 
					import { configs } from 'ts/utils/configs';
 | 
				
			||||||
 | 
					import { constants } from 'ts/utils/constants';
 | 
				
			||||||
 | 
					import { Translate } from 'ts/utils/translate';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* tslint:disable:no-var-requires */
 | 
				
			||||||
 | 
					const IntroMarkdown = require('md/docs/order_utils/introduction');
 | 
				
			||||||
 | 
					const InstallationMarkdown = require('md/docs/order_utils/installation');
 | 
				
			||||||
 | 
					/* tslint:enable:no-var-requires */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const docSections = {
 | 
				
			||||||
 | 
					    introduction: 'introduction',
 | 
				
			||||||
 | 
					    installation: 'installation',
 | 
				
			||||||
 | 
					    usage: 'usage',
 | 
				
			||||||
 | 
					    types: 'types',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const docsInfoConfig: DocsInfoConfig = {
 | 
				
			||||||
 | 
					    id: DocPackages.OrderUtils,
 | 
				
			||||||
 | 
					    type: SupportedDocJson.TypeDoc,
 | 
				
			||||||
 | 
					    displayName: 'Order utils',
 | 
				
			||||||
 | 
					    packageUrl: 'https://github.com/0xProject/0x-monorepo',
 | 
				
			||||||
 | 
					    menu: {
 | 
				
			||||||
 | 
					        introduction: [docSections.introduction],
 | 
				
			||||||
 | 
					        install: [docSections.installation],
 | 
				
			||||||
 | 
					        usage: [docSections.usage],
 | 
				
			||||||
 | 
					        types: [docSections.types],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    sectionNameToMarkdown: {
 | 
				
			||||||
 | 
					        [docSections.introduction]: IntroMarkdown,
 | 
				
			||||||
 | 
					        [docSections.installation]: InstallationMarkdown,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    sectionNameToModulePath: {
 | 
				
			||||||
 | 
					        [docSections.usage]: [
 | 
				
			||||||
 | 
					            '"order-utils/src/order_hash"',
 | 
				
			||||||
 | 
					            '"order-utils/src/signature_utils"',
 | 
				
			||||||
 | 
					            '"order-utils/src/order_factory"',
 | 
				
			||||||
 | 
					            '"order-utils/src/salt"',
 | 
				
			||||||
 | 
					            '"order-utils/src/assert"',
 | 
				
			||||||
 | 
					            '"order-utils/src/constants"',
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        [docSections.types]: ['"order-utils/src/types"', '"types/src/index"'],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    menuSubsectionToVersionWhenIntroduced: {},
 | 
				
			||||||
 | 
					    sections: docSections,
 | 
				
			||||||
 | 
					    visibleConstructors: [],
 | 
				
			||||||
 | 
					    typeConfigs: {
 | 
				
			||||||
 | 
					        // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
 | 
				
			||||||
 | 
					        // currently no way to extract the re-exported types from index.ts via TypeDoc :(
 | 
				
			||||||
 | 
					        publicTypes: [
 | 
				
			||||||
 | 
					            'OrderError',
 | 
				
			||||||
 | 
					            'Order',
 | 
				
			||||||
 | 
					            'SignedOrder',
 | 
				
			||||||
 | 
					            'ECSignature',
 | 
				
			||||||
 | 
					            'Provider',
 | 
				
			||||||
 | 
					            'JSONRPCRequestPayload',
 | 
				
			||||||
 | 
					            'JSONRPCResponsePayload',
 | 
				
			||||||
 | 
					            'JSONRPCErrorCallback',
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        typeNameToExternalLink: {
 | 
				
			||||||
 | 
					            BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const docsInfo = new DocsInfo(docsInfoConfig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ConnectedState {
 | 
				
			||||||
 | 
					    docsVersion: string;
 | 
				
			||||||
 | 
					    availableDocVersions: string[];
 | 
				
			||||||
 | 
					    docsInfo: DocsInfo;
 | 
				
			||||||
 | 
					    translate: Translate;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ConnectedDispatch {
 | 
				
			||||||
 | 
					    dispatcher: Dispatcher;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({
 | 
				
			||||||
 | 
					    docsVersion: state.docsVersion,
 | 
				
			||||||
 | 
					    availableDocVersions: state.availableDocVersions,
 | 
				
			||||||
 | 
					    translate: state.translate,
 | 
				
			||||||
 | 
					    docsInfo,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
 | 
				
			||||||
 | 
					    dispatcher: new Dispatcher(dispatch),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)(
 | 
				
			||||||
 | 
					    DocPageComponent,
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
@@ -61,6 +61,9 @@ const LazySolCovDocumentation = createLazyComponent('Documentation', async () =>
 | 
				
			|||||||
const LazySubprovidersDocumentation = createLazyComponent('Documentation', async () =>
 | 
					const LazySubprovidersDocumentation = createLazyComponent('Documentation', async () =>
 | 
				
			||||||
    System.import<any>(/* webpackChunkName: "subproviderDocs" */ 'ts/containers/subproviders_documentation'),
 | 
					    System.import<any>(/* webpackChunkName: "subproviderDocs" */ 'ts/containers/subproviders_documentation'),
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					const LazyOrderUtilsDocumentation = createLazyComponent('Documentation', async () =>
 | 
				
			||||||
 | 
					    System.import<any>(/* webpackChunkName: "orderUtilsDocs" */ 'ts/containers/order_utils_documentation'),
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
analytics.init();
 | 
					analytics.init();
 | 
				
			||||||
// tslint:disable-next-line:no-floating-promises
 | 
					// tslint:disable-next-line:no-floating-promises
 | 
				
			||||||
@@ -93,6 +96,10 @@ render(
 | 
				
			|||||||
                                path={`${WebsitePaths.Subproviders}/:version?`}
 | 
					                                path={`${WebsitePaths.Subproviders}/:version?`}
 | 
				
			||||||
                                component={LazySubprovidersDocumentation}
 | 
					                                component={LazySubprovidersDocumentation}
 | 
				
			||||||
                            />
 | 
					                            />
 | 
				
			||||||
 | 
					                            <Route
 | 
				
			||||||
 | 
					                                path={`${WebsitePaths.OrderUtils}/:version?`}
 | 
				
			||||||
 | 
					                                component={LazyOrderUtilsDocumentation}
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
                            <Route
 | 
					                            <Route
 | 
				
			||||||
                                path={`${WebsitePaths.Web3Wrapper}/:version?`}
 | 
					                                path={`${WebsitePaths.Web3Wrapper}/:version?`}
 | 
				
			||||||
                                component={LazyWeb3WrapperDocumentation}
 | 
					                                component={LazyWeb3WrapperDocumentation}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,7 @@ const docIdToSubpackageName: { [id: string]: string } = {
 | 
				
			|||||||
    [DocPackages.JSONSchemas]: 'json-schemas',
 | 
					    [DocPackages.JSONSchemas]: 'json-schemas',
 | 
				
			||||||
    [DocPackages.SolCov]: 'sol-cov',
 | 
					    [DocPackages.SolCov]: 'sol-cov',
 | 
				
			||||||
    [DocPackages.Subproviders]: 'subproviders',
 | 
					    [DocPackages.Subproviders]: 'subproviders',
 | 
				
			||||||
 | 
					    [DocPackages.OrderUtils]: 'order-utils',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface DocPageProps {
 | 
					export interface DocPageProps {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -361,6 +361,7 @@ export enum WebsitePaths {
 | 
				
			|||||||
    JSONSchemas = '/docs/json-schemas',
 | 
					    JSONSchemas = '/docs/json-schemas',
 | 
				
			||||||
    SolCov = '/docs/sol-cov',
 | 
					    SolCov = '/docs/sol-cov',
 | 
				
			||||||
    Subproviders = '/docs/subproviders',
 | 
					    Subproviders = '/docs/subproviders',
 | 
				
			||||||
 | 
					    OrderUtils = '/docs/order-utils',
 | 
				
			||||||
    Jobs = '/jobs',
 | 
					    Jobs = '/jobs',
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -373,6 +374,7 @@ export enum DocPackages {
 | 
				
			|||||||
    JSONSchemas = 'JSON_SCHEMAS',
 | 
					    JSONSchemas = 'JSON_SCHEMAS',
 | 
				
			||||||
    SolCov = 'SOL_COV',
 | 
					    SolCov = 'SOL_COV',
 | 
				
			||||||
    Subproviders = 'SUBPROVIDERS',
 | 
					    Subproviders = 'SUBPROVIDERS',
 | 
				
			||||||
 | 
					    OrderUtils = 'ORDER_UTILS',
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum Key {
 | 
					export enum Key {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import { ECSignature, ExchangeContractErrs, ZeroEx, ZeroExError } from '0x.js';
 | 
					import { ECSignature, ExchangeContractErrs, ZeroEx, ZeroExError } from '0x.js';
 | 
				
			||||||
 | 
					import { OrderError } from '@0xproject/order-utils';
 | 
				
			||||||
import { constants as sharedConstants, EtherscanLinkSuffixes, Networks } from '@0xproject/react-shared';
 | 
					import { constants as sharedConstants, EtherscanLinkSuffixes, Networks } from '@0xproject/react-shared';
 | 
				
			||||||
import { Provider } from '@0xproject/types';
 | 
					import { Provider } from '@0xproject/types';
 | 
				
			||||||
import { BigNumber } from '@0xproject/utils';
 | 
					import { BigNumber } from '@0xproject/utils';
 | 
				
			||||||
@@ -202,7 +203,7 @@ export const utils = {
 | 
				
			|||||||
            [ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
 | 
					            [ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
 | 
				
			||||||
            [ZeroExError.UnhandledError]: 'Unhandled error occured',
 | 
					            [ZeroExError.UnhandledError]: 'Unhandled error occured',
 | 
				
			||||||
            [ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
 | 
					            [ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
 | 
				
			||||||
            [ZeroExError.InvalidSignature]: 'Order signature is not valid',
 | 
					            [OrderError.InvalidSignature]: 'Order signature is not valid',
 | 
				
			||||||
            [ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
 | 
					            [ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
 | 
				
			||||||
            [ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
 | 
					            [ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
 | 
				
			||||||
            [ZeroExError.OutOfGas]: 'Transaction ran out of gas',
 | 
					            [ZeroExError.OutOfGas]: 'Transaction ran out of gas',
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user