Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { selectLastSelectedEvmAccount } from '../../../../../selectors/accountsC
import { InternalAccount } from '@metamask/keyring-internal-api';
import { isNonEvmChainId } from '@metamask/bridge-controller';
import { useTokensWithBalance } from '../useTokensWithBalance';
import { BtcScope, SolScope, TrxScope } from '@metamask/keyring-api';
import { BtcScope, SolScope, TrxScope, XlmScope } from '@metamask/keyring-api';

export const useSortedSourceNetworks = () => {
const enabledSourceChains = useSelector(selectEnabledSourceChains);
Expand Down Expand Up @@ -77,6 +77,15 @@ export const useSortedSourceNetworks = () => {
0,
);

// Calculate total fiat value for Stellar (native + tokens)
const xlmTokensWithBalance = useTokensWithBalance({
chainIds: [XlmScope.Pubnet],
});
const xlmFiatTotal = xlmTokensWithBalance.reduce(
(sum, token) => sum + (token.tokenFiatAmount ?? 0),
0,
);

// Sort networks by total fiat value in descending order
const sortedSourceNetworks = useMemo(
() =>
Expand All @@ -90,6 +99,8 @@ export const useSortedSourceNetworks = () => {
totalFiatValue = btcFiatTotal;
} else if (chain.chainId === TrxScope.Mainnet) {
totalFiatValue = trxFiatTotal;
} else if (chain.chainId === XlmScope.Pubnet) {
totalFiatValue = xlmFiatTotal;
} else {
totalFiatValue = getEvmChainTotalFiatValue(chain.chainId);
}
Expand All @@ -106,6 +117,7 @@ export const useSortedSourceNetworks = () => {
solFiatTotal,
btcFiatTotal,
trxFiatTotal,
xlmFiatTotal,
],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,11 @@ describe('CustomNetworkSelector', () => {
selectedBitcoinAccount: { id: 'bitcoin-account' } as InternalAccount,
selectedTronAccount: { id: 'tron-account' } as InternalAccount,
tronNetworks: mockNetworks,
stellarNetworks: mockNetworks,
selectedStellarAccount: { id: 'stellar-account' } as InternalAccount,
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
areAllNetworksSelectedCombined: false,
areAllEvmNetworksSelected: false,
areAllSolanaNetworksSelected: false,
Expand Down Expand Up @@ -470,9 +473,12 @@ describe('CustomNetworkSelector', () => {
selectedSolanaAccount: null,
selectedBitcoinAccount: null,
selectedTronAccount: null,
selectedStellarAccount: null,
tronNetworks: [],
stellarNetworks: [],
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
areAllNetworksSelectedCombined: false,
areAllEvmNetworksSelected: false,
areAllSolanaNetworksSelected: false,
Expand Down Expand Up @@ -518,9 +524,12 @@ describe('CustomNetworkSelector', () => {
selectedSolanaAccount: null,
selectedBitcoinAccount: null,
selectedTronAccount: null,
selectedStellarAccount: null,
tronNetworks: [],
stellarNetworks: [],
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
areAllNetworksSelectedCombined: false,
areAllEvmNetworksSelected: false,
areAllSolanaNetworksSelected: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,10 @@ describe('NetworkMultiSelector', () => {
bitcoinNetworks: networks.filter((n) =>
n.caipChainId.startsWith('bip122:'),
),
tronNetworks: [],
tronNetworks: networks.filter((n) => n.caipChainId.startsWith('tron:')),
stellarNetworks: networks.filter((n) =>
n.caipChainId.startsWith('stellar:'),
),
selectedEvmAccount: networks.some((n) =>
n.caipChainId.startsWith('eip155:'),
)
Expand All @@ -251,11 +254,13 @@ describe('NetworkMultiSelector', () => {
: null,
selectedBitcoinAccount: null,
selectedTronAccount: null,
selectedStellarAccount: null,
areAllNetworksSelectedCombined: areAllSelected,
areAllEvmNetworksSelected: false,
areAllSolanaNetworksSelected: false,
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
});

const setupMockSelectors = (
Expand Down Expand Up @@ -375,15 +380,18 @@ describe('NetworkMultiSelector', () => {
solanaNetworks: mockNetworks,
bitcoinNetworks: mockNetworks,
tronNetworks: mockNetworks,
stellarNetworks: mockNetworks,
selectedEvmAccount: { id: 'evm-account' } as InternalAccount,
selectedSolanaAccount: { id: 'solana-account' } as InternalAccount,
selectedBitcoinAccount: { id: 'bitcoin-account' } as InternalAccount,
selectedTronAccount: { id: 'tron-account' } as InternalAccount,
selectedStellarAccount: { id: 'stellar-account' } as InternalAccount,
areAllNetworksSelectedCombined: false,
areAllEvmNetworksSelected: false,
areAllSolanaNetworksSelected: false,
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
});

mockUseSelector.mockImplementation((selector) => {
Expand Down Expand Up @@ -772,6 +780,7 @@ describe('NetworkMultiSelector', () => {
solanaNetworks: [],
bitcoinNetworks: [],
tronNetworks: [],
stellarNetworks: [],
selectedEvmAccount: { id: 'evm-account' } as InternalAccount,
selectedSolanaAccount: null,
selectedBitcoinAccount: null,
Expand All @@ -780,7 +789,9 @@ describe('NetworkMultiSelector', () => {
areAllSolanaNetworksSelected: false,
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
selectedTronAccount: null,
selectedStellarAccount: null,
});

// Setup selector mock
Expand Down Expand Up @@ -854,12 +865,15 @@ describe('NetworkMultiSelector', () => {
solanaNetworks: mockSolanaNetworks,
bitcoinNetworks: [],
tronNetworks: [],
stellarNetworks: [],
selectedEvmAccount: null,
selectedSolanaAccount: { id: 'solana-account' } as InternalAccount,
selectedBitcoinAccount: null,
selectedTronAccount: null,
selectedStellarAccount: null,
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
areAllNetworksSelectedCombined: true,
areAllEvmNetworksSelected: false,
areAllSolanaNetworksSelected: true,
Expand Down Expand Up @@ -935,6 +949,7 @@ describe('NetworkMultiSelector', () => {
solanaNetworks: [],
bitcoinNetworks: [],
tronNetworks: [],
stellarNetworks: [],
selectedEvmAccount: null,
selectedSolanaAccount: null,
selectedBitcoinAccount: null,
Expand All @@ -943,7 +958,9 @@ describe('NetworkMultiSelector', () => {
areAllSolanaNetworksSelected: false,
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
selectedTronAccount: null,
selectedStellarAccount: null,
});

mockUseSelector.mockImplementation((selector) => {
Expand Down Expand Up @@ -1008,15 +1025,18 @@ describe('NetworkMultiSelector', () => {
solanaNetworks: [],
bitcoinNetworks: [],
tronNetworks: [],
stellarNetworks: [],
selectedEvmAccount: null,
selectedSolanaAccount: null,
selectedBitcoinAccount: null,
selectedTronAccount: null,
selectedStellarAccount: null,
areAllNetworksSelectedCombined: false,
areAllEvmNetworksSelected: false,
areAllSolanaNetworksSelected: false,
areAllBitcoinNetworksSelected: false,
areAllTronNetworksSelected: false,
areAllStellarNetworksSelected: false,
});

mockUseSelector.mockImplementation((selector) => {
Expand Down
4 changes: 3 additions & 1 deletion app/components/UI/QuickBuy/hooks/enrichTokenBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
isNativeAddress,
isSolanaChainId,
} from '@metamask/bridge-controller';
import { BtcScope, TrxScope } from '@metamask/keyring-api';
import { BtcScope, TrxScope, XlmScope } from '@metamask/keyring-api';
import type { BridgeToken } from '../../Bridge/types';
import { formatCurrency } from '../../Bridge/utils/currencyUtils';
import { calcTokenFiatRate } from '../../Bridge/utils/exchange-rates';
Expand Down Expand Up @@ -51,6 +51,7 @@ export interface TokenBalanceDeps {
allNetworkConfigs?: Record<string, { nativeCurrency?: string } | undefined>;
solanaAccount?: { id: string };
tronAccount?: { id: string };
stellarAccount?: { id: string };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is for quick buy and sell, safe for added when only activate if stellar account exist + bridge FF activate

bitcoinAccount?: { id: string };
multichainBalances?: Record<
string,
Expand Down Expand Up @@ -149,6 +150,7 @@ const getNonEvmAccount = (
): { id: string } | undefined => {
if (isSolanaChainId(chainId)) return deps.solanaAccount;
if (chainId === TrxScope.Mainnet) return deps.tronAccount;
if (chainId === XlmScope.Pubnet) return deps.stellarAccount;
if (chainId === BtcScope.Mainnet) return deps.bitcoinAccount;
return undefined;
};
Expand Down
5 changes: 4 additions & 1 deletion app/components/UI/QuickBuy/hooks/usePayWithTokens.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { SolScope, TrxScope, BtcScope } from '@metamask/keyring-api';
import { SolScope, TrxScope, BtcScope, XlmScope } from '@metamask/keyring-api';
import type { CaipChainId } from '@metamask/utils';
import type { BridgeToken } from '../../Bridge/types';
import type { RootState } from '../../../../reducers';
Expand Down Expand Up @@ -54,6 +54,7 @@ export const usePayWithTokens = (): {

const solanaAccount = accountByScope(SolScope.Mainnet);
const tronAccount = accountByScope(TrxScope.Mainnet);
const stellarAccount = accountByScope(XlmScope.Pubnet);
const bitcoinAccount = accountByScope(BtcScope.Mainnet);
const multichainBalances = useSelector(selectMultichainBalances);
const multichainRates = useSelector(selectMultichainAssetsRates);
Expand Down Expand Up @@ -82,6 +83,7 @@ export const usePayWithTokens = (): {
allNetworkConfigs,
solanaAccount: solanaAccount ?? undefined,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is for quick buy and sell, safe for added when only activate if stellar account exist + bridge FF activate

tronAccount: tronAccount ?? undefined,
stellarAccount: stellarAccount ?? undefined,
bitcoinAccount: bitcoinAccount ?? undefined,
multichainBalances,
multichainRates: multichainRates as Record<
Expand Down Expand Up @@ -125,6 +127,7 @@ export const usePayWithTokens = (): {
allNetworkConfigs,
solanaAccount,
tronAccount,
stellarAccount,
bitcoinAccount,
multichainBalances,
multichainRates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
isNativeAddress,
formatChainIdToHex,
} from '@metamask/bridge-controller';
import { SolScope, TrxScope, BtcScope } from '@metamask/keyring-api';
import { SolScope, TrxScope, BtcScope, XlmScope } from '@metamask/keyring-api';
import type { Hex, CaipChainId } from '@metamask/utils';
import type { BridgeToken } from '../../Bridge/types';
import type { RootState } from '../../../../reducers';
Expand Down Expand Up @@ -70,6 +70,9 @@ export const usePositionTokenBalance = (
const tronAccount = useSelector((state: RootState) =>
selectSelectedInternalAccountByScope(state)(TrxScope.Mainnet),
);
const stellarAccount = useSelector((state: RootState) =>
selectSelectedInternalAccountByScope(state)(XlmScope.Pubnet),
);
const bitcoinAccount = useSelector((state: RootState) =>
selectSelectedInternalAccountByScope(state)(BtcScope.Mainnet),
);
Expand Down Expand Up @@ -170,6 +173,7 @@ export const usePositionTokenBalance = (
allNetworkConfigs,
solanaAccount: solanaAccount ?? undefined,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is for quick buy and sell, safe for added when only activate if stellar account exist + bridge FF activate

tronAccount: tronAccount ?? undefined,
stellarAccount: stellarAccount ?? undefined,
bitcoinAccount: bitcoinAccount ?? undefined,
multichainBalances,
multichainRates: multichainRates as Record<
Expand Down Expand Up @@ -228,6 +232,7 @@ export const usePositionTokenBalance = (
accountAddress,
solanaAccount,
tronAccount,
stellarAccount,
bitcoinAccount,
multichainBalances,
multichainRates,
Expand Down
11 changes: 8 additions & 3 deletions app/components/UI/QuickBuy/hooks/useReceiveTokens.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { isNonEvmChainId, isSolanaChainId } from '@metamask/bridge-controller';
import { BtcScope, SolScope, TrxScope } from '@metamask/keyring-api';
import { BtcScope, SolScope, TrxScope, XlmScope } from '@metamask/keyring-api';
import type { CaipChainId } from '@metamask/utils';
import type { BridgeToken } from '../../Bridge/types';
import type { RootState } from '../../../../reducers';
Expand Down Expand Up @@ -54,7 +54,8 @@ const STABLECOIN_CANDIDATES: BridgeToken[] = (() => {
typeof token.chainId === 'string' &&
(token.chainId.startsWith('0x') ||
isSolanaChainId(token.chainId) ||
token.chainId === TrxScope.Mainnet),
token.chainId === TrxScope.Mainnet ||
token.chainId === XlmScope.Pubnet),
);
const seen = new Set(primaries.map(getTokenKey));
const extras = RECEIVE_STABLECOIN_CANDIDATES.filter(
Expand Down Expand Up @@ -137,6 +138,7 @@ export const useReceiveTokens = (
);
const solanaAccount = selectAccountByScope(SolScope.Mainnet);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is for quick buy and sell, safe for added when only activate if stellar account exist + bridge FF activate

const tronAccount = selectAccountByScope(TrxScope.Mainnet);
const stellarAccount = selectAccountByScope(XlmScope.Pubnet);
const bitcoinAccount = selectAccountByScope(BtcScope.Mainnet);

// Non-EVM accounts in the selected group, keyed by the CAIP chain id the
Expand All @@ -146,9 +148,10 @@ export const useReceiveTokens = (
() => ({
[SolScope.Mainnet]: solanaAccount,
[TrxScope.Mainnet]: tronAccount,
[XlmScope.Pubnet]: stellarAccount,
[BtcScope.Mainnet]: bitcoinAccount,
}),
[solanaAccount, tronAccount, bitcoinAccount],
[solanaAccount, tronAccount, stellarAccount, bitcoinAccount],
);

const candidates = useMemo(
Expand Down Expand Up @@ -195,6 +198,7 @@ export const useReceiveTokens = (
allNetworkConfigs,
solanaAccount: solanaAccount ?? undefined,
tronAccount: tronAccount ?? undefined,
stellarAccount: stellarAccount ?? undefined,
bitcoinAccount: bitcoinAccount ?? undefined,
multichainBalances,
multichainRates: multichainRates as Record<
Expand All @@ -219,6 +223,7 @@ export const useReceiveTokens = (
allNetworkConfigs,
solanaAccount,
tronAccount,
stellarAccount,
bitcoinAccount,
multichainBalances,
multichainRates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { useSearchTracking } from '../../hooks/useSearchTracking/useSearchTracki
import { FilterButton } from '../../components/FilterBar/FilterBar';
import TokenListPageLayout from '../../components/TokenListPageLayout/TokenListPageLayout';
import { TRENDING_NETWORKS_LIST } from '../../utils/trendingNetworksList';
import { useTrendingChainIds } from '../../hooks/useTrendingChainIds/useTrendingChainIds';
import type { Theme } from '../../../../../util/theme/models';
import { useABTest } from '../../../../../hooks/useABTest';
import {
Expand Down Expand Up @@ -142,6 +143,13 @@ const TrendingTokensFullView = () => {
const [quickTradeToken, setQuickTradeToken] = useState<TrendingAsset | null>(
null,
);
const trendingChainIds = useTrendingChainIds();
const trendingNetworks = useMemo(() => {
const allowedChainIds = new Set(trendingChainIds);
return TRENDING_NETWORKS_LIST.filter((network) =>
allowedChainIds.has(network.caipChainId),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

gated by FF

);
}, [trendingChainIds]);
const { variant: quickBuyVariant } = useABTest(
EXPLORE_QUICK_BUY_AB_KEY,
EXPLORE_QUICK_BUY_VARIANTS,
Expand Down Expand Up @@ -303,7 +311,7 @@ const TrendingTokensFullView = () => {
searchResults={searchResults}
isLoading={isLoading}
onRefresh={handleRefresh}
allowedNetworks={TRENDING_NETWORKS_LIST}
allowedNetworks={trendingNetworks}
extraFilters={timeFilterButton}
onLoadMore={loadMore}
isLoadingMore={isLoadingMore}
Expand Down
Loading
Loading