From 2398e299dc5526c7d67c3e88d48e296ad942b0fb Mon Sep 17 00:00:00 2001 From: David Adegoke <64401859+Blazebrain@users.noreply.github.com> Date: Thu, 19 Feb 2026 18:51:29 +0100 Subject: [PATCH] feat: Load default tokens in available swap currencies (#2926) --- lib/evm/cw_evm.dart | 4 ++ lib/solana/cw_solana.dart | 3 + lib/tron/cw_tron.dart | 3 + lib/utils/token_utilities.dart | 69 +++++++++++++++++++ .../exchange/exchange_view_model.dart | 15 ++-- tool/configure.dart | 3 + 6 files changed, 88 insertions(+), 9 deletions(-) diff --git a/lib/evm/cw_evm.dart b/lib/evm/cw_evm.dart index 984599690..705013779 100644 --- a/lib/evm/cw_evm.dart +++ b/lib/evm/cw_evm.dart @@ -307,6 +307,10 @@ class CWEVM extends EVM { HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect) => EVMChainTrezorService(connect); + @override + List getDefaultTokensByChainId(int chainId) => + EVMChainDefaultTokens.getDefaultTokensByChainId(chainId); + @override List getDefaultTokenContractAddresses(WalletBase wallet) { final chainId = getSelectedChainId(wallet); diff --git a/lib/solana/cw_solana.dart b/lib/solana/cw_solana.dart index 7d541fa74..55d5448ba 100644 --- a/lib/solana/cw_solana.dart +++ b/lib/solana/cw_solana.dart @@ -172,6 +172,9 @@ class CWSolana extends Solana { return (wallet as SolanaWallet).estimatedFee; } + @override + List getDefaultSPLTokens() => DefaultSPLTokens().initialSPLTokens; + @override List getDefaultTokenContractAddresses() { return DefaultSPLTokens().initialSPLTokens.map((e) => e.mintAddress).toList(); diff --git a/lib/tron/cw_tron.dart b/lib/tron/cw_tron.dart index 8c73d684d..0b6dd8cba 100644 --- a/lib/tron/cw_tron.dart +++ b/lib/tron/cw_tron.dart @@ -134,6 +134,9 @@ class CWTron extends Tron { (wallet as TronWallet).updateScanProviderUsageState(isEnabled); } + @override + List getDefaultTronTokens() => DefaultTronTokens().initialTronTokens; + @override List getDefaultTokenContractAddresses() { return DefaultTronTokens().initialTronTokens.map((e) => e.contractAddress).toList(); diff --git a/lib/utils/token_utilities.dart b/lib/utils/token_utilities.dart index e76544f4a..616c874c0 100644 --- a/lib/utils/token_utilities.dart +++ b/lib/utils/token_utilities.dart @@ -1,5 +1,7 @@ import 'package:cake_wallet/reactions/wallet_connect.dart'; import 'package:cake_wallet/evm/evm.dart'; +import 'package:cake_wallet/solana/solana.dart'; +import 'package:cake_wallet/tron/tron.dart'; import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/currency_for_wallet_type.dart'; @@ -75,6 +77,73 @@ class TokenUtilities { return unique; } + static List loadDefaultEvmTokensForSwap() { + if (evm == null) return []; + + final tokens = []; + final seen = {}; + + for (final chain in evm!.getAllChains()) { + for (final token in evm!.getDefaultTokensByChainId(chain.chainId)) { + final key = '${chain.chainId}|${token.contractAddress.toLowerCase()}'; + if (seen.add(key)) tokens.add(token); + } + } + + return tokens; + } + + static List loadDefaultSolTokensForSwap() => + solana != null ? solana!.getDefaultSPLTokens() : []; + + static List loadDefaultTronTokensForSwap() => + tron != null ? tron!.getDefaultTronTokens() : []; + + static Future> loadEvmTokensForSwap() async { + final defaultTokens = loadDefaultEvmTokensForSwap(); + final userTokens = await loadAllUniqueEvmTokens(); + + final seen = {}; + final result = []; + + for (final t in [...defaultTokens, ...userTokens]) { + final key = '${t.tag ?? 'ETH'}|${t.contractAddress.toLowerCase()}'; + if (seen.add(key)) result.add(t); + } + + return result; + } + + static Future> loadSolTokensForSwap() async { + final defaultTokens = loadDefaultSolTokensForSwap(); + final userTokens = await loadAllUniqueSolTokens(); + + final seen = {}; + final result = []; + + for (final t in [...defaultTokens, ...userTokens]) { + final key = t.mintAddress.toLowerCase(); + if (seen.add(key)) result.add(t); + } + + return result; + } + + static Future> loadTronTokensForSwap() async { + final defaultTokens = loadDefaultTronTokensForSwap(); + final userTokens = await loadAllUniqueTronTokens(); + + final seen = {}; + final result = []; + + for (final t in [...defaultTokens, ...userTokens]) { + final key = t.contractAddress.toLowerCase(); + if (seen.add(key)) result.add(t); + } + + return result; + } + /// Finds a token by address across wallets depending on [walletType] /// - EVM chains: match by contractAddress /// - Solana: match by mintAddress diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 69152d707..929dde3e7 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -1126,12 +1126,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with @action Future _injectUserEthTokensIntoCurrencyLists() async { - final userTokens = await TokenUtilities.loadAllUniqueEvmTokens(); - + final tokens = await TokenUtilities.loadEvmTokensForSwap(); final toAddReceive = []; final toAddDeposit = []; - for (final token in userTokens) { + for (final token in tokens) { if (!_listContainsToken(receiveCurrencies, token)) toAddReceive.add(token); if (!_listContainsToken(depositCurrencies, token)) toAddDeposit.add(token); } @@ -1164,12 +1163,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with @action Future _injectUserSplTokensIntoCurrencyLists() async { - final userTokens = await TokenUtilities.loadAllUniqueSolTokens(); - + final tokens = await TokenUtilities.loadSolTokensForSwap(); final toAddReceive = []; final toAddDeposit = []; - for (final token in userTokens) { + for (final token in tokens) { if (!_listContainsSplToken(receiveCurrencies, token)) toAddReceive.add(token); if (!_listContainsSplToken(depositCurrencies, token)) toAddDeposit.add(token); } @@ -1192,12 +1190,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with @action Future _injectUserTronTokensIntoCurrencyLists() async { - final userTokens = await TokenUtilities.loadAllUniqueTronTokens(); - + final tokens = await TokenUtilities.loadTronTokensForSwap(); final toAddReceive = []; final toAddDeposit = []; - for (final token in userTokens) { + for (final token in tokens) { if (!_listContainsTronToken(receiveCurrencies, token)) toAddReceive.add(token); if (!_listContainsTronToken(depositCurrencies, token)) toAddDeposit.add(token); } diff --git a/tool/configure.dart b/tool/configure.dart index beebcb6d6..5a5210439 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -968,6 +968,7 @@ abstract class Solana { String getTokenAddress(CryptoCurrency asset); List? getValidationLength(CryptoCurrency type); double? getEstimateFees(WalletBase wallet); + List getDefaultSPLTokens(); List getDefaultTokenContractAddresses(); List getDefaultTokenSymbols(); bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress); @@ -1094,6 +1095,7 @@ abstract class Tron { String? getTronTRC20EstimatedFee(WalletBase wallet); void updateTronGridUsageState(WalletBase wallet, bool isEnabled); + List getDefaultTronTokens(); List getDefaultTokenContractAddresses(); List getDefaultTokenSymbols(); bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress); @@ -1490,6 +1492,7 @@ abstract class EVM { HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect); // Utility methods + List getDefaultTokensByChainId(int chainId); List getDefaultTokenContractAddresses(WalletBase wallet); List getDefaultTokenSymbols(WalletBase wallet); bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);