aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts')
-rw-r--r--packages/website/ts/blockchain.ts321
-rw-r--r--packages/website/ts/components/fill_order.tsx122
-rw-r--r--packages/website/ts/globals.d.ts10
-rw-r--r--packages/website/ts/types.ts19
-rw-r--r--packages/website/ts/web3_wrapper.ts7
5 files changed, 232 insertions, 247 deletions
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index 7851ea8ff..b13c48a65 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -1,60 +1,59 @@
+import * as _ from 'lodash';
+import * as React from 'react';
import {
- BlockParam,
- DecodedLogEvent,
+ ZeroEx,
+ ZeroExError,
ExchangeContractErrs,
ExchangeContractEventArgs,
ExchangeEvents,
+ SubscriptionOpts,
IndexedFilterValues,
- LogCancelContractEventArgs,
+ DecodedLogEvent,
+ BlockParam,
LogFillContractEventArgs,
- LogWithDecodedArgs,
- Order,
- SignedOrder,
- SubscriptionOpts,
+ LogCancelContractEventArgs,
Token as ZeroExToken,
+ LogWithDecodedArgs,
TransactionReceiptWithDecodedLogs,
- ZeroEx,
- ZeroExError,
+ SignedOrder,
+ Order,
} from '0x.js';
import BigNumber from 'bignumber.js';
-import compareVersions = require('compare-versions');
+import Web3 = require('web3');
import promisify = require('es6-promisify');
-import ethUtil = require('ethereumjs-util');
import findVersions = require('find-versions');
-import * as _ from 'lodash';
-import * as React from 'react';
+import compareVersions = require('compare-versions');
import contract = require('truffle-contract');
-import {TokenSendCompleted} from 'ts/components/flash_messages/token_send_completed';
+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 {trackedTokenStorage} from 'ts/local_storage/tracked_token_storage';
-import {tradeHistoryStorage} from 'ts/local_storage/trade_history_storage';
-import {Dispatcher} from 'ts/redux/dispatcher';
+import {TokenSendCompleted} from 'ts/components/flash_messages/token_send_completed';
+import {RedundantRPCSubprovider} from 'ts/subproviders/redundant_rpc_subprovider';
import {InjectedWeb3SubProvider} from 'ts/subproviders/injected_web3_subprovider';
import {ledgerWalletSubproviderFactory} from 'ts/subproviders/ledger_wallet_subprovider_factory';
-import {RedundantRPCSubprovider} from 'ts/subproviders/redundant_rpc_subprovider';
+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 {
- BlockchainCallErrs,
BlockchainErrs,
- ContractInstance,
+ Token,
+ SignatureData,
+ Side,
ContractResponse,
- EtherscanLinkSuffixes,
- LedgerWalletSubprovider,
+ BlockchainCallErrs,
+ ContractInstance,
ProviderType,
- Side,
- SignatureData,
- Token,
+ LedgerWalletSubprovider,
+ EtherscanLinkSuffixes,
TokenByAddress,
TokenStateByAddress,
} from 'ts/types';
-import {configs} from 'ts/utils/configs';
-import {constants} from 'ts/utils/constants';
-import {errorReporter} from 'ts/utils/error_reporter';
-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 {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 * as MintableArtifacts from '../contracts/Mintable.json';
const ALLOWANCE_TO_ZERO_GAS_AMOUNT = 45730;
@@ -73,116 +72,9 @@ export class Blockchain {
private cachedProvider: Web3.Provider;
private ledgerSubProvider: LedgerWalletSubprovider;
private zrxPollIntervalId: number;
- public static toHumanReadableErrorMsg(error: ZeroExError|ExchangeContractErrs, takerAddress: string): string {
- const ZeroExErrorToHumanReadableError: {[error: string]: string} = {
- [ZeroExError.TokenTransferProxyContractDoesNotExist]: 'Token transfer proxy contract does not exist',
- [ZeroExError.TokenContractDoesNotExist]: 'Token contract does not exist',
- [ZeroExError.ZRXContractDoesNotExist]: 'ZRX contract does not exist',
- [ZeroExError.EtherTokenContractDoesNotExist]: 'Ether token 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;
- }
- private static async getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number): Promise<Web3.Provider> {
- 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 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 onPageLoadAsync() {
- if (document.readyState === 'complete') {
- return; // Already loaded
- }
- return new Promise((resolve, reject) => {
- window.onload = resolve;
- });
- }
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) {
@@ -265,8 +157,8 @@ export class Blockchain {
this.web3Wrapper.destroy();
const shouldPollUserAddress = false;
this.web3Wrapper = new Web3Wrapper(this.dispatcher, provider, this.networkId, shouldPollUserAddress);
- this.zeroEx.setProvider(provider, this.networkId);
- this.postInstantiationOrUpdatingProviderZeroEx();
+ await this.zeroEx.setProviderAsync(provider);
+ await this.postInstantiationOrUpdatingProviderZeroExAsync();
break;
}
@@ -277,8 +169,8 @@ export class Blockchain {
provider = this.cachedProvider;
const shouldPollUserAddress = true;
this.web3Wrapper = new Web3Wrapper(this.dispatcher, provider, this.networkId, shouldPollUserAddress);
- this.zeroEx.setProvider(provider, this.networkId);
- this.postInstantiationOrUpdatingProviderZeroEx();
+ await this.zeroEx.setProviderAsync(provider);
+ await this.postInstantiationOrUpdatingProviderZeroExAsync();
delete this.ledgerSubProvider;
delete this.cachedProvider;
break;
@@ -316,7 +208,7 @@ export class Blockchain {
amountInBaseUnits,
}));
}
- public portalOrderToSignedOrder(maker: string, takerIfExists: string, makerTokenAddress: string,
+ public portalOrderToSignedOrder(maker: string, taker: string, makerTokenAddress: string,
takerTokenAddress: string, makerTokenAmount: BigNumber,
takerTokenAmount: BigNumber, makerFee: BigNumber,
takerFee: BigNumber, expirationUnixTimestampSec: BigNumber,
@@ -324,7 +216,7 @@ export class Blockchain {
signatureData: SignatureData, salt: BigNumber): SignedOrder {
const ecSignature = signatureData;
const exchangeContractAddress = this.getExchangeContractAddressIfExists();
- const taker = _.isEmpty(takerIfExists) ? constants.NULL_ADDRESS : takerIfExists;
+ taker = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
const signedOrder = {
ecSignature,
exchangeContractAddress,
@@ -381,6 +273,51 @@ 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> {
@@ -509,7 +446,6 @@ 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(
@@ -549,7 +485,7 @@ export class Blockchain {
// Start a subscription for new logs
const exchangeAddress = this.getExchangeContractAddressIfExists();
- const subscriptionId = this.zeroEx.exchange.subscribe(
+ const subscriptionId = await this.zeroEx.exchange.subscribeAsync(
ExchangeEvents.LogFill, indexFilterValues,
async (err: Error, decodedLogEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
const decodedLog = decodedLogEvent.log;
@@ -557,9 +493,7 @@ 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 {
@@ -595,7 +529,7 @@ export class Blockchain {
}
}
private async convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
- const args = decodedLog.args;
+ const args = decodedLog.args as LogFillContractEventArgs;
const blockTimestamp = await this.web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash);
const fill = {
filledTakerTokenAmount: args.filledTakerTokenAmount,
@@ -614,7 +548,7 @@ export class Blockchain {
return fill;
}
private doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs<LogFillContractEventArgs>) {
- const args = decodedLog.args;
+ const args = decodedLog.args as LogFillContractEventArgs;
const isUserMakerOrTaker = args.maker === this.userAddress ||
args.taker === this.userAddress;
return isUserMakerOrTaker;
@@ -660,7 +594,7 @@ export class Blockchain {
return tokenByAddress;
}
private async onPageLoadInitFireAndForgetAsync() {
- await Blockchain.onPageLoadAsync(); // wait for page to load
+ await this.onPageLoadAsync(); // wait for page to load
// Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
// order to properly instantiate the web3Wrapper. Since we must use the async call, we cannot
@@ -678,34 +612,81 @@ export class Blockchain {
}
}
- const provider = await Blockchain.getProviderAsync(injectedWeb3, networkId);
- const zeroExConfig = {
- networkId: this.networkId,
- };
- this.zeroEx = new ZeroEx(provider, zeroExConfig);
- this.updateProviderName(injectedWeb3);
+ const provider = await this.getProviderAsync(injectedWeb3, networkId);
+ this.zeroEx = new ZeroEx(provider);
+ await this.updateProviderName(injectedWeb3);
const shouldPollUserAddress = true;
this.web3Wrapper = new Web3Wrapper(this.dispatcher, provider, networkId, shouldPollUserAddress);
- this.postInstantiationOrUpdatingProviderZeroEx();
+ await this.postInstantiationOrUpdatingProviderZeroExAsync();
}
// This method should always be run after instantiating or updating the provider
// of the ZeroEx instance.
- private postInstantiationOrUpdatingProviderZeroEx(): void {
+ private async postInstantiationOrUpdatingProviderZeroExAsync() {
utils.assert(!_.isUndefined(this.zeroEx), 'ZeroEx must be instantiated.');
- this.exchangeAddress = this.zeroEx.exchange.getContractAddress();
+ this.exchangeAddress = await this.zeroEx.exchange.getContractAddressAsync();
}
- private updateProviderName(injectedWeb3: Web3): void {
+ private updateProviderName(injectedWeb3: Web3) {
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
const providerName = doesInjectedWeb3Exist ?
- Blockchain.getNameGivenProvider(injectedWeb3.currentProvider) :
+ this.getNameGivenProvider(injectedWeb3.currentProvider) :
constants.PUBLIC_PROVIDER_NAME;
this.dispatcher.updateInjectedProviderName(providerName);
}
// This is only ever called by the LedgerWallet subprovider in order to retrieve
// the current networkId without this value going stale.
- private getBlockchainNetworkId(): number {
+ 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');
@@ -795,4 +776,12 @@ export class Blockchain {
}
}
}
-} // tslint:disable:max-file-line-count
+ private async onPageLoadAsync() {
+ if (document.readyState === 'complete') {
+ return; // Already loaded
+ }
+ return new Promise((resolve, reject) => {
+ window.onload = resolve;
+ });
+ }
+}
diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx
index 4077e4f8b..dc965283e 100644
--- a/packages/website/ts/components/fill_order.tsx
+++ b/packages/website/ts/components/fill_order.tsx
@@ -1,44 +1,44 @@
-import {Order as ZeroExOrder, ZeroEx} from '0x.js';
+import * as _ from 'lodash';
+import * as React from 'react';
import * as accounting from 'accounting';
+import {Link} from 'react-router-dom';
+import {ZeroEx, Order as ZeroExOrder} from '0x.js';
+import * as moment from 'moment';
import BigNumber from 'bignumber.js';
-import * as _ from 'lodash';
-import {Card, CardHeader, CardText} from 'material-ui/Card';
-import Divider from 'material-ui/Divider';
import Paper from 'material-ui/Paper';
-import RaisedButton from 'material-ui/RaisedButton';
+import {Card, CardText, CardHeader} from 'material-ui/Card';
+import Divider from 'material-ui/Divider';
import TextField from 'material-ui/TextField';
-import * as moment from 'moment';
-import * as React from 'react';
-import {Link} from 'react-router-dom';
-import {Blockchain} from 'ts/blockchain';
-import {TrackTokenConfirmationDialog} from 'ts/components/dialogs/track_token_confirmation_dialog';
-import {FillOrderJSON} from 'ts/components/fill_order_json';
-import {FillWarningDialog} from 'ts/components/fill_warning_dialog';
-import {TokenAmountInput} from 'ts/components/inputs/token_amount_input';
-import {Alert} from 'ts/components/ui/alert';
-import {EthereumAddress} from 'ts/components/ui/ethereum_address';
-import {Identicon} from 'ts/components/ui/identicon';
-import {VisualOrder} from 'ts/components/visual_order';
-import {trackedTokenStorage} from 'ts/local_storage/tracked_token_storage';
-import {Dispatcher} from 'ts/redux/dispatcher';
-import {orderSchema} from 'ts/schemas/order_schema';
-import {SchemaValidator} from 'ts/schemas/validator';
+import RaisedButton from 'material-ui/RaisedButton';
+import {utils} from 'ts/utils/utils';
+import {constants} from 'ts/utils/constants';
import {
- AlertTypes,
- BlockchainErrs,
- ContractResponse,
- ExchangeContractErrs,
- Order,
- OrderToken,
Side,
- Token,
TokenByAddress,
TokenStateByAddress,
+ Order,
+ BlockchainErrs,
+ OrderToken,
+ Token,
+ ExchangeContractErrs,
+ AlertTypes,
+ ContractResponse,
WebsitePaths,
} from 'ts/types';
-import {constants} from 'ts/utils/constants';
+import {Alert} from 'ts/components/ui/alert';
+import {Identicon} from 'ts/components/ui/identicon';
+import {EthereumAddress} from 'ts/components/ui/ethereum_address';
+import {TokenAmountInput} from 'ts/components/inputs/token_amount_input';
+import {FillWarningDialog} from 'ts/components/fill_warning_dialog';
+import {FillOrderJSON} from 'ts/components/fill_order_json';
+import {VisualOrder} from 'ts/components/visual_order';
+import {SchemaValidator} from 'ts/schemas/validator';
+import {orderSchema} from 'ts/schemas/order_schema';
+import {Dispatcher} from 'ts/redux/dispatcher';
+import {Blockchain} from 'ts/blockchain';
import {errorReporter} from 'ts/utils/error_reporter';
-import {utils} from 'ts/utils/utils';
+import {trackedTokenStorage} from 'ts/local_storage/tracked_token_storage';
+import {TrackTokenConfirmationDialog} from 'ts/components/dialogs/track_token_confirmation_dialog';
const CUSTOM_LIGHT_GRAY = '#BBBBBB';
@@ -76,31 +76,6 @@ interface FillOrderState {
export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
private validator: SchemaValidator;
- private static formatCurrencyAmount(amount: BigNumber, decimals: number): number {
- const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
- const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
- return roundedUnitAmount;
- }
- private static renderFillSuccessMsg() {
- return (
- <div>
- Order successfully filled. See the trade details in your{' '}
- <Link
- to={`${WebsitePaths.Portal}/trades`}
- style={{color: 'white'}}
- >
- trade history
- </Link>
- </div>
- );
- }
- private static renderCancelSuccessMsg() {
- return (
- <div>
- Order successfully cancelled.
- </div>
- );
- }
constructor(props: FillOrderProps) {
super(props);
this.state = {
@@ -244,7 +219,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
let orderReceiveAmount = 0;
if (!_.isUndefined(this.props.orderFillAmount)) {
const orderReceiveAmountBigNumber = exchangeRate.mul(this.props.orderFillAmount);
- orderReceiveAmount = FillOrder.formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals);
+ orderReceiveAmount = this.formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals);
}
const isUserMaker = !_.isUndefined(this.state.parsedOrder) &&
this.state.parsedOrder.maker.address === this.props.userAddress;
@@ -324,7 +299,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
{this.state.didCancelOrderSucceed &&
<Alert
type={AlertTypes.SUCCESS}
- message={FillOrder.renderCancelSuccessMsg()}
+ message={this.renderCancelSuccessMsg()}
/>
}
</div> :
@@ -341,7 +316,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
{this.state.didFillOrderSucceed &&
<Alert
type={AlertTypes.SUCCESS}
- message={FillOrder.renderFillSuccessMsg()}
+ message={this.renderFillSuccessMsg()}
/>
}
</div>
@@ -350,6 +325,26 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
</div>
);
}
+ private renderFillSuccessMsg() {
+ return (
+ <div>
+ Order successfully filled. See the trade details in your{' '}
+ <Link
+ to={`${WebsitePaths.Portal}/trades`}
+ style={{color: 'white'}}
+ >
+ trade history
+ </Link>
+ </div>
+ );
+ }
+ private renderCancelSuccessMsg() {
+ return (
+ <div>
+ Order successfully cancelled.
+ </div>
+ );
+ }
private onFillOrderClick() {
if (!this.state.isMakerTokenAddressInRegistry || !this.state.isTakerTokenAddressInRegistry) {
this.setState({
@@ -568,7 +563,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
signedOrder, takerFillAmount, this.props.userAddress);
} catch (err) {
- globalErrMsg = Blockchain.toHumanReadableErrorMsg(err.message, parsedOrder.taker.address);
+ globalErrMsg = this.props.blockchain.toHumanReadableErrorMsg(err.message, parsedOrder.taker.address);
}
}
if (!_.isEmpty(globalErrMsg)) {
@@ -657,7 +652,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(
signedOrder, availableTakerTokenAmount);
} catch (err) {
- globalErrMsg = Blockchain.toHumanReadableErrorMsg(err.message, parsedOrder.taker.address);
+ globalErrMsg = this.props.blockchain.toHumanReadableErrorMsg(err.message, parsedOrder.taker.address);
}
if (!_.isEmpty(globalErrMsg)) {
this.setState({
@@ -694,6 +689,11 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
return;
}
}
+ private formatCurrencyAmount(amount: BigNumber, decimals: number): number {
+ const unitAmount = ZeroEx.toUnitAmount(amount, decimals);
+ const roundedUnitAmount = Math.round(unitAmount.toNumber() * 100000) / 100000;
+ return roundedUnitAmount;
+ }
private onToggleTrackConfirmDialog(didConfirmTokenTracking: boolean) {
if (!didConfirmTokenTracking) {
this.setState({
@@ -711,4 +711,4 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
tokensToTrack: [],
});
}
-} // tslint:disable:max-file-line-count
+}
diff --git a/packages/website/ts/globals.d.ts b/packages/website/ts/globals.d.ts
index a7f1c1f18..ee449ecfd 100644
--- a/packages/website/ts/globals.d.ts
+++ b/packages/website/ts/globals.d.ts
@@ -126,7 +126,7 @@ declare function isMobile(): boolean;
declare module 'is-mobile' {
export = isMobile;
}
-// tslint:disable:max-classes-per-file
+
// web3-provider-engine declarations
declare class Subprovider {}
declare module 'web3-provider-engine/subproviders/subprovider' {
@@ -148,9 +148,7 @@ 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/types.ts b/packages/website/ts/types.ts
index c1dcb35c5..2d0103499 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -1,5 +1,5 @@
-import BigNumber from 'bignumber.js';
import * as _ from 'lodash';
+import BigNumber from 'bignumber.js';
// 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
@@ -566,7 +566,7 @@ export interface TxParams {
export interface PublicNodeUrlsByNetworkId {
[networkId: number]: string[];
-}
+};
export interface JSONRPCPayload {
params: any[];
@@ -690,4 +690,3 @@ export enum WebsitePaths {
Whitepaper = '/pdfs/0x_white_paper.pdf',
SmartContracts = '/docs/contracts',
}
-// tslint:disable:max-file-line-count
diff --git a/packages/website/ts/web3_wrapper.ts b/packages/website/ts/web3_wrapper.ts
index c43436c7e..24279f5d2 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,7 +21,6 @@ export class Web3Wrapper {
this.web3 = new Web3();
this.web3.setProvider(provider);
- // tslint:disable-next-line:no-floating-promises
this.startEmittingNetworkConnectionAndUserBalanceStateAsync();
}
public isAddress(address: string) {
@@ -36,7 +35,7 @@ export class Web3Wrapper {
if (_.isEmpty(addresses)) {
return '';
}
- return (addresses)[0];
+ return (addresses as string[])[0];
}
public async getNodeVersionAsync() {
const nodeVersion = await promisify(this.web3.version.getNode)();