diff --git a/shared/types/bridge.ts b/shared/types/bridge.ts index ce9b3e509abd..96d83313a55a 100644 --- a/shared/types/bridge.ts +++ b/shared/types/bridge.ts @@ -50,11 +50,11 @@ export type BridgeToken = { symbol: string; image: string; decimals: number; - chainId: CaipChainId; + chainId: number | Hex | ChainId | CaipChainId; balance: string; // raw balance string: string | undefined; // normalized balance as a stringified number tokenFiatAmount?: number | null; -} | null; +}; // Types copied from Metabridge API export enum BridgeFlag { diff --git a/ui/ducks/bridge/bridge.test.ts b/ui/ducks/bridge/bridge.test.ts index 5dc1a60f2710..c9005fbaa703 100644 --- a/ui/ducks/bridge/bridge.test.ts +++ b/ui/ducks/bridge/bridge.test.ts @@ -101,7 +101,12 @@ describe('Ducks - Bridge', () => { expect(actions[0].type).toStrictEqual('bridge/setToToken'); const newState = bridgeReducer(state, actions[0]); expect(newState.toToken).toStrictEqual( - expect.objectContaining({ ...actionPayload, chainId: 'eip155:10' }), + expect.objectContaining({ + ...actionPayload, + balance: '0', + chainId: '0xa', + string: '0', + }), ); }); }); diff --git a/ui/ducks/bridge/bridge.ts b/ui/ducks/bridge/bridge.ts index 97d625b783b2..87a54abad2b5 100644 --- a/ui/ducks/bridge/bridge.ts +++ b/ui/ducks/bridge/bridge.ts @@ -14,8 +14,8 @@ import { getTokenExchangeRate } from './utils'; export type BridgeState = { toChainId: CaipChainId | null; - fromToken: BridgeToken; - toToken: BridgeToken; + fromToken: BridgeToken | null; + toToken: BridgeToken | null; fromTokenInputValue: string | null; fromTokenExchangeRate: number | null; // Exchange rate from selected token to the default currency (can be fiat or crypto) toTokenExchangeRate: number | null; // Exchange rate from the selected token to the default currency (can be fiat or crypto) @@ -82,7 +82,7 @@ const bridgeSlice = createSlice({ ...payload, balance: payload.balance ?? '0', string: payload.string ?? '0', - chainId: formatChainIdToCaip(payload.chainId), + chainId: payload.chainId, }; } else { state.fromToken = payload; @@ -94,7 +94,7 @@ const bridgeSlice = createSlice({ ...payload, balance: payload.balance ?? '0', string: payload.string ?? '0', - chainId: formatChainIdToCaip(payload.chainId), + chainId: payload.chainId, address: payload.address || zeroAddress(), }; } else { diff --git a/ui/ducks/bridge/selectors.ts b/ui/ducks/bridge/selectors.ts index 048b8dc30a51..ec54c5830ebc 100644 --- a/ui/ducks/bridge/selectors.ts +++ b/ui/ducks/bridge/selectors.ts @@ -182,7 +182,7 @@ export const getToChain = createSelector( export const getFromToken = createSelector( (state: BridgeAppState) => state.bridge.fromToken, getFromChain, - (fromToken, fromChain): BridgeToken => { + (fromToken, fromChain): BridgeToken | null => { if (!fromChain?.chainId) { return null; } @@ -204,7 +204,7 @@ export const getFromToken = createSelector( }, ); -export const getToToken = (state: BridgeAppState): BridgeToken => { +export const getToToken = (state: BridgeAppState): BridgeToken | null => { return state.bridge.toToken; }; diff --git a/ui/hooks/bridge/useTokensWithFiltering.ts b/ui/hooks/bridge/useTokensWithFiltering.ts index 83e001bfd7d4..854c7dfb093f 100644 --- a/ui/hooks/bridge/useTokensWithFiltering.ts +++ b/ui/hooks/bridge/useTokensWithFiltering.ts @@ -16,6 +16,7 @@ import { import { AssetType } from '../../../shared/constants/transaction'; import { formatChainIdToCaip, + formatChainIdToHex, isNativeAddress, } from '../../../shared/modules/bridge-utils/caip-formatters'; import { CHAIN_ID_TOKEN_IMAGE_MAP } from '../../../shared/constants/network'; @@ -35,6 +36,7 @@ import { type BridgeAppState, getTopAssetsFromFeatureFlags, } from '../../ducks/bridge/selectors'; +import { type BridgeToken } from '../../../shared/types/bridge'; type FilterPredicate = ( symbol: string, @@ -58,11 +60,7 @@ type FilterPredicate = ( */ export const useTokensWithFiltering = ( chainId?: ChainId | Hex | CaipChainId, - tokenToExclude?: null | { - symbol: string; - address?: string; - chainId?: string; - }, + tokenToExclude?: null | Pick, ) => { const allDetectedTokens: Record = useSelector( getAllDetectedTokensForSelectedAddress, @@ -79,15 +77,15 @@ export const useTokensWithFiltering = ( const { value: tokenList, pending: isTokenListLoading } = useAsyncResult< Record >(async () => { - if (chainId && isStrictHexString(chainId)) { - const timestamp = cachedTokens[chainId]?.timestamp; + if (chainId && chainId !== MultichainNetworks.SOLANA) { + const hexChainId = formatChainIdToHex(chainId); + const timestamp = cachedTokens[hexChainId]?.timestamp; // Use cached token data if updated in the last 10 minutes if (timestamp && Date.now() - timestamp <= 10 * MINUTE) { - return cachedTokens[chainId]?.data; + return cachedTokens[hexChainId]?.data; } // Otherwise fetch new token data - - return await fetchBridgeTokens(chainId); + return await fetchBridgeTokens(hexChainId); } if (chainId && formatChainIdToCaip(chainId) === MultichainNetworks.SOLANA) { return await fetchNonEvmTokens(chainId); @@ -118,8 +116,9 @@ export const useTokensWithFiltering = ( if (!chainId || !token || !isStrictHexString(chainId)) { return undefined; } + const hexChainId = formatChainIdToHex(chainId); // Only tokens on the active chain are processed here here - const sharedFields = { ...token, chainId }; + const sharedFields = { ...token, chainId: hexChainId }; if (isNativeAddress(token.address)) { return { @@ -138,12 +137,8 @@ export const useTokensWithFiltering = ( return { ...sharedFields, - ...(tokenList?.[token.address.toLowerCase()] ?? {}), type: AssetType.token, - image: - token.iconUrl ?? - tokenList?.[token.address.toLowerCase()]?.iconUrl ?? - '', + image: token.iconUrl ?? tokenList?.[token.address]?.iconUrl ?? '', // Only tokens with 0 balance are processed here so hardcode empty string balance: '', string: undefined, @@ -273,11 +268,7 @@ export const useTokensWithFiltering = ( const matchedToken = tokenList?.[token_.address]; if ( matchedToken && - shouldAddToken( - matchedToken.symbol, - matchedToken.address ?? undefined, - chainId, - ) + shouldAddToken(matchedToken.symbol, matchedToken.address, chainId) ) { const token = buildTokenData(matchedToken); if (token) { @@ -290,7 +281,7 @@ export const useTokensWithFiltering = ( for (const token_ of Object.values(tokenList)) { if ( token_ && - shouldAddToken(token_.symbol, token_.address ?? undefined, chainId) + shouldAddToken(token_.symbol, token_.address, chainId) ) { const token = buildTokenData(token_); if (token) {