feat: Load default tokens in available swap currencies (#2926)
David Adegoke committed
Feb 19, 2026 at 18:51 UTC
2398e299dc5526c7d67c3e88d48e296ad942b0fb
6 files changed
+88
-9
lib/evm/cw_evm.dart
+4
@@ -307,6 +307,10 @@ class CWEVM extends EVM {
307
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect) =>
308
EVMChainTrezorService(connect);
309
310
+ @override
311
+ List<Erc20Token> getDefaultTokensByChainId(int chainId) =>
312
+ EVMChainDefaultTokens.getDefaultTokensByChainId(chainId);
313
+
314
@override
315
List<String> getDefaultTokenContractAddresses(WalletBase wallet) {
316
final chainId = getSelectedChainId(wallet);
lib/solana/cw_solana.dart
+3
@@ -172,6 +172,9 @@ class CWSolana extends Solana {
172
return (wallet as SolanaWallet).estimatedFee;
173
}
174
175
+ @override
176
+ List<SPLToken> getDefaultSPLTokens() => DefaultSPLTokens().initialSPLTokens;
177
+
178
@override
179
List<String> getDefaultTokenContractAddresses() {
180
return DefaultSPLTokens().initialSPLTokens.map((e) => e.mintAddress).toList();
lib/tron/cw_tron.dart
+3
@@ -134,6 +134,9 @@ class CWTron extends Tron {
134
(wallet as TronWallet).updateScanProviderUsageState(isEnabled);
135
}
136
137
+ @override
138
+ List<TronToken> getDefaultTronTokens() => DefaultTronTokens().initialTronTokens;
139
+
140
@override
141
List<String> getDefaultTokenContractAddresses() {
142
return DefaultTronTokens().initialTronTokens.map((e) => e.contractAddress).toList();
lib/utils/token_utilities.dart
+69
@@ -1,5 +1,7 @@
1
import 'package:cake_wallet/reactions/wallet_connect.dart';
2
import 'package:cake_wallet/evm/evm.dart';
3
+import 'package:cake_wallet/solana/solana.dart';
4
+import 'package:cake_wallet/tron/tron.dart';
5
import 'package:cw_core/cake_hive.dart';
6
import 'package:cw_core/crypto_currency.dart';
7
import 'package:cw_core/currency_for_wallet_type.dart';
@@ -75,6 +77,73 @@ class TokenUtilities {
77
return unique;
78
}
79
80
+ static List<Erc20Token> loadDefaultEvmTokensForSwap() {
81
+ if (evm == null) return [];
82
+
83
+ final tokens = <Erc20Token>[];
84
+ final seen = <String>{};
85
+
86
+ for (final chain in evm!.getAllChains()) {
87
+ for (final token in evm!.getDefaultTokensByChainId(chain.chainId)) {
88
+ final key = '${chain.chainId}|${token.contractAddress.toLowerCase()}';
89
+ if (seen.add(key)) tokens.add(token);
90
+ }
91
+ }
92
+
93
+ return tokens;
94
+ }
95
+
96
+ static List<SPLToken> loadDefaultSolTokensForSwap() =>
97
+ solana != null ? solana!.getDefaultSPLTokens() : [];
98
+
99
+ static List<TronToken> loadDefaultTronTokensForSwap() =>
100
+ tron != null ? tron!.getDefaultTronTokens() : [];
101
+
102
+ static Future<List<Erc20Token>> loadEvmTokensForSwap() async {
103
+ final defaultTokens = loadDefaultEvmTokensForSwap();
104
+ final userTokens = await loadAllUniqueEvmTokens();
105
+
106
+ final seen = <String>{};
107
+ final result = <Erc20Token>[];
108
+
109
+ for (final t in [...defaultTokens, ...userTokens]) {
110
+ final key = '${t.tag ?? 'ETH'}|${t.contractAddress.toLowerCase()}';
111
+ if (seen.add(key)) result.add(t);
112
+ }
113
+
114
+ return result;
115
+ }
116
+
117
+ static Future<List<SPLToken>> loadSolTokensForSwap() async {
118
+ final defaultTokens = loadDefaultSolTokensForSwap();
119
+ final userTokens = await loadAllUniqueSolTokens();
120
+
121
+ final seen = <String>{};
122
+ final result = <SPLToken>[];
123
+
124
+ for (final t in [...defaultTokens, ...userTokens]) {
125
+ final key = t.mintAddress.toLowerCase();
126
+ if (seen.add(key)) result.add(t);
127
+ }
128
+
129
+ return result;
130
+ }
131
+
132
+ static Future<List<TronToken>> loadTronTokensForSwap() async {
133
+ final defaultTokens = loadDefaultTronTokensForSwap();
134
+ final userTokens = await loadAllUniqueTronTokens();
135
+
136
+ final seen = <String>{};
137
+ final result = <TronToken>[];
138
+
139
+ for (final t in [...defaultTokens, ...userTokens]) {
140
+ final key = t.contractAddress.toLowerCase();
141
+ if (seen.add(key)) result.add(t);
142
+ }
143
+
144
+ return result;
145
+ }
146
+
147
/// Finds a token by address across wallets depending on [walletType]
148
/// - EVM chains: match by contractAddress
149
/// - Solana: match by mintAddress
lib/view_model/exchange/exchange_view_model.dart
+6
-9
@@ -1126,12 +1126,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1126
1127
@action
1128
Future<void> _injectUserEthTokensIntoCurrencyLists() async {
1129
- final userTokens = await TokenUtilities.loadAllUniqueEvmTokens();
1130
-
1129
+ final tokens = await TokenUtilities.loadEvmTokensForSwap();
1130
final toAddReceive = <CryptoCurrency>[];
1131
final toAddDeposit = <CryptoCurrency>[];
1132
1134
- for (final token in userTokens) {
1133
+ for (final token in tokens) {
1134
if (!_listContainsToken(receiveCurrencies, token)) toAddReceive.add(token);
1135
if (!_listContainsToken(depositCurrencies, token)) toAddDeposit.add(token);
1136
}
@@ -1164,12 +1163,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1163
1164
@action
1165
Future<void> _injectUserSplTokensIntoCurrencyLists() async {
1167
- final userTokens = await TokenUtilities.loadAllUniqueSolTokens();
1168
-
1166
+ final tokens = await TokenUtilities.loadSolTokensForSwap();
1167
final toAddReceive = <CryptoCurrency>[];
1168
final toAddDeposit = <CryptoCurrency>[];
1169
1172
- for (final token in userTokens) {
1170
+ for (final token in tokens) {
1171
if (!_listContainsSplToken(receiveCurrencies, token)) toAddReceive.add(token);
1172
if (!_listContainsSplToken(depositCurrencies, token)) toAddDeposit.add(token);
1173
}
@@ -1192,12 +1190,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1190
1191
@action
1192
Future<void> _injectUserTronTokensIntoCurrencyLists() async {
1195
- final userTokens = await TokenUtilities.loadAllUniqueTronTokens();
1196
-
1193
+ final tokens = await TokenUtilities.loadTronTokensForSwap();
1194
final toAddReceive = <CryptoCurrency>[];
1195
final toAddDeposit = <CryptoCurrency>[];
1196
1200
- for (final token in userTokens) {
1197
+ for (final token in tokens) {
1198
if (!_listContainsTronToken(receiveCurrencies, token)) toAddReceive.add(token);
1199
if (!_listContainsTronToken(depositCurrencies, token)) toAddDeposit.add(token);
1200
}
tool/configure.dart
+3
@@ -968,6 +968,7 @@ abstract class Solana {
968
String getTokenAddress(CryptoCurrency asset);
969
List<int>? getValidationLength(CryptoCurrency type);
970
double? getEstimateFees(WalletBase wallet);
971
+ List<SPLToken> getDefaultSPLTokens();
972
List<String> getDefaultTokenContractAddresses();
973
List<String> getDefaultTokenSymbols();
974
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);
@@ -1094,6 +1095,7 @@ abstract class Tron {
1095
String? getTronTRC20EstimatedFee(WalletBase wallet);
1096
1097
void updateTronGridUsageState(WalletBase wallet, bool isEnabled);
1098
+ List<TronToken> getDefaultTronTokens();
1099
List<String> getDefaultTokenContractAddresses();
1100
List<String> getDefaultTokenSymbols();
1101
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);
@@ -1490,6 +1492,7 @@ abstract class EVM {
1492
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect);
1493
1494
// Utility methods
1495
+ List<Erc20Token> getDefaultTokensByChainId(int chainId);
1496
List<String> getDefaultTokenContractAddresses(WalletBase wallet);
1497
List<String> getDefaultTokenSymbols(WalletBase wallet);
1498
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);