aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant
diff options
context:
space:
mode:
authorfragosti <francesco.agosti93@gmail.com>2018-11-02 07:13:43 +0800
committerfragosti <francesco.agosti93@gmail.com>2018-11-02 07:13:43 +0800
commit695d1453ac941fd7ef79ff1c4a255630eb76c764 (patch)
tree8e18b543df236ce7ef00d33770ed71f91e6b7d67 /packages/instant
parentce19ec207b07696a675bdadf71ea39d933ea2715 (diff)
parent7c30fd4b2da83c9522f9137f4d18e6c308f2b66f (diff)
downloaddexon-sol-tools-695d1453ac941fd7ef79ff1c4a255630eb76c764.tar
dexon-sol-tools-695d1453ac941fd7ef79ff1c4a255630eb76c764.tar.gz
dexon-sol-tools-695d1453ac941fd7ef79ff1c4a255630eb76c764.tar.bz2
dexon-sol-tools-695d1453ac941fd7ef79ff1c4a255630eb76c764.tar.lz
dexon-sol-tools-695d1453ac941fd7ef79ff1c4a255630eb76c764.tar.xz
dexon-sol-tools-695d1453ac941fd7ef79ff1c4a255630eb76c764.tar.zst
dexon-sol-tools-695d1453ac941fd7ef79ff1c4a255630eb76c764.zip
Merge branch 'development' of https://github.com/0xProject/0x-monorepo into feature/instant/maker-asset-datas-interface
Diffstat (limited to 'packages/instant')
-rw-r--r--packages/instant/public/index.html57
-rw-r--r--packages/instant/src/components/ui/icon.tsx76
-rw-r--r--packages/instant/src/components/ui/index.ts3
-rw-r--r--packages/instant/src/components/ui/overlay.tsx38
-rw-r--r--packages/instant/src/components/zero_ex_instant.tsx131
-rw-r--r--packages/instant/src/components/zero_ex_instant_overlay.tsx21
-rw-r--r--packages/instant/src/components/zero_ex_instant_provider.tsx126
-rw-r--r--packages/instant/src/constants.ts1
-rw-r--r--packages/instant/src/data/asset_data_network_mapping.ts5
-rw-r--r--packages/instant/src/data/asset_meta_data_map.ts6
-rw-r--r--packages/instant/src/index.ts1
-rw-r--r--packages/instant/src/index.umd.ts35
-rw-r--r--packages/instant/src/style/theme.ts1
13 files changed, 331 insertions, 170 deletions
diff --git a/packages/instant/public/index.html b/packages/instant/public/index.html
index 4c35e6f3b..e1f8432be 100644
--- a/packages/instant/public/index.html
+++ b/packages/instant/public/index.html
@@ -34,28 +34,47 @@
EXPONENTIAL_AT: 1000,
DECIMAL_PLACES: 78,
});
- const providedOrder = {
- senderAddress: '0x0000000000000000000000000000000000000000',
- makerAddress: '0x14e2f1f157e7dd4057d02817436d628a37120fd1',
- takerAddress: '0x0000000000000000000000000000000000000000',
- makerFee: new BigNumber('0'),
- takerFee: new BigNumber('0'),
- makerAssetAmount: new BigNumber('100000000000000000000'),
- takerAssetAmount: new BigNumber('10000000000000000'),
- makerAssetData: '0xf47261b00000000000000000000000002002d3812f58e35f0ea1ffbf80a75a38c32175fa',
- takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
- expirationTimeSeconds: new BigNumber('1591858800'),
- feeRecipientAddress: '0x0000000000000000000000000000000000000000',
- salt: new BigNumber(
- '54983920541892966634674340965984367456810207583416050222519063020710969340046',
- ),
- signature:
- '0x1b949656218421c845995457303569a656764afa2b979d41dcefff0009d57ce15001490268bc7caa4269894fd83b741465fc5a7a53eda6ece17eb91fb32655d83703',
- exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2',
- };
+ const providedOrders = [
+ // Order selling REP
+ {
+ senderAddress: '0x0000000000000000000000000000000000000000',
+ makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
+ takerAddress: '0x0000000000000000000000000000000000000000',
+ makerFee: new BigNumber('0'),
+ takerFee: new BigNumber('0'),
+ makerAssetAmount: new BigNumber('400000000000000000000'),
+ takerAssetAmount: new BigNumber('40000000000000000000'),
+ makerAssetData: '0xf47261b00000000000000000000000008cb3971b8eb709c14616bd556ff6683019e90d9c',
+ takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
+ expirationTimeSeconds: new BigNumber('1543046400'),
+ feeRecipientAddress: '0x0000000000000000000000000000000000000000',
+ salt: new BigNumber('47929252863126413473766089649682650973189811771354566206928245255479607883031'),
+ signature: '0x1c0bf8ba709ceb5b32e6b0b5a8bb7f07e9d19aba88d8530715f8a298d12188e3862fcc0a30ddfad4062b30459f2859323c064052f12cc687466c457934b9419a1b03',
+ exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
+ },
+ // Order selling ZRX
+ {
+ senderAddress: '0x0000000000000000000000000000000000000000',
+ makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
+ takerAddress: '0x0000000000000000000000000000000000000000',
+ makerFee: new BigNumber('0'),
+ takerFee: new BigNumber('0'),
+ makerAssetAmount: new BigNumber('300000000000000000000'),
+ takerAssetAmount: new BigNumber('31000000000000000000'),
+ makerAssetData: '0xf47261b00000000000000000000000002002d3812f58e35f0ea1ffbf80a75a38c32175fa',
+ takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
+ expirationTimeSeconds: new BigNumber('2524636800'),
+ feeRecipientAddress: '0x0000000000000000000000000000000000000000',
+ salt: new BigNumber('64592004666704945574675477805199411288137454783320798602050822322450089238268'),
+ signature: '0x1c13cacddca8d7d8248e91f412377e68f8f1f9891a59a6c1b2eea9f7b33558c30c4fb86a448e08ab7def40a28fb3a3062dcb33bb3c45302447fce5c4288b7c7f5b03',
+ exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
+ }
+ ];
const queryParams = new Uri(window.location.search);
const renderOptionsDefaults = {
orderSource: 'https://api.radarrelay.com/0x/v2/',
+ assetData: '0xf47261b0000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498',
+ onClose: () => { console.log('0x Instant Closed') }
}
const orderSourceOverride = queryParams.getQueryParamValue('orderSource');
const availableAssetDatasString = queryParams.getQueryParamValue('availableAssetDatas');
diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx
index 61b382760..574cb26b7 100644
--- a/packages/instant/src/components/ui/icon.tsx
+++ b/packages/instant/src/components/ui/icon.tsx
@@ -1,5 +1,8 @@
+import * as _ from 'lodash';
import * as React from 'react';
+import { styled } from '../../style/theme';
+
type svgRule = 'evenodd' | 'nonzero' | 'inherit';
interface IconInfo {
viewBox: string;
@@ -13,11 +16,19 @@ interface IconInfo {
strokeLinejoin?: 'miter' | 'round' | 'bevel' | 'inherit';
}
interface IconInfoMapping {
+ closeX: IconInfo;
failed: IconInfo;
success: IconInfo;
chevron: IconInfo;
}
const ICONS: IconInfoMapping = {
+ closeX: {
+ viewBox: '0 0 11 11',
+ fillRule: 'evenodd',
+ clipRule: 'evenodd',
+ path:
+ 'M10.45 10.449C10.7539 10.1453 10.7539 9.65282 10.45 9.34909L6.60068 5.49999L10.45 1.65093C10.7538 1.3472 10.7538 0.854765 10.45 0.551038C10.1462 0.24731 9.65378 0.24731 9.34995 0.551038L5.50058 4.40006L1.65024 0.549939C1.34641 0.246212 0.853973 0.246212 0.550262 0.549939C0.246429 0.853667 0.246429 1.34611 0.550262 1.64983L4.40073 5.49995L0.55014 9.35019C0.246307 9.65392 0.246307 10.1464 0.55014 10.4501C0.853851 10.7538 1.34628 10.7538 1.65012 10.4501L5.5007 6.59987L9.35007 10.449C9.6539 10.7527 10.1463 10.7527 10.45 10.449Z',
+ },
failed: {
viewBox: '0 0 34 34',
fillRule: 'evenodd',
@@ -44,33 +55,56 @@ const ICONS: IconInfoMapping = {
};
export interface IconProps {
+ className?: string;
width: number;
height?: number;
color?: string;
icon: keyof IconInfoMapping;
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
+ padding?: string;
}
-export const Icon: React.SFC<IconProps> = props => {
+const PlainIcon: React.SFC<IconProps> = props => {
const iconInfo = ICONS[props.icon];
-
return (
- <svg
- width={props.width}
- height={props.height}
- viewBox={iconInfo.viewBox}
- fill="none"
- xmlns="http://www.w3.org/2000/svg"
- >
- <path
- d={iconInfo.path}
- fill={props.color}
- fillRule={iconInfo.fillRule || 'nonzero'}
- clipRule={iconInfo.clipRule || 'nonzero'}
- stroke={iconInfo.stroke}
- strokeOpacity={iconInfo.strokeOpacity}
- strokeWidth={iconInfo.strokeWidth}
- strokeLinecap={iconInfo.strokeLinecap}
- strokeLinejoin={iconInfo.strokeLinejoin}
- />
- </svg>
+ <div onClick={props.onClick} className={props.className}>
+ <svg
+ width={props.width}
+ height={props.height}
+ viewBox={iconInfo.viewBox}
+ fill="none"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d={iconInfo.path}
+ fill={props.color}
+ fillRule={iconInfo.fillRule || 'nonzero'}
+ clipRule={iconInfo.clipRule || 'nonzero'}
+ stroke={iconInfo.stroke}
+ strokeOpacity={iconInfo.strokeOpacity}
+ strokeWidth={iconInfo.strokeWidth}
+ strokeLinecap={iconInfo.strokeLinecap}
+ strokeLinejoin={iconInfo.strokeLinejoin}
+ />
+ </svg>
+ </div>
);
};
+
+export const Icon = styled(PlainIcon)`
+ cursor: ${props => (!_.isUndefined(props.onClick) ? 'pointer' : 'default')};
+ transition: opacity 0.5s ease;
+ padding: ${props => props.padding};
+ opacity: ${props => (!_.isUndefined(props.onClick) ? 0.7 : 1)};
+ &:hover {
+ opacity: 1;
+ }
+ &:active {
+ opacity: 1;
+ }
+`;
+
+Icon.defaultProps = {
+ padding: '0em 0em',
+};
+
+Icon.displayName = 'Icon';
diff --git a/packages/instant/src/components/ui/index.ts b/packages/instant/src/components/ui/index.ts
index 28f76c262..0efabdb85 100644
--- a/packages/instant/src/components/ui/index.ts
+++ b/packages/instant/src/components/ui/index.ts
@@ -1,7 +1,8 @@
-export { Text, Title } from './text';
+export { Text, TextProps, Title } from './text';
export { Button, ButtonProps } from './button';
export { Flex, FlexProps } from './flex';
export { Container, ContainerProps } from './container';
export { Input, InputProps } from './input';
export { Icon, IconProps } from './icon';
export { Spinner, SpinnerProps } from './spinner';
+export { Overlay, OverlayProps } from './overlay';
diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx
new file mode 100644
index 000000000..c5258b031
--- /dev/null
+++ b/packages/instant/src/components/ui/overlay.tsx
@@ -0,0 +1,38 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { overlayBlack, styled } from '../../style/theme';
+
+import { Container } from './container';
+import { Flex } from './flex';
+import { Icon } from './icon';
+
+export interface OverlayProps {
+ className?: string;
+ onClose?: () => void;
+ zIndex?: number;
+}
+
+const PlainOverlay: React.StatelessComponent<OverlayProps> = ({ children, className, onClose }) => (
+ <Flex height="100vh" className={className}>
+ <Container position="absolute" top="0px" right="0px">
+ <Icon height={18} width={18} color="white" icon="closeX" onClick={onClose} padding="2em 2em" />
+ </Container>
+ <div>{children}</div>
+ </Flex>
+);
+export const Overlay = styled(PlainOverlay)`
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: ${props => props.zIndex}
+ background-color: ${overlayBlack};
+`;
+
+Overlay.defaultProps = {
+ zIndex: 100,
+};
+
+Overlay.displayName = 'Overlay';
diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx
index f3b212058..907c42e7a 100644
--- a/packages/instant/src/components/zero_ex_instant.tsx
+++ b/packages/instant/src/components/zero_ex_instant.tsx
@@ -1,127 +1,14 @@
-import { AssetBuyer } from '@0x/asset-buyer';
-import { ObjectMap, SignedOrder } from '@0x/types';
-import * as _ from 'lodash';
import * as React from 'react';
-import { Provider } from 'react-redux';
-
-import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider';
-import { asyncData } from '../redux/async_data';
-import { INITIAL_STATE, State } from '../redux/reducer';
-import { store, Store } from '../redux/store';
-import { fonts } from '../style/fonts';
-import { AssetMetaData, Network } from '../types';
-import { assetUtils } from '../util/asset';
-import { BigNumberInput } from '../util/big_number_input';
-import { errorFlasher } from '../util/error_flasher';
-import { gasPriceEstimator } from '../util/gas_price_estimator';
-import { getProvider } from '../util/provider';
-import { web3Wrapper } from '../util/web3_wrapper';
import { ZeroExInstantContainer } from './zero_ex_instant_container';
+import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
-fonts.include();
-
-export type ZeroExInstantProps = ZeroExInstantRequiredProps & Partial<ZeroExInstantOptionalProps>;
-
-export interface ZeroExInstantRequiredProps {
- orderSource: string | SignedOrder[];
-}
-
-export interface ZeroExInstantOptionalProps {
- availableAssetDatas: string[];
- defaultAssetBuyAmount: number;
- defaultSelectedAssetData: string;
- additionalAssetMetaDataMap: ObjectMap<AssetMetaData>;
- networkId: Network;
-}
-
-export class ZeroExInstant extends React.Component<ZeroExInstantProps> {
- private readonly _store: Store;
- // TODO(fragosti): Write tests for this beast once we inject a provider.
- private static _mergeInitialStateWithProps(props: ZeroExInstantProps, state: State = INITIAL_STATE): State {
- const networkId = props.networkId || state.network;
- // TODO: Provider needs to not be hard-coded to injected web3.
- const provider = getProvider();
- const assetBuyerOptions = {
- networkId,
- };
- let assetBuyer;
- if (_.isString(props.orderSource)) {
- assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(
- provider,
- props.orderSource,
- assetBuyerOptions,
- );
- } else {
- assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.orderSource, assetBuyerOptions);
- }
- const completeAssetMetaDataMap = {
- ...props.additionalAssetMetaDataMap,
- ...state.assetMetaDataMap,
- };
- const storeStateFromProps: State = {
- ...state,
- assetBuyer,
- network: networkId,
- selectedAsset: _.isUndefined(props.defaultSelectedAssetData)
- ? undefined
- : assetUtils.createAssetFromAssetDataOrThrow(
- props.defaultSelectedAssetData,
- completeAssetMetaDataMap,
- networkId,
- ),
- selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount)
- ? state.selectedAssetAmount
- : new BigNumberInput(props.defaultAssetBuyAmount),
- availableAssets: _.isUndefined(props.availableAssetDatas)
- ? undefined
- : assetUtils.createAssetsFromAssetDatas(props.availableAssetDatas, completeAssetMetaDataMap, networkId),
- assetMetaDataMap: completeAssetMetaDataMap,
- };
- return storeStateFromProps;
- }
- constructor(props: ZeroExInstantProps) {
- super(props);
- const initialAppState = ZeroExInstant._mergeInitialStateWithProps(this.props, INITIAL_STATE);
- this._store = store.create(initialAppState);
- }
-
- public componentDidMount(): void {
- const state = this._store.getState();
- // tslint:disable-next-line:no-floating-promises
- asyncData.fetchEthPriceAndDispatchToStore(this._store);
- // fetch available assets if none are specified
- if (_.isUndefined(state.availableAssets)) {
- // tslint:disable-next-line:no-floating-promises
- asyncData.fetchAvailableAssetDatasAndDispatchToStore(this._store);
- }
-
- // warm up the gas price estimator cache just in case we can't
- // grab the gas price estimate when submitting the transaction
- // tslint:disable-next-line:no-floating-promises
- gasPriceEstimator.getFastAmountInWeiAsync();
-
- // tslint:disable-next-line:no-floating-promises
- this._flashErrorIfWrongNetwork();
- }
-
- public render(): React.ReactNode {
- return (
- <Provider store={this._store}>
- <SelectedAssetThemeProvider>
- <ZeroExInstantContainer />
- </SelectedAssetThemeProvider>
- </Provider>
- );
- }
+export type ZeroExInstantProps = ZeroExInstantProviderProps;
- private readonly _flashErrorIfWrongNetwork = async (): Promise<void> => {
- const msToShowError = 30000; // 30 seconds
- const network = this._store.getState().network;
- const networkOfProvider = await web3Wrapper.getNetworkIdAsync();
- if (network !== networkOfProvider) {
- const errorMessage = `Wrong network detected. Try switching to ${Network[network]}.`;
- errorFlasher.flashNewErrorMessage(this._store.dispatch, errorMessage, msToShowError);
- }
- };
-}
+export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = props => {
+ return (
+ <ZeroExInstantProvider {...props}>
+ <ZeroExInstantContainer />
+ </ZeroExInstantProvider>
+ );
+};
diff --git a/packages/instant/src/components/zero_ex_instant_overlay.tsx b/packages/instant/src/components/zero_ex_instant_overlay.tsx
new file mode 100644
index 000000000..8f872f896
--- /dev/null
+++ b/packages/instant/src/components/zero_ex_instant_overlay.tsx
@@ -0,0 +1,21 @@
+import * as React from 'react';
+
+import { Overlay } from './ui';
+import { ZeroExInstantContainer } from './zero_ex_instant_container';
+import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
+
+export interface ZeroExInstantOverlayProps extends ZeroExInstantProviderProps {
+ onClose?: () => void;
+ zIndex?: number;
+}
+
+export const ZeroExInstantOverlay: React.StatelessComponent<ZeroExInstantOverlayProps> = props => {
+ const { onClose, zIndex, ...rest } = props;
+ return (
+ <ZeroExInstantProvider {...rest}>
+ <Overlay onClose={onClose} zIndex={zIndex}>
+ <ZeroExInstantContainer />
+ </Overlay>
+ </ZeroExInstantProvider>
+ );
+};
diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx
new file mode 100644
index 000000000..8552a7fb5
--- /dev/null
+++ b/packages/instant/src/components/zero_ex_instant_provider.tsx
@@ -0,0 +1,126 @@
+import { AssetBuyer } from '@0x/asset-buyer';
+import { ObjectMap, SignedOrder } from '@0x/types';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { Provider } from 'react-redux';
+
+import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider';
+import { asyncData } from '../redux/async_data';
+import { INITIAL_STATE, State } from '../redux/reducer';
+import { store, Store } from '../redux/store';
+import { fonts } from '../style/fonts';
+import { AssetMetaData, Network } from '../types';
+import { assetUtils } from '../util/asset';
+import { BigNumberInput } from '../util/big_number_input';
+import { errorFlasher } from '../util/error_flasher';
+import { gasPriceEstimator } from '../util/gas_price_estimator';
+import { getProvider } from '../util/provider';
+import { web3Wrapper } from '../util/web3_wrapper';
+
+import { ZeroExInstantContainer } from './zero_ex_instant_container';
+
+fonts.include();
+
+export type ZeroExInstantProviderProps = ZeroExInstantProviderRequiredProps &
+ Partial<ZeroExInstantProviderOptionalProps>;
+
+export interface ZeroExInstantProviderRequiredProps {
+ orderSource: string | SignedOrder[];
+}
+
+export interface ZeroExInstantProviderOptionalProps {
+ availableAssetDatas: string[];
+ defaultAssetBuyAmount: number;
+ defaultSelectedAssetData: string;
+ additionalAssetMetaDataMap: ObjectMap<AssetMetaData>;
+ networkId: Network;
+}
+
+export class ZeroExInstantProvider extends React.Component<ZeroExInstantProviderProps> {
+ private readonly _store: Store;
+ // TODO(fragosti): Write tests for this beast once we inject a provider.
+ private static _mergeInitialStateWithProps(props: ZeroExInstantProviderProps, state: State = INITIAL_STATE): State {
+ const networkId = props.networkId || state.network;
+ // TODO: Provider needs to not be hard-coded to injected web3.
+ const provider = getProvider();
+ const assetBuyerOptions = {
+ networkId,
+ };
+ let assetBuyer;
+ if (_.isString(props.orderSource)) {
+ assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(
+ provider,
+ props.orderSource,
+ assetBuyerOptions,
+ );
+ } else {
+ assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.orderSource, assetBuyerOptions);
+ }
+ const completeAssetMetaDataMap = {
+ ...props.additionalAssetMetaDataMap,
+ ...state.assetMetaDataMap,
+ };
+ const storeStateFromProps: State = {
+ ...state,
+ assetBuyer,
+ network: networkId,
+ selectedAsset: _.isUndefined(props.defaultSelectedAssetData)
+ ? undefined
+ : assetUtils.createAssetFromAssetDataOrThrow(
+ props.defaultSelectedAssetData,
+ completeAssetMetaDataMap,
+ networkId,
+ ),
+ selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount)
+ ? state.selectedAssetAmount
+ : new BigNumberInput(props.defaultAssetBuyAmount),
+ availableAssets: _.isUndefined(props.availableAssetDatas)
+ ? undefined
+ : assetUtils.createAssetsFromAssetDatas(props.availableAssetDatas, completeAssetMetaDataMap, networkId),
+ assetMetaDataMap: completeAssetMetaDataMap,
+ };
+ return storeStateFromProps;
+ }
+ constructor(props: ZeroExInstantProviderProps) {
+ super(props);
+ const initialAppState = ZeroExInstantProvider._mergeInitialStateWithProps(this.props, INITIAL_STATE);
+ this._store = store.create(initialAppState);
+ }
+
+ public componentDidMount(): void {
+ const state = this._store.getState();
+ // tslint:disable-next-line:no-floating-promises
+ asyncData.fetchEthPriceAndDispatchToStore(this._store);
+ // fetch available assets if none are specified
+ if (_.isUndefined(state.availableAssets)) {
+ // tslint:disable-next-line:no-floating-promises
+ asyncData.fetchAvailableAssetDatasAndDispatchToStore(this._store);
+ }
+
+ // warm up the gas price estimator cache just in case we can't
+ // grab the gas price estimate when submitting the transaction
+ // tslint:disable-next-line:no-floating-promises
+ gasPriceEstimator.getFastAmountInWeiAsync();
+
+ // tslint:disable-next-line:no-floating-promises
+ this._flashErrorIfWrongNetwork();
+ }
+
+ public render(): React.ReactNode {
+ return (
+ <Provider store={this._store}>
+ <SelectedAssetThemeProvider>{this.props.children}</SelectedAssetThemeProvider>
+ </Provider>
+ );
+ }
+
+ private readonly _flashErrorIfWrongNetwork = async (): Promise<void> => {
+ const msToShowError = 30000; // 30 seconds
+ const network = this._store.getState().network;
+ const networkOfProvider = await web3Wrapper.getNetworkIdAsync();
+ if (network !== networkOfProvider) {
+ const errorMessage = `Wrong network detected. Try switching to ${Network[network]}.`;
+ errorFlasher.flashNewErrorMessage(this._store.dispatch, errorMessage, msToShowError);
+ }
+ };
+}
diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts
index 424f35ecb..3e830ba00 100644
--- a/packages/instant/src/constants.ts
+++ b/packages/instant/src/constants.ts
@@ -2,6 +2,7 @@ import { BigNumber } from '@0x/utils';
export const BIG_NUMBER_ZERO = new BigNumber(0);
export const ETH_DECIMALS = 18;
export const DEFAULT_ZERO_EX_CONTAINER_SELECTOR = '#zeroExInstantContainer';
+export const INJECTED_DIV_ID = 'zeroExInstant';
export const WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX = 'Transaction failed';
export const GWEI_IN_WEI = new BigNumber(1000000000);
export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6);
diff --git a/packages/instant/src/data/asset_data_network_mapping.ts b/packages/instant/src/data/asset_data_network_mapping.ts
index 45bfc2a02..a7bc6a967 100644
--- a/packages/instant/src/data/asset_data_network_mapping.ts
+++ b/packages/instant/src/data/asset_data_network_mapping.ts
@@ -56,4 +56,9 @@ export const assetDataNetworkMapping: AssetDataByNetwork[] = [
{
[Network.Mainnet]: '0xf47261b000000000000000000000000008d32b0da63e2C3bcF8019c9c5d849d7a9d791e6',
},
+ // REP
+ {
+ [Network.Kovan]: '0xf47261b00000000000000000000000008cb3971b8eb709c14616bd556ff6683019e90d9c',
+ [Network.Mainnet]: '0xf47261b0000000000000000000000000e94327d07fc17907b4db788e5adf2ed424addff6',
+ },
];
diff --git a/packages/instant/src/data/asset_meta_data_map.ts b/packages/instant/src/data/asset_meta_data_map.ts
index d77298d78..d7cf2c0d8 100644
--- a/packages/instant/src/data/asset_meta_data_map.ts
+++ b/packages/instant/src/data/asset_meta_data_map.ts
@@ -65,4 +65,10 @@ export const assetMetaDataMap: ObjectMap<AssetMetaData> = {
primaryColor: '#000',
symbol: 'dentacoin',
},
+ '0xf47261b0000000000000000000000000e94327d07fc17907b4db788e5adf2ed424addff6': {
+ assetProxyId: AssetProxyId.ERC20,
+ decimals: 18,
+ primaryColor: '#512D80',
+ symbol: 'rep',
+ },
};
diff --git a/packages/instant/src/index.ts b/packages/instant/src/index.ts
index 54059cdad..6e611dae8 100644
--- a/packages/instant/src/index.ts
+++ b/packages/instant/src/index.ts
@@ -1 +1,2 @@
export { ZeroExInstant, ZeroExInstantProps } from './components/zero_ex_instant';
+export { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './components/zero_ex_instant_overlay';
diff --git a/packages/instant/src/index.umd.ts b/packages/instant/src/index.umd.ts
index b998abe95..81d59e092 100644
--- a/packages/instant/src/index.umd.ts
+++ b/packages/instant/src/index.umd.ts
@@ -2,26 +2,47 @@ import * as _ from 'lodash';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
-import { DEFAULT_ZERO_EX_CONTAINER_SELECTOR } from './constants';
-import { ZeroExInstant, ZeroExInstantProps } from './index';
+import { DEFAULT_ZERO_EX_CONTAINER_SELECTOR, INJECTED_DIV_ID } from './constants';
+import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index';
import { assert } from './util/assert';
-export const render = (props: ZeroExInstantProps, selector: string = DEFAULT_ZERO_EX_CONTAINER_SELECTOR) => {
+export const render = (props: ZeroExInstantOverlayProps, selector: string = DEFAULT_ZERO_EX_CONTAINER_SELECTOR) => {
assert.isValidOrderSource('orderSource', props.orderSource);
if (!_.isUndefined(props.defaultSelectedAssetData)) {
assert.isHexString('defaultSelectedAssetData', props.defaultSelectedAssetData);
}
if (!_.isUndefined(props.additionalAssetMetaDataMap)) {
- assert.isValidAssetMetaDataMap('additionalAssetMetaDataMap', props.additionalAssetMetaDataMap);
+ assert.isValidAssetMetaDataMap('props.additionalAssetMetaDataMap', props.additionalAssetMetaDataMap);
}
if (!_.isUndefined(props.defaultAssetBuyAmount)) {
- assert.isNumber('defaultAssetBuyAmount', props.defaultAssetBuyAmount);
+ assert.isNumber('props.defaultAssetBuyAmount', props.defaultAssetBuyAmount);
}
if (!_.isUndefined(props.networkId)) {
- assert.isNumber('networkId', props.networkId);
+ assert.isNumber('props.networkId', props.networkId);
}
if (!_.isUndefined(props.availableAssetDatas)) {
assert.areValidAssetDatas('availableAssetDatas', props.availableAssetDatas);
}
- ReactDOM.render(React.createElement(ZeroExInstant, props), document.querySelector(selector));
+ if (!_.isUndefined(props.onClose)) {
+ assert.isFunction('props.onClose', props.onClose);
+ }
+ if (!_.isUndefined(props.zIndex)) {
+ assert.isNumber('props.zIndex', props.zIndex);
+ }
+ const appendToIfExists = document.querySelector(selector);
+ assert.assert(!_.isNull(appendToIfExists), `Could not find div with selector: ${selector}`);
+ const appendTo = appendToIfExists as Element;
+ const injectedDiv = document.createElement('div');
+ injectedDiv.setAttribute('id', INJECTED_DIV_ID);
+ appendTo.appendChild(injectedDiv);
+ const instantOverlayProps = {
+ ...props,
+ onClose: () => {
+ appendTo.removeChild(injectedDiv);
+ if (!_.isUndefined(props.onClose)) {
+ props.onClose();
+ }
+ },
+ };
+ ReactDOM.render(React.createElement(ZeroExInstantOverlay, instantOverlayProps), injectedDiv);
};
diff --git a/packages/instant/src/style/theme.ts b/packages/instant/src/style/theme.ts
index 6575ff9f4..e81694620 100644
--- a/packages/instant/src/style/theme.ts
+++ b/packages/instant/src/style/theme.ts
@@ -29,5 +29,6 @@ export const theme: Theme = {
};
export const transparentWhite = 'rgba(255,255,255,0.3)';
+export const overlayBlack = 'rgba(0, 0, 0, 0.6)';
export { styled, css, keyframes, ThemeProvider };