User story / Problem statement
Currently, TokenSelect lists tokens in the token-list's source order. Users who already hold tokens have to scroll or search to find them, even though those are overwhelmingly the ones they want to pick. Burying held tokens under a long alphabetical list hurts discoverability.
The sort-by-USD-value logic already exists in src/hooks/useTokens.ts (sortFn at L240-L247) but is gated on the showBalance prop, which defaults to false. That prop conflates two concerns: (a) fetch balances + sort, and (b) render a balance column per row.
On chains not covered by LI.FI (e.g. Sepolia), the sort never runs even with showBalance={true}, because the LI.FI price/balance queries return nothing.
Expected outcome
When a user connects a wallet and opens the token selector, tokens with a positive balance appear at the top of the list, ordered by USD value descending. Tokens with zero balance follow, in the current source order. This happens on any chain LI.FI supports, regardless of whether the consumer opted into showing the balance column.
Disconnected users see the current source-order list with no balance-fetching side effects.
Acceptance criteria
Alternatives considered
For chains LI.FI does not cover, two approaches were weighed:
- Batched on-chain multicall (ERC-20
balanceOf + native getBalance) for the active chain, reusing patterns from src/hooks/useErc20Balance.ts (L38-L61) and wagmi's useBalance. Higher implementation cost, consistent UX.
- Unsorted fallback on unsupported chains, documented as a known limitation. Zero implementation cost, inconsistent UX.
Option 1 is preferred but listed as a stretch goal above; the implementation PR picks one.
Technical notes
Proposed change.
- Split the two concerns. Introduce a new prop
sortByBalance?: boolean on TokenSelect (and pass-through on TokenInput, TokenDropdown). Default: true when a wallet is connected.
- In
useTokens (src/hooks/useTokens.ts), accept a separate sortByBalance param (or always fetch balance + price when an account is present) so updateTokensBalances runs even when the caller does not want to render the balance column.
- Zero-balance tokens retain their current ordering, grouped after positive-balance tokens. Do not drop them.
Current state -- where the sort lives.
- Sort function:
src/hooks/useTokens.ts:240-247
- Applied at:
src/hooks/useTokens.ts:214 inside updateTokensBalances
- Gating conditions:
src/hooks/useTokens.ts:129-139 (requires withBalance && account + loaded LI.FI data)
- Consumer wiring:
src/components/sharedComponents/TokenSelect/index.tsx:125-128 passes withBalance: showBalance; showBalance defaults to false (line 60)
- Only in-repo opt-in:
src/components/pageComponents/home/Examples/demos/TokenInput/index.tsx:132 uses showBalance={isWalletConnected}
Non-goals.
- Changing the hardcoded
TopTokens order (src/components/sharedComponents/TokenSelect/TopTokens/index.tsx:19-38).
- Introducing a user-facing sort toggle.
- Filtering out zero-balance tokens.
References.
useTokens hook: src/hooks/useTokens.ts
- Existing sort function:
src/hooks/useTokens.ts:240-247
- Consumer component:
src/components/sharedComponents/TokenSelect/index.tsx
- Fallback balance hooks:
src/hooks/useErc20Balance.ts, src/components/sharedComponents/TokenSelect/List/TokenBalance.tsx
User story / Problem statement
Currently,
TokenSelectlists tokens in the token-list's source order. Users who already hold tokens have to scroll or search to find them, even though those are overwhelmingly the ones they want to pick. Burying held tokens under a long alphabetical list hurts discoverability.The sort-by-USD-value logic already exists in
src/hooks/useTokens.ts(sortFnat L240-L247) but is gated on theshowBalanceprop, which defaults tofalse. That prop conflates two concerns: (a) fetch balances + sort, and (b) render a balance column per row.On chains not covered by LI.FI (e.g. Sepolia), the sort never runs even with
showBalance={true}, because the LI.FI price/balance queries return nothing.Expected outcome
When a user connects a wallet and opens the token selector, tokens with a positive balance appear at the top of the list, ordered by USD value descending. Tokens with zero balance follow, in the current source order. This happens on any chain LI.FI supports, regardless of whether the consumer opted into showing the balance column.
Disconnected users see the current source-order list with no balance-fetching side effects.
Acceptance criteria
showBalance={true}.showBalancecontinues to control only whether the balance column is rendered in each row.sortByBalanceprop is documented in JSDoc onTokenSelect,TokenInput,TokenDropdown.TokenInputdemo atsrc/components/pageComponents/home/Examples/demos/TokenInput/index.tsx) keep working unchanged.useTokens.test.ts(or equivalent) asserts positive-balance tokens come before zero-balance tokens afterupdateTokensBalances.Alternatives considered
For chains LI.FI does not cover, two approaches were weighed:
balanceOf+ nativegetBalance) for the active chain, reusing patterns fromsrc/hooks/useErc20Balance.ts(L38-L61) and wagmi'suseBalance. Higher implementation cost, consistent UX.Option 1 is preferred but listed as a stretch goal above; the implementation PR picks one.
Technical notes
Proposed change.
sortByBalance?: booleanonTokenSelect(and pass-through onTokenInput,TokenDropdown). Default:truewhen a wallet is connected.useTokens(src/hooks/useTokens.ts), accept a separatesortByBalanceparam (or always fetch balance + price when an account is present) soupdateTokensBalancesruns even when the caller does not want to render the balance column.Current state -- where the sort lives.
src/hooks/useTokens.ts:240-247src/hooks/useTokens.ts:214insideupdateTokensBalancessrc/hooks/useTokens.ts:129-139(requireswithBalance && account+ loaded LI.FI data)src/components/sharedComponents/TokenSelect/index.tsx:125-128passeswithBalance: showBalance;showBalancedefaults tofalse(line 60)src/components/pageComponents/home/Examples/demos/TokenInput/index.tsx:132usesshowBalance={isWalletConnected}Non-goals.
TopTokensorder (src/components/sharedComponents/TokenSelect/TopTokens/index.tsx:19-38).References.
useTokenshook:src/hooks/useTokens.tssrc/hooks/useTokens.ts:240-247src/components/sharedComponents/TokenSelect/index.tsxsrc/hooks/useErc20Balance.ts,src/components/sharedComponents/TokenSelect/List/TokenBalance.tsx