diff --git a/src/components/MultiHopTrade/hooks/useAccountIds.tsx b/src/components/MultiHopTrade/hooks/useAccountIds.tsx index e90df7366c4..85f82ac7d86 100644 --- a/src/components/MultiHopTrade/hooks/useAccountIds.tsx +++ b/src/components/MultiHopTrade/hooks/useAccountIds.tsx @@ -1,12 +1,6 @@ import type { AccountId } from '@shapeshiftoss/caip' -import { useCallback, useMemo } from 'react' -import { - selectAccountIdByAccountNumberAndChainId, - selectAccountNumberByAccountId, - selectFirstHopSellAccountId, - selectInputBuyAsset, - selectLastHopBuyAccountId, -} from 'state/slices/selectors' +import { useCallback } from 'react' +import { selectFirstHopSellAccountId, selectLastHopBuyAccountId } from 'state/slices/selectors' import { tradeInput } from 'state/slices/tradeInputSlice/tradeInputSlice' import { useAppDispatch, useAppSelector } from 'state/store' @@ -19,31 +13,8 @@ export const useAccountIds = (): { const dispatch = useAppDispatch() // Default sellAssetAccountId selection - const sellAssetAccountId = useAppSelector(selectFirstHopSellAccountId) - const sellAssetAccountNumberFilter = useMemo( - () => ({ accountId: sellAssetAccountId }), - [sellAssetAccountId], - ) - const sellAssetAccountNumber = useAppSelector(state => - selectAccountNumberByAccountId(state, sellAssetAccountNumberFilter), - ) - - // Default buyAssetAccountId selection - - const accountIdsByAccountNumberAndChainId = useAppSelector( - selectAccountIdByAccountNumberAndChainId, - ) - const inputBuyAsset = useAppSelector(selectInputBuyAsset) - const maybeMatchingBuyAccountId = - accountIdsByAccountNumberAndChainId[sellAssetAccountNumber as number]?.[inputBuyAsset?.chainId] - - // We always default the buy asset account to be synchronized with the sellAssetAccountNumber - // - if this isn't possible, i.e there is no matching account number on the buy side, we default to the highest balance - // - if this was to fail for any reason, we default to the first account number as a default - const buyAssetAccountId = useAppSelector(state => - selectLastHopBuyAccountId(state, { accountId: maybeMatchingBuyAccountId }), - ) + const buyAssetAccountId = useAppSelector(selectLastHopBuyAccountId) // Setters - the selectors above initially select a *default* value, but eventually onAccountIdChange may fire if the user changes the account diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx index f498ce16001..396cc4e0f26 100644 --- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx +++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx @@ -124,10 +124,7 @@ export const useGetTradeQuotes = () => { const isDebouncing = debouncedSellAmountCryptoPrecision !== sellAmountCryptoPrecision const sellAccountId = useAppSelector(selectFirstHopSellAccountId) - // No need to pass a sellAssetAccountId to synchronize the buy account here - by the time this is called, we already have a valid buyAccountId - const buyAccountId = useAppSelector(state => - selectLastHopBuyAccountId(state, { accountId: undefined }), - ) + const buyAccountId = useAppSelector(selectLastHopBuyAccountId) const userslippageTolerancePercentageDecimal = useAppSelector(selectUserSlippagePercentageDecimal) diff --git a/src/components/MultiHopTrade/hooks/useReceiveAddress.tsx b/src/components/MultiHopTrade/hooks/useReceiveAddress.tsx index abdbf45fbbb..4da30b6e32c 100644 --- a/src/components/MultiHopTrade/hooks/useReceiveAddress.tsx +++ b/src/components/MultiHopTrade/hooks/useReceiveAddress.tsx @@ -7,7 +7,6 @@ import { useWallet } from 'hooks/useWallet/useWallet' import { selectPortfolioAccountMetadataByAccountId } from 'state/slices/portfolioSlice/selectors' import { isUtxoAccountId } from 'state/slices/portfolioSlice/utils' import { - selectFirstHopSellAccountId, selectInputBuyAsset, selectLastHopBuyAccountId, selectManualReceiveAddress, @@ -39,11 +38,7 @@ export const useReceiveAddress = ({ // Selectors const buyAsset = useAppSelector(selectInputBuyAsset) - const sellAssetAccountId = useAppSelector(selectFirstHopSellAccountId) - - const buyAccountId = useAppSelector(state => - selectLastHopBuyAccountId(state, { accountId: sellAssetAccountId }), - ) + const buyAccountId = useAppSelector(selectLastHopBuyAccountId) const buyAccountMetadata = useAppSelector(state => selectPortfolioAccountMetadataByAccountId(state, { accountId: buyAccountId }), ) @@ -51,9 +46,15 @@ export const useReceiveAddress = ({ const getReceiveAddressFromBuyAsset = useCallback( async (buyAsset: Asset) => { - if (!wallet) return - if (!buyAccountId) return - if (!buyAccountMetadata) return + if (!wallet) { + return + } + if (!buyAccountId) { + return + } + if (!buyAccountMetadata) { + return + } if (isUtxoAccountId(buyAccountId) && !buyAccountMetadata.accountType) throw new Error(`Missing accountType for UTXO account ${buyAccountId}`) const buyAssetChainId = buyAsset.chainId @@ -62,7 +63,9 @@ export const useReceiveAddress = ({ * do NOT remove * super dangerous - don't use the wrong bip44 params to generate receive addresses */ - if (buyAssetChainId !== buyAssetAccountChainId) return + if (buyAssetChainId !== buyAssetAccountChainId) { + return + } const receiveAddress = await getReceiveAddress({ asset: buyAsset, wallet, diff --git a/src/state/slices/tradeInputSlice/selectors.ts b/src/state/slices/tradeInputSlice/selectors.ts index a517033982f..80060a736cb 100644 --- a/src/state/slices/tradeInputSlice/selectors.ts +++ b/src/state/slices/tradeInputSlice/selectors.ts @@ -4,14 +4,17 @@ import { bn } from 'lib/bignumber/bignumber' import { toBaseUnit } from 'lib/math' import type { ReduxState } from 'state/reducer' import { createDeepEqualOutputSelector } from 'state/selector-utils' -import { selectAccountIdParamFromFilter } from 'state/selectors' import { selectPortfolioCryptoBalanceBaseUnitByFilter, selectWalletAccountIds, } from '../common-selectors' import { selectCryptoMarketData, selectUserCurrencyToUsdRate } from '../marketDataSlice/selectors' -import { selectPortfolioAssetAccountBalancesSortedUserCurrency } from '../portfolioSlice/selectors' +import { + selectAccountIdByAccountNumberAndChainId, + selectPortfolioAccountMetadata, + selectPortfolioAssetAccountBalancesSortedUserCurrency, +} from '../portfolioSlice/selectors' import { getFirstAccountIdByChainId, getHighestUserCurrencyBalanceAccountByAssetId, @@ -105,23 +108,40 @@ export const selectLastHopSellAccountId = selectFirstHopSellAccountId export const selectLastHopBuyAccountId = createSelector( selectTradeInput, selectInputBuyAsset, - selectPortfolioAssetAccountBalancesSortedUserCurrency, selectWalletAccountIds, - selectAccountIdParamFromFilter, - (tradeInput, buyAsset, accountIdAssetValues, accountIds, maybeMatchingBuyAccountId) => { + selectAccountIdByAccountNumberAndChainId, + selectFirstHopSellAccountId, + selectPortfolioAccountMetadata, + ( + tradeInput, + buyAsset, + accountIds, + accountIdByAccountNumberAndChainId, + firstHopSellAccountId, + accountMetadata, + ) => { // return the users selection if it exists - if (tradeInput.buyAssetAccountId) return tradeInput.buyAssetAccountId - // an AccountId was found matching the sell asset's account number, return it - if (maybeMatchingBuyAccountId) return maybeMatchingBuyAccountId + if (tradeInput.buyAssetAccountId) { + return tradeInput.buyAssetAccountId + } - const highestFiatBalanceBuyAccountId = getHighestUserCurrencyBalanceAccountByAssetId( - accountIdAssetValues, - buyAsset.assetId, - ) - const firstBuyAssetAccountId = getFirstAccountIdByChainId(accountIds, buyAsset.chainId) + // maybe convert the account id to an account number + const maybeMatchingBuyAccountNumber = firstHopSellAccountId + ? accountMetadata[firstHopSellAccountId]?.bip44Params.accountNumber + : undefined + + // maybe convert account number to account id on the buy asset chain + const maybeMatchingBuyAccountId = maybeMatchingBuyAccountNumber + ? accountIdByAccountNumberAndChainId[maybeMatchingBuyAccountNumber]?.[buyAsset.chainId] + : undefined + + // an AccountId was found matching the sell asset's account number and chainId, return it + if (maybeMatchingBuyAccountId) { + return maybeMatchingBuyAccountId + } // otherwise return a sane default - return highestFiatBalanceBuyAccountId ?? firstBuyAssetAccountId + return getFirstAccountIdByChainId(accountIds, buyAsset.chainId) }, )