Skip to content

Commit 92fdda4

Browse files
authored
Merge pull request #411 from reservoirprotocol/ted/relay-6471-longtail-token-visibility
Optimize token list merging and sorting logic in TokenSelector
2 parents a735617 + 9d16628 commit 92fdda4

File tree

4 files changed

+78
-38
lines changed

4 files changed

+78
-38
lines changed

.changeset/silly-feet-buy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@reservoir0x/relay-kit-ui': patch
3+
---
4+
5+
Optimize token list merging and sorting logic in TokenSelector

packages/ui/src/components/common/TokenSelector/TokenSelector.tsx

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { bitcoin } from '../../../utils/bitcoin.js'
3434
import { evmDeadAddress } from '@reservoir0x/relay-sdk'
3535
import { solDeadAddress } from '@reservoir0x/relay-sdk'
3636
import { bitcoinDeadAddress } from '@reservoir0x/relay-sdk'
37+
import { mergeTokenLists } from '../../../utils/tokens.js'
3738

3839
export type TokenSelectorProps = {
3940
openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>]
@@ -263,7 +264,7 @@ const TokenSelector: FC<TokenSelectorProps> = ({
263264
suggestedTokenQuery
264265
? {
265266
tokens: suggestedTokenQuery,
266-
limit: 20,
267+
limit: 30,
267268
depositAddressOnly
268269
}
269270
: undefined,
@@ -299,47 +300,44 @@ const TokenSelector: FC<TokenSelectorProps> = ({
299300
return mergedList
300301
}, [tokenList, externalTokenList])
301302

302-
// Filter out unconfigured chains and append Relay Chain to each currency
303+
// Enhance token list with Relay chain data, balances and sort by usd value/balances
303304
const enhancedCurrencyList = useMemo(() => {
304-
const _tokenList =
305-
combinedTokenList && (combinedTokenList as any).length
306-
? (combinedTokenList as CurrencyList[])
307-
: undefined
308-
305+
// Filter suggested tokens by chain if needed
309306
const filteredSuggestedTokens = chainFilter.id
310-
? suggestedTokens
311-
?.map((tokenList) =>
312-
tokenList.filter((token) => token.chainId === chainFilter.id)
313-
)
314-
.filter((tokenList) => tokenList.length > 0)
307+
? suggestedTokens?.map((tokenList) =>
308+
tokenList.filter((token) => token.chainId === chainFilter.id)
309+
)
315310
: suggestedTokens
316311

317-
let list =
318-
context === 'from' &&
319-
useDefaultTokenList &&
320-
chainFilter.id === undefined &&
321-
filteredSuggestedTokens &&
322-
filteredSuggestedTokens.length > 0
323-
? filteredSuggestedTokens
324-
: combinedTokenList
325-
326-
const ethTokens = _tokenList?.find(
327-
(list) => list[0] && list[0].groupID === 'ETH'
312+
// Only merge suggested tokens when using default list
313+
const list = useDefaultTokenList
314+
? mergeTokenLists([filteredSuggestedTokens, combinedTokenList])
315+
: combinedTokenList || []
316+
317+
// Prioritize ETH and USDC tokens
318+
const ethTokens = list.find(
319+
(tokenList) => tokenList[0] && tokenList[0].groupID === 'ETH'
328320
)
329-
const usdcTokens = _tokenList?.find(
330-
(list) => list[0] && list[0].groupID === 'USDC'
321+
const usdcTokens = list.find(
322+
(tokenList) => tokenList[0] && tokenList[0].groupID === 'USDC'
331323
)
332-
if (list && suggestedTokens) {
333-
list = list?.filter(
334-
(tokenList) =>
335-
tokenList[0] &&
336-
tokenList[0].groupID !== 'ETH' &&
337-
tokenList[0].groupID !== 'USDC'
338-
)
339-
list = [ethTokens ?? [], usdcTokens ?? []].concat(list)
340-
}
341324

342-
const mappedList = list?.map((currencyList) => {
325+
// Remove ETH/USDC from main list and add them to the front
326+
const filteredList = list.filter(
327+
(tokenList) =>
328+
tokenList[0] &&
329+
tokenList[0].groupID !== 'ETH' &&
330+
tokenList[0].groupID !== 'USDC'
331+
)
332+
333+
const sortedList = [
334+
...(ethTokens ? [ethTokens] : []),
335+
...(usdcTokens ? [usdcTokens] : []),
336+
...filteredList
337+
]
338+
339+
// Map and enhance the currency list
340+
const mappedList = sortedList?.map((currencyList) => {
343341
const filteredList = currencyList
344342
.map((currency) => {
345343
const relayChain = configuredChains.find(
@@ -394,8 +392,21 @@ const TokenSelector: FC<TokenSelectorProps> = ({
394392
totalValueUsd
395393
}
396394
})
397-
.filter((list) => list !== undefined)
398-
.sort((a, b) => (b?.totalValueUsd ?? 0) - (a?.totalValueUsd ?? 0))
395+
.filter((list): list is NonNullable<typeof list> => list !== undefined)
396+
.sort((a, b) => {
397+
// First sort by USD value if available
398+
if (a.totalValueUsd !== b.totalValueUsd) {
399+
return b.totalValueUsd - a.totalValueUsd
400+
}
401+
// Then sort by balance if USD value is equal or undefined
402+
if (a.totalBalance !== b.totalBalance) {
403+
return Number(b.totalBalance - a.totalBalance)
404+
}
405+
// Finally prioritize verified tokens
406+
const aVerified = a.chains[0]?.metadata?.verified ?? false
407+
const bVerified = b.chains[0]?.metadata?.verified ?? false
408+
return bVerified === aVerified ? 0 : bVerified ? 1 : -1
409+
})
399410
}, [
400411
context,
401412
combinedTokenList,

packages/ui/src/components/common/TokenSelector/steps/SetCurrencyStep.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ export const SetCurrencyStep: FC<SetCurrencyProps> = ({
411411
}}
412412
/>
413413
<Text style="subtitle3" color="subtle">
414-
Popular Tokens
414+
Suggested Tokens
415415
</Text>
416416
</>
417417
) : null}

packages/ui/src/utils/tokens.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { CurrencyList } from '@reservoir0x/relay-kit-hooks'
12
import type { Token } from '../types/index.js'
23
import { ASSETS_RELAY_API } from '@reservoir0x/relay-sdk'
34
import type { paths, RelayChain } from '@reservoir0x/relay-sdk'
@@ -42,3 +43,26 @@ export const findBridgableToken = (chain?: RelayChain, token?: Token) => {
4243
}
4344
return null
4445
}
46+
47+
export const mergeTokenLists = (lists: (CurrencyList[] | undefined)[]) => {
48+
const mergedList: CurrencyList[] = []
49+
const seenTokens = new Set<string>()
50+
51+
lists.forEach((list) => {
52+
if (!list) return
53+
54+
list.forEach((currencyList) => {
55+
const currency = currencyList[0]
56+
if (!currency) return
57+
58+
const tokenKey = `${currency.chainId}:${currency.address?.toLowerCase()}`
59+
60+
if (!seenTokens.has(tokenKey)) {
61+
seenTokens.add(tokenKey)
62+
mergedList.push(currencyList)
63+
}
64+
})
65+
})
66+
67+
return mergedList
68+
}

0 commit comments

Comments
 (0)