From fe5dd3885fb171c58587b4197fa6b624c0c08508 Mon Sep 17 00:00:00 2001 From: Apotheosis <97164662+0xApotheosis@users.noreply.github.com> Date: Mon, 19 Aug 2024 09:18:43 +1000 Subject: [PATCH 1/2] chore: improve tradeQuoteSlice selectors --- .../components/ApprovalStep.tsx | 24 ++++++++++++++++--- .../MultiHopTradeConfirm/components/Hop.tsx | 16 +++++++++++-- .../components/HopTransactionStep.tsx | 9 ++++++- .../hooks/useAllowanceApproval.tsx | 11 ++++++++- .../hooks/useThorStreamingProgress.tsx | 9 ++++++- .../hooks/useTradeExecution.tsx | 10 +++++++- src/state/selectors.ts | 13 ++++++++++ src/state/slices/tradeQuoteSlice/selectors.ts | 12 ++++++---- 8 files changed, 91 insertions(+), 13 deletions(-) diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx index 6b3fe0166e0..159d18619b2 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx @@ -124,9 +124,15 @@ const ApprovalStepPending = ({ const [isExactAllowance, toggleIsExactAllowance] = useToggle(isLifiStep ? true : false) const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp() + const selectHopExecutionMetadataFilter = useMemo(() => { + return { + tradeId: activeTradeId, + hopIndex, + } + }, [activeTradeId, hopIndex]) const { state, allowanceReset, approval } = useAppSelector(state => - selectHopExecutionMetadata(state, activeTradeId, hopIndex), + selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter), ) const isAwaitingReset = useMemo(() => { @@ -374,8 +380,14 @@ const ApprovalStepComplete = ({ activeTradeId, }: ApprovalStepProps) => { const translate = useTranslate() + const selectHopExecutionMetadataFilter = useMemo(() => { + return { + tradeId: activeTradeId, + hopIndex, + } + }, [activeTradeId, hopIndex]) const { state, allowanceReset, approval } = useAppSelector(state => - selectHopExecutionMetadata(state, activeTradeId, hopIndex), + selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter), ) const stepIndicator = useMemo(() => { @@ -453,8 +465,14 @@ export const ApprovalStep = ({ isAllowanceResetStep, activeTradeId, }: ApprovalStepProps) => { + const selectHopExecutionMetadataFilter = useMemo(() => { + return { + tradeId: activeTradeId, + hopIndex, + } + }, [activeTradeId, hopIndex]) const { state } = useAppSelector(state => - selectHopExecutionMetadata(state, activeTradeId, hopIndex), + selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter), ) const isComplete = useMemo(() => { diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx index 993c597b836..8f5e64b0b57 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx @@ -71,20 +71,32 @@ export const Hop = ({ number: { toCrypto }, } = useLocaleFormatter() const translate = useTranslate() + const selectHopTotalProtocolFeesFiatPrecisionFilter = useMemo(() => { + return { + hopIndex, + } + }, [hopIndex]) const networkFeeFiatPrecision = useAppSelector(state => - selectHopNetworkFeeUserCurrencyPrecision(state, hopIndex), + selectHopNetworkFeeUserCurrencyPrecision(state, selectHopTotalProtocolFeesFiatPrecisionFilter), ) const protocolFeeFiatPrecision = useAppSelector(state => selectHopTotalProtocolFeesFiatPrecision(state, hopIndex), ) const isMultiHopTrade = useAppSelector(selectIsActiveQuoteMultiHop) + const selectHopExecutionMetadataFilter = useMemo(() => { + return { + tradeId: activeTradeId, + hopIndex, + } + }, [activeTradeId, hopIndex]) + const { state: hopExecutionState, approval, swap, allowanceReset, - } = useAppSelector(state => selectHopExecutionMetadata(state, activeTradeId, hopIndex)) + } = useAppSelector(state => selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter)) const isError = useMemo( () => [approval.state, swap.state].includes(TransactionExecutionState.Failed), diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx index 2ae17aa2692..a4dc2b09277 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx @@ -54,9 +54,16 @@ export const HopTransactionStep = ({ const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp() + const selectHopExecutionMetadataFilter = useMemo(() => { + return { + tradeId: activeTradeId, + hopIndex, + } + }, [activeTradeId, hopIndex]) + const { swap: { state: swapTxState, sellTxHash, buyTxHash, message }, - } = useAppSelector(state => selectHopExecutionMetadata(state, activeTradeId, hopIndex)) + } = useAppSelector(state => selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter)) const isError = useMemo(() => swapTxState === TransactionExecutionState.Failed, [swapTxState]) diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx index c5a30764e62..b1ddbb9b878 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx @@ -27,7 +27,16 @@ export const useAllowanceApproval = ( const dispatch = useAppDispatch() const { showErrorToast } = useErrorHandler() const wallet = useWallet().state.wallet ?? undefined - const sellAssetAccountId = useAppSelector(state => selectHopSellAccountId(state, hopIndex)) + + const selectHopSellAccountIdFilter = useMemo(() => { + return { + hopIndex, + } + }, [hopIndex]) + + const sellAssetAccountId = useAppSelector(state => + selectHopSellAccountId(state, selectHopSellAccountIdFilter), + ) const isReset = useMemo(() => allowanceType === AllowanceType.Reset, [allowanceType]) diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx index f104134807c..9033a6ef074 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx @@ -68,9 +68,16 @@ export const useThorStreamingProgress = ( const streamingSwapDataRef = useRef() const { poll, cancelPolling } = usePoll() const dispatch = useAppDispatch() + const selectHopExecutionMetadataFilter = useMemo(() => { + return { + tradeId: confirmedTradeId, + hopIndex, + } + }, [confirmedTradeId, hopIndex]) + const { swap: { sellTxHash, streamingSwap: streamingSwapMeta }, - } = useAppSelector(state => selectHopExecutionMetadata(state, confirmedTradeId, hopIndex)) + } = useAppSelector(state => selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter)) useEffect(() => { // don't start polling until we have a tx diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx index 74ffdc4b8a0..1790d422309 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx @@ -47,7 +47,15 @@ export const useTradeExecution = ( const trackMixpanelEvent = useMixpanel() const hasMixpanelSuccessOrFailFiredRef = useRef(false) - const sellAssetAccountId = useAppSelector(state => selectHopSellAccountId(state, hopIndex)) + const selectHopSellAccountIdFilter = useMemo(() => { + return { + hopIndex, + } + }, [hopIndex]) + + const sellAssetAccountId = useAppSelector(state => + selectHopSellAccountId(state, selectHopSellAccountIdFilter), + ) const accountMetadataFilter = useMemo( () => ({ accountId: sellAssetAccountId }), diff --git a/src/state/selectors.ts b/src/state/selectors.ts index 76118ea5e2b..b2f29d79909 100644 --- a/src/state/selectors.ts +++ b/src/state/selectors.ts @@ -2,6 +2,7 @@ import type { QueryStatus } from '@reduxjs/toolkit/dist/query' import type { AccountId, AssetId, ChainId } from '@shapeshiftoss/caip' +import type { TradeQuote } from '@shapeshiftoss/swapper' import type { HistoryTimeframe } from '@shapeshiftoss/types' import type { TxStatus } from '@shapeshiftoss/unchained-client' import createCachedSelector from 're-reselect' @@ -52,6 +53,8 @@ type ParamFilter = Partial<{ feeModel: ParameterModel timeframe: HistoryTimeframe onlyConnectedChains: boolean + hopIndex: number + tradeId: TradeQuote['id'] }> type ParamFilterKey = keyof ParamFilter @@ -66,6 +69,13 @@ export const selectParamFromFilter = (param: T) => `${param}-${filter?.[param] ?? param}`, ) +export const selectRequiredParamFromFilter = (param: T) => + createCachedSelector( + (_state: ReduxState, filter: Required>): NonNullable => + filter[param] as NonNullable, + (paramValue: NonNullable): NonNullable => paramValue, + )((_state: ReduxState, filter: Required>) => `${param}-${filter[param]}`) + export const selectAccountIdParamFromFilter = selectParamFromFilter('accountId') export const selectAccountIdsParamFromFilter = selectParamFromFilter('accountIds') export const selectFromParamFromFilter = selectParamFromFilter('from') @@ -88,3 +98,6 @@ export const selectTxStatusParamFromFilter = selectParamFromFilter('txStatus') export const selectFeeModelParamFromFilter = selectParamFromFilter('feeModel') export const selectTimeframeParamFromFilter = selectParamFromFilter('timeframe') export const selectOnlyConnectedChainsParamFromFilter = selectParamFromFilter('onlyConnectedChains') + +export const selectHopIndexParamFromRequiredFilter = selectRequiredParamFromFilter('hopIndex') +export const selectTradeIdParamFromRequiredFilter = selectRequiredParamFromFilter('tradeId') diff --git a/src/state/slices/tradeQuoteSlice/selectors.ts b/src/state/slices/tradeQuoteSlice/selectors.ts index 16731b96261..07a3ffde316 100644 --- a/src/state/slices/tradeQuoteSlice/selectors.ts +++ b/src/state/slices/tradeQuoteSlice/selectors.ts @@ -23,6 +23,10 @@ import { TradeQuoteRequestError, TradeQuoteWarning } from 'state/apis/swapper/ty import { getEnabledSwappers } from 'state/helpers' import type { ReduxState } from 'state/reducer' import { createDeepEqualOutputSelector } from 'state/selector-utils' +import { + selectHopIndexParamFromRequiredFilter, + selectTradeIdParamFromRequiredFilter, +} from 'state/selectors' import { selectFeeAssetById } from 'state/slices/assetsSlice/selectors' import { selectFirstHopSellAccountId, @@ -484,7 +488,7 @@ export const selectSecondHopNetworkFeeUserCurrencyPrecision: Selector< export const selectHopNetworkFeeUserCurrencyPrecision = createDeepEqualOutputSelector( selectFirstHopNetworkFeeUserCurrencyPrecision, selectSecondHopNetworkFeeUserCurrencyPrecision, - (_state: ReduxState, hopIndex: number) => hopIndex, + selectHopIndexParamFromRequiredFilter, (firstHopNetworkFeeUserCurrencyPrecision, secondHopNetworkFeeUserCurrencyPrecision, hopIndex) => { return hopIndex === 0 ? firstHopNetworkFeeUserCurrencyPrecision @@ -646,7 +650,7 @@ export const selectConfirmedTradeExecutionState = createSelector( export const selectHopSellAccountId = createSelector( selectFirstHopSellAccountId, selectSecondHopSellAccountId, - (_state: ReduxState, hopIndex: number) => hopIndex, + selectHopIndexParamFromRequiredFilter, (firstHopSellAccountId, secondHopSellAccountId, hopIndex) => { return hopIndex === 0 ? firstHopSellAccountId : secondHopSellAccountId }, @@ -654,8 +658,8 @@ export const selectHopSellAccountId = createSelector( export const selectHopExecutionMetadata = createDeepEqualOutputSelector( selectTradeQuoteSlice, - (_state: ReduxState, tradeId: TradeQuote['id']) => tradeId, - (_state: ReduxState, _tradeId: TradeQuote['id'], hopIndex: number) => hopIndex, + selectTradeIdParamFromRequiredFilter, + selectHopIndexParamFromRequiredFilter, (swappers, tradeId, hopIndex) => { return hopIndex === 0 ? swappers.tradeExecution[tradeId].firstHop From 20407119916771f67359dadcae5ee3c6d42c5b44 Mon Sep 17 00:00:00 2001 From: Apotheosis <97164662+0xApotheosis@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:59:43 +1000 Subject: [PATCH 2/2] chore: rename filters --- .../MultiHopTradeConfirm/components/ApprovalStep.tsx | 12 ++++++------ .../MultiHopTradeConfirm/components/Hop.tsx | 8 ++++---- .../components/HopTransactionStep.tsx | 4 ++-- .../hooks/useAllowanceApproval.tsx | 4 ++-- .../hooks/useThorStreamingProgress.tsx | 4 ++-- .../MultiHopTradeConfirm/hooks/useTradeExecution.tsx | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx index 159d18619b2..20fbd97feae 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx @@ -124,7 +124,7 @@ const ApprovalStepPending = ({ const [isExactAllowance, toggleIsExactAllowance] = useToggle(isLifiStep ? true : false) const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp() - const selectHopExecutionMetadataFilter = useMemo(() => { + const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: activeTradeId, hopIndex, @@ -132,7 +132,7 @@ const ApprovalStepPending = ({ }, [activeTradeId, hopIndex]) const { state, allowanceReset, approval } = useAppSelector(state => - selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter), + selectHopExecutionMetadata(state, hopExecutionMetadataFilter), ) const isAwaitingReset = useMemo(() => { @@ -380,14 +380,14 @@ const ApprovalStepComplete = ({ activeTradeId, }: ApprovalStepProps) => { const translate = useTranslate() - const selectHopExecutionMetadataFilter = useMemo(() => { + const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: activeTradeId, hopIndex, } }, [activeTradeId, hopIndex]) const { state, allowanceReset, approval } = useAppSelector(state => - selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter), + selectHopExecutionMetadata(state, hopExecutionMetadataFilter), ) const stepIndicator = useMemo(() => { @@ -465,14 +465,14 @@ export const ApprovalStep = ({ isAllowanceResetStep, activeTradeId, }: ApprovalStepProps) => { - const selectHopExecutionMetadataFilter = useMemo(() => { + const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: activeTradeId, hopIndex, } }, [activeTradeId, hopIndex]) const { state } = useAppSelector(state => - selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter), + selectHopExecutionMetadata(state, hopExecutionMetadataFilter), ) const isComplete = useMemo(() => { diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx index 8f5e64b0b57..b138d90982e 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Hop.tsx @@ -71,20 +71,20 @@ export const Hop = ({ number: { toCrypto }, } = useLocaleFormatter() const translate = useTranslate() - const selectHopTotalProtocolFeesFiatPrecisionFilter = useMemo(() => { + const hopTotalProtocolFeesFiatPrecisionFilter = useMemo(() => { return { hopIndex, } }, [hopIndex]) const networkFeeFiatPrecision = useAppSelector(state => - selectHopNetworkFeeUserCurrencyPrecision(state, selectHopTotalProtocolFeesFiatPrecisionFilter), + selectHopNetworkFeeUserCurrencyPrecision(state, hopTotalProtocolFeesFiatPrecisionFilter), ) const protocolFeeFiatPrecision = useAppSelector(state => selectHopTotalProtocolFeesFiatPrecision(state, hopIndex), ) const isMultiHopTrade = useAppSelector(selectIsActiveQuoteMultiHop) - const selectHopExecutionMetadataFilter = useMemo(() => { + const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: activeTradeId, hopIndex, @@ -96,7 +96,7 @@ export const Hop = ({ approval, swap, allowanceReset, - } = useAppSelector(state => selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter)) + } = useAppSelector(state => selectHopExecutionMetadata(state, hopExecutionMetadataFilter)) const isError = useMemo( () => [approval.state, swap.state].includes(TransactionExecutionState.Failed), diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx index a4dc2b09277..ca88e36b7de 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx @@ -54,7 +54,7 @@ export const HopTransactionStep = ({ const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp() - const selectHopExecutionMetadataFilter = useMemo(() => { + const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: activeTradeId, hopIndex, @@ -63,7 +63,7 @@ export const HopTransactionStep = ({ const { swap: { state: swapTxState, sellTxHash, buyTxHash, message }, - } = useAppSelector(state => selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter)) + } = useAppSelector(state => selectHopExecutionMetadata(state, hopExecutionMetadataFilter)) const isError = useMemo(() => swapTxState === TransactionExecutionState.Failed, [swapTxState]) diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx index b1ddbb9b878..00419ea5b7a 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowanceApproval.tsx @@ -28,14 +28,14 @@ export const useAllowanceApproval = ( const { showErrorToast } = useErrorHandler() const wallet = useWallet().state.wallet ?? undefined - const selectHopSellAccountIdFilter = useMemo(() => { + const hopSellAccountIdFilter = useMemo(() => { return { hopIndex, } }, [hopIndex]) const sellAssetAccountId = useAppSelector(state => - selectHopSellAccountId(state, selectHopSellAccountIdFilter), + selectHopSellAccountId(state, hopSellAccountIdFilter), ) const isReset = useMemo(() => allowanceType === AllowanceType.Reset, [allowanceType]) diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx index fd896d437b4..bf8ef51bdc0 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useThorStreamingProgress.tsx @@ -68,7 +68,7 @@ export const useThorStreamingProgress = ( const streamingSwapDataRef = useRef() const { poll, cancelPolling } = usePoll() const dispatch = useAppDispatch() - const selectHopExecutionMetadataFilter = useMemo(() => { + const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: confirmedTradeId, hopIndex, @@ -77,7 +77,7 @@ export const useThorStreamingProgress = ( const { swap: { sellTxHash, streamingSwap: streamingSwapMeta }, - } = useAppSelector(state => selectHopExecutionMetadata(state, selectHopExecutionMetadataFilter)) + } = useAppSelector(state => selectHopExecutionMetadata(state, hopExecutionMetadataFilter)) useEffect(() => { // don't start polling until we have a tx diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx index 1790d422309..8877e32673a 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx @@ -47,14 +47,14 @@ export const useTradeExecution = ( const trackMixpanelEvent = useMixpanel() const hasMixpanelSuccessOrFailFiredRef = useRef(false) - const selectHopSellAccountIdFilter = useMemo(() => { + const hopSellAccountIdFilter = useMemo(() => { return { hopIndex, } }, [hopIndex]) const sellAssetAccountId = useAppSelector(state => - selectHopSellAccountId(state, selectHopSellAccountIdFilter), + selectHopSellAccountId(state, hopSellAccountIdFilter), ) const accountMetadataFilter = useMemo(