aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/containers/selected_erc20_asset_amount_input.ts
diff options
context:
space:
mode:
authorSteve Klebanoff <steve.klebanoff@gmail.com>2018-10-27 03:47:24 +0800
committerSteve Klebanoff <steve.klebanoff@gmail.com>2018-10-27 03:47:24 +0800
commit9be4c4749935a765cbd55783735d1d1f719322c0 (patch)
tree49c3f3f42e58b49547799e6dfadc1b10c82381db /packages/instant/src/containers/selected_erc20_asset_amount_input.ts
parent9512978de9aee1953930d4f16a105ec5ef7f048e (diff)
parentaf91a56a5594d07d7da6caaeff79f5a7fb31ff98 (diff)
downloaddexon-sol-tools-9be4c4749935a765cbd55783735d1d1f719322c0.tar
dexon-sol-tools-9be4c4749935a765cbd55783735d1d1f719322c0.tar.gz
dexon-sol-tools-9be4c4749935a765cbd55783735d1d1f719322c0.tar.bz2
dexon-sol-tools-9be4c4749935a765cbd55783735d1d1f719322c0.tar.lz
dexon-sol-tools-9be4c4749935a765cbd55783735d1d1f719322c0.tar.xz
dexon-sol-tools-9be4c4749935a765cbd55783735d1d1f719322c0.tar.zst
dexon-sol-tools-9be4c4749935a765cbd55783735d1d1f719322c0.zip
Merge branch 'development' into feature/not-enough-eth
Diffstat (limited to 'packages/instant/src/containers/selected_erc20_asset_amount_input.ts')
-rw-r--r--packages/instant/src/containers/selected_erc20_asset_amount_input.ts135
1 files changed, 135 insertions, 0 deletions
diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts
new file mode 100644
index 000000000..67c3ce6a5
--- /dev/null
+++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts
@@ -0,0 +1,135 @@
+import { AssetBuyer, BuyQuote } from '@0x/asset-buyer';
+import { AssetProxyId } from '@0x/types';
+import { BigNumber } from '@0x/utils';
+import { Web3Wrapper } from '@0x/web3-wrapper';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { connect } from 'react-redux';
+import { Dispatch } from 'redux';
+
+import { Action, actions } from '../redux/actions';
+import { State } from '../redux/reducer';
+import { ColorOption } from '../style/theme';
+import { getBestAddress } from '../util/address';
+import { BigNumberInput } from '../util/big_number_input';
+import { errorUtil } from '../util/error';
+import { web3Wrapper } from '../util/web3_wrapper';
+
+import { ERC20AssetAmountInput } from '../components/erc20_asset_amount_input';
+
+import { ERC20Asset, OrderProcessState, ZeroExInstantError } from '../types';
+
+export interface SelectedERC20AssetAmountInputProps {
+ fontColor?: ColorOption;
+ startingFontSizePx: number;
+}
+
+interface ConnectedState {
+ assetBuyer?: AssetBuyer;
+ value?: BigNumberInput;
+ asset?: ERC20Asset;
+}
+
+interface ConnectedDispatch {
+ updateBuyQuote: (assetBuyer?: AssetBuyer, value?: BigNumberInput, asset?: ERC20Asset) => void;
+}
+
+interface ConnectedProps {
+ value?: BigNumberInput;
+ asset?: ERC20Asset;
+ onChange: (value?: BigNumberInput, asset?: ERC20Asset) => void;
+}
+
+type FinalProps = ConnectedProps & SelectedERC20AssetAmountInputProps;
+
+const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputProps): ConnectedState => {
+ const selectedAsset = state.selectedAsset;
+ if (_.isUndefined(selectedAsset) || selectedAsset.metaData.assetProxyId !== AssetProxyId.ERC20) {
+ return {
+ value: state.selectedAssetAmount,
+ };
+ }
+ return {
+ assetBuyer: state.assetBuyer,
+ value: state.selectedAssetAmount,
+ asset: selectedAsset as ERC20Asset,
+ };
+};
+
+const updateBuyQuoteAsync = async (
+ assetBuyer: AssetBuyer,
+ dispatch: Dispatch<Action>,
+ asset: ERC20Asset,
+ assetAmount: BigNumber,
+): Promise<void> => {
+ // get a new buy quote.
+ const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, asset.metaData.decimals);
+
+ // mark quote as pending
+ dispatch(actions.setQuoteRequestStatePending());
+
+ let newBuyQuote: BuyQuote | undefined;
+ try {
+ newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue);
+ } catch (error) {
+ dispatch(actions.setQuoteRequestStateFailure());
+ errorUtil.errorFlasher.flashNewError(dispatch, error);
+ return;
+ }
+ // We have a successful new buy quote
+ errorUtil.errorFlasher.clearError(dispatch);
+ // invalidate the last buy quote.
+ dispatch(actions.updateLatestBuyQuote(newBuyQuote));
+
+ // set error if user doesn't have appropriate balance
+ const takerAddress = await getBestAddress();
+ const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
+ if (balanceWei < newBuyQuote.worstCaseQuoteInfo.totalEthAmount) {
+ const balanceError = new Error(ZeroExInstantError.InsufficientBalance);
+ errorUtil.errorFlasher.flashNewError(dispatch, balanceError);
+ }
+};
+
+const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true });
+
+const mapDispatchToProps = (
+ dispatch: Dispatch<Action>,
+ _ownProps: SelectedERC20AssetAmountInputProps,
+): ConnectedDispatch => ({
+ updateBuyQuote: (assetBuyer, value, asset) => {
+ // Update the input
+ dispatch(actions.updateSelectedAssetAmount(value));
+ // invalidate the last buy quote.
+ dispatch(actions.updateLatestBuyQuote(undefined));
+ // reset our buy state
+ dispatch(actions.updateBuyOrderState({ processState: OrderProcessState.NONE }));
+
+ if (!_.isUndefined(value) && !_.isUndefined(asset) && !_.isUndefined(assetBuyer)) {
+ // even if it's debounced, give them the illusion it's loading
+ dispatch(actions.setQuoteRequestStatePending());
+ // tslint:disable-next-line:no-floating-promises
+ debouncedUpdateBuyQuoteAsync(assetBuyer, dispatch, asset, value);
+ }
+ },
+});
+
+const mergeProps = (
+ connectedState: ConnectedState,
+ connectedDispatch: ConnectedDispatch,
+ ownProps: SelectedERC20AssetAmountInputProps,
+): FinalProps => {
+ return {
+ ...ownProps,
+ asset: connectedState.asset,
+ value: connectedState.value,
+ onChange: (value, asset) => {
+ connectedDispatch.updateBuyQuote(connectedState.assetBuyer, value, asset);
+ },
+ };
+};
+
+export const SelectedERC20AssetAmountInput: React.ComponentClass<SelectedERC20AssetAmountInputProps> = connect(
+ mapStateToProps,
+ mapDispatchToProps,
+ mergeProps,
+)(ERC20AssetAmountInput);