Merge branch 'development' into feature/updateReadmes
* development: (35 commits) Remove etherToken from smart contract docs Update new WETH addresses and localStorage clearance key Fix merge Remove re-assignment Fix scrolling topBar on Portal Fix overflow issue on calculated fillAmount Fix faulty import Refactor remaining _.assign to spread operator Move muiTheme into it's own module Add WETH remove extra space Remove binding on prop passed callbacks Add airtable tasks to TODO's Refactor configs and constants, standardize on uppercase/snakecase, alphebetize, rename for logical grouping Sort colors into color spectrum remove unused style standarize on `grey` over `gray` spelling and other color related fixes Standardize colors to always be in uppercase hex and consolidate material-ui greys Consolidate all custom colors and material-ui colors into a colors module Remove unused `location` prop ...
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
"dependencies": {
|
||||
"0x.js": "~0.27.2",
|
||||
"@0xproject/subproviders": "^0.1.0",
|
||||
"@0xproject/utils": "^0.1.0",
|
||||
"accounting": "^0.4.1",
|
||||
"basscss": "^8.0.3",
|
||||
"bignumber.js": "~4.1.0",
|
||||
|
@@ -77,21 +77,21 @@ export class Blockchain {
|
||||
}
|
||||
private static getNameGivenProvider(provider: Web3.Provider): string {
|
||||
if (!_.isUndefined((provider as any).isMetaMask)) {
|
||||
return constants.METAMASK_PROVIDER_NAME;
|
||||
return constants.PROVIDER_NAME_METAMASK;
|
||||
}
|
||||
|
||||
// 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.PROVIDER_NAME_PARITY_SIGNER;
|
||||
}
|
||||
|
||||
return constants.GENERIC_PROVIDER_NAME;
|
||||
return constants.PROVIDER_NAME_GENERIC;
|
||||
}
|
||||
private static async getProviderAsync(injectedWeb3: Web3, networkIdIfExists: number) {
|
||||
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
|
||||
const publicNodeUrlsIfExistsForNetworkId = constants.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
|
||||
const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
|
||||
const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
|
||||
|
||||
let provider;
|
||||
@@ -114,11 +114,11 @@ export class Blockchain {
|
||||
// injected into their browser.
|
||||
provider = new ProviderEngine();
|
||||
provider.addProvider(new FilterSubprovider());
|
||||
const networkId = configs.isMainnetEnabled ?
|
||||
constants.MAINNET_NETWORK_ID :
|
||||
constants.TESTNET_NETWORK_ID;
|
||||
const networkId = configs.IS_MAINNET_ENABLED ?
|
||||
constants.NETWORK_ID_MAINNET :
|
||||
constants.NETWORK_ID_TESTNET;
|
||||
provider.addProvider(new RedundantRPCSubprovider(
|
||||
constants.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId],
|
||||
configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId],
|
||||
));
|
||||
provider.start();
|
||||
}
|
||||
@@ -135,11 +135,11 @@ export class Blockchain {
|
||||
const isConnected = !_.isUndefined(newNetworkId);
|
||||
if (!isConnected) {
|
||||
this.networkId = newNetworkId;
|
||||
this.dispatcher.encounteredBlockchainError(BlockchainErrs.DISCONNECTED_FROM_ETHEREUM_NODE);
|
||||
this.dispatcher.encounteredBlockchainError(BlockchainErrs.DisconnectedFromEthereumNode);
|
||||
this.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
} else if (this.networkId !== newNetworkId) {
|
||||
this.networkId = newNetworkId;
|
||||
this.dispatcher.encounteredBlockchainError('');
|
||||
this.dispatcher.encounteredBlockchainError(BlockchainErrs.NoError);
|
||||
await this.fetchTokenInformationAsync();
|
||||
await this.rehydrateStoreWithContractEvents();
|
||||
}
|
||||
@@ -158,6 +158,14 @@ export class Blockchain {
|
||||
}
|
||||
public async isAddressInTokenRegistryAsync(tokenAddress: string): Promise<boolean> {
|
||||
utils.assert(!_.isUndefined(this.zeroEx), 'ZeroEx must be instantiated.');
|
||||
// HACK: temporarily whitelist the new WETH token address `as if` they were
|
||||
// already in the tokenRegistry.
|
||||
// TODO: Remove this hack once we've updated the TokenRegistries
|
||||
// Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
|
||||
if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN &&
|
||||
tokenAddress === configs.NEW_WRAPPED_ETHERS[this.networkId]) {
|
||||
return true;
|
||||
}
|
||||
const tokenIfExists = await this.zeroEx.tokenRegistry.getTokenIfExistsAsync(tokenAddress);
|
||||
return !_.isUndefined(tokenIfExists);
|
||||
}
|
||||
@@ -186,7 +194,7 @@ export class Blockchain {
|
||||
// later on in the logic.
|
||||
let provider;
|
||||
switch (providerType) {
|
||||
case ProviderType.LEDGER: {
|
||||
case ProviderType.Ledger: {
|
||||
const isU2FSupported = await utils.isU2FSupportedAsync();
|
||||
if (!isU2FSupported) {
|
||||
throw new Error('Cannot update providerType to LEDGER without U2F support');
|
||||
@@ -205,11 +213,11 @@ export class Blockchain {
|
||||
this.ledgerSubprovider = new LedgerSubprovider(ledgerWalletConfigs);
|
||||
provider.addProvider(this.ledgerSubprovider);
|
||||
provider.addProvider(new FilterSubprovider());
|
||||
const networkId = configs.isMainnetEnabled ?
|
||||
constants.MAINNET_NETWORK_ID :
|
||||
constants.TESTNET_NETWORK_ID;
|
||||
const networkId = configs.IS_MAINNET_ENABLED ?
|
||||
constants.NETWORK_ID_MAINNET :
|
||||
constants.NETWORK_ID_TESTNET;
|
||||
provider.addProvider(new RedundantRPCSubprovider(
|
||||
constants.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId],
|
||||
configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId],
|
||||
));
|
||||
provider.start();
|
||||
this.web3Wrapper.destroy();
|
||||
@@ -220,7 +228,7 @@ export class Blockchain {
|
||||
break;
|
||||
}
|
||||
|
||||
case ProviderType.INJECTED: {
|
||||
case ProviderType.Injected: {
|
||||
if (_.isUndefined(this.cachedProvider)) {
|
||||
return; // Going from injected to injected, so we noop
|
||||
}
|
||||
@@ -241,8 +249,8 @@ export class Blockchain {
|
||||
await this.fetchTokenInformationAsync();
|
||||
}
|
||||
public async setProxyAllowanceAsync(token: Token, amountInBaseUnits: BigNumber): Promise<void> {
|
||||
utils.assert(this.isValidAddress(token.address), BlockchainCallErrs.TOKEN_ADDRESS_IS_INVALID);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES);
|
||||
utils.assert(this.isValidAddress(token.address), BlockchainCallErrs.TokenAddressIsInvalid);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
|
||||
utils.assert(!_.isUndefined(this.zeroEx), 'ZeroEx must be instantiated.');
|
||||
|
||||
const txHash = await this.zeroEx.token.setProxyAllowanceAsync(
|
||||
@@ -258,7 +266,7 @@ export class Blockchain {
|
||||
token.address, this.userAddress, toAddress, amountInBaseUnits,
|
||||
);
|
||||
await this.showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
|
||||
const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.tx);
|
||||
const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
|
||||
this.dispatcher.showFlashMessage(React.createElement(TokenSendCompleted, {
|
||||
etherScanLinkIfExists,
|
||||
token,
|
||||
@@ -294,7 +302,7 @@ export class Blockchain {
|
||||
}
|
||||
public async fillOrderAsync(signedOrder: SignedOrder,
|
||||
fillTakerTokenAmount: BigNumber): Promise<BigNumber> {
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
|
||||
|
||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||
|
||||
@@ -346,7 +354,7 @@ export class Blockchain {
|
||||
return this.web3Wrapper.isAddress(lowercaseAddress);
|
||||
}
|
||||
public async pollTokenBalanceAsync(token: Token) {
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
|
||||
|
||||
const [currBalance] = await this.getTokenBalanceAndAllowanceAsync(this.userAddress, token.address);
|
||||
|
||||
@@ -375,7 +383,7 @@ export class Blockchain {
|
||||
return signatureData;
|
||||
}
|
||||
public async mintTestTokensAsync(token: Token) {
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
|
||||
|
||||
const mintableContract = await this.instantiateContractIfExistsAsync(MintableArtifacts, token.address);
|
||||
await mintableContract.mint(constants.MINT_AMOUNT, {
|
||||
@@ -390,14 +398,14 @@ export class Blockchain {
|
||||
}
|
||||
public async convertEthToWrappedEthTokensAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
|
||||
utils.assert(!_.isUndefined(this.zeroEx), 'ZeroEx must be instantiated.');
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
|
||||
|
||||
const txHash = await this.zeroEx.etherToken.depositAsync(etherTokenAddress, amount, this.userAddress);
|
||||
await this.showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
|
||||
}
|
||||
public async convertWrappedEthTokensToEthAsync(etherTokenAddress: string, amount: BigNumber): Promise<void> {
|
||||
utils.assert(!_.isUndefined(this.zeroEx), 'ZeroEx must be instantiated.');
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
|
||||
|
||||
const txHash = await this.zeroEx.etherToken.withdrawAsync(etherTokenAddress, amount, this.userAddress);
|
||||
await this.showEtherScanLinkAndAwaitTransactionMinedAsync(txHash);
|
||||
@@ -463,7 +471,7 @@ export class Blockchain {
|
||||
}
|
||||
private async showEtherScanLinkAndAwaitTransactionMinedAsync(
|
||||
txHash: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.tx);
|
||||
const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx);
|
||||
this.dispatcher.showFlashMessage(React.createElement(TransactionSubmitted, {
|
||||
etherScanLinkIfExists,
|
||||
}));
|
||||
@@ -491,7 +499,7 @@ export class Blockchain {
|
||||
}
|
||||
private async startListeningForExchangeLogFillEventsAsync(indexFilterValues: IndexedFilterValues): Promise<void> {
|
||||
utils.assert(!_.isUndefined(this.zeroEx), 'ZeroEx must be instantiated.');
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES);
|
||||
utils.assert(this.doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
|
||||
|
||||
// Fetch historical logs
|
||||
await this.fetchHistoricalExchangeLogFillEventsAsync(indexFilterValues);
|
||||
@@ -591,19 +599,19 @@ export class Blockchain {
|
||||
_.each(tokenRegistryTokens, (t: ZeroExToken, i: number) => {
|
||||
// HACK: For now we have a hard-coded list of iconUrls for the dummyTokens
|
||||
// TODO: Refactor this out and pull the iconUrl directly from the TokenRegistry
|
||||
const iconUrl = constants.iconUrlBySymbol[t.symbol];
|
||||
const iconUrl = configs.ICON_URL_BY_SYMBOL[t.symbol];
|
||||
// HACK: Temporarily we hijack the WETH addresses fetched from the tokenRegistry
|
||||
// so that we can take our time with actually updating it. This ensures that when
|
||||
// we deploy the new WETH page, everyone will re-fill their trackedTokens with the
|
||||
// new canonical WETH.
|
||||
// TODO: Remove this hack once we've updated the TokenRegistries
|
||||
// Airtable task: https://airtable.com/tblFe0Q9JuKJPYbTn/viwsOG2Y97qdIeCIO/recv3VGmIorFzHBVz
|
||||
let address = t.address;
|
||||
if (t.symbol === 'WETH') {
|
||||
if (this.networkId === 1) {
|
||||
address = '0xe495bcacaf29a0eb00fb67b86e9cd2a994dd55d8';
|
||||
} else if (this.networkId === 42) {
|
||||
address = '0x739e78d6bebbdf24105a5145fa04436589d1cbd9';
|
||||
}
|
||||
if (configs.SHOULD_DEPRECATE_OLD_WETH_TOKEN && t.symbol === 'WETH') {
|
||||
const newEtherTokenAddressIfExists = configs.NEW_WRAPPED_ETHERS[this.networkId];
|
||||
if (!_.isUndefined(newEtherTokenAddressIfExists)) {
|
||||
address = newEtherTokenAddressIfExists;
|
||||
}
|
||||
}
|
||||
const token: Token = {
|
||||
iconUrl,
|
||||
@@ -639,9 +647,9 @@ export class Blockchain {
|
||||
|
||||
const provider = await Blockchain.getProviderAsync(injectedWeb3, networkIdIfExists);
|
||||
const networkId = !_.isUndefined(networkIdIfExists) ? networkIdIfExists :
|
||||
configs.isMainnetEnabled ?
|
||||
constants.MAINNET_NETWORK_ID :
|
||||
constants.TESTNET_NETWORK_ID;
|
||||
configs.IS_MAINNET_ENABLED ?
|
||||
constants.NETWORK_ID_MAINNET :
|
||||
constants.NETWORK_ID_TESTNET;
|
||||
const zeroExConfigs = {
|
||||
networkId,
|
||||
};
|
||||
@@ -661,7 +669,7 @@ export class Blockchain {
|
||||
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
|
||||
const providerName = doesInjectedWeb3Exist ?
|
||||
Blockchain.getNameGivenProvider(injectedWeb3.currentProvider) :
|
||||
constants.PUBLIC_PROVIDER_NAME;
|
||||
constants.PROVIDER_NAME_PUBLIC;
|
||||
this.dispatcher.updateInjectedProviderName(providerName);
|
||||
}
|
||||
private async fetchTokenInformationAsync() {
|
||||
@@ -686,7 +694,7 @@ export class Blockchain {
|
||||
let trackedTokensIfExists = trackedTokenStorage.getTrackedTokensIfExists(this.userAddress, this.networkId);
|
||||
const tokenRegistryTokens = _.values(tokenRegistryTokensByAddress);
|
||||
if (_.isUndefined(trackedTokensIfExists)) {
|
||||
trackedTokensIfExists = _.map(configs.defaultTrackedTokenSymbols, symbol => {
|
||||
trackedTokensIfExists = _.map(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, symbol => {
|
||||
const token = _.find(tokenRegistryTokens, t => t.symbol === symbol);
|
||||
token.isTracked = true;
|
||||
return token;
|
||||
@@ -709,11 +717,11 @@ export class Blockchain {
|
||||
await this.updateTokenBalancesAndAllowancesAsync(trackedTokensIfExists);
|
||||
|
||||
const mostPopularTradingPairTokens: Token[] = [
|
||||
_.find(allTokens, {symbol: configs.defaultTrackedTokenSymbols[0]}),
|
||||
_.find(allTokens, {symbol: configs.defaultTrackedTokenSymbols[1]}),
|
||||
_.find(allTokens, {symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[0]}),
|
||||
_.find(allTokens, {symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[1]}),
|
||||
];
|
||||
this.dispatcher.updateChosenAssetTokenAddress(Side.deposit, mostPopularTradingPairTokens[0].address);
|
||||
this.dispatcher.updateChosenAssetTokenAddress(Side.receive, mostPopularTradingPairTokens[1].address);
|
||||
this.dispatcher.updateChosenAssetTokenAddress(Side.Deposit, mostPopularTradingPairTokens[0].address);
|
||||
this.dispatcher.updateChosenAssetTokenAddress(Side.Receive, mostPopularTradingPairTokens[1].address);
|
||||
this.dispatcher.updateBlockchainIsLoaded(true);
|
||||
}
|
||||
private async instantiateContractIfExistsAsync(artifact: any, address?: string): Promise<ContractInstance> {
|
||||
@@ -733,7 +741,7 @@ export class Blockchain {
|
||||
const doesContractExist = await this.doesContractExistAtAddressAsync(contractAddress);
|
||||
if (!doesContractExist) {
|
||||
utils.consoleLog(`Contract does not exist: ${artifact.contract_name} at ${contractAddress}`);
|
||||
throw new Error(BlockchainCallErrs.CONTRACT_DOES_NOT_EXIST);
|
||||
throw new Error(BlockchainCallErrs.ContractDoesNotExist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,10 +754,10 @@ export class Blockchain {
|
||||
const errMsg = `${err}`;
|
||||
utils.consoleLog(`Notice: Error encountered: ${err} ${err.stack}`);
|
||||
if (_.includes(errMsg, 'not been deployed to detected network')) {
|
||||
throw new Error(BlockchainCallErrs.CONTRACT_DOES_NOT_EXIST);
|
||||
throw new Error(BlockchainCallErrs.ContractDoesNotExist);
|
||||
} else {
|
||||
await errorReporter.reportAsync(err);
|
||||
throw new Error(BlockchainCallErrs.UNHANDLED_ERROR);
|
||||
throw new Error(BlockchainCallErrs.UnhandledError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import * as _ from 'lodash';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Blockchain} from 'ts/blockchain';
|
||||
import {BlockchainErrs} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
|
||||
@@ -46,22 +46,22 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
|
||||
);
|
||||
}
|
||||
private getTitle(hasWalletAddress: boolean) {
|
||||
if (this.props.blockchainErr === BlockchainErrs.A_CONTRACT_NOT_DEPLOYED_ON_NETWORK) {
|
||||
if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
|
||||
return '0x smart contracts not found';
|
||||
} else if (!hasWalletAddress) {
|
||||
return 'Enable wallet communication';
|
||||
} else if (this.props.blockchainErr === BlockchainErrs.DISCONNECTED_FROM_ETHEREUM_NODE) {
|
||||
} else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
|
||||
return 'Disconnected from Ethereum network';
|
||||
} else {
|
||||
return 'Unexpected error';
|
||||
}
|
||||
}
|
||||
private renderExplanation(hasWalletAddress: boolean) {
|
||||
if (this.props.blockchainErr === BlockchainErrs.A_CONTRACT_NOT_DEPLOYED_ON_NETWORK) {
|
||||
if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) {
|
||||
return this.renderContractsNotDeployedExplanation();
|
||||
} else if (!hasWalletAddress) {
|
||||
return this.renderNoWalletFoundExplanation();
|
||||
} else if (this.props.blockchainErr === BlockchainErrs.DISCONNECTED_FROM_ETHEREUM_NODE) {
|
||||
} else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) {
|
||||
return this.renderDisconnectedFromNode();
|
||||
} else {
|
||||
return this.renderUnexpectedErrorExplanation();
|
||||
@@ -71,9 +71,9 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
|
||||
return (
|
||||
<div>
|
||||
You were disconnected from the backing Ethereum node.
|
||||
{' '}If using <a href={constants.METAMASK_CHROME_STORE_URL} target="_blank">
|
||||
{' '}If using <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
|
||||
Metamask
|
||||
</a> or <a href={constants.MIST_DOWNLOAD_URL} target="_blank">Mist</a> try refreshing
|
||||
</a> or <a href={constants.URL_MIST_DOWNLOAD} target="_blank">Mist</a> try refreshing
|
||||
{' '}the page. If using a locally hosted Ethereum node, make sure it's still running.
|
||||
</div>
|
||||
);
|
||||
@@ -97,7 +97,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
|
||||
<h4>1. Metamask chrome extension</h4>
|
||||
<div>
|
||||
You can install the{' '}
|
||||
<a href={constants.METAMASK_CHROME_STORE_URL} target="_blank">
|
||||
<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
|
||||
Metamask
|
||||
</a> Chrome extension Ethereum wallet. Once installed and set up, refresh this page.
|
||||
<div className="pt1">
|
||||
@@ -107,11 +107,11 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
|
||||
</div>
|
||||
<h4>Parity Signer</h4>
|
||||
<div>
|
||||
The <a href={constants.PARITY_CHROME_STORE_URL} target="_blank">Parity Signer
|
||||
The <a href={constants.URL_PARITY_CHROME_STORE} target="_blank">Parity Signer
|
||||
Chrome extension</a>{' '}lets you connect to a locally running Parity node.
|
||||
Make sure you have started your local Parity node with{' '}
|
||||
{configs.isMainnetEnabled && '`parity ui` or'} `parity --chain kovan ui`{' '}
|
||||
in order to connect to {configs.isMainnetEnabled ? 'mainnet or Kovan respectively.' : 'Kovan.'}
|
||||
{configs.IS_MAINNET_ENABLED && '`parity ui` or'} `parity --chain kovan ui`{' '}
|
||||
in order to connect to {configs.IS_MAINNET_ENABLED ? 'mainnet or Kovan respectively.' : 'Kovan.'}
|
||||
</div>
|
||||
<div className="pt2">
|
||||
<span className="bold">Note:</span>
|
||||
@@ -130,24 +130,24 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp
|
||||
{' '}currently connected to (network Id: {this.props.networkId}).
|
||||
{' '}In order to use the 0x portal dApp,
|
||||
{' '}please connect to the
|
||||
{' '}{constants.TESTNET_NAME} testnet (network Id: {constants.TESTNET_NETWORK_ID})
|
||||
{configs.isMainnetEnabled ?
|
||||
` or ${constants.MAINNET_NAME} (network Id: ${constants.MAINNET_NETWORK_ID}).` :
|
||||
{' '}{constants.TESTNET_NAME} testnet (network Id: {constants.NETWORK_ID_TESTNET})
|
||||
{configs.IS_MAINNET_ENABLED ?
|
||||
` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).` :
|
||||
`.`
|
||||
}
|
||||
</div>
|
||||
<h4>Metamask</h4>
|
||||
<div>
|
||||
If you are using{' '}
|
||||
<a href={constants.METAMASK_CHROME_STORE_URL} target="_blank">
|
||||
<a href={constants.URL_METAMASK_CHROME_STORE} target="_blank">
|
||||
Metamask
|
||||
</a>, you can switch networks in the top left corner of the extension popover.
|
||||
</div>
|
||||
<h4>Parity Signer</h4>
|
||||
<div>
|
||||
If using the <a href={constants.PARITY_CHROME_STORE_URL} target="_blank">Parity Signer
|
||||
If using the <a href={constants.URL_PARITY_CHROME_STORE} target="_blank">Parity Signer
|
||||
Chrome extension</a>, make sure to start your local Parity node with{' '}
|
||||
{configs.isMainnetEnabled ?
|
||||
{configs.IS_MAINNET_ENABLED ?
|
||||
'`parity ui` or `parity --chain Kovan ui` in order to connect to mainnet \
|
||||
or Kovan respectively.' :
|
||||
'`parity --chain kovan ui` in order to connect to Kovan.'
|
||||
|
@@ -5,8 +5,7 @@ import * as React from 'react';
|
||||
import {EthAmountInput} from 'ts/components/inputs/eth_amount_input';
|
||||
import {TokenAmountInput} from 'ts/components/inputs/token_amount_input';
|
||||
import {Side, Token, TokenState} from 'ts/types';
|
||||
|
||||
const DARK_BLUE = '#4D5481';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface EthWethConversionDialogProps {
|
||||
direction: Side;
|
||||
@@ -47,7 +46,7 @@ export class EthWethConversionDialog extends
|
||||
onTouchTap={this.onConvertClick.bind(this)}
|
||||
/>,
|
||||
];
|
||||
const title = this.props.direction === Side.deposit ? 'Wrap ETH' : 'Unwrap WETH';
|
||||
const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH';
|
||||
return (
|
||||
<Dialog
|
||||
title={title}
|
||||
@@ -61,10 +60,10 @@ export class EthWethConversionDialog extends
|
||||
);
|
||||
}
|
||||
private renderConversionDialogBody() {
|
||||
const explanation = this.props.direction === Side.deposit ?
|
||||
const explanation = this.props.direction === Side.Deposit ?
|
||||
'Convert your Ether into a tokenized, tradable form.' :
|
||||
'Convert your Wrapped Ether back into it\'s native form.';
|
||||
const isWrappedVersion = this.props.direction === Side.receive;
|
||||
const isWrappedVersion = this.props.direction === Side.Receive;
|
||||
return (
|
||||
<div>
|
||||
<div className="pb2">
|
||||
@@ -75,7 +74,7 @@ export class EthWethConversionDialog extends
|
||||
{this.renderCurrency(isWrappedVersion)}
|
||||
<div style={{paddingTop: 68}}>
|
||||
<i
|
||||
style={{fontSize: 28, color: DARK_BLUE}}
|
||||
style={{fontSize: 28, color: colors.darkBlue}}
|
||||
className="zmdi zmdi-arrow-right"
|
||||
/>
|
||||
</div>
|
||||
@@ -85,7 +84,7 @@ export class EthWethConversionDialog extends
|
||||
className="pt2 mx-auto"
|
||||
style={{width: 245}}
|
||||
>
|
||||
{this.props.direction === Side.receive ?
|
||||
{this.props.direction === Side.Receive ?
|
||||
<TokenAmountInput
|
||||
token={this.props.token}
|
||||
tokenState={this.props.tokenState}
|
||||
@@ -109,7 +108,16 @@ export class EthWethConversionDialog extends
|
||||
className="pt1"
|
||||
style={{fontSize: 12}}
|
||||
>
|
||||
1 ETH = 1 WETH
|
||||
<div className="left">1 ETH = 1 WETH</div>
|
||||
{this.props.direction === Side.Receive &&
|
||||
<div
|
||||
className="right"
|
||||
onClick={this.onMaxClick.bind(this)}
|
||||
style={{color: colors.darkBlue, textDecoration: 'underline', cursor: 'pointer'}}
|
||||
>
|
||||
Max
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,7 +132,7 @@ export class EthWethConversionDialog extends
|
||||
<div className="mx-auto pt2">
|
||||
<div
|
||||
className="center"
|
||||
style={{color: DARK_BLUE}}
|
||||
style={{color: colors.darkBlue}}
|
||||
>
|
||||
{name}
|
||||
</div>
|
||||
@@ -137,6 +145,11 @@ export class EthWethConversionDialog extends
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private onMaxClick() {
|
||||
this.setState({
|
||||
value: this.props.tokenState.balance,
|
||||
});
|
||||
}
|
||||
private onValueChange(isValid: boolean, amount?: BigNumber) {
|
||||
this.setState({
|
||||
value: amount,
|
||||
|
@@ -2,7 +2,6 @@ import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -17,6 +16,8 @@ import ReactTooltip = require('react-tooltip');
|
||||
import {Blockchain} from 'ts/blockchain';
|
||||
import {LifeCycleRaisedButton} from 'ts/components/ui/lifecycle_raised_button';
|
||||
import {Dispatcher} from 'ts/redux/dispatcher';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
@@ -52,7 +53,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
|
||||
stepIndex: LedgerSteps.CONNECT,
|
||||
userAddresses: [],
|
||||
addressBalances: [],
|
||||
derivationPath: constants.DEFAULT_DERIVATION_PATH,
|
||||
derivationPath: configs.DEFAULT_DERIVATION_PATH,
|
||||
derivationErrMsg: '',
|
||||
};
|
||||
}
|
||||
@@ -146,7 +147,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
|
||||
<div className="overflow-hidden" style={{width: 180}}>
|
||||
<TextField
|
||||
floatingLabelFixed={true}
|
||||
floatingLabelStyle={{color: colors.grey500}}
|
||||
floatingLabelStyle={{color: colors.grey}}
|
||||
floatingLabelText="Update path derivation (advanced)"
|
||||
value={this.state.derivationPath}
|
||||
errorText={this.state.derivationErrMsg}
|
||||
@@ -170,7 +171,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps,
|
||||
const balance = this.state.addressBalances[i];
|
||||
const addressTooltipId = `address-${userAddress}`;
|
||||
const balanceTooltipId = `balance-${userAddress}`;
|
||||
const networkName = constants.networkNameById[this.props.networkId];
|
||||
const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
// We specifically prefix kovan ETH.
|
||||
// TODO: We should probably add prefixes for all networks
|
||||
const isKovanNetwork = networkName === 'Kovan';
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface PortalDisclaimerDialogProps {
|
||||
isOpen: boolean;
|
||||
@@ -17,11 +17,11 @@ export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) {
|
||||
<FlatButton
|
||||
key="portalAgree"
|
||||
label="I Agree"
|
||||
onTouchTap={props.onToggleDialog.bind(this)}
|
||||
onTouchTap={props.onToggleDialog}
|
||||
/>,
|
||||
]}
|
||||
open={props.isOpen}
|
||||
onRequestClose={props.onToggleDialog.bind(this)}
|
||||
onRequestClose={props.onToggleDialog}
|
||||
autoScrollBodyContent={true}
|
||||
modal={true}
|
||||
>
|
||||
|
@@ -73,7 +73,9 @@ export class TrackTokenConfirmationDialog extends
|
||||
isAddingTokenToTracked: true,
|
||||
});
|
||||
for (const token of this.props.tokens) {
|
||||
const newTokenEntry = _.assign({}, token);
|
||||
const newTokenEntry = {
|
||||
...token,
|
||||
};
|
||||
|
||||
newTokenEntry.isTracked = true;
|
||||
trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
|
||||
interface U2fNotSupportedDialogProps {
|
||||
@@ -39,7 +39,7 @@ export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) {
|
||||
<li>
|
||||
Firefox with{' '}
|
||||
<a
|
||||
href={constants.FIREFOX_U2F_ADDON}
|
||||
href={constants.URL_FIREFOX_U2F_ADDON}
|
||||
target="_blank"
|
||||
style={{textDecoration: 'underline'}}
|
||||
>
|
||||
|
@@ -0,0 +1,38 @@
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
|
||||
interface WrappedEthSectionNoticeDialogProps {
|
||||
isOpen: boolean;
|
||||
onToggleDialog: () => void;
|
||||
}
|
||||
|
||||
export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDialogProps) {
|
||||
return (
|
||||
<Dialog
|
||||
title="Dedicated Wrapped Ether Section"
|
||||
titleStyle={{fontWeight: 100}}
|
||||
actions={[
|
||||
<FlatButton
|
||||
key="acknowledgeWrapEthSection"
|
||||
label="Sounds good"
|
||||
onTouchTap={props.onToggleDialog}
|
||||
/>,
|
||||
]}
|
||||
open={props.isOpen}
|
||||
onRequestClose={props.onToggleDialog}
|
||||
autoScrollBodyContent={true}
|
||||
modal={true}
|
||||
>
|
||||
<div className="pt2" style={{color: colors.grey700}}>
|
||||
<div>
|
||||
We have recently updated the Wrapped Ether token (WETH) used by 0x Portal.
|
||||
Don't worry, unwrapping Ether tied to the old Wrapped Ether token can
|
||||
be done at any time by clicking on the "Wrap ETH" section in the menu
|
||||
to the left.
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
@@ -45,7 +45,7 @@ export class EthWethConversionButton extends
|
||||
const labelStyle = this.state.isEthConversionHappening ? {fontSize: 10} : {};
|
||||
let callToActionLabel;
|
||||
let inProgressLabel;
|
||||
if (this.props.direction === Side.deposit) {
|
||||
if (this.props.direction === Side.Deposit) {
|
||||
callToActionLabel = 'Wrap';
|
||||
inProgressLabel = 'Wrapping...';
|
||||
} else {
|
||||
@@ -87,9 +87,9 @@ export class EthWethConversionButton extends
|
||||
const tokenState = this.props.ethTokenState;
|
||||
let balance = tokenState.balance;
|
||||
try {
|
||||
if (direction === Side.deposit) {
|
||||
if (direction === Side.Deposit) {
|
||||
await this.props.blockchain.convertEthToWrappedEthTokensAsync(token.address, value);
|
||||
const ethAmount = ZeroEx.toUnitAmount(value, constants.ETH_DECIMAL_PLACES);
|
||||
const ethAmount = ZeroEx.toUnitAmount(value, constants.DECIMAL_PLACES_ETH);
|
||||
this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`);
|
||||
balance = balance.plus(value);
|
||||
} else {
|
||||
@@ -104,13 +104,13 @@ export class EthWethConversionButton extends
|
||||
this.props.onConversionSuccessful();
|
||||
} catch (err) {
|
||||
const errMsg = '' + err;
|
||||
if (_.includes(errMsg, BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES)) {
|
||||
if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
|
||||
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
} else if (!_.includes(errMsg, 'User denied transaction')) {
|
||||
utils.consoleLog(`Unexpected error encountered: ${err}`);
|
||||
utils.consoleLog(err.stack);
|
||||
await errorReporter.reportAsync(err);
|
||||
const errorMsg = direction === Side.deposit ?
|
||||
const errorMsg = direction === Side.Deposit ?
|
||||
'Failed to wrap your ETH. Please try again.' :
|
||||
'Failed to unwrap your WETH. Please try again.';
|
||||
this.props.dispatcher.showFlashMessage(errorMsg);
|
||||
|
@@ -2,7 +2,6 @@ import {ZeroEx} from '0x.js';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import Divider from 'material-ui/Divider';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -13,10 +12,12 @@ import {
|
||||
} from 'material-ui/Table';
|
||||
import * as moment from 'moment';
|
||||
import * as React from 'react';
|
||||
import ReactTooltip = require('react-tooltip');
|
||||
import {Blockchain} from 'ts/blockchain';
|
||||
import {EthWethConversionButton} from 'ts/components/eth_weth_conversion_button';
|
||||
import {Dispatcher} from 'ts/redux/dispatcher';
|
||||
import {
|
||||
EtherscanLinkSuffixes,
|
||||
OutdatedWrappedEtherByNetworkId,
|
||||
Side,
|
||||
Token,
|
||||
@@ -24,12 +25,13 @@ import {
|
||||
TokenState,
|
||||
TokenStateByAddress,
|
||||
} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const PRECISION = 5;
|
||||
const DATE_FORMAT = 'D/M/YY';
|
||||
const LIGHT_GRAY = '#A5A5A5';
|
||||
const ICON_DIMENSION = 40;
|
||||
const ETHER_ICON_PATH = '/images/ether.png';
|
||||
const OUTDATED_WETH_ICON_PATH = '/images/wrapped_eth_gray.png';
|
||||
@@ -83,8 +85,12 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
const tokens = _.values(this.props.tokenByAddress);
|
||||
const etherToken = _.find(tokens, {symbol: 'WETH'});
|
||||
const etherTokenState = this.props.tokenStateByAddress[etherToken.address];
|
||||
const wethBalance = ZeroEx.toUnitAmount(etherTokenState.balance, 18);
|
||||
const wethBalance = ZeroEx.toUnitAmount(etherTokenState.balance, constants.DECIMAL_PLACES_ETH);
|
||||
const isBidirectional = true;
|
||||
const etherscanUrl = utils.getEtherScanLinkIfExists(
|
||||
etherToken.address, this.props.networkId, EtherscanLinkSuffixes.Address,
|
||||
);
|
||||
const tokenLabel = this.renderToken('Wrapped Ether', etherToken.address, configs.ICON_URL_BY_SYMBOL.WETH);
|
||||
return (
|
||||
<div className="clearfix lg-px4 md-px4 sm-px2" style={{minHeight: 600}}>
|
||||
<div className="relative">
|
||||
@@ -92,8 +98,8 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
<div className="absolute" style={{top: 0, right: 0}}>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://weth.io/"
|
||||
style={{color: LIGHT_GRAY}}
|
||||
href={constants.URL_WETH_IO}
|
||||
style={{color: colors.grey}}
|
||||
>
|
||||
<div className="flex">
|
||||
<div>About Wrapped ETH</div>
|
||||
@@ -131,8 +137,11 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
style={{width: ICON_DIMENSION, height: ICON_DIMENSION}}
|
||||
src={ETHER_ICON_PATH}
|
||||
/>
|
||||
<div className="mt2 ml2 sm-hide xs-hide">
|
||||
Ether
|
||||
<div
|
||||
className="ml2 sm-hide xs-hide"
|
||||
style={{marginTop: 12}}
|
||||
>
|
||||
ETH
|
||||
</div>
|
||||
</div>
|
||||
</TableRowColumn>
|
||||
@@ -142,7 +151,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
<TableRowColumn>
|
||||
<EthWethConversionButton
|
||||
isOutdatedWrappedEther={false}
|
||||
direction={Side.deposit}
|
||||
direction={Side.Deposit}
|
||||
ethToken={etherToken}
|
||||
ethTokenState={etherTokenState}
|
||||
dispatcher={this.props.dispatcher}
|
||||
@@ -153,15 +162,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
</TableRow>
|
||||
<TableRow key="WETH">
|
||||
<TableRowColumn className="py1">
|
||||
<div className="flex">
|
||||
<img
|
||||
style={{width: ICON_DIMENSION, height: ICON_DIMENSION}}
|
||||
src={constants.iconUrlBySymbol.WETH}
|
||||
/>
|
||||
<div className="mt2 ml2 sm-hide xs-hide">
|
||||
Wrapped Ether
|
||||
</div>
|
||||
</div>
|
||||
{this.renderTokenLink(tokenLabel, etherscanUrl)}
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
{wethBalance.toFixed(PRECISION)} WETH
|
||||
@@ -169,7 +170,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
<TableRowColumn>
|
||||
<EthWethConversionButton
|
||||
isOutdatedWrappedEther={false}
|
||||
direction={Side.receive}
|
||||
direction={Side.Receive}
|
||||
ethToken={etherToken}
|
||||
ethTokenState={etherTokenState}
|
||||
dispatcher={this.props.dispatcher}
|
||||
@@ -242,10 +243,13 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
);
|
||||
}
|
||||
private renderOutdatedWeths(etherToken: Token, etherTokenState: TokenState) {
|
||||
const rows = _.map(configs.outdatedWrappedEthers,
|
||||
const rows = _.map(configs.OUTDATED_WRAPPED_ETHERS,
|
||||
(outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => {
|
||||
const outdatedWETH = outdatedWETHByNetworkId[this.props.networkId];
|
||||
const timestampMsRange = outdatedWETH.timestampMsRange;
|
||||
const outdatedWETHIfExists = outdatedWETHByNetworkId[this.props.networkId];
|
||||
if (_.isUndefined(outdatedWETHIfExists)) {
|
||||
return null; // noop
|
||||
}
|
||||
const timestampMsRange = outdatedWETHIfExists.timestampMsRange;
|
||||
let dateRange: string;
|
||||
if (!_.isUndefined(timestampMsRange)) {
|
||||
const startMoment = moment(timestampMsRange.startTimestampMs);
|
||||
@@ -256,26 +260,26 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
}
|
||||
const outdatedEtherToken = {
|
||||
...etherToken,
|
||||
address: outdatedWETH.address,
|
||||
address: outdatedWETHIfExists.address,
|
||||
};
|
||||
const isStateLoaded = this.state.outdatedWETHAddressToIsStateLoaded[outdatedWETH.address];
|
||||
const outdatedEtherTokenState = this.state.outdatedWETHStateByAddress[outdatedWETH.address];
|
||||
const isStateLoaded = this.state.outdatedWETHAddressToIsStateLoaded[outdatedWETHIfExists.address];
|
||||
const outdatedEtherTokenState = this.state.outdatedWETHStateByAddress[outdatedWETHIfExists.address];
|
||||
const balanceInEthIfExists = isStateLoaded ?
|
||||
ZeroEx.toUnitAmount(outdatedEtherTokenState.balance, 18).toFixed(PRECISION) :
|
||||
ZeroEx.toUnitAmount(
|
||||
outdatedEtherTokenState.balance, constants.DECIMAL_PLACES_ETH,
|
||||
).toFixed(PRECISION) :
|
||||
undefined;
|
||||
const onConversionSuccessful = this.onOutdatedConversionSuccessfulAsync.bind(this, outdatedWETH.address);
|
||||
const onConversionSuccessful = this.onOutdatedConversionSuccessfulAsync.bind(
|
||||
this, outdatedWETHIfExists.address,
|
||||
);
|
||||
const etherscanUrl = utils.getEtherScanLinkIfExists(
|
||||
outdatedWETHIfExists.address, this.props.networkId, EtherscanLinkSuffixes.Address,
|
||||
);
|
||||
const tokenLabel = this.renderToken(dateRange, outdatedEtherToken.address, OUTDATED_WETH_ICON_PATH);
|
||||
return (
|
||||
<TableRow key={`weth-${outdatedWETH.address}`}>
|
||||
<TableRow key={`weth-${outdatedWETHIfExists.address}`}>
|
||||
<TableRowColumn className="py1">
|
||||
<div className="flex">
|
||||
<img
|
||||
style={{width: ICON_DIMENSION, height: ICON_DIMENSION}}
|
||||
src={OUTDATED_WETH_ICON_PATH}
|
||||
/>
|
||||
<div className="mt2 ml2 sm-hide xs-hide">
|
||||
{dateRange}
|
||||
</div>
|
||||
</div>
|
||||
{this.renderTokenLink(tokenLabel, etherscanUrl)}
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
{isStateLoaded ?
|
||||
@@ -287,7 +291,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
<EthWethConversionButton
|
||||
isDisabled={!isStateLoaded}
|
||||
isOutdatedWrappedEther={true}
|
||||
direction={Side.receive}
|
||||
direction={Side.Receive}
|
||||
ethToken={outdatedEtherToken}
|
||||
ethTokenState={outdatedEtherTokenState}
|
||||
dispatcher={this.props.dispatcher}
|
||||
@@ -301,6 +305,41 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
});
|
||||
return rows;
|
||||
}
|
||||
private renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string) {
|
||||
return (
|
||||
<span>
|
||||
{_.isUndefined(etherscanUrl) ?
|
||||
tokenLabel :
|
||||
<a href={etherscanUrl} target="_blank" style={{textDecoration: 'none'}}>
|
||||
{tokenLabel}
|
||||
</a>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
private renderToken(name: string, address: string, imgPath: string) {
|
||||
const tooltipId = `tooltip-${address}`;
|
||||
return (
|
||||
<div className="flex">
|
||||
<img
|
||||
style={{width: ICON_DIMENSION, height: ICON_DIMENSION}}
|
||||
src={imgPath}
|
||||
/>
|
||||
<div
|
||||
className="ml2 sm-hide xs-hide"
|
||||
style={{marginTop: 12}}
|
||||
>
|
||||
<span
|
||||
data-tip={true}
|
||||
data-for={tooltipId}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
<ReactTooltip id={tooltipId}>{address}</ReactTooltip>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private async onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string) {
|
||||
this.setState({
|
||||
outdatedWETHAddressToIsStateLoaded: {
|
||||
@@ -345,9 +384,15 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt
|
||||
});
|
||||
}
|
||||
private getOutdatedWETHAddresses(): string[] {
|
||||
const outdatedWETHAddresses = _.map(configs.outdatedWrappedEthers, outdatedWrappedEther => {
|
||||
return outdatedWrappedEther[this.props.networkId].address;
|
||||
});
|
||||
const outdatedWETHAddresses = _.compact(_.map(configs.OUTDATED_WRAPPED_ETHERS,
|
||||
outdatedWrappedEtherByNetwork => {
|
||||
const outdatedWrappedEtherIfExists = outdatedWrappedEtherByNetwork[this.props.networkId];
|
||||
if (_.isUndefined(outdatedWrappedEtherIfExists)) {
|
||||
return undefined;
|
||||
}
|
||||
const address = outdatedWrappedEtherIfExists.address;
|
||||
return address;
|
||||
}));
|
||||
return outdatedWETHAddresses;
|
||||
}
|
||||
} // tslint:disable:max-file-line-count
|
||||
|
@@ -28,12 +28,11 @@ import {
|
||||
TokenStateByAddress,
|
||||
WebsitePaths,
|
||||
} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {errorReporter} from 'ts/utils/error_reporter';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const CUSTOM_LIGHT_GRAY = '#BBBBBB';
|
||||
|
||||
interface FillOrderProps {
|
||||
blockchain: Blockchain;
|
||||
blockchainErr: BlockchainErrs;
|
||||
@@ -222,7 +221,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
<div className="clearfix pb2" style={{width: '100%'}}>
|
||||
<div className="inline left">Order details</div>
|
||||
<div className="inline right" style={{minWidth: 208}}>
|
||||
<div className="col col-4 pl2" style={{color: '#BEBEBE'}}>
|
||||
<div className="col col-4 pl2" style={{color: colors.grey}}>
|
||||
Maker:
|
||||
</div>
|
||||
<div className="col col-2 pr1">
|
||||
@@ -259,22 +258,20 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
</div>
|
||||
</div>
|
||||
{!isUserMaker &&
|
||||
<div className="clearfix mx-auto" style={{width: 315, height: 108}}>
|
||||
<div className="col col-7" style={{maxWidth: 235}}>
|
||||
<TokenAmountInput
|
||||
label="Fill amount"
|
||||
onChange={this.onFillAmountChange.bind(this)}
|
||||
shouldShowIncompleteErrs={false}
|
||||
token={fillToken}
|
||||
tokenState={fillTokenState}
|
||||
amount={fillAssetToken.amount}
|
||||
shouldCheckBalance={true}
|
||||
shouldCheckAllowance={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="clearfix mx-auto relative" style={{width: 235, height: 108}}>
|
||||
<TokenAmountInput
|
||||
label="Fill amount"
|
||||
onChange={this.onFillAmountChange.bind(this)}
|
||||
shouldShowIncompleteErrs={false}
|
||||
token={fillToken}
|
||||
tokenState={fillTokenState}
|
||||
amount={fillAssetToken.amount}
|
||||
shouldCheckBalance={true}
|
||||
shouldCheckAllowance={true}
|
||||
/>
|
||||
<div
|
||||
className="col col-5 pl1"
|
||||
style={{color: CUSTOM_LIGHT_GRAY, paddingTop: 39}}
|
||||
className="absolute sm-hide xs-hide"
|
||||
style={{color: colors.grey400, right: -247, top: 39, width: 242}}
|
||||
>
|
||||
= {accounting.formatNumber(orderReceiveAmount, 6)} {makerToken.symbol}
|
||||
</div>
|
||||
@@ -324,7 +321,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
Order successfully filled. See the trade details in your{' '}
|
||||
<Link
|
||||
to={`${WebsitePaths.Portal}/trades`}
|
||||
style={{color: 'white'}}
|
||||
style={{color: colors.white}}
|
||||
>
|
||||
trade history
|
||||
</Link>
|
||||
@@ -381,22 +378,24 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
const isUnseenMakerToken = _.isUndefined(makerTokenIfExists);
|
||||
const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked;
|
||||
if (isUnseenMakerToken) {
|
||||
tokensToTrack.push(_.assign({}, this.state.parsedOrder.maker.token, {
|
||||
tokensToTrack.push({
|
||||
...this.state.parsedOrder.maker.token,
|
||||
iconUrl: undefined,
|
||||
isTracked: false,
|
||||
isRegistered: false,
|
||||
}));
|
||||
});
|
||||
} else if (!isMakerTokenTracked) {
|
||||
tokensToTrack.push(makerTokenIfExists);
|
||||
}
|
||||
const isUnseenTakerToken = _.isUndefined(takerTokenIfExists);
|
||||
const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked;
|
||||
if (isUnseenTakerToken) {
|
||||
tokensToTrack.push(_.assign({}, this.state.parsedOrder.taker.token, {
|
||||
tokensToTrack.push({
|
||||
...this.state.parsedOrder.taker.token,
|
||||
iconUrl: undefined,
|
||||
isTracked: false,
|
||||
isRegistered: false,
|
||||
}));
|
||||
});
|
||||
} else if (!isTakerTokenTracked) {
|
||||
tokensToTrack.push(takerTokenIfExists);
|
||||
}
|
||||
|
@@ -24,11 +24,11 @@ export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrder
|
||||
const tokenAddresses = _.keys(this.props.tokenByAddress);
|
||||
const exchangeContract = this.props.blockchain.getExchangeContractAddressIfExists();
|
||||
const hintSideToAssetToken = {
|
||||
[Side.deposit]: {
|
||||
[Side.Deposit]: {
|
||||
amount: new BigNumber(35),
|
||||
address: tokenAddresses[0],
|
||||
},
|
||||
[Side.receive]: {
|
||||
[Side.Receive]: {
|
||||
amount: new BigNumber(89),
|
||||
address: tokenAddresses[1],
|
||||
},
|
||||
@@ -41,9 +41,10 @@ export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrder
|
||||
v: 27,
|
||||
};
|
||||
const hintSalt = ZeroEx.generatePseudoRandomSalt();
|
||||
const feeRecipient = constants.NULL_ADDRESS;
|
||||
const hintOrder = utils.generateOrder(this.props.networkId, exchangeContract, hintSideToAssetToken,
|
||||
hintOrderExpiryTimestamp, '', '', constants.MAKER_FEE,
|
||||
constants.TAKER_FEE, constants.FEE_RECIPIENT_ADDRESS,
|
||||
constants.TAKER_FEE, feeRecipient,
|
||||
hintSignatureData, this.props.tokenByAddress, hintSalt);
|
||||
const hintOrderJSON = `${JSON.stringify(hintOrder, null, '\t').substring(0, 500)}...`;
|
||||
return (
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface FillWarningDialogProps {
|
||||
isOpen: boolean;
|
||||
|
@@ -3,6 +3,7 @@ import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import {Token} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
interface TokenSendCompletedProps {
|
||||
@@ -19,7 +20,7 @@ export class TokenSendCompleted extends React.Component<TokenSendCompletedProps,
|
||||
const etherScanLink = !_.isUndefined(this.props.etherScanLinkIfExists) &&
|
||||
(
|
||||
<a
|
||||
style={{color: 'white'}}
|
||||
style={{color: colors.white}}
|
||||
href={`${this.props.etherScanLinkIfExists}`}
|
||||
target="_blank"
|
||||
>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface TransactionSubmittedProps {
|
||||
etherScanLinkIfExists?: string;
|
||||
@@ -16,7 +17,7 @@ export class TransactionSubmitted extends React.Component<TransactionSubmittedPr
|
||||
<div>
|
||||
Transaction submitted to the network:{' '}
|
||||
<a
|
||||
style={{color: 'white'}}
|
||||
style={{color: colors.white}}
|
||||
href={`${this.props.etherScanLinkIfExists}`}
|
||||
target="_blank"
|
||||
>
|
||||
|
@@ -4,6 +4,7 @@ import {
|
||||
Link,
|
||||
} from 'react-router-dom';
|
||||
import {WebsitePaths} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
|
||||
interface MenuItemsBySection {
|
||||
@@ -24,9 +25,6 @@ enum Sections {
|
||||
}
|
||||
|
||||
const ICON_DIMENSION = 16;
|
||||
const CUSTOM_DARK_GRAY = '#393939';
|
||||
const CUSTOM_LIGHT_GRAY = '#CACACA';
|
||||
const CUSTOM_LIGHTEST_GRAY = '#9E9E9E';
|
||||
const menuItemsBySection: MenuItemsBySection = {
|
||||
Documentation: [
|
||||
{
|
||||
@@ -59,25 +57,25 @@ const menuItemsBySection: MenuItemsBySection = {
|
||||
{
|
||||
title: 'Rocket.chat',
|
||||
isExternal: true,
|
||||
path: constants.ZEROEX_CHAT_URL,
|
||||
path: constants.URL_ZEROEX_CHAT,
|
||||
fileName: 'rocketchat.png',
|
||||
},
|
||||
{
|
||||
title: 'Blog',
|
||||
isExternal: true,
|
||||
path: constants.BLOG_URL,
|
||||
path: constants.URL_BLOG,
|
||||
fileName: 'medium.png',
|
||||
},
|
||||
{
|
||||
title: 'Twitter',
|
||||
isExternal: true,
|
||||
path: constants.TWITTER_URL,
|
||||
path: constants.URL_TWITTER,
|
||||
fileName: 'twitter.png',
|
||||
},
|
||||
{
|
||||
title: 'Reddit',
|
||||
isExternal: true,
|
||||
path: constants.REDDIT_URL,
|
||||
path: constants.URL_REDDIT,
|
||||
fileName: 'reddit.png',
|
||||
},
|
||||
],
|
||||
@@ -90,7 +88,7 @@ const menuItemsBySection: MenuItemsBySection = {
|
||||
{
|
||||
title: 'Careers',
|
||||
isExternal: true,
|
||||
path: constants.ANGELLIST_URL,
|
||||
path: constants.URL_ANGELLIST,
|
||||
},
|
||||
{
|
||||
title: 'Contact',
|
||||
@@ -100,7 +98,7 @@ const menuItemsBySection: MenuItemsBySection = {
|
||||
],
|
||||
};
|
||||
const linkStyle = {
|
||||
color: 'white',
|
||||
color: colors.white,
|
||||
cursor: 'pointer',
|
||||
};
|
||||
|
||||
@@ -111,23 +109,23 @@ const titleToIcon: {[title: string]: string} = {
|
||||
'Reddit': 'reddit.png',
|
||||
};
|
||||
|
||||
export interface FooterProps {
|
||||
location: Location;
|
||||
}
|
||||
export interface FooterProps {}
|
||||
|
||||
interface FooterState {}
|
||||
|
||||
export class Footer extends React.Component<FooterProps, FooterState> {
|
||||
public render() {
|
||||
return (
|
||||
<div className="relative pb4 pt2" style={{backgroundColor: CUSTOM_DARK_GRAY}}>
|
||||
<div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{color: 'white'}}>
|
||||
<div className="relative pb4 pt2" style={{backgroundColor: colors.darkerGrey}}>
|
||||
<div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{color: colors.white}}>
|
||||
<div className="col lg-col-4 md-col-4 col-12 left">
|
||||
<div className="sm-mx-auto" style={{width: 148}}>
|
||||
<div>
|
||||
<img src="/images/protocol_logo_white.png" height="30" />
|
||||
</div>
|
||||
<div style={{fontSize: 11, color: CUSTOM_LIGHTEST_GRAY, paddingLeft: 37, paddingTop: 2}}>
|
||||
<div
|
||||
style={{fontSize: 11, color: colors.grey, paddingLeft: 37, paddingTop: 2}}
|
||||
>
|
||||
© ZeroEx, Intl.
|
||||
</div>
|
||||
</div>
|
||||
@@ -211,7 +209,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
|
||||
private renderHeader(title: string) {
|
||||
const headerStyle = {
|
||||
textTransform: 'uppercase',
|
||||
color: CUSTOM_LIGHT_GRAY,
|
||||
color: colors.grey400,
|
||||
letterSpacing: 2,
|
||||
fontFamily: 'Roboto Mono',
|
||||
fontSize: 13,
|
||||
|
@@ -244,7 +244,9 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
|
||||
});
|
||||
const tokenAddress = this.state.chosenTrackTokenAddress;
|
||||
const token = this.props.tokenByAddress[tokenAddress];
|
||||
const newTokenEntry = _.assign({}, token);
|
||||
const newTokenEntry = {
|
||||
...token,
|
||||
};
|
||||
|
||||
newTokenEntry.isTracked = true;
|
||||
trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry);
|
||||
|
@@ -3,7 +3,6 @@ import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
import Divider from 'material-ui/Divider';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Blockchain} from 'ts/blockchain';
|
||||
import {ExpirationInput} from 'ts/components/inputs/expiration_input';
|
||||
@@ -30,6 +29,7 @@ import {
|
||||
TokenByAddress,
|
||||
TokenStateByAddress,
|
||||
} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {errorReporter} from 'ts/utils/error_reporter';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
@@ -78,10 +78,10 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
}
|
||||
public render() {
|
||||
const dispatcher = this.props.dispatcher;
|
||||
const depositTokenAddress = this.props.sideToAssetToken[Side.deposit].address;
|
||||
const depositTokenAddress = this.props.sideToAssetToken[Side.Deposit].address;
|
||||
const depositToken = this.props.tokenByAddress[depositTokenAddress];
|
||||
const depositTokenState = this.props.tokenStateByAddress[depositTokenAddress];
|
||||
const receiveTokenAddress = this.props.sideToAssetToken[Side.receive].address;
|
||||
const receiveTokenAddress = this.props.sideToAssetToken[Side.Receive].address;
|
||||
const receiveToken = this.props.tokenByAddress[receiveTokenAddress];
|
||||
const receiveTokenState = this.props.tokenStateByAddress[receiveTokenAddress];
|
||||
const takerExplanation = 'If a taker is specified, only they are<br> \
|
||||
@@ -102,9 +102,9 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
blockchainErr={this.props.blockchainErr}
|
||||
dispatcher={this.props.dispatcher}
|
||||
label="Selling"
|
||||
side={Side.deposit}
|
||||
side={Side.Deposit}
|
||||
networkId={this.props.networkId}
|
||||
assetToken={this.props.sideToAssetToken[Side.deposit]}
|
||||
assetToken={this.props.sideToAssetToken[Side.Deposit]}
|
||||
updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
|
||||
tokenByAddress={this.props.tokenByAddress}
|
||||
/>
|
||||
@@ -112,8 +112,8 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
label="Sell amount"
|
||||
token={depositToken}
|
||||
tokenState={depositTokenState}
|
||||
amount={this.props.sideToAssetToken[Side.deposit].amount}
|
||||
onChange={this.onTokenAmountChange.bind(this, depositToken, Side.deposit)}
|
||||
amount={this.props.sideToAssetToken[Side.Deposit].amount}
|
||||
onChange={this.onTokenAmountChange.bind(this, depositToken, Side.Deposit)}
|
||||
shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
|
||||
shouldCheckBalance={true}
|
||||
shouldCheckAllowance={true}
|
||||
@@ -133,9 +133,9 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
blockchainErr={this.props.blockchainErr}
|
||||
dispatcher={this.props.dispatcher}
|
||||
label="Buying"
|
||||
side={Side.receive}
|
||||
side={Side.Receive}
|
||||
networkId={this.props.networkId}
|
||||
assetToken={this.props.sideToAssetToken[Side.receive]}
|
||||
assetToken={this.props.sideToAssetToken[Side.Receive]}
|
||||
updateChosenAssetToken={dispatcher.updateChosenAssetToken.bind(dispatcher)}
|
||||
tokenByAddress={this.props.tokenByAddress}
|
||||
/>
|
||||
@@ -143,8 +143,8 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
label="Receive amount"
|
||||
token={receiveToken}
|
||||
tokenState={receiveTokenState}
|
||||
amount={this.props.sideToAssetToken[Side.receive].amount}
|
||||
onChange={this.onTokenAmountChange.bind(this, receiveToken, Side.receive)}
|
||||
amount={this.props.sideToAssetToken[Side.Receive].amount}
|
||||
onChange={this.onTokenAmountChange.bind(this, receiveToken, Side.Receive)}
|
||||
shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs}
|
||||
shouldCheckBalance={false}
|
||||
shouldCheckAllowance={false}
|
||||
@@ -154,7 +154,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
</div>
|
||||
<div className="pt1 sm-pb2 lg-px4 md-px4">
|
||||
<div className="lg-px3 md-px3">
|
||||
<div style={{fontSize: 12, color: colors.grey500}}>Expiration</div>
|
||||
<div style={{fontSize: 12, color: colors.grey}}>Expiration</div>
|
||||
<ExpirationInput
|
||||
orderExpiryTimestamp={this.props.orderExpiryTimestamp}
|
||||
updateOrderExpiry={dispatcher.updateOrderExpiry.bind(dispatcher)}
|
||||
@@ -235,16 +235,16 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
});
|
||||
}
|
||||
private async onSignClickedAsync(): Promise<boolean> {
|
||||
if (this.props.blockchainErr !== '') {
|
||||
if (this.props.blockchainErr !== BlockchainErrs.NoError) {
|
||||
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if all required inputs were supplied
|
||||
const debitToken = this.props.sideToAssetToken[Side.deposit];
|
||||
const debitToken = this.props.sideToAssetToken[Side.Deposit];
|
||||
const debitBalance = this.props.tokenStateByAddress[debitToken.address].balance;
|
||||
const debitAllowance = this.props.tokenStateByAddress[debitToken.address].allowance;
|
||||
const receiveAmount = this.props.sideToAssetToken[Side.receive].amount;
|
||||
const receiveAmount = this.props.sideToAssetToken[Side.Receive].amount;
|
||||
if (!_.isUndefined(debitToken.amount) && !_.isUndefined(receiveAmount) &&
|
||||
debitToken.amount.gt(0) && receiveAmount.gt(0) &&
|
||||
this.props.userAddress !== '' &&
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import * as React from 'react';
|
||||
import {Blockchain} from 'ts/blockchain';
|
||||
@@ -9,6 +8,7 @@ import {Alert} from 'ts/components/ui/alert';
|
||||
import {LifeCycleRaisedButton} from 'ts/components/ui/lifecycle_raised_button';
|
||||
import {RequiredLabel} from 'ts/components/ui/required_label';
|
||||
import {AlertTypes, Token, TokenByAddress, TokenState} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface NewTokenFormProps {
|
||||
blockchain: Blockchain;
|
||||
@@ -49,7 +49,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
|
||||
<div>
|
||||
<TextField
|
||||
floatingLabelFixed={true}
|
||||
floatingLabelStyle={{color: colors.grey500}}
|
||||
floatingLabelStyle={{color: colors.grey}}
|
||||
floatingLabelText={<RequiredLabel label="Name" />}
|
||||
value={this.state.name}
|
||||
errorText={this.state.nameErrText}
|
||||
@@ -59,7 +59,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
|
||||
<div>
|
||||
<TextField
|
||||
floatingLabelFixed={true}
|
||||
floatingLabelStyle={{color: colors.grey500}}
|
||||
floatingLabelStyle={{color: colors.grey}}
|
||||
floatingLabelText={<RequiredLabel label="Symbol" />}
|
||||
value={this.state.symbol}
|
||||
errorText={this.state.symbolErrText}
|
||||
@@ -78,7 +78,7 @@ export class NewTokenForm extends React.Component<NewTokenFormProps, NewTokenFor
|
||||
<div>
|
||||
<TextField
|
||||
floatingLabelFixed={true}
|
||||
floatingLabelStyle={{color: colors.grey500}}
|
||||
floatingLabelStyle={{color: colors.grey}}
|
||||
floatingLabelText={<RequiredLabel label="Decimals" />}
|
||||
value={this.state.decimals}
|
||||
errorText={this.state.decimalsErrText}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import {addressUtils} from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import * as React from 'react';
|
||||
import {RequiredLabel} from 'ts/components/ui/required_label';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface AddressInputProps {
|
||||
disabled?: boolean;
|
||||
@@ -50,7 +50,7 @@ export class AddressInput extends React.Component<AddressInputProps, AddressInpu
|
||||
fullWidth={true}
|
||||
hintText={hintText}
|
||||
floatingLabelFixed={true}
|
||||
floatingLabelStyle={{color: colors.grey500, display: labelDisplay}}
|
||||
floatingLabelStyle={{color: colors.grey, display: labelDisplay}}
|
||||
floatingLabelText={label}
|
||||
errorText={this.state.errMsg}
|
||||
value={this.state.address}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import * as React from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {RequiredLabel} from 'ts/components/ui/required_label';
|
||||
import {InputErrMsg, ValidatedBigNumberCallback, WebsitePaths} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
interface BalanceBoundedInputProps {
|
||||
@@ -83,7 +83,7 @@ export class BalanceBoundedInput extends
|
||||
fullWidth={true}
|
||||
floatingLabelText={label}
|
||||
floatingLabelFixed={true}
|
||||
floatingLabelStyle={{color: colors.grey500, width: 206}}
|
||||
floatingLabelStyle={{color: colors.grey, width: 206}}
|
||||
errorText={errorText}
|
||||
value={this.state.amountString}
|
||||
hintText={<span style={{textTransform: 'capitalize'}}>amount</span>}
|
||||
@@ -133,7 +133,7 @@ export class BalanceBoundedInput extends
|
||||
const increaseBalanceText = 'Increase balance';
|
||||
const linkStyle = {
|
||||
cursor: 'pointer',
|
||||
color: colors.grey900,
|
||||
color: colors.darkestGrey,
|
||||
textDecoration: 'underline',
|
||||
display: 'inline',
|
||||
};
|
||||
|
@@ -22,7 +22,7 @@ interface EthAmountInputState {}
|
||||
export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmountInputState> {
|
||||
public render() {
|
||||
const amount = this.props.amount ?
|
||||
ZeroEx.toUnitAmount(this.props.amount, constants.ETH_DECIMAL_PLACES) :
|
||||
ZeroEx.toUnitAmount(this.props.amount, constants.DECIMAL_PLACES_ETH) :
|
||||
undefined;
|
||||
return (
|
||||
<div className="flex overflow-hidden" style={{height: 63}}>
|
||||
@@ -45,7 +45,7 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
|
||||
private onChange(isValid: boolean, amount?: BigNumber) {
|
||||
const baseUnitAmountIfExists = _.isUndefined(amount) ?
|
||||
undefined :
|
||||
ZeroEx.toBaseUnitAmount(amount, constants.ETH_DECIMAL_PLACES);
|
||||
ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);
|
||||
this.props.onChange(isValid, baseUnitAmountIfExists);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import {ZeroEx} from '0x.js';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {BalanceBoundedInput} from 'ts/components/inputs/balance_bounded_input';
|
||||
import {InputErrMsg, Token, TokenState, ValidatedBigNumberCallback, WebsitePaths} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface TokenAmountInputProps {
|
||||
token: Token;
|
||||
@@ -59,7 +59,7 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
|
||||
Insufficient allowance.{' '}
|
||||
<Link
|
||||
to={`${WebsitePaths.Portal}/balances`}
|
||||
style={{cursor: 'pointer', color: colors.grey900}}
|
||||
style={{cursor: 'pointer', color: colors.darkestGrey}}
|
||||
>
|
||||
Set allowance
|
||||
</Link>
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import * as _ from 'lodash';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Blockchain} from 'ts/blockchain';
|
||||
import {AssetPicker} from 'ts/components/generate_order/asset_picker';
|
||||
@@ -8,6 +7,7 @@ import {InputLabel} from 'ts/components/ui/input_label';
|
||||
import {TokenIcon} from 'ts/components/ui/token_icon';
|
||||
import {Dispatcher} from 'ts/redux/dispatcher';
|
||||
import {AssetToken, BlockchainErrs, Side, Token, TokenByAddress} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
const TOKEN_ICON_DIMENSION = 80;
|
||||
|
||||
@@ -62,7 +62,7 @@ export class TokenInput extends React.Component<TokenInputProps, TokenInputState
|
||||
>
|
||||
<TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
|
||||
</div>
|
||||
<div className="py1 center" style={{color: colors.grey500}}>
|
||||
<div className="py1 center" style={{color: colors.grey}}>
|
||||
{token.name}
|
||||
</div>
|
||||
</Paper>
|
||||
@@ -95,7 +95,7 @@ export class TokenInput extends React.Component<TokenInputProps, TokenInputState
|
||||
});
|
||||
}
|
||||
private onAssetClicked() {
|
||||
if (this.props.blockchainErr !== '') {
|
||||
if (this.props.blockchainErr !== BlockchainErrs.NoError) {
|
||||
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
return;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import {Paper} from 'material-ui/Paper';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import * as React from 'react';
|
||||
import {CopyIcon} from 'ts/components/ui/copy_icon';
|
||||
@@ -137,9 +137,8 @@ You can see and fill it here: ${this.state.shareLink}`);
|
||||
}
|
||||
private async generateShareLinkAsync(): Promise<string> {
|
||||
const longUrl = encodeURIComponent(this.getOrderUrl());
|
||||
const bitlyRequestUrl = constants.BITLY_ENDPOINT + '/v3/shorten?' +
|
||||
'access_token=' + constants.BITLY_ACCESS_TOKEN +
|
||||
'&longUrl=' + longUrl;
|
||||
const bitlyRequestUrl =
|
||||
`${constants.URL_BITLY_API}/v3/shorten?access_token=${configs.BITLY_ACCESS_TOKEN}&longUrl=${longUrl}`;
|
||||
const response = await fetch(bitlyRequestUrl);
|
||||
const responseBody = await response.text();
|
||||
const bodyObj = JSON.parse(responseBody);
|
||||
|
@@ -1,13 +1,13 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import * as DocumentTitle from 'react-document-title';
|
||||
import {Route, Switch} from 'react-router-dom';
|
||||
import {Blockchain} from 'ts/blockchain';
|
||||
import {BlockchainErrDialog} from 'ts/components/dialogs/blockchain_err_dialog';
|
||||
import {PortalDisclaimerDialog} from 'ts/components/dialogs/portal_disclaimer_dialog';
|
||||
import {WrappedEthSectionNoticeDialog} from 'ts/components/dialogs/wrapped_eth_section_notice_dialog';
|
||||
import {EthWrappers} from 'ts/components/eth_wrappers';
|
||||
import {FillOrder} from 'ts/components/fill_order';
|
||||
import {Footer} from 'ts/components/footer';
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
TokenStateByAddress,
|
||||
WebsitePaths,
|
||||
} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
@@ -63,22 +64,39 @@ interface PortalAllState {
|
||||
prevNetworkId: number;
|
||||
prevNodeVersion: string;
|
||||
prevUserAddress: string;
|
||||
hasAcceptedDisclaimer: boolean;
|
||||
prevPathname: string;
|
||||
isDisclaimerDialogOpen: boolean;
|
||||
isWethNoticeDialogOpen: boolean;
|
||||
}
|
||||
|
||||
export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
private blockchain: Blockchain;
|
||||
private sharedOrderIfExists: Order;
|
||||
private throttledScreenWidthUpdate: () => void;
|
||||
public static hasAlreadyDismissedWethNotice() {
|
||||
const didDismissWethNotice = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE);
|
||||
const hasAlreadyDismissedWethNotice = !_.isUndefined(didDismissWethNotice) &&
|
||||
!_.isEmpty(didDismissWethNotice);
|
||||
return hasAlreadyDismissedWethNotice;
|
||||
}
|
||||
constructor(props: PortalAllProps) {
|
||||
super(props);
|
||||
this.sharedOrderIfExists = this.getSharedOrderIfExists();
|
||||
this.throttledScreenWidthUpdate = _.throttle(this.updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
|
||||
|
||||
const isViewingBalances = _.includes(props.location.pathname, `${WebsitePaths.Portal}/balances`);
|
||||
const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
|
||||
|
||||
const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
|
||||
const hasAcceptedDisclaimer = !_.isUndefined(didAcceptPortalDisclaimer) &&
|
||||
!_.isEmpty(didAcceptPortalDisclaimer);
|
||||
this.state = {
|
||||
prevNetworkId: this.props.networkId,
|
||||
prevNodeVersion: this.props.nodeVersion,
|
||||
prevUserAddress: this.props.userAddress,
|
||||
hasAcceptedDisclaimer: false,
|
||||
prevPathname: this.props.location.pathname,
|
||||
isDisclaimerDialogOpen: !hasAcceptedDisclaimer,
|
||||
isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
|
||||
};
|
||||
}
|
||||
public componentDidMount() {
|
||||
@@ -87,12 +105,6 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
}
|
||||
public componentWillMount() {
|
||||
this.blockchain = new Blockchain(this.props.dispatcher);
|
||||
const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.ACCEPT_DISCLAIMER_LOCAL_STORAGE_KEY);
|
||||
const hasAcceptedDisclaimer = !_.isUndefined(didAcceptPortalDisclaimer) &&
|
||||
!_.isEmpty(didAcceptPortalDisclaimer);
|
||||
this.setState({
|
||||
hasAcceptedDisclaimer,
|
||||
});
|
||||
}
|
||||
public componentWillUnmount() {
|
||||
this.blockchain.destroy();
|
||||
@@ -128,6 +140,14 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this.blockchain.nodeVersionUpdatedFireAndForgetAsync(nextProps.nodeVersion);
|
||||
}
|
||||
if (nextProps.location.pathname !== this.state.prevPathname) {
|
||||
const isViewingBalances = _.includes(nextProps.location.pathname, `${WebsitePaths.Portal}/balances`);
|
||||
const hasAlreadyDismissedWethNotice = Portal.hasAlreadyDismissedWethNotice();
|
||||
this.setState({
|
||||
prevPathname: nextProps.location.pathname,
|
||||
isWethNoticeDialogOpen: !hasAlreadyDismissedWethNotice && isViewingBalances,
|
||||
});
|
||||
}
|
||||
}
|
||||
public render() {
|
||||
const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher
|
||||
@@ -138,6 +158,11 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
};
|
||||
const portalMenuContainerStyle: React.CSSProperties = {
|
||||
overflow: 'hidden',
|
||||
backgroundColor: colors.darkestGrey,
|
||||
color: colors.white,
|
||||
};
|
||||
return (
|
||||
<div style={portalStyle}>
|
||||
<DocumentTitle title="0x Portal DApp"/>
|
||||
@@ -146,9 +171,9 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
blockchainIsLoaded={this.props.blockchainIsLoaded}
|
||||
location={this.props.location}
|
||||
/>
|
||||
<div id="portal" className="mx-auto max-width-4 pt4" style={{width: '100%'}}>
|
||||
<div id="portal" className="mx-auto max-width-4" style={{width: '100%'}}>
|
||||
<Paper className="mb3 mt2">
|
||||
{!configs.isMainnetEnabled && this.props.networkId === constants.MAINNET_NETWORK_ID ?
|
||||
{!configs.IS_MAINNET_ENABLED && this.props.networkId === constants.NETWORK_ID_MAINNET ?
|
||||
<div className="p3 center">
|
||||
<div className="h2 py2">Mainnet unavailable</div>
|
||||
<div className="mx-auto pb2 pt2">
|
||||
@@ -171,9 +196,9 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
<div className="mx-auto flex">
|
||||
<div
|
||||
className="col col-2 pr2 pt1 sm-hide xs-hide"
|
||||
style={{overflow: 'hidden', backgroundColor: 'rgb(39, 39, 39)', color: 'white'}}
|
||||
style={portalMenuContainerStyle}
|
||||
>
|
||||
<PortalMenu menuItemStyle={{color: 'white'}} />
|
||||
<PortalMenu menuItemStyle={{color: colors.white}} />
|
||||
</div>
|
||||
<div className="col col-12 lg-col-10 md-col-10 sm-col sm-col-12">
|
||||
<div className="py2" style={{backgroundColor: colors.grey50}}>
|
||||
@@ -215,8 +240,12 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
toggleDialogFn={updateShouldBlockchainErrDialogBeOpen}
|
||||
networkId={this.props.networkId}
|
||||
/>
|
||||
<WrappedEthSectionNoticeDialog
|
||||
isOpen={this.state.isWethNoticeDialogOpen}
|
||||
onToggleDialog={this.onWethNoticeAccepted.bind(this)}
|
||||
/>
|
||||
<PortalDisclaimerDialog
|
||||
isOpen={!this.state.hasAcceptedDisclaimer}
|
||||
isOpen={this.state.isDisclaimerDialogOpen}
|
||||
onToggleDialog={this.onPortalDisclaimerAccepted.bind(this)}
|
||||
/>
|
||||
<FlashMessage
|
||||
@@ -224,7 +253,7 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
flashMessage={this.props.flashMessage}
|
||||
/>
|
||||
</div>
|
||||
<Footer location={this.props.location} />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -295,9 +324,15 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
|
||||
);
|
||||
}
|
||||
private onPortalDisclaimerAccepted() {
|
||||
localStorage.setItem(constants.ACCEPT_DISCLAIMER_LOCAL_STORAGE_KEY, 'set');
|
||||
localStorage.setItem(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER, 'set');
|
||||
this.setState({
|
||||
hasAcceptedDisclaimer: true,
|
||||
isDisclaimerDialogOpen: false,
|
||||
});
|
||||
}
|
||||
private onWethNoticeAccepted() {
|
||||
localStorage.setItem(constants.LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE, 'set');
|
||||
this.setState({
|
||||
isWethNoticeDialogOpen: false,
|
||||
});
|
||||
}
|
||||
private getSharedOrderIfExists(): Order {
|
||||
|
@@ -70,14 +70,14 @@ export class SendButton extends React.Component<SendButtonProps, SendButtonState
|
||||
this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance);
|
||||
} catch (err) {
|
||||
const errMsg = `${err}`;
|
||||
if (_.includes(errMsg, BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES)) {
|
||||
if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
|
||||
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
return;
|
||||
} else if (!_.includes(errMsg, 'User denied transaction')) {
|
||||
utils.consoleLog(`Unexpected error encountered: ${err}`);
|
||||
utils.consoleLog(err.stack);
|
||||
await errorReporter.reportAsync(err);
|
||||
this.props.onError();
|
||||
await errorReporter.reportAsync(err);
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
|
@@ -7,7 +7,6 @@ import Divider from 'material-ui/Divider';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import FloatingActionButton from 'material-ui/FloatingActionButton';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import ContentAdd from 'material-ui/svg-icons/content/add';
|
||||
import ContentRemove from 'material-ui/svg-icons/content/remove';
|
||||
import {
|
||||
@@ -42,6 +41,7 @@ import {
|
||||
TokenStateByAddress,
|
||||
TokenVisibility,
|
||||
} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {errorReporter} from 'ts/utils/error_reporter';
|
||||
@@ -115,7 +115,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
if (!_.isUndefined(this.state.currentZrxBalance) && !nextZrxTokenBalance.eq(this.state.currentZrxBalance)) {
|
||||
if (this.state.isZRXSpinnerVisible) {
|
||||
const receivedAmount = nextZrxTokenBalance.minus(this.state.currentZrxBalance);
|
||||
const receiveAmountInUnits = ZeroEx.toUnitAmount(receivedAmount, 18);
|
||||
const receiveAmountInUnits = ZeroEx.toUnitAmount(receivedAmount, constants.DECIMAL_PLACES_ZRX);
|
||||
this.props.dispatcher.showFlashMessage(`Received ${receiveAmountInUnits.toString(10)} Kovan ZRX`);
|
||||
}
|
||||
this.setState({
|
||||
@@ -144,7 +144,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
onTouchTap={this.onDharmaDialogToggle.bind(this, false)}
|
||||
/>,
|
||||
];
|
||||
const isTestNetwork = this.props.networkId === constants.TESTNET_NETWORK_ID;
|
||||
const isTestNetwork = this.props.networkId === constants.NETWORK_ID_TESTNET;
|
||||
const dharmaButtonColumnStyle = {
|
||||
paddingLeft: 3,
|
||||
display: isTestNetwork ? 'table-cell' : 'none',
|
||||
@@ -156,7 +156,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
const tokenTableHeight = allTokenRowHeight < MAX_TOKEN_TABLE_HEIGHT ?
|
||||
allTokenRowHeight :
|
||||
MAX_TOKEN_TABLE_HEIGHT;
|
||||
const isSmallScreen = this.props.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
|
||||
const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
|
||||
const dharmaLoanExplanation = 'If you need access to larger amounts of ether,<br> \
|
||||
you can request a loan from the Dharma Loan<br> \
|
||||
@@ -164,7 +164,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
minutes or less.';
|
||||
const allowanceExplanation = '0x smart contracts require access to your<br> \
|
||||
token balances in order to execute trades.<br> \
|
||||
Toggling permissions sets an allowance for the<br> \
|
||||
Toggling sets an allowance for the<br> \
|
||||
smart contract so you can start trading that token.';
|
||||
return (
|
||||
<div className="lg-px4 md-px4 sm-px1 pb2">
|
||||
@@ -302,7 +302,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn style={{paddingLeft: 3}}>Balance</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<div className="inline-block">{!isSmallScreen && 'Trade '}Permissions</div>
|
||||
<div className="inline-block">Allowance</div>
|
||||
<HelpTooltip
|
||||
style={{paddingLeft: 4}}
|
||||
explanation={allowanceExplanation}
|
||||
@@ -311,7 +311,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
<TableHeaderColumn>
|
||||
Action
|
||||
</TableHeaderColumn>
|
||||
{this.props.screenWidth !== ScreenWidths.SM &&
|
||||
{this.props.screenWidth !== ScreenWidths.Sm &&
|
||||
<TableHeaderColumn>
|
||||
Send
|
||||
</TableHeaderColumn>
|
||||
@@ -333,9 +333,9 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
</Dialog>
|
||||
<Dialog
|
||||
title="Request Dharma Loan"
|
||||
titleStyle={{fontWeight: 100, backgroundColor: 'rgb(250, 250, 250)'}}
|
||||
bodyStyle={{backgroundColor: 'rgb(37, 37, 37)'}}
|
||||
actionsContainerStyle={{backgroundColor: 'rgb(250, 250, 250)'}}
|
||||
titleStyle={{fontWeight: 100, backgroundColor: colors.white}}
|
||||
bodyStyle={{backgroundColor: colors.dharmaDarkGrey}}
|
||||
actionsContainerStyle={{backgroundColor: colors.white}}
|
||||
autoScrollBodyContent={true}
|
||||
actions={dharmaDialogActions}
|
||||
open={this.state.isDharmaDialogVisible}
|
||||
@@ -357,10 +357,10 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
);
|
||||
}
|
||||
private renderTokenTableRows() {
|
||||
if (!this.props.blockchainIsLoaded || this.props.blockchainErr !== '') {
|
||||
if (!this.props.blockchainIsLoaded || this.props.blockchainErr !== BlockchainErrs.NoError) {
|
||||
return '';
|
||||
}
|
||||
const isSmallScreen = this.props.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
|
||||
const tokenColSpan = isSmallScreen ? TOKEN_COL_SPAN_SM : TOKEN_COL_SPAN_LG;
|
||||
const actionPaddingX = isSmallScreen ? 2 : 24;
|
||||
const allTokens = _.values(this.props.tokenByAddress);
|
||||
@@ -379,9 +379,9 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
private renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token) {
|
||||
const tokenState = this.props.tokenStateByAddress[token.address];
|
||||
const tokenLink = utils.getEtherScanLinkIfExists(token.address, this.props.networkId,
|
||||
EtherscanLinkSuffixes.address);
|
||||
const isMintable = _.includes(configs.symbolsOfMintableTokens, token.symbol) &&
|
||||
this.props.networkId !== constants.MAINNET_NETWORK_ID;
|
||||
EtherscanLinkSuffixes.Address);
|
||||
const isMintable = _.includes(configs.SYMBOLS_OF_MINTABLE_TOKENS, token.symbol) &&
|
||||
this.props.networkId !== constants.NETWORK_ID_MAINNET;
|
||||
return (
|
||||
<TableRow key={token.address} style={{height: TOKEN_TABLE_ROW_HEIGHT}}>
|
||||
<TableRowColumn
|
||||
@@ -423,7 +423,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
onClickAsyncFn={this.onMintTestTokensAsync.bind(this, token)}
|
||||
/>
|
||||
}
|
||||
{token.symbol === ZRX_TOKEN_SYMBOL && this.props.networkId === constants.TESTNET_NETWORK_ID &&
|
||||
{token.symbol === ZRX_TOKEN_SYMBOL && this.props.networkId === constants.NETWORK_ID_TESTNET &&
|
||||
<LifeCycleRaisedButton
|
||||
labelReady="Request"
|
||||
labelLoading="Sending..."
|
||||
@@ -432,7 +432,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
/>
|
||||
}
|
||||
</TableRowColumn>
|
||||
{this.props.screenWidth !== ScreenWidths.SM &&
|
||||
{this.props.screenWidth !== ScreenWidths.Sm &&
|
||||
<TableRowColumn
|
||||
style={{paddingLeft: actionPaddingX, paddingRight: actionPaddingX}}
|
||||
>
|
||||
@@ -456,13 +456,14 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
return;
|
||||
}
|
||||
const token = this.props.tokenByAddress[tokenAddress];
|
||||
const isDefaultTrackedToken = _.includes(configs.defaultTrackedTokenSymbols, token.symbol);
|
||||
const isDefaultTrackedToken = _.includes(configs.DEFAULT_TRACKED_TOKEN_SYMBOLS, token.symbol);
|
||||
if (!this.state.isAddingToken && !isDefaultTrackedToken) {
|
||||
if (token.isRegistered) {
|
||||
// Remove the token from tracked tokens
|
||||
const newToken = _.assign({}, token, {
|
||||
const newToken = {
|
||||
...token,
|
||||
isTracked: false,
|
||||
});
|
||||
};
|
||||
this.props.dispatcher.updateTokenByAddress([newToken]);
|
||||
} else {
|
||||
this.props.dispatcher.removeTokenToTokenByAddress(token);
|
||||
@@ -507,7 +508,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
return (
|
||||
<div>
|
||||
Our faucet can only send test Ether to addresses on the {constants.TESTNET_NAME}
|
||||
{' '}testnet (networkId {constants.TESTNET_NETWORK_ID}). Please make sure you are
|
||||
{' '}testnet (networkId {constants.NETWORK_ID_TESTNET}). Please make sure you are
|
||||
{' '}connected to the {constants.TESTNET_NAME} testnet and try requesting ether again.
|
||||
</div>
|
||||
);
|
||||
@@ -580,7 +581,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
return true;
|
||||
} catch (err) {
|
||||
const errMsg = '' + err;
|
||||
if (_.includes(errMsg, BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES)) {
|
||||
if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) {
|
||||
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
return false;
|
||||
}
|
||||
@@ -604,7 +605,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
|
||||
// If on another network other then the testnet our faucet serves test ether
|
||||
// from, we must show user an error message
|
||||
if (this.props.blockchain.networkId !== constants.TESTNET_NETWORK_ID) {
|
||||
if (this.props.blockchain.networkId !== constants.NETWORK_ID_TESTNET) {
|
||||
this.setState({
|
||||
errorType: BalanceErrs.incorrectNetworkForFaucet,
|
||||
});
|
||||
@@ -614,7 +615,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala
|
||||
await utils.sleepAsync(ARTIFICIAL_FAUCET_REQUEST_DELAY);
|
||||
|
||||
const segment = isEtherRequest ? 'ether' : 'zrx';
|
||||
const response = await fetch(`${constants.ETHER_FAUCET_ENDPOINT}/${segment}/${this.props.userAddress}`);
|
||||
const response = await fetch(`${constants.URL_ETHER_FAUCET}/${segment}/${this.props.userAddress}`);
|
||||
const responseBody = await response.text();
|
||||
if (response.status !== constants.SUCCESS_STATUS) {
|
||||
utils.consoleLog(`Unexpected status code: ${response.status} -> ${responseBody}`);
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import * as _ from 'lodash';
|
||||
import Drawer from 'material-ui/Drawer';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import ReactTooltip = require('react-tooltip');
|
||||
@@ -12,11 +11,9 @@ import {Identicon} from 'ts/components/ui/identicon';
|
||||
import {DocsInfo} from 'ts/pages/documentation/docs_info';
|
||||
import {NestedSidebarMenu} from 'ts/pages/shared/nested_sidebar_menu';
|
||||
import {DocsMenu, MenuSubsectionsBySection, Styles, WebsitePaths} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
|
||||
const CUSTOM_DARK_GRAY = '#231F20';
|
||||
const SECTION_HEADER_COLOR = 'rgb(234, 234, 234)';
|
||||
|
||||
interface TopBarProps {
|
||||
userAddress?: string;
|
||||
blockchainIsLoaded: boolean;
|
||||
@@ -44,16 +41,11 @@ const styles: Styles = {
|
||||
whiteSpace: 'nowrap',
|
||||
width: 70,
|
||||
},
|
||||
addressPopover: {
|
||||
backgroundColor: colors.blueGrey500,
|
||||
color: 'white',
|
||||
padding: 3,
|
||||
},
|
||||
topBar: {
|
||||
backgroundColor: 'white',
|
||||
backgroundcolor: colors.white,
|
||||
height: 59,
|
||||
width: '100%',
|
||||
position: 'fixed',
|
||||
position: 'relative',
|
||||
top: 0,
|
||||
zIndex: 1100,
|
||||
paddingBottom: 1,
|
||||
@@ -63,7 +55,7 @@ const styles: Styles = {
|
||||
},
|
||||
menuItem: {
|
||||
fontSize: 14,
|
||||
color: CUSTOM_DARK_GRAY,
|
||||
color: colors.darkestGrey,
|
||||
paddingTop: 6,
|
||||
paddingBottom: 6,
|
||||
marginTop: 17,
|
||||
@@ -114,7 +106,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
key="subMenuItem-standard-relayer-api"
|
||||
target="_blank"
|
||||
className="text-decoration-none"
|
||||
href={constants.STANDARD_RELAYER_API_GITHUB}
|
||||
href={constants.URL_STANDARD_RELAYER_API_GITHUB}
|
||||
>
|
||||
<MenuItem style={{fontSize: styles.menuItem.fontSize}} primaryText="Standard Relayer API" />
|
||||
</a>,
|
||||
@@ -122,7 +114,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
key="subMenuItem-github"
|
||||
target="_blank"
|
||||
className="text-decoration-none"
|
||||
href={constants.GITHUB_URL}
|
||||
href={constants.URL_GITHUB_ORG}
|
||||
>
|
||||
<MenuItem style={{fontSize: styles.menuItem.fontSize}} primaryText="GitHub" />
|
||||
</a>,
|
||||
@@ -222,7 +214,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
{this.renderPortalMenu()}
|
||||
{this.renderDocsMenu()}
|
||||
{this.renderWiki()}
|
||||
<div className="pl1 py1 mt3" style={{backgroundColor: SECTION_HEADER_COLOR}}>Website</div>
|
||||
<div className="pl1 py1 mt3" style={{backgroundColor: colors.lightGrey}}>Website</div>
|
||||
<Link to={WebsitePaths.Home} className="text-decoration-none">
|
||||
<MenuItem className="py2">Home</MenuItem>
|
||||
</Link>
|
||||
@@ -262,7 +254,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
<a
|
||||
className="text-decoration-none"
|
||||
target="_blank"
|
||||
href={constants.BLOG_URL}
|
||||
href={constants.URL_BLOG}
|
||||
>
|
||||
<MenuItem className="py2">Blog</MenuItem>
|
||||
</a>
|
||||
@@ -286,7 +278,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
const sectionTitle = `${this.props.docsInfo.displayName} Docs`;
|
||||
return (
|
||||
<div className="lg-hide md-hide">
|
||||
<div className="pl1 py1" style={{backgroundColor: SECTION_HEADER_COLOR}}>{sectionTitle}</div>
|
||||
<div className="pl1 py1" style={{backgroundColor: colors.lightGrey}}>{sectionTitle}</div>
|
||||
<NestedSidebarMenu
|
||||
topLevelMenu={this.props.menu}
|
||||
menuSubsectionsBySection={this.props.menuSubsectionsBySection}
|
||||
@@ -306,7 +298,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
|
||||
return (
|
||||
<div className="lg-hide md-hide">
|
||||
<div className="pl1 py1" style={{backgroundColor: SECTION_HEADER_COLOR}}>0x Protocol Wiki</div>
|
||||
<div className="pl1 py1" style={{backgroundColor: colors.lightGrey}}>0x Protocol Wiki</div>
|
||||
<NestedSidebarMenu
|
||||
topLevelMenu={this.props.menuSubsectionsBySection}
|
||||
menuSubsectionsBySection={this.props.menuSubsectionsBySection}
|
||||
@@ -323,7 +315,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
|
||||
return (
|
||||
<div className="lg-hide md-hide">
|
||||
<div className="pl1 py1" style={{backgroundColor: SECTION_HEADER_COLOR}}>Portal DApp</div>
|
||||
<div className="pl1 py1" style={{backgroundColor: colors.lightGrey}}>Portal DApp</div>
|
||||
<PortalMenu
|
||||
menuItemStyle={{color: 'black'}}
|
||||
onClick={this.onMenuButtonClick.bind(this)}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
const CUSTOM_DARK_GRAY = '#231F20';
|
||||
const DEFAULT_STYLE = {
|
||||
color: CUSTOM_DARK_GRAY,
|
||||
color: colors.darkestGrey,
|
||||
};
|
||||
|
||||
interface TopBarMenuItemProps {
|
||||
@@ -28,7 +28,7 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM
|
||||
public render() {
|
||||
const primaryStyles = this.props.isPrimary ? {
|
||||
borderRadius: 4,
|
||||
border: `1px solid ${this.props.isNightVersion ? '#979797' : 'rgb(230, 229, 229)'}`,
|
||||
border: `1px solid ${this.props.isNightVersion ? colors.grey : colors.greyishPink}`,
|
||||
marginTop: 15,
|
||||
paddingLeft: 9,
|
||||
paddingRight: 9,
|
||||
@@ -36,7 +36,7 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM
|
||||
} : {};
|
||||
const menuItemColor = this.props.isNightVersion ? 'white' : this.props.style.color;
|
||||
const linkColor = _.isUndefined(menuItemColor) ?
|
||||
CUSTOM_DARK_GRAY :
|
||||
colors.darkestGrey :
|
||||
menuItemColor;
|
||||
return (
|
||||
<div
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Party} from 'ts/components/ui/party';
|
||||
import {Token, TokenByAddress} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
interface TrackTokenConfirmationProps {
|
||||
|
@@ -2,13 +2,13 @@ import {ZeroEx} from '0x.js';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as _ from 'lodash';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as moment from 'moment';
|
||||
import * as React from 'react';
|
||||
import * as ReactTooltip from 'react-tooltip';
|
||||
import {EtherScanIcon} from 'ts/components/ui/etherscan_icon';
|
||||
import {Party} from 'ts/components/ui/party';
|
||||
import {EtherscanLinkSuffixes, Fill, Token, TokenByAddress} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
const PRECISION = 5;
|
||||
const IDENTICON_DIAMETER = 40;
|
||||
@@ -87,7 +87,7 @@ export class TradeHistoryItem extends React.Component<TradeHistoryItemProps, Tra
|
||||
<EtherScanIcon
|
||||
addressOrTxHash={fill.transactionHash}
|
||||
networkId={this.props.networkId}
|
||||
etherscanLinkSuffixes={EtherscanLinkSuffixes.tx}
|
||||
etherscanLinkSuffixes={EtherscanLinkSuffixes.Tx}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,8 +1,6 @@
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {AlertTypes} from 'ts/types';
|
||||
|
||||
const CUSTOM_GREEN = 'rgb(137, 199, 116)';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface AlertProps {
|
||||
type: AlertTypes;
|
||||
@@ -12,8 +10,8 @@ interface AlertProps {
|
||||
export function Alert(props: AlertProps) {
|
||||
const isAlert = props.type === AlertTypes.ERROR;
|
||||
const errMsgStyles = {
|
||||
background: isAlert ? colors.red200 : CUSTOM_GREEN,
|
||||
color: 'white',
|
||||
background: isAlert ? colors.red200 : colors.lightestGreen,
|
||||
color: colors.white,
|
||||
marginTop: 10,
|
||||
padding: 4,
|
||||
paddingLeft: 8,
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import * as CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import ReactTooltip = require('react-tooltip');
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface CopyIconProps {
|
||||
data: string;
|
||||
|
@@ -2,9 +2,9 @@ import * as _ from 'lodash';
|
||||
import Menu from 'material-ui/Menu';
|
||||
import Popover from 'material-ui/Popover';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
const CHECK_CLOSE_POPOVER_INTERVAL_MS = 300;
|
||||
const CUSTOM_LIGHT_GRAY = '#848484';
|
||||
const DEFAULT_STYLE = {
|
||||
fontSize: 14,
|
||||
};
|
||||
@@ -72,7 +72,7 @@ export class DropDownMenuItem extends React.Component<DropDownMenuItemProps, Dro
|
||||
onMouseEnter={this.onHover.bind(this)}
|
||||
onMouseLeave={this.onHoverOff.bind(this)}
|
||||
>
|
||||
<Menu style={{color: CUSTOM_LIGHT_GRAY}}>
|
||||
<Menu style={{color: colors.grey}}>
|
||||
{this.props.subMenuItems}
|
||||
</Menu>
|
||||
</div>
|
||||
|
@@ -26,7 +26,7 @@ export const EthereumAddress = (props: EthereumAddressProps) => {
|
||||
<EtherScanIcon
|
||||
addressOrTxHash={props.address}
|
||||
networkId={props.networkId}
|
||||
etherscanLinkSuffixes={EtherscanLinkSuffixes.address}
|
||||
etherscanLinkSuffixes={EtherscanLinkSuffixes.Address}
|
||||
/>
|
||||
</div>
|
||||
<ReactTooltip id={tooltipId}>{props.address}</ReactTooltip>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import ReactTooltip = require('react-tooltip');
|
||||
import {EtherscanLinkSuffixes} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
interface EtherScanIconProps {
|
||||
@@ -13,7 +13,7 @@ interface EtherScanIconProps {
|
||||
|
||||
export const EtherScanIcon = (props: EtherScanIconProps) => {
|
||||
const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
|
||||
props.addressOrTxHash, props.networkId, EtherscanLinkSuffixes.address,
|
||||
props.addressOrTxHash, props.networkId, EtherscanLinkSuffixes.Address,
|
||||
);
|
||||
const transactionTooltipId = `${props.addressOrTxHash}-etherscan-icon-tooltip`;
|
||||
return (
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
export interface InputLabelProps {
|
||||
text: string | Element | React.ReactNode;
|
||||
@@ -7,7 +7,7 @@ export interface InputLabelProps {
|
||||
|
||||
const styles = {
|
||||
label: {
|
||||
color: colors.grey500,
|
||||
color: colors.grey,
|
||||
fontSize: 12,
|
||||
pointerEvents: 'none',
|
||||
textAlign: 'left',
|
||||
|
@@ -1,73 +0,0 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
|
||||
const CUSTOM_BLUE = '#63A6F1';
|
||||
|
||||
interface LabeledSwitcherProps {
|
||||
labelLeft: string;
|
||||
labelRight: string;
|
||||
isLeftInitiallySelected: boolean;
|
||||
onLeftLabelClickAsync: () => Promise<boolean>;
|
||||
onRightLabelClickAsync: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
interface LabeledSwitcherState {
|
||||
isLeftSelected: boolean;
|
||||
}
|
||||
|
||||
export class LabeledSwitcher extends React.Component<LabeledSwitcherProps, LabeledSwitcherState> {
|
||||
constructor(props: LabeledSwitcherProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isLeftSelected: props.isLeftInitiallySelected,
|
||||
};
|
||||
}
|
||||
public render() {
|
||||
const isLeft = true;
|
||||
return (
|
||||
<div
|
||||
className="rounded clearfix"
|
||||
>
|
||||
{this.renderLabel(this.props.labelLeft, isLeft, this.state.isLeftSelected)}
|
||||
{this.renderLabel(this.props.labelRight, !isLeft, !this.state.isLeftSelected)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private renderLabel(title: string, isLeft: boolean, isSelected: boolean) {
|
||||
const borderStyle = `2px solid ${isSelected ? '#4F8BCF' : '#DADADA'}`;
|
||||
const style = {
|
||||
cursor: 'pointer',
|
||||
backgroundColor: isSelected ? CUSTOM_BLUE : colors.grey200,
|
||||
color: isSelected ? 'white' : '#A5A5A5',
|
||||
boxShadow: isSelected ? `inset 0px 0px 4px #4083CE` : 'inset 0px 0px 4px #F7F6F6',
|
||||
borderTop: borderStyle,
|
||||
borderBottom: borderStyle,
|
||||
[isLeft ? 'borderLeft' : 'borderRight']: borderStyle,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={`col col-6 center p1 ${isLeft ? 'rounded-left' : 'rounded-right'}`}
|
||||
style={style}
|
||||
onClick={this.onLabelClickAsync.bind(this, isLeft)}
|
||||
>
|
||||
{title}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private async onLabelClickAsync(isLeft: boolean): Promise<void> {
|
||||
this.setState({
|
||||
isLeftSelected: isLeft,
|
||||
});
|
||||
const didSucceed = isLeft ?
|
||||
await this.props.onLeftLabelClickAsync() :
|
||||
await this.props.onRightLabelClickAsync();
|
||||
if (!didSucceed) {
|
||||
this.setState({
|
||||
isLeftSelected: !isLeft,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
import * as _ from 'lodash';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const COMPLETE_STATE_SHOW_LENGTH_MS = 2000;
|
||||
@@ -31,8 +32,8 @@ export class LifeCycleRaisedButton extends
|
||||
React.Component<LifeCycleRaisedButtonProps, LifeCycleRaisedButtonState> {
|
||||
public static defaultProps: Partial<LifeCycleRaisedButtonProps> = {
|
||||
isDisabled: false,
|
||||
backgroundColor: 'white',
|
||||
labelColor: 'rgb(97, 97, 97)',
|
||||
backgroundColor: colors.white,
|
||||
labelColor: colors.darkGrey,
|
||||
};
|
||||
private buttonTimeoutId: number;
|
||||
private didUnmount: boolean;
|
||||
|
@@ -1,15 +1,14 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import ReactTooltip = require('react-tooltip');
|
||||
import {EthereumAddress} from 'ts/components/ui/ethereum_address';
|
||||
import {Identicon} from 'ts/components/ui/identicon';
|
||||
import {EtherscanLinkSuffixes} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const IMAGE_DIMENSION = 100;
|
||||
const IDENTICON_DIAMETER = 95;
|
||||
const CHECK_MARK_GREEN = 'rgb(0, 195, 62)';
|
||||
|
||||
interface PartyProps {
|
||||
label: string;
|
||||
@@ -45,7 +44,7 @@ export class Party extends React.Component<PartyProps, PartyState> {
|
||||
height: IMAGE_DIMENSION,
|
||||
};
|
||||
const etherscanLinkIfExists = utils.getEtherScanLinkIfExists(
|
||||
this.props.address, this.props.networkId, EtherscanLinkSuffixes.address,
|
||||
this.props.address, this.props.networkId, EtherscanLinkSuffixes.Address,
|
||||
);
|
||||
const isRegistered = this.props.isInTokenRegistry;
|
||||
const registeredTooltipId = `${this.props.address}-${isRegistered}-registeredTooltip`;
|
||||
@@ -94,7 +93,7 @@ export class Party extends React.Component<PartyProps, PartyState> {
|
||||
className="mx-auto"
|
||||
style={{fontSize: 13, width: 127}}
|
||||
>
|
||||
<span style={{color: isRegistered ? CHECK_MARK_GREEN : colors.red500}}>
|
||||
<span style={{color: isRegistered ? colors.brightGreen : colors.red500}}>
|
||||
<i
|
||||
className={`zmdi ${isRegistered ? 'zmdi-check-circle' : 'zmdi-alert-triangle'}`}
|
||||
/>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
export interface RequiredLabelProps {
|
||||
label: string|React.ReactNode;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface SwapIconProps {
|
||||
swapTokensFn: () => void;
|
||||
|
@@ -43,8 +43,8 @@ interface ConnectedDispatch {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: State, ownProps: PortalComponentAllProps): ConnectedState => {
|
||||
const receiveAssetToken = state.sideToAssetToken[Side.receive];
|
||||
const depositAssetToken = state.sideToAssetToken[Side.deposit];
|
||||
const receiveAssetToken = state.sideToAssetToken[Side.Receive];
|
||||
const depositAssetToken = state.sideToAssetToken[Side.Deposit];
|
||||
const receiveAddress = !_.isUndefined(receiveAssetToken.address) ?
|
||||
receiveAssetToken.address : constants.NULL_ADDRESS;
|
||||
const depositAddress = !_.isUndefined(depositAssetToken.address) ?
|
||||
@@ -56,7 +56,7 @@ const mapStateToProps = (state: State, ownProps: PortalComponentAllProps): Conne
|
||||
const hashData = {
|
||||
depositAmount,
|
||||
depositTokenContractAddr: depositAddress,
|
||||
feeRecipientAddress: constants.FEE_RECIPIENT_ADDRESS,
|
||||
feeRecipientAddress: constants.NULL_ADDRESS,
|
||||
makerFee: constants.MAKER_FEE,
|
||||
orderExpiryTimestamp: state.orderExpiryTimestamp,
|
||||
orderMakerAddress: state.userAddress,
|
||||
|
@@ -9,16 +9,13 @@ import {
|
||||
} from 'ts/pages/documentation/documentation';
|
||||
import {Dispatcher} from 'ts/redux/dispatcher';
|
||||
import {State} from 'ts/redux/reducer';
|
||||
import {DocsInfoConfig, WebsitePaths} from 'ts/types';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {DocsInfoConfig, SmartContractDocSections as Sections, WebsitePaths} from 'ts/types';
|
||||
import {doxityUtils} from 'ts/utils/doxity_utils';
|
||||
|
||||
/* tslint:disable:no-var-requires */
|
||||
const IntroMarkdown = require('md/docs/smart_contracts/introduction');
|
||||
/* tslint:enable:no-var-requires */
|
||||
|
||||
const sections = constants.smartContractDocSections;
|
||||
|
||||
const docsInfoConfig: DocsInfoConfig = {
|
||||
displayName: '0x Smart Contracts',
|
||||
packageUrl: 'https://github.com/0xProject/contracts',
|
||||
@@ -26,26 +23,30 @@ const docsInfoConfig: DocsInfoConfig = {
|
||||
docsJsonRoot: 'https://s3.amazonaws.com/smart-contracts-docs-json',
|
||||
menu: {
|
||||
introduction: [
|
||||
sections.Introduction,
|
||||
Sections.Introduction,
|
||||
],
|
||||
contracts: [
|
||||
sections.Exchange,
|
||||
sections.TokenRegistry,
|
||||
sections.ZRXToken,
|
||||
sections.EtherToken,
|
||||
sections.TokenTransferProxy,
|
||||
Sections.Exchange,
|
||||
Sections.TokenRegistry,
|
||||
Sections.ZRXToken,
|
||||
Sections.TokenTransferProxy,
|
||||
],
|
||||
},
|
||||
sectionNameToMarkdown: {
|
||||
[sections.Introduction]: IntroMarkdown,
|
||||
[Sections.Introduction]: IntroMarkdown,
|
||||
},
|
||||
sections: {
|
||||
Introduction: Sections.Introduction,
|
||||
Exchange: Sections.Exchange,
|
||||
TokenTransferProxy: Sections.TokenTransferProxy,
|
||||
TokenRegistry: Sections.TokenRegistry,
|
||||
ZRXToken: Sections.ZRXToken,
|
||||
},
|
||||
sections,
|
||||
visibleConstructors: [
|
||||
sections.Exchange,
|
||||
sections.TokenRegistry,
|
||||
sections.ZRXToken,
|
||||
sections.EtherToken,
|
||||
sections.TokenTransferProxy,
|
||||
Sections.Exchange,
|
||||
Sections.TokenRegistry,
|
||||
Sections.ZRXToken,
|
||||
Sections.TokenTransferProxy,
|
||||
],
|
||||
convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils),
|
||||
};
|
||||
|
@@ -1,8 +1,8 @@
|
||||
// Polyfills
|
||||
import 'whatwg-fetch';
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import {colors, getMuiTheme, MuiThemeProvider} from 'material-ui/styles';
|
||||
import {bigNumberConfigs} from '@0xproject/utils';
|
||||
import {MuiThemeProvider} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {render} from 'react-dom';
|
||||
import {Provider} from 'react-redux';
|
||||
@@ -19,59 +19,18 @@ import {NotFound} from 'ts/pages/not_found';
|
||||
import {Wiki} from 'ts/pages/wiki/wiki';
|
||||
import {reducer, State} from 'ts/redux/reducer';
|
||||
import {WebsitePaths} from 'ts/types';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {muiTheme} from 'ts/utils/mui_theme';
|
||||
injectTapEventPlugin();
|
||||
|
||||
// By default BigNumber's `toString` method converts to exponential notation if the value has
|
||||
// more then 20 digits. We want to avoid this behavior, so we set EXPONENTIAL_AT to a high number
|
||||
BigNumber.config({
|
||||
EXPONENTIAL_AT: 1000,
|
||||
});
|
||||
bigNumberConfigs.configure();
|
||||
|
||||
// Check if we've introduced an update that requires us to clear the tradeHistory local storage entries
|
||||
tradeHistoryStorage.clearIfRequired();
|
||||
trackedTokenStorage.clearIfRequired();
|
||||
|
||||
const CUSTOM_GREY = 'rgb(39, 39, 39)';
|
||||
const CUSTOM_GREEN = 'rgb(102, 222, 117)';
|
||||
const CUSTOM_DARKER_GREEN = 'rgb(77, 197, 92)';
|
||||
|
||||
import 'basscss/css/basscss.css';
|
||||
import 'less/all.less';
|
||||
|
||||
const muiTheme = getMuiTheme({
|
||||
appBar: {
|
||||
height: 45,
|
||||
color: 'white',
|
||||
textColor: 'black',
|
||||
},
|
||||
palette: {
|
||||
pickerHeaderColor: constants.CUSTOM_BLUE,
|
||||
primary1Color: constants.CUSTOM_BLUE,
|
||||
primary2Color: constants.CUSTOM_BLUE,
|
||||
textColor: colors.grey700,
|
||||
},
|
||||
datePicker: {
|
||||
color: colors.grey700,
|
||||
textColor: 'white',
|
||||
calendarTextColor: 'white',
|
||||
selectColor: CUSTOM_GREY,
|
||||
selectTextColor: 'white',
|
||||
},
|
||||
timePicker: {
|
||||
color: colors.grey700,
|
||||
textColor: 'white',
|
||||
accentColor: 'white',
|
||||
headerColor: CUSTOM_GREY,
|
||||
selectColor: CUSTOM_GREY,
|
||||
selectTextColor: CUSTOM_GREY,
|
||||
},
|
||||
toggle: {
|
||||
thumbOnColor: CUSTOM_GREEN,
|
||||
trackOnColor: CUSTOM_DARKER_GREEN,
|
||||
},
|
||||
});
|
||||
|
||||
// We pass modulePromise returning lambda instead of module promise,
|
||||
// cause we only want to import the module when the user navigates to the page.
|
||||
// At the same time webpack statically parses for System.import() to determine bundle chunk split points
|
||||
|
@@ -11,10 +11,10 @@ export const trackedTokenStorage = {
|
||||
// that introduced a backward incompatible change requiring the tracked tokens to be re-set
|
||||
clearIfRequired() {
|
||||
const lastClearFillDate = localStorage.getItemIfExists(TRACKED_TOKENS_CLEAR_KEY);
|
||||
if (lastClearFillDate !== configs.lastLocalStorageTrackedTokenClearanceDate) {
|
||||
if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE) {
|
||||
localStorage.removeItem(TRACKED_TOKENS_KEY);
|
||||
}
|
||||
localStorage.setItem(TRACKED_TOKENS_CLEAR_KEY, configs.lastLocalStorageTrackedTokenClearanceDate);
|
||||
localStorage.setItem(TRACKED_TOKENS_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE);
|
||||
},
|
||||
addTrackedTokenToUser(userAddress: string, networkId: number, token: Token) {
|
||||
const trackedTokensByUserAddress = this.getTrackedTokensByUserAddress();
|
||||
|
@@ -16,7 +16,7 @@ export const tradeHistoryStorage = {
|
||||
// the blockchain
|
||||
clearIfRequired() {
|
||||
const lastClearFillDate = localStorage.getItemIfExists(FILL_CLEAR_KEY);
|
||||
if (lastClearFillDate !== configs.lastLocalStorageFillClearanceDate) {
|
||||
if (lastClearFillDate !== configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE) {
|
||||
const localStorageKeys = localStorage.getAllKeys();
|
||||
_.each(localStorageKeys, key => {
|
||||
if (_.startsWith(key, `${FILLS_KEY}-`) || _.startsWith(key, `${FILLS_LATEST_BLOCK}-`)) {
|
||||
@@ -24,7 +24,7 @@ export const tradeHistoryStorage = {
|
||||
}
|
||||
});
|
||||
}
|
||||
localStorage.setItem(FILL_CLEAR_KEY, configs.lastLocalStorageFillClearanceDate);
|
||||
localStorage.setItem(FILL_CLEAR_KEY, configs.LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE);
|
||||
},
|
||||
addFillToUser(userAddress: string, networkId: number, fill: Fill) {
|
||||
const fillsByHash = this.getUserFillsByHash(userAddress, networkId);
|
||||
|
@@ -1,18 +1,14 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import * as DocumentTitle from 'react-document-title';
|
||||
import {Footer} from 'ts/components/footer';
|
||||
import {TopBar} from 'ts/components/top_bar';
|
||||
import {Profile} from 'ts/pages/about/profile';
|
||||
import {ProfileInfo, Styles} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const CUSTOM_BACKGROUND_COLOR = '#F0F0F0';
|
||||
const CUSTOM_GRAY = '#4C4C4C';
|
||||
const CUSTOM_LIGHT_GRAY = '#A2A2A2';
|
||||
|
||||
const teamRow1: ProfileInfo[] = [
|
||||
{
|
||||
name: 'Will Warren',
|
||||
@@ -145,6 +141,12 @@ const styles: Styles = {
|
||||
color: 'black',
|
||||
paddingTop: 110,
|
||||
},
|
||||
weAreHiring: {
|
||||
fontSize: 30,
|
||||
color: colors.darkestGrey,
|
||||
fontFamily: 'Roboto Mono',
|
||||
letterSpacing: 7.5,
|
||||
},
|
||||
};
|
||||
|
||||
export class About extends React.Component<AboutProps, AboutState> {
|
||||
@@ -153,12 +155,12 @@ export class About extends React.Component<AboutProps, AboutState> {
|
||||
}
|
||||
public render() {
|
||||
return (
|
||||
<div style={{backgroundColor: CUSTOM_BACKGROUND_COLOR}}>
|
||||
<div style={{backgroundColor: colors.lightestGrey}}>
|
||||
<DocumentTitle title="0x About Us"/>
|
||||
<TopBar
|
||||
blockchainIsLoaded={false}
|
||||
location={this.props.location}
|
||||
style={{backgroundColor: CUSTOM_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.lightestGrey}}
|
||||
/>
|
||||
<div
|
||||
id="about"
|
||||
@@ -176,7 +178,7 @@ export class About extends React.Component<AboutProps, AboutState> {
|
||||
</div>
|
||||
<div
|
||||
className="pt3"
|
||||
style={{fontSize: 17, color: CUSTOM_GRAY, lineHeight: 1.5}}
|
||||
style={{fontSize: 17, color: colors.darkestGrey, lineHeight: 1.5}}
|
||||
>
|
||||
Our team is a diverse and globally distributed group with backgrounds
|
||||
in engineering, research, business and design. We are passionate about
|
||||
@@ -195,7 +197,7 @@ export class About extends React.Component<AboutProps, AboutState> {
|
||||
<div className="pt3 pb2">
|
||||
<div
|
||||
className="pt2 pb3 sm-center md-pl4 lg-pl0 md-ml3"
|
||||
style={{color: CUSTOM_LIGHT_GRAY, fontSize: 24, fontFamily: 'Roboto Mono'}}
|
||||
style={{color: colors.grey, fontSize: 24, fontFamily: 'Roboto Mono'}}
|
||||
>
|
||||
Advisors:
|
||||
</div>
|
||||
@@ -206,17 +208,17 @@ export class About extends React.Component<AboutProps, AboutState> {
|
||||
<div className="mx-auto py4 sm-px3" style={{maxWidth: 308}}>
|
||||
<div
|
||||
className="pb2"
|
||||
style={{fontSize: 30, color: CUSTOM_GRAY, fontFamily: 'Roboto Mono', letterSpacing: 7.5}}
|
||||
style={styles.weAreHiring}
|
||||
>
|
||||
WE'RE HIRING
|
||||
</div>
|
||||
<div
|
||||
className="pb4 mb4"
|
||||
style={{fontSize: 16, color: CUSTOM_GRAY, lineHeight: 1.5, letterSpacing: '0.5px'}}
|
||||
style={{fontSize: 16, color: colors.darkestGrey, lineHeight: 1.5, letterSpacing: '0.5px'}}
|
||||
>
|
||||
We are seeking outstanding candidates to{' '}
|
||||
<a
|
||||
href={constants.ANGELLIST_URL}
|
||||
href={constants.URL_ANGELLIST}
|
||||
target="_blank"
|
||||
style={{color: 'black'}}
|
||||
>
|
||||
@@ -226,7 +228,7 @@ export class About extends React.Component<AboutProps, AboutState> {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer location={this.props.location} />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import {ProfileInfo, Styles} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
const IMAGE_DIMENSION = 149;
|
||||
const styles: Styles = {
|
||||
@@ -48,7 +49,7 @@ export function Profile(props: ProfileProps) {
|
||||
{!_.isUndefined(props.profileInfo.title) &&
|
||||
<div
|
||||
className="pt1 center"
|
||||
style={{fontSize: 14, fontFamily: 'Roboto Mono', color: '#818181'}}
|
||||
style={{fontSize: 14, fontFamily: 'Roboto Mono', color: colors.darkGrey}}
|
||||
>
|
||||
{props.profileInfo.title.toUpperCase()}
|
||||
</div>
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import findVersions = require('find-versions');
|
||||
import * as _ from 'lodash';
|
||||
import CircularProgress from 'material-ui/CircularProgress';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import DocumentTitle = require('react-document-title');
|
||||
import {
|
||||
@@ -34,19 +33,18 @@ import {
|
||||
TypeDefinitionByName,
|
||||
TypescriptMethod,
|
||||
} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {docUtils} from 'ts/utils/doc_utils';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const SCROLL_TOP_ID = 'docsScrollTop';
|
||||
const CUSTOM_PURPLE = '#690596';
|
||||
const CUSTOM_RED = '#e91751';
|
||||
const CUSTOM_TURQUOIS = '#058789';
|
||||
|
||||
const networkNameToColor: {[network: string]: string} = {
|
||||
[Networks.kovan]: CUSTOM_PURPLE,
|
||||
[Networks.ropsten]: CUSTOM_RED,
|
||||
[Networks.mainnet]: CUSTOM_TURQUOIS,
|
||||
[Networks.kovan]: colors.purple,
|
||||
[Networks.ropsten]: colors.red,
|
||||
[Networks.mainnet]: colors.turquois,
|
||||
};
|
||||
|
||||
export interface DocumentationAllProps {
|
||||
@@ -273,7 +271,7 @@ export class Documentation extends
|
||||
);
|
||||
}
|
||||
private renderNetworkBadgesIfExists(sectionName: string) {
|
||||
const networkToAddressByContractName = constants.contractAddresses[this.props.docsVersion];
|
||||
const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
|
||||
const badges = _.map(networkToAddressByContractName,
|
||||
(addressByContractName: AddressByContractName, networkName: string) => {
|
||||
const contractAddress = addressByContractName[sectionName];
|
||||
@@ -281,14 +279,14 @@ export class Documentation extends
|
||||
return null;
|
||||
}
|
||||
const linkIfExists = utils.getEtherScanLinkIfExists(
|
||||
contractAddress, constants.networkIdByName[networkName], EtherscanLinkSuffixes.address,
|
||||
contractAddress, constants.NETWORK_ID_BY_NAME[networkName], EtherscanLinkSuffixes.Address,
|
||||
);
|
||||
return (
|
||||
<a
|
||||
key={`badge-${networkName}-${sectionName}`}
|
||||
href={linkIfExists}
|
||||
target="_blank"
|
||||
style={{color: 'white', textDecoration: 'none'}}
|
||||
style={{color: colors.white, textDecoration: 'none'}}
|
||||
>
|
||||
<Badge
|
||||
title={networkName}
|
||||
|
@@ -4,8 +4,7 @@ import {DocsInfo} from 'ts/pages/documentation/docs_info';
|
||||
import {Type} from 'ts/pages/documentation/type';
|
||||
import {AnchorTitle} from 'ts/pages/shared/anchor_title';
|
||||
import {Event, EventArg, HeaderSizes} from 'ts/types';
|
||||
|
||||
const CUSTOM_GREEN = 'rgb(77, 162, 75)';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface EventDefinitionProps {
|
||||
event: Event;
|
||||
@@ -50,7 +49,7 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event
|
||||
);
|
||||
}
|
||||
private renderEventCode() {
|
||||
const indexed = <span style={{color: CUSTOM_GREEN}}> indexed</span>;
|
||||
const indexed = <span style={{color: colors.green}}> indexed</span>;
|
||||
const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
|
||||
const type = (
|
||||
<Type
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Comment} from 'ts/pages/documentation/comment';
|
||||
import {DocsInfo} from 'ts/pages/documentation/docs_info';
|
||||
@@ -14,6 +13,7 @@ import {
|
||||
TypeDefinitionByName,
|
||||
TypescriptMethod,
|
||||
} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {typeDocUtils} from 'ts/utils/typedoc_utils';
|
||||
|
||||
interface MethodBlockProps {
|
||||
@@ -31,7 +31,7 @@ const styles: Styles = {
|
||||
chip: {
|
||||
fontSize: 13,
|
||||
backgroundColor: colors.lightBlueA700,
|
||||
color: 'white',
|
||||
color: colors.white,
|
||||
height: 11,
|
||||
borderRadius: 14,
|
||||
marginTop: 19,
|
||||
@@ -150,7 +150,7 @@ export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockSt
|
||||
<div className="bold">
|
||||
{parameter.name}
|
||||
</div>
|
||||
<div className="pt1" style={{color: colors.grey500, fontSize: 14}}>
|
||||
<div className="pt1" style={{color: colors.grey, fontSize: 14}}>
|
||||
{isOptional && 'optional'}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Source} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
interface SourceLinkProps {
|
||||
source: Source;
|
||||
@@ -29,7 +29,7 @@ export function SourceLink(props: SourceLinkProps) {
|
||||
href={sourceCodeUrl}
|
||||
target="_blank"
|
||||
className="underline"
|
||||
style={{color: colors.grey500}}
|
||||
style={{color: colors.grey}}
|
||||
>
|
||||
Source
|
||||
</a>
|
||||
|
@@ -1,24 +1,21 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Link as ScrollLink} from 'react-scroll';
|
||||
import * as ReactTooltip from 'react-tooltip';
|
||||
import {DocsInfo} from 'ts/pages/documentation/docs_info';
|
||||
import {TypeDefinition} from 'ts/pages/documentation/type_definition';
|
||||
import {Type as TypeDef, TypeDefinitionByName, TypeDocTypes} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const BUILT_IN_TYPE_COLOR = '#e69d00';
|
||||
const STRING_LITERAL_COLOR = '#4da24b';
|
||||
|
||||
// Some types reference other libraries. For these types, we want to link the user to the relevant documentation.
|
||||
const typeToUrl: {[typeName: string]: string} = {
|
||||
Web3: constants.WEB3_DOCS_URL,
|
||||
Provider: constants.WEB3_PROVIDER_DOCS_URL,
|
||||
BigNumber: constants.BIGNUMBERJS_GITHUB_URL,
|
||||
DecodedLogEntryEvent: constants.WEB3_DECODED_LOG_ENTRY_EVENT_URL,
|
||||
LogEntryEvent: constants.WEB3_LOG_ENTRY_EVENT_URL,
|
||||
Web3: constants.URL_WEB3_DOCS,
|
||||
Provider: constants.URL_WEB3_PROVIDER_DOCS,
|
||||
BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
|
||||
DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT,
|
||||
LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT,
|
||||
};
|
||||
|
||||
const typePrefix: {[typeName: string]: string} = {
|
||||
@@ -56,7 +53,7 @@ export function Type(props: TypeProps): any {
|
||||
case TypeDocTypes.Intrinsic:
|
||||
case TypeDocTypes.Unknown:
|
||||
typeName = type.name;
|
||||
typeNameColor = BUILT_IN_TYPE_COLOR;
|
||||
typeNameColor = colors.orange;
|
||||
break;
|
||||
|
||||
case TypeDocTypes.Reference:
|
||||
@@ -90,7 +87,7 @@ export function Type(props: TypeProps): any {
|
||||
|
||||
case TypeDocTypes.StringLiteral:
|
||||
typeName = `'${type.value}'`;
|
||||
typeNameColor = STRING_LITERAL_COLOR;
|
||||
typeNameColor = colors.green;
|
||||
break;
|
||||
|
||||
case TypeDocTypes.Array:
|
||||
|
@@ -9,10 +9,9 @@ import {MethodSignature} from 'ts/pages/documentation/method_signature';
|
||||
import {Type} from 'ts/pages/documentation/type';
|
||||
import {AnchorTitle} from 'ts/pages/shared/anchor_title';
|
||||
import {CustomType, CustomTypeChild, HeaderSizes, KindString, TypeDocTypes} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
const KEYWORD_COLOR = '#a81ca6';
|
||||
|
||||
interface TypeDefinitionProps {
|
||||
customType: CustomType;
|
||||
shouldAddId?: boolean;
|
||||
@@ -76,11 +75,15 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
|
||||
);
|
||||
break;
|
||||
|
||||
case KindString['Type alias']:
|
||||
case KindString.TypeAlias:
|
||||
typePrefix = 'Type Alias';
|
||||
codeSnippet = (
|
||||
<span>
|
||||
<span style={{color: KEYWORD_COLOR}}>type</span> {customType.name} ={' '}
|
||||
<span
|
||||
style={{color: colors.lightPurple}}
|
||||
>
|
||||
type
|
||||
</span> {customType.name} ={' '}
|
||||
{customType.type.typeDocType !== TypeDocTypes.Reflection ?
|
||||
<Type type={customType.type} docsInfo={this.props.docsInfo} /> :
|
||||
<MethodSignature
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import * as _ from 'lodash';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import * as DocumentTitle from 'react-document-title';
|
||||
import {Footer} from 'ts/components/footer';
|
||||
import {TopBar} from 'ts/components/top_bar';
|
||||
import {Question} from 'ts/pages/faq/question';
|
||||
import {FAQQuestion, FAQSection, Styles, WebsitePaths} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
|
||||
@@ -411,7 +411,7 @@ const sections: FAQSection[] = [
|
||||
prompt: 'How can I get involved?',
|
||||
answer: (
|
||||
<div>
|
||||
Join our <a href={constants.ZEROEX_CHAT_URL} target="_blank">Rocket.chat</a>!
|
||||
Join our <a href={constants.URL_ZEROEX_CHAT} target="_blank">Rocket.chat</a>!
|
||||
As an open source project, 0x will rely on a worldwide community of passionate
|
||||
developers to contribute proposals, ideas and code.
|
||||
</div>
|
||||
@@ -462,7 +462,7 @@ export class FAQ extends React.Component<FAQProps, FAQState> {
|
||||
{this.renderSections()}
|
||||
</div>
|
||||
</div>
|
||||
<Footer location={this.props.location} />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import * as _ from 'lodash';
|
||||
import {Card, CardHeader, CardText} from 'material-ui/Card';
|
||||
import * as React from 'react';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
export interface QuestionProps {
|
||||
prompt: string;
|
||||
@@ -31,7 +32,7 @@ export class Question extends React.Component<QuestionProps, QuestionState> {
|
||||
<CardHeader
|
||||
title={this.props.prompt}
|
||||
style={{borderBottom: this.state.isExpanded ? '1px solid rgba(0, 0, 0, 0.19)' : 'none'}}
|
||||
titleStyle={{color: 'rgb(66, 66, 66)'}}
|
||||
titleStyle={{color: colors.darkerGrey}}
|
||||
actAsExpander={true}
|
||||
showExpandableButton={true}
|
||||
/>
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import * as _ from 'lodash';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import DocumentTitle = require('react-document-title');
|
||||
import {Link} from 'react-router-dom';
|
||||
import {Footer} from 'ts/components/footer';
|
||||
import {TopBar} from 'ts/components/top_bar';
|
||||
import {ScreenWidths, WebsitePaths} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
@@ -35,11 +35,6 @@ interface Project {
|
||||
}
|
||||
|
||||
const THROTTLE_TIMEOUT = 100;
|
||||
const CUSTOM_HERO_BACKGROUND_COLOR = '#404040';
|
||||
const CUSTOM_PROJECTS_BACKGROUND_COLOR = '#343333';
|
||||
const CUSTOM_WHITE_BACKGROUND = 'rgb(245, 245, 245)';
|
||||
const CUSTOM_WHITE_TEXT = '#E4E4E4';
|
||||
const CUSTOM_GRAY_TEXT = '#919191';
|
||||
|
||||
const boxContents: BoxContent[] = [
|
||||
{
|
||||
@@ -70,67 +65,67 @@ const boxContents: BoxContent[] = [
|
||||
const projects: Project[] = [
|
||||
{
|
||||
logoFileName: 'ethfinex-top.png',
|
||||
projectUrl: constants.ETHFINEX_URL,
|
||||
projectUrl: constants.PROJECT_URL_ETHFINEX,
|
||||
},
|
||||
{
|
||||
logoFileName: 'radar_relay_top.png',
|
||||
projectUrl: constants.RADAR_RELAY_URL,
|
||||
projectUrl: constants.PROJECT_URL_RADAR_RELAY,
|
||||
},
|
||||
{
|
||||
logoFileName: 'paradex_top.png',
|
||||
projectUrl: constants.PARADEX_URL,
|
||||
projectUrl: constants.PROJECT_URL_PARADEX,
|
||||
},
|
||||
{
|
||||
logoFileName: 'the_ocean.png',
|
||||
projectUrl: constants.OCEAN_URL,
|
||||
projectUrl: constants.PROJECT_URL_0CEAN,
|
||||
},
|
||||
{
|
||||
logoFileName: 'dydx.png',
|
||||
projectUrl: constants.DYDX_URL,
|
||||
projectUrl: constants.PROJECT_URL_DYDX,
|
||||
},
|
||||
{
|
||||
logoFileName: 'melonport.png',
|
||||
projectUrl: constants.MELONPORT_URL,
|
||||
projectUrl: constants.PROJECT_URL_MELONPORT,
|
||||
},
|
||||
{
|
||||
logoFileName: 'maker.png',
|
||||
projectUrl: constants.MAKER_URL,
|
||||
projectUrl: constants.PROJECT_URL_MAKER,
|
||||
},
|
||||
{
|
||||
logoFileName: 'dharma.png',
|
||||
projectUrl: constants.DHARMA_URL,
|
||||
projectUrl: constants.PROJECT_URL_DHARMA,
|
||||
},
|
||||
{
|
||||
logoFileName: 'lendroid.png',
|
||||
projectUrl: constants.LENDROID_URL,
|
||||
projectUrl: constants.PROJECT_URL_LENDROID,
|
||||
},
|
||||
{
|
||||
logoFileName: 'district0x.png',
|
||||
projectUrl: constants.DISTRICT_0X_URL,
|
||||
projectUrl: constants.PROJECT_URL_DISTRICT_0X,
|
||||
},
|
||||
{
|
||||
logoFileName: 'aragon.png',
|
||||
projectUrl: constants.ARAGON_URL,
|
||||
projectUrl: constants.PROJECT_URL_ARAGON,
|
||||
},
|
||||
{
|
||||
logoFileName: 'blocknet.png',
|
||||
projectUrl: constants.BLOCKNET_URL,
|
||||
projectUrl: constants.PROJECT_URL_BLOCKNET,
|
||||
},
|
||||
{
|
||||
logoFileName: 'status.png',
|
||||
projectUrl: constants.STATUS_URL,
|
||||
projectUrl: constants.PROJECT_URL_STATUS,
|
||||
},
|
||||
{
|
||||
logoFileName: 'augur.png',
|
||||
projectUrl: constants.AUGUR_URL,
|
||||
projectUrl: constants.PROJECT_URL_AUGUR,
|
||||
},
|
||||
{
|
||||
logoFileName: 'anx.png',
|
||||
projectUrl: constants.OPEN_ANX_URL,
|
||||
projectUrl: constants.PROJECT_URL_OPEN_ANX,
|
||||
},
|
||||
{
|
||||
logoFileName: 'auctus.png',
|
||||
projectUrl: constants.AUCTUS_URL,
|
||||
projectUrl: constants.PROJECT_URL_AUCTUS,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -160,13 +155,13 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
}
|
||||
public render() {
|
||||
return (
|
||||
<div id="landing" className="clearfix" style={{color: colors.grey800}}>
|
||||
<div id="landing" className="clearfix" style={{color: colors.grey500}}>
|
||||
<DocumentTitle title="0x Protocol"/>
|
||||
<TopBar
|
||||
blockchainIsLoaded={false}
|
||||
location={this.props.location}
|
||||
isNightVersion={true}
|
||||
style={{backgroundColor: CUSTOM_HERO_BACKGROUND_COLOR, position: 'relative'}}
|
||||
style={{backgroundColor: colors.heroGrey, position: 'relative'}}
|
||||
/>
|
||||
{this.renderHero()}
|
||||
{this.renderProjects()}
|
||||
@@ -176,12 +171,12 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
{this.renderBuildingBlocksSection()}
|
||||
{this.renderUseCases()}
|
||||
{this.renderCallToAction()}
|
||||
<Footer location={this.props.location} />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private renderHero() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
const buttonLabelStyle: React.CSSProperties = {
|
||||
textTransform: 'none',
|
||||
fontSize: isSmallScreen ? 12 : 14,
|
||||
@@ -197,7 +192,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
return (
|
||||
<div
|
||||
className="clearfix py4"
|
||||
style={{backgroundColor: CUSTOM_HERO_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.heroGrey}}
|
||||
>
|
||||
<div
|
||||
className="mx-auto max-width-4 clearfix"
|
||||
@@ -211,7 +206,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
</div>
|
||||
<div
|
||||
className={left}
|
||||
style={{color: 'white'}}
|
||||
style={{color: colors.white}}
|
||||
>
|
||||
<div style={{paddingLeft: isSmallScreen ? 0 : 12}}>
|
||||
<div
|
||||
@@ -241,7 +236,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
</div>
|
||||
<div className="col col-6 sm-center">
|
||||
<a
|
||||
href={constants.ZEROEX_CHAT_URL}
|
||||
href={constants.URL_ZEROEX_CHAT}
|
||||
target="_blank"
|
||||
className="text-decoration-none"
|
||||
>
|
||||
@@ -249,7 +244,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
style={{borderRadius: 6, minWidth: 150}}
|
||||
buttonStyle={lightButtonStyle}
|
||||
labelColor="white"
|
||||
backgroundColor={CUSTOM_HERO_BACKGROUND_COLOR}
|
||||
backgroundColor={colors.heroGrey}
|
||||
labelStyle={buttonLabelStyle}
|
||||
label="Join the community"
|
||||
onClick={_.noop}
|
||||
@@ -265,8 +260,8 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderProjects() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isMediumScreen = this.state.screenWidth === ScreenWidths.MD;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
const isMediumScreen = this.state.screenWidth === ScreenWidths.Md;
|
||||
const projectList = _.map(projects, (project: Project, i: number) => {
|
||||
const colWidth = isSmallScreen ? 3 : (isMediumScreen ? 4 : 2 - (i % 2));
|
||||
return (
|
||||
@@ -291,7 +286,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
});
|
||||
const titleStyle: React.CSSProperties = {
|
||||
fontFamily: 'Roboto Mono',
|
||||
color: '#A4A4A4',
|
||||
color: colors.grey,
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: 300,
|
||||
letterSpacing: 3,
|
||||
@@ -299,7 +294,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
return (
|
||||
<div
|
||||
className="clearfix py4"
|
||||
style={{backgroundColor: CUSTOM_PROJECTS_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.projectsGrey}}
|
||||
>
|
||||
<div className="mx-auto max-width-4 clearfix sm-px3">
|
||||
<div
|
||||
@@ -313,13 +308,13 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
</div>
|
||||
<div
|
||||
className="pt3 mx-auto center"
|
||||
style={{color: CUSTOM_GRAY_TEXT, fontFamily: 'Roboto Mono', maxWidth: 300, fontSize: 14}}
|
||||
style={{color: colors.landingLinkGrey, fontFamily: 'Roboto Mono', maxWidth: 300, fontSize: 14}}
|
||||
>
|
||||
view the{' '}
|
||||
<Link
|
||||
to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
|
||||
className="text-decoration-none underline"
|
||||
style={{color: CUSTOM_GRAY_TEXT}}
|
||||
style={{color: colors.landingLinkGrey}}
|
||||
>
|
||||
full list
|
||||
</Link>
|
||||
@@ -329,11 +324,11 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderTokenizationSection() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
return (
|
||||
<div
|
||||
className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2"
|
||||
style={{backgroundColor: CUSTOM_WHITE_BACKGROUND}}
|
||||
style={{backgroundColor: colors.grey100}}
|
||||
>
|
||||
<div className="mx-auto max-width-4 py4 clearfix">
|
||||
{isSmallScreen &&
|
||||
@@ -382,11 +377,11 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderProtocolSection() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
return (
|
||||
<div
|
||||
className="clearfix lg-py4 md-py4 sm-pt4"
|
||||
style={{backgroundColor: CUSTOM_HERO_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.heroGrey}}
|
||||
>
|
||||
<div className="mx-auto max-width-4 lg-py4 md-py4 sm-pt4 clearfix">
|
||||
<div className="col lg-col-6 md-col-6 col-12 sm-center">
|
||||
@@ -397,7 +392,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
</div>
|
||||
<div
|
||||
className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto"
|
||||
style={{color: CUSTOM_WHITE_TEXT, paddingTop: 8, maxWidth: isSmallScreen ? 'none' : 445}}
|
||||
style={{color: colors.beigeWhite, paddingTop: 8, maxWidth: isSmallScreen ? 'none' : 445}}
|
||||
>
|
||||
<div
|
||||
className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center"
|
||||
@@ -420,7 +415,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
</div>
|
||||
<div
|
||||
className="pt3 sm-mx-auto sm-px3"
|
||||
style={{color: CUSTOM_GRAY_TEXT, maxWidth: isSmallScreen ? 412 : 'none'}}
|
||||
style={{color: colors.landingLinkGrey, maxWidth: isSmallScreen ? 412 : 'none'}}
|
||||
>
|
||||
<div className="flex" style={{fontSize: 18}}>
|
||||
<div
|
||||
@@ -433,7 +428,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
<Link
|
||||
to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
|
||||
className="text-decoration-none underline"
|
||||
style={{color: CUSTOM_GRAY_TEXT, fontFamily: 'Roboto Mono'}}
|
||||
style={{color: colors.landingLinkGrey, fontFamily: 'Roboto Mono'}}
|
||||
>
|
||||
view all
|
||||
</Link>
|
||||
@@ -468,7 +463,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderBuildingBlocksSection() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
const descriptionStyle: React.CSSProperties = {
|
||||
fontFamily: 'Roboto Mono',
|
||||
lineHeight: isSmallScreen ? 1.5 : 2,
|
||||
@@ -485,7 +480,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
return (
|
||||
<div
|
||||
className="clearfix lg-pt4 md-pt4"
|
||||
style={{backgroundColor: CUSTOM_HERO_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.heroGrey}}
|
||||
>
|
||||
<div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix">
|
||||
{isSmallScreen &&
|
||||
@@ -493,7 +488,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
}
|
||||
<div
|
||||
className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3"
|
||||
style={{color: CUSTOM_WHITE_TEXT}}
|
||||
style={{color: colors.beigeWhite}}
|
||||
>
|
||||
<div
|
||||
className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
|
||||
@@ -517,7 +512,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
<Link
|
||||
to={WebsitePaths.ZeroExJs}
|
||||
className="text-decoration-none underline"
|
||||
style={{color: CUSTOM_WHITE_TEXT, fontFamily: 'Roboto Mono'}}
|
||||
style={{color: colors.beigeWhite, fontFamily: 'Roboto Mono'}}
|
||||
>
|
||||
0x.js
|
||||
</Link>
|
||||
@@ -525,7 +520,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
<Link
|
||||
to={WebsitePaths.SmartContracts}
|
||||
className="text-decoration-none underline"
|
||||
style={{color: CUSTOM_WHITE_TEXT, fontFamily: 'Roboto Mono'}}
|
||||
style={{color: colors.beigeWhite, fontFamily: 'Roboto Mono'}}
|
||||
>
|
||||
smart contract
|
||||
</Link>
|
||||
@@ -540,7 +535,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderBlockChipImage() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
return (
|
||||
<div className="col lg-col-6 md-col-6 col-12 sm-center">
|
||||
<img
|
||||
@@ -551,7 +546,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderTokenCloud() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
return (
|
||||
<div className="col lg-col-6 md-col-6 col-12 center">
|
||||
<img
|
||||
@@ -562,7 +557,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderAssetTypes() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
const assetTypes: AssetType[] = [
|
||||
{
|
||||
title: 'Currency',
|
||||
@@ -601,11 +596,11 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
return assets;
|
||||
}
|
||||
private renderInfoBoxes() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
const boxStyle: React.CSSProperties = {
|
||||
maxWidth: 252,
|
||||
height: 386,
|
||||
backgroundColor: '#F9F9F9',
|
||||
backgroundColor: colors.grey50,
|
||||
borderRadius: 5,
|
||||
padding: '10px 24px 24px',
|
||||
};
|
||||
@@ -642,7 +637,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
return (
|
||||
<div
|
||||
className="clearfix"
|
||||
style={{backgroundColor: CUSTOM_HERO_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.heroGrey}}
|
||||
>
|
||||
<div
|
||||
className="mx-auto py4 sm-mt2 clearfix"
|
||||
@@ -654,7 +649,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderUseCases() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
|
||||
const useCases: UseCase[] = [
|
||||
{
|
||||
@@ -709,14 +704,14 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
const cases = _.map(useCases, (useCase: UseCase) => {
|
||||
const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
|
||||
const useCaseBoxStyle = {
|
||||
color: '#A2A2A2',
|
||||
color: colors.grey,
|
||||
border: '1px solid #565656',
|
||||
borderRadius: 4,
|
||||
maxWidth: isSmallScreen ? 375 : 'none',
|
||||
...style,
|
||||
};
|
||||
const typeStyle: React.CSSProperties = {
|
||||
color: '#EBEBEB',
|
||||
color: colors.lightGrey,
|
||||
fontSize: 13,
|
||||
textTransform: 'uppercase',
|
||||
fontFamily: 'Roboto Mono',
|
||||
@@ -753,7 +748,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
return (
|
||||
<div
|
||||
className="clearfix pb4 lg-pt2 md-pt2 sm-pt4"
|
||||
style={{backgroundColor: CUSTOM_HERO_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.heroGrey}}
|
||||
>
|
||||
<div
|
||||
className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix"
|
||||
@@ -765,7 +760,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
);
|
||||
}
|
||||
private renderCallToAction() {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.SM;
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
const buttonLabelStyle: React.CSSProperties = {
|
||||
textTransform: 'none',
|
||||
fontSize: 15,
|
||||
@@ -782,14 +777,14 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
return (
|
||||
<div
|
||||
className="clearfix pb4"
|
||||
style={{backgroundColor: CUSTOM_HERO_BACKGROUND_COLOR}}
|
||||
style={{backgroundColor: colors.heroGrey}}
|
||||
>
|
||||
<div
|
||||
className="mx-auto max-width-4 pb4 mb3 clearfix"
|
||||
>
|
||||
<div
|
||||
className={callToActionClassNames}
|
||||
style={{fontFamily: 'Roboto Mono', color: 'white', lineHeight: isSmallScreen ? 1.7 : 3}}
|
||||
style={{fontFamily: 'Roboto Mono', color: colors.white, lineHeight: isSmallScreen ? 1.7 : 3}}
|
||||
>
|
||||
Get started on building the decentralized future
|
||||
</div>
|
||||
@@ -799,7 +794,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
style={{borderRadius: 6, minWidth: 150}}
|
||||
buttonStyle={lightButtonStyle}
|
||||
labelColor={colors.white}
|
||||
backgroundColor={CUSTOM_HERO_BACKGROUND_COLOR}
|
||||
backgroundColor={colors.heroGrey}
|
||||
labelStyle={buttonLabelStyle}
|
||||
label="Build on 0x"
|
||||
onClick={_.noop}
|
||||
|
@@ -38,7 +38,7 @@ export class NotFound extends React.Component<NotFoundProps, NotFoundState> {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer location={this.props.location} />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import * as _ from 'lodash';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import {Link as ScrollLink} from 'react-scroll';
|
||||
import {VersionDropDown} from 'ts/pages/shared/version_drop_down';
|
||||
import {MenuSubsectionsBySection, Styles} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
|
||||
@@ -55,7 +55,7 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N
|
||||
containerId={constants.DOCS_CONTAINER_ID}
|
||||
>
|
||||
<div
|
||||
style={{color: colors.grey500, cursor: 'pointer'}}
|
||||
style={{color: colors.grey, cursor: 'pointer'}}
|
||||
className="pb1"
|
||||
>
|
||||
{finalSectionName.toUpperCase()}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import * as _ from 'lodash';
|
||||
import CircularProgress from 'material-ui/CircularProgress';
|
||||
import {colors} from 'material-ui/styles';
|
||||
import * as React from 'react';
|
||||
import DocumentTitle = require('react-document-title');
|
||||
import {
|
||||
@@ -11,6 +10,7 @@ import {MarkdownSection} from 'ts/pages/shared/markdown_section';
|
||||
import {NestedSidebarMenu} from 'ts/pages/shared/nested_sidebar_menu';
|
||||
import {SectionHeader} from 'ts/pages/shared/section_header';
|
||||
import {Article, ArticlesBySection, HeaderSizes, Styles, WebsitePaths} from 'ts/types';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
@@ -112,7 +112,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> {
|
||||
>
|
||||
<div id="0xProtocolWiki" />
|
||||
<h1 className="md-pl2 sm-pl3">
|
||||
<a href={constants.GITHUB_WIKI_URL} target="_blank">
|
||||
<a href={constants.URL_GITHUB_WIKI} target="_blank">
|
||||
0x Protocol Wiki
|
||||
</a>
|
||||
</h1>
|
||||
@@ -134,7 +134,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> {
|
||||
private renderSection(sectionName: string) {
|
||||
const articles = this.state.articlesBySection[sectionName];
|
||||
const renderedArticles = _.map(articles, (article: Article) => {
|
||||
const githubLink = `${constants.GITHUB_WIKI_URL}/edit/master/${sectionName}/${article.fileName}`;
|
||||
const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
|
||||
return (
|
||||
<div key={`markdown-section-${article.title}`}>
|
||||
<MarkdownSection
|
||||
@@ -143,7 +143,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> {
|
||||
headerSize={HeaderSizes.H2}
|
||||
githubLink={githubLink}
|
||||
/>
|
||||
<div className="mb4 mt3 p3 center" style={{backgroundColor: '#f9f5ef'}}>
|
||||
<div className="mb4 mt3 p3 center" style={{backgroundColor: colors.lightestGrey}}>
|
||||
See a way to make this article better?{' '}
|
||||
<a
|
||||
href={githubLink}
|
||||
|
@@ -5,7 +5,6 @@ import {
|
||||
ActionTypes,
|
||||
AssetToken,
|
||||
BlockchainErrs,
|
||||
Direction,
|
||||
Order,
|
||||
ProviderType,
|
||||
ScreenWidths,
|
||||
@@ -23,48 +22,42 @@ export class Dispatcher {
|
||||
// Portal
|
||||
public resetState() {
|
||||
this.dispatch({
|
||||
type: ActionTypes.RESET_STATE,
|
||||
type: ActionTypes.ResetState,
|
||||
});
|
||||
}
|
||||
public updateNodeVersion(nodeVersion: string) {
|
||||
this.dispatch({
|
||||
data: nodeVersion,
|
||||
type: ActionTypes.UPDATE_NODE_VERSION,
|
||||
type: ActionTypes.UpdateNodeVersion,
|
||||
});
|
||||
}
|
||||
public updateScreenWidth(screenWidth: ScreenWidths) {
|
||||
this.dispatch({
|
||||
data: screenWidth,
|
||||
type: ActionTypes.UPDATE_SCREEN_WIDTH,
|
||||
type: ActionTypes.UpdateScreenWidth,
|
||||
});
|
||||
}
|
||||
public swapAssetTokenSymbols() {
|
||||
this.dispatch({
|
||||
type: ActionTypes.SWAP_ASSET_TOKENS,
|
||||
});
|
||||
}
|
||||
public updateGenerateOrderStep(direction: Direction) {
|
||||
this.dispatch({
|
||||
data: direction,
|
||||
type: ActionTypes.UPDATE_GENERATE_ORDER_STEP,
|
||||
type: ActionTypes.SwapAssetTokens,
|
||||
});
|
||||
}
|
||||
public updateOrderSalt(salt: BigNumber) {
|
||||
this.dispatch({
|
||||
data: salt,
|
||||
type: ActionTypes.UPDATE_ORDER_SALT,
|
||||
type: ActionTypes.UpdateOrderSalt,
|
||||
});
|
||||
}
|
||||
public updateUserSuppliedOrderCache(order: Order) {
|
||||
this.dispatch({
|
||||
data: order,
|
||||
type: ActionTypes.UPDATE_USER_SUPPLIED_ORDER_CACHE,
|
||||
type: ActionTypes.UpdateUserSuppliedOrderCache,
|
||||
});
|
||||
}
|
||||
public updateShouldBlockchainErrDialogBeOpen(shouldBeOpen: boolean) {
|
||||
this.dispatch({
|
||||
data: shouldBeOpen,
|
||||
type: ActionTypes.UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN,
|
||||
type: ActionTypes.UpdateShouldBlockchainErrDialogBeOpen,
|
||||
});
|
||||
}
|
||||
public updateChosenAssetToken(side: Side, token: AssetToken) {
|
||||
@@ -73,7 +66,7 @@ export class Dispatcher {
|
||||
side,
|
||||
token,
|
||||
},
|
||||
type: ActionTypes.UPDATE_CHOSEN_ASSET_TOKEN,
|
||||
type: ActionTypes.UpdateChosenAssetToken,
|
||||
});
|
||||
}
|
||||
public updateChosenAssetTokenAddress(side: Side, address: string) {
|
||||
@@ -82,72 +75,72 @@ export class Dispatcher {
|
||||
address,
|
||||
side,
|
||||
},
|
||||
type: ActionTypes.UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS,
|
||||
type: ActionTypes.UpdateChosenAssetTokenAddress,
|
||||
});
|
||||
}
|
||||
public updateOrderTakerAddress(address: string) {
|
||||
this.dispatch({
|
||||
data: address,
|
||||
type: ActionTypes.UPDATE_ORDER_TAKER_ADDRESS,
|
||||
type: ActionTypes.UpdateOrderTakerAddress,
|
||||
});
|
||||
}
|
||||
public updateUserAddress(address: string) {
|
||||
this.dispatch({
|
||||
data: address,
|
||||
type: ActionTypes.UPDATE_USER_ADDRESS,
|
||||
type: ActionTypes.UpdateUserAddress,
|
||||
});
|
||||
}
|
||||
public updateOrderExpiry(unixTimestampSec: BigNumber) {
|
||||
this.dispatch({
|
||||
data: unixTimestampSec,
|
||||
type: ActionTypes.UPDATE_ORDER_EXPIRY,
|
||||
type: ActionTypes.UpdateOrderExpiry,
|
||||
});
|
||||
}
|
||||
public encounteredBlockchainError(err: BlockchainErrs) {
|
||||
this.dispatch({
|
||||
data: err,
|
||||
type: ActionTypes.BLOCKCHAIN_ERR_ENCOUNTERED,
|
||||
type: ActionTypes.BlockchainErrEncountered,
|
||||
});
|
||||
}
|
||||
public updateBlockchainIsLoaded(isLoaded: boolean) {
|
||||
this.dispatch({
|
||||
data: isLoaded,
|
||||
type: ActionTypes.UPDATE_BLOCKCHAIN_IS_LOADED,
|
||||
type: ActionTypes.UpdateBlockchainIsLoaded,
|
||||
});
|
||||
}
|
||||
public addTokenToTokenByAddress(token: Token) {
|
||||
this.dispatch({
|
||||
data: token,
|
||||
type: ActionTypes.ADD_TOKEN_TO_TOKEN_BY_ADDRESS,
|
||||
type: ActionTypes.AddTokenToTokenByAddress,
|
||||
});
|
||||
}
|
||||
public removeTokenToTokenByAddress(token: Token) {
|
||||
this.dispatch({
|
||||
data: token,
|
||||
type: ActionTypes.REMOVE_TOKEN_TO_TOKEN_BY_ADDRESS,
|
||||
type: ActionTypes.RemoveTokenFromTokenByAddress,
|
||||
});
|
||||
}
|
||||
public clearTokenByAddress() {
|
||||
this.dispatch({
|
||||
type: ActionTypes.CLEAR_TOKEN_BY_ADDRESS,
|
||||
type: ActionTypes.ClearTokenByAddress,
|
||||
});
|
||||
}
|
||||
public updateTokenByAddress(tokens: Token[]) {
|
||||
this.dispatch({
|
||||
data: tokens,
|
||||
type: ActionTypes.UPDATE_TOKEN_BY_ADDRESS,
|
||||
type: ActionTypes.UpdateTokenByAddress,
|
||||
});
|
||||
}
|
||||
public updateTokenStateByAddress(tokenStateByAddress: TokenStateByAddress) {
|
||||
this.dispatch({
|
||||
data: tokenStateByAddress,
|
||||
type: ActionTypes.UPDATE_TOKEN_STATE_BY_ADDRESS,
|
||||
type: ActionTypes.UpdateTokenStateByAddress,
|
||||
});
|
||||
}
|
||||
public removeFromTokenStateByAddress(tokenAddress: string) {
|
||||
this.dispatch({
|
||||
data: tokenAddress,
|
||||
type: ActionTypes.REMOVE_FROM_TOKEN_STATE_BY_ADDRESS,
|
||||
type: ActionTypes.RemoveFromTokenStateByAddress,
|
||||
});
|
||||
}
|
||||
public replaceTokenAllowanceByAddress(address: string, allowance: BigNumber) {
|
||||
@@ -156,7 +149,7 @@ export class Dispatcher {
|
||||
address,
|
||||
allowance,
|
||||
},
|
||||
type: ActionTypes.REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS,
|
||||
type: ActionTypes.ReplaceTokenAllowanceByAddress,
|
||||
});
|
||||
}
|
||||
public replaceTokenBalanceByAddress(address: string, balance: BigNumber) {
|
||||
@@ -165,7 +158,7 @@ export class Dispatcher {
|
||||
address,
|
||||
balance,
|
||||
},
|
||||
type: ActionTypes.REPLACE_TOKEN_BALANCE_BY_ADDRESS,
|
||||
type: ActionTypes.ReplaceTokenBalanceByAddress,
|
||||
});
|
||||
}
|
||||
public updateTokenBalanceByAddress(address: string, balanceDelta: BigNumber) {
|
||||
@@ -174,31 +167,31 @@ export class Dispatcher {
|
||||
address,
|
||||
balanceDelta,
|
||||
},
|
||||
type: ActionTypes.UPDATE_TOKEN_BALANCE_BY_ADDRESS,
|
||||
type: ActionTypes.UpdateTokenBalanceByAddress,
|
||||
});
|
||||
}
|
||||
public updateSignatureData(signatureData: SignatureData) {
|
||||
this.dispatch({
|
||||
data: signatureData,
|
||||
type: ActionTypes.UPDATE_ORDER_SIGNATURE_DATA,
|
||||
type: ActionTypes.UpdateOrderSignatureData,
|
||||
});
|
||||
}
|
||||
public updateUserEtherBalance(balance: BigNumber) {
|
||||
this.dispatch({
|
||||
data: balance,
|
||||
type: ActionTypes.UPDATE_USER_ETHER_BALANCE,
|
||||
type: ActionTypes.UpdateUserEtherBalance,
|
||||
});
|
||||
}
|
||||
public updateNetworkId(networkId: number) {
|
||||
this.dispatch({
|
||||
data: networkId,
|
||||
type: ActionTypes.UPDATE_NETWORK_ID,
|
||||
type: ActionTypes.UpdateNetworkId,
|
||||
});
|
||||
}
|
||||
public updateOrderFillAmount(amount: BigNumber) {
|
||||
this.dispatch({
|
||||
data: amount,
|
||||
type: ActionTypes.UPDATE_ORDER_FILL_AMOUNT,
|
||||
type: ActionTypes.UpdateOrderFillAmount,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -206,13 +199,13 @@ export class Dispatcher {
|
||||
public updateCurrentDocsVersion(version: string) {
|
||||
this.dispatch({
|
||||
data: version,
|
||||
type: ActionTypes.UPDATE_LIBRARY_VERSION,
|
||||
type: ActionTypes.UpdateLibraryVersion,
|
||||
});
|
||||
}
|
||||
public updateAvailableDocVersions(versions: string[]) {
|
||||
this.dispatch({
|
||||
data: versions,
|
||||
type: ActionTypes.UPDATE_AVAILABLE_LIBRARY_VERSIONS,
|
||||
type: ActionTypes.UpdateAvailableLibraryVersions,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -220,23 +213,23 @@ export class Dispatcher {
|
||||
public showFlashMessage(msg: string|React.ReactNode) {
|
||||
this.dispatch({
|
||||
data: msg,
|
||||
type: ActionTypes.SHOW_FLASH_MESSAGE,
|
||||
type: ActionTypes.ShowFlashMessage,
|
||||
});
|
||||
}
|
||||
public hideFlashMessage() {
|
||||
this.dispatch({
|
||||
type: ActionTypes.HIDE_FLASH_MESSAGE,
|
||||
type: ActionTypes.HideFlashMessage,
|
||||
});
|
||||
}
|
||||
public updateProviderType(providerType: ProviderType) {
|
||||
this.dispatch({
|
||||
type: ActionTypes.UPDATE_PROVIDER_TYPE,
|
||||
type: ActionTypes.UpdateProviderType,
|
||||
data: providerType,
|
||||
});
|
||||
}
|
||||
public updateInjectedProviderName(injectedProviderName: string) {
|
||||
this.dispatch({
|
||||
type: ActionTypes.UPDATE_INJECTED_PROVIDER_NAME,
|
||||
type: ActionTypes.UpdateInjectedProviderName,
|
||||
data: injectedProviderName,
|
||||
});
|
||||
}
|
||||
|
@@ -5,8 +5,6 @@ import {
|
||||
Action,
|
||||
ActionTypes,
|
||||
BlockchainErrs,
|
||||
Direction,
|
||||
GenerateOrderSteps,
|
||||
Order,
|
||||
ProviderType,
|
||||
ScreenWidths,
|
||||
@@ -28,7 +26,6 @@ export interface State {
|
||||
// Portal
|
||||
blockchainErr: BlockchainErrs;
|
||||
blockchainIsLoaded: boolean;
|
||||
generateOrderStep: GenerateOrderSteps;
|
||||
networkId: number;
|
||||
orderExpiryTimestamp: BigNumber;
|
||||
orderFillAmount: BigNumber;
|
||||
@@ -58,9 +55,8 @@ export interface State {
|
||||
|
||||
const INITIAL_STATE: State = {
|
||||
// Portal
|
||||
blockchainErr: '',
|
||||
blockchainErr: BlockchainErrs.NoError,
|
||||
blockchainIsLoaded: false,
|
||||
generateOrderStep: GenerateOrderSteps.ChooseAssets,
|
||||
networkId: undefined,
|
||||
orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
|
||||
orderFillAmount: undefined,
|
||||
@@ -76,8 +72,8 @@ const INITIAL_STATE: State = {
|
||||
screenWidth: utils.getScreenWidth(),
|
||||
shouldBlockchainErrDialogBeOpen: false,
|
||||
sideToAssetToken: {
|
||||
[Side.deposit]: {},
|
||||
[Side.receive]: {},
|
||||
[Side.Deposit]: {},
|
||||
[Side.Receive]: {},
|
||||
},
|
||||
tokenByAddress: {},
|
||||
tokenStateByAddress: {},
|
||||
@@ -91,270 +87,300 @@ const INITIAL_STATE: State = {
|
||||
|
||||
// Shared
|
||||
flashMessage: undefined,
|
||||
providerType: ProviderType.INJECTED,
|
||||
providerType: ProviderType.Injected,
|
||||
injectedProviderName: '',
|
||||
};
|
||||
|
||||
export function reducer(state: State = INITIAL_STATE, action: Action) {
|
||||
switch (action.type) {
|
||||
// Portal
|
||||
case ActionTypes.RESET_STATE:
|
||||
case ActionTypes.ResetState:
|
||||
return INITIAL_STATE;
|
||||
|
||||
case ActionTypes.UPDATE_ORDER_SALT: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateOrderSalt: {
|
||||
return {
|
||||
...state,
|
||||
orderSalt: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_NODE_VERSION: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateNodeVersion: {
|
||||
return {
|
||||
...state,
|
||||
nodeVersion: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_ORDER_FILL_AMOUNT: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateOrderFillAmount: {
|
||||
return {
|
||||
...state,
|
||||
orderFillAmount: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateShouldBlockchainErrDialogBeOpen: {
|
||||
return {
|
||||
...state,
|
||||
shouldBlockchainErrDialogBeOpen: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_USER_ETHER_BALANCE: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateUserEtherBalance: {
|
||||
return {
|
||||
...state,
|
||||
userEtherBalance: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_USER_SUPPLIED_ORDER_CACHE: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateUserSuppliedOrderCache: {
|
||||
return {
|
||||
...state,
|
||||
userSuppliedOrderCache: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.CLEAR_TOKEN_BY_ADDRESS: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.ClearTokenByAddress: {
|
||||
return {
|
||||
...state,
|
||||
tokenByAddress: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.ADD_TOKEN_TO_TOKEN_BY_ADDRESS: {
|
||||
case ActionTypes.AddTokenToTokenByAddress: {
|
||||
const newTokenByAddress = state.tokenByAddress;
|
||||
newTokenByAddress[action.data.address] = action.data;
|
||||
return _.assign({}, state, {
|
||||
return {
|
||||
...state,
|
||||
tokenByAddress: newTokenByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.REMOVE_TOKEN_TO_TOKEN_BY_ADDRESS: {
|
||||
case ActionTypes.RemoveTokenFromTokenByAddress: {
|
||||
const newTokenByAddress = state.tokenByAddress;
|
||||
delete newTokenByAddress[action.data.address];
|
||||
return _.assign({}, state, {
|
||||
return {
|
||||
...state,
|
||||
tokenByAddress: newTokenByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_TOKEN_BY_ADDRESS: {
|
||||
case ActionTypes.UpdateTokenByAddress: {
|
||||
const tokenByAddress = state.tokenByAddress;
|
||||
const tokens = action.data;
|
||||
_.each(tokens, token => {
|
||||
const updatedToken = _.assign({}, tokenByAddress[token.address], token);
|
||||
const updatedToken = {
|
||||
...tokenByAddress[token.address],
|
||||
...token,
|
||||
};
|
||||
tokenByAddress[token.address] = updatedToken;
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
return {
|
||||
...state,
|
||||
tokenByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_TOKEN_STATE_BY_ADDRESS: {
|
||||
case ActionTypes.UpdateTokenStateByAddress: {
|
||||
const tokenStateByAddress = state.tokenStateByAddress;
|
||||
const updatedTokenStateByAddress = action.data;
|
||||
_.each(updatedTokenStateByAddress, (tokenState: TokenState, address: string) => {
|
||||
const updatedTokenState = _.assign({}, tokenStateByAddress[address], tokenState);
|
||||
const updatedTokenState = {
|
||||
...tokenStateByAddress[address],
|
||||
...tokenState,
|
||||
};
|
||||
tokenStateByAddress[address] = updatedTokenState;
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
return {
|
||||
...state,
|
||||
tokenStateByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.REMOVE_FROM_TOKEN_STATE_BY_ADDRESS: {
|
||||
case ActionTypes.RemoveFromTokenStateByAddress: {
|
||||
const tokenStateByAddress = state.tokenStateByAddress;
|
||||
const tokenAddress = action.data;
|
||||
delete tokenStateByAddress[tokenAddress];
|
||||
return _.assign({}, state, {
|
||||
return {
|
||||
...state,
|
||||
tokenStateByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS: {
|
||||
case ActionTypes.ReplaceTokenAllowanceByAddress: {
|
||||
const tokenStateByAddress = state.tokenStateByAddress;
|
||||
const allowance = action.data.allowance;
|
||||
const tokenAddress = action.data.address;
|
||||
tokenStateByAddress[tokenAddress] = _.assign({}, tokenStateByAddress[tokenAddress], {
|
||||
tokenStateByAddress[tokenAddress] = {
|
||||
...tokenStateByAddress[tokenAddress],
|
||||
allowance,
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
tokenStateByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.REPLACE_TOKEN_BALANCE_BY_ADDRESS: {
|
||||
case ActionTypes.ReplaceTokenBalanceByAddress: {
|
||||
const tokenStateByAddress = state.tokenStateByAddress;
|
||||
const balance = action.data.balance;
|
||||
const tokenAddress = action.data.address;
|
||||
tokenStateByAddress[tokenAddress] = _.assign({}, tokenStateByAddress[tokenAddress], {
|
||||
tokenStateByAddress[tokenAddress] = {
|
||||
...tokenStateByAddress[tokenAddress],
|
||||
balance,
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
tokenStateByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_TOKEN_BALANCE_BY_ADDRESS: {
|
||||
case ActionTypes.UpdateTokenBalanceByAddress: {
|
||||
const tokenStateByAddress = state.tokenStateByAddress;
|
||||
const balanceDelta = action.data.balanceDelta;
|
||||
const tokenAddress = action.data.address;
|
||||
const currBalance = tokenStateByAddress[tokenAddress].balance;
|
||||
tokenStateByAddress[tokenAddress] = _.assign({}, tokenStateByAddress[tokenAddress], {
|
||||
tokenStateByAddress[tokenAddress] = {
|
||||
...tokenStateByAddress[tokenAddress],
|
||||
balance: currBalance.plus(balanceDelta),
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
tokenStateByAddress,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_ORDER_SIGNATURE_DATA: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateOrderSignatureData: {
|
||||
return {
|
||||
...state,
|
||||
orderSignatureData: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_SCREEN_WIDTH: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateScreenWidth: {
|
||||
return {
|
||||
...state,
|
||||
screenWidth: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_BLOCKCHAIN_IS_LOADED: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateBlockchainIsLoaded: {
|
||||
return {
|
||||
...state,
|
||||
blockchainIsLoaded: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.BLOCKCHAIN_ERR_ENCOUNTERED: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.BlockchainErrEncountered: {
|
||||
return {
|
||||
...state,
|
||||
blockchainErr: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_NETWORK_ID: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateNetworkId: {
|
||||
return {
|
||||
...state,
|
||||
networkId: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_GENERATE_ORDER_STEP: {
|
||||
const direction = action.data;
|
||||
let nextGenerateOrderStep = state.generateOrderStep;
|
||||
if (direction === Direction.forward) {
|
||||
nextGenerateOrderStep += 1;
|
||||
} else if (state.generateOrderStep !== 0) {
|
||||
nextGenerateOrderStep -= 1;
|
||||
}
|
||||
return _.assign({}, state, {
|
||||
generateOrderStep: nextGenerateOrderStep,
|
||||
});
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_CHOSEN_ASSET_TOKEN: {
|
||||
const newSideToAssetToken = _.assign({}, state.sideToAssetToken, {
|
||||
case ActionTypes.UpdateChosenAssetToken: {
|
||||
const newSideToAssetToken = {
|
||||
...state.sideToAssetToken,
|
||||
[action.data.side]: action.data.token,
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
sideToAssetToken: newSideToAssetToken,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS: {
|
||||
case ActionTypes.UpdateChosenAssetTokenAddress: {
|
||||
const newAssetToken = state.sideToAssetToken[action.data.side];
|
||||
newAssetToken.address = action.data.address;
|
||||
const newSideToAssetToken = _.assign({}, state.sideToAssetToken, {
|
||||
const newSideToAssetToken = {
|
||||
...state.sideToAssetToken,
|
||||
[action.data.side]: newAssetToken,
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
sideToAssetToken: newSideToAssetToken,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.SWAP_ASSET_TOKENS: {
|
||||
const newSideToAssetToken = _.assign({}, state.sideToAssetToken, {
|
||||
[Side.deposit]: state.sideToAssetToken[Side.receive],
|
||||
[Side.receive]: state.sideToAssetToken[Side.deposit],
|
||||
});
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.SwapAssetTokens: {
|
||||
const newSideToAssetToken = {
|
||||
[Side.Deposit]: state.sideToAssetToken[Side.Receive],
|
||||
[Side.Receive]: state.sideToAssetToken[Side.Deposit],
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
sideToAssetToken: newSideToAssetToken,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_ORDER_EXPIRY: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateOrderExpiry: {
|
||||
return {
|
||||
...state,
|
||||
orderExpiryTimestamp: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_ORDER_TAKER_ADDRESS: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateOrderTakerAddress: {
|
||||
return {
|
||||
...state,
|
||||
orderTakerAddress: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_USER_ADDRESS: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateUserAddress: {
|
||||
return {
|
||||
...state,
|
||||
userAddress: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Docs
|
||||
case ActionTypes.UPDATE_LIBRARY_VERSION: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateLibraryVersion: {
|
||||
return {
|
||||
...state,
|
||||
docsVersion: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
case ActionTypes.UPDATE_AVAILABLE_LIBRARY_VERSIONS: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateAvailableLibraryVersions: {
|
||||
return {
|
||||
...state,
|
||||
availableDocVersions: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Shared
|
||||
case ActionTypes.SHOW_FLASH_MESSAGE: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.ShowFlashMessage: {
|
||||
return {
|
||||
...state,
|
||||
flashMessage: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.HIDE_FLASH_MESSAGE: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.HideFlashMessage: {
|
||||
return {
|
||||
...state,
|
||||
flashMessage: undefined,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_PROVIDER_TYPE: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateProviderType: {
|
||||
return {
|
||||
...state,
|
||||
providerType: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.UPDATE_INJECTED_PROVIDER_NAME: {
|
||||
return _.assign({}, state, {
|
||||
case ActionTypes.UpdateInjectedProviderName: {
|
||||
return {
|
||||
...state,
|
||||
injectedProviderName: action.data,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
|
@@ -1,42 +1,11 @@
|
||||
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
|
||||
function strEnum(values: string[]): {[key: string]: string} {
|
||||
return _.reduce(values, (result, key) => {
|
||||
result[key] = key;
|
||||
return result;
|
||||
}, Object.create(null));
|
||||
export enum Side {
|
||||
Receive = 'RECEIVE',
|
||||
Deposit = 'DEPOSIT',
|
||||
}
|
||||
|
||||
export enum GenerateOrderSteps {
|
||||
ChooseAssets,
|
||||
GrantAllowance,
|
||||
RemainingConfigs,
|
||||
SignTransaction,
|
||||
CopyAndShare,
|
||||
}
|
||||
|
||||
export const Side = strEnum([
|
||||
'receive',
|
||||
'deposit',
|
||||
]);
|
||||
export type Side = keyof typeof Side;
|
||||
|
||||
export const BlockchainErrs = strEnum([
|
||||
'A_CONTRACT_NOT_DEPLOYED_ON_NETWORK',
|
||||
'DISCONNECTED_FROM_ETHEREUM_NODE',
|
||||
'UNHANDLED_ERROR',
|
||||
]);
|
||||
export type BlockchainErrs = keyof typeof BlockchainErrs;
|
||||
|
||||
export const Direction = strEnum([
|
||||
'forward',
|
||||
'backward',
|
||||
]);
|
||||
export type Direction = keyof typeof Direction;
|
||||
|
||||
export interface Token {
|
||||
iconUrl?: string;
|
||||
name: string;
|
||||
@@ -139,48 +108,46 @@ export enum BalanceErrs {
|
||||
allowanceSettingFailed,
|
||||
}
|
||||
|
||||
export const ActionTypes = strEnum([
|
||||
export enum ActionTypes {
|
||||
// Portal
|
||||
'UPDATE_SCREEN_WIDTH',
|
||||
'UPDATE_NODE_VERSION',
|
||||
'RESET_STATE',
|
||||
'ADD_TOKEN_TO_TOKEN_BY_ADDRESS',
|
||||
'BLOCKCHAIN_ERR_ENCOUNTERED',
|
||||
'CLEAR_TOKEN_BY_ADDRESS',
|
||||
'UPDATE_BLOCKCHAIN_IS_LOADED',
|
||||
'UPDATE_NETWORK_ID',
|
||||
'UPDATE_GENERATE_ORDER_STEP',
|
||||
'UPDATE_CHOSEN_ASSET_TOKEN',
|
||||
'UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS',
|
||||
'UPDATE_ORDER_TAKER_ADDRESS',
|
||||
'UPDATE_ORDER_SALT',
|
||||
'UPDATE_ORDER_SIGNATURE_DATA',
|
||||
'UPDATE_TOKEN_BY_ADDRESS',
|
||||
'REMOVE_TOKEN_TO_TOKEN_BY_ADDRESS',
|
||||
'UPDATE_TOKEN_STATE_BY_ADDRESS',
|
||||
'REMOVE_FROM_TOKEN_STATE_BY_ADDRESS',
|
||||
'REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS',
|
||||
'REPLACE_TOKEN_BALANCE_BY_ADDRESS',
|
||||
'UPDATE_TOKEN_BALANCE_BY_ADDRESS',
|
||||
'UPDATE_ORDER_EXPIRY',
|
||||
'SWAP_ASSET_TOKENS',
|
||||
'UPDATE_USER_ADDRESS',
|
||||
'UPDATE_USER_ETHER_BALANCE',
|
||||
'UPDATE_USER_SUPPLIED_ORDER_CACHE',
|
||||
'UPDATE_ORDER_FILL_AMOUNT',
|
||||
'UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN',
|
||||
UpdateScreenWidth = 'UPDATE_SCREEN_WIDTH',
|
||||
UpdateNodeVersion = 'UPDATE_NODE_VERSION',
|
||||
ResetState = 'RESET_STATE',
|
||||
AddTokenToTokenByAddress = 'ADD_TOKEN_TO_TOKEN_BY_ADDRESS',
|
||||
BlockchainErrEncountered = 'BLOCKCHAIN_ERR_ENCOUNTERED',
|
||||
ClearTokenByAddress = 'CLEAR_TOKEN_BY_ADDRESS',
|
||||
UpdateBlockchainIsLoaded = 'UPDATE_BLOCKCHAIN_IS_LOADED',
|
||||
UpdateNetworkId = 'UPDATE_NETWORK_ID',
|
||||
UpdateChosenAssetToken = 'UPDATE_CHOSEN_ASSET_TOKEN',
|
||||
UpdateChosenAssetTokenAddress = 'UPDATE_CHOSEN_ASSET_TOKEN_ADDRESS',
|
||||
UpdateOrderTakerAddress = 'UPDATE_ORDER_TAKER_ADDRESS',
|
||||
UpdateOrderSalt = 'UPDATE_ORDER_SALT',
|
||||
UpdateOrderSignatureData = 'UPDATE_ORDER_SIGNATURE_DATA',
|
||||
UpdateTokenByAddress = 'UPDATE_TOKEN_BY_ADDRESS',
|
||||
RemoveTokenFromTokenByAddress = 'REMOVE_TOKEN_FROM_TOKEN_BY_ADDRESS',
|
||||
UpdateTokenStateByAddress = 'UPDATE_TOKEN_STATE_BY_ADDRESS',
|
||||
RemoveFromTokenStateByAddress = 'REMOVE_FROM_TOKEN_STATE_BY_ADDRESS',
|
||||
ReplaceTokenAllowanceByAddress = 'REPLACE_TOKEN_ALLOWANCE_BY_ADDRESS',
|
||||
ReplaceTokenBalanceByAddress = 'REPLACE_TOKEN_BALANCE_BY_ADDRESS',
|
||||
UpdateTokenBalanceByAddress = 'UPDATE_TOKEN_BALANCE_BY_ADDRESS',
|
||||
UpdateOrderExpiry = 'UPDATE_ORDER_EXPIRY',
|
||||
SwapAssetTokens = 'SWAP_ASSET_TOKENS',
|
||||
UpdateUserAddress = 'UPDATE_USER_ADDRESS',
|
||||
UpdateUserEtherBalance = 'UPDATE_USER_ETHER_BALANCE',
|
||||
UpdateUserSuppliedOrderCache = 'UPDATE_USER_SUPPLIED_ORDER_CACHE',
|
||||
UpdateOrderFillAmount = 'UPDATE_ORDER_FILL_AMOUNT',
|
||||
UpdateShouldBlockchainErrDialogBeOpen = 'UPDATE_SHOULD_BLOCKCHAIN_ERR_DIALOG_BE_OPEN',
|
||||
|
||||
// Docs
|
||||
'UPDATE_LIBRARY_VERSION',
|
||||
'UPDATE_AVAILABLE_LIBRARY_VERSIONS',
|
||||
UpdateLibraryVersion = 'UPDATE_LIBRARY_VERSION',
|
||||
UpdateAvailableLibraryVersions = 'UPDATE_AVAILABLE_LIBRARY_VERSIONS',
|
||||
|
||||
// Shared
|
||||
'SHOW_FLASH_MESSAGE',
|
||||
'HIDE_FLASH_MESSAGE',
|
||||
'UPDATE_PROVIDER_TYPE',
|
||||
'UPDATE_INJECTED_PROVIDER_NAME',
|
||||
]);
|
||||
export type ActionTypes = keyof typeof ActionTypes;
|
||||
ShowFlashMessage = 'SHOW_FLASH_MESSAGE',
|
||||
HideFlashMessage = 'HIDE_FLASH_MESSAGE',
|
||||
UpdateProviderType = 'UPDATE_PROVIDER_TYPE',
|
||||
UpdateInjectedProviderName = 'UPDATE_INJECTED_PROVIDER_NAME',
|
||||
}
|
||||
|
||||
export interface Action {
|
||||
type: ActionTypes;
|
||||
@@ -253,44 +220,47 @@ export interface ContractEvent {
|
||||
|
||||
export type InputErrMsg = React.ReactNode | string | undefined;
|
||||
export type ValidatedBigNumberCallback = (isValid: boolean, amount?: BigNumber) => void;
|
||||
export const ScreenWidths = strEnum([
|
||||
'SM',
|
||||
'MD',
|
||||
'LG',
|
||||
]);
|
||||
export type ScreenWidths = keyof typeof ScreenWidths;
|
||||
export enum ScreenWidths {
|
||||
Sm = 'SM',
|
||||
Md = 'MD',
|
||||
Lg = 'LG',
|
||||
}
|
||||
|
||||
export enum AlertTypes {
|
||||
ERROR,
|
||||
SUCCESS,
|
||||
}
|
||||
|
||||
export const EtherscanLinkSuffixes = strEnum([
|
||||
'address',
|
||||
'tx',
|
||||
]);
|
||||
export type EtherscanLinkSuffixes = keyof typeof EtherscanLinkSuffixes;
|
||||
export enum EtherscanLinkSuffixes {
|
||||
Address = 'address',
|
||||
Tx = 'tx',
|
||||
}
|
||||
|
||||
export const BlockchainCallErrs = strEnum([
|
||||
'CONTRACT_DOES_NOT_EXIST',
|
||||
'USER_HAS_NO_ASSOCIATED_ADDRESSES',
|
||||
'UNHANDLED_ERROR',
|
||||
'TOKEN_ADDRESS_IS_INVALID',
|
||||
'INVALID_SIGNATURE',
|
||||
]);
|
||||
export type BlockchainCallErrs = keyof typeof BlockchainCallErrs;
|
||||
export enum BlockchainErrs {
|
||||
AContractNotDeployedOnNetwork = 'A_CONTRACT_NOT_DEPLOYED_ON_NETWORK',
|
||||
DisconnectedFromEthereumNode = 'DISCONNECTED_FROM_ETHEREUM_NODE',
|
||||
NoError = 'NO_ERROR',
|
||||
}
|
||||
|
||||
export const KindString = strEnum([
|
||||
'Constructor',
|
||||
'Property',
|
||||
'Method',
|
||||
'Interface',
|
||||
'Type alias',
|
||||
'Variable',
|
||||
'Function',
|
||||
'Enumeration',
|
||||
]);
|
||||
export type KindString = keyof typeof KindString;
|
||||
export enum BlockchainCallErrs {
|
||||
ContractDoesNotExist = 'CONTRACT_DOES_NOT_EXIST',
|
||||
UserHasNoAssociatedAddresses = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
|
||||
UnhandledError = 'UNHANDLED_ERROR',
|
||||
TokenAddressIsInvalid = 'TOKEN_ADDRESS_IS_INVALID',
|
||||
}
|
||||
|
||||
// Exception: We don't make the values uppercase because these KindString's need to
|
||||
// match up those returned by TypeDoc
|
||||
export enum KindString {
|
||||
Constructor = 'Constructor',
|
||||
Property = 'Property',
|
||||
Method = 'Method',
|
||||
Interface = 'Interface',
|
||||
TypeAlias = 'Type alias',
|
||||
Variable = 'Variable',
|
||||
Function = 'Function',
|
||||
Enumeration = 'Enumeration',
|
||||
}
|
||||
|
||||
export interface EnumValue {
|
||||
name: string;
|
||||
@@ -486,11 +456,10 @@ export interface MenuSubsectionsBySection {
|
||||
[section: string]: string[];
|
||||
}
|
||||
|
||||
export const ProviderType = strEnum([
|
||||
'INJECTED',
|
||||
'LEDGER',
|
||||
]);
|
||||
export type ProviderType = keyof typeof ProviderType;
|
||||
export enum ProviderType {
|
||||
Injected = 'INJECTED',
|
||||
Ledger = 'LEDGER',
|
||||
}
|
||||
|
||||
export interface Fact {
|
||||
title: string;
|
||||
@@ -694,4 +663,12 @@ export interface OutdatedWrappedEtherByNetworkId {
|
||||
};
|
||||
}
|
||||
|
||||
export enum SmartContractDocSections {
|
||||
Introduction = 'Introduction',
|
||||
Exchange = 'Exchange',
|
||||
TokenTransferProxy = 'TokenTransferProxy',
|
||||
TokenRegistry = 'TokenRegistry',
|
||||
ZRXToken = 'ZRXToken',
|
||||
}
|
||||
|
||||
// tslint:disable:max-file-line-count
|
||||
|
43
packages/website/ts/utils/colors.ts
Normal file
43
packages/website/ts/utils/colors.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import {colors as materialUiColors} from 'material-ui/styles';
|
||||
|
||||
export const colors = {
|
||||
...materialUiColors,
|
||||
grey50: '#FAFAFA',
|
||||
grey100: '#F5F5F5',
|
||||
lightestGrey: '#F0F0F0',
|
||||
greyishPink: '#E6E5E5',
|
||||
grey300: '#E0E0E0',
|
||||
beigeWhite: '#E4E4E4',
|
||||
grey400: '#BDBDBD',
|
||||
lightGrey: '#BBBBBB',
|
||||
grey500: '#9E9E9E',
|
||||
grey: '#A5A5A5',
|
||||
darkGrey: '#818181',
|
||||
landingLinkGrey: '#919191',
|
||||
grey700: '#616161',
|
||||
grey800: '#424242',
|
||||
darkerGrey: '#393939',
|
||||
heroGrey: '#404040',
|
||||
projectsGrey: '#343333',
|
||||
darkestGrey: '#272727',
|
||||
dharmaDarkGrey: '#252525',
|
||||
lightBlue: '#60A4F4',
|
||||
lightBlueA700: '#0091EA',
|
||||
darkBlue: '#4D5481',
|
||||
turquois: '#058789',
|
||||
lightPurple: '#A81CA6',
|
||||
purple: '#690596',
|
||||
red200: '#EF9A9A',
|
||||
red: '#E91751',
|
||||
red500: '#F44336',
|
||||
red600: '#E53935',
|
||||
limeGreen: '#66DE75',
|
||||
lightGreen: '#4DC55C',
|
||||
lightestGreen: '#89C774',
|
||||
brightGreen: '#00C33E',
|
||||
green400: '#66BB6A',
|
||||
green: '#4DA24B',
|
||||
amber600: '#FFB300',
|
||||
orange: '#E69D00',
|
||||
amber800: '#FF8F00',
|
||||
};
|
@@ -1,25 +1,105 @@
|
||||
import * as _ from 'lodash';
|
||||
import {
|
||||
ContractAddresses,
|
||||
Environments,
|
||||
Networks,
|
||||
OutdatedWrappedEtherByNetworkId,
|
||||
PublicNodeUrlsByNetworkId,
|
||||
SmartContractDocSections,
|
||||
} from 'ts/types';
|
||||
|
||||
const BASE_URL = window.location.origin;
|
||||
const isDevelopment = _.includes(BASE_URL, 'https://0xproject.dev:3572') ||
|
||||
_.includes(BASE_URL, 'https://localhost:3572') ||
|
||||
_.includes(BASE_URL, 'https://127.0.0.1');
|
||||
const isDevelopment = _.includes([
|
||||
'https://0xproject.localhost:3572',
|
||||
'https://localhost:3572',
|
||||
'https://127.0.0.1',
|
||||
], BASE_URL);
|
||||
const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs';
|
||||
|
||||
export const configs = {
|
||||
BASE_URL,
|
||||
ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,
|
||||
BACKEND_BASE_URL: isDevelopment ? 'https://localhost:3001' : 'https://website-api.0xproject.com',
|
||||
symbolsOfMintableTokens: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'],
|
||||
BASE_URL,
|
||||
BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
|
||||
CONTRACT_ADDRESS: {
|
||||
'1.0.0': {
|
||||
[Networks.mainnet]: {
|
||||
[SmartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
|
||||
[SmartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
|
||||
[SmartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
|
||||
[SmartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
|
||||
},
|
||||
[Networks.ropsten]: {
|
||||
[SmartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
|
||||
[SmartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
|
||||
[SmartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
|
||||
[SmartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
|
||||
},
|
||||
[Networks.kovan]: {
|
||||
[SmartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
|
||||
[SmartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
|
||||
[SmartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
|
||||
[SmartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
|
||||
},
|
||||
},
|
||||
} as ContractAddresses,
|
||||
DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
|
||||
// WARNING: ZRX & WETH MUST always be default trackedTokens
|
||||
defaultTrackedTokenSymbols: ['WETH', 'ZRX'],
|
||||
lastLocalStorageFillClearanceDate: '2017-11-22',
|
||||
lastLocalStorageTrackedTokenClearanceDate: '2017-12-13',
|
||||
isMainnetEnabled: true,
|
||||
outdatedWrappedEthers: [
|
||||
DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],
|
||||
DOMAIN_STAGING: 'staging-0xproject.s3-website-us-east-1.amazonaws.com',
|
||||
DOMAIN_DEVELOPMENT: '0xproject.localhost:3572',
|
||||
DOMAIN_PRODUCTION: '0xproject.com',
|
||||
ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,
|
||||
ICON_URL_BY_SYMBOL: {
|
||||
'REP': '/images/token_icons/augur.png',
|
||||
'DGD': '/images/token_icons/digixdao.png',
|
||||
'WETH': '/images/token_icons/ether_erc20.png',
|
||||
'MLN': '/images/token_icons/melon.png',
|
||||
'GNT': '/images/token_icons/golem.png',
|
||||
'MKR': '/images/token_icons/makerdao.png',
|
||||
'ZRX': '/images/token_icons/zero_ex.png',
|
||||
'ANT': '/images/token_icons/aragon.png',
|
||||
'BNT': '/images/token_icons/bancor.png',
|
||||
'BAT': '/images/token_icons/basicattentiontoken.png',
|
||||
'CVC': '/images/token_icons/civic.png',
|
||||
'EOS': '/images/token_icons/eos.png',
|
||||
'FUN': '/images/token_icons/funfair.png',
|
||||
'GNO': '/images/token_icons/gnosis.png',
|
||||
'ICN': '/images/token_icons/iconomi.png',
|
||||
'OMG': '/images/token_icons/omisego.png',
|
||||
'SNT': '/images/token_icons/status.png',
|
||||
'STORJ': '/images/token_icons/storjcoinx.png',
|
||||
'PAY': '/images/token_icons/tenx.png',
|
||||
'QTUM': '/images/token_icons/qtum.png',
|
||||
'DNT': '/images/token_icons/district0x.png',
|
||||
'SNGLS': '/images/token_icons/singularity.png',
|
||||
'EDG': '/images/token_icons/edgeless.png',
|
||||
'1ST': '/images/token_icons/firstblood.jpg',
|
||||
'WINGS': '/images/token_icons/wings.png',
|
||||
'BQX': '/images/token_icons/bitquence.png',
|
||||
'LUN': '/images/token_icons/lunyr.png',
|
||||
'RLC': '/images/token_icons/iexec.png',
|
||||
'MCO': '/images/token_icons/monaco.png',
|
||||
'ADT': '/images/token_icons/adtoken.png',
|
||||
'CFI': '/images/token_icons/cofound-it.png',
|
||||
'ROL': '/images/token_icons/etheroll.png',
|
||||
'WGNT': '/images/token_icons/golem.png',
|
||||
'MTL': '/images/token_icons/metal.png',
|
||||
'NMR': '/images/token_icons/numeraire.png',
|
||||
'SAN': '/images/token_icons/santiment.png',
|
||||
'TAAS': '/images/token_icons/taas.png',
|
||||
'TKN': '/images/token_icons/tokencard.png',
|
||||
'TRST': '/images/token_icons/trust.png',
|
||||
} as {[symbol: string]: string},
|
||||
IS_MAINNET_ENABLED: true,
|
||||
LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE: '2017-11-22',
|
||||
LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE: '2017-12-19',
|
||||
// NEW_WRAPPED_ETHERS is temporary until we remove the SHOULD_DEPRECATE_OLD_WETH_TOKEN flag
|
||||
// and add the new WETHs to the tokenRegistry
|
||||
NEW_WRAPPED_ETHERS: {
|
||||
1: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
||||
42: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
} as {[networkId: string]: string},
|
||||
OUTDATED_WRAPPED_ETHERS: [
|
||||
{
|
||||
42: {
|
||||
address: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c',
|
||||
@@ -37,4 +117,15 @@ export const configs = {
|
||||
},
|
||||
},
|
||||
] as OutdatedWrappedEtherByNetworkId[],
|
||||
// The order matters. We first try first node and only then fall back to others.
|
||||
PUBLIC_NODE_URLS_BY_NETWORK_ID: {
|
||||
[1]: [
|
||||
`https://mainnet.infura.io/${INFURA_API_KEY}`,
|
||||
],
|
||||
[42]: [
|
||||
`https://kovan.infura.io/${INFURA_API_KEY}`,
|
||||
],
|
||||
} as PublicNodeUrlsByNetworkId,
|
||||
SHOULD_DEPRECATE_OLD_WETH_TOKEN: true,
|
||||
SYMBOLS_OF_MINTABLE_TOKENS: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'],
|
||||
};
|
||||
|
@@ -1,188 +1,87 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
import {
|
||||
ContractAddresses,
|
||||
Docs,
|
||||
Networks,
|
||||
PublicNodeUrlsByNetworkId,
|
||||
WebsitePaths,
|
||||
} from 'ts/types';
|
||||
|
||||
const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs';
|
||||
const smartContractDocSections = {
|
||||
Introduction: 'Introduction',
|
||||
Exchange: 'Exchange',
|
||||
TokenTransferProxy: 'TokenTransferProxy',
|
||||
TokenRegistry: 'TokenRegistry',
|
||||
ZRXToken: 'ZRXToken',
|
||||
EtherToken: 'EtherToken',
|
||||
};
|
||||
|
||||
export const constants = {
|
||||
ANGELLIST_URL: 'https://angel.co/0xproject/jobs',
|
||||
STAGING_DOMAIN: 'staging-0xproject.s3-website-us-east-1.amazonaws.com',
|
||||
PRODUCTION_DOMAIN: '0xproject.com',
|
||||
DEVELOPMENT_DOMAIN: '0xproject.dev:3572',
|
||||
BIGNUMBERJS_GITHUB_URL: 'http://mikemcl.github.io/bignumber.js',
|
||||
BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
|
||||
BITLY_ENDPOINT: 'https://api-ssl.bitly.com',
|
||||
BLOG_URL: 'https://blog.0xproject.com/latest',
|
||||
CUSTOM_BLUE: '#60a4f4',
|
||||
DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
|
||||
ETHER_FAUCET_ENDPOINT: 'https://faucet.0xproject.com',
|
||||
FEE_RECIPIENT_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||
FIREFOX_U2F_ADDON: 'https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/',
|
||||
GITHUB_URL: 'https://github.com/0xProject',
|
||||
GITHUB_WIKI_URL: 'https://github.com/0xProject/wiki',
|
||||
HTTP_NO_CONTENT_STATUS_CODE: 204,
|
||||
ACCEPT_DISCLAIMER_LOCAL_STORAGE_KEY: 'didAcceptPortalDisclaimer',
|
||||
LINKEDIN_0X_URL: 'https://www.linkedin.com/company/0x',
|
||||
LEDGER_PROVIDER_NAME: 'Ledger',
|
||||
METAMASK_PROVIDER_NAME: 'Metamask',
|
||||
DECIMAL_PLACES_ETH: 18,
|
||||
DECIMAL_PLACES_ZRX: 18,
|
||||
DOCS_SCROLL_DURATION_MS: 0,
|
||||
DOCS_CONTAINER_ID: 'documentation',
|
||||
GENESIS_ORDER_BLOCK_BY_NETWORK_ID: {
|
||||
1: 4145578,
|
||||
42: 3117574,
|
||||
50: 0,
|
||||
} as {[networkId: number]: number},
|
||||
PUBLIC_PROVIDER_NAME: '0x Public',
|
||||
// The order matters. We first try first node and only then fall back to others.
|
||||
PUBLIC_NODE_URLS_BY_NETWORK_ID: {
|
||||
[1]: [
|
||||
`https://mainnet.infura.io/${INFURA_API_KEY}`,
|
||||
],
|
||||
[42]: [
|
||||
`https://kovan.infura.io/${INFURA_API_KEY}`,
|
||||
],
|
||||
} as PublicNodeUrlsByNetworkId,
|
||||
PARITY_SIGNER_PROVIDER_NAME: 'Parity Signer',
|
||||
GENERIC_PROVIDER_NAME: 'Injected Web3',
|
||||
HOME_SCROLL_DURATION_MS: 500,
|
||||
HTTP_NO_CONTENT_STATUS_CODE: 204,
|
||||
LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER: 'didAcceptPortalDisclaimer',
|
||||
LOCAL_STORAGE_KEY_DISMISS_WETH_NOTICE: 'hasDismissedWethNotice',
|
||||
MAKER_FEE: new BigNumber(0),
|
||||
MAINNET_NAME: 'Main network',
|
||||
MAINNET_NETWORK_ID: 1,
|
||||
METAMASK_CHROME_STORE_URL: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',
|
||||
// tslint:disable-next-line:max-line-length
|
||||
PARITY_CHROME_STORE_URL: 'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig',
|
||||
MIST_DOWNLOAD_URL: 'https://github.com/ethereum/mist/releases',
|
||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||
ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
|
||||
DOCS_SCROLL_DURATION_MS: 0,
|
||||
DOCS_CONTAINER_ID: 'documentation',
|
||||
HOME_SCROLL_DURATION_MS: 500,
|
||||
REDDIT_URL: 'https://reddit.com/r/0xproject',
|
||||
STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md',
|
||||
SUCCESS_STATUS: 200,
|
||||
UNAVAILABLE_STATUS: 503,
|
||||
TAKER_FEE: new BigNumber(0),
|
||||
TESTNET_NAME: 'Kovan',
|
||||
TESTNET_NETWORK_ID: 42,
|
||||
TESTRPC_NETWORK_ID: 50,
|
||||
TWITTER_URL: 'https://twitter.com/0xproject',
|
||||
ETH_DECIMAL_PLACES: 18,
|
||||
MINT_AMOUNT: new BigNumber('100000000000000000000'),
|
||||
WEB3_DOCS_URL: 'https://github.com/ethereum/wiki/wiki/JavaScript-API',
|
||||
WEB3_PROVIDER_DOCS_URL: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150',
|
||||
WEB3_DECODED_LOG_ENTRY_EVENT_URL:
|
||||
'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123',
|
||||
WEB3_LOG_ENTRY_EVENT_URL: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127',
|
||||
ZEROEX_CHAT_URL: 'https://chat.0xproject.com',
|
||||
// Projects
|
||||
ETHFINEX_URL: 'https://www.bitfinex.com/ethfinex',
|
||||
RADAR_RELAY_URL: 'https://radarrelay.com',
|
||||
PARADEX_URL: 'https://paradex.io',
|
||||
DYDX_URL: 'https://dydx.exchange',
|
||||
MELONPORT_URL: 'https://melonport.com',
|
||||
DISTRICT_0X_URL: 'https://district0x.io',
|
||||
DHARMA_URL: 'https://dharma.io',
|
||||
LENDROID_URL: 'https://lendroid.com',
|
||||
MAKER_URL: 'https://makerdao.com',
|
||||
ARAGON_URL: 'https://aragon.one',
|
||||
BLOCKNET_URL: 'https://blocknet.co',
|
||||
OCEAN_URL: 'http://the0cean.com',
|
||||
STATUS_URL: 'https://status.im',
|
||||
AUGUR_URL: 'https://augur.net',
|
||||
AUCTUS_URL: 'https://auctus.org',
|
||||
OPEN_ANX_URL: 'https://www.openanx.org',
|
||||
|
||||
iconUrlBySymbol: {
|
||||
'REP': '/images/token_icons/augur.png',
|
||||
'DGD': '/images/token_icons/digixdao.png',
|
||||
'WETH': '/images/token_icons/ether_erc20.png',
|
||||
'MLN': '/images/token_icons/melon.png',
|
||||
'GNT': '/images/token_icons/golem.png',
|
||||
'MKR': '/images/token_icons/makerdao.png',
|
||||
'ZRX': '/images/token_icons/zero_ex.png',
|
||||
'ANT': '/images/token_icons/aragon.png',
|
||||
'BNT': '/images/token_icons/bancor.png',
|
||||
'BAT': '/images/token_icons/basicattentiontoken.png',
|
||||
'CVC': '/images/token_icons/civic.png',
|
||||
'EOS': '/images/token_icons/eos.png',
|
||||
'FUN': '/images/token_icons/funfair.png',
|
||||
'GNO': '/images/token_icons/gnosis.png',
|
||||
'ICN': '/images/token_icons/iconomi.png',
|
||||
'OMG': '/images/token_icons/omisego.png',
|
||||
'SNT': '/images/token_icons/status.png',
|
||||
'STORJ': '/images/token_icons/storjcoinx.png',
|
||||
'PAY': '/images/token_icons/tenx.png',
|
||||
'QTUM': '/images/token_icons/qtum.png',
|
||||
'DNT': '/images/token_icons/district0x.png',
|
||||
'SNGLS': '/images/token_icons/singularity.png',
|
||||
'EDG': '/images/token_icons/edgeless.png',
|
||||
'1ST': '/images/token_icons/firstblood.jpg',
|
||||
'WINGS': '/images/token_icons/wings.png',
|
||||
'BQX': '/images/token_icons/bitquence.png',
|
||||
'LUN': '/images/token_icons/lunyr.png',
|
||||
'RLC': '/images/token_icons/iexec.png',
|
||||
'MCO': '/images/token_icons/monaco.png',
|
||||
'ADT': '/images/token_icons/adtoken.png',
|
||||
'CFI': '/images/token_icons/cofound-it.png',
|
||||
'ROL': '/images/token_icons/etheroll.png',
|
||||
'WGNT': '/images/token_icons/golem.png',
|
||||
'MTL': '/images/token_icons/metal.png',
|
||||
'NMR': '/images/token_icons/numeraire.png',
|
||||
'SAN': '/images/token_icons/santiment.png',
|
||||
'TAAS': '/images/token_icons/taas.png',
|
||||
'TKN': '/images/token_icons/tokencard.png',
|
||||
'TRST': '/images/token_icons/trust.png',
|
||||
} as {[symbol: string]: string},
|
||||
networkNameById: {
|
||||
NETWORK_ID_MAINNET: 1,
|
||||
NETWORK_ID_TESTNET: 42,
|
||||
NETWORK_ID_TESTRPC: 50,
|
||||
NETWORK_NAME_BY_ID: {
|
||||
1: Networks.mainnet,
|
||||
3: Networks.ropsten,
|
||||
4: Networks.rinkeby,
|
||||
42: Networks.kovan,
|
||||
} as {[symbol: number]: string},
|
||||
networkIdByName: {
|
||||
NETWORK_ID_BY_NAME: {
|
||||
[Networks.mainnet]: 1,
|
||||
[Networks.ropsten]: 3,
|
||||
[Networks.rinkeby]: 4,
|
||||
[Networks.kovan]: 42,
|
||||
} as {[networkName: string]: number},
|
||||
docToPath: {
|
||||
[Docs.ZeroExJs]: WebsitePaths.ZeroExJs,
|
||||
[Docs.SmartContracts]: WebsitePaths.SmartContracts,
|
||||
},
|
||||
smartContractDocSections,
|
||||
contractAddresses: {
|
||||
'1.0.0': {
|
||||
[Networks.mainnet]: {
|
||||
[smartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
|
||||
[smartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
|
||||
[smartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
|
||||
[smartContractDocSections.EtherToken]: '0x2956356cd2a2bf3202f771f50d3d14a367b48070',
|
||||
[smartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
|
||||
},
|
||||
[Networks.ropsten]: {
|
||||
[smartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
|
||||
[smartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
|
||||
[smartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
|
||||
[smartContractDocSections.EtherToken]: '0xc00fd9820cd2898cc4c054b7bf142de637ad129a',
|
||||
[smartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
|
||||
},
|
||||
[Networks.kovan]: {
|
||||
[smartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
|
||||
[smartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
|
||||
[smartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
|
||||
[smartContractDocSections.EtherToken]: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c',
|
||||
[smartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
|
||||
},
|
||||
},
|
||||
} as ContractAddresses,
|
||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||
PROVIDER_NAME_LEDGER: 'Ledger',
|
||||
PROVIDER_NAME_METAMASK: 'Metamask',
|
||||
PROVIDER_NAME_PARITY_SIGNER: 'Parity Signer',
|
||||
PROVIDER_NAME_GENERIC: 'Injected Web3',
|
||||
PROVIDER_NAME_PUBLIC: '0x Public',
|
||||
ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
|
||||
SUCCESS_STATUS: 200,
|
||||
UNAVAILABLE_STATUS: 503,
|
||||
TAKER_FEE: new BigNumber(0),
|
||||
TESTNET_NAME: 'Kovan',
|
||||
PROJECT_URL_ETHFINEX: 'https://www.bitfinex.com/ethfinex',
|
||||
PROJECT_URL_RADAR_RELAY: 'https://radarrelay.com',
|
||||
PROJECT_URL_PARADEX: 'https://paradex.io',
|
||||
PROJECT_URL_DYDX: 'https://dydx.exchange',
|
||||
PROJECT_URL_MELONPORT: 'https://melonport.com',
|
||||
PROJECT_URL_DISTRICT_0X: 'https://district0x.io',
|
||||
PROJECT_URL_DHARMA: 'https://dharma.io',
|
||||
PROJECT_URL_LENDROID: 'https://lendroid.com',
|
||||
PROJECT_URL_MAKER: 'https://makerdao.com',
|
||||
PROJECT_URL_ARAGON: 'https://aragon.one',
|
||||
PROJECT_URL_BLOCKNET: 'https://blocknet.co',
|
||||
PROJECT_URL_0CEAN: 'http://the0cean.com',
|
||||
PROJECT_URL_STATUS: 'https://status.im',
|
||||
PROJECT_URL_AUGUR: 'https://augur.net',
|
||||
PROJECT_URL_AUCTUS: 'https://auctus.org',
|
||||
PROJECT_URL_OPEN_ANX: 'https://www.openanx.org',
|
||||
URL_ANGELLIST: 'https://angel.co/0xproject/jobs',
|
||||
URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js',
|
||||
URL_BITLY_API: 'https://api-ssl.bitly.com',
|
||||
URL_BLOG: 'https://blog.0xproject.com/latest',
|
||||
URL_FIREFOX_U2F_ADDON: 'https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/',
|
||||
URL_ETHER_FAUCET: 'https://faucet.0xproject.com',
|
||||
URL_GITHUB_ORG: 'https://github.com/0xProject',
|
||||
URL_GITHUB_WIKI: 'https://github.com/0xProject/wiki',
|
||||
URL_METAMASK_CHROME_STORE: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',
|
||||
URL_MIST_DOWNLOAD: 'https://github.com/ethereum/mist/releases',
|
||||
URL_PARITY_CHROME_STORE:
|
||||
'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig',
|
||||
URL_REDDIT: 'https://reddit.com/r/0xproject',
|
||||
URL_STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md',
|
||||
URL_TWITTER: 'https://twitter.com/0xproject',
|
||||
URL_WEB3_DOCS: 'https://github.com/ethereum/wiki/wiki/JavaScript-API',
|
||||
URL_WEB3_DECODED_LOG_ENTRY_EVENT:
|
||||
'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123',
|
||||
URL_WEB3_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127',
|
||||
URL_WEB3_PROVIDER_DOCS: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150',
|
||||
URL_WETH_IO: 'https://weth.io/',
|
||||
URL_ZEROEX_CHAT: 'https://chat.0xproject.com',
|
||||
};
|
||||
|
@@ -15,7 +15,7 @@ const rollbarConfig = {
|
||||
environment: configs.ENVIRONMENT,
|
||||
},
|
||||
uncaughtErrorLevel: 'error',
|
||||
hostWhiteList: [constants.PRODUCTION_DOMAIN, constants.STAGING_DOMAIN],
|
||||
hostWhiteList: [configs.DOMAIN_PRODUCTION, configs.DOMAIN_STAGING],
|
||||
ignoredMessages: [
|
||||
// Errors from the third-party scripts
|
||||
'Script error',
|
||||
|
35
packages/website/ts/utils/mui_theme.ts
Normal file
35
packages/website/ts/utils/mui_theme.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import {getMuiTheme} from 'material-ui/styles';
|
||||
import {colors} from 'ts/utils/colors';
|
||||
|
||||
export const muiTheme = getMuiTheme({
|
||||
appBar: {
|
||||
height: 45,
|
||||
color: colors.white,
|
||||
textColor: colors.black,
|
||||
},
|
||||
palette: {
|
||||
pickerHeaderColor: colors.lightBlue,
|
||||
primary1Color: colors.lightBlue,
|
||||
primary2Color: colors.lightBlue,
|
||||
textColor: colors.grey700,
|
||||
},
|
||||
datePicker: {
|
||||
color: colors.grey700,
|
||||
textColor: colors.white,
|
||||
calendarTextColor: colors.white,
|
||||
selectColor: colors.darkestGrey,
|
||||
selectTextColor: colors.white,
|
||||
},
|
||||
timePicker: {
|
||||
color: colors.grey700,
|
||||
textColor: colors.white,
|
||||
accentColor: colors.white,
|
||||
headerColor: colors.darkestGrey,
|
||||
selectColor: colors.darkestGrey,
|
||||
selectTextColor: colors.darkestGrey,
|
||||
},
|
||||
toggle: {
|
||||
thumbOnColor: colors.limeGreen,
|
||||
trackOnColor: colors.lightGreen,
|
||||
},
|
||||
});
|
@@ -22,7 +22,7 @@ export const typeDocUtils = {
|
||||
isType(entity: TypeDocNode): boolean {
|
||||
return entity.kindString === KindString.Interface ||
|
||||
entity.kindString === KindString.Function ||
|
||||
entity.kindString === KindString['Type alias'] ||
|
||||
entity.kindString === KindString.TypeAlias ||
|
||||
entity.kindString === KindString.Variable ||
|
||||
entity.kindString === KindString.Enumeration;
|
||||
},
|
||||
@@ -126,7 +126,7 @@ export const typeDocUtils = {
|
||||
case KindString.Function:
|
||||
case KindString.Variable:
|
||||
case KindString.Enumeration:
|
||||
case KindString['Type alias']:
|
||||
case KindString.TypeAlias:
|
||||
if (docsInfo.isPublicType(entity.name)) {
|
||||
const customType = typeDocUtils._convertCustomType(
|
||||
entity, docsInfo.sections, sectionName, docsInfo.subPackageName);
|
||||
|
@@ -15,6 +15,7 @@ import {
|
||||
Token,
|
||||
TokenByAddress,
|
||||
} from 'ts/types';
|
||||
import {configs} from 'ts/utils/configs';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import * as u2f from 'ts/vendor/u2f_api';
|
||||
|
||||
@@ -61,8 +62,8 @@ export const utils = {
|
||||
orderExpiryTimestamp: BigNumber, orderTakerAddress: string, orderMakerAddress: string,
|
||||
makerFee: BigNumber, takerFee: BigNumber, feeRecipient: string,
|
||||
signatureData: SignatureData, tokenByAddress: TokenByAddress, orderSalt: BigNumber): Order {
|
||||
const makerToken = tokenByAddress[sideToAssetToken[Side.deposit].address];
|
||||
const takerToken = tokenByAddress[sideToAssetToken[Side.receive].address];
|
||||
const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address];
|
||||
const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address];
|
||||
const order = {
|
||||
maker: {
|
||||
address: orderMakerAddress,
|
||||
@@ -72,7 +73,7 @@ export const utils = {
|
||||
decimals: makerToken.decimals,
|
||||
address: makerToken.address,
|
||||
},
|
||||
amount: sideToAssetToken[Side.deposit].amount.toString(),
|
||||
amount: sideToAssetToken[Side.Deposit].amount.toString(),
|
||||
feeAmount: makerFee.toString(),
|
||||
},
|
||||
taker: {
|
||||
@@ -83,7 +84,7 @@ export const utils = {
|
||||
decimals: takerToken.decimals,
|
||||
address: takerToken.address,
|
||||
},
|
||||
amount: sideToAssetToken[Side.receive].amount.toString(),
|
||||
amount: sideToAssetToken[Side.Receive].amount.toString(),
|
||||
feeAmount: takerFee.toString(),
|
||||
},
|
||||
expiration: orderExpiryTimestamp.toString(),
|
||||
@@ -124,11 +125,11 @@ export const utils = {
|
||||
// This logic mirrors the CSS media queries in BassCSS for the `lg-`, `md-` and `sm-` CSS
|
||||
// class prefixes. Do not edit these.
|
||||
if (widthInEm > LG_MIN_EM) {
|
||||
return ScreenWidths.LG;
|
||||
return ScreenWidths.Lg;
|
||||
} else if (widthInEm > MD_MIN_EM) {
|
||||
return ScreenWidths.MD;
|
||||
return ScreenWidths.Md;
|
||||
} else {
|
||||
return ScreenWidths.SM;
|
||||
return ScreenWidths.Sm;
|
||||
}
|
||||
},
|
||||
isUserOnMobile(): boolean {
|
||||
@@ -136,7 +137,7 @@ export const utils = {
|
||||
return isUserOnMobile;
|
||||
},
|
||||
getEtherScanLinkIfExists(addressOrTxHash: string, networkId: number, suffix: EtherscanLinkSuffixes): string {
|
||||
const networkName = constants.networkNameById[networkId];
|
||||
const networkName = constants.NETWORK_NAME_BY_ID[networkId];
|
||||
if (_.isUndefined(networkName)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -182,11 +183,11 @@ export const utils = {
|
||||
},
|
||||
getCurrentEnvironment() {
|
||||
switch (location.host) {
|
||||
case constants.DEVELOPMENT_DOMAIN:
|
||||
case configs.DOMAIN_DEVELOPMENT:
|
||||
return 'development';
|
||||
case constants.STAGING_DOMAIN:
|
||||
case configs.DOMAIN_STAGING:
|
||||
return 'staging';
|
||||
case constants.PRODUCTION_DOMAIN:
|
||||
case configs.DOMAIN_PRODUCTION:
|
||||
return 'production';
|
||||
default:
|
||||
return 'production';
|
||||
|
Reference in New Issue
Block a user