@@ -6,13 +6,13 @@ import {
66 useDeferredValue ,
77 startTransition ,
88} from 'react' ;
9- import { toNative } from '@wormhole-foundation/sdk' ;
9+ import { toNative , isNative } from '@wormhole-foundation/sdk' ;
1010import type { Chain } from '@wormhole-foundation/sdk' ;
1111import type { Token } from 'config/tokens' ;
1212import config from 'config' ;
1313import { useTokens } from 'contexts/TokensContext' ;
1414import { getTokenSymbol } from 'utils' ;
15- import type { Balances } from 'utils/wallet/types ' ;
15+ import { getWrappedNativeToken } from 'utils/wrappedNativeTokens ' ;
1616import { unionBy } from 'es-toolkit' ;
1717
1818interface UseTokenListWithSearchParams {
@@ -22,8 +22,6 @@ interface UseTokenListWithSearchParams {
2222 isSource : boolean ;
2323 isSameChainSwap : boolean ;
2424 sourceToken ?: Token ;
25- balances : Balances ;
26- walletAddress : string ;
2725 tokenPastingEnabled ?: boolean ;
2826}
2927
@@ -46,8 +44,6 @@ export const useTokenListWithSearch = ({
4644 isSource,
4745 isSameChainSwap,
4846 sourceToken,
49- balances,
50- walletAddress,
5147 tokenPastingEnabled = true ,
5248} : UseTokenListWithSearchParams ) : UseTokenListWithSearchReturn => {
5349 const [ searchedTokens , setSearchedTokens ] = useState < Token [ ] > ( [ ] ) ;
@@ -60,6 +56,15 @@ export const useTokenListWithSearch = ({
6056 setSearchedTokens ( ( prev ) => [ ...prev , token ] ) ;
6157 } , [ ] ) ;
6258
59+ // Get wrapped native address for same-chain swaps (only for destination selection)
60+ const wrappedNativeAddr = useMemo ( ( ) => {
61+ if ( ! isSameChainSwap || ! chain || isSource ) {
62+ return undefined ;
63+ }
64+ const wrapped = getWrappedNativeToken ( config . network , chain ) ;
65+ return wrapped ?. toLowerCase ( ) ;
66+ } , [ isSameChainSwap , chain , isSource ] ) ;
67+
6368 useEffect ( ( ) => {
6469 if ( ! chain || ! tokenPastingEnabled || ! deferredSearch ) {
6570 setSearchedTokens ( [ ] ) ;
@@ -103,6 +108,20 @@ export const useTokenListWithSearch = ({
103108 addTokenIfNotExists ,
104109 ] ) ;
105110
111+ const sourceTokenInfo = useMemo ( ( ) => {
112+ if ( ! sourceToken || ! isSameChainSwap || isSource ) {
113+ return null ;
114+ }
115+
116+ return {
117+ addressString : sourceToken . addressString ,
118+ isNative : isNative ( sourceToken . address ) ,
119+ isWrapped : wrappedNativeAddr
120+ ? sourceToken . addressString . toLowerCase ( ) === wrappedNativeAddr
121+ : false ,
122+ } ;
123+ } , [ sourceToken , isSameChainSwap , isSource , wrappedNativeAddr ] ) ;
124+
106125 const sortedTokens = useMemo ( ( ) => {
107126 // Merge base tokens with any fetched tokens only when searching
108127 let tokens = deferredSearch
@@ -139,11 +158,30 @@ export const useTokenListWithSearch = ({
139158 } ) ;
140159 }
141160
142- // For destination token list in same-chain swaps, filter out the source token
143- if ( ! isSource && isSameChainSwap && sourceToken ) {
144- tokens = tokens . filter (
145- ( t ) => t . addressString !== sourceToken . addressString ,
146- ) ;
161+ // For destination token list in same-chain swaps, filter out invalid options
162+ if ( sourceTokenInfo ) {
163+ tokens = tokens . filter ( ( t ) => {
164+ // Filter out exact same token
165+ if ( t . addressString === sourceTokenInfo . addressString ) {
166+ return false ;
167+ }
168+
169+ // Block native-wrapped token pairs if we have wrapped native address
170+ if ( wrappedNativeAddr ) {
171+ const destIsWrapped =
172+ t . addressString . toLowerCase ( ) === wrappedNativeAddr ;
173+ const destIsNative = isNative ( t . address ) ;
174+
175+ if (
176+ ( sourceTokenInfo . isNative && destIsWrapped ) ||
177+ ( sourceTokenInfo . isWrapped && destIsNative )
178+ ) {
179+ return false ;
180+ }
181+ }
182+
183+ return true ;
184+ } ) ;
147185 }
148186
149187 return tokens ;
@@ -152,9 +190,8 @@ export const useTokenListWithSearch = ({
152190 searchedTokens ,
153191 deferredSearch ,
154192 searchLower ,
155- isSource ,
156- isSameChainSwap ,
157- sourceToken ,
193+ sourceTokenInfo ,
194+ wrappedNativeAddr ,
158195 ] ) ;
159196
160197 const tokenPrices = useMemo (
0 commit comments