From 4245f24a2e485bd016c8ec9bd14afb17790efdbf Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 4 Nov 2022 11:14:43 -0500 Subject: [PATCH] Fix issue with awaiting swaps page (#16344) * fix issue with awaiting swaps and smart-transaction-status pages when service worker dies --- test/jest/mock-store.js | 73 +++++++++++++++++++ .../confirm-transaction-base.container.js | 12 ++- ui/pages/swaps/awaiting-swap/awaiting-swap.js | 25 ++++--- .../swaps/awaiting-swap/awaiting-swap.test.js | 1 + ui/pages/swaps/index.js | 4 +- .../smart-transaction-status.js | 70 ++++++++++++------ ui/selectors/selectors.js | 25 ++++++- 7 files changed, 171 insertions(+), 39 deletions(-) diff --git a/test/jest/mock-store.js b/test/jest/mock-store.js index 334d3fe85..5d4055628 100644 --- a/test/jest/mock-store.js +++ b/test/jest/mock-store.js @@ -103,6 +103,9 @@ const createGetSmartTransactionFeesApiResponse = () => { export const createSwapsMockStore = () => { return { + confirmTransaction: { + txData: {}, + }, swaps: { customGas: { limit: '0x0', @@ -144,6 +147,76 @@ export const createSwapsMockStore = () => { showFiatInTestnets: true, }, currentCurrency: 'ETH', + currentNetworkTxList: [ + { + id: 6571648590592143, + time: 1667403993369, + status: 'confirmed', + metamaskNetworkId: '5', + originalGasEstimate: '0x7548', + userEditedGasLimit: false, + chainId: '0x5', + loadingDefaults: false, + dappSuggestedGasFees: null, + sendFlowHistory: null, + txParams: { + from: '0x806627172af48bd5b0765d3449a7def80d6576ff', + to: '0x881d40237659c251811cec9c364ef91dc08d300c', + nonce: '0x30', + value: '0x5af3107a4000', + gas: '0x7548', + maxFeePerGas: '0x19286f704d', + maxPriorityFeePerGas: '0x77359400', + }, + origin: 'metamask', + actionId: 1667403993358.877, + type: 'swap', + userFeeLevel: 'medium', + defaultGasEstimates: { + estimateType: 'medium', + gas: '0x7548', + maxFeePerGas: '0x19286f704d', + maxPriorityFeePerGas: '0x77359400', + }, + sourceTokenSymbol: 'ETH', + destinationTokenSymbol: 'USDC', + destinationTokenDecimals: 6, + destinationTokenAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7', + swapMetaData: { + token_from: 'ETH', + token_from_amount: '0.0001', + token_to: 'USDC', + token_to_amount: '0.15471500', + slippage: 2, + custom_slippage: false, + best_quote_source: 'pmm', + other_quote_selected: false, + other_quote_selected_source: '', + gas_fees: '3.016697', + estimated_gas: '30024', + used_gas_price: '0', + is_hardware_wallet: false, + stx_enabled: false, + current_stx_enabled: false, + stx_user_opt_in: false, + reg_tx_fee_in_usd: 3.02, + reg_tx_fee_in_eth: 0.00193, + reg_tx_max_fee_in_usd: 5.06, + reg_tx_max_fee_in_eth: 0.00324, + max_fee_per_gas: '19286f704d', + max_priority_fee_per_gas: '77359400', + base_and_priority_fee_per_gas: 'efd93d95a', + }, + swapTokenValue: '0.0001', + estimatedBaseFee: 'e865e455a', + hash: '0x8216e3696e7deb7ca794703015f17d5114a09362ae98f6a1611203e4c9509243', + submittedTime: 1667403996143, + firstRetryBlockNumber: '0x7838fe', + baseFeePerGas: '0xe0ef7d207', + blockTimestamp: '636290e8', + postTxBalance: '19a61aaaf06e4bd1', + }, + ], conversionRate: 1, contractExchangeRates: { '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 2, diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js index cecc4af26..e59ae735f 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -59,7 +59,10 @@ import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils'; import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app'; import { isLegacyTransaction } from '../../helpers/utils/transactions.util'; import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas'; -import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; +import { + TRANSACTION_STATUSES, + TRANSACTION_TYPES, +} from '../../../shared/constants/transaction'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; import { getTokenAddressParam } from '../../helpers/utils/token-util'; import { calcGasTotal } from '../../../shared/lib/transactions-controller-utils'; @@ -164,7 +167,12 @@ const mapStateToProps = (state, ownProps) => { const methodData = getKnownMethodData(state, data) || {}; - const fullTxData = getFullTxData(state, txId, customTxParamsData); + const fullTxData = getFullTxData( + state, + txId, + TRANSACTION_STATUSES.UNAPPROVED, + customTxParamsData, + ); const isCollectibleTransfer = Boolean( allCollectibleContracts?.[selectedAddress]?.[chainId]?.find((contract) => { diff --git a/ui/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/pages/swaps/awaiting-swap/awaiting-swap.js index d8b21f44d..506654867 100644 --- a/ui/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/pages/swaps/awaiting-swap/awaiting-swap.js @@ -20,6 +20,7 @@ import { getUSDConversionRate, isHardwareWallet, getHardwareWalletType, + getFullTxData, } from '../../../selectors'; import { @@ -72,15 +73,16 @@ export default function AwaitingSwap({ txHash, tokensReceived, submittingSwap, + txId, }) { const t = useContext(I18nContext); const trackEvent = useContext(MetaMetricsContext); const history = useHistory(); const dispatch = useDispatch(); const animationEventEmitter = useRef(new EventEmitter()); - + const { swapMetaData } = + useSelector((state) => getFullTxData(state, txId)) || {}; const fetchParams = useSelector(getFetchParams, isEqual); - const { destinationTokenInfo, sourceTokenInfo } = fetchParams?.metaData || {}; const fromTokenInputValue = useSelector(getFromTokenInputValue); const maxSlippage = useSelector(getMaxSlippage); const usedQuote = useSelector(getUsedQuote, isEqual); @@ -103,7 +105,7 @@ export default function AwaitingSwap({ currentCurrency, conversionRate: usdConversionRate, tradeValue: usedQuote?.trade?.value, - sourceSymbol: sourceTokenInfo?.symbol, + sourceSymbol: swapMetaData?.token_from, sourceAmount: usedQuote.sourceAmount, chainId, }); @@ -120,12 +122,12 @@ export default function AwaitingSwap({ getCurrentSmartTransactionsEnabled, ); const sensitiveProperties = { - token_from: sourceTokenInfo?.symbol, - token_from_amount: fetchParams?.value, - token_to: destinationTokenInfo?.symbol, + token_from: swapMetaData?.token_from, + token_from_amount: swapMetaData?.token_from_amount, + token_to: swapMetaData?.token_to, request_type: fetchParams?.balanceError ? 'Quote' : 'Order', - slippage: fetchParams?.slippage, - custom_slippage: fetchParams?.slippage === 2, + slippage: swapMetaData?.slippage, + custom_slippage: swapMetaData?.slippage === 2, gas_fees: feeinUnformattedFiat, is_hardware_wallet: hardwareWalletUsed, hardware_wallet_type: hardwareWalletType, @@ -227,7 +229,7 @@ export default function AwaitingSwap({ key="swapOnceTransactionHasProcess-1" className="awaiting-swap__amount-and-symbol" > - {destinationTokenInfo.symbol} + {swapMetaData?.token_to} , ]); content = blockExplorerUrl && ( @@ -245,7 +247,7 @@ export default function AwaitingSwap({ key="swapTokenAvailable-2" className="awaiting-swap__amount-and-symbol" > - {`${tokensReceived || ''} ${destinationTokenInfo.symbol}`} + {`${tokensReceived || ''} ${swapMetaData?.token_to}`} , ]); content = blockExplorerUrl && ( @@ -300,7 +302,7 @@ export default function AwaitingSwap({ } else if (errorKey) { await dispatch(navigateBackToBuildQuote(history)); } else if ( - isSwapsDefaultTokenSymbol(destinationTokenInfo?.symbol, chainId) || + isSwapsDefaultTokenSymbol(swapMetaData?.token_to, chainId) || swapComplete ) { history.push(DEFAULT_ROUTE); @@ -331,4 +333,5 @@ AwaitingSwap.propTypes = { CONTRACT_DATA_DISABLED_ERROR, ]), submittingSwap: PropTypes.bool, + txId: PropTypes.number, }; diff --git a/ui/pages/swaps/awaiting-swap/awaiting-swap.test.js b/ui/pages/swaps/awaiting-swap/awaiting-swap.test.js index 923a9c48f..e213d4ca4 100644 --- a/ui/pages/swaps/awaiting-swap/awaiting-swap.test.js +++ b/ui/pages/swaps/awaiting-swap/awaiting-swap.test.js @@ -29,6 +29,7 @@ const createProps = (customProps = {}) => { submittingSwap: true, inputValue: 5, maxSlippage: SLIPPAGE.DEFAULT, + txId: 6571648590592143, ...customProps, }; }; diff --git a/ui/pages/swaps/index.js b/ui/pages/swaps/index.js index cc7e9d0a6..0aedc8e87 100644 --- a/ui/pages/swaps/index.js +++ b/ui/pages/swaps/index.js @@ -515,6 +515,7 @@ export default function Swap() { swapComplete={false} errorKey={swapsErrorKey} txHash={tradeTxData?.hash} + txId={tradeTxData?.id} submittedTime={tradeTxData?.submittedTime} /> ); @@ -574,7 +575,7 @@ export default function Swap() { path={SMART_TRANSACTION_STATUS_ROUTE} exact render={() => { - return ; + return ; }} /> ; } else if ( @@ -325,23 +339,34 @@ export default function SmartTransactionStatus() { fontWeight={FONT_WEIGHT.BOLD} boxProps={{ marginLeft: 1, marginRight: 2 }} > - {sourceTokenInfo?.symbol} + {fetchParamsSourceTokenInfo.symbol ?? + latestSmartTransaction?.sourceTokenSymbol} - + {fetchParamsSourceTokenInfo.iconUrl ? ( + + ) : null} - + {fetchParamsDestinationTokenInfo.iconUrl ? ( + + ) : null} - {destinationTokenInfo?.symbol} + {fetchParamsDestinationTokenInfo.symbol ?? + latestSmartTransaction?.destinationTokenSymbol} state.metamask.unapprovedTxs; +const getCurrentNetworkTransactionList = (state) => + state.metamask.currentNetworkTxList; + export const getTxData = (state) => state.confirmTransaction.txData; export const getUnapprovedTransaction = createDeepEqualSelector( @@ -803,11 +807,26 @@ export const getUnapprovedTransaction = createDeepEqualSelector( }, ); +export const getTransaction = createDeepEqualSelector( + getCurrentNetworkTransactionList, + (_, transactionId) => transactionId, + (unapprovedTxs, transactionId) => { + return ( + Object.values(unapprovedTxs).find(({ id }) => id === transactionId) || {} + ); + }, +); + export const getFullTxData = createDeepEqualSelector( getTxData, - (state, transactionId) => getUnapprovedTransaction(state, transactionId), - (_state, _transactionId, customTxParamsData) => customTxParamsData, - (txData, transaction, customTxParamsData) => { + (state, transactionId, status) => { + if (status === TRANSACTION_STATUSES.UNAPPROVED) { + return getUnapprovedTransaction(state, transactionId); + } + return getTransaction(state, transactionId); + }, + (_state, _transactionId, _status, customTxParamsData) => customTxParamsData, + (txData, transaction, _status, customTxParamsData) => { let fullTxData = { ...txData, ...transaction }; if (transaction && transaction.simulationFails) { txData.simulationFails = transaction.simulationFails;