diff --git a/packages/komodo_coins/lib/src/asset_filter.dart b/packages/komodo_coins/lib/src/asset_filter.dart index 89bda79d..54a3cee2 100644 --- a/packages/komodo_coins/lib/src/asset_filter.dart +++ b/packages/komodo_coins/lib/src/asset_filter.dart @@ -1,15 +1,24 @@ +import 'package:equatable/equatable.dart'; import 'package:komodo_defi_types/komodo_defi_type_utils.dart'; import 'package:komodo_defi_types/komodo_defi_types.dart'; /// Strategy interface for filtering assets based on coin configuration. -abstract class AssetFilterStrategy { +abstract class AssetFilterStrategy extends Equatable { + const AssetFilterStrategy(this.name); + + /// A unique name for the strategy used for comparison and caching. + final String name; + /// Returns `true` if the asset should be included. bool shouldInclude(Asset asset, JsonMap coinConfig); + + @override + List get props => [name]; } /// Default strategy that includes all assets. -class NoAssetFilterStrategy implements AssetFilterStrategy { - const NoAssetFilterStrategy(); +class NoAssetFilterStrategy extends AssetFilterStrategy { + const NoAssetFilterStrategy() : super('none'); @override bool shouldInclude(Asset asset, JsonMap coinConfig) => true; @@ -21,8 +30,8 @@ class NoAssetFilterStrategy implements AssetFilterStrategy { /// activate on Trezor. /// ERC20, Arbitrum, and MATIC explicitly do not support Trezor via KDF /// at this time, so they are also excluded. -class TrezorAssetFilterStrategy implements AssetFilterStrategy { - const TrezorAssetFilterStrategy(); +class TrezorAssetFilterStrategy extends AssetFilterStrategy { + const TrezorAssetFilterStrategy() : super('trezor'); @override bool shouldInclude(Asset asset, JsonMap coinConfig) { @@ -37,8 +46,8 @@ class TrezorAssetFilterStrategy implements AssetFilterStrategy { } /// Filters out assets that are not UTXO-based chains. -class UtxoAssetFilterStrategy implements AssetFilterStrategy { - const UtxoAssetFilterStrategy(); +class UtxoAssetFilterStrategy extends AssetFilterStrategy { + const UtxoAssetFilterStrategy() : super('utxo'); @override bool shouldInclude(Asset asset, JsonMap coinConfig) { @@ -51,8 +60,8 @@ class UtxoAssetFilterStrategy implements AssetFilterStrategy { /// This includes various EVM-compatible chains like Ethereum, Binance, etc. /// This strategy is necessary for external wallets like Metamask or /// WalletConnect. -class EvmAssetFilterStrategy implements AssetFilterStrategy { - const EvmAssetFilterStrategy(); +class EvmAssetFilterStrategy extends AssetFilterStrategy { + const EvmAssetFilterStrategy() : super('evm'); @override bool shouldInclude(Asset asset, JsonMap coinConfig) => diff --git a/packages/komodo_coins/lib/src/komodo_coins_base.dart b/packages/komodo_coins/lib/src/komodo_coins_base.dart index 10f2a2d7..444af7db 100644 --- a/packages/komodo_coins/lib/src/komodo_coins_base.dart +++ b/packages/komodo_coins/lib/src/komodo_coins_base.dart @@ -18,6 +18,7 @@ class KomodoCoins { } Map? _assets; + final Map> _filterCache = {}; @mustCallSuper Future init() async { @@ -81,9 +82,10 @@ class KomodoCoins { coinData, knownIds: platformIds, ).map( - (id) => id.isChildAsset - ? AssetId.parse(coinData, knownIds: platformIds) - : id, + (id) => + id.isChildAsset + ? AssetId.parse(coinData, knownIds: platformIds) + : id, ); // Create Asset instance for each valid AssetId @@ -124,6 +126,10 @@ class KomodoCoins { if (!isInitialized) { throw StateError('Assets have not been initialized. Call init() first.'); } + final cacheKey = strategy.name; + final cached = _filterCache[cacheKey]; + if (cached != null) return cached; + final result = {}; for (final entry in _assets!.entries) { final config = entry.value.protocol.config; @@ -131,6 +137,7 @@ class KomodoCoins { result[entry.key] = entry.value; } } + _filterCache[cacheKey] = result; return result; } diff --git a/packages/komodo_defi_sdk/lib/src/assets/asset_manager.dart b/packages/komodo_defi_sdk/lib/src/assets/asset_manager.dart index cb92984f..b968f5a8 100644 --- a/packages/komodo_defi_sdk/lib/src/assets/asset_manager.dart +++ b/packages/komodo_defi_sdk/lib/src/assets/asset_manager.dart @@ -65,6 +65,7 @@ class AssetManager implements IAssetProvider { late final AssetIdMap _orderedCoins; StreamSubscription? _authSubscription; bool _isDisposed = false; + AssetFilterStrategy? _currentFilterStrategy; /// NB: This cannot be used during initialization. This is a workaround /// to publicly expose the activation manager's activation methods. @@ -95,9 +96,11 @@ class AssetManager implements IAssetProvider { } void _refreshCoins(AssetFilterStrategy strategy) { + if (_currentFilterStrategy?.name == strategy.name) return; _orderedCoins ..clear() ..addAll(_coins.filteredAssets(strategy)); + _currentFilterStrategy = strategy; } /// Applies a new [strategy] for filtering available assets.