Skip to content
Merged
36 changes: 22 additions & 14 deletions src/components/TradeAssetSearch/TradeAssetSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { FiatMenuButton } from '../AssetSelection/components/FiatMenuButton'
import { CustomAssetAcknowledgement } from './components/CustomAssetAcknowledgement'
import { DefaultAssetList } from './components/DefaultAssetList'
import { SearchTermAssetList } from './components/SearchTermAssetList'
import { filterAssetsForWallet } from './helpers/filterAssetsForWallet'
import { useAssetSearchWorker } from './hooks/useAssetSearchWorker'
import { useGetPopularAssetsQuery } from './hooks/useGetPopularAssetsQuery'

Expand Down Expand Up @@ -170,14 +171,13 @@ export const TradeAssetSearch: FC<TradeAssetSearchProps> = ({
)

const popularAssets = useMemo(() => {
const unfilteredPopularAssets = popularAssetsByChainId?.[activeChainId] ?? []
const filteredPopularAssets = unfilteredPopularAssets.filter(
asset => assetFilterPredicate?.(asset.assetId) ?? true,
)
if (allowWalletUnsupportedAssets || !hasWallet) return filteredPopularAssets

// TODO: move `allowWalletUnsupportedAssets` into `assetFilterPredicate`
return filteredPopularAssets.filter(asset => walletConnectedChainIds.includes(asset.chainId))
return filterAssetsForWallet({
assets: popularAssetsByChainId?.[activeChainId] ?? [],
hasWallet,
allowWalletUnsupportedAssets,
walletConnectedChainIds,
assetFilterPredicate,
})
}, [
popularAssetsByChainId,
activeChainId,
Expand Down Expand Up @@ -211,12 +211,20 @@ export const TradeAssetSearch: FC<TradeAssetSearchProps> = ({
}, [activeChainId, popularAssets])

const portfolioAssetsSortedByBalanceForChain = useMemo(() => {
const filteredPortfolioAssetsSortedByBalance = portfolioAssetsSortedByBalance.filter(
asset => assetFilterPredicate?.(asset.assetId) ?? true,
)

return filteredPortfolioAssetsSortedByBalance
}, [portfolioAssetsSortedByBalance, assetFilterPredicate])
return filterAssetsForWallet({
assets: portfolioAssetsSortedByBalance,
hasWallet,
allowWalletUnsupportedAssets,
walletConnectedChainIds,
assetFilterPredicate,
})
}, [
portfolioAssetsSortedByBalance,
assetFilterPredicate,
hasWallet,
allowWalletUnsupportedAssets,
walletConnectedChainIds,
])

const chainIds: (ChainId | 'All')[] = useMemo(() => {
const unsortedChainIds = (() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { btcAssetId, ethAssetId } from '@shapeshiftoss/caip'
import type { Asset } from '@shapeshiftoss/types'
import { KnownChainIds } from '@shapeshiftoss/types'
import { describe, expect, it } from 'vitest'

import { filterAssetsForWallet } from './filterAssetsForWallet'

describe('filterAssetsForWallet', () => {
const supportedAsset = {
assetId: ethAssetId,
chainId: KnownChainIds.EthereumMainnet,
} as Asset

const unsupportedAsset = {
assetId: btcAssetId,
chainId: KnownChainIds.BitcoinMainnet,
} as Asset

const assets = [supportedAsset, unsupportedAsset]

it('excludes unsupported chains when wallet is connected and allowWalletUnsupportedAssets is false', () => {
const result = filterAssetsForWallet({
assets,
hasWallet: true,
allowWalletUnsupportedAssets: false,
walletConnectedChainIds: [KnownChainIds.EthereumMainnet],
})

expect(result).toEqual([supportedAsset])
})

it('excludes unsupported chains when wallet is connected and allowWalletUnsupportedAssets is omitted, as in send/receive', () => {
const result = filterAssetsForWallet({
assets,
hasWallet: true,
walletConnectedChainIds: [KnownChainIds.EthereumMainnet],
})

expect(result).toEqual([supportedAsset])
})

it('retains unsupported chains when wallet is connected and allowWalletUnsupportedAssets is true', () => {
const result = filterAssetsForWallet({
assets,
hasWallet: true,
allowWalletUnsupportedAssets: true,
walletConnectedChainIds: [KnownChainIds.EthereumMainnet],
})

expect(result).toEqual([supportedAsset, unsupportedAsset])
})

it('does not filter by walletConnectedChainIds when no wallet is connected', () => {
const result = filterAssetsForWallet({
assets,
hasWallet: false,
allowWalletUnsupportedAssets: false,
walletConnectedChainIds: [KnownChainIds.EthereumMainnet],
})

expect(result).toEqual([supportedAsset, unsupportedAsset])
})

it('applies assetFilterPredicate if provided', () => {
const result = filterAssetsForWallet({
assets,
hasWallet: false,
allowWalletUnsupportedAssets: true,
walletConnectedChainIds: [],
assetFilterPredicate: assetId => assetId === ethAssetId,
})

expect(result).toEqual([supportedAsset])
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { AssetId, ChainId } from '@shapeshiftoss/caip'
import type { Asset } from '@shapeshiftoss/types'

export type FilterAssetsForWalletArgs = {
assets: Asset[]
hasWallet: boolean
allowWalletUnsupportedAssets?: boolean
walletConnectedChainIds: ChainId[]
assetFilterPredicate?: (assetId: AssetId) => boolean
}

export const filterAssetsForWallet = ({
assets,
hasWallet,
allowWalletUnsupportedAssets,
walletConnectedChainIds,
assetFilterPredicate,
}: FilterAssetsForWalletArgs): Asset[] => {
const filteredAssets = assets.filter(asset => assetFilterPredicate?.(asset.assetId) ?? true)

if (!hasWallet || allowWalletUnsupportedAssets) return filteredAssets

return filteredAssets.filter(asset => walletConnectedChainIds.includes(asset.chainId))
}
Loading