aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website')
-rw-r--r--packages/website/package.json10
-rw-r--r--packages/website/ts/artifacts/Exchange.json610
-rw-r--r--packages/website/ts/blockchain.ts197
-rw-r--r--packages/website/ts/components/fill_order.tsx111
-rw-r--r--packages/website/ts/components/fill_order_json.tsx6
-rw-r--r--packages/website/ts/components/generate_order/generate_order_form.tsx53
-rw-r--r--packages/website/ts/components/inputs/hash_input.tsx28
-rw-r--r--packages/website/ts/components/order_json.tsx6
-rw-r--r--packages/website/ts/components/portal/portal.tsx8
-rw-r--r--packages/website/ts/containers/generate_order_form.ts4
-rw-r--r--packages/website/ts/containers/portal.ts4
-rw-r--r--packages/website/ts/redux/dispatcher.ts10
-rw-r--r--packages/website/ts/redux/reducer.ts17
-rw-r--r--packages/website/ts/schemas/portal_order_schema.ts2
-rw-r--r--packages/website/ts/types.ts22
-rw-r--r--packages/website/ts/utils/analytics.ts17
-rw-r--r--packages/website/ts/utils/order_parser.ts50
-rw-r--r--packages/website/ts/utils/utils.ts61
18 files changed, 305 insertions, 911 deletions
diff --git a/packages/website/package.json b/packages/website/package.json
index 878544d27..4c6299a4f 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -18,13 +18,14 @@
"author": "Fabio Berger",
"license": "Apache-2.0",
"dependencies": {
- "@0xproject/contract-wrappers": "^0.0.5",
- "@0xproject/order-utils": "^0.0.9",
+ "0x.js": "^0.38.6",
+ "@0xproject/contract-wrappers": "^1.0.1-rc.5",
+ "@0xproject/order-utils": "^1.0.1-rc.6",
"@0xproject/react-docs": "^1.0.7",
"@0xproject/react-shared": "^1.0.8",
"@0xproject/subproviders": "^2.0.1",
- "@0xproject/types": "^0.8.1",
- "@0xproject/typescript-typings": "^0.4.3",
+ "@0xproject/types": "^1.0.1-rc.6",
+ "@0xproject/typescript-typings": "^1.0.5",
"@0xproject/utils": "^1.0.7",
"@0xproject/web3-wrapper": "^2.0.1",
"accounting": "^0.4.1",
@@ -32,6 +33,7 @@
"blockies": "^0.0.2",
"bowser": "^1.9.3",
"deep-equal": "^1.0.1",
+ "ethereum-types": "^1.0.5",
"ethereumjs-util": "^5.1.1",
"find-versions": "^2.0.0",
"jsonschema": "^1.2.0",
diff --git a/packages/website/ts/artifacts/Exchange.json b/packages/website/ts/artifacts/Exchange.json
deleted file mode 100644
index af8db7360..000000000
--- a/packages/website/ts/artifacts/Exchange.json
+++ /dev/null
@@ -1,610 +0,0 @@
-{
- "contract_name": "Exchange",
- "abi": [
- {
- "constant": true,
- "inputs": [
- {
- "name": "numerator",
- "type": "uint256"
- },
- {
- "name": "denominator",
- "type": "uint256"
- },
- {
- "name": "target",
- "type": "uint256"
- }
- ],
- "name": "isRoundingError",
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [
- {
- "name": "",
- "type": "bytes32"
- }
- ],
- "name": "filled",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [
- {
- "name": "",
- "type": "bytes32"
- }
- ],
- "name": "cancelled",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5][]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6][]"
- },
- {
- "name": "fillTakerTokenAmount",
- "type": "uint256"
- },
- {
- "name": "shouldThrowOnInsufficientBalanceOrAllowance",
- "type": "bool"
- },
- {
- "name": "v",
- "type": "uint8[]"
- },
- {
- "name": "r",
- "type": "bytes32[]"
- },
- {
- "name": "s",
- "type": "bytes32[]"
- }
- ],
- "name": "fillOrdersUpTo",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6]"
- },
- {
- "name": "cancelTakerTokenAmount",
- "type": "uint256"
- }
- ],
- "name": "cancelOrder",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "ZRX_TOKEN_CONTRACT",
- "outputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5][]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6][]"
- },
- {
- "name": "fillTakerTokenAmounts",
- "type": "uint256[]"
- },
- {
- "name": "v",
- "type": "uint8[]"
- },
- {
- "name": "r",
- "type": "bytes32[]"
- },
- {
- "name": "s",
- "type": "bytes32[]"
- }
- ],
- "name": "batchFillOrKillOrders",
- "outputs": [],
- "payable": false,
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6]"
- },
- {
- "name": "fillTakerTokenAmount",
- "type": "uint256"
- },
- {
- "name": "v",
- "type": "uint8"
- },
- {
- "name": "r",
- "type": "bytes32"
- },
- {
- "name": "s",
- "type": "bytes32"
- }
- ],
- "name": "fillOrKillOrder",
- "outputs": [],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [
- {
- "name": "orderHash",
- "type": "bytes32"
- }
- ],
- "name": "getUnavailableTakerTokenAmount",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [
- {
- "name": "signer",
- "type": "address"
- },
- {
- "name": "hash",
- "type": "bytes32"
- },
- {
- "name": "v",
- "type": "uint8"
- },
- {
- "name": "r",
- "type": "bytes32"
- },
- {
- "name": "s",
- "type": "bytes32"
- }
- ],
- "name": "isValidSignature",
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [
- {
- "name": "numerator",
- "type": "uint256"
- },
- {
- "name": "denominator",
- "type": "uint256"
- },
- {
- "name": "target",
- "type": "uint256"
- }
- ],
- "name": "getPartialAmount",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "TOKEN_TRANSFER_PROXY_CONTRACT",
- "outputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5][]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6][]"
- },
- {
- "name": "fillTakerTokenAmounts",
- "type": "uint256[]"
- },
- {
- "name": "shouldThrowOnInsufficientBalanceOrAllowance",
- "type": "bool"
- },
- {
- "name": "v",
- "type": "uint8[]"
- },
- {
- "name": "r",
- "type": "bytes32[]"
- },
- {
- "name": "s",
- "type": "bytes32[]"
- }
- ],
- "name": "batchFillOrders",
- "outputs": [],
- "payable": false,
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5][]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6][]"
- },
- {
- "name": "cancelTakerTokenAmounts",
- "type": "uint256[]"
- }
- ],
- "name": "batchCancelOrders",
- "outputs": [],
- "payable": false,
- "type": "function"
- },
- {
- "constant": false,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6]"
- },
- {
- "name": "fillTakerTokenAmount",
- "type": "uint256"
- },
- {
- "name": "shouldThrowOnInsufficientBalanceOrAllowance",
- "type": "bool"
- },
- {
- "name": "v",
- "type": "uint8"
- },
- {
- "name": "r",
- "type": "bytes32"
- },
- {
- "name": "s",
- "type": "bytes32"
- }
- ],
- "name": "fillOrder",
- "outputs": [
- {
- "name": "filledTakerTokenAmount",
- "type": "uint256"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [
- {
- "name": "orderAddresses",
- "type": "address[5]"
- },
- {
- "name": "orderValues",
- "type": "uint256[6]"
- }
- ],
- "name": "getOrderHash",
- "outputs": [
- {
- "name": "",
- "type": "bytes32"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "EXTERNAL_QUERY_GAS_LIMIT",
- "outputs": [
- {
- "name": "",
- "type": "uint16"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "VERSION",
- "outputs": [
- {
- "name": "",
- "type": "string"
- }
- ],
- "payable": false,
- "type": "function"
- },
- {
- "inputs": [
- {
- "name": "_zrxToken",
- "type": "address"
- },
- {
- "name": "_tokenTransferProxy",
- "type": "address"
- }
- ],
- "payable": false,
- "type": "constructor"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "maker",
- "type": "address"
- },
- {
- "indexed": false,
- "name": "taker",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "feeRecipient",
- "type": "address"
- },
- {
- "indexed": false,
- "name": "makerToken",
- "type": "address"
- },
- {
- "indexed": false,
- "name": "takerToken",
- "type": "address"
- },
- {
- "indexed": false,
- "name": "filledMakerTokenAmount",
- "type": "uint256"
- },
- {
- "indexed": false,
- "name": "filledTakerTokenAmount",
- "type": "uint256"
- },
- {
- "indexed": false,
- "name": "paidMakerFee",
- "type": "uint256"
- },
- {
- "indexed": false,
- "name": "paidTakerFee",
- "type": "uint256"
- },
- {
- "indexed": true,
- "name": "tokens",
- "type": "bytes32"
- },
- {
- "indexed": false,
- "name": "orderHash",
- "type": "bytes32"
- }
- ],
- "name": "LogFill",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "maker",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "feeRecipient",
- "type": "address"
- },
- {
- "indexed": false,
- "name": "makerToken",
- "type": "address"
- },
- {
- "indexed": false,
- "name": "takerToken",
- "type": "address"
- },
- {
- "indexed": false,
- "name": "cancelledMakerTokenAmount",
- "type": "uint256"
- },
- {
- "indexed": false,
- "name": "cancelledTakerTokenAmount",
- "type": "uint256"
- },
- {
- "indexed": true,
- "name": "tokens",
- "type": "bytes32"
- },
- {
- "indexed": false,
- "name": "orderHash",
- "type": "bytes32"
- }
- ],
- "name": "LogCancel",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "errorId",
- "type": "uint8"
- },
- {
- "indexed": true,
- "name": "orderHash",
- "type": "bytes32"
- }
- ],
- "name": "LogError",
- "type": "event"
- }
- ],
- "networks": {
- "1": {
- "address": "0x12459c951127e0c374ff9105dda097662a027093"
- },
- "3": {
- "address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac"
- },
- "4": {
- "address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05"
- },
- "42": {
- "address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364"
- },
- "50": {
- "address": "0x48bacb9266a570d521063ef5dd96e61686dbe788"
- }
- }
-}
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index 45994be5f..b97d86e99 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -1,15 +1,15 @@
+import { ZeroEx } from '0x.js';
import {
BlockRange,
ContractWrappers,
DecodedLogEvent,
- ExchangeContractEventArgs,
+ ExchangeCancelEventArgs,
+ ExchangeEventArgs,
ExchangeEvents,
+ ExchangeFillEventArgs,
IndexedFilterValues,
- LogCancelContractEventArgs,
- LogFillContractEventArgs,
- Token as ZeroExToken,
} from '@0xproject/contract-wrappers';
-import { isValidOrderHash, signOrderHashAsync } from '@0xproject/order-utils';
+import { assetDataUtils, orderHashUtils, signatureUtils, SignerType } from '@0xproject/order-utils';
import { EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared';
import {
ledgerEthereumBrowserClientFactoryAsync,
@@ -19,21 +19,15 @@ import {
SignerSubprovider,
Web3ProviderEngine,
} from '@0xproject/subproviders';
-import {
- BlockParam,
- ECSignature,
- LogWithDecodedArgs,
- Order,
- Provider,
- SignedOrder,
- TransactionReceiptWithDecodedLogs,
-} from '@0xproject/types';
+import { ECSignature, Order, SignedOrder, Token as ZeroExToken } from '@0xproject/types';
import { BigNumber, intervalUtils, logUtils, promisify } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import { BlockParam, LogWithDecodedArgs, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash';
import * as moment from 'moment';
import * as React from 'react';
import contract = require('truffle-contract');
+
import { BlockchainWatcher } from 'ts/blockchain_watcher';
import { AssetSendCompleted } from 'ts/components/flash_messages/asset_send_completed';
import { TransactionSubmitted } from 'ts/components/flash_messages/transaction_submitted';
@@ -48,7 +42,7 @@ import {
InjectedProviderObservable,
InjectedProviderUpdate,
InjectedWeb3,
- Order as PortalOrder,
+ PortalOrder,
Providers,
ProviderType,
Side,
@@ -65,9 +59,6 @@ import FilterSubprovider = require('web3-provider-engine/subproviders/filters');
import * as MintableArtifacts from '../contracts/Mintable.json';
-// HACK: remove this hard-coded abi and use @0xproject/contract-wrappers
-import * as Exchange from './artifacts/Exchange.json';
-
const BLOCK_NUMBER_BACK_TRACK = 50;
const GWEI_IN_WEI = 1000000000;
@@ -83,6 +74,7 @@ export class Blockchain {
public networkId: number;
public nodeVersion: string;
private _contractWrappers: ContractWrappers;
+ private _zeroEx: ZeroEx;
private readonly _dispatcher: Dispatcher;
private _web3Wrapper?: Web3Wrapper;
private _blockchainWatcher?: BlockchainWatcher;
@@ -230,8 +222,8 @@ export class Blockchain {
}
}
public async isAddressInTokenRegistryAsync(tokenAddress: string): Promise<boolean> {
- utils.assert(!_.isUndefined(this._contractWrappers), 'Contract Wrappers must be instantiated.');
- const tokenIfExists = await this._contractWrappers.tokenRegistry.getTokenIfExistsAsync(tokenAddress);
+ utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+ const tokenIfExists = await this._zeroEx.tokenRegistry.getTokenIfExistsAsync(tokenAddress);
return !_.isUndefined(tokenIfExists);
}
public getLedgerDerivationPathIfExists(): string {
@@ -266,7 +258,7 @@ export class Blockchain {
utils.assert(!_.isUndefined(this._contractWrappers), 'Contract Wrappers must be instantiated.');
this._showFlashMessageIfLedger();
- const txHash = await this._contractWrappers.token.setProxyAllowanceAsync(
+ const txHash = await this._contractWrappers.erc20Token.setProxyAllowanceAsync(
token.address,
this._userAddressIfExists,
amountInBaseUnits,
@@ -307,7 +299,7 @@ export class Blockchain {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
this._showFlashMessageIfLedger();
- const txHash = await this._contractWrappers.token.transferAsync(
+ const txHash = await this._contractWrappers.erc20Token.transferAsync(
token.address,
this._userAddressIfExists,
toAddress,
@@ -332,66 +324,41 @@ export class Blockchain {
}),
);
}
- public portalOrderToZeroExOrder(portalOrder: PortalOrder): SignedOrder {
- const exchangeContractAddress = this.getExchangeContractAddressIfExists();
- const zeroExSignedOrder = {
- exchangeContractAddress,
- maker: portalOrder.signedOrder.maker,
- taker: portalOrder.signedOrder.taker,
- makerTokenAddress: portalOrder.signedOrder.makerTokenAddress,
- takerTokenAddress: portalOrder.signedOrder.takerTokenAddress,
- makerTokenAmount: new BigNumber(portalOrder.signedOrder.makerTokenAmount),
- takerTokenAmount: new BigNumber(portalOrder.signedOrder.takerTokenAmount),
- makerFee: new BigNumber(portalOrder.signedOrder.makerFee),
- takerFee: new BigNumber(portalOrder.signedOrder.takerFee),
- expirationUnixTimestampSec: new BigNumber(portalOrder.signedOrder.expirationUnixTimestampSec),
- feeRecipient: portalOrder.signedOrder.feeRecipient,
- ecSignature: portalOrder.signedOrder.ecSignature,
- salt: new BigNumber(portalOrder.signedOrder.salt),
- };
- return zeroExSignedOrder;
- }
public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber): Promise<BigNumber> {
utils.assert(!_.isUndefined(this._contractWrappers), 'ContractWrappers must be instantiated.');
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
-
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
-
this._showFlashMessageIfLedger();
const txHash = await this._contractWrappers.exchange.fillOrderAsync(
signedOrder,
fillTakerTokenAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
this._userAddressIfExists,
{
gasPrice: this._defaultGasPrice,
},
);
const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
- const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
- this._contractWrappers.exchange.throwLogErrorsAsErrors(logs);
- const logFill = _.find(logs, { event: 'LogFill' });
- const args = (logFill.args as any) as LogFillContractEventArgs;
- const filledTakerTokenAmount = args.filledTakerTokenAmount;
- return filledTakerTokenAmount;
- }
- public async cancelOrderAsync(signedOrder: SignedOrder, cancelTakerTokenAmount: BigNumber): Promise<BigNumber> {
+ const logs: Array<LogWithDecodedArgs<ExchangeEventArgs>> = receipt.logs as any;
+ const logFill = _.find(logs, { event: ExchangeEvents.Fill });
+ const args = (logFill.args as any) as ExchangeFillEventArgs;
+ const takerAssetFilledAmount = args.takerAssetFilledAmount;
+ return takerAssetFilledAmount;
+ }
+ public async cancelOrderAsync(signedOrder: SignedOrder): Promise<string> {
this._showFlashMessageIfLedger();
- const txHash = await this._contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelTakerTokenAmount, {
+ const txHash = await this._contractWrappers.exchange.cancelOrderAsync(signedOrder, {
gasPrice: this._defaultGasPrice,
});
const receipt = await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
- const logs: Array<LogWithDecodedArgs<ExchangeContractEventArgs>> = receipt.logs as any;
- this._contractWrappers.exchange.throwLogErrorsAsErrors(logs);
- const logCancel = _.find(logs, { event: ExchangeEvents.LogCancel });
- const args = (logCancel.args as any) as LogCancelContractEventArgs;
- const cancelledTakerTokenAmount = args.cancelledTakerTokenAmount;
- return cancelledTakerTokenAmount;
+ const logs: Array<LogWithDecodedArgs<ExchangeEventArgs>> = receipt.logs as any;
+ const logCancel = _.find(logs, { event: ExchangeEvents.Cancel });
+ const args = (logCancel.args as any) as ExchangeCancelEventArgs;
+ const cancelledOrderHash = args.orderHash;
+ return cancelledOrderHash;
}
public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
- utils.assert(isValidOrderHash(orderHash), 'Must be valid orderHash');
+ utils.assert(orderHashUtils.isValidOrderHash(orderHash), 'Must be valid orderHash');
utils.assert(!_.isUndefined(this._contractWrappers), 'ContractWrappers must be instantiated.');
- const unavailableTakerAmount = await this._contractWrappers.exchange.getUnavailableTakerAmountAsync(orderHash);
+ const unavailableTakerAmount = await this._contractWrappers.exchange.getFilledTakerAssetAmountAsync(orderHash);
return unavailableTakerAmount;
}
public getExchangeContractAddressIfExists(): string | undefined {
@@ -402,22 +369,27 @@ export class Blockchain {
fillTakerTokenAmount: BigNumber,
takerAddress: string,
): Promise<void> {
- await this._contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder,
- fillTakerTokenAmount,
- takerAddress,
- );
- }
- public async validateCancelOrderThrowIfInvalidAsync(
- order: Order,
- cancelTakerTokenAmount: BigNumber,
- ): Promise<void> {
- await this._contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(order, cancelTakerTokenAmount);
+ // TODO: add validation here
+ // we can use OrderValidationUtils here?
+ // await this._contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
+ // signedOrder,
+ // fillTakerTokenAmount,
+ // takerAddress,
+ // );
}
public isValidAddress(address: string): boolean {
const lowercaseAddress = address.toLowerCase();
return Web3Wrapper.isAddress(lowercaseAddress);
}
+ public async isValidSignatureAsync(data: string, signature: string, signerAddress: string): Promise<boolean> {
+ const result = await signatureUtils.isValidSignatureAsync(
+ this._contractWrappers.getProvider(),
+ data,
+ signature,
+ signerAddress,
+ );
+ return result;
+ }
public async pollTokenBalanceAsync(token: Token): Promise<BigNumber> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
@@ -446,7 +418,7 @@ export class Blockchain {
return newTokenBalancePromise;
}
- public async signOrderHashAsync(orderHash: string): Promise<ECSignature> {
+ public async signOrderHashAsync(orderHash: string): Promise<string> {
utils.assert(!_.isUndefined(this._contractWrappers), 'ContractWrappers must be instantiated.');
const makerAddress = this._userAddressIfExists;
// If makerAddress is undefined, this means they have a web3 instance injected into their browser
@@ -454,20 +426,25 @@ export class Blockchain {
if (_.isUndefined(makerAddress)) {
throw new Error('Tried to send a sign request but user has no associated addresses');
}
-
this._showFlashMessageIfLedger();
- const nodeVersion = await this._web3Wrapper.getNodeVersionAsync();
- const isParityNode = utils.isParityNode(nodeVersion);
- const isTestRpc = utils.isTestRpc(nodeVersion);
- const isLedgerSigner = !_.isUndefined(this._ledgerSubprovider);
- let shouldAddPersonalMessagePrefix = true;
- if ((isParityNode && !isLedgerSigner) || isTestRpc || isLedgerSigner) {
- shouldAddPersonalMessagePrefix = false;
- }
const provider = this._contractWrappers.getProvider();
- const ecSignature = await signOrderHashAsync(provider, orderHash, makerAddress, shouldAddPersonalMessagePrefix);
- this._dispatcher.updateECSignature(ecSignature);
- return ecSignature;
+ const isLedgerSigner = !_.isUndefined(this._ledgerSubprovider);
+ const injectedProvider = Blockchain._getInjectedWeb3().currentProvider;
+ const isMetaMaskSigner = utils.getProviderType(injectedProvider) === Providers.Metamask;
+ let signerType = SignerType.Default;
+ if (isLedgerSigner) {
+ signerType = SignerType.Ledger;
+ } else if (isMetaMaskSigner) {
+ signerType = SignerType.Metamask;
+ }
+ const ecSignatureString = await signatureUtils.ecSignOrderHashAsync(
+ provider,
+ orderHash,
+ makerAddress,
+ signerType,
+ );
+ this._dispatcher.updateSignature(ecSignatureString);
+ return ecSignatureString;
}
public async mintTestTokensAsync(token: Token): Promise<void> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
@@ -540,8 +517,8 @@ export class Blockchain {
let allowance = new BigNumber(0);
if (this._doesUserAddressExist()) {
[balance, allowance] = await Promise.all([
- this._contractWrappers.token.getBalanceAsync(tokenAddress, ownerAddressIfExists),
- this._contractWrappers.token.getProxyAllowanceAsync(tokenAddress, ownerAddressIfExists),
+ this._contractWrappers.erc20Token.getBalanceAsync(tokenAddress, ownerAddressIfExists),
+ this._contractWrappers.erc20Token.getProxyAllowanceAsync(tokenAddress, ownerAddressIfExists),
]);
}
return [balance, allowance];
@@ -653,8 +630,7 @@ export class Blockchain {
);
const provider = this._contractWrappers.getProvider();
const web3Wrapper = new Web3Wrapper(provider);
- // HACK: remove this hard-coded abi and use @0xproject/contract-wrappers
- const exchangeAbi = _.get(Exchange, 'abi', []);
+ const exchangeAbi = this._contractWrappers.exchange.abi;
web3Wrapper.abiDecoder.addABI(exchangeAbi);
const receipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
return receipt;
@@ -699,9 +675,9 @@ export class Blockchain {
// Start a subscription for new logs
this._contractWrappers.exchange.subscribe(
- ExchangeEvents.LogFill,
+ ExchangeEvents.Fill,
indexFilterValues,
- async (err: Error, decodedLogEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ async (err: Error, decodedLogEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
if (err) {
// Note: it's not entirely clear from the documentation which
// errors will be thrown by `watch`. For now, let's log the error
@@ -732,8 +708,8 @@ export class Blockchain {
fromBlock,
toBlock: 'latest' as BlockParam,
};
- const decodedLogs = await this._contractWrappers.exchange.getLogsAsync<LogFillContractEventArgs>(
- ExchangeEvents.LogFill,
+ const decodedLogs = await this._contractWrappers.exchange.getLogsAsync<ExchangeFillEventArgs>(
+ ExchangeEvents.Fill,
blockRange,
indexFilterValues,
);
@@ -746,28 +722,28 @@ export class Blockchain {
tradeHistoryStorage.addFillToUser(this._userAddressIfExists, this.networkId, fill);
}
}
- private async _convertDecodedLogToFillAsync(
- decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>,
- ): Promise<Fill> {
+ private async _convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<ExchangeFillEventArgs>): Promise<Fill> {
const args = decodedLog.args;
const blockTimestamp = await this._web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
+ const makerToken = assetDataUtils.decodeERC20AssetData(args.makerAssetData).tokenAddress;
+ const takerToken = assetDataUtils.decodeERC20AssetData(args.takerAssetData).tokenAddress;
const fill = {
- filledTakerTokenAmount: args.filledTakerTokenAmount,
- filledMakerTokenAmount: args.filledMakerTokenAmount,
+ filledTakerTokenAmount: args.takerAssetFilledAmount,
+ filledMakerTokenAmount: args.makerAssetFilledAmount,
logIndex: decodedLog.logIndex,
- maker: args.maker,
+ maker: args.makerAddress,
orderHash: args.orderHash,
- taker: args.taker,
- makerToken: args.makerToken,
- takerToken: args.takerToken,
- paidMakerFee: args.paidMakerFee,
- paidTakerFee: args.paidTakerFee,
+ taker: args.takerAddress,
+ makerToken,
+ takerToken,
+ paidMakerFee: args.makerFeePaid,
+ paidTakerFee: args.takerFeePaid,
transactionHash: decodedLog.transactionHash,
blockTimestamp,
};
return fill;
}
- private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>): boolean {
+ private _doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<ExchangeFillEventArgs>): boolean {
const args = decodedLog.args;
const isUserMakerOrTaker = args.maker === this._userAddressIfExists || args.taker === this._userAddressIfExists;
return isUserMakerOrTaker;
@@ -796,8 +772,8 @@ export class Blockchain {
if (this.networkId === constants.NETWORK_ID_MAINNET) {
tokenRegistryTokens = await backendClient.getTokenInfosAsync();
} else {
- utils.assert(!_.isUndefined(this._contractWrappers), 'ContractWrappers must be instantiated.');
- tokenRegistryTokens = await this._contractWrappers.tokenRegistry.getTokensAsync();
+ utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
+ tokenRegistryTokens = await this._zeroEx.tokenRegistry.getTokensAsync();
}
const tokenByAddress: TokenByAddress = {};
_.each(tokenRegistryTokens, (t: ZeroExToken) => {
@@ -877,6 +853,11 @@ export class Blockchain {
} else {
this._contractWrappers = new ContractWrappers(provider, { networkId });
}
+ if (!_.isUndefined(this._zeroEx)) {
+ this._zeroEx.setProvider(provider, networkId);
+ } else {
+ this._zeroEx = new ZeroEx(provider, { networkId });
+ }
if (!_.isUndefined(this._blockchainWatcher)) {
this._blockchainWatcher.destroy();
}
diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx
index 7da2e0870..95f2039b3 100644
--- a/packages/website/ts/components/fill_order.tsx
+++ b/packages/website/ts/components/fill_order.tsx
@@ -1,4 +1,4 @@
-import { getOrderHashHex, isValidSignature } from '@0xproject/order-utils';
+import { assetDataUtils, orderHashUtils, signatureUtils } from '@0xproject/order-utils';
import { colors } from '@0xproject/react-shared';
import { Order as ZeroExOrder } from '@0xproject/types';
import { BigNumber, logUtils } from '@0xproject/utils';
@@ -22,10 +22,11 @@ import { VisualOrder } from 'ts/components/visual_order';
import { Dispatcher } from 'ts/redux/dispatcher';
import { portalOrderSchema } from 'ts/schemas/portal_order_schema';
import { validator } from 'ts/schemas/validator';
-import { AlertTypes, BlockchainErrs, Order, Token, TokenByAddress, WebsitePaths } from 'ts/types';
+import { AlertTypes, BlockchainErrs, PortalOrder, Token, TokenByAddress, WebsitePaths } from 'ts/types';
import { analytics } from 'ts/utils/analytics';
import { constants } from 'ts/utils/constants';
import { errorReporter } from 'ts/utils/error_reporter';
+import { orderParser } from 'ts/utils/order_parser';
import { utils } from 'ts/utils/utils';
interface FillOrderProps {
@@ -36,7 +37,7 @@ interface FillOrderProps {
networkId: number;
userAddress: string;
tokenByAddress: TokenByAddress;
- initialOrder: Order;
+ initialOrder: PortalOrder;
dispatcher: Dispatcher;
lastForceTokenStateRefetch: number;
isFullWidth?: boolean;
@@ -49,7 +50,7 @@ interface FillOrderState {
globalErrMsg: string;
orderJSON: string;
orderJSONErrMsg: string;
- parsedOrder: Order;
+ parsedOrder: PortalOrder;
didFillOrderSucceed: boolean;
didCancelOrderSucceed: boolean;
unavailableTakerAmount: BigNumber;
@@ -191,16 +192,18 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
);
}
private _renderVisualOrder(): React.ReactNode {
- const takerTokenAddress = this.state.parsedOrder.signedOrder.takerTokenAddress;
+ const takerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.takerAssetData)
+ .tokenAddress;
const takerToken = this.props.tokenByAddress[takerTokenAddress];
- const orderTakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.takerTokenAmount);
- const orderMakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.makerTokenAmount);
+ const orderTakerAmount = this.state.parsedOrder.signedOrder.takerAssetAmount;
+ const orderMakerAmount = this.state.parsedOrder.signedOrder.makerAssetAmount;
const takerAssetToken = {
amount: orderTakerAmount.minus(this.state.unavailableTakerAmount),
symbol: takerToken.symbol,
};
const fillToken = this.props.tokenByAddress[takerTokenAddress];
- const makerTokenAddress = this.state.parsedOrder.signedOrder.makerTokenAddress;
+ const makerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.makerAssetData)
+ .tokenAddress;
const makerToken = this.props.tokenByAddress[makerTokenAddress];
const makerAssetToken = {
amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount),
@@ -210,7 +213,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
amount: this.props.orderFillAmount,
symbol: takerToken.symbol,
};
- const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec);
+ const parsedOrderExpiration = this.state.parsedOrder.signedOrder.expirationTimeSeconds;
let orderReceiveAmount = 0;
if (!_.isUndefined(this.props.orderFillAmount)) {
@@ -222,7 +225,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
}
const isUserMaker =
!_.isUndefined(this.state.parsedOrder) &&
- this.state.parsedOrder.signedOrder.maker === this.props.userAddress;
+ this.state.parsedOrder.signedOrder.makerAddress === this.props.userAddress;
const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration);
return (
<div className="pt3 pb1">
@@ -233,11 +236,11 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
Maker:
</div>
<div className="col col-2 pr1">
- <Identicon address={this.state.parsedOrder.signedOrder.maker} diameter={23} />
+ <Identicon address={this.state.parsedOrder.signedOrder.makerAddress} diameter={23} />
</div>
<div className="col col-6">
<EthereumAddress
- address={this.state.parsedOrder.signedOrder.maker}
+ address={this.state.parsedOrder.signedOrder.makerAddress}
networkId={this.props.networkId}
/>
</div>
@@ -367,17 +370,19 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
if (!_.isEmpty(this.state.orderJSONErrMsg)) {
return;
}
-
- const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.signedOrder.makerTokenAddress];
- const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.signedOrder.takerTokenAddress];
-
+ const makerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.makerAssetData)
+ .tokenAddress;
+ const takerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.takerAssetData)
+ .tokenAddress;
+ const makerTokenIfExists = this.props.tokenByAddress[makerTokenAddress];
+ const takerTokenIfExists = this.props.tokenByAddress[takerTokenAddress];
const tokensToTrack: Token[] = [];
const isUnseenMakerToken = _.isUndefined(makerTokenIfExists);
const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && utils.isTokenTracked(makerTokenIfExists);
if (isUnseenMakerToken) {
tokensToTrack.push({
...this.state.parsedOrder.metadata.makerToken,
- address: this.state.parsedOrder.signedOrder.makerTokenAddress,
+ address: makerTokenAddress,
iconUrl: undefined,
trackedTimestamp: undefined,
isRegistered: false,
@@ -390,7 +395,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
if (isUnseenTakerToken) {
tokensToTrack.push({
...this.state.parsedOrder.metadata.takerToken,
- address: this.state.parsedOrder.signedOrder.takerTokenAddress,
+ address: takerTokenAddress,
iconUrl: undefined,
trackedTimestamp: undefined,
isRegistered: false,
@@ -411,10 +416,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
}
private async _validateFillOrderFireAndForgetAsync(orderJSON: string): Promise<void> {
let orderJSONErrMsg = '';
- let parsedOrder: Order;
+ let parsedOrder: PortalOrder;
let orderHash: string;
try {
- const order = JSON.parse(orderJSON);
+ const order = orderParser.parseJsonString(orderJSON);
const validationResult = validator.validate(order, portalOrderSchema);
if (validationResult.errors.length > 0) {
orderJSONErrMsg = 'Submitted order JSON is not a valid order';
@@ -422,36 +427,16 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
return;
}
parsedOrder = order;
-
- const makerAmount = new BigNumber(parsedOrder.signedOrder.makerTokenAmount);
- const takerAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount);
- const expiration = new BigNumber(parsedOrder.signedOrder.expirationUnixTimestampSec);
- const salt = new BigNumber(parsedOrder.signedOrder.salt);
- const parsedMakerFee = new BigNumber(parsedOrder.signedOrder.makerFee);
- const parsedTakerFee = new BigNumber(parsedOrder.signedOrder.takerFee);
-
- const zeroExOrder: ZeroExOrder = {
- exchangeContractAddress: parsedOrder.signedOrder.exchangeContractAddress,
- expirationUnixTimestampSec: expiration,
- feeRecipient: parsedOrder.signedOrder.feeRecipient,
- maker: parsedOrder.signedOrder.maker,
- makerFee: parsedMakerFee,
- makerTokenAddress: parsedOrder.signedOrder.makerTokenAddress,
- makerTokenAmount: makerAmount,
- salt,
- taker: _.isEmpty(parsedOrder.signedOrder.taker)
- ? constants.NULL_ADDRESS
- : parsedOrder.signedOrder.taker,
- takerFee: parsedTakerFee,
- takerTokenAddress: parsedOrder.signedOrder.takerTokenAddress,
- takerTokenAmount: takerAmount,
- };
- orderHash = getOrderHashHex(zeroExOrder);
-
+ const signedOrder = parsedOrder.signedOrder;
+ orderHash = orderHashUtils.getOrderHashHex(signedOrder);
const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
- const signature = parsedOrder.signedOrder.ecSignature;
- const isSignatureValid = isValidSignature(orderHash, signature, parsedOrder.signedOrder.maker);
- if (exchangeContractAddr !== parsedOrder.signedOrder.exchangeContractAddress) {
+ const signature = signedOrder.signature;
+ const isSignatureValid = await this.props.blockchain.isValidSignatureAsync(
+ orderHash,
+ signature,
+ signedOrder.makerAddress,
+ );
+ if (exchangeContractAddr !== signedOrder.exchangeAddress) {
orderJSONErrMsg = 'This order was made on another network or using a deprecated Exchange contract';
parsedOrder = undefined;
} else if (!isSignatureValid) {
@@ -484,11 +469,15 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
this.props.dispatcher.updateUserSuppliedOrderCache(undefined);
} else {
unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
+ const makerTokenAddress = assetDataUtils.decodeERC20AssetData(parsedOrder.signedOrder.makerAssetData)
+ .tokenAddress;
+ const takerTokenAddress = assetDataUtils.decodeERC20AssetData(parsedOrder.signedOrder.takerAssetData)
+ .tokenAddress;
const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
- parsedOrder.signedOrder.makerTokenAddress,
+ makerTokenAddress,
);
const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
- parsedOrder.signedOrder.takerTokenAddress,
+ takerTokenAddress,
);
this.setState({
isMakerTokenAddressInRegistry,
@@ -496,6 +485,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
});
}
+ console.log(parsedOrder);
this.setState({
didOrderValidationRun: true,
orderJSON,
@@ -537,7 +527,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
globalErrMsg = 'You must specify a fill amount';
}
- const signedOrder = this.props.blockchain.portalOrderToZeroExOrder(parsedOrder);
+ const signedOrder = parsedOrder.signedOrder;
if (_.isEmpty(globalErrMsg)) {
try {
await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
@@ -546,7 +536,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
this.props.userAddress,
);
} catch (err) {
- globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.taker);
+ globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.takerAddress);
}
}
if (!_.isEmpty(globalErrMsg)) {
@@ -611,18 +601,11 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
return;
}
let globalErrMsg = '';
-
- const takerTokenAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount);
-
- const signedOrder = this.props.blockchain.portalOrderToZeroExOrder(parsedOrder);
- const orderHash = getOrderHashHex(signedOrder);
+ const signedOrder = parsedOrder.signedOrder;
+ const takerTokenAmount = signedOrder.takerAssetAmount;
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount);
- try {
- await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount);
- } catch (err) {
- globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.taker);
- }
if (!_.isEmpty(globalErrMsg)) {
this.setState({
isCancelling: false,
@@ -631,7 +614,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
return;
}
try {
- await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount);
+ await this.props.blockchain.cancelOrderAsync(signedOrder);
this.setState({
isCancelling: false,
didCancelOrderSucceed: true,
diff --git a/packages/website/ts/components/fill_order_json.tsx b/packages/website/ts/components/fill_order_json.tsx
index 90eedbb18..1ecc426bd 100644
--- a/packages/website/ts/components/fill_order_json.tsx
+++ b/packages/website/ts/components/fill_order_json.tsx
@@ -33,11 +33,7 @@ export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrder
},
};
const hintOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec();
- const hintECSignature = {
- r: '0xf01103f759e2289a28593eaf22e5820032...',
- s: '937862111edcba395f8a9e0cc1b2c5e12320...',
- v: 27,
- };
+ const hintECSignature = '0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33';
const hintSalt = generatePseudoRandomSalt();
const feeRecipient = constants.NULL_ADDRESS;
const hintOrder = utils.generateOrder(
diff --git a/packages/website/ts/components/generate_order/generate_order_form.tsx b/packages/website/ts/components/generate_order/generate_order_form.tsx
index 72efab033..bb6265170 100644
--- a/packages/website/ts/components/generate_order/generate_order_form.tsx
+++ b/packages/website/ts/components/generate_order/generate_order_form.tsx
@@ -1,4 +1,4 @@
-import { generatePseudoRandomSalt, getOrderHashHex } from '@0xproject/order-utils';
+import { assetDataUtils, generatePseudoRandomSalt, orderHashUtils } from '@0xproject/order-utils';
import { colors } from '@0xproject/react-shared';
import { ECSignature, Order as ZeroExOrder } from '@0xproject/types';
import { BigNumber, logUtils } from '@0xproject/utils';
@@ -20,7 +20,16 @@ import { SwapIcon } from 'ts/components/ui/swap_icon';
import { Dispatcher } from 'ts/redux/dispatcher';
import { portalOrderSchema } from 'ts/schemas/portal_order_schema';
import { validator } from 'ts/schemas/validator';
-import { AlertTypes, BlockchainErrs, HashData, Order, Side, SideToAssetToken, Token, TokenByAddress } from 'ts/types';
+import {
+ AlertTypes,
+ BlockchainErrs,
+ HashData,
+ PortalOrder,
+ Side,
+ SideToAssetToken,
+ Token,
+ TokenByAddress,
+} from 'ts/types';
import { analytics } from 'ts/utils/analytics';
import { constants } from 'ts/utils/constants';
import { errorReporter } from 'ts/utils/error_reporter';
@@ -41,7 +50,7 @@ interface GenerateOrderFormProps {
orderExpiryTimestamp: BigNumber;
networkId: number;
userAddress: string;
- orderECSignature: ECSignature;
+ orderSignature: string;
orderTakerAddress: string;
orderSalt: BigNumber;
sideToAssetToken: SideToAssetToken;
@@ -212,7 +221,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
<OrderJSON
exchangeContractIfExists={exchangeContractIfExists}
orderExpiryTimestamp={this.props.orderExpiryTimestamp}
- orderECSignature={this.props.orderECSignature}
+ orderSignature={this.props.orderSignature}
orderTakerAddress={this.props.orderTakerAddress}
orderMakerAddress={this.props.userAddress}
orderSalt={this.props.orderSalt}
@@ -294,12 +303,12 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
return false;
}
}
- private async _signTransactionAsync(): Promise<Order | undefined> {
+ private async _signTransactionAsync(): Promise<PortalOrder | undefined> {
this.setState({
signingState: SigningState.SIGNING,
});
- const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
- if (_.isUndefined(exchangeContractAddr)) {
+ const exchangeAddress = this.props.blockchain.getExchangeContractAddressIfExists();
+ if (_.isUndefined(exchangeAddress)) {
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
this.setState({
signingState: SigningState.UNSIGNED,
@@ -308,28 +317,31 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
}
const hashData = this.props.hashData;
+ const makerAssetData = assetDataUtils.encodeERC20AssetData(hashData.depositTokenContractAddr);
+ const takerAssetData = assetDataUtils.encodeERC20AssetData(hashData.receiveTokenContractAddr);
const zeroExOrder: ZeroExOrder = {
- exchangeContractAddress: exchangeContractAddr,
- expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
- feeRecipient: hashData.feeRecipientAddress,
- maker: hashData.orderMakerAddress,
+ senderAddress: constants.NULL_ADDRESS,
+ exchangeAddress,
+ expirationTimeSeconds: hashData.orderExpiryTimestamp,
+ feeRecipientAddress: hashData.feeRecipientAddress,
+ makerAddress: hashData.orderMakerAddress,
makerFee: hashData.makerFee,
- makerTokenAddress: hashData.depositTokenContractAddr,
- makerTokenAmount: hashData.depositAmount,
+ makerAssetData,
+ makerAssetAmount: hashData.depositAmount,
salt: hashData.orderSalt,
- taker: hashData.orderTakerAddress,
+ takerAddress: hashData.orderTakerAddress,
takerFee: hashData.takerFee,
- takerTokenAddress: hashData.receiveTokenContractAddr,
- takerTokenAmount: hashData.receiveAmount,
+ takerAssetData,
+ takerAssetAmount: hashData.receiveAmount,
};
- const orderHash = getOrderHashHex(zeroExOrder);
+ const orderHash = orderHashUtils.getOrderHashHex(zeroExOrder);
let globalErrMsg = '';
let order;
try {
- const ecSignature = await this.props.blockchain.signOrderHashAsync(orderHash);
+ const signature = await this.props.blockchain.signOrderHashAsync(orderHash);
order = utils.generateOrder(
- exchangeContractAddr,
+ exchangeAddress,
this.props.sideToAssetToken,
hashData.orderExpiryTimestamp,
this.props.orderTakerAddress,
@@ -337,10 +349,11 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
hashData.makerFee,
hashData.takerFee,
hashData.feeRecipientAddress,
- ecSignature,
+ signature,
this.props.tokenByAddress,
hashData.orderSalt,
);
+ console.log(order);
const validationResult = validator.validate(order, portalOrderSchema);
if (validationResult.errors.length > 0) {
globalErrMsg = 'Order signing failed. Please refresh and try again';
diff --git a/packages/website/ts/components/inputs/hash_input.tsx b/packages/website/ts/components/inputs/hash_input.tsx
index 8d9cdfc0b..5125ec4de 100644
--- a/packages/website/ts/components/inputs/hash_input.tsx
+++ b/packages/website/ts/components/inputs/hash_input.tsx
@@ -1,9 +1,10 @@
-import { getOrderHashHex } from '@0xproject/order-utils';
+import { assetDataUtils, orderHashUtils } from '@0xproject/order-utils';
import { Styles } from '@0xproject/react-shared';
import { Order } from '@0xproject/types';
import * as _ from 'lodash';
import * as React from 'react';
import ReactTooltip = require('react-tooltip');
+
import { Blockchain } from 'ts/blockchain';
import { FakeTextField } from 'ts/components/ui/fake_text_field';
import { HashData } from 'ts/types';
@@ -42,23 +43,26 @@ export class HashInput extends React.Component<HashInputProps, HashInputState> {
);
}
private _generateMessageHashHex(): string {
- const exchangeContractAddress = this.props.blockchain.getExchangeContractAddressIfExists();
+ const exchangeAddress = this.props.blockchain.getExchangeContractAddressIfExists();
const hashData = this.props.hashData;
+ const makerAssetData = assetDataUtils.encodeERC20AssetData(hashData.depositTokenContractAddr);
+ const takerAssetData = assetDataUtils.encodeERC20AssetData(hashData.receiveTokenContractAddr);
const order: Order = {
- exchangeContractAddress,
- expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
- feeRecipient: hashData.feeRecipientAddress,
- maker: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress,
+ senderAddress: constants.NULL_ADDRESS,
+ exchangeAddress,
+ expirationTimeSeconds: hashData.orderExpiryTimestamp,
+ feeRecipientAddress: hashData.feeRecipientAddress,
+ makerAddress: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress,
makerFee: hashData.makerFee,
- makerTokenAddress: hashData.depositTokenContractAddr,
- makerTokenAmount: hashData.depositAmount,
+ makerAssetData,
+ makerAssetAmount: hashData.depositAmount,
salt: hashData.orderSalt,
- taker: hashData.orderTakerAddress,
+ takerAddress: hashData.orderTakerAddress,
takerFee: hashData.takerFee,
- takerTokenAddress: hashData.receiveTokenContractAddr,
- takerTokenAmount: hashData.receiveAmount,
+ takerAssetData,
+ takerAssetAmount: hashData.receiveAmount,
};
- const orderHash = getOrderHashHex(order);
+ const orderHash = orderHashUtils.getOrderHashHex(order);
return orderHash;
}
}
diff --git a/packages/website/ts/components/order_json.tsx b/packages/website/ts/components/order_json.tsx
index cf06f10c8..2a4d992a0 100644
--- a/packages/website/ts/components/order_json.tsx
+++ b/packages/website/ts/components/order_json.tsx
@@ -14,7 +14,7 @@ import { utils } from 'ts/utils/utils';
interface OrderJSONProps {
exchangeContractIfExists: string;
orderExpiryTimestamp: BigNumber;
- orderECSignature: ECSignature;
+ orderSignature: string;
orderTakerAddress: string;
orderMakerAddress: string;
orderSalt: BigNumber;
@@ -48,7 +48,7 @@ export class OrderJSON extends React.Component<OrderJSONProps, OrderJSONState> {
this.props.orderMakerFee,
this.props.orderTakerFee,
this.props.orderFeeRecipient,
- this.props.orderECSignature,
+ this.props.orderSignature,
this.props.tokenByAddress,
this.props.orderSalt,
);
@@ -169,7 +169,7 @@ You can see and fill it here: ${this.state.shareLink}`);
this.props.orderMakerFee,
this.props.orderTakerFee,
this.props.orderFeeRecipient,
- this.props.orderECSignature,
+ this.props.orderSignature,
this.props.tokenByAddress,
this.props.orderSalt,
);
diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index ff11880e3..b8d7ceea9 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -39,7 +39,7 @@ import {
BlockchainErrs,
HashData,
ItemByAddress,
- Order,
+ PortalOrder,
ProviderType,
ScreenWidths,
Token,
@@ -71,7 +71,7 @@ export interface PortalProps {
userEtherBalanceInWei?: BigNumber;
userAddress: string;
shouldBlockchainErrDialogBeOpen: boolean;
- userSuppliedOrderCache: Order;
+ userSuppliedOrderCache: PortalOrder;
location: Location;
flashMessage?: string | React.ReactNode;
lastForceTokenStateRefetch: number;
@@ -114,11 +114,11 @@ const DOCUMENT_DESCRIPTION = 'Learn about and trade on 0x Relayers';
export class Portal extends React.Component<PortalProps, PortalState> {
private _blockchain: Blockchain;
- private readonly _sharedOrderIfExists: Order;
+ private readonly _sharedOrderIfExists: PortalOrder;
private readonly _throttledScreenWidthUpdate: () => void;
constructor(props: PortalProps) {
super(props);
- this._sharedOrderIfExists = orderParser.parse(window.location.search);
+ this._sharedOrderIfExists = orderParser.parseQueryString(window.location.search);
this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
const hasAcceptedDisclaimer =
diff --git a/packages/website/ts/containers/generate_order_form.ts b/packages/website/ts/containers/generate_order_form.ts
index 92296dbab..b2f74f0f8 100644
--- a/packages/website/ts/containers/generate_order_form.ts
+++ b/packages/website/ts/containers/generate_order_form.ts
@@ -20,7 +20,7 @@ interface ConnectedState {
blockchainErr: BlockchainErrs;
blockchainIsLoaded: boolean;
orderExpiryTimestamp: BigNumber;
- orderECSignature: ECSignature;
+ orderSignature: string;
userAddress: string;
orderTakerAddress: string;
orderSalt: BigNumber;
@@ -34,7 +34,7 @@ const mapStateToProps = (state: State, _ownProps: GenerateOrderFormProps): Conne
blockchainErr: state.blockchainErr,
blockchainIsLoaded: state.blockchainIsLoaded,
orderExpiryTimestamp: state.orderExpiryTimestamp,
- orderECSignature: state.orderECSignature,
+ orderSignature: state.orderSignature,
orderTakerAddress: state.orderTakerAddress,
orderSalt: state.orderSalt,
networkId: state.networkId,
diff --git a/packages/website/ts/containers/portal.ts b/packages/website/ts/containers/portal.ts
index 6747cdf4e..4d7ff2f55 100644
--- a/packages/website/ts/containers/portal.ts
+++ b/packages/website/ts/containers/portal.ts
@@ -6,7 +6,7 @@ import { Dispatch } from 'redux';
import { Portal as PortalComponent, PortalProps as PortalComponentProps } from 'ts/components/portal/portal';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
-import { BlockchainErrs, HashData, Order, ProviderType, ScreenWidths, Side, TokenByAddress } from 'ts/types';
+import { BlockchainErrs, HashData, PortalOrder, ProviderType, ScreenWidths, Side, TokenByAddress } from 'ts/types';
import { constants } from 'ts/utils/constants';
import { Translate } from 'ts/utils/translate';
@@ -25,7 +25,7 @@ interface ConnectedState {
screenWidth: ScreenWidths;
shouldBlockchainErrDialogBeOpen: boolean;
userAddress: string;
- userSuppliedOrderCache: Order;
+ userSuppliedOrderCache: PortalOrder;
flashMessage?: string | React.ReactNode;
translate: Translate;
isPortalOnboardingShowing: boolean;
diff --git a/packages/website/ts/redux/dispatcher.ts b/packages/website/ts/redux/dispatcher.ts
index db008d319..5e79b6518 100644
--- a/packages/website/ts/redux/dispatcher.ts
+++ b/packages/website/ts/redux/dispatcher.ts
@@ -7,7 +7,7 @@ import {
AssetToken,
BlockchainErrs,
Language,
- Order,
+ PortalOrder,
ProviderType,
ScreenWidths,
Side,
@@ -50,7 +50,7 @@ export class Dispatcher {
type: ActionTypes.UpdateOrderSalt,
});
}
- public updateUserSuppliedOrderCache(order: Order): void {
+ public updateUserSuppliedOrderCache(order: PortalOrder): void {
this._dispatch({
data: order,
type: ActionTypes.UpdateUserSuppliedOrderCache,
@@ -149,10 +149,10 @@ export class Dispatcher {
type: ActionTypes.ForceTokenStateRefetch,
});
}
- public updateECSignature(ecSignature: ECSignature): void {
+ public updateSignature(signature: string): void {
this._dispatch({
- data: ecSignature,
- type: ActionTypes.UpdateOrderECSignature,
+ data: signature,
+ type: ActionTypes.UpdateOrderSignature,
});
}
public updateUserWeiBalance(balance?: BigNumber): void {
diff --git a/packages/website/ts/redux/reducer.ts b/packages/website/ts/redux/reducer.ts
index 1bc4611e0..99907e93e 100644
--- a/packages/website/ts/redux/reducer.ts
+++ b/packages/website/ts/redux/reducer.ts
@@ -7,7 +7,7 @@ import {
Action,
ActionTypes,
BlockchainErrs,
- Order,
+ PortalOrder,
ProviderType,
ScreenWidths,
Side,
@@ -31,7 +31,7 @@ export interface State {
orderExpiryTimestamp: BigNumber;
orderFillAmount: BigNumber;
orderTakerAddress: string;
- orderECSignature: ECSignature;
+ orderSignature: string;
orderSalt: BigNumber;
nodeVersion: string;
screenWidth: ScreenWidths;
@@ -45,7 +45,7 @@ export interface State {
isPortalOnboardingShowing: boolean;
hasPortalOnboardingBeenClosed: boolean;
// Note: cache of supplied orderJSON in fill order step. Do not use for anything else.
- userSuppliedOrderCache: Order;
+ userSuppliedOrderCache: PortalOrder;
// Docs
docsVersion: string;
@@ -65,11 +65,7 @@ export const INITIAL_STATE: State = {
networkId: undefined,
orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
orderFillAmount: undefined,
- orderECSignature: {
- r: '',
- s: '',
- v: 27,
- },
+ orderSignature: '',
orderTakerAddress: constants.NULL_ADDRESS,
orderSalt: generatePseudoRandomSalt(),
nodeVersion: undefined,
@@ -90,7 +86,6 @@ export const INITIAL_STATE: State = {
// Docs
docsVersion: DEFAULT_DOCS_VERSION,
availableDocVersions: [DEFAULT_DOCS_VERSION],
-
// Shared
flashMessage: undefined,
providerType: ProviderType.Injected,
@@ -207,10 +202,10 @@ export function reducer(state: State = INITIAL_STATE, action: Action): State {
lastForceTokenStateRefetch: moment().unix(),
};
- case ActionTypes.UpdateOrderECSignature: {
+ case ActionTypes.UpdateOrderSignature: {
return {
...state,
- orderECSignature: action.data,
+ orderSignature: action.data,
};
}
diff --git a/packages/website/ts/schemas/portal_order_schema.ts b/packages/website/ts/schemas/portal_order_schema.ts
index ea8aeabc6..15e61f5e4 100644
--- a/packages/website/ts/schemas/portal_order_schema.ts
+++ b/packages/website/ts/schemas/portal_order_schema.ts
@@ -1,7 +1,7 @@
export const portalOrderSchema = {
id: '/PortalOrder',
properties: {
- signedOrder: { $ref: '/SignedOrder' },
+ signedOrder: { $ref: '/signedOrderSchema' },
metadata: { $ref: '/OrderMetadata' },
},
required: ['signedOrder', 'metadata'],
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index 6ab17e261..19cc8f858 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -1,4 +1,4 @@
-import { ECSignature } from '@0xproject/types';
+import { ECSignature, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Provider } from 'ethereum-types';
import * as React from 'react';
@@ -56,28 +56,12 @@ export interface OrderToken {
decimals: number;
}
-export interface SignedOrder {
- maker: string;
- taker: string;
- makerTokenAddress: string;
- takerTokenAddress: string;
- makerFee: string;
- takerFee: string;
- makerTokenAmount: string;
- takerTokenAmount: string;
- expirationUnixTimestampSec: string;
- feeRecipient: string;
- salt: string;
- ecSignature: ECSignature;
- exchangeContractAddress: string;
-}
-
export interface OrderMetadata {
makerToken: OrderToken;
takerToken: OrderToken;
}
-export interface Order {
+export interface PortalOrder {
signedOrder: SignedOrder;
metadata: OrderMetadata;
}
@@ -120,7 +104,7 @@ export enum ActionTypes {
UpdateChosenAssetTokenAddress = 'UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS',
UpdateOrderTakerAddress = 'UPDATE_ORDER_TAKER_ADDRESS',
UpdateOrderSalt = 'UPDATE_ORDER_SALT',
- UpdateOrderECSignature = 'UPDATE_ORDER_EC_SIGNATURE',
+ UpdateOrderSignature = 'UPDATE_ORDER_SIGNATURE',
UpdateTokenByAddress = 'UPDATE_TOKEN_BY_ADDRESS',
RemoveTokenFromTokenByAddress = 'REMOVE_TOKEN_FROM_TOKEN_BY_ADDRESS',
ForceTokenStateRefetch = 'FORCE_TOKEN_STATE_REFETCH',
diff --git a/packages/website/ts/utils/analytics.ts b/packages/website/ts/utils/analytics.ts
index e5a1ddfa4..62dbff2b9 100644
--- a/packages/website/ts/utils/analytics.ts
+++ b/packages/website/ts/utils/analytics.ts
@@ -1,5 +1,6 @@
+import { assetDataUtils } from '@0xproject/order-utils';
import * as _ from 'lodash';
-import { ObjectMap, Order } from 'ts/types';
+import { ObjectMap, PortalOrder } from 'ts/types';
import { utils } from 'ts/utils/utils';
export interface HeapAnalytics {
@@ -53,12 +54,16 @@ export class Analytics {
}
// tslint:enable:no-floating-promises
// Custom methods
- public trackOrderEvent(eventName: string, order: Order): void {
+ public trackOrderEvent(eventName: string, order: PortalOrder): void {
+ const takerTokenAmount = order.signedOrder.takerAssetAmount.toString();
+ const makerTokenAmount = order.signedOrder.makerAssetAmount.toString();
+ const takerToken = assetDataUtils.decodeERC20AssetData(order.signedOrder.takerAssetData).tokenAddress;
+ const makerToken = assetDataUtils.decodeERC20AssetData(order.signedOrder.makerAssetData).tokenAddress;
const orderLoggingData = {
- takerTokenAmount: order.signedOrder.takerTokenAmount,
- makeTokenAmount: order.signedOrder.makerTokenAmount,
- takerToken: order.metadata.takerToken.symbol,
- makerToken: order.metadata.makerToken.symbol,
+ takerTokenAmount,
+ makerTokenAmount,
+ takerToken,
+ makerToken,
};
this.track(eventName, orderLoggingData);
}
diff --git a/packages/website/ts/utils/order_parser.ts b/packages/website/ts/utils/order_parser.ts
index be08da80e..2e1d4d2f2 100644
--- a/packages/website/ts/utils/order_parser.ts
+++ b/packages/website/ts/utils/order_parser.ts
@@ -1,12 +1,12 @@
-import { logUtils } from '@0xproject/utils';
+import { BigNumber, logUtils } from '@0xproject/utils';
import * as _ from 'lodash';
import { portalOrderSchema } from 'ts/schemas/portal_order_schema';
import { validator } from 'ts/schemas/validator';
-import { Order } from 'ts/types';
+import { PortalOrder } from 'ts/types';
export const orderParser = {
- parse(queryString: string): Order | undefined {
+ parseQueryString(queryString: string): PortalOrder | undefined {
if (queryString.length === 0) {
return undefined;
}
@@ -28,6 +28,48 @@ export const orderParser = {
logUtils.log(`Invalid shared order: ${validationResult.errors}`);
return undefined;
}
- return order;
+ const signedOrder = _.get(order, 'signedOrder');
+ const convertedSignedOrder = convertOrderStringFieldsToBigNumber(signedOrder);
+ const result = {
+ ...order,
+ signedOrder: convertedSignedOrder,
+ };
+ return result;
+ },
+ parseJsonString(orderJson: string): PortalOrder {
+ const order = JSON.parse(orderJson);
+ const signedOrder = _.get(order, 'signedOrder');
+ const convertedSignedOrder = convertOrderStringFieldsToBigNumber(signedOrder);
+ const result = {
+ ...order,
+ signedOrder: convertedSignedOrder,
+ };
+ return result;
},
};
+
+// TODO: consolidate this function with that in typeConverters in @0xproject/connect
+function convertOrderStringFieldsToBigNumber(order: any): any {
+ return convertStringsFieldsToBigNumbers(order, [
+ 'makerAssetAmount',
+ 'takerAssetAmount',
+ 'makerFee',
+ 'takerFee',
+ 'expirationTimeSeconds',
+ 'salt',
+ ]);
+}
+
+// TODO: consolidate this function with that in typeConverters in @0xproject/connect
+function convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
+ const result = _.assign({}, obj);
+ _.each(fields, field => {
+ _.update(result, field, (value: string) => {
+ if (_.isUndefined(value)) {
+ throw new Error(`Could not find field '${field}' while converting string fields to BigNumber.`);
+ }
+ return new BigNumber(value);
+ });
+ });
+ return result;
+}
diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts
index 39bbd404c..eda0e513d 100644
--- a/packages/website/ts/utils/utils.ts
+++ b/packages/website/ts/utils/utils.ts
@@ -1,11 +1,12 @@
-import { ContractWrappersError, ExchangeContractErrs } from '@0xproject/contract-wrappers';
-import { OrderError } from '@0xproject/order-utils';
+import { ContractWrappersError } from '@0xproject/contract-wrappers';
+import { assetDataUtils, OrderError } from '@0xproject/order-utils';
import { constants as sharedConstants, Networks } from '@0xproject/react-shared';
-import { ECSignature, Provider } from '@0xproject/types';
+import { ECSignature, ExchangeContractErrs } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as bowser from 'bowser';
import deepEqual = require('deep-equal');
+import { Provider } from 'ethereum-types';
import * as _ from 'lodash';
import * as moment from 'moment';
import * as numeral from 'numeral';
@@ -16,7 +17,7 @@ import {
BrowserType,
Environments,
OperatingSystemType,
- Order,
+ PortalOrder,
Providers,
ProviderType,
ScreenWidths,
@@ -64,35 +65,36 @@ export const utils = {
return formattedDate;
},
generateOrder(
- exchangeContractAddress: string,
+ exchangeAddress: string,
sideToAssetToken: SideToAssetToken,
- expirationUnixTimestampSec: BigNumber,
+ expirationTimeSeconds: BigNumber,
orderTakerAddress: string,
orderMakerAddress: string,
makerFee: BigNumber,
takerFee: BigNumber,
- feeRecipient: string,
- ecSignature: ECSignature,
+ feeRecipientAddress: string,
+ signature: string,
tokenByAddress: TokenByAddress,
orderSalt: BigNumber,
- ): Order {
+ ): PortalOrder {
const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address];
const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address];
const order = {
signedOrder: {
- maker: orderMakerAddress,
- taker: orderTakerAddress,
- makerFee: makerFee.toString(),
- takerFee: takerFee.toString(),
- makerTokenAmount: sideToAssetToken[Side.Deposit].amount.toString(),
- takerTokenAmount: sideToAssetToken[Side.Receive].amount.toString(),
- makerTokenAddress: makerToken.address,
- takerTokenAddress: takerToken.address,
- expirationUnixTimestampSec: expirationUnixTimestampSec.toString(),
- feeRecipient,
- salt: orderSalt.toString(),
- ecSignature,
- exchangeContractAddress,
+ senderAddress: constants.NULL_ADDRESS,
+ makerAddress: orderMakerAddress,
+ takerAddress: orderTakerAddress,
+ makerFee,
+ takerFee,
+ makerAssetAmount: sideToAssetToken[Side.Deposit].amount,
+ takerAssetAmount: sideToAssetToken[Side.Receive].amount,
+ makerAssetData: assetDataUtils.encodeERC20AssetData(makerToken.address),
+ takerAssetData: assetDataUtils.encodeERC20AssetData(takerToken.address),
+ expirationTimeSeconds,
+ feeRecipientAddress,
+ salt: orderSalt,
+ signature,
+ exchangeAddress,
},
metadata: {
makerToken: {
@@ -231,10 +233,10 @@ export const utils = {
const ContractWrappersErrorToHumanReadableError: { [error: string]: string } = {
[ContractWrappersError.ExchangeContractDoesNotExist]: 'Exchange contract does not exist',
[ContractWrappersError.EtherTokenContractDoesNotExist]: 'EtherToken contract does not exist',
- [ContractWrappersError.TokenTransferProxyContractDoesNotExist]:
- 'TokenTransferProxy contract does not exist',
- [ContractWrappersError.TokenRegistryContractDoesNotExist]: 'TokenRegistry contract does not exist',
- [ContractWrappersError.TokenContractDoesNotExist]: 'Token contract does not exist',
+ [ContractWrappersError.ERC20ProxyContractDoesNotExist]: 'ERC20 proxy contract des not exist',
+ [ContractWrappersError.ERC721ProxyContractDoesNotExist]: 'ERC721 proxy contract des not exist',
+ [ContractWrappersError.ERC20TokenContractDoesNotExist]: 'ERC20 token contract does not exist',
+ [ContractWrappersError.ERC721TokenContractDoesNotExist]: 'ERC721 token contract does not exist',
[ContractWrappersError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
[BlockchainCallErrs.UserHasNoAssociatedAddresses]: 'User has no addresses available',
[OrderError.InvalidSignature]: 'Order signature is not valid',
@@ -247,12 +249,9 @@ export const utils = {
} = {
[ExchangeContractErrs.OrderFillExpired]: 'This order has expired',
[ExchangeContractErrs.OrderCancelExpired]: 'This order has expired',
- [ExchangeContractErrs.OrderCancelAmountZero]: "Order cancel amount can't be 0",
- [ExchangeContractErrs.OrderAlreadyCancelledOrFilled]:
- 'This order has already been completely filled or cancelled',
+ [ExchangeContractErrs.OrderCancelled]: 'This order has been cancelled',
[ExchangeContractErrs.OrderFillAmountZero]: "Order fill amount can't be 0",
- [ExchangeContractErrs.OrderRemainingFillAmountZero]:
- 'This order has already been completely filled or cancelled',
+ [ExchangeContractErrs.OrderRemainingFillAmountZero]: 'This order has already been completely filled',
[ExchangeContractErrs.OrderFillRoundingError]:
'Rounding error will occur when filling this order. Please try filling a different amount.',
[ExchangeContractErrs.InsufficientTakerBalance]: