Merge pull request #636 from 0xProject/refactor/order-utils/for-v2
Refactor order-utils for v2
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -86,6 +86,7 @@ packages/contract-wrappers/src/contract_wrappers/generated/
 | 
			
		||||
packages/metacoin/src/contract_wrappers
 | 
			
		||||
packages/fill-scenarios/src/generated_contract_wrappers/
 | 
			
		||||
packages/order-watcher/src/generated_contract_wrappers/
 | 
			
		||||
packages/order-utils/src/generated_contract_wrappers/
 | 
			
		||||
packages/migrations/src/v1/contract_wrappers
 | 
			
		||||
packages/migrations/src/v2/contract_wrappers
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,9 @@
 | 
			
		||||
        "rebuild": "run-s clean build",
 | 
			
		||||
        "test": "wsrun test $PKG --fast-exit --serial --exclude-missing",
 | 
			
		||||
        "stage_docs": "wsrun docs:stage $PKG --fast-exit --parallel --exclude-missing",
 | 
			
		||||
        "lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing"
 | 
			
		||||
        "lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing",
 | 
			
		||||
        "comment:postinstall": "HACK: For some reason `yarn` is not setting up symlinks properly for order-utils. We temporarily set them manually. Remove this after V2 refactor is complete.",
 | 
			
		||||
        "postinstall": "rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types"
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
        "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,7 @@
 | 
			
		||||
        "@0xproject/assert": "^0.2.10",
 | 
			
		||||
        "@0xproject/base-contract": "^0.3.2",
 | 
			
		||||
        "@0xproject/contract-wrappers": "^0.0.2",
 | 
			
		||||
        "@0xproject/order-utils": "^0.0.5",
 | 
			
		||||
        "@0xproject/order-utils": "0.0.5",
 | 
			
		||||
        "@0xproject/order-watcher": "^0.0.2",
 | 
			
		||||
        "@0xproject/sol-compiler": "^0.5.0",
 | 
			
		||||
        "@0xproject/types": "0.7.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@
 | 
			
		||||
        "@0xproject/base-contract": "^0.3.2",
 | 
			
		||||
        "@0xproject/fill-scenarios": "^0.0.2",
 | 
			
		||||
        "@0xproject/json-schemas": "0.7.22",
 | 
			
		||||
        "@0xproject/order-utils": "^0.0.5",
 | 
			
		||||
        "@0xproject/order-utils": "0.0.5",
 | 
			
		||||
        "@0xproject/types": "0.7.0",
 | 
			
		||||
        "@0xproject/typescript-typings": "^0.3.2",
 | 
			
		||||
        "@0xproject/utils": "^0.6.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -69,9 +69,9 @@
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0xproject/base-contract": "^0.3.2",
 | 
			
		||||
        "@0xproject/order-utils": "^0.0.5",
 | 
			
		||||
        "@0xproject/order-utils": "^0.0.6",
 | 
			
		||||
        "@0xproject/sol-compiler": "^0.5.0",
 | 
			
		||||
        "@0xproject/types": "^0.7.0",
 | 
			
		||||
        "@0xproject/types": "^1.0.0",
 | 
			
		||||
        "@0xproject/typescript-typings": "^0.3.2",
 | 
			
		||||
        "@0xproject/utils": "^0.6.2",
 | 
			
		||||
        "@0xproject/web3-wrapper": "^0.6.4",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
 | 
			
		||||
 | 
			
		||||
import { crypto } from './crypto';
 | 
			
		||||
import { crypto, generatePseudoRandomSalt } from '@0xproject/order-utils';
 | 
			
		||||
 | 
			
		||||
export const addressUtils = {
 | 
			
		||||
    generatePseudoRandomAddress(): string {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import { LogEntry, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
			
		||||
@@ -10,7 +10,7 @@ import { constants } from './constants';
 | 
			
		||||
import { formatters } from './formatters';
 | 
			
		||||
import { LogDecoder } from './log_decoder';
 | 
			
		||||
import { orderUtils } from './order_utils';
 | 
			
		||||
import { AssetProxyId, OrderInfo, SignedTransaction } from './types';
 | 
			
		||||
import { OrderInfo, SignedTransaction } from './types';
 | 
			
		||||
 | 
			
		||||
export class ExchangeWrapper {
 | 
			
		||||
    private _exchange: ExchangeContract;
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,8 @@ export const formatters = {
 | 
			
		||||
            takerAssetFillAmounts,
 | 
			
		||||
        };
 | 
			
		||||
        _.forEach(signedOrders, signedOrder => {
 | 
			
		||||
            const orderStruct = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
            batchFill.orders.push(orderStruct);
 | 
			
		||||
            const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
            batchFill.orders.push(orderWithoutExchangeAddress);
 | 
			
		||||
            batchFill.signatures.push(signedOrder.signature);
 | 
			
		||||
            if (takerAssetFillAmounts.length < signedOrders.length) {
 | 
			
		||||
                batchFill.takerAssetFillAmounts.push(signedOrder.takerAssetAmount);
 | 
			
		||||
@@ -29,8 +29,8 @@ export const formatters = {
 | 
			
		||||
            takerAssetFillAmount,
 | 
			
		||||
        };
 | 
			
		||||
        _.forEach(signedOrders, signedOrder => {
 | 
			
		||||
            const orderStruct = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
            marketSellOrders.orders.push(orderStruct);
 | 
			
		||||
            const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
            marketSellOrders.orders.push(orderWithoutExchangeAddress);
 | 
			
		||||
            marketSellOrders.signatures.push(signedOrder.signature);
 | 
			
		||||
        });
 | 
			
		||||
        return marketSellOrders;
 | 
			
		||||
@@ -42,8 +42,8 @@ export const formatters = {
 | 
			
		||||
            makerAssetFillAmount,
 | 
			
		||||
        };
 | 
			
		||||
        _.forEach(signedOrders, signedOrder => {
 | 
			
		||||
            const orderStruct = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
            marketBuyOrders.orders.push(orderStruct);
 | 
			
		||||
            const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
            marketBuyOrders.orders.push(orderWithoutExchangeAddress);
 | 
			
		||||
            marketBuyOrders.signatures.push(signedOrder.signature);
 | 
			
		||||
        });
 | 
			
		||||
        return marketBuyOrders;
 | 
			
		||||
@@ -53,8 +53,8 @@ export const formatters = {
 | 
			
		||||
            orders: [],
 | 
			
		||||
        };
 | 
			
		||||
        _.forEach(signedOrders, signedOrder => {
 | 
			
		||||
            const orderStruct = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
            batchCancel.orders.push(orderStruct);
 | 
			
		||||
            const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
            batchCancel.orders.push(orderWithoutExchangeAddress);
 | 
			
		||||
        });
 | 
			
		||||
        return batchCancel;
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { assetProxyUtils, crypto, orderHashUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import { LogWithDecodedArgs } from 'ethereum-types';
 | 
			
		||||
@@ -15,17 +16,13 @@ import {
 | 
			
		||||
    ExchangeContract,
 | 
			
		||||
    FillContractEventArgs,
 | 
			
		||||
} from '../contract_wrappers/generated/exchange';
 | 
			
		||||
import { assetProxyUtils } from '../utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../utils/chai_setup';
 | 
			
		||||
import { constants } from '../utils/constants';
 | 
			
		||||
import { crypto } from '../utils/crypto';
 | 
			
		||||
import { ERC20Wrapper } from '../utils/erc20_wrapper';
 | 
			
		||||
import { ERC721Wrapper } from '../utils/erc721_wrapper';
 | 
			
		||||
import { ExchangeWrapper } from '../utils/exchange_wrapper';
 | 
			
		||||
import { OrderFactory } from '../utils/order_factory';
 | 
			
		||||
import { orderUtils } from '../utils/order_utils';
 | 
			
		||||
import {
 | 
			
		||||
    AssetProxyId,
 | 
			
		||||
    ContractName,
 | 
			
		||||
    ERC20BalancesByOwner,
 | 
			
		||||
    ERC721TokenIdsByOwner,
 | 
			
		||||
@@ -123,7 +120,7 @@ export class MatchOrderTester {
 | 
			
		||||
        const feeRecipientAddressRight = signedOrderRight.feeRecipientAddress;
 | 
			
		||||
        // Verify Left order preconditions
 | 
			
		||||
        const orderTakerAssetFilledAmountLeft = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
            orderUtils.getOrderHashHex(signedOrderLeft),
 | 
			
		||||
            orderHashUtils.getOrderHashHex(signedOrderLeft),
 | 
			
		||||
        );
 | 
			
		||||
        const expectedOrderFilledAmountLeft = initialTakerAssetFilledAmountLeft
 | 
			
		||||
            ? initialTakerAssetFilledAmountLeft
 | 
			
		||||
@@ -131,7 +128,7 @@ export class MatchOrderTester {
 | 
			
		||||
        expect(expectedOrderFilledAmountLeft).to.be.bignumber.equal(orderTakerAssetFilledAmountLeft);
 | 
			
		||||
        // Verify Right order preconditions
 | 
			
		||||
        const orderTakerAssetFilledAmountRight = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
            orderUtils.getOrderHashHex(signedOrderRight),
 | 
			
		||||
            orderHashUtils.getOrderHashHex(signedOrderRight),
 | 
			
		||||
        );
 | 
			
		||||
        const expectedOrderFilledAmountRight = initialTakerAssetFilledAmountRight
 | 
			
		||||
            ? initialTakerAssetFilledAmountRight
 | 
			
		||||
@@ -182,7 +179,7 @@ export class MatchOrderTester {
 | 
			
		||||
        orderTakerAssetFilledAmountRight: BigNumber,
 | 
			
		||||
    ): Promise<TransferAmounts> {
 | 
			
		||||
        let amountBoughtByLeftMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
            orderUtils.getOrderHashHex(signedOrderLeft),
 | 
			
		||||
            orderHashUtils.getOrderHashHex(signedOrderLeft),
 | 
			
		||||
        );
 | 
			
		||||
        amountBoughtByLeftMaker = amountBoughtByLeftMaker.minus(orderTakerAssetFilledAmountLeft);
 | 
			
		||||
        const amountSoldByLeftMaker = amountBoughtByLeftMaker
 | 
			
		||||
@@ -193,7 +190,7 @@ export class MatchOrderTester {
 | 
			
		||||
            .dividedToIntegerBy(signedOrderRight.makerAssetAmount);
 | 
			
		||||
        const amountReceivedByTaker = amountSoldByLeftMaker.minus(amountReceivedByRightMaker);
 | 
			
		||||
        let amountBoughtByRightMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
            orderUtils.getOrderHashHex(signedOrderRight),
 | 
			
		||||
            orderHashUtils.getOrderHashHex(signedOrderRight),
 | 
			
		||||
        );
 | 
			
		||||
        amountBoughtByRightMaker = amountBoughtByRightMaker.minus(orderTakerAssetFilledAmountRight);
 | 
			
		||||
        const amountSoldByRightMaker = amountBoughtByRightMaker
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,21 @@
 | 
			
		||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
 | 
			
		||||
import { SignedOrder, UnsignedOrder } from '@0xproject/types';
 | 
			
		||||
import { generatePseudoRandomSalt, orderHashUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { Order, SignatureType, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { constants } from './constants';
 | 
			
		||||
import { orderUtils } from './order_utils';
 | 
			
		||||
import { signingUtils } from './signing_utils';
 | 
			
		||||
import { SignatureType } from './types';
 | 
			
		||||
 | 
			
		||||
export class OrderFactory {
 | 
			
		||||
    private _defaultOrderParams: Partial<UnsignedOrder>;
 | 
			
		||||
    private _defaultOrderParams: Partial<Order>;
 | 
			
		||||
    private _privateKey: Buffer;
 | 
			
		||||
    constructor(privateKey: Buffer, defaultOrderParams: Partial<UnsignedOrder>) {
 | 
			
		||||
    constructor(privateKey: Buffer, defaultOrderParams: Partial<Order>) {
 | 
			
		||||
        this._defaultOrderParams = defaultOrderParams;
 | 
			
		||||
        this._privateKey = privateKey;
 | 
			
		||||
    }
 | 
			
		||||
    public newSignedOrder(
 | 
			
		||||
        customOrderParams: Partial<UnsignedOrder> = {},
 | 
			
		||||
        signatureType: SignatureType = SignatureType.Ecrecover,
 | 
			
		||||
        customOrderParams: Partial<Order> = {},
 | 
			
		||||
        signatureType: SignatureType = SignatureType.EthSign,
 | 
			
		||||
    ): SignedOrder {
 | 
			
		||||
        const tenMinutes = 10 * 60 * 1000;
 | 
			
		||||
        const randomExpiration = new BigNumber(Date.now() + tenMinutes);
 | 
			
		||||
@@ -28,8 +26,8 @@ export class OrderFactory {
 | 
			
		||||
            takerAddress: constants.NULL_ADDRESS,
 | 
			
		||||
            ...this._defaultOrderParams,
 | 
			
		||||
            ...customOrderParams,
 | 
			
		||||
        } as any) as UnsignedOrder;
 | 
			
		||||
        const orderHashBuff = orderUtils.getOrderHashBuff(order);
 | 
			
		||||
        } as any) as Order;
 | 
			
		||||
        const orderHashBuff = orderHashUtils.getOrderHashBuff(order);
 | 
			
		||||
        const signature = signingUtils.signMessage(orderHashBuff, this._privateKey, signatureType);
 | 
			
		||||
        const signedOrder = {
 | 
			
		||||
            ...order,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,13 @@
 | 
			
		||||
import { Order, SignedOrder, UnsignedOrder } from '@0xproject/types';
 | 
			
		||||
import { Order, OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import ethUtil = require('ethereumjs-util');
 | 
			
		||||
 | 
			
		||||
import { crypto } from './crypto';
 | 
			
		||||
import { CancelOrder, MatchOrder } from './types';
 | 
			
		||||
 | 
			
		||||
export const orderUtils = {
 | 
			
		||||
    createFill: (signedOrder: SignedOrder, takerAssetFillAmount?: BigNumber) => {
 | 
			
		||||
        const fill = {
 | 
			
		||||
            order: orderUtils.getOrderStruct(signedOrder),
 | 
			
		||||
            order: orderUtils.getOrderWithoutExchangeAddress(signedOrder),
 | 
			
		||||
            takerAssetFillAmount: takerAssetFillAmount || signedOrder.takerAssetAmount,
 | 
			
		||||
            signature: signedOrder.signature,
 | 
			
		||||
        };
 | 
			
		||||
@@ -16,12 +15,12 @@ export const orderUtils = {
 | 
			
		||||
    },
 | 
			
		||||
    createCancel(signedOrder: SignedOrder, takerAssetCancelAmount?: BigNumber): CancelOrder {
 | 
			
		||||
        const cancel = {
 | 
			
		||||
            order: orderUtils.getOrderStruct(signedOrder),
 | 
			
		||||
            order: orderUtils.getOrderWithoutExchangeAddress(signedOrder),
 | 
			
		||||
            takerAssetCancelAmount: takerAssetCancelAmount || signedOrder.takerAssetAmount,
 | 
			
		||||
        };
 | 
			
		||||
        return cancel;
 | 
			
		||||
    },
 | 
			
		||||
    getOrderStruct(signedOrder: SignedOrder): Order {
 | 
			
		||||
    getOrderWithoutExchangeAddress(signedOrder: SignedOrder): OrderWithoutExchangeAddress {
 | 
			
		||||
        const orderStruct = {
 | 
			
		||||
            senderAddress: signedOrder.senderAddress,
 | 
			
		||||
            makerAddress: signedOrder.makerAddress,
 | 
			
		||||
@@ -38,75 +37,10 @@ export const orderUtils = {
 | 
			
		||||
        };
 | 
			
		||||
        return orderStruct;
 | 
			
		||||
    },
 | 
			
		||||
    getDomainSeparatorSchemaHex(): string {
 | 
			
		||||
        const domainSeparatorSchemaHashBuff = crypto.solSHA3(['DomainSeparator(address contract)']);
 | 
			
		||||
        const schemaHashHex = `0x${domainSeparatorSchemaHashBuff.toString('hex')}`;
 | 
			
		||||
        return schemaHashHex;
 | 
			
		||||
    },
 | 
			
		||||
    getDomainSeparatorHashHex(exchangeAddress: string): string {
 | 
			
		||||
        const domainSeparatorHashBuff = crypto.solSHA3([exchangeAddress]);
 | 
			
		||||
        const domainSeparatorHashHex = `0x${domainSeparatorHashBuff.toString('hex')}`;
 | 
			
		||||
        return domainSeparatorHashHex;
 | 
			
		||||
    },
 | 
			
		||||
    getOrderSchemaHex(): string {
 | 
			
		||||
        const orderSchemaHashBuff = crypto.solSHA3([
 | 
			
		||||
            'Order(',
 | 
			
		||||
            'address makerAddress,',
 | 
			
		||||
            'address takerAddress,',
 | 
			
		||||
            'address feeRecipientAddress,',
 | 
			
		||||
            'address senderAddress,',
 | 
			
		||||
            'uint256 makerAssetAmount,',
 | 
			
		||||
            'uint256 takerAssetAmount,',
 | 
			
		||||
            'uint256 makerFee,',
 | 
			
		||||
            'uint256 takerFee,',
 | 
			
		||||
            'uint256 expirationTimeSeconds,',
 | 
			
		||||
            'uint256 salt,',
 | 
			
		||||
            'bytes makerAssetData,',
 | 
			
		||||
            'bytes takerAssetData,',
 | 
			
		||||
            ')',
 | 
			
		||||
        ]);
 | 
			
		||||
        const schemaHashHex = `0x${orderSchemaHashBuff.toString('hex')}`;
 | 
			
		||||
        return schemaHashHex;
 | 
			
		||||
    },
 | 
			
		||||
    getOrderHashBuff(order: SignedOrder | UnsignedOrder): Buffer {
 | 
			
		||||
        const makerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.makerAssetData)]);
 | 
			
		||||
        const takerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.takerAssetData)]);
 | 
			
		||||
 | 
			
		||||
        const orderParamsHashBuff = crypto.solSHA3([
 | 
			
		||||
            order.makerAddress,
 | 
			
		||||
            order.takerAddress,
 | 
			
		||||
            order.feeRecipientAddress,
 | 
			
		||||
            order.senderAddress,
 | 
			
		||||
            order.makerAssetAmount,
 | 
			
		||||
            order.takerAssetAmount,
 | 
			
		||||
            order.makerFee,
 | 
			
		||||
            order.takerFee,
 | 
			
		||||
            order.expirationTimeSeconds,
 | 
			
		||||
            order.salt,
 | 
			
		||||
            makerAssetDataHash,
 | 
			
		||||
            takerAssetDataHash,
 | 
			
		||||
        ]);
 | 
			
		||||
        const orderParamsHashHex = `0x${orderParamsHashBuff.toString('hex')}`;
 | 
			
		||||
        const orderSchemaHashHex = orderUtils.getOrderSchemaHex();
 | 
			
		||||
        const domainSeparatorHashHex = this.getDomainSeparatorHashHex(order.exchangeAddress);
 | 
			
		||||
        const domainSeparatorSchemaHex = this.getDomainSeparatorSchemaHex();
 | 
			
		||||
        const orderHashBuff = crypto.solSHA3([
 | 
			
		||||
            new BigNumber(domainSeparatorSchemaHex),
 | 
			
		||||
            new BigNumber(domainSeparatorHashHex),
 | 
			
		||||
            new BigNumber(orderSchemaHashHex),
 | 
			
		||||
            new BigNumber(orderParamsHashHex),
 | 
			
		||||
        ]);
 | 
			
		||||
        return orderHashBuff;
 | 
			
		||||
    },
 | 
			
		||||
    getOrderHashHex(order: SignedOrder | UnsignedOrder): string {
 | 
			
		||||
        const orderHashBuff = orderUtils.getOrderHashBuff(order);
 | 
			
		||||
        const orderHashHex = `0x${orderHashBuff.toString('hex')}`;
 | 
			
		||||
        return orderHashHex;
 | 
			
		||||
    },
 | 
			
		||||
    createMatchOrders(signedOrderLeft: SignedOrder, signedOrderRight: SignedOrder): MatchOrder {
 | 
			
		||||
        const fill = {
 | 
			
		||||
            left: orderUtils.getOrderStruct(signedOrderLeft),
 | 
			
		||||
            right: orderUtils.getOrderStruct(signedOrderRight),
 | 
			
		||||
            left: orderUtils.getOrderWithoutExchangeAddress(signedOrderLeft),
 | 
			
		||||
            right: orderUtils.getOrderWithoutExchangeAddress(signedOrderRight),
 | 
			
		||||
            leftSignature: signedOrderLeft.signature,
 | 
			
		||||
            rightSignature: signedOrderRight.signature,
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,9 @@
 | 
			
		||||
import { SignatureType } from '@0xproject/types';
 | 
			
		||||
import * as ethUtil from 'ethereumjs-util';
 | 
			
		||||
 | 
			
		||||
import { SignatureType } from './types';
 | 
			
		||||
 | 
			
		||||
export const signingUtils = {
 | 
			
		||||
    signMessage(message: Buffer, privateKey: Buffer, signatureType: SignatureType): Buffer {
 | 
			
		||||
        if (signatureType === SignatureType.Ecrecover) {
 | 
			
		||||
        if (signatureType === SignatureType.EthSign) {
 | 
			
		||||
            const prefixedMessage = ethUtil.hashPersonalMessage(message);
 | 
			
		||||
            const ecSignature = ethUtil.ecsign(prefixedMessage, privateKey);
 | 
			
		||||
            const signature = Buffer.concat([
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
 | 
			
		||||
import { crypto, generatePseudoRandomSalt } from '@0xproject/order-utils';
 | 
			
		||||
import { SignatureType } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as ethUtil from 'ethereumjs-util';
 | 
			
		||||
 | 
			
		||||
import { crypto } from './crypto';
 | 
			
		||||
import { signingUtils } from './signing_utils';
 | 
			
		||||
import { SignatureType, SignedTransaction } from './types';
 | 
			
		||||
import { SignedTransaction } from './types';
 | 
			
		||||
 | 
			
		||||
export class TransactionFactory {
 | 
			
		||||
    private _signerBuff: Buffer;
 | 
			
		||||
@@ -15,10 +15,7 @@ export class TransactionFactory {
 | 
			
		||||
        this._exchangeAddress = exchangeAddress;
 | 
			
		||||
        this._signerBuff = ethUtil.privateToAddress(this._privateKey);
 | 
			
		||||
    }
 | 
			
		||||
    public newSignedTransaction(
 | 
			
		||||
        data: string,
 | 
			
		||||
        signatureType: SignatureType = SignatureType.Ecrecover,
 | 
			
		||||
    ): SignedTransaction {
 | 
			
		||||
    public newSignedTransaction(data: string, signatureType: SignatureType = SignatureType.EthSign): SignedTransaction {
 | 
			
		||||
        const salt = generatePseudoRandomSalt();
 | 
			
		||||
        const txHash = crypto.solSHA3([this._exchangeAddress, this._signerBuff, salt, ethUtil.toBuffer(data)]);
 | 
			
		||||
        const signature = signingUtils.signMessage(txHash, this._privateKey, signatureType);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { Order } from '@0xproject/types';
 | 
			
		||||
import { Order, OrderWithoutExchangeAddress } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { AbiDefinition, ContractAbi } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
@@ -19,37 +19,31 @@ export interface SubmissionContractEventArgs {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BatchFillOrders {
 | 
			
		||||
    orders: Order[];
 | 
			
		||||
    orders: OrderWithoutExchangeAddress[];
 | 
			
		||||
    signatures: string[];
 | 
			
		||||
    takerAssetFillAmounts: BigNumber[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface MarketSellOrders {
 | 
			
		||||
    orders: Order[];
 | 
			
		||||
    orders: OrderWithoutExchangeAddress[];
 | 
			
		||||
    signatures: string[];
 | 
			
		||||
    takerAssetFillAmount: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface MarketBuyOrders {
 | 
			
		||||
    orders: Order[];
 | 
			
		||||
    orders: OrderWithoutExchangeAddress[];
 | 
			
		||||
    signatures: string[];
 | 
			
		||||
    makerAssetFillAmount: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BatchCancelOrders {
 | 
			
		||||
    orders: Order[];
 | 
			
		||||
    orders: OrderWithoutExchangeAddress[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface CancelOrdersBefore {
 | 
			
		||||
    salt: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum AssetProxyId {
 | 
			
		||||
    INVALID,
 | 
			
		||||
    ERC20,
 | 
			
		||||
    ERC721,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface TransactionDataParams {
 | 
			
		||||
    name: string;
 | 
			
		||||
    abi: AbiDefinition[];
 | 
			
		||||
@@ -115,18 +109,6 @@ export enum ContractName {
 | 
			
		||||
    Whitelist = 'Whitelist',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum SignatureType {
 | 
			
		||||
    Illegal,
 | 
			
		||||
    Invalid,
 | 
			
		||||
    EIP712,
 | 
			
		||||
    Ecrecover,
 | 
			
		||||
    TxOrigin,
 | 
			
		||||
    Caller,
 | 
			
		||||
    Contract,
 | 
			
		||||
    PreSigned,
 | 
			
		||||
    Trezor,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface SignedTransaction {
 | 
			
		||||
    exchangeAddress: string;
 | 
			
		||||
    salt: BigNumber;
 | 
			
		||||
@@ -162,31 +144,14 @@ export interface OrderInfo {
 | 
			
		||||
    orderTakerAssetFilledAmount: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ERC20ProxyData {
 | 
			
		||||
    assetProxyId: AssetProxyId;
 | 
			
		||||
    tokenAddress: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ERC721ProxyData {
 | 
			
		||||
    assetProxyId: AssetProxyId;
 | 
			
		||||
    tokenAddress: string;
 | 
			
		||||
    tokenId: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ProxyData {
 | 
			
		||||
    assetProxyId: AssetProxyId;
 | 
			
		||||
    tokenAddress?: string;
 | 
			
		||||
    data?: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface CancelOrder {
 | 
			
		||||
    order: Order;
 | 
			
		||||
    order: OrderWithoutExchangeAddress;
 | 
			
		||||
    takerAssetCancelAmount: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface MatchOrder {
 | 
			
		||||
    left: Order;
 | 
			
		||||
    right: Order;
 | 
			
		||||
    left: OrderWithoutExchangeAddress;
 | 
			
		||||
    right: OrderWithoutExchangeAddress;
 | 
			
		||||
    leftSignature: string;
 | 
			
		||||
    rightSignature: string;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { assetProxyUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { AssetProxyId } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
@@ -8,12 +10,10 @@ import { DummyERC20TokenContract } from '../../src/contract_wrappers/generated/d
 | 
			
		||||
import { DummyERC721TokenContract } from '../../src/contract_wrappers/generated/dummy_e_r_c721_token';
 | 
			
		||||
import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c20_proxy';
 | 
			
		||||
import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c721_proxy';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
 | 
			
		||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
 | 
			
		||||
import { AssetProxyId } from '../../src/utils/types';
 | 
			
		||||
import { provider, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { assetProxyUtils, crypto, orderHashUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
@@ -18,16 +19,13 @@ import {
 | 
			
		||||
    FillContractEventArgs,
 | 
			
		||||
} from '../../src/contract_wrappers/generated/exchange';
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { crypto } from '../../src/utils/crypto';
 | 
			
		||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
 | 
			
		||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
 | 
			
		||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
 | 
			
		||||
import { OrderFactory } from '../../src/utils/order_factory';
 | 
			
		||||
import { orderUtils } from '../../src/utils/order_utils';
 | 
			
		||||
import { AssetProxyId, ContractName, ERC20BalancesByOwner, ExchangeStatus } from '../../src/utils/types';
 | 
			
		||||
import { ContractName, ERC20BalancesByOwner, ExchangeStatus } from '../../src/utils/types';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
@@ -128,7 +126,6 @@ describe('Exchange core', () => {
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
        await blockchainLifecycle.revertAsync();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe('fillOrder', () => {
 | 
			
		||||
        beforeEach(async () => {
 | 
			
		||||
            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
			
		||||
@@ -142,7 +139,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
 | 
			
		||||
 | 
			
		||||
@@ -152,7 +149,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const takerAssetFilledAmountAfter1 = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(takerAssetFilledAmountAfter1).to.be.bignumber.equal(fillTakerAssetAmount1);
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +159,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const takerAssetFilledAmountAfter2 = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(takerAssetFilledAmountAfter2).to.be.bignumber.equal(takerAssetFilledAmountAfter1);
 | 
			
		||||
        });
 | 
			
		||||
@@ -174,7 +171,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
 | 
			
		||||
 | 
			
		||||
@@ -182,7 +179,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
 | 
			
		||||
 | 
			
		||||
            const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
 | 
			
		||||
 | 
			
		||||
@@ -227,7 +224,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
 | 
			
		||||
 | 
			
		||||
@@ -235,7 +232,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
 | 
			
		||||
 | 
			
		||||
            const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
 | 
			
		||||
 | 
			
		||||
@@ -280,7 +277,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
 | 
			
		||||
 | 
			
		||||
@@ -288,7 +285,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
 | 
			
		||||
 | 
			
		||||
            const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
 | 
			
		||||
 | 
			
		||||
@@ -334,7 +331,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
 | 
			
		||||
 | 
			
		||||
@@ -342,7 +339,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
 | 
			
		||||
 | 
			
		||||
            const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
 | 
			
		||||
                orderUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
                orderHashUtils.getOrderHashHex(signedOrder),
 | 
			
		||||
            );
 | 
			
		||||
            const expectedMakerAmountBoughtAfter = takerAssetFillAmount.add(takerAssetFilledAmountBefore);
 | 
			
		||||
            expect(makerAmountBoughtAfter).to.be.bignumber.equal(expectedMakerAmountBoughtAfter);
 | 
			
		||||
@@ -442,7 +439,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            expect(expectedFilledTakerAssetAmount).to.be.bignumber.equal(logArgs.takerAssetFilledAmount);
 | 
			
		||||
            expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.makerFeePaid);
 | 
			
		||||
            expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.takerFeePaid);
 | 
			
		||||
            expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
 | 
			
		||||
            expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should throw when taker is specified and order is claimed by other', async () => {
 | 
			
		||||
@@ -536,12 +533,6 @@ describe('Exchange core', () => {
 | 
			
		||||
            await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith(
 | 
			
		||||
                constants.REVERT,
 | 
			
		||||
            );
 | 
			
		||||
            await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
                await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
 | 
			
		||||
                    from: makerAddress,
 | 
			
		||||
                }),
 | 
			
		||||
                constants.AWAIT_TRANSACTION_MINED_MS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should throw if taker allowances are too low to fill order', async () => {
 | 
			
		||||
@@ -557,12 +548,6 @@ describe('Exchange core', () => {
 | 
			
		||||
            await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith(
 | 
			
		||||
                constants.REVERT,
 | 
			
		||||
            );
 | 
			
		||||
            await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
                await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
 | 
			
		||||
                    from: takerAddress,
 | 
			
		||||
                }),
 | 
			
		||||
                constants.AWAIT_TRANSACTION_MINED_MS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should not change erc20Balances if an order is expired', async () => {
 | 
			
		||||
@@ -653,7 +638,7 @@ describe('Exchange core', () => {
 | 
			
		||||
            expect(signedOrder.feeRecipientAddress).to.be.equal(logArgs.feeRecipientAddress);
 | 
			
		||||
            expect(signedOrder.makerAssetData).to.be.equal(logArgs.makerAssetData);
 | 
			
		||||
            expect(signedOrder.takerAssetData).to.be.equal(logArgs.takerAssetData);
 | 
			
		||||
            expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
 | 
			
		||||
            expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should log an error if already cancelled', async () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { assetProxyUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { AssetProxyId } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as Web3 from 'web3';
 | 
			
		||||
@@ -8,12 +10,10 @@ import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c2
 | 
			
		||||
import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c721_proxy';
 | 
			
		||||
import { TestAssetProxyDispatcherContract } from '../../src/contract_wrappers/generated/test_asset_proxy_dispatcher';
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
 | 
			
		||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
 | 
			
		||||
import { AssetProxyId } from '../../src/utils/types';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
@@ -7,11 +8,9 @@ import ethUtil = require('ethereumjs-util');
 | 
			
		||||
import { TestLibsContract } from '../../src/contract_wrappers/generated/test_libs';
 | 
			
		||||
import { addressUtils } from '../../src/utils/address_utils';
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { OrderFactory } from '../../src/utils/order_factory';
 | 
			
		||||
import { orderUtils } from '../../src/utils/order_utils';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
@@ -58,20 +57,20 @@ describe('Exchange libs', () => {
 | 
			
		||||
        describe('getOrderSchema', () => {
 | 
			
		||||
            it('should output the correct order schema hash', async () => {
 | 
			
		||||
                const orderSchema = await libs.getOrderSchemaHash.callAsync();
 | 
			
		||||
                expect(orderUtils.getOrderSchemaHex()).to.be.equal(orderSchema);
 | 
			
		||||
                expect(orderHashUtils._getOrderSchemaHex()).to.be.equal(orderSchema);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        describe('getDomainSeparatorSchema', () => {
 | 
			
		||||
            it('should output the correct domain separator schema hash', async () => {
 | 
			
		||||
                const domainSeparatorSchema = await libs.getDomainSeparatorSchemaHash.callAsync();
 | 
			
		||||
                expect(orderUtils.getDomainSeparatorSchemaHex()).to.be.equal(domainSeparatorSchema);
 | 
			
		||||
                expect(orderHashUtils._getDomainSeparatorSchemaHex()).to.be.equal(domainSeparatorSchema);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        describe('getOrderHash', () => {
 | 
			
		||||
            it('should output the correct orderHash', async () => {
 | 
			
		||||
                signedOrder = orderFactory.newSignedOrder();
 | 
			
		||||
                const orderHashHex = await libs.publicGetOrderHash.callAsync(signedOrder);
 | 
			
		||||
                expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
 | 
			
		||||
                expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { assetProxyUtils, crypto } from '@0xproject/order-utils';
 | 
			
		||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
@@ -18,17 +19,14 @@ import {
 | 
			
		||||
    FillContractEventArgs,
 | 
			
		||||
} from '../../src/contract_wrappers/generated/exchange';
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { crypto } from '../../src/utils/crypto';
 | 
			
		||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
 | 
			
		||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
 | 
			
		||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
 | 
			
		||||
import { MatchOrderTester } from '../../src/utils/match_order_tester';
 | 
			
		||||
import { OrderFactory } from '../../src/utils/order_factory';
 | 
			
		||||
import { orderUtils } from '../../src/utils/order_utils';
 | 
			
		||||
import {
 | 
			
		||||
    AssetProxyId,
 | 
			
		||||
    ContractName,
 | 
			
		||||
    ERC20BalancesByOwner,
 | 
			
		||||
    ERC721TokenIdsByOwner,
 | 
			
		||||
@@ -37,8 +35,6 @@ import {
 | 
			
		||||
} from '../../src/utils/types';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
import { MatchOrderTester } from '../../src/utils/match_order_tester';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
@@ -7,11 +8,9 @@ import ethUtil = require('ethereumjs-util');
 | 
			
		||||
import { TestSignatureValidatorContract } from '../../src/contract_wrappers/generated/test_signature_validator';
 | 
			
		||||
import { addressUtils } from '../../src/utils/address_utils';
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { OrderFactory } from '../../src/utils/order_factory';
 | 
			
		||||
import { orderUtils } from '../../src/utils/order_utils';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
@@ -64,7 +63,7 @@ describe('MixinSignatureValidator', () => {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should return true with a valid signature', async () => {
 | 
			
		||||
            const orderHashHex = orderUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
			
		||||
                orderHashHex,
 | 
			
		||||
                signedOrder.makerAddress,
 | 
			
		||||
@@ -81,7 +80,7 @@ describe('MixinSignatureValidator', () => {
 | 
			
		||||
            const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]);
 | 
			
		||||
            const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`;
 | 
			
		||||
            signedOrder.signature = invalidSigHex;
 | 
			
		||||
            const orderHashHex = orderUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
			
		||||
                orderHashHex,
 | 
			
		||||
                signedOrder.makerAddress,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
			
		||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
 | 
			
		||||
import { Order, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
 | 
			
		||||
import { AssetProxyId, Order, OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import * as ethUtil from 'ethereumjs-util';
 | 
			
		||||
@@ -11,7 +11,6 @@ import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c2
 | 
			
		||||
import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange';
 | 
			
		||||
import { WhitelistContract } from '../../src/contract_wrappers/generated/whitelist';
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
 | 
			
		||||
@@ -19,13 +18,7 @@ import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
 | 
			
		||||
import { OrderFactory } from '../../src/utils/order_factory';
 | 
			
		||||
import { orderUtils } from '../../src/utils/order_utils';
 | 
			
		||||
import { TransactionFactory } from '../../src/utils/transaction_factory';
 | 
			
		||||
import {
 | 
			
		||||
    AssetProxyId,
 | 
			
		||||
    ERC20BalancesByOwner,
 | 
			
		||||
    ExchangeStatus,
 | 
			
		||||
    SignatureType,
 | 
			
		||||
    SignedTransaction,
 | 
			
		||||
} from '../../src/utils/types';
 | 
			
		||||
import { ERC20BalancesByOwner, ExchangeStatus, SignedTransaction } from '../../src/utils/types';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
@@ -48,7 +41,7 @@ describe('Exchange transactions', () => {
 | 
			
		||||
    let erc20Balances: ERC20BalancesByOwner;
 | 
			
		||||
    let signedOrder: SignedOrder;
 | 
			
		||||
    let signedTx: SignedTransaction;
 | 
			
		||||
    let order: Order;
 | 
			
		||||
    let orderWithoutExchangeAddress: OrderWithoutExchangeAddress;
 | 
			
		||||
    let orderFactory: OrderFactory;
 | 
			
		||||
    let makerTransactionFactory: TransactionFactory;
 | 
			
		||||
    let takerTransactionFactory: TransactionFactory;
 | 
			
		||||
@@ -121,11 +114,11 @@ describe('Exchange transactions', () => {
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
			
		||||
                signedOrder = orderFactory.newSignedOrder();
 | 
			
		||||
                order = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
                orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
 | 
			
		||||
                takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
 | 
			
		||||
                const data = exchange.fillOrder.getABIEncodedTransactionData(
 | 
			
		||||
                    order,
 | 
			
		||||
                    orderWithoutExchangeAddress,
 | 
			
		||||
                    takerAssetFillAmount,
 | 
			
		||||
                    signedOrder.signature,
 | 
			
		||||
                );
 | 
			
		||||
@@ -189,7 +182,7 @@ describe('Exchange transactions', () => {
 | 
			
		||||
 | 
			
		||||
        describe('cancelOrder', () => {
 | 
			
		||||
            beforeEach(async () => {
 | 
			
		||||
                const data = exchange.cancelOrder.getABIEncodedTransactionData(order);
 | 
			
		||||
                const data = exchange.cancelOrder.getABIEncodedTransactionData(orderWithoutExchangeAddress);
 | 
			
		||||
                signedTx = makerTransactionFactory.newSignedTransaction(data);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
@@ -248,12 +241,12 @@ describe('Exchange transactions', () => {
 | 
			
		||||
                await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }),
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            const orderStruct = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
            orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
            const takerAssetFillAmount = signedOrder.takerAssetAmount;
 | 
			
		||||
            const salt = generatePseudoRandomSalt();
 | 
			
		||||
            return expect(
 | 
			
		||||
                whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
 | 
			
		||||
                    orderStruct,
 | 
			
		||||
                    orderWithoutExchangeAddress,
 | 
			
		||||
                    takerAssetFillAmount,
 | 
			
		||||
                    salt,
 | 
			
		||||
                    signedOrder.signature,
 | 
			
		||||
@@ -268,12 +261,12 @@ describe('Exchange transactions', () => {
 | 
			
		||||
                await whitelist.updateWhitelistStatus.sendTransactionAsync(makerAddress, isApproved, { from: owner }),
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            const orderStruct = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
            orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
            const takerAssetFillAmount = signedOrder.takerAssetAmount;
 | 
			
		||||
            const salt = generatePseudoRandomSalt();
 | 
			
		||||
            return expect(
 | 
			
		||||
                whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
 | 
			
		||||
                    orderStruct,
 | 
			
		||||
                    orderWithoutExchangeAddress,
 | 
			
		||||
                    takerAssetFillAmount,
 | 
			
		||||
                    salt,
 | 
			
		||||
                    signedOrder.signature,
 | 
			
		||||
@@ -292,12 +285,12 @@ describe('Exchange transactions', () => {
 | 
			
		||||
                await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }),
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            const orderStruct = orderUtils.getOrderStruct(signedOrder);
 | 
			
		||||
            orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
 | 
			
		||||
            const takerAssetFillAmount = signedOrder.takerAssetAmount;
 | 
			
		||||
            const salt = generatePseudoRandomSalt();
 | 
			
		||||
            await web3Wrapper.awaitTransactionSuccessAsync(
 | 
			
		||||
                await whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
 | 
			
		||||
                    orderStruct,
 | 
			
		||||
                    orderWithoutExchangeAddress,
 | 
			
		||||
                    takerAssetFillAmount,
 | 
			
		||||
                    salt,
 | 
			
		||||
                    signedOrder.signature,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
 | 
			
		||||
import { SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { assetProxyUtils } from '@0xproject/order-utils';
 | 
			
		||||
import { AssetProxyId, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
@@ -14,14 +15,13 @@ import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c
 | 
			
		||||
import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange';
 | 
			
		||||
import { TokenRegistryContract } from '../../src/contract_wrappers/generated/token_registry';
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
 | 
			
		||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
 | 
			
		||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
 | 
			
		||||
import { OrderFactory } from '../../src/utils/order_factory';
 | 
			
		||||
import { AssetProxyId, ERC20BalancesByOwner } from '../../src/utils/types';
 | 
			
		||||
import { ERC20BalancesByOwner } from '../../src/utils/types';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
 | 
			
		||||
import { AssetProxyId } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import BN = require('bn.js');
 | 
			
		||||
@@ -11,7 +12,6 @@ import { TestLibBytesContract } from '../../src/contract_wrappers/generated/test
 | 
			
		||||
import { artifacts } from '../../src/utils/artifacts';
 | 
			
		||||
import { chaiSetup } from '../../src/utils/chai_setup';
 | 
			
		||||
import { constants } from '../../src/utils/constants';
 | 
			
		||||
import { AssetProxyId } from '../../src/utils/types';
 | 
			
		||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0xproject/base-contract": "^0.3.2",
 | 
			
		||||
        "@0xproject/order-utils": "^0.0.5",
 | 
			
		||||
        "@0xproject/order-utils": "0.0.5",
 | 
			
		||||
        "@0xproject/types": "0.7.0",
 | 
			
		||||
        "ethereum-types": "^0.0.1",
 | 
			
		||||
        "@0xproject/typescript-typings": "^0.3.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0xproject/json-schemas",
 | 
			
		||||
    "version": "0.7.24",
 | 
			
		||||
    "version": "1.0.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								packages/json-schemas/schemas/ec_signature_schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/json-schemas/schemas/ec_signature_schema.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
export const ecSignatureParameterSchema = {
 | 
			
		||||
    id: '/ECSignatureParameter',
 | 
			
		||||
    type: 'string',
 | 
			
		||||
    pattern: '^0[xX][0-9A-Fa-f]{64}$',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const ecSignatureSchema = {
 | 
			
		||||
    id: '/ECSignature',
 | 
			
		||||
    properties: {
 | 
			
		||||
        v: {
 | 
			
		||||
            type: 'number',
 | 
			
		||||
            minimum: 27,
 | 
			
		||||
            maximum: 28,
 | 
			
		||||
        },
 | 
			
		||||
        r: { $ref: '/ECSignatureParameter' },
 | 
			
		||||
        s: { $ref: '/ECSignatureParameter' },
 | 
			
		||||
    },
 | 
			
		||||
    required: ['v', 'r', 's'],
 | 
			
		||||
    type: 'object',
 | 
			
		||||
};
 | 
			
		||||
@@ -5,11 +5,13 @@ export const orderSchema = {
 | 
			
		||||
        takerAddress: { $ref: '/Address' },
 | 
			
		||||
        makerFee: { $ref: '/Number' },
 | 
			
		||||
        takerFee: { $ref: '/Number' },
 | 
			
		||||
        senderAddress: { $ref: '/Address' },
 | 
			
		||||
        makerAssetAmount: { $ref: '/Number' },
 | 
			
		||||
        takerAssetAmount: { $ref: '/Number' },
 | 
			
		||||
        makerAssetData: { $ref: '/Hex' },
 | 
			
		||||
        takerAssetData: { $ref: '/Hex' },
 | 
			
		||||
        salt: { $ref: '/Number' },
 | 
			
		||||
        exchangeAddress: { $ref: '/Address' },
 | 
			
		||||
        feeRecipientAddress: { $ref: '/Address' },
 | 
			
		||||
        expirationTimeSeconds: { $ref: '/Number' },
 | 
			
		||||
    },
 | 
			
		||||
@@ -18,11 +20,13 @@ export const orderSchema = {
 | 
			
		||||
        'takerAddress',
 | 
			
		||||
        'makerFee',
 | 
			
		||||
        'takerFee',
 | 
			
		||||
        'senderAddress',
 | 
			
		||||
        'makerAssetAmount',
 | 
			
		||||
        'takerAssetAmount',
 | 
			
		||||
        'makerAssetData',
 | 
			
		||||
        'takerAssetData',
 | 
			
		||||
        'salt',
 | 
			
		||||
        'exchangeAddress',
 | 
			
		||||
        'feeRecipientAddress',
 | 
			
		||||
        'expirationTimeSeconds',
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { addressSchema, hexSchema, numberSchema } from '../schemas/basic_type_schemas';
 | 
			
		||||
import { blockParamSchema, blockRangeSchema } from '../schemas/block_range_schema';
 | 
			
		||||
import { ecSignatureSchema } from '../schemas/ec_signature_schema';
 | 
			
		||||
import { indexFilterValuesSchema } from '../schemas/index_filter_values_schema';
 | 
			
		||||
import { orderCancellationRequestsSchema } from '../schemas/order_cancel_schema';
 | 
			
		||||
import { orderFillOrKillRequestsSchema } from '../schemas/order_fill_or_kill_requests_schema';
 | 
			
		||||
@@ -31,6 +32,7 @@ export const schemas = {
 | 
			
		||||
    numberSchema,
 | 
			
		||||
    addressSchema,
 | 
			
		||||
    hexSchema,
 | 
			
		||||
    ecSignatureSchema,
 | 
			
		||||
    indexFilterValuesSchema,
 | 
			
		||||
    orderCancellationRequestsSchema,
 | 
			
		||||
    orderFillOrKillRequestsSchema,
 | 
			
		||||
 
 | 
			
		||||
@@ -171,6 +171,7 @@ describe('Schema', () => {
 | 
			
		||||
        const order = {
 | 
			
		||||
            makerAddress: NULL_ADDRESS,
 | 
			
		||||
            takerAddress: NULL_ADDRESS,
 | 
			
		||||
            senderAddress: NULL_ADDRESS,
 | 
			
		||||
            makerFee: '1',
 | 
			
		||||
            takerFee: '2',
 | 
			
		||||
            makerAssetAmount: '1',
 | 
			
		||||
@@ -179,6 +180,7 @@ describe('Schema', () => {
 | 
			
		||||
            takerAssetData: NULL_ADDRESS,
 | 
			
		||||
            salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
 | 
			
		||||
            feeRecipientAddress: NULL_ADDRESS,
 | 
			
		||||
            exchangeAddress: NULL_ADDRESS,
 | 
			
		||||
            expirationTimeSeconds: '42',
 | 
			
		||||
        };
 | 
			
		||||
        describe('#orderSchema', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "artifactsDir": "artifacts/1.0.0",
 | 
			
		||||
    "contractsDir": "../contracts/src/contracts",
 | 
			
		||||
    "contracts": [
 | 
			
		||||
        "Exchange_v1",
 | 
			
		||||
        "DummyERC20Token",
 | 
			
		||||
        "ZRXToken",
 | 
			
		||||
        "WETH9",
 | 
			
		||||
        "TokenTransferProxy_v1",
 | 
			
		||||
        "MultiSigWallet",
 | 
			
		||||
        "MultiSigWalletWithTimeLock",
 | 
			
		||||
        "MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress",
 | 
			
		||||
        "TokenRegistry"
 | 
			
		||||
    ],
 | 
			
		||||
    "compilerSettings": {
 | 
			
		||||
        "outputSelection": {
 | 
			
		||||
            "*": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0xproject/order-utils",
 | 
			
		||||
    "version": "0.0.5",
 | 
			
		||||
    "version": "0.0.6",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -9,13 +9,17 @@
 | 
			
		||||
    "types": "lib/src/index.d.ts",
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "watch": "tsc -w",
 | 
			
		||||
        "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
 | 
			
		||||
        "test": "run-s clean build run_mocha",
 | 
			
		||||
        "build": "run-s clean update_artifacts generate_contract_wrappers transpile copy_monorepo_scripts",
 | 
			
		||||
        "transpile": "tsc",
 | 
			
		||||
        "copy_monorepo_scripts": "copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
 | 
			
		||||
        "generate_contract_wrappers": "abi-gen --abis 'lib/src/artifacts/@(Exchange|IWallet|IValidator).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers && prettier --write 'src/generated_contract_wrappers/**.ts'",
 | 
			
		||||
        "update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json lib/src/artifacts; done;",
 | 
			
		||||
        "test": "run-s 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",
 | 
			
		||||
        "clean": "shx rm -rf lib scripts lib/src/artifacts src/generated_contract_wrappers",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "manual:postpublish": "yarn build; node ./scripts/postpublish.js",
 | 
			
		||||
        "docs:stage": "node scripts/stage_docs.js",
 | 
			
		||||
@@ -23,6 +27,7 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
        "contracts": "IWallet IValidator Exchange",
 | 
			
		||||
        "postpublish": {
 | 
			
		||||
            "docPublishConfigs": {
 | 
			
		||||
                "extraFileIncludes": [
 | 
			
		||||
@@ -66,15 +71,19 @@
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0xproject/assert": "^0.2.10",
 | 
			
		||||
        "@0xproject/json-schemas": "0.7.22",
 | 
			
		||||
        "@0xproject/types": "0.7.0",
 | 
			
		||||
        "@0xproject/base-contract": "^0.3.2",
 | 
			
		||||
        "@0xproject/json-schemas": "1.0.0",
 | 
			
		||||
        "@0xproject/sol-compiler": "^0.5.0",
 | 
			
		||||
        "@0xproject/types": "^1.0.0",
 | 
			
		||||
        "@0xproject/typescript-typings": "^0.3.2",
 | 
			
		||||
        "@0xproject/utils": "^0.6.2",
 | 
			
		||||
        "@0xproject/web3-wrapper": "^0.6.4",
 | 
			
		||||
        "@types/node": "^8.0.53",
 | 
			
		||||
        "bn.js": "^4.11.8",
 | 
			
		||||
        "ethereum-types": "^0.0.1",
 | 
			
		||||
        "ethereumjs-abi": "^0.6.4",
 | 
			
		||||
        "ethereumjs-util": "^5.1.1",
 | 
			
		||||
        "ethers": "^3.0.15",
 | 
			
		||||
        "lodash": "^4.17.4"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								packages/order-utils/src/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								packages/order-utils/src/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
import { Artifact } from '@0xproject/types';
 | 
			
		||||
 | 
			
		||||
import * as Exchange from './artifacts/Exchange.json';
 | 
			
		||||
import * as IValidator from './artifacts/IValidator.json';
 | 
			
		||||
import * as IWallet from './artifacts/IWallet.json';
 | 
			
		||||
export const artifacts = {
 | 
			
		||||
    Exchange: (Exchange as any) as Artifact,
 | 
			
		||||
    IWallet: (IWallet as any) as Artifact,
 | 
			
		||||
    IValidator: (IValidator as any) as Artifact,
 | 
			
		||||
};
 | 
			
		||||
@@ -3,12 +3,12 @@ import { assert as sharedAssert } from '@0xproject/assert';
 | 
			
		||||
// tslint:disable-next-line:no-unused-variable
 | 
			
		||||
import { Schema } from '@0xproject/json-schemas';
 | 
			
		||||
// tslint:disable-next-line:no-unused-variable
 | 
			
		||||
import { ECSignature } from '@0xproject/types';
 | 
			
		||||
import { ECSignature, SignatureType } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { isValidSignature } from './signature_utils';
 | 
			
		||||
import { utils } from './utils';
 | 
			
		||||
 | 
			
		||||
export const assert = {
 | 
			
		||||
    ...sharedAssert,
 | 
			
		||||
@@ -24,4 +24,14 @@ export const assert = {
 | 
			
		||||
            `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
 | 
			
		||||
        );
 | 
			
		||||
    },
 | 
			
		||||
    isOneOfExpectedSignatureTypes(signature: string, signatureTypes: SignatureType[]): void {
 | 
			
		||||
        sharedAssert.isHexString('signature', signature);
 | 
			
		||||
        const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
 | 
			
		||||
        const isExpectedSignatureType = _.includes(signatureTypes, signatureTypeIndexIfExists);
 | 
			
		||||
        if (!isExpectedSignatureType) {
 | 
			
		||||
            throw new Error(
 | 
			
		||||
                `Unexpected signatureType: ${signatureTypeIndexIfExists}. Valid signature types: ${signatureTypes}`,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
import { AssetProxyId, ERC20ProxyData, ERC721ProxyData, ProxyData } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import BN = require('bn.js');
 | 
			
		||||
import ethUtil = require('ethereumjs-util');
 | 
			
		||||
 | 
			
		||||
import { AssetProxyId, ERC20ProxyData, ERC721ProxyData, ProxyData } from './types';
 | 
			
		||||
const ERC20_PROXY_METADATA_BYTE_LENGTH = 21;
 | 
			
		||||
const ERC721_PROXY_METADATA_BYTE_LENGTH = 53;
 | 
			
		||||
 | 
			
		||||
export const assetProxyUtils = {
 | 
			
		||||
    encodeAssetProxyId(assetProxyId: AssetProxyId): Buffer {
 | 
			
		||||
@@ -26,8 +28,10 @@ export const assetProxyUtils = {
 | 
			
		||||
        return address;
 | 
			
		||||
    },
 | 
			
		||||
    encodeUint256(value: BigNumber): Buffer {
 | 
			
		||||
        const formattedValue = new BN(value.toString(10));
 | 
			
		||||
        const base = 10;
 | 
			
		||||
        const formattedValue = new BN(value.toString(base));
 | 
			
		||||
        const encodedValue = ethUtil.toBuffer(formattedValue);
 | 
			
		||||
        // tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
        const paddedValue = ethUtil.setLengthLeft(encodedValue, 32);
 | 
			
		||||
        return paddedValue;
 | 
			
		||||
    },
 | 
			
		||||
@@ -45,7 +49,7 @@ export const assetProxyUtils = {
 | 
			
		||||
    },
 | 
			
		||||
    decodeERC20ProxyData(proxyData: string): ERC20ProxyData {
 | 
			
		||||
        const encodedProxyMetadata = ethUtil.toBuffer(proxyData);
 | 
			
		||||
        if (encodedProxyMetadata.byteLength !== 21) {
 | 
			
		||||
        if (encodedProxyMetadata.byteLength !== ERC20_PROXY_METADATA_BYTE_LENGTH) {
 | 
			
		||||
            throw new Error(
 | 
			
		||||
                `Could not decode ERC20 Proxy Data. Expected length of encoded data to be 21. Got ${
 | 
			
		||||
                    encodedProxyMetadata.byteLength
 | 
			
		||||
@@ -61,7 +65,8 @@ export const assetProxyUtils = {
 | 
			
		||||
                }), but got ${assetProxyId}`,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        const encodedTokenAddress = encodedProxyMetadata.slice(0, 20);
 | 
			
		||||
        const addressOffset = ERC20_PROXY_METADATA_BYTE_LENGTH - 1;
 | 
			
		||||
        const encodedTokenAddress = encodedProxyMetadata.slice(0, addressOffset);
 | 
			
		||||
        const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress);
 | 
			
		||||
        const erc20ProxyData = {
 | 
			
		||||
            assetProxyId,
 | 
			
		||||
@@ -79,7 +84,7 @@ export const assetProxyUtils = {
 | 
			
		||||
    },
 | 
			
		||||
    decodeERC721ProxyData(proxyData: string): ERC721ProxyData {
 | 
			
		||||
        const encodedProxyMetadata = ethUtil.toBuffer(proxyData);
 | 
			
		||||
        if (encodedProxyMetadata.byteLength !== 53) {
 | 
			
		||||
        if (encodedProxyMetadata.byteLength !== ERC721_PROXY_METADATA_BYTE_LENGTH) {
 | 
			
		||||
            throw new Error(
 | 
			
		||||
                `Could not decode ERC20 Proxy Data. Expected length of encoded data to be 53. Got ${
 | 
			
		||||
                    encodedProxyMetadata.byteLength
 | 
			
		||||
@@ -95,9 +100,11 @@ export const assetProxyUtils = {
 | 
			
		||||
                }), but got ${assetProxyId}`,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        const encodedTokenAddress = encodedProxyMetadata.slice(0, 20);
 | 
			
		||||
        const addressOffset = ERC20_PROXY_METADATA_BYTE_LENGTH - 1;
 | 
			
		||||
        const encodedTokenAddress = encodedProxyMetadata.slice(0, addressOffset);
 | 
			
		||||
        const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress);
 | 
			
		||||
        const encodedTokenId = encodedProxyMetadata.slice(20, 52);
 | 
			
		||||
        const tokenIdOffset = ERC721_PROXY_METADATA_BYTE_LENGTH - 1;
 | 
			
		||||
        const encodedTokenId = encodedProxyMetadata.slice(addressOffset, tokenIdOffset);
 | 
			
		||||
        const tokenId = assetProxyUtils.decodeUint256(encodedTokenId);
 | 
			
		||||
        const erc721ProxyData = {
 | 
			
		||||
            assetProxyId,
 | 
			
		||||
@@ -26,7 +26,8 @@ export const crypto = {
 | 
			
		||||
                argTypes.push('uint8');
 | 
			
		||||
            } else if (arg.isBigNumber) {
 | 
			
		||||
                argTypes.push('uint256');
 | 
			
		||||
                args[i] = new BN(arg.toString(10), 10);
 | 
			
		||||
                const base = 10;
 | 
			
		||||
                args[i] = new BN(arg.toString(base), base);
 | 
			
		||||
            } else if (ethUtil.isValidAddress(arg)) {
 | 
			
		||||
                argTypes.push('address');
 | 
			
		||||
            } else if (_.isString(arg)) {
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
import { Order, OrderAddresses, OrderValues } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
 | 
			
		||||
export const formatters = {
 | 
			
		||||
    getOrderAddressesAndValues(order: Order): [OrderAddresses, OrderValues] {
 | 
			
		||||
        const orderAddresses: OrderAddresses = [
 | 
			
		||||
            order.maker,
 | 
			
		||||
            order.taker,
 | 
			
		||||
            order.makerTokenAddress,
 | 
			
		||||
            order.takerTokenAddress,
 | 
			
		||||
            order.feeRecipient,
 | 
			
		||||
        ];
 | 
			
		||||
        const orderValues: OrderValues = [
 | 
			
		||||
            order.makerTokenAmount,
 | 
			
		||||
            order.takerTokenAmount,
 | 
			
		||||
            order.makerFee,
 | 
			
		||||
            order.takerFee,
 | 
			
		||||
            order.expirationUnixTimestampSec,
 | 
			
		||||
            order.salt,
 | 
			
		||||
        ];
 | 
			
		||||
        return [orderAddresses, orderValues];
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
export { getOrderHashHex, isValidOrderHash } from './order_hash';
 | 
			
		||||
export { isValidSignature, signOrderHashAsync } from './signature_utils';
 | 
			
		||||
export { orderHashUtils } from './order_hash';
 | 
			
		||||
export { isValidSignatureAsync, ecSignOrderHashAsync, addSignedMessagePrefix } from './signature_utils';
 | 
			
		||||
export { orderFactory } from './order_factory';
 | 
			
		||||
export { constants } from './constants';
 | 
			
		||||
export { crypto } from './crypto';
 | 
			
		||||
export { generatePseudoRandomSalt } from './salt';
 | 
			
		||||
export { OrderError } from './types';
 | 
			
		||||
export { formatters } from './formatters';
 | 
			
		||||
export { OrderError, MessagePrefixType, MessagePrefixOpts } from './types';
 | 
			
		||||
export { AbstractBalanceAndProxyAllowanceFetcher } from './abstract/abstract_balance_and_proxy_allowance_fetcher';
 | 
			
		||||
export { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher';
 | 
			
		||||
export { RemainingFillableCalculator } from './remaining_fillable_calculator';
 | 
			
		||||
export { OrderStateUtils } from './order_state_utils';
 | 
			
		||||
export { assetProxyUtils } from './asset_proxy_utils';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,49 +1,69 @@
 | 
			
		||||
import { Provider, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { ECSignature, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import { Provider } from 'ethereum-types';
 | 
			
		||||
import * as ethUtil from 'ethereumjs-util';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { getOrderHashHex } from './order_hash';
 | 
			
		||||
import { orderHashUtils } from './order_hash';
 | 
			
		||||
import { generatePseudoRandomSalt } from './salt';
 | 
			
		||||
import { signOrderHashAsync } from './signature_utils';
 | 
			
		||||
 | 
			
		||||
const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
 | 
			
		||||
import { ecSignOrderHashAsync } from './signature_utils';
 | 
			
		||||
import { MessagePrefixType } from './types';
 | 
			
		||||
 | 
			
		||||
export const orderFactory = {
 | 
			
		||||
    async createSignedOrderAsync(
 | 
			
		||||
        provider: Provider,
 | 
			
		||||
        maker: string,
 | 
			
		||||
        taker: string,
 | 
			
		||||
        makerAddress: string,
 | 
			
		||||
        takerAddress: string,
 | 
			
		||||
        senderAddress: string,
 | 
			
		||||
        makerFee: BigNumber,
 | 
			
		||||
        takerFee: BigNumber,
 | 
			
		||||
        makerTokenAmount: BigNumber,
 | 
			
		||||
        makerTokenAddress: string,
 | 
			
		||||
        takerTokenAmount: BigNumber,
 | 
			
		||||
        takerTokenAddress: string,
 | 
			
		||||
        exchangeContractAddress: string,
 | 
			
		||||
        feeRecipient: string,
 | 
			
		||||
        expirationUnixTimestampSecIfExists?: BigNumber,
 | 
			
		||||
        makerAssetAmount: BigNumber,
 | 
			
		||||
        makerAssetData: string,
 | 
			
		||||
        takerAssetAmount: BigNumber,
 | 
			
		||||
        takerAssetData: string,
 | 
			
		||||
        exchangeAddress: string,
 | 
			
		||||
        feeRecipientAddress: string,
 | 
			
		||||
        expirationTimeSecondsIfExists?: BigNumber,
 | 
			
		||||
    ): Promise<SignedOrder> {
 | 
			
		||||
        const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
 | 
			
		||||
        const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
 | 
			
		||||
        const expirationTimeSeconds = _.isUndefined(expirationTimeSecondsIfExists)
 | 
			
		||||
            ? defaultExpirationUnixTimestampSec
 | 
			
		||||
            : expirationUnixTimestampSecIfExists;
 | 
			
		||||
            : expirationTimeSecondsIfExists;
 | 
			
		||||
        const order = {
 | 
			
		||||
            maker,
 | 
			
		||||
            taker,
 | 
			
		||||
            makerAddress,
 | 
			
		||||
            takerAddress,
 | 
			
		||||
            senderAddress,
 | 
			
		||||
            makerFee,
 | 
			
		||||
            takerFee,
 | 
			
		||||
            makerTokenAmount,
 | 
			
		||||
            takerTokenAmount,
 | 
			
		||||
            makerTokenAddress,
 | 
			
		||||
            takerTokenAddress,
 | 
			
		||||
            makerAssetAmount,
 | 
			
		||||
            takerAssetAmount,
 | 
			
		||||
            makerAssetData,
 | 
			
		||||
            takerAssetData,
 | 
			
		||||
            salt: generatePseudoRandomSalt(),
 | 
			
		||||
            exchangeContractAddress,
 | 
			
		||||
            feeRecipient,
 | 
			
		||||
            expirationUnixTimestampSec,
 | 
			
		||||
            exchangeAddress,
 | 
			
		||||
            feeRecipientAddress,
 | 
			
		||||
            expirationTimeSeconds,
 | 
			
		||||
        };
 | 
			
		||||
        const orderHash = getOrderHashHex(order);
 | 
			
		||||
        const ecSignature = await signOrderHashAsync(provider, orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
 | 
			
		||||
        const signedOrder: SignedOrder = _.assign(order, { ecSignature });
 | 
			
		||||
        const orderHash = orderHashUtils.getOrderHashHex(order);
 | 
			
		||||
        const messagePrefixOpts = {
 | 
			
		||||
            prefixType: MessagePrefixType.EthSign,
 | 
			
		||||
            shouldAddPrefixBeforeCallingEthSign: false,
 | 
			
		||||
        };
 | 
			
		||||
        const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, messagePrefixOpts);
 | 
			
		||||
        const signature = getVRSHexString(ecSignature);
 | 
			
		||||
        const signedOrder: SignedOrder = _.assign(order, { signature });
 | 
			
		||||
        return signedOrder;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function getVRSHexString(ecSignature: ECSignature): string {
 | 
			
		||||
    const vrs = `0x${intToHex(ecSignature.v)}${ethUtil.stripHexPrefix(ecSignature.r)}${ethUtil.stripHexPrefix(
 | 
			
		||||
        ecSignature.s,
 | 
			
		||||
    )}`;
 | 
			
		||||
    return vrs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function intToHex(i: number): string {
 | 
			
		||||
    const hex = ethUtil.bufferToHex(ethUtil.toBuffer(i));
 | 
			
		||||
    return hex;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +1,41 @@
 | 
			
		||||
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
 | 
			
		||||
import { Order, SignedOrder, SolidityTypes } from '@0xproject/types';
 | 
			
		||||
import { Order, SignedOrder } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import BN = require('bn.js');
 | 
			
		||||
import { SolidityTypes } from 'ethereum-types';
 | 
			
		||||
import * as ethABI from 'ethereumjs-abi';
 | 
			
		||||
import * as ethUtil from 'ethereumjs-util';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { assert } from './assert';
 | 
			
		||||
import { crypto } from './crypto';
 | 
			
		||||
 | 
			
		||||
const INVALID_TAKER_FORMAT = 'instance.taker is not of a type(s) string';
 | 
			
		||||
const INVALID_TAKER_FORMAT = 'instance.takerAddress 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.
 | 
			
		||||
export const orderHashUtils = {
 | 
			
		||||
    /**
 | 
			
		||||
     * 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.
 | 
			
		||||
     */
 | 
			
		||||
function bigNumberToBN(value: BigNumber): BN {
 | 
			
		||||
    const base = 10;
 | 
			
		||||
    return new BN(value.toString(), base);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    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;
 | 
			
		||||
    },
 | 
			
		||||
    /**
 | 
			
		||||
     * 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 {
 | 
			
		||||
    getOrderHashHex(order: SignedOrder | Order): string {
 | 
			
		||||
        try {
 | 
			
		||||
        assert.doesConformToSchema('order', order, schemas.orderSchema);
 | 
			
		||||
            assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (_.includes(error.message, INVALID_TAKER_FORMAT)) {
 | 
			
		||||
                const errMsg =
 | 
			
		||||
@@ -37,54 +44,74 @@ export function getOrderHashHex(order: Order | SignedOrder): string {
 | 
			
		||||
            }
 | 
			
		||||
            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.
 | 
			
		||||
        const orderHashBuff = this.getOrderHashBuff(order);
 | 
			
		||||
        const orderHashHex = `0x${orderHashBuff.toString('hex')}`;
 | 
			
		||||
        return orderHashHex;
 | 
			
		||||
    },
 | 
			
		||||
    /**
 | 
			
		||||
     * Computes the orderHash for a supplied order and returns it as a Buffer
 | 
			
		||||
     * @param   order   An object that conforms to the Order or SignedOrder interface definitions.
 | 
			
		||||
     * @return  The resulting orderHash from hashing the supplied order as a Buffer
 | 
			
		||||
     */
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
    getOrderHashBuff(order: SignedOrder | Order): Buffer {
 | 
			
		||||
        const makerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.makerAssetData)]);
 | 
			
		||||
        const takerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.takerAssetData)]);
 | 
			
		||||
 | 
			
		||||
        const orderParamsHashBuff = crypto.solSHA3([
 | 
			
		||||
            order.makerAddress,
 | 
			
		||||
            order.takerAddress,
 | 
			
		||||
            order.feeRecipientAddress,
 | 
			
		||||
            order.senderAddress,
 | 
			
		||||
            order.makerAssetAmount,
 | 
			
		||||
            order.takerAssetAmount,
 | 
			
		||||
            order.makerFee,
 | 
			
		||||
            order.takerFee,
 | 
			
		||||
            order.expirationTimeSeconds,
 | 
			
		||||
            order.salt,
 | 
			
		||||
            makerAssetDataHash,
 | 
			
		||||
            takerAssetDataHash,
 | 
			
		||||
        ]);
 | 
			
		||||
        const orderParamsHashHex = `0x${orderParamsHashBuff.toString('hex')}`;
 | 
			
		||||
        const orderSchemaHashHex = this._getOrderSchemaHex();
 | 
			
		||||
        const domainSeparatorHashHex = this._getDomainSeparatorHashHex(order.exchangeAddress);
 | 
			
		||||
        const domainSeparatorSchemaHex = this._getDomainSeparatorSchemaHex();
 | 
			
		||||
        const orderHashBuff = crypto.solSHA3([
 | 
			
		||||
            new BigNumber(domainSeparatorSchemaHex),
 | 
			
		||||
            new BigNumber(domainSeparatorHashHex),
 | 
			
		||||
            new BigNumber(orderSchemaHashHex),
 | 
			
		||||
            new BigNumber(orderParamsHashHex),
 | 
			
		||||
        ]);
 | 
			
		||||
        return orderHashBuff;
 | 
			
		||||
    },
 | 
			
		||||
    _getOrderSchemaHex(): string {
 | 
			
		||||
        const orderSchemaHashBuff = crypto.solSHA3([
 | 
			
		||||
            'Order(',
 | 
			
		||||
            'address makerAddress,',
 | 
			
		||||
            'address takerAddress,',
 | 
			
		||||
            'address feeRecipientAddress,',
 | 
			
		||||
            'address senderAddress,',
 | 
			
		||||
            'uint256 makerAssetAmount,',
 | 
			
		||||
            'uint256 takerAssetAmount,',
 | 
			
		||||
            'uint256 makerFee,',
 | 
			
		||||
            'uint256 takerFee,',
 | 
			
		||||
            'uint256 expirationTimeSeconds,',
 | 
			
		||||
            'uint256 salt,',
 | 
			
		||||
            'bytes makerAssetData,',
 | 
			
		||||
            'bytes takerAssetData,',
 | 
			
		||||
            ')',
 | 
			
		||||
        ]);
 | 
			
		||||
        const schemaHashHex = `0x${orderSchemaHashBuff.toString('hex')}`;
 | 
			
		||||
        return schemaHashHex;
 | 
			
		||||
    },
 | 
			
		||||
    _getDomainSeparatorSchemaHex(): string {
 | 
			
		||||
        const domainSeparatorSchemaHashBuff = crypto.solSHA3(['DomainSeparator(address contract)']);
 | 
			
		||||
        const schemaHashHex = `0x${domainSeparatorSchemaHashBuff.toString('hex')}`;
 | 
			
		||||
        return schemaHashHex;
 | 
			
		||||
    },
 | 
			
		||||
    _getDomainSeparatorHashHex(exchangeAddress: string): string {
 | 
			
		||||
        const domainSeparatorHashBuff = crypto.solSHA3([exchangeAddress]);
 | 
			
		||||
        const domainSeparatorHashHex = `0x${domainSeparatorHashBuff.toString('hex')}`;
 | 
			
		||||
        return domainSeparatorHashHex;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,8 @@ import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AbstractBalanceAndProxyAllowanceFetcher } from './abstract/abstract_balance_and_proxy_allowance_fetcher';
 | 
			
		||||
import { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher';
 | 
			
		||||
import { getOrderHashHex } from './order_hash';
 | 
			
		||||
import { assetProxyUtils } from './asset_proxy_utils';
 | 
			
		||||
import { orderHashUtils } from './order_hash';
 | 
			
		||||
import { RemainingFillableCalculator } from './remaining_fillable_calculator';
 | 
			
		||||
 | 
			
		||||
const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001;
 | 
			
		||||
@@ -23,7 +24,7 @@ export class OrderStateUtils {
 | 
			
		||||
        const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add(
 | 
			
		||||
            orderRelevantState.filledTakerTokenAmount,
 | 
			
		||||
        );
 | 
			
		||||
        const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
 | 
			
		||||
        const availableTakerTokenAmount = signedOrder.takerAssetAmount.minus(unavailableTakerTokenAmount);
 | 
			
		||||
        if (availableTakerTokenAmount.eq(0)) {
 | 
			
		||||
            throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
 | 
			
		||||
        }
 | 
			
		||||
@@ -42,9 +43,9 @@ export class OrderStateUtils {
 | 
			
		||||
                throw new Error(ExchangeContractErrs.InsufficientMakerFeeAllowance);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
 | 
			
		||||
        const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerAssetAmount
 | 
			
		||||
            .dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
 | 
			
		||||
            .dividedBy(signedOrder.makerTokenAmount);
 | 
			
		||||
            .dividedBy(signedOrder.makerAssetAmount);
 | 
			
		||||
        if (
 | 
			
		||||
            orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
 | 
			
		||||
                minFillableTakerTokenAmountWithinNoRoundingErrorRange,
 | 
			
		||||
@@ -62,7 +63,7 @@ export class OrderStateUtils {
 | 
			
		||||
    }
 | 
			
		||||
    public async getOrderStateAsync(signedOrder: SignedOrder): Promise<OrderState> {
 | 
			
		||||
        const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder);
 | 
			
		||||
        const orderHash = getOrderHashHex(signedOrder);
 | 
			
		||||
        const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
        try {
 | 
			
		||||
            OrderStateUtils._validateIfOrderIsValid(signedOrder, orderRelevantState);
 | 
			
		||||
            const orderState: OrderStateValid = {
 | 
			
		||||
@@ -82,22 +83,22 @@ export class OrderStateUtils {
 | 
			
		||||
    }
 | 
			
		||||
    public async getOrderRelevantStateAsync(signedOrder: SignedOrder): Promise<OrderRelevantState> {
 | 
			
		||||
        const zrxTokenAddress = this._orderFilledCancelledFetcher.getZRXTokenAddress();
 | 
			
		||||
        const orderHash = getOrderHashHex(signedOrder);
 | 
			
		||||
        const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
        const makerBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(
 | 
			
		||||
            signedOrder.makerTokenAddress,
 | 
			
		||||
            signedOrder.maker,
 | 
			
		||||
            signedOrder.makerAssetData,
 | 
			
		||||
            signedOrder.makerAddress,
 | 
			
		||||
        );
 | 
			
		||||
        const makerProxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
 | 
			
		||||
            signedOrder.makerTokenAddress,
 | 
			
		||||
            signedOrder.maker,
 | 
			
		||||
            signedOrder.makerAssetData,
 | 
			
		||||
            signedOrder.makerAddress,
 | 
			
		||||
        );
 | 
			
		||||
        const makerFeeBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(
 | 
			
		||||
            zrxTokenAddress,
 | 
			
		||||
            signedOrder.maker,
 | 
			
		||||
            signedOrder.makerAddress,
 | 
			
		||||
        );
 | 
			
		||||
        const makerFeeProxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
 | 
			
		||||
            zrxTokenAddress,
 | 
			
		||||
            signedOrder.maker,
 | 
			
		||||
            signedOrder.makerAddress,
 | 
			
		||||
        );
 | 
			
		||||
        const filledTakerTokenAmount = await this._orderFilledCancelledFetcher.getFilledTakerAmountAsync(orderHash);
 | 
			
		||||
        const cancelledTakerTokenAmount = await this._orderFilledCancelledFetcher.getCancelledTakerAmountAsync(
 | 
			
		||||
@@ -106,8 +107,8 @@ export class OrderStateUtils {
 | 
			
		||||
        const unavailableTakerTokenAmount = await this._orderFilledCancelledFetcher.getUnavailableTakerAmountAsync(
 | 
			
		||||
            orderHash,
 | 
			
		||||
        );
 | 
			
		||||
        const totalMakerTokenAmount = signedOrder.makerTokenAmount;
 | 
			
		||||
        const totalTakerTokenAmount = signedOrder.takerTokenAmount;
 | 
			
		||||
        const totalMakerTokenAmount = signedOrder.makerAssetAmount;
 | 
			
		||||
        const totalTakerTokenAmount = signedOrder.takerAssetAmount;
 | 
			
		||||
        const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount);
 | 
			
		||||
        const remainingMakerTokenAmount = remainingTakerTokenAmount
 | 
			
		||||
            .times(totalMakerTokenAmount)
 | 
			
		||||
@@ -115,7 +116,8 @@ export class OrderStateUtils {
 | 
			
		||||
        const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
 | 
			
		||||
        const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
 | 
			
		||||
 | 
			
		||||
        const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
 | 
			
		||||
        const zrxAssetData = assetProxyUtils.encodeERC20ProxyData(zrxTokenAddress);
 | 
			
		||||
        const isMakerTokenZRX = signedOrder.makerAssetData === zrxAssetData;
 | 
			
		||||
        const remainingFillableCalculator = new RemainingFillableCalculator(
 | 
			
		||||
            signedOrder,
 | 
			
		||||
            isMakerTokenZRX,
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ export class RemainingFillableCalculator {
 | 
			
		||||
        this._remainingMakerTokenAmount = remainingMakerTokenAmount;
 | 
			
		||||
        this._remainingMakerFeeAmount = remainingMakerTokenAmount
 | 
			
		||||
            .times(signedOrder.makerFee)
 | 
			
		||||
            .dividedToIntegerBy(signedOrder.makerTokenAmount);
 | 
			
		||||
            .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
			
		||||
    }
 | 
			
		||||
    public computeRemainingMakerFillable(): BigNumber {
 | 
			
		||||
        if (this._hasSufficientFundsForFeeAndTransferAmount()) {
 | 
			
		||||
@@ -36,8 +36,8 @@ export class RemainingFillableCalculator {
 | 
			
		||||
    }
 | 
			
		||||
    public computeRemainingTakerFillable(): BigNumber {
 | 
			
		||||
        return this.computeRemainingMakerFillable()
 | 
			
		||||
            .times(this._signedOrder.takerTokenAmount)
 | 
			
		||||
            .dividedToIntegerBy(this._signedOrder.makerTokenAmount);
 | 
			
		||||
            .times(this._signedOrder.takerAssetAmount)
 | 
			
		||||
            .dividedToIntegerBy(this._signedOrder.makerAssetAmount);
 | 
			
		||||
    }
 | 
			
		||||
    private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
 | 
			
		||||
        if (this._isMakerTokenZRX) {
 | 
			
		||||
@@ -59,7 +59,7 @@ export class RemainingFillableCalculator {
 | 
			
		||||
    }
 | 
			
		||||
    private _calculatePartiallyFillableMakerTokenAmount(): BigNumber {
 | 
			
		||||
        // Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1
 | 
			
		||||
        const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedBy(this._signedOrder.makerFee);
 | 
			
		||||
        const orderToFeeRatio = this._signedOrder.makerAssetAmount.dividedBy(this._signedOrder.makerFee);
 | 
			
		||||
        // The number of times the maker can fill the order, if each fill only required the transfer of a single
 | 
			
		||||
        // baseUnit of fee tokens.
 | 
			
		||||
        // Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
 | 
			
		||||
@@ -81,10 +81,10 @@ export class RemainingFillableCalculator {
 | 
			
		||||
        // When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
 | 
			
		||||
        // This can result in a RoundingError being thrown by the Exchange Contract.
 | 
			
		||||
        const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
 | 
			
		||||
            .times(this._signedOrder.makerTokenAmount)
 | 
			
		||||
            .times(this._signedOrder.makerAssetAmount)
 | 
			
		||||
            .dividedToIntegerBy(this._signedOrder.makerFee);
 | 
			
		||||
        const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
 | 
			
		||||
            .times(this._signedOrder.makerTokenAmount)
 | 
			
		||||
            .times(this._signedOrder.makerAssetAmount)
 | 
			
		||||
            .dividedToIntegerBy(this._signedOrder.makerFee);
 | 
			
		||||
        const partiallyFillableAmount = BigNumber.min(
 | 
			
		||||
            partiallyFillableMakerTokenAmount,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +1,167 @@
 | 
			
		||||
import { schemas } from '@0xproject/json-schemas';
 | 
			
		||||
import { ECSignature, Provider } from '@0xproject/types';
 | 
			
		||||
import { ECSignature, SignatureType, ValidatorSignature } from '@0xproject/types';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import { Provider } from 'ethereum-types';
 | 
			
		||||
import * as ethUtil from 'ethereumjs-util';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { artifacts } from './artifacts';
 | 
			
		||||
import { assert } from './assert';
 | 
			
		||||
import { OrderError } from './types';
 | 
			
		||||
import { ExchangeContract } from './generated_contract_wrappers/exchange';
 | 
			
		||||
import { IValidatorContract } from './generated_contract_wrappers/i_validator';
 | 
			
		||||
import { IWalletContract } from './generated_contract_wrappers/i_wallet';
 | 
			
		||||
import { MessagePrefixOpts, MessagePrefixType, OrderError } from './types';
 | 
			
		||||
import { utils } from './utils';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Verifies that the elliptic curve signature `signature` was generated
 | 
			
		||||
 * by signing `data` with the private key corresponding to the `signerAddress` address.
 | 
			
		||||
 * Verifies that the provided signature is valid according to the 0x Protocol smart contracts
 | 
			
		||||
 * @param   data          The hex encoded data signed by the supplied signature.
 | 
			
		||||
 * @param   signature     An object containing the elliptic curve signature parameters.
 | 
			
		||||
 * @param   signature     A hex encoded 0x Protocol signature made up of: [TypeSpecificData][SignatureType].
 | 
			
		||||
 *          E.g [vrs][SignatureType.EIP712]
 | 
			
		||||
 * @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 {
 | 
			
		||||
export async function isValidSignatureAsync(
 | 
			
		||||
    provider: Provider,
 | 
			
		||||
    data: string,
 | 
			
		||||
    signature: string,
 | 
			
		||||
    signerAddress: string,
 | 
			
		||||
): Promise<boolean> {
 | 
			
		||||
    const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
 | 
			
		||||
    if (_.isUndefined(signatureTypeIndexIfExists)) {
 | 
			
		||||
        throw new Error(`Unrecognized signatureType in signature: ${signature}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (signatureTypeIndexIfExists) {
 | 
			
		||||
        case SignatureType.Illegal:
 | 
			
		||||
        case SignatureType.Invalid:
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        case SignatureType.EIP712: {
 | 
			
		||||
            const ecSignature = parseECSignature(signature);
 | 
			
		||||
            return isValidECSignature(data, ecSignature, signerAddress);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case SignatureType.EthSign: {
 | 
			
		||||
            const ecSignature = parseECSignature(signature);
 | 
			
		||||
            const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.EthSign);
 | 
			
		||||
            return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case SignatureType.Caller:
 | 
			
		||||
            // HACK: We currently do not "validate" the caller signature type.
 | 
			
		||||
            // It can only be validated during Exchange contract execution.
 | 
			
		||||
            throw new Error('Caller signature type cannot be validated off-chain');
 | 
			
		||||
 | 
			
		||||
        case SignatureType.Wallet: {
 | 
			
		||||
            const isValid = await isValidWalletSignatureAsync(provider, data, signature, signerAddress);
 | 
			
		||||
            return isValid;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case SignatureType.Validator: {
 | 
			
		||||
            const isValid = await isValidValidatorSignatureAsync(provider, data, signature, signerAddress);
 | 
			
		||||
            return isValid;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case SignatureType.PreSigned: {
 | 
			
		||||
            return isValidPresignedSignatureAsync(provider, data, signerAddress);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case SignatureType.Trezor: {
 | 
			
		||||
            const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.Trezor);
 | 
			
		||||
            const ecSignature = parseECSignature(signature);
 | 
			
		||||
            return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(`Unhandled SignatureType: ${signatureTypeIndexIfExists}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Verifies that the provided presigned signature is valid according to the 0x Protocol smart contracts
 | 
			
		||||
 * @param   data          The hex encoded data signed by the supplied signature.
 | 
			
		||||
 * @param   signature     A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
 | 
			
		||||
 * @param   signerAddress The hex encoded address that signed the data, producing the supplied signature.
 | 
			
		||||
 * @return  Whether the data was preSigned by the supplied signerAddress.
 | 
			
		||||
 */
 | 
			
		||||
export async function isValidPresignedSignatureAsync(
 | 
			
		||||
    provider: Provider,
 | 
			
		||||
    data: string,
 | 
			
		||||
    signerAddress: string,
 | 
			
		||||
): Promise<boolean> {
 | 
			
		||||
    const exchangeContract = new ExchangeContract(artifacts.Exchange.abi, signerAddress, provider);
 | 
			
		||||
    const isValid = await exchangeContract.preSigned.callAsync(data, signerAddress);
 | 
			
		||||
    return isValid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Verifies that the provided wallet signature is valid according to the 0x Protocol smart contracts
 | 
			
		||||
 * @param   data          The hex encoded data signed by the supplied signature.
 | 
			
		||||
 * @param   signature     A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
 | 
			
		||||
 * @param   signerAddress The hex encoded address that signed the data, producing the supplied signature.
 | 
			
		||||
 * @return  Whether the data was preSigned by the supplied signerAddress.
 | 
			
		||||
 */
 | 
			
		||||
export async function isValidWalletSignatureAsync(
 | 
			
		||||
    provider: Provider,
 | 
			
		||||
    data: string,
 | 
			
		||||
    signature: string,
 | 
			
		||||
    signerAddress: string,
 | 
			
		||||
): Promise<boolean> {
 | 
			
		||||
    // tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
    const signatureWithoutType = signature.slice(-2);
 | 
			
		||||
    const walletContract = new IWalletContract(artifacts.IWallet.abi, signerAddress, provider);
 | 
			
		||||
    const isValid = await walletContract.isValidSignature.callAsync(data, signatureWithoutType);
 | 
			
		||||
    return isValid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Verifies that the provided validator signature is valid according to the 0x Protocol smart contracts
 | 
			
		||||
 * @param   data          The hex encoded data signed by the supplied signature.
 | 
			
		||||
 * @param   signature     A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
 | 
			
		||||
 * @param   signerAddress The hex encoded address that signed the data, producing the supplied signature.
 | 
			
		||||
 * @return  Whether the data was preSigned by the supplied signerAddress.
 | 
			
		||||
 */
 | 
			
		||||
export async function isValidValidatorSignatureAsync(
 | 
			
		||||
    provider: Provider,
 | 
			
		||||
    data: string,
 | 
			
		||||
    signature: string,
 | 
			
		||||
    signerAddress: string,
 | 
			
		||||
): Promise<boolean> {
 | 
			
		||||
    const validatorSignature = parseValidatorSignature(signature);
 | 
			
		||||
    const exchangeContract = new ExchangeContract(artifacts.Exchange.abi, signerAddress, provider);
 | 
			
		||||
    const isValidatorApproved = await exchangeContract.allowedValidators.callAsync(
 | 
			
		||||
        signerAddress,
 | 
			
		||||
        validatorSignature.validatorAddress,
 | 
			
		||||
    );
 | 
			
		||||
    if (!isValidatorApproved) {
 | 
			
		||||
        throw new Error(`Validator ${validatorSignature.validatorAddress} was not pre-approved by ${signerAddress}.`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const validatorContract = new IValidatorContract(artifacts.IValidator.abi, signerAddress, provider);
 | 
			
		||||
    const isValid = await validatorContract.isValidSignature.callAsync(
 | 
			
		||||
        data,
 | 
			
		||||
        signerAddress,
 | 
			
		||||
        validatorSignature.signature,
 | 
			
		||||
    );
 | 
			
		||||
    return isValid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if the supplied elliptic curve signature corresponds to signing `data` with
 | 
			
		||||
 * the private key corresponding to `signerAddress`
 | 
			
		||||
 * @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 ECSignature is valid.
 | 
			
		||||
 */
 | 
			
		||||
export function isValidECSignature(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);
 | 
			
		||||
    const msgHashBuff = ethUtil.toBuffer(data);
 | 
			
		||||
    try {
 | 
			
		||||
        const pubKey = ethUtil.ecrecover(
 | 
			
		||||
            msgHashBuff,
 | 
			
		||||
@@ -36,23 +175,23 @@ export function isValidSignature(data: string, signature: ECSignature, signerAdd
 | 
			
		||||
        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.
 | 
			
		||||
 * @param   hashPrefixOpts Different signers add/require different prefixes be appended to the message being signed.
 | 
			
		||||
 *          Since we cannot know ahead of time which signer you are using, you must supply both a prefixType and
 | 
			
		||||
 *          whether it must be added before calling `eth_sign` (some signers add it themselves)
 | 
			
		||||
 * @return  An object containing the Elliptic curve signature parameters generated by signing the orderHash.
 | 
			
		||||
 */
 | 
			
		||||
export async function signOrderHashAsync(
 | 
			
		||||
export async function ecSignOrderHashAsync(
 | 
			
		||||
    provider: Provider,
 | 
			
		||||
    orderHash: string,
 | 
			
		||||
    signerAddress: string,
 | 
			
		||||
    shouldAddPersonalMessagePrefix: boolean,
 | 
			
		||||
    messagePrefixOpts: MessagePrefixOpts,
 | 
			
		||||
): Promise<ECSignature> {
 | 
			
		||||
    assert.isHexString('orderHash', orderHash);
 | 
			
		||||
    const web3Wrapper = new Web3Wrapper(provider);
 | 
			
		||||
@@ -60,12 +199,10 @@ export async function signOrderHashAsync(
 | 
			
		||||
    const normalizedSignerAddress = signerAddress.toLowerCase();
 | 
			
		||||
 | 
			
		||||
    let msgHashHex = orderHash;
 | 
			
		||||
    if (shouldAddPersonalMessagePrefix) {
 | 
			
		||||
        const orderHashBuff = ethUtil.toBuffer(orderHash);
 | 
			
		||||
        const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
 | 
			
		||||
        msgHashHex = ethUtil.bufferToHex(msgHashBuff);
 | 
			
		||||
    const prefixedMsgHashHex = addSignedMessagePrefix(orderHash, messagePrefixOpts.prefixType);
 | 
			
		||||
    if (messagePrefixOpts.shouldAddPrefixBeforeCallingEthSign) {
 | 
			
		||||
        msgHashHex = prefixedMsgHashHex;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const signature = await web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHashHex);
 | 
			
		||||
 | 
			
		||||
    // HACK: There is no consensus on whether the signatureHex string should be formatted as
 | 
			
		||||
@@ -76,7 +213,7 @@ export async function signOrderHashAsync(
 | 
			
		||||
    const validVParamValues = [27, 28];
 | 
			
		||||
    const ecSignatureVRS = parseSignatureHexAsVRS(signature);
 | 
			
		||||
    if (_.includes(validVParamValues, ecSignatureVRS.v)) {
 | 
			
		||||
        const isValidVRSSignature = isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress);
 | 
			
		||||
        const isValidVRSSignature = isValidECSignature(prefixedMsgHashHex, ecSignatureVRS, normalizedSignerAddress);
 | 
			
		||||
        if (isValidVRSSignature) {
 | 
			
		||||
            return ecSignatureVRS;
 | 
			
		||||
        }
 | 
			
		||||
@@ -84,7 +221,7 @@ export async function signOrderHashAsync(
 | 
			
		||||
 | 
			
		||||
    const ecSignatureRSV = parseSignatureHexAsRSV(signature);
 | 
			
		||||
    if (_.includes(validVParamValues, ecSignatureRSV.v)) {
 | 
			
		||||
        const isValidRSVSignature = isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress);
 | 
			
		||||
        const isValidRSVSignature = isValidECSignature(prefixedMsgHashHex, ecSignatureRSV, normalizedSignerAddress);
 | 
			
		||||
        if (isValidRSVSignature) {
 | 
			
		||||
            return ecSignatureRSV;
 | 
			
		||||
        }
 | 
			
		||||
@@ -93,6 +230,64 @@ export async function signOrderHashAsync(
 | 
			
		||||
    throw new Error(OrderError.InvalidSignature);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adds the relevant prefix to the message being signed.
 | 
			
		||||
 * @param message Message to sign
 | 
			
		||||
 * @param messagePrefixType The type of message prefix to add. Different signers expect
 | 
			
		||||
 *                          specific message prefixes.
 | 
			
		||||
 * @return Prefixed message
 | 
			
		||||
 */
 | 
			
		||||
export function addSignedMessagePrefix(message: string, messagePrefixType: MessagePrefixType): string {
 | 
			
		||||
    switch (messagePrefixType) {
 | 
			
		||||
        case MessagePrefixType.None:
 | 
			
		||||
            return message;
 | 
			
		||||
 | 
			
		||||
        case MessagePrefixType.EthSign: {
 | 
			
		||||
            const msgBuff = ethUtil.toBuffer(message);
 | 
			
		||||
            const prefixedMsgBuff = ethUtil.hashPersonalMessage(msgBuff);
 | 
			
		||||
            const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
 | 
			
		||||
            return prefixedMsgHex;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case MessagePrefixType.Trezor: {
 | 
			
		||||
            const msgBuff = ethUtil.toBuffer(message);
 | 
			
		||||
            const prefixedMsgBuff = hashTrezorPersonalMessage(msgBuff);
 | 
			
		||||
            const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
 | 
			
		||||
            return prefixedMsgHex;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(`Unrecognized MessagePrefixType: ${messagePrefixType}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function hashTrezorPersonalMessage(message: Buffer): Buffer {
 | 
			
		||||
    const prefix = ethUtil.toBuffer('\x19Ethereum Signed Message:\n' + String.fromCharCode(message.length));
 | 
			
		||||
    return ethUtil.sha3(Buffer.concat([prefix, message]));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parseECSignature(signature: string): ECSignature {
 | 
			
		||||
    const ecSignatureTypes = [SignatureType.EthSign, SignatureType.EIP712, SignatureType.Trezor];
 | 
			
		||||
    assert.isOneOfExpectedSignatureTypes(signature, ecSignatureTypes);
 | 
			
		||||
 | 
			
		||||
    // tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
    const vrsHex = signature.slice(0, -2);
 | 
			
		||||
    const ecSignature = parseSignatureHexAsVRS(vrsHex);
 | 
			
		||||
 | 
			
		||||
    return ecSignature;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parseValidatorSignature(signature: string): ValidatorSignature {
 | 
			
		||||
    assert.isOneOfExpectedSignatureTypes(signature, [SignatureType.Validator]);
 | 
			
		||||
    // tslint:disable:custom-no-magic-numbers
 | 
			
		||||
    const validatorSignature = {
 | 
			
		||||
        validatorAddress: signature.slice(-22, -2),
 | 
			
		||||
        signature: signature.slice(0, -22),
 | 
			
		||||
    };
 | 
			
		||||
    // tslint:enable:custom-no-magic-numbers
 | 
			
		||||
    return validatorSignature;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parseSignatureHexAsVRS(signatureHex: string): ECSignature {
 | 
			
		||||
    const signatureBuffer = ethUtil.toBuffer(signatureHex);
 | 
			
		||||
    let v = signatureBuffer[0];
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,25 @@
 | 
			
		||||
export enum OrderError {
 | 
			
		||||
    InvalidSignature = 'INVALID_SIGNATURE',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The requisite message prefix (is any) to add to an `eth_sign` request.
 | 
			
		||||
 */
 | 
			
		||||
export enum MessagePrefixType {
 | 
			
		||||
    None = 'NONE',
 | 
			
		||||
    EthSign = 'ETH_SIGN',
 | 
			
		||||
    Trezor = 'TREZOR',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Options related to message prefixing of messages sent to `eth_sign`
 | 
			
		||||
 * Some signers prepend a message prefix (e.g Parity Signer, Ledger, TestRPC), while
 | 
			
		||||
 * others require it already be prepended (e.g Metamask). In addition, different signers
 | 
			
		||||
 * expect slightly different prefixes (See: https://github.com/ethereum/go-ethereum/issues/14794).
 | 
			
		||||
 * Depending on the signer that will receive your signing request, you must specify the
 | 
			
		||||
 * desired prefix and whether it should be added before making the `eth_sign` request.
 | 
			
		||||
 */
 | 
			
		||||
export interface MessagePrefixOpts {
 | 
			
		||||
    prefixType: MessagePrefixType;
 | 
			
		||||
    shouldAddPrefixBeforeCallingEthSign: boolean;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								packages/order-utils/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								packages/order-utils/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
export const utils = {
 | 
			
		||||
    getSignatureTypeIndexIfExists(signature: string): number {
 | 
			
		||||
        // tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
        const signatureTypeHex = signature.slice(-2);
 | 
			
		||||
        const base = 16;
 | 
			
		||||
        const signatureTypeInt = parseInt(signatureTypeHex, base);
 | 
			
		||||
        return signatureTypeInt;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@@ -1,10 +1,11 @@
 | 
			
		||||
import { web3Factory } from '@0xproject/dev-utils';
 | 
			
		||||
import { Order } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import 'make-promises-safe';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
 | 
			
		||||
import { constants, getOrderHashHex } from '../src';
 | 
			
		||||
import { constants, orderHashUtils } from '../src';
 | 
			
		||||
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { web3Wrapper } from './utils/web3_wrapper';
 | 
			
		||||
@@ -14,34 +15,50 @@ const expect = chai.expect;
 | 
			
		||||
 | 
			
		||||
describe('Order hashing', () => {
 | 
			
		||||
    describe('#getOrderHashHex', () => {
 | 
			
		||||
        const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
 | 
			
		||||
        const expectedOrderHash = '0x367ad7730eb8b5feab8a9c9f47c6fcba77a2d4df125ee6a59cc26ac955710f7e';
 | 
			
		||||
        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,
 | 
			
		||||
        const order: Order = {
 | 
			
		||||
            makerAddress: constants.NULL_ADDRESS,
 | 
			
		||||
            takerAddress: constants.NULL_ADDRESS,
 | 
			
		||||
            senderAddress: constants.NULL_ADDRESS,
 | 
			
		||||
            feeRecipientAddress: constants.NULL_ADDRESS,
 | 
			
		||||
            makerAssetData: constants.NULL_ADDRESS,
 | 
			
		||||
            takerAssetData: constants.NULL_ADDRESS,
 | 
			
		||||
            exchangeAddress: 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),
 | 
			
		||||
            makerAssetAmount: new BigNumber(0),
 | 
			
		||||
            takerAssetAmount: new BigNumber(0),
 | 
			
		||||
            expirationTimeSeconds: new BigNumber(0),
 | 
			
		||||
        };
 | 
			
		||||
        it('calculates the order hash', async () => {
 | 
			
		||||
            const orderHash = getOrderHashHex(order);
 | 
			
		||||
            const orderHash = orderHashUtils.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,
 | 
			
		||||
                takerAddress: (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);
 | 
			
		||||
            expect(() => orderHashUtils.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#isValidOrderHash', () => {
 | 
			
		||||
        it('returns false if the value is not a hex string', () => {
 | 
			
		||||
            const isValid = orderHashUtils.isValidOrderHash('not a hex');
 | 
			
		||||
            expect(isValid).to.be.false();
 | 
			
		||||
        });
 | 
			
		||||
        it('returns false if the length is wrong', () => {
 | 
			
		||||
            const isValid = orderHashUtils.isValidOrderHash('0xdeadbeef');
 | 
			
		||||
            expect(isValid).to.be.false();
 | 
			
		||||
        });
 | 
			
		||||
        it('returns true if order hash is correct', () => {
 | 
			
		||||
            const orderHashLength = 65;
 | 
			
		||||
            const isValid = orderHashUtils.isValidOrderHash('0x' + Array(orderHashLength).join('0'));
 | 
			
		||||
            expect(isValid).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
import { web3Factory } from '@0xproject/dev-utils';
 | 
			
		||||
import { JSONRPCErrorCallback, JSONRPCRequestPayload } from '@0xproject/types';
 | 
			
		||||
import { BigNumber } from '@0xproject/utils';
 | 
			
		||||
import * as chai from 'chai';
 | 
			
		||||
import { JSONRPCErrorCallback, JSONRPCRequestPayload } from 'ethereum-types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import 'make-promises-safe';
 | 
			
		||||
import 'mocha';
 | 
			
		||||
import * as Sinon from 'sinon';
 | 
			
		||||
 | 
			
		||||
import { generatePseudoRandomSalt, isValidOrderHash, isValidSignature, signOrderHashAsync } from '../src';
 | 
			
		||||
import * as signatureUtils from '../src/signature_utils';
 | 
			
		||||
import { ecSignOrderHashAsync, generatePseudoRandomSalt, MessagePrefixType, orderHashUtils } from '../src';
 | 
			
		||||
import { isValidECSignature, isValidSignatureAsync } from '../src/signature_utils';
 | 
			
		||||
 | 
			
		||||
import { chaiSetup } from './utils/chai_setup';
 | 
			
		||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
 | 
			
		||||
@@ -16,32 +16,82 @@ 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';
 | 
			
		||||
        let dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
 | 
			
		||||
        const ethSignSignature =
 | 
			
		||||
            '0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403';
 | 
			
		||||
        let 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();
 | 
			
		||||
            expect(await isValidSignatureAsync(provider, '0x0', ethSignSignature, 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();
 | 
			
		||||
            expect(
 | 
			
		||||
                await isValidSignatureAsync(provider, dataHex, ethSignSignature, 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();
 | 
			
		||||
            const signatureArray = ethSignSignature.split('');
 | 
			
		||||
            // tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
            signatureArray[5] = 'C'; // V = 28, instead of 27
 | 
			
		||||
            const wrongSignature = signatureArray.join('');
 | 
			
		||||
            expect(await isValidSignatureAsync(provider, 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);
 | 
			
		||||
 | 
			
		||||
        it('should throw if signatureType is invalid', () => {
 | 
			
		||||
            const signatureArray = ethSignSignature.split('');
 | 
			
		||||
            signatureArray[3] = '9'; // SignatureType w/ index 9 doesn't exist
 | 
			
		||||
            const signatureWithInvalidType = signatureArray.join('');
 | 
			
		||||
            expect(isValidSignatureAsync(provider, dataHex, signatureWithInvalidType, address)).to.be.rejected();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should return true for a valid Ecrecover (EthSign) signature', async () => {
 | 
			
		||||
            const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, ethSignSignature, address);
 | 
			
		||||
            expect(isValidSignatureLocal).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should return true for a valid EIP712 signature', async () => {
 | 
			
		||||
            dataHex = '0xa1d7403bcbbcd75ec233cfd6584ff8dabed677d0e9bb32c2bea94e9dd8a109da';
 | 
			
		||||
            address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb';
 | 
			
		||||
            const eip712Signature =
 | 
			
		||||
                '0x1bdde07aac4bf12c12ddbb155919c43eba4146a2cfcf904a862950dbebe332554c6674975603eb5a4eaf8fd7f2e06350267e5b36cda9851a89f8bb49fe2fc9afe202';
 | 
			
		||||
            const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, eip712Signature, address);
 | 
			
		||||
            expect(isValidSignatureLocal).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should return true for a valid Trezor signature', async () => {
 | 
			
		||||
            dataHex = '0xd0d994e31c88f33fd8a572552a70ed339de579e5ba49ee1d17cc978bbe1cdd21';
 | 
			
		||||
            address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb';
 | 
			
		||||
            const trezorSignature =
 | 
			
		||||
                '0x1ce4760660e6495b5ae6723087bea073b3a99ce98ea81fdf00c240279c010e63d05b87bc34c4d67d4776e8d5aeb023a67484f4eaf0fd353b40893e5101e845cd9908';
 | 
			
		||||
            const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, trezorSignature, address);
 | 
			
		||||
            expect(isValidSignatureLocal).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#isValidECSignature', () => {
 | 
			
		||||
        const signature = {
 | 
			
		||||
            v: 27,
 | 
			
		||||
            r: '0xaca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d64393',
 | 
			
		||||
            s: '0x46b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf2',
 | 
			
		||||
        };
 | 
			
		||||
        const data = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad';
 | 
			
		||||
        const address = '0x0e5cb767cce09a7f3ca594df118aa519be5e2b5a';
 | 
			
		||||
 | 
			
		||||
        it("should return false if the data doesn't pertain to the signature & address", async () => {
 | 
			
		||||
            expect(isValidECSignature('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(isValidECSignature(data, signature, validUnrelatedAddress)).to.be.false();
 | 
			
		||||
        });
 | 
			
		||||
        it("should return false if the signature doesn't pertain to the data & address", async () => {
 | 
			
		||||
            const wrongSignature = _.assign({}, signature, { v: 28 });
 | 
			
		||||
            expect(isValidECSignature(data, wrongSignature, address)).to.be.false();
 | 
			
		||||
        });
 | 
			
		||||
        it('should return true if the signature does pertain to the data & address', async () => {
 | 
			
		||||
            const isValidSignatureLocal = isValidECSignature(data, signature, address);
 | 
			
		||||
            expect(isValidSignatureLocal).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
@@ -58,22 +108,7 @@ describe('Signature utils', () => {
 | 
			
		||||
            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 orderHashLength = 65;
 | 
			
		||||
            const isValid = isValidOrderHash('0x' + Array(orderHashLength).join('0'));
 | 
			
		||||
            expect(isValid).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#signOrderHashAsync', () => {
 | 
			
		||||
    describe('#ecSignOrderHashAsync', () => {
 | 
			
		||||
        let stubs: Sinon.SinonStub[] = [];
 | 
			
		||||
        let makerAddress: string;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
@@ -92,12 +127,11 @@ describe('Signature utils', () => {
 | 
			
		||||
                r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
 | 
			
		||||
                s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
 | 
			
		||||
            };
 | 
			
		||||
            const ecSignature = await signOrderHashAsync(
 | 
			
		||||
                provider,
 | 
			
		||||
                orderHash,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
			
		||||
            );
 | 
			
		||||
            const messagePrefixOpts = {
 | 
			
		||||
                prefixType: MessagePrefixType.EthSign,
 | 
			
		||||
                shouldAddPrefixBeforeCallingEthSign: false,
 | 
			
		||||
            };
 | 
			
		||||
            const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, messagePrefixOpts);
 | 
			
		||||
            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
 | 
			
		||||
@@ -126,12 +160,11 @@ describe('Signature utils', () => {
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const ecSignature = await signOrderHashAsync(
 | 
			
		||||
                fakeProvider,
 | 
			
		||||
                orderHash,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
			
		||||
            );
 | 
			
		||||
            const messagePrefixOpts = {
 | 
			
		||||
                prefixType: MessagePrefixType.EthSign,
 | 
			
		||||
                shouldAddPrefixBeforeCallingEthSign: false,
 | 
			
		||||
            };
 | 
			
		||||
            const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts);
 | 
			
		||||
            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
 | 
			
		||||
@@ -157,12 +190,11 @@ describe('Signature utils', () => {
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const ecSignature = await signOrderHashAsync(
 | 
			
		||||
                fakeProvider,
 | 
			
		||||
                orderHash,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
 | 
			
		||||
            );
 | 
			
		||||
            const messagePrefixOpts = {
 | 
			
		||||
                prefixType: MessagePrefixType.EthSign,
 | 
			
		||||
                shouldAddPrefixBeforeCallingEthSign: false,
 | 
			
		||||
            };
 | 
			
		||||
            const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts);
 | 
			
		||||
            expect(ecSignature).to.deep.equal(expectedECSignature);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import { devConstants, web3Factory } from '@0xproject/dev-utils';
 | 
			
		||||
import { Provider } from '@0xproject/types';
 | 
			
		||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
 | 
			
		||||
import { Provider } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
 | 
			
		||||
const web3Wrapper = new Web3Wrapper(provider);
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@
 | 
			
		||||
        "@0xproject/contract-wrappers": "^0.0.2",
 | 
			
		||||
        "@0xproject/fill-scenarios": "^0.0.2",
 | 
			
		||||
        "@0xproject/json-schemas": "0.7.22",
 | 
			
		||||
        "@0xproject/order-utils": "^0.0.5",
 | 
			
		||||
        "@0xproject/order-utils": "0.0.5",
 | 
			
		||||
        "@0xproject/types": "0.7.0",
 | 
			
		||||
        "@0xproject/typescript-typings": "^0.3.2",
 | 
			
		||||
        "@0xproject/utils": "^0.6.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0xproject/assert": "^0.2.10",
 | 
			
		||||
        "@0xproject/types": "0.7.0",
 | 
			
		||||
        "@0xproject/order-utils": "^0.0.5",
 | 
			
		||||
        "@0xproject/order-utils": "0.0.5",
 | 
			
		||||
        "@0xproject/connect": "0.6.12",
 | 
			
		||||
        "@0xproject/json-schemas": "0.7.22",
 | 
			
		||||
        "@0xproject/typescript-typings": "^0.3.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0xproject/types",
 | 
			
		||||
    "version": "0.7.1",
 | 
			
		||||
    "version": "1.0.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,26 @@
 | 
			
		||||
import { BigNumber } from 'bignumber.js';
 | 
			
		||||
import { ContractAbi, DecodedLogArgs, LogEntry, LogWithDecodedArgs, TransactionReceipt } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
// HACK: Rather then extending from OrderWithoutExchangeAddress
 | 
			
		||||
// we don't, because our docs don't expand inherited types, and it's unnecessarily
 | 
			
		||||
// confusing to introduce the user to the OrderWithoutExchangeAddress type.
 | 
			
		||||
export interface Order {
 | 
			
		||||
    senderAddress: string;
 | 
			
		||||
    makerAddress: string;
 | 
			
		||||
    takerAddress: string;
 | 
			
		||||
    makerFee: BigNumber;
 | 
			
		||||
    takerFee: BigNumber;
 | 
			
		||||
    makerAssetAmount: BigNumber;
 | 
			
		||||
    takerAssetAmount: BigNumber;
 | 
			
		||||
    makerAssetData: string;
 | 
			
		||||
    takerAssetData: string;
 | 
			
		||||
    salt: BigNumber;
 | 
			
		||||
    exchangeAddress: string;
 | 
			
		||||
    feeRecipientAddress: string;
 | 
			
		||||
    expirationTimeSeconds: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface OrderWithoutExchangeAddress {
 | 
			
		||||
    senderAddress: string;
 | 
			
		||||
    makerAddress: string;
 | 
			
		||||
    takerAddress: string;
 | 
			
		||||
@@ -16,14 +35,10 @@ export interface Order {
 | 
			
		||||
    expirationTimeSeconds: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface SignedOrder extends UnsignedOrder {
 | 
			
		||||
export interface SignedOrder extends Order {
 | 
			
		||||
    signature: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface UnsignedOrder extends Order {
 | 
			
		||||
    exchangeAddress: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Elliptic Curve signature
 | 
			
		||||
 */
 | 
			
		||||
@@ -33,6 +48,14 @@ export interface ECSignature {
 | 
			
		||||
    s: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validator signature components
 | 
			
		||||
 */
 | 
			
		||||
export interface ValidatorSignature {
 | 
			
		||||
    validatorAddress: string;
 | 
			
		||||
    signature: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Errors originating from the 0x exchange contract
 | 
			
		||||
 */
 | 
			
		||||
@@ -106,3 +129,47 @@ export interface Token {
 | 
			
		||||
    symbol: string;
 | 
			
		||||
    decimals: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum SignatureType {
 | 
			
		||||
    Illegal,
 | 
			
		||||
    Invalid,
 | 
			
		||||
    EIP712,
 | 
			
		||||
    EthSign,
 | 
			
		||||
    Caller,
 | 
			
		||||
    Wallet,
 | 
			
		||||
    Validator,
 | 
			
		||||
    PreSigned,
 | 
			
		||||
    Trezor,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Elliptic Curve signature
 | 
			
		||||
 */
 | 
			
		||||
export interface ECSignature {
 | 
			
		||||
    v: number;
 | 
			
		||||
    r: string;
 | 
			
		||||
    s: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum AssetProxyId {
 | 
			
		||||
    INVALID,
 | 
			
		||||
    ERC20,
 | 
			
		||||
    ERC721,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ERC20ProxyData {
 | 
			
		||||
    assetProxyId: AssetProxyId;
 | 
			
		||||
    tokenAddress: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ERC721ProxyData {
 | 
			
		||||
    assetProxyId: AssetProxyId;
 | 
			
		||||
    tokenAddress: string;
 | 
			
		||||
    tokenId: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ProxyData {
 | 
			
		||||
    assetProxyId: AssetProxyId;
 | 
			
		||||
    tokenAddress?: string;
 | 
			
		||||
    data?: any;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -29,7 +29,32 @@
 | 
			
		||||
    jsonschema "^1.2.0"
 | 
			
		||||
    lodash.values "^4.3.0"
 | 
			
		||||
 | 
			
		||||
"@0xproject/types@0.7.0":
 | 
			
		||||
"@0xproject/json-schemas@^0.7.23", "@0xproject/json-schemas@^0.7.24":
 | 
			
		||||
  version "0.7.24"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@0xproject/json-schemas/-/json-schemas-0.7.24.tgz#21a12b43ab0ab4aa302d02c4891668cda36b6c64"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@0xproject/typescript-typings" "^0.3.2"
 | 
			
		||||
    "@types/node" "^8.0.53"
 | 
			
		||||
    jsonschema "^1.2.0"
 | 
			
		||||
    lodash.values "^4.3.0"
 | 
			
		||||
 | 
			
		||||
"@0xproject/order-utils@0.0.5":
 | 
			
		||||
  version "0.0.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@0xproject/order-utils/-/order-utils-0.0.5.tgz#c8d92a112740b0020e08f13137844f8c183c863b"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@0xproject/assert" "^0.2.10"
 | 
			
		||||
    "@0xproject/json-schemas" "^0.7.24"
 | 
			
		||||
    "@0xproject/types" "^0.7.0"
 | 
			
		||||
    "@0xproject/typescript-typings" "^0.3.2"
 | 
			
		||||
    "@0xproject/utils" "^0.6.2"
 | 
			
		||||
    "@0xproject/web3-wrapper" "^0.6.4"
 | 
			
		||||
    "@types/node" "^8.0.53"
 | 
			
		||||
    bn.js "^4.11.8"
 | 
			
		||||
    ethereumjs-abi "^0.6.4"
 | 
			
		||||
    ethereumjs-util "^5.1.1"
 | 
			
		||||
    lodash "^4.17.4"
 | 
			
		||||
 | 
			
		||||
"@0xproject/types@0.7.0", "@0xproject/types@^0.7.0":
 | 
			
		||||
  version "0.7.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@0xproject/types/-/types-0.7.0.tgz#fad13925ee92ad4ee1980668a5cb2bed4dcaab8f"
 | 
			
		||||
  dependencies:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user