Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swap seach popular in rainbow #1696

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
21 changes: 21 additions & 0 deletions src/core/resources/search/parseTokenSearch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { AddressOrEth } from '~/core/types/assets';
import { ChainId } from '~/core/types/chains';
import { SearchAsset } from '~/core/types/search';
import { isNativeAsset } from '~/core/utils/chains';

export function parseTokenSearch(
asset: SearchAsset,
chainId: ChainId,
): SearchAsset {
const networkInfo = asset.networks[chainId];

return {
...asset,
address: networkInfo ? networkInfo.address : asset.address,
chainId,
decimals: networkInfo ? networkInfo.decimals : asset.decimals,
isNativeAsset: isNativeAsset(asset.address, chainId),
mainnetAddress: asset.uniqueId as AddressOrEth,
uniqueId: `${networkInfo?.address || asset.uniqueId}_${chainId}`,
};
}
101 changes: 0 additions & 101 deletions src/core/resources/search/swappableAddresses.ts

This file was deleted.

47 changes: 47 additions & 0 deletions src/core/resources/search/tokenDiscovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useQuery } from '@tanstack/react-query';

import { createHttpClient } from '~/core/network/internal/createHttpClient';
import { QueryFunctionArgs, createQueryKey } from '~/core/react-query';
import { ChainId } from '~/core/types/chains';
import { SearchAsset } from '~/core/types/search';

import { parseTokenSearch } from './parseTokenSearch';

const tokenSearchDiscoveryHttp = createHttpClient({
baseUrl: 'https://token-search.rainbow.me/v3/discovery',
timeout: 30000,
});

type TokenDiscoveryArgs = {
chainId: ChainId;
};

const tokenDiscoveryQueryKey = ({ chainId }: TokenDiscoveryArgs) =>
createQueryKey('TokenDiscovery', { chainId }, { persisterVersion: 1 });

async function tokenSearchQueryFunction({
queryKey: [{ chainId }],
}: QueryFunctionArgs<typeof tokenDiscoveryQueryKey>) {
const url = `/${chainId}`;

try {
const tokenSearch = await tokenSearchDiscoveryHttp.get<{
data: SearchAsset[];
}>(url);
return tokenSearch.data.data.map((asset) =>
parseTokenSearch(asset, chainId),
);
} catch (e) {
return [];
}
}

export function useTokenDiscovery({ chainId }: TokenDiscoveryArgs) {
return useQuery({
queryKey: tokenDiscoveryQueryKey({ chainId }),
queryFn: tokenSearchQueryFunction,
staleTime: 15 * 60 * 1000, // 15 min
gcTime: 24 * 60 * 60 * 1000, // 1 day
select: (data) => data.slice(0, 3),
});
}
43 changes: 5 additions & 38 deletions src/core/resources/search/tokenSearch.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { isAddress } from '@ethersproject/address';
import { useQueries, useQuery } from '@tanstack/react-query';
import qs from 'qs';
import { Address } from 'viem';

import { tokenSearchHttp } from '~/core/network/tokenSearch';
import {
Expand All @@ -11,11 +10,6 @@ import {
createQueryKey,
queryClient,
} from '~/core/react-query';
import {
BNB_BSC_ADDRESS,
ETH_ADDRESS,
POL_POLYGON_ADDRESS,
} from '~/core/references';
import { ChainId } from '~/core/types/chains';
import {
SearchAsset,
Expand All @@ -25,6 +19,8 @@ import {
} from '~/core/types/search';
import { getSupportedChains, isCustomChain } from '~/core/utils/chains';

import { parseTokenSearch } from './parseTokenSearch';

// ///////////////////////////////////////////////
// Query Types

Expand Down Expand Up @@ -90,43 +86,14 @@ async function tokenSearchQueryFunction({
const url = `/${chainId}/?${qs.stringify(queryParams)}`;
try {
const tokenSearch = await tokenSearchHttp.get<{ data: SearchAsset[] }>(url);
return parseTokenSearch(tokenSearch.data.data, chainId);
return tokenSearch.data.data.map((asset) =>
parseTokenSearch(asset, chainId),
);
} catch (e) {
return [];
}
}

function parseTokenSearch(assets: SearchAsset[], chainId: ChainId) {
return assets
.map((a) => {
const networkInfo = a.networks[chainId];

const asset: SearchAsset = {
...a,
address: networkInfo ? networkInfo.address : a.address,
chainId,
decimals: networkInfo ? networkInfo.decimals : a.decimals,
isNativeAsset: [
`${ETH_ADDRESS}_${ChainId.mainnet}`,
`${ETH_ADDRESS}_${ChainId.optimism}`,
`${ETH_ADDRESS}_${ChainId.arbitrum}`,
`${BNB_BSC_ADDRESS}_${ChainId.bsc}`,
`${POL_POLYGON_ADDRESS}_${ChainId.polygon}`,
`${ETH_ADDRESS}_${ChainId.base}`,
`${ETH_ADDRESS}_${ChainId.zora}`,
`${ETH_ADDRESS}_${ChainId.avalanche}`,
`${ETH_ADDRESS}_${ChainId.blast}`,
`${ETH_ADDRESS}_${ChainId.degen}`,
].includes(`${a.uniqueId}_${chainId}`),
mainnetAddress: a.uniqueId as Address,
uniqueId: `${networkInfo?.address || a.uniqueId}_${chainId}`,
};

return asset;
})
.filter(Boolean);
}

type TokenSearchResult = QueryFunctionResult<typeof tokenSearchQueryFunction>;

// ///////////////////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion src/core/state/favorites/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import {
ETH_BLAST_ADDRESS,
ETH_OPTIMISM_ADDRESS,
ETH_ZORA_ADDRESS,
POL_POLYGON_ADDRESS,
OP_ADDRESS,
POL_POLYGON_ADDRESS,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eslint sort imports rule

SOCKS_ADDRESS,
SOCKS_ARBITRUM_ADDRESS,
USDB_BLAST_ADDRESS,
Expand Down
53 changes: 45 additions & 8 deletions src/entries/popup/hooks/useSearchCurrencyLists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Address } from 'viem';
import { SUPPORTED_CHAINS } from '~/core/references/chains';
import { useAssetSearchMetadataAllNetworks } from '~/core/resources/assets/assetMetadata';
import { useTokenSearch } from '~/core/resources/search';
import { useTokenDiscovery } from '~/core/resources/search/tokenDiscovery';
import { useTokenSearchAllNetworks } from '~/core/resources/search/tokenSearch';
import { useTestnetModeStore } from '~/core/state/currentSettings/testnetMode';
import { ParsedSearchAsset } from '~/core/types/assets';
Expand Down Expand Up @@ -43,7 +44,8 @@ export type AssetToBuySectionId =
| 'favorites'
| 'verified'
| 'unverified'
| 'other_networks';
| 'other_networks'
| 'popular';

export interface AssetToBuySection {
data: SearchAsset[];
Expand All @@ -66,6 +68,18 @@ const filterBridgeAsset = ({
asset?.name?.toLowerCase()?.startsWith(filter?.toLowerCase()) ||
asset?.symbol?.toLowerCase()?.startsWith(filter?.toLowerCase());

function difference(
assets: SearchAsset[],
others: (SearchAsset | undefined | null)[],
) {
const _others = others.filter(Boolean);
return assets.filter((asset) => {
return !_others.some((other) =>
isLowerCaseMatch(other.address, asset.address),
);
});
}

export function useSearchCurrencyLists({
assetToSell,
inputChainId,
Expand Down Expand Up @@ -279,6 +293,10 @@ export function useSearchCurrencyLists({
},
);

const { data: popularAssets = [] } = useTokenDiscovery({
chainId: outputChainId,
});

const { favorites } = useFavoriteAssets();

const favoritesList = useMemo(() => {
Expand Down Expand Up @@ -508,6 +526,10 @@ export function useSearchCurrencyLists({
return sections;
}

if (popularAssets?.length) {
sections.push({ id: 'popular', data: popularAssets });
}

if (bridgeAsset) {
sections.push({
data: [bridgeAsset],
Expand All @@ -516,15 +538,27 @@ export function useSearchCurrencyLists({
}
if (favoritesList?.length) {
sections.push({
data: filterAssetsFromBridgeAndAssetToSell(favoritesList),
data: difference(favoritesList, [
...popularAssets,
bridgeAsset,
assetToSell,
]),
id: 'favorites',
});
}

const otherSectionsAssets = [
...popularAssets,
...favoritesList,
bridgeAsset,
assetToSell,
];

if (query === '') {
sections.push({
data: filterAssetsFromFavoritesBridgeAndAssetToSell(
curatedAssets[outputChainId],
data: difference(
curatedAssets[outputChainId] || [],
otherSectionsAssets,
),
id: 'verified',
});
Expand All @@ -533,8 +567,9 @@ export function useSearchCurrencyLists({

if (hasVerifiedAssets) {
sections.push({
data: filterAssetsFromFavoritesBridgeAndAssetToSell(
data: difference(
targetAllNetworksVerifiedAssets,
otherSectionsAssets,
),
id: 'verified',
});
Expand All @@ -545,14 +580,15 @@ export function useSearchCurrencyLists({
targetAllNetworkMetadataAssets.length > 0;

if (hasSomeUnverifiedAssets) {
let allUnverifiedAssets = filterAssetsFromFavoritesBridgeAndAssetToSell(
let allUnverifiedAssets = difference(
uniqBy(
[
...targetAllNetworksUnverifiedAssets,
...targetAllNetworkMetadataAssets,
],
'uniqueId',
),
otherSectionsAssets,
);

if (hasVerifiedAssets) {
Expand Down Expand Up @@ -599,13 +635,13 @@ export function useSearchCurrencyLists({
return sections;
}, [
bridge,
popularAssets,
bridgeAsset,
favoritesList,
assetToSell,
query,
enableAllNetworkTokenSearch,
bridgeList,
filterAssetsFromBridgeAndAssetToSell,
filterAssetsFromFavoritesBridgeAndAssetToSell,
curatedAssets,
outputChainId,
targetAllNetworksVerifiedAssets,
Expand All @@ -616,6 +652,7 @@ export function useSearchCurrencyLists({
targetUnverifiedAssets,
enableUnverifiedSearch,
crosschainExactMatches,
filterAssetsFromFavoritesBridgeAndAssetToSell,
]);

return {
Expand Down
Loading
Loading