Merge pull request #1188 from 0xProject/fix/instant/quote-race-conditions
[instant] Make sure quote updates are consistent with the current state
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { AssetBuyer, BuyQuote } from '@0x/asset-buyer';
|
import { AssetBuyer, BuyQuote } from '@0x/asset-buyer';
|
||||||
import { ObjectMap } from '@0x/types';
|
import { AssetProxyId, ObjectMap } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { assetMetaDataMap } from '../data/asset_meta_data_map';
|
import { assetMetaDataMap } from '../data/asset_meta_data_map';
|
||||||
@@ -57,11 +58,19 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State =>
|
|||||||
selectedAssetAmount: action.data,
|
selectedAssetAmount: action.data,
|
||||||
};
|
};
|
||||||
case ActionTypes.UPDATE_LATEST_BUY_QUOTE:
|
case ActionTypes.UPDATE_LATEST_BUY_QUOTE:
|
||||||
return {
|
const newBuyQuoteIfExists = action.data;
|
||||||
...state,
|
const shouldUpdate =
|
||||||
latestBuyQuote: action.data,
|
_.isUndefined(newBuyQuoteIfExists) || doesBuyQuoteMatchState(newBuyQuoteIfExists, state);
|
||||||
quoteRequestState: AsyncProcessState.SUCCESS,
|
if (shouldUpdate) {
|
||||||
};
|
return {
|
||||||
|
...state,
|
||||||
|
latestBuyQuote: newBuyQuoteIfExists,
|
||||||
|
quoteRequestState: AsyncProcessState.SUCCESS,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
case ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING:
|
case ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -122,3 +131,29 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State =>
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const doesBuyQuoteMatchState = (buyQuote: BuyQuote, state: State): boolean => {
|
||||||
|
const selectedAssetIfExists = state.selectedAsset;
|
||||||
|
const selectedAssetAmountIfExists = state.selectedAssetAmount;
|
||||||
|
// if no selectedAsset or selectedAssetAmount exists on the current state, return false
|
||||||
|
if (_.isUndefined(selectedAssetIfExists) || _.isUndefined(selectedAssetAmountIfExists)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// if buyQuote's assetData does not match that of the current selected asset, return false
|
||||||
|
if (selectedAssetIfExists.assetData !== buyQuote.assetData) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// if ERC20 and buyQuote's assetBuyAmount does not match selectedAssetAmount, return false
|
||||||
|
// if ERC721, return true
|
||||||
|
const selectedAssetMetaData = selectedAssetIfExists.metaData;
|
||||||
|
if (selectedAssetMetaData.assetProxyId === AssetProxyId.ERC20) {
|
||||||
|
const selectedAssetAmountBaseUnits = Web3Wrapper.toBaseUnitAmount(
|
||||||
|
selectedAssetAmountIfExists,
|
||||||
|
selectedAssetMetaData.decimals,
|
||||||
|
);
|
||||||
|
const doesAssetAmountMatch = selectedAssetAmountBaseUnits.eq(buyQuote.assetBuyAmount);
|
||||||
|
return doesAssetAmountMatch;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user