aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/components
diff options
context:
space:
mode:
authorBrandon Millman <brandon@0xproject.com>2018-11-08 15:40:43 +0800
committerGitHub <noreply@github.com>2018-11-08 15:40:43 +0800
commitf6abc007ffb249e4bbf85b8a7a77309d43e0a147 (patch)
tree0bf9d75eed4bc60d37b7aed47be6adc2b4551a40 /packages/instant/src/components
parent771f8a6a6cff935631e8c6ebcdc012cdd3533de6 (diff)
parent54b51830d075fcfc9b9e3ce0f4f4a4ef26eaf036 (diff)
downloaddexon-0x-contracts-f6abc007ffb249e4bbf85b8a7a77309d43e0a147.tar.gz
dexon-0x-contracts-f6abc007ffb249e4bbf85b8a7a77309d43e0a147.tar.zst
dexon-0x-contracts-f6abc007ffb249e4bbf85b8a7a77309d43e0a147.zip
Merge pull request #1221 from 0xProject/feature/instant/fallback-provider
[instant] Ensure we always have a provider from initial state
Diffstat (limited to 'packages/instant/src/components')
-rw-r--r--packages/instant/src/components/buy_button.tsx8
-rw-r--r--packages/instant/src/components/buy_order_progress.tsx8
-rw-r--r--packages/instant/src/components/buy_order_state_buttons.tsx10
-rw-r--r--packages/instant/src/components/instant_heading.tsx14
-rw-r--r--packages/instant/src/components/zero_ex_instant_provider.tsx72
5 files changed, 51 insertions, 61 deletions
diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx
index e6d50de96..515cd18e9 100644
--- a/packages/instant/src/components/buy_button.tsx
+++ b/packages/instant/src/components/buy_button.tsx
@@ -17,7 +17,7 @@ import { Text } from './ui/text';
export interface BuyButtonProps {
buyQuote?: BuyQuote;
- assetBuyer?: AssetBuyer;
+ assetBuyer: AssetBuyer;
affiliateInfo?: AffiliateInfo;
onValidationPending: (buyQuote: BuyQuote) => void;
onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void;
@@ -34,7 +34,7 @@ export class BuyButton extends React.Component<BuyButtonProps> {
onBuyFailure: util.boundNoop,
};
public render(): React.ReactNode {
- const shouldDisableButton = _.isUndefined(this.props.buyQuote) || _.isUndefined(this.props.assetBuyer);
+ const shouldDisableButton = _.isUndefined(this.props.buyQuote);
return (
<Button width="100%" onClick={this._handleClick} isDisabled={shouldDisableButton}>
<Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px">
@@ -46,11 +46,13 @@ export class BuyButton extends React.Component<BuyButtonProps> {
private readonly _handleClick = async () => {
// The button is disabled when there is no buy quote anyway.
const { buyQuote, assetBuyer, affiliateInfo } = this.props;
- if (_.isUndefined(buyQuote) || _.isUndefined(assetBuyer)) {
+ if (_.isUndefined(buyQuote)) {
return;
}
this.props.onValidationPending(buyQuote);
+
+ // TODO(bmillman): move address and balance fetching to the async state
const web3Wrapper = new Web3Wrapper(assetBuyer.provider);
const takerAddress = await getBestAddress(web3Wrapper);
diff --git a/packages/instant/src/components/buy_order_progress.tsx b/packages/instant/src/components/buy_order_progress.tsx
index 7fe4e77e9..bc7319423 100644
--- a/packages/instant/src/components/buy_order_progress.tsx
+++ b/packages/instant/src/components/buy_order_progress.tsx
@@ -14,12 +14,12 @@ export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> =
const { buyOrderState } = props;
if (
- buyOrderState.processState === OrderProcessState.PROCESSING ||
- buyOrderState.processState === OrderProcessState.SUCCESS ||
- buyOrderState.processState === OrderProcessState.FAILURE
+ buyOrderState.processState === OrderProcessState.Processing ||
+ buyOrderState.processState === OrderProcessState.Success ||
+ buyOrderState.processState === OrderProcessState.Failure
) {
const progress = buyOrderState.progress;
- const hasEnded = buyOrderState.processState !== OrderProcessState.PROCESSING;
+ const hasEnded = buyOrderState.processState !== OrderProcessState.Processing;
const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix;
return (
<Container padding="20px 20px 0px 20px" width="100%">
diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx
index 0d54d3187..3d0ede7b1 100644
--- a/packages/instant/src/components/buy_order_state_buttons.tsx
+++ b/packages/instant/src/components/buy_order_state_buttons.tsx
@@ -15,7 +15,7 @@ import { Text } from './ui/text';
export interface BuyOrderStateButtonProps {
buyQuote?: BuyQuote;
buyOrderProcessingState: OrderProcessState;
- assetBuyer?: AssetBuyer;
+ assetBuyer: AssetBuyer;
affiliateInfo?: AffiliateInfo;
onViewTransaction: () => void;
onValidationPending: (buyQuote: BuyQuote) => void;
@@ -28,7 +28,7 @@ export interface BuyOrderStateButtonProps {
}
export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonProps> = props => {
- if (props.buyOrderProcessingState === OrderProcessState.FAILURE) {
+ if (props.buyOrderProcessingState === OrderProcessState.Failure) {
return (
<Flex justify="space-between">
<Button width="48%" onClick={props.onRetry}>
@@ -42,11 +42,11 @@ export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonP
</Flex>
);
} else if (
- props.buyOrderProcessingState === OrderProcessState.SUCCESS ||
- props.buyOrderProcessingState === OrderProcessState.PROCESSING
+ props.buyOrderProcessingState === OrderProcessState.Success ||
+ props.buyOrderProcessingState === OrderProcessState.Processing
) {
return <SecondaryButton onClick={props.onViewTransaction}>View Transaction</SecondaryButton>;
- } else if (props.buyOrderProcessingState === OrderProcessState.VALIDATING) {
+ } else if (props.buyOrderProcessingState === OrderProcessState.Validating) {
return <PlacingOrderButton />;
}
diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx
index 6d87bc292..b07776b2c 100644
--- a/packages/instant/src/components/instant_heading.tsx
+++ b/packages/instant/src/components/instant_heading.tsx
@@ -77,11 +77,11 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> {
private _renderIcon(): React.ReactNode {
const processState = this.props.buyOrderState.processState;
- if (processState === OrderProcessState.FAILURE) {
+ if (processState === OrderProcessState.Failure) {
return <Icon icon="failed" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />;
- } else if (processState === OrderProcessState.PROCESSING) {
+ } else if (processState === OrderProcessState.Processing) {
return <Spinner widthPx={ICON_HEIGHT} heightPx={ICON_HEIGHT} />;
- } else if (processState === OrderProcessState.SUCCESS) {
+ } else if (processState === OrderProcessState.Success) {
return <Icon icon="success" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />;
}
return undefined;
@@ -89,11 +89,11 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> {
private _renderTopText(): React.ReactNode {
const processState = this.props.buyOrderState.processState;
- if (processState === OrderProcessState.FAILURE) {
+ if (processState === OrderProcessState.Failure) {
return 'Order failed';
- } else if (processState === OrderProcessState.PROCESSING) {
+ } else if (processState === OrderProcessState.Processing) {
return 'Processing Order...';
- } else if (processState === OrderProcessState.SUCCESS) {
+ } else if (processState === OrderProcessState.Success) {
return 'Tokens received!';
}
@@ -101,7 +101,7 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> {
}
private _renderPlaceholderOrAmount(amountFunction: () => React.ReactNode): React.ReactNode {
- if (this.props.quoteRequestState === AsyncProcessState.PENDING) {
+ if (this.props.quoteRequestState === AsyncProcessState.Pending) {
return <AmountPlaceholder isPulsating={true} color={PLACEHOLDER_COLOR} />;
}
if (_.isUndefined(this.props.selectedAssetAmount)) {
diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx
index 0b9408329..1fb5cf64f 100644
--- a/packages/instant/src/components/zero_ex_instant_provider.tsx
+++ b/packages/instant/src/components/zero_ex_instant_provider.tsx
@@ -1,23 +1,20 @@
-import { AssetBuyer } from '@0x/asset-buyer';
-import { ObjectMap, SignedOrder } from '@0x/types';
+import { ObjectMap } from '@0x/types';
import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
import { Provider } from 'ethereum-types';
import * as _ from 'lodash';
import * as React from 'react';
import { Provider as ReduxProvider } from 'react-redux';
-import { oc } from 'ts-optchain';
import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider';
import { asyncData } from '../redux/async_data';
-import { INITIAL_STATE, State } from '../redux/reducer';
+import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer';
import { store, Store } from '../redux/store';
import { fonts } from '../style/fonts';
-import { AffiliateInfo, AssetMetaData, Network } from '../types';
+import { AffiliateInfo, AssetMetaData, Network, OrderSource } from '../types';
import { assetUtils } from '../util/asset';
import { errorFlasher } from '../util/error_flasher';
import { gasPriceEstimator } from '../util/gas_price_estimator';
-import { getInjectedProvider } from '../util/injected_provider';
+import { providerStateFactory } from '../util/provider_state_factory';
fonts.include();
@@ -25,7 +22,7 @@ export type ZeroExInstantProviderProps = ZeroExInstantProviderRequiredProps &
Partial<ZeroExInstantProviderOptionalProps>;
export interface ZeroExInstantProviderRequiredProps {
- orderSource: string | SignedOrder[];
+ orderSource: OrderSource;
}
export interface ZeroExInstantProviderOptionalProps {
@@ -41,30 +38,27 @@ export interface ZeroExInstantProviderOptionalProps {
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: Proper wallet connect flow
- const provider = props.provider || getInjectedProvider();
- const assetBuyerOptions = {
+ private static _mergeDefaultStateWithProps(
+ props: ZeroExInstantProviderProps,
+ defaultState: DefaultState = DEFAULT_STATE,
+ ): State {
+ // use the networkId passed in with the props, otherwise default to that of the default state (1, mainnet)
+ const networkId = props.networkId || defaultState.network;
+ // construct the ProviderState
+ const providerState = providerStateFactory.getInitialProviderState(
+ props.orderSource,
networkId,
- };
- let assetBuyer;
- if (_.isString(props.orderSource)) {
- assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(
- provider,
- props.orderSource,
- assetBuyerOptions,
- );
- } else {
- assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.orderSource, assetBuyerOptions);
- }
+ props.provider,
+ );
+ // merge the additional additionalAssetMetaDataMap with our default map
const completeAssetMetaDataMap = {
...props.additionalAssetMetaDataMap,
- ...state.assetMetaDataMap,
+ ...defaultState.assetMetaDataMap,
};
+ // construct the final state
const storeStateFromProps: State = {
- ...state,
- assetBuyer,
+ ...defaultState,
+ providerState,
network: networkId,
selectedAsset: _.isUndefined(props.defaultSelectedAssetData)
? undefined
@@ -74,7 +68,7 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
networkId,
),
selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount)
- ? state.selectedAssetAmount
+ ? undefined
: new BigNumber(props.defaultAssetBuyAmount),
availableAssets: _.isUndefined(props.availableAssetDatas)
? undefined
@@ -86,10 +80,9 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
}
constructor(props: ZeroExInstantProviderProps) {
super(props);
- const initialAppState = ZeroExInstantProvider._mergeInitialStateWithProps(this.props, INITIAL_STATE);
+ const initialAppState = ZeroExInstantProvider._mergeDefaultStateWithProps(this.props);
this._store = store.create(initialAppState);
}
-
public componentDidMount(): void {
const state = this._store.getState();
// tslint:disable-next-line:no-floating-promises
@@ -108,7 +101,6 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
// tslint:disable-next-line:no-floating-promises
this._flashErrorIfWrongNetwork();
}
-
public render(): React.ReactNode {
return (
<ReduxProvider store={this._store}>
@@ -116,19 +108,15 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
</ReduxProvider>
);
}
-
private readonly _flashErrorIfWrongNetwork = async (): Promise<void> => {
const msToShowError = 30000; // 30 seconds
- const network = this._store.getState().network;
- const assetBuyerIfExists = this._store.getState().assetBuyer;
- const providerIfExists = oc(assetBuyerIfExists).provider();
- if (!_.isUndefined(providerIfExists)) {
- const web3Wrapper = new Web3Wrapper(providerIfExists);
- 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);
- }
+ const state = this._store.getState();
+ const network = state.network;
+ const web3Wrapper = state.providerState.web3Wrapper;
+ 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);
}
};
}