aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts')
-rw-r--r--packages/website/ts/blockchain.ts244
-rw-r--r--packages/website/ts/components/fill_order.tsx4
-rw-r--r--packages/website/ts/globals.d.ts11
-rw-r--r--packages/website/ts/local_storage/tracked_token_storage.ts2
-rw-r--r--packages/website/ts/redux/dispatcher.ts14
-rw-r--r--packages/website/ts/redux/reducer.ts22
-rw-r--r--packages/website/ts/schemas/validator.ts6
-rw-r--r--packages/website/ts/subproviders/injected_web3_subprovider.ts3
-rw-r--r--packages/website/ts/subproviders/ledger_wallet_subprovider_factory.ts8
-rw-r--r--packages/website/ts/subproviders/redundant_rpc_subprovider.ts32
-rw-r--r--packages/website/ts/types.ts22
-rw-r--r--packages/website/ts/utils/constants.ts10
-rw-r--r--packages/website/ts/utils/doc_utils.ts16
-rw-r--r--packages/website/ts/utils/doxity_utils.ts14
-rw-r--r--packages/website/ts/utils/error_reporter.ts8
-rw-r--r--packages/website/ts/utils/typedoc_utils.ts28
-rw-r--r--packages/website/ts/utils/utils.ts76
-rw-r--r--packages/website/ts/web3_wrapper.ts7
18 files changed, 272 insertions, 255 deletions
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index b13c48a65..fbe12ee75 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -1,59 +1,60 @@
-import * as _ from 'lodash';
-import * as React from 'react';
import {
- ZeroEx,
- ZeroExError,
+ BlockParam,
+ DecodedLogEvent,
ExchangeContractErrs,
ExchangeContractEventArgs,
ExchangeEvents,
- SubscriptionOpts,
IndexedFilterValues,
- DecodedLogEvent,
- BlockParam,
- LogFillContractEventArgs,
LogCancelContractEventArgs,
- Token as ZeroExToken,
+ LogFillContractEventArgs,
LogWithDecodedArgs,
- TransactionReceiptWithDecodedLogs,
- SignedOrder,
Order,
+ SignedOrder,
+ SubscriptionOpts,
+ Token as ZeroExToken,
+ TransactionReceiptWithDecodedLogs,
+ ZeroEx,
+ ZeroExError,
} from '0x.js';
import BigNumber from 'bignumber.js';
-import Web3 = require('web3');
+import compareVersions = require('compare-versions');
import promisify = require('es6-promisify');
+import ethUtil = require('ethereumjs-util');
import findVersions = require('find-versions');
-import compareVersions = require('compare-versions');
+import * as _ from 'lodash';
+import * as React from 'react';
import contract = require('truffle-contract');
-import ethUtil = require('ethereumjs-util');
-import ProviderEngine = require('web3-provider-engine');
-import FilterSubprovider = require('web3-provider-engine/subproviders/filters');
-import { TransactionSubmitted } from 'ts/components/flash_messages/transaction_submitted';
import {TokenSendCompleted} from 'ts/components/flash_messages/token_send_completed';
-import {RedundantRPCSubprovider} from 'ts/subproviders/redundant_rpc_subprovider';
+import { TransactionSubmitted } from 'ts/components/flash_messages/transaction_submitted';
+import {trackedTokenStorage} from 'ts/local_storage/tracked_token_storage';
+import {tradeHistoryStorage} from 'ts/local_storage/trade_history_storage';
+import {Dispatcher} from 'ts/redux/dispatcher';
import {InjectedWeb3SubProvider} from 'ts/subproviders/injected_web3_subprovider';
import {ledgerWalletSubproviderFactory} from 'ts/subproviders/ledger_wallet_subprovider_factory';
-import {Dispatcher} from 'ts/redux/dispatcher';
-import {utils} from 'ts/utils/utils';
-import {constants} from 'ts/utils/constants';
-import {configs} from 'ts/utils/configs';
+import {RedundantRPCSubprovider} from 'ts/subproviders/redundant_rpc_subprovider';
import {
- BlockchainErrs,
- Token,
- SignatureData,
- Side,
- ContractResponse,
BlockchainCallErrs,
+ BlockchainErrs,
ContractInstance,
- ProviderType,
- LedgerWalletSubprovider,
+ ContractResponse,
EtherscanLinkSuffixes,
+ LedgerWalletSubprovider,
+ ProviderType,
+ Side,
+ SignatureData,
+ Token,
TokenByAddress,
TokenStateByAddress,
} from 'ts/types';
-import {Web3Wrapper} from 'ts/web3_wrapper';
+import {configs} from 'ts/utils/configs';
+import {constants} from 'ts/utils/constants';
import {errorReporter} from 'ts/utils/error_reporter';
-import {tradeHistoryStorage} from 'ts/local_storage/trade_history_storage';
-import {trackedTokenStorage} from 'ts/local_storage/tracked_token_storage';
+import {utils} from 'ts/utils/utils';
+import {Web3Wrapper} from 'ts/web3_wrapper';
+import Web3 = require('web3');
+import ProviderEngine = require('web3-provider-engine');
+import FilterSubprovider = require('web3-provider-engine/subproviders/filters');
+
import * as MintableArtifacts from '../contracts/Mintable.json';
const ALLOWANCE_TO_ZERO_GAS_AMOUNT = 45730;
@@ -72,9 +73,68 @@ export class Blockchain {
private cachedProvider: Web3.Provider;
private ledgerSubProvider: LedgerWalletSubprovider;
private zrxPollIntervalId: number;
+ private static async onPageLoadAsync() {
+ if (document.readyState === 'complete') {
+ return; // Already loaded
+ }
+ return new Promise((resolve, reject) => {
+ window.onload = resolve;
+ });
+ }
+ private static getNameGivenProvider(provider: Web3.Provider): string {
+ if (!_.isUndefined((provider as any).isMetaMask)) {
+ return constants.METAMASK_PROVIDER_NAME;
+ }
+
+ // HACK: We use the fact that Parity Signer's provider is an instance of their
+ // internal `Web3FrameProvider` class.
+ const isParitySigner = _.startsWith(provider.constructor.toString(), 'function Web3FrameProvider');
+ if (isParitySigner) {
+ return constants.PARITY_SIGNER_PROVIDER_NAME;
+ }
+
+ return constants.GENERIC_PROVIDER_NAME;
+ }
+ private static async getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
+ const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
+ const publicNodeUrlsIfExistsForNetworkId = constants.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
+ const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
+
+ let provider;
+ if (doesInjectedWeb3Exist && isPublicNodeAvailableForNetworkId) {
+ // We catch all requests involving a users account and send it to the injectedWeb3
+ // instance. All other requests go to the public hosted node.
+ provider = new ProviderEngine();
+ provider.addProvider(new InjectedWeb3SubProvider(injectedWeb3));
+ provider.addProvider(new FilterSubprovider());
+ provider.addProvider(new RedundantRPCSubprovider(
+ publicNodeUrlsIfExistsForNetworkId,
+ ));
+ provider.start();
+ } else if (doesInjectedWeb3Exist) {
+ // Since no public node for this network, all requests go to injectedWeb3 instance
+ provider = injectedWeb3.currentProvider;
+ } else {
+ // If no injectedWeb3 instance, all requests fallback to our public hosted mainnet/testnet node
+ // We do this so that users can still browse the 0x Portal DApp even if they do not have web3
+ // injected into their browser.
+ provider = new ProviderEngine();
+ provider.addProvider(new FilterSubprovider());
+ const networkId = configs.isMainnetEnabled ?
+ constants.MAINNET_NETWORK_ID :
+ constants.TESTNET_NETWORK_ID;
+ provider.addProvider(new RedundantRPCSubprovider(
+ constants.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId],
+ ));
+ provider.start();
+ }
+
+ return provider;
+ }
constructor(dispatcher: Dispatcher, isSalePage: boolean = false) {
this.dispatcher = dispatcher;
this.userAddress = '';
+ // tslint:disable-next-line:no-floating-promises
this.onPageLoadInitFireAndForgetAsync();
}
public async networkIdUpdatedFireAndForgetAsync(newNetworkId: number) {
@@ -216,7 +276,7 @@ export class Blockchain {
signatureData: SignatureData, salt: BigNumber): SignedOrder {
const ecSignature = signatureData;
const exchangeContractAddress = this.getExchangeContractAddressIfExists();
- taker = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
+ const takerOrNullAddress = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
const signedOrder = {
ecSignature,
exchangeContractAddress,
@@ -227,7 +287,7 @@ export class Blockchain {
makerTokenAddress,
makerTokenAmount,
salt,
- taker,
+ taker: takerOrNullAddress,
takerFee,
takerTokenAddress,
takerTokenAmount,
@@ -273,51 +333,6 @@ export class Blockchain {
public getExchangeContractAddressIfExists() {
return this.exchangeAddress;
}
- public toHumanReadableErrorMsg(error: ZeroExError|ExchangeContractErrs, takerAddress: string): string {
- const ZeroExErrorToHumanReadableError: {[error: string]: string} = {
- [ZeroExError.ContractDoesNotExist]: 'Contract does not exist',
- [ZeroExError.ExchangeContractDoesNotExist]: 'Exchange contract does not exist',
- [ZeroExError.UnhandledError]: ' Unhandled error occured',
- [ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
- [ZeroExError.InvalidSignature]: 'Order signature is not valid',
- [ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
- [ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
- [ZeroExError.OutOfGas]: 'Transaction ran out of gas',
- [ZeroExError.NoNetworkId]: 'No network id detected',
- };
- const exchangeContractErrorToHumanReadableError: {[error: string]: string} = {
- [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.OrderFillAmountZero]: 'Order fill amount can\'t be 0',
- [ExchangeContractErrs.OrderRemainingFillAmountZero]:
- 'This order has already been completely filled or cancelled',
- [ExchangeContractErrs.OrderFillRoundingError]: 'Rounding error will occur when filling this order',
- [ExchangeContractErrs.InsufficientTakerBalance]:
- 'Taker no longer has a sufficient balance to complete this order',
- [ExchangeContractErrs.InsufficientTakerAllowance]:
- 'Taker no longer has a sufficient allowance to complete this order',
- [ExchangeContractErrs.InsufficientMakerBalance]:
- 'Maker no longer has a sufficient balance to complete this order',
- [ExchangeContractErrs.InsufficientMakerAllowance]:
- 'Maker no longer has a sufficient allowance to complete this order',
- [ExchangeContractErrs.InsufficientTakerFeeBalance]: 'Taker no longer has a sufficient balance to pay fees',
- [ExchangeContractErrs.InsufficientTakerFeeAllowance]:
- 'Taker no longer has a sufficient allowance to pay fees',
- [ExchangeContractErrs.InsufficientMakerFeeBalance]: 'Maker no longer has a sufficient balance to pay fees',
- [ExchangeContractErrs.InsufficientMakerFeeAllowance]:
- 'Maker no longer has a sufficient allowance to pay fees',
- [ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker]:
- `This order can only be filled by ${takerAddress}`,
- [ExchangeContractErrs.InsufficientRemainingFillAmount]:
- 'Insufficient remaining fill amount',
- };
- const humanReadableErrorMsg = exchangeContractErrorToHumanReadableError[error] ||
- ZeroExErrorToHumanReadableError[error];
- return humanReadableErrorMsg;
- }
public async validateFillOrderThrowIfInvalidAsync(signedOrder: SignedOrder,
fillTakerTokenAmount: BigNumber,
takerAddress: string): Promise<void> {
@@ -446,6 +461,7 @@ export class Blockchain {
public destroy() {
clearInterval(this.zrxPollIntervalId);
this.web3Wrapper.destroy();
+ // tslint:disable-next-line:no-floating-promises
this.stopWatchingExchangeLogFillEventsAsync(); // fire and forget
}
private async showEtherScanLinkAndAwaitTransactionMinedAsync(
@@ -485,7 +501,7 @@ export class Blockchain {
// Start a subscription for new logs
const exchangeAddress = this.getExchangeContractAddressIfExists();
- const subscriptionId = await this.zeroEx.exchange.subscribeAsync(
+ const subscriptionId = this.zeroEx.exchange.subscribe(
ExchangeEvents.LogFill, indexFilterValues,
async (err: Error, decodedLogEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
const decodedLog = decodedLogEvent.log;
@@ -493,7 +509,9 @@ export class Blockchain {
// Note: it's not entirely clear from the documentation which
// errors will be thrown by `watch`. For now, let's log the error
// to rollbar and stop watching when one occurs
+ // tslint:disable-next-line:no-floating-promises
errorReporter.reportAsync(err); // fire and forget
+ // tslint:disable-next-line:no-floating-promises
this.stopWatchingExchangeLogFillEventsAsync(); // fire and forget
return;
} else {
@@ -529,7 +547,7 @@ export class Blockchain {
}
}
private async convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
- const args = decodedLog.args as LogFillContractEventArgs;
+ const args = decodedLog.args;
const blockTimestamp = await this.web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
const fill = {
filledTakerTokenAmount: args.filledTakerTokenAmount,
@@ -548,7 +566,7 @@ export class Blockchain {
return fill;
}
private doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
- const args = decodedLog.args as LogFillContractEventArgs;
+ const args = decodedLog.args;
const isUserMakerOrTaker = args.maker === this.userAddress ||
args.taker === this.userAddress;
return isUserMakerOrTaker;
@@ -614,7 +632,7 @@ export class Blockchain {
const provider = await this.getProviderAsync(injectedWeb3, networkId);
this.zeroEx = new ZeroEx(provider);
- await this.updateProviderName(injectedWeb3);
+ this.updateProviderName(injectedWeb3);
const shouldPollUserAddress = true;
this.web3Wrapper = new Web3Wrapper(this.dispatcher, provider, networkId, shouldPollUserAddress);
await this.postInstantiationOrUpdatingProviderZeroExAsync();
@@ -637,56 +655,6 @@ export class Blockchain {
private getBlockchainNetworkId() {
return this.networkId;
}
- private async getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
- const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
- const publicNodeUrlsIfExistsForNetworkId = constants.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
- const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
-
- let provider;
- if (doesInjectedWeb3Exist && isPublicNodeAvailableForNetworkId) {
- // We catch all requests involving a users account and send it to the injectedWeb3
- // instance. All other requests go to the public hosted node.
- provider = new ProviderEngine();
- provider.addProvider(new InjectedWeb3SubProvider(injectedWeb3));
- provider.addProvider(new FilterSubprovider());
- provider.addProvider(new RedundantRPCSubprovider(
- publicNodeUrlsIfExistsForNetworkId,
- ));
- provider.start();
- } else if (doesInjectedWeb3Exist) {
- // Since no public node for this network, all requests go to injectedWeb3 instance
- provider = injectedWeb3.currentProvider;
- } else {
- // If no injectedWeb3 instance, all requests fallback to our public hosted mainnet/testnet node
- // We do this so that users can still browse the 0x Portal DApp even if they do not have web3
- // injected into their browser.
- provider = new ProviderEngine();
- provider.addProvider(new FilterSubprovider());
- const networkId = configs.isMainnetEnabled ?
- constants.MAINNET_NETWORK_ID :
- constants.TESTNET_NETWORK_ID;
- provider.addProvider(new RedundantRPCSubprovider(
- constants.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId],
- ));
- provider.start();
- }
-
- return provider;
- }
- private getNameGivenProvider(provider: Web3.Provider): string {
- if (!_.isUndefined((provider as any).isMetaMask)) {
- return constants.METAMASK_PROVIDER_NAME;
- }
-
- // HACK: We use the fact that Parity Signer's provider is an instance of their
- // internal `Web3FrameProvider` class.
- const isParitySigner = _.startsWith(provider.constructor.toString(), 'function Web3FrameProvider');
- if (isParitySigner) {
- return constants.PARITY_SIGNER_PROVIDER_NAME;
- }
-
- return constants.GENERIC_PROVIDER_NAME;
- }
private async fetchTokenInformationAsync() {
utils.assert(!_.isUndefined(this.networkId),
'Cannot call fetchTokenInformationAsync if disconnected from Ethereum node');
@@ -776,12 +744,4 @@ export class Blockchain {
}
}
}
- private async onPageLoadAsync() {
- if (document.readyState === 'complete') {
- return; // Already loaded
- }
- return new Promise((resolve, reject) => {
- window.onload = resolve;
- });
- }
-}
+} // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx
index dc965283e..0d652d33f 100644
--- a/packages/website/ts/components/fill_order.tsx
+++ b/packages/website/ts/components/fill_order.tsx
@@ -563,7 +563,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
signedOrder, takerFillAmount, this.props.userAddress);
} catch (err) {
- globalErrMsg = this.props.blockchain.toHumanReadableErrorMsg(err.message, parsedOrder.taker.address);
+ globalErrMsg = this.props.blockchain.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
}
}
if (!_.isEmpty(globalErrMsg)) {
@@ -652,7 +652,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(
signedOrder, availableTakerTokenAmount);
} catch (err) {
- globalErrMsg = this.props.blockchain.toHumanReadableErrorMsg(err.message, parsedOrder.taker.address);
+ globalErrMsg = this.props.blockchain.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address);
}
if (!_.isEmpty(globalErrMsg)) {
this.setState({
diff --git a/packages/website/ts/globals.d.ts b/packages/website/ts/globals.d.ts
index ee449ecfd..c5b94dc45 100644
--- a/packages/website/ts/globals.d.ts
+++ b/packages/website/ts/globals.d.ts
@@ -132,6 +132,8 @@ declare class Subprovider {}
declare module 'web3-provider-engine/subproviders/subprovider' {
export = Subprovider;
}
+
+// tslint:disable-next-line:max-classes-per-file
declare class RpcSubprovider {
constructor(options: {rpcUrl: string});
public handleRequest(payload: any, next: any, end: (err?: Error, data?: any) => void): void;
@@ -139,6 +141,7 @@ declare class RpcSubprovider {
declare module 'web3-provider-engine/subproviders/rpc' {
export = RpcSubprovider;
}
+// tslint:disable-next-line:max-classes-per-file
declare class HookedWalletSubprovider {
constructor(wallet: any);
}
@@ -148,7 +151,9 @@ declare module 'web3-provider-engine/subproviders/hooked-wallet' {
declare interface Artifact {
abi: any;
- networks: {[networkId: number]: {
- address: string;
- }};
+ networks: {
+ [networkId: number]: {
+ address: string;
+ };
+ };
}
diff --git a/packages/website/ts/local_storage/tracked_token_storage.ts b/packages/website/ts/local_storage/tracked_token_storage.ts
index 0b54a66e0..051a78ae1 100644
--- a/packages/website/ts/local_storage/tracked_token_storage.ts
+++ b/packages/website/ts/local_storage/tracked_token_storage.ts
@@ -1,6 +1,6 @@
import * as _ from 'lodash';
-import {Token, TrackedTokensByNetworkId} from 'ts/types';
import {localStorage} from 'ts/local_storage/local_storage';
+import {Token, TrackedTokensByNetworkId} from 'ts/types';
const TRACKED_TOKENS_KEY = 'trackedTokens';
diff --git a/packages/website/ts/redux/dispatcher.ts b/packages/website/ts/redux/dispatcher.ts
index 566ab8a01..a0a1da21b 100644
--- a/packages/website/ts/redux/dispatcher.ts
+++ b/packages/website/ts/redux/dispatcher.ts
@@ -1,20 +1,20 @@
+import BigNumber from 'bignumber.js';
import {Dispatch} from 'redux';
import {State} from 'ts/redux/reducer';
import {
- Direction,
- Side,
+ ActionTypes,
AssetToken,
BlockchainErrs,
- Token,
- SignatureData,
+ Direction,
Fill,
Order,
- ActionTypes,
- ScreenWidths,
ProviderType,
+ ScreenWidths,
+ Side,
+ SignatureData,
+ Token,
TokenStateByAddress,
} from 'ts/types';
-import BigNumber from 'bignumber.js';
export class Dispatcher {
private dispatch: Dispatch<State>;
diff --git a/packages/website/ts/redux/reducer.ts b/packages/website/ts/redux/reducer.ts
index 7723597cd..da69a9d00 100644
--- a/packages/website/ts/redux/reducer.ts
+++ b/packages/website/ts/redux/reducer.ts
@@ -1,23 +1,23 @@
-import * as _ from 'lodash';
import {ZeroEx} from '0x.js';
import BigNumber from 'bignumber.js';
-import {utils} from 'ts/utils/utils';
+import * as _ from 'lodash';
import {
+ Action,
+ ActionTypes,
+ BlockchainErrs,
+ Direction,
GenerateOrderSteps,
+ Order,
+ ProviderType,
+ ScreenWidths,
Side,
SideToAssetToken,
- Direction,
- BlockchainErrs,
SignatureData,
TokenByAddress,
- TokenStateByAddress,
- Order,
- Action,
- ActionTypes,
- ScreenWidths,
- ProviderType,
TokenState,
+ TokenStateByAddress,
} from 'ts/types';
+import {utils} from 'ts/utils/utils';
// Instead of defaulting the docs version to an empty string, we pre-populate it with
// a valid version value. This does not need to be updated however, since onLoad, it
@@ -54,7 +54,7 @@ export interface State {
flashMessage: string|React.ReactNode;
providerType: ProviderType;
injectedProviderName: string;
-};
+}
const INITIAL_STATE: State = {
// Portal
diff --git a/packages/website/ts/schemas/validator.ts b/packages/website/ts/schemas/validator.ts
index bf6ba4044..e8eb4aaf2 100644
--- a/packages/website/ts/schemas/validator.ts
+++ b/packages/website/ts/schemas/validator.ts
@@ -1,8 +1,8 @@
-import {Validator, Schema as JSONSchema} from 'jsonschema';
-import {signatureDataSchema} from 'ts/schemas/signature_data_schema';
+import {Schema as JSONSchema, Validator} from 'jsonschema';
import {orderSchema} from 'ts/schemas/order_schema';
-import {tokenSchema} from 'ts/schemas/token_schema';
import {orderTakerSchema} from 'ts/schemas/order_taker_schema';
+import {signatureDataSchema} from 'ts/schemas/signature_data_schema';
+import {tokenSchema} from 'ts/schemas/token_schema';
export class SchemaValidator {
private validator: Validator;
diff --git a/packages/website/ts/subproviders/injected_web3_subprovider.ts b/packages/website/ts/subproviders/injected_web3_subprovider.ts
index b9e5af3ef..910fe3cdf 100644
--- a/packages/website/ts/subproviders/injected_web3_subprovider.ts
+++ b/packages/website/ts/subproviders/injected_web3_subprovider.ts
@@ -1,6 +1,6 @@
import * as _ from 'lodash';
-import Web3 = require('web3');
import {constants} from 'ts/utils/constants';
+import Web3 = require('web3');
/*
* This class implements the web3-provider-engine subprovider interface and forwards
@@ -38,6 +38,7 @@ export class InjectedWeb3SubProvider {
}
}
// Required to implement this method despite not needing it for this subprovider
+ // tslint:disable-next-line:prefer-function-over-method
public setEngine(engine: any) {
// noop
}
diff --git a/packages/website/ts/subproviders/ledger_wallet_subprovider_factory.ts b/packages/website/ts/subproviders/ledger_wallet_subprovider_factory.ts
index df0c5a4db..bfabc90ae 100644
--- a/packages/website/ts/subproviders/ledger_wallet_subprovider_factory.ts
+++ b/packages/website/ts/subproviders/ledger_wallet_subprovider_factory.ts
@@ -1,11 +1,11 @@
-import * as _ from 'lodash';
-import Web3 = require('web3');
import * as EthereumTx from 'ethereumjs-tx';
import ethUtil = require('ethereumjs-util');
import * as ledger from 'ledgerco';
-import HookedWalletSubprovider = require('web3-provider-engine/subproviders/hooked-wallet');
-import {constants} from 'ts/utils/constants';
+import * as _ from 'lodash';
import {LedgerEthConnection, SignPersonalMessageParams, TxParams} from 'ts/types';
+import {constants} from 'ts/utils/constants';
+import Web3 = require('web3');
+import HookedWalletSubprovider = require('web3-provider-engine/subproviders/hooked-wallet');
const NUM_ADDRESSES_TO_FETCH = 10;
const ASK_FOR_ON_DEVICE_CONFIRMATION = false;
diff --git a/packages/website/ts/subproviders/redundant_rpc_subprovider.ts b/packages/website/ts/subproviders/redundant_rpc_subprovider.ts
index a6c53ebd1..74675d910 100644
--- a/packages/website/ts/subproviders/redundant_rpc_subprovider.ts
+++ b/packages/website/ts/subproviders/redundant_rpc_subprovider.ts
@@ -1,11 +1,26 @@
+import promisify = require('es6-promisify');
import * as _ from 'lodash';
import {JSONRPCPayload} from 'ts/types';
-import promisify = require('es6-promisify');
-import Subprovider = require('web3-provider-engine/subproviders/subprovider');
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
+import Subprovider = require('web3-provider-engine/subproviders/subprovider');
export class RedundantRPCSubprovider extends Subprovider {
private rpcs: RpcSubprovider[];
+ private static async firstSuccessAsync(
+ rpcs: RpcSubprovider[], payload: JSONRPCPayload, next: () => void,
+ ): Promise<any> {
+ let lastErr;
+ for (const rpc of rpcs) {
+ try {
+ const data = await promisify(rpc.handleRequest.bind(rpc))(payload, next);
+ return data;
+ } catch (err) {
+ lastErr = err;
+ continue;
+ }
+ }
+ throw Error(lastErr);
+ }
constructor(endpoints: string[]) {
super();
this.rpcs = _.map(endpoints, endpoint => {
@@ -25,17 +40,4 @@ export class RedundantRPCSubprovider extends Subprovider {
}
}
- private async firstSuccessAsync(rpcs: RpcSubprovider[], payload: JSONRPCPayload, next: () => void): Promise<any> {
- let lastErr;
- for (const rpc of rpcs) {
- try {
- const data = await promisify(rpc.handleRequest.bind(rpc))(payload, next);
- return data;
- } catch (err) {
- lastErr = err;
- continue;
- }
- }
- throw Error(lastErr);
- }
}
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index 2d0103499..403af9e78 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -1,5 +1,5 @@
-import * as _ from 'lodash';
import BigNumber from 'bignumber.js';
+import * as _ from 'lodash';
// Utility function to create a K:V from a list of strings
// Adapted from: https://basarat.gitbooks.io/typescript/content/docs/types/literal-types.html
@@ -16,7 +16,7 @@ export enum GenerateOrderSteps {
RemainingConfigs,
SignTransaction,
CopyAndShare,
-};
+}
export const Side = strEnum([
'receive',
@@ -45,11 +45,11 @@ export interface Token {
decimals: number;
isTracked: boolean;
isRegistered: boolean;
-};
+}
export interface TokenByAddress {
[address: string]: Token;
-};
+}
export interface TokenState {
allowance: BigNumber;
@@ -58,7 +58,7 @@ export interface TokenState {
export interface TokenStateByAddress {
[address: string]: TokenState;
-};
+}
export interface AssetToken {
address?: string;
@@ -67,14 +67,14 @@ export interface AssetToken {
export interface SideToAssetToken {
[side: string]: AssetToken;
-};
+}
export interface SignatureData {
hash: string;
r: string;
s: string;
v: number;
-};
+}
export interface HashData {
depositAmount: BigNumber;
@@ -138,7 +138,7 @@ export enum BalanceErrs {
wethConversionFailed,
sendFailed,
allowanceSettingFailed,
-};
+}
export const ActionTypes = strEnum([
// Portal
@@ -535,7 +535,7 @@ interface LedgerSignResult {
s: string;
}
interface LedgerCommunication {
- close_async: () => void;
+ close_async: () => Promise<void>;
}
export interface LedgerEthConnection {
getAddress_async: (derivationPath: string, askForDeviceConfirmation: boolean,
@@ -566,7 +566,7 @@ export interface TxParams {
export interface PublicNodeUrlsByNetworkId {
[networkId: number]: string[];
-};
+}
export interface JSONRPCPayload {
params: any[];
@@ -689,4 +689,4 @@ export enum WebsitePaths {
About = '/about',
Whitepaper = '/pdfs/0x_white_paper.pdf',
SmartContracts = '/docs/contracts',
-}
+} // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts
index 7fc52b035..77a6e3e38 100644
--- a/packages/website/ts/utils/constants.ts
+++ b/packages/website/ts/utils/constants.ts
@@ -1,14 +1,14 @@
+import BigNumber from 'bignumber.js';
import {
+ ContractAddresses,
+ Docs,
ExchangeContractErrs,
+ Networks,
PublicNodeUrlsByNetworkId,
- ZeroExJsDocSections,
SmartContractsDocSections,
- Docs,
- ContractAddresses,
- Networks,
WebsitePaths,
+ ZeroExJsDocSections,
} from 'ts/types';
-import BigNumber from 'bignumber.js';
const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs';
diff --git a/packages/website/ts/utils/doc_utils.ts b/packages/website/ts/utils/doc_utils.ts
index ca6e0dc52..594e3bae6 100644
--- a/packages/website/ts/utils/doc_utils.ts
+++ b/packages/website/ts/utils/doc_utils.ts
@@ -1,9 +1,9 @@
-import * as _ from 'lodash';
import findVersions = require('find-versions');
-import convert = require('xml-js');
+import * as _ from 'lodash';
+import {DoxityDocObj, S3FileObject, TypeDocNode, VersionToFileName} from 'ts/types';
import {constants} from 'ts/utils/constants';
import {utils} from 'ts/utils/utils';
-import {VersionToFileName, S3FileObject, TypeDocNode, DoxityDocObj} from 'ts/types';
+import convert = require('xml-js');
export const docUtils = {
async getVersionToFileNameAsync(s3DocJsonRoot: string):
@@ -29,12 +29,10 @@ export const docUtils = {
compact: true,
});
const responseObj = JSON.parse(responseJSONString);
- let fileObjs: S3FileObject[];
- if (_.isArray(responseObj.ListBucketResult.Contents)) {
- fileObjs = responseObj.ListBucketResult.Contents as S3FileObject[];
- } else {
- fileObjs = [responseObj.ListBucketResult.Contents];
- }
+ const fileObjs: S3FileObject[] = (_.isArray(responseObj.ListBucketResult.Contents)) ?
+ responseObj.ListBucketResult.Contents as S3FileObject[] :
+ [responseObj.ListBucketResult.Contents];
+
const versionFileNames = _.map(fileObjs, fileObj => {
return fileObj.Key._text;
});
diff --git a/packages/website/ts/utils/doxity_utils.ts b/packages/website/ts/utils/doxity_utils.ts
index 3bab0a69d..26e555b16 100644
--- a/packages/website/ts/utils/doxity_utils.ts
+++ b/packages/website/ts/utils/doxity_utils.ts
@@ -1,18 +1,18 @@
import * as _ from 'lodash';
import {
- DoxityDocObj,
- DoxityContractObj,
- DoxityAbiDoc,
- DoxityInput,
+ AbiTypes,
DocAgnosticFormat,
DocSection,
+ DoxityAbiDoc,
+ DoxityContractObj,
+ DoxityDocObj,
+ DoxityInput,
+ EventArg,
Parameter,
Property,
+ SolidityMethod,
Type,
TypeDocTypes,
- EventArg,
- AbiTypes,
- SolidityMethod,
} from 'ts/types';
export const doxityUtils = {
diff --git a/packages/website/ts/utils/error_reporter.ts b/packages/website/ts/utils/error_reporter.ts
index a9731c4d4..40991afbf 100644
--- a/packages/website/ts/utils/error_reporter.ts
+++ b/packages/website/ts/utils/error_reporter.ts
@@ -1,7 +1,7 @@
-import {utils} from 'ts/utils/utils';
-import {constants} from 'ts/utils/constants';
-import {configs} from 'ts/utils/configs';
import {Environments} from 'ts/types';
+import {configs} from 'ts/utils/configs';
+import {constants} from 'ts/utils/constants';
+import {utils} from 'ts/utils/utils';
// Suggested way to include Rollbar with Webpack
// https://github.com/rollbar/rollbar.js/tree/master/examples/webpack
@@ -32,7 +32,7 @@ import Rollbar = require('../../public/js/rollbar.umd.nojson.min.js');
const rollbar = Rollbar.init(rollbarConfig);
export const errorReporter = {
- reportAsync(err: Error): Promise<any> {
+ async reportAsync(err: Error): Promise<any> {
if (configs.ENVIRONMENT === Environments.DEVELOPMENT) {
return; // Let's not log development errors to rollbar
}
diff --git a/packages/website/ts/utils/typedoc_utils.ts b/packages/website/ts/utils/typedoc_utils.ts
index b3d0f7d90..bb2f7745a 100644
--- a/packages/website/ts/utils/typedoc_utils.ts
+++ b/packages/website/ts/utils/typedoc_utils.ts
@@ -1,25 +1,25 @@
-import * as _ from 'lodash';
import compareVersions = require('compare-versions');
-import {constants} from 'ts/utils/constants';
-import {utils} from 'ts/utils/utils';
+import * as _ from 'lodash';
import {
- TypeDocNode,
- KindString,
- ZeroExJsDocSections,
- MenuSubsectionsBySection,
- TypeDocType,
- Type,
+ CustomType,
+ CustomTypeChild,
DocAgnosticFormat,
DocSection,
- TypescriptMethod,
+ IndexSignature,
+ KindString,
+ MenuSubsectionsBySection,
Parameter,
Property,
- CustomType,
- IndexSignature,
- CustomTypeChild,
- TypeParameter,
+ Type,
+ TypeDocNode,
+ TypeDocType,
TypeDocTypes,
+ TypeParameter,
+ TypescriptMethod,
+ ZeroExJsDocSections,
} from 'ts/types';
+import {constants} from 'ts/utils/constants';
+import {utils} from 'ts/utils/utils';
const TYPES_MODULE_PATH = '"src/types"';
diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts
index eb4c5be3a..8b23b6a40 100644
--- a/packages/website/ts/utils/utils.ts
+++ b/packages/website/ts/utils/utils.ts
@@ -1,23 +1,24 @@
+import {ExchangeContractErrs, ZeroExError} from '0x.js';
+import BigNumber from 'bignumber.js';
+import deepEqual = require('deep-equal');
+import ethUtil = require('ethereumjs-util');
+import isMobile = require('is-mobile');
import * as _ from 'lodash';
+import * as moment from 'moment';
import {
- SideToAssetToken,
- SignatureData,
+ EtherscanLinkSuffixes,
+ Networks,
Order,
- Side,
- TokenByAddress,
OrderParty,
ScreenWidths,
- EtherscanLinkSuffixes,
+ Side,
+ SideToAssetToken,
+ SignatureData,
Token,
- Networks,
+ TokenByAddress,
} from 'ts/types';
-import * as moment from 'moment';
-import isMobile = require('is-mobile');
-import * as u2f from 'ts/vendor/u2f_api';
-import deepEqual = require('deep-equal');
-import ethUtil = require('ethereumjs-util');
-import BigNumber from 'bignumber.js';
import {constants} from 'ts/utils/constants';
+import * as u2f from 'ts/vendor/u2f_api';
const LG_MIN_EM = 64;
const MD_MIN_EM = 52;
@@ -101,7 +102,7 @@ export const utils = {
console.log(message);
/* tslint:enable */
},
- sleepAsync(ms: number) {
+ async sleepAsync(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
},
deepEqual(actual: any, expected: any, opts?: {strict: boolean}) {
@@ -212,4 +213,53 @@ export const utils = {
const isUniqueSymbol = _.isUndefined(tokenWithSameSymbolIfExists);
return isUniqueName && isUniqueSymbol;
},
+ zeroExErrToHumanReadableErrMsg(error: ZeroExError|ExchangeContractErrs, takerAddress: string): string {
+ const ZeroExErrorToHumanReadableError: {[error: string]: string} = {
+ [ZeroExError.ExchangeContractDoesNotExist]: 'Exchange contract does not exist',
+ [ZeroExError.EtherTokenContractDoesNotExist]: 'EtherToken contract does not exist',
+ [ZeroExError.TokenTransferProxyContractDoesNotExist]: 'TokenTransferProxy contract does not exist',
+ [ZeroExError.TokenRegistryContractDoesNotExist]: 'TokenRegistry contract does not exist',
+ [ZeroExError.TokenContractDoesNotExist]: 'Token contract does not exist',
+ [ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
+ [ZeroExError.UnhandledError]: 'Unhandled error occured',
+ [ZeroExError.UserHasNoAssociatedAddress]: 'User has no addresses available',
+ [ZeroExError.InvalidSignature]: 'Order signature is not valid',
+ [ZeroExError.ContractNotDeployedOnNetwork]: 'Contract is not deployed on the detected network',
+ [ZeroExError.InvalidJump]: 'Invalid jump occured while executing the transaction',
+ [ZeroExError.OutOfGas]: 'Transaction ran out of gas',
+ [ZeroExError.NoNetworkId]: 'No network id detected',
+ };
+ const exchangeContractErrorToHumanReadableError: {[error: string]: string} = {
+ [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.OrderFillAmountZero]: 'Order fill amount can\'t be 0',
+ [ExchangeContractErrs.OrderRemainingFillAmountZero]:
+ 'This order has already been completely filled or cancelled',
+ [ExchangeContractErrs.OrderFillRoundingError]: 'Rounding error will occur when filling this order',
+ [ExchangeContractErrs.InsufficientTakerBalance]:
+ 'Taker no longer has a sufficient balance to complete this order',
+ [ExchangeContractErrs.InsufficientTakerAllowance]:
+ 'Taker no longer has a sufficient allowance to complete this order',
+ [ExchangeContractErrs.InsufficientMakerBalance]:
+ 'Maker no longer has a sufficient balance to complete this order',
+ [ExchangeContractErrs.InsufficientMakerAllowance]:
+ 'Maker no longer has a sufficient allowance to complete this order',
+ [ExchangeContractErrs.InsufficientTakerFeeBalance]: 'Taker no longer has a sufficient balance to pay fees',
+ [ExchangeContractErrs.InsufficientTakerFeeAllowance]:
+ 'Taker no longer has a sufficient allowance to pay fees',
+ [ExchangeContractErrs.InsufficientMakerFeeBalance]: 'Maker no longer has a sufficient balance to pay fees',
+ [ExchangeContractErrs.InsufficientMakerFeeAllowance]:
+ 'Maker no longer has a sufficient allowance to pay fees',
+ [ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker]:
+ `This order can only be filled by ${takerAddress}`,
+ [ExchangeContractErrs.InsufficientRemainingFillAmount]:
+ 'Insufficient remaining fill amount',
+ };
+ const humanReadableErrorMsg = exchangeContractErrorToHumanReadableError[error] ||
+ ZeroExErrorToHumanReadableError[error];
+ return humanReadableErrorMsg;
+ },
};
diff --git a/packages/website/ts/web3_wrapper.ts b/packages/website/ts/web3_wrapper.ts
index 24279f5d2..c43436c7e 100644
--- a/packages/website/ts/web3_wrapper.ts
+++ b/packages/website/ts/web3_wrapper.ts
@@ -1,8 +1,8 @@
-import * as _ from 'lodash';
-import Web3 = require('web3');
import BigNumber from 'bignumber.js';
import promisify = require('es6-promisify');
+import * as _ from 'lodash';
import {Dispatcher} from 'ts/redux/dispatcher';
+import Web3 = require('web3');
export class Web3Wrapper {
private dispatcher: Dispatcher;
@@ -21,6 +21,7 @@ export class Web3Wrapper {
this.web3 = new Web3();
this.web3.setProvider(provider);
+ // tslint:disable-next-line:no-floating-promises
this.startEmittingNetworkConnectionAndUserBalanceStateAsync();
}
public isAddress(address: string) {
@@ -35,7 +36,7 @@ export class Web3Wrapper {
if (_.isEmpty(addresses)) {
return '';
}
- return (addresses as string[])[0];
+ return (addresses)[0];
}
public async getNodeVersionAsync() {
const nodeVersion = await promisify(this.web3.version.getNode)();