Skip to content

Commit

Permalink
feat(asset): Add legacy asset transition helpers
Browse files Browse the repository at this point in the history
Implement a set of extensions used while transitioning KW to the KDF SDK.

NB: These likely will be removed in the future.
  • Loading branch information
CharlVS committed Dec 12, 2024
1 parent 2707fc8 commit 0643805
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/komodo_defi_sdk/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
include: package:very_good_analysis/analysis_options.6.0.0.yaml
analyzer:
errors:
use_if_null_to_convert_nulls_to_bools: ignore
1 change: 1 addition & 0 deletions packages/komodo_defi_sdk/lib/src/assets/_assets_index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export 'asset_extensions.dart';
export 'asset_history_storage.dart';
export 'asset_manager.dart';
export 'balance_manager.dart';
export 'legacy_asset_extensions.dart';
6 changes: 3 additions & 3 deletions packages/komodo_defi_sdk/lib/src/assets/asset_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import 'dart:collection';

import 'package:komodo_coins/komodo_coins.dart';
import 'package:komodo_defi_local_auth/komodo_defi_local_auth.dart';
import 'package:komodo_defi_sdk/src/activation/activation_manager.dart';
import 'package:komodo_defi_sdk/src/assets/asset_extensions.dart';
import 'package:komodo_defi_sdk/src/assets/asset_history_storage.dart';
import 'package:komodo_defi_sdk/src/_internal_exports.dart';
import 'package:komodo_defi_sdk/src/sdk/sdk_config.dart';
import 'package:komodo_defi_types/komodo_defi_types.dart';

Expand Down Expand Up @@ -49,6 +47,8 @@ class AssetManager {

_orderedCoins.addAll(_coins.all);

initTickerIndex();

final currentUser = await _auth.currentUser;
await _onAuthStateChanged(currentUser);

Expand Down
152 changes: 152 additions & 0 deletions packages/komodo_defi_sdk/lib/src/assets/legacy_asset_extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// This file contains a set of extensions used while transitioning KW to the
// KDF SDK.
// NB: These likely will be removed in the future.

import 'package:komodo_defi_sdk/src/_internal_exports.dart';
import 'package:komodo_defi_sdk/src/komodo_defi_sdk.dart';
import 'package:komodo_defi_types/komodo_defi_types.dart';
import 'package:mutex/mutex.dart';

/// Message used for deprecation warnings
const _deprecatedMessage =
'This extension/class/method is intended for use while transitioning KW to the KDF SDK. \n'
'NB: These likely will be removed in the future.';

/// Extension providing deprecated ticker-based asset lookup functionality
/// while transitioning from KW to KDF SDK.
///
/// Example usage:
/// ```dart
/// // Initialize the index
/// await assetManager.initTickerIndex();
///
/// // Look up assets by ticker
/// final btcAssets = assetManager.assetsFromTicker('BTC');
/// print('Found ${btcAssets.length} BTC assets');
///
/// // Access assets across chains
/// for (final asset in btcAssets) {
/// print('${asset.id.name} on ${asset.protocol.subClass.formatted}');
/// }
/// ```
@Deprecated(_deprecatedMessage)
extension AssetTickerIndexExtension on AssetManager {
static final Map<String, Set<Asset>> _tickerIndex = {};
static bool _isInitialized = false;
static final _lock = Mutex();

/// Initializes the ticker index. Must be called before
/// using [assetsFromTicker].
///
/// Thread-safe and idempotent - can be called multiple times safely.
///
/// Called as part of KomodoDefiSdk initialization.
///
/// Example:
/// ```dart
/// final sdk = KomodoDefiSdk();
/// await sdk.init();
/// ```
Future<void> initTickerIndex() async {
await _lock.protect(() async {
if (_isInitialized) return;
_tickerIndex
..clear()
..addAll(_buildTickerIndex(availableOrdered.values));
_isInitialized = true;
});
}

/// Internal method to build the ticker-to-assets index
Map<String, Set<Asset>> _buildTickerIndex(Iterable<Asset> assets) {
final index = <String, Set<Asset>>{};
for (final asset in assets) {
(index[asset.id.id] ??= {}).add(asset);
}
return Map.unmodifiable(index);
}

/// Returns all assets matching the given ticker symbol.
///
/// Must call [initTickerIndex] before using this method.
/// Returns an unmodifiable set to prevent accidental modifications.
///
/// Example:
/// ```dart
/// final ethAssets = assetManager.assetsFromTicker('ETH');
/// final mainnetEth = ethAssets.firstWhere((a) => !a.protocol.isTestnet);
/// ```
@Deprecated(_deprecatedMessage)
Set<Asset> assetsFromTicker(String ticker) {
assert(
_isInitialized,
'Ticker index not initialized. Call initTickerIndex() first.',
);
return Set<Asset>.unmodifiable(_tickerIndex[ticker] ?? {});
}

/// Cleans up the ticker index. Call when the manager is no longer needed.
void dispose() {
_tickerIndex.clear();
_isInitialized = false;
}

// Internal methods for maintaining the index
// ignore: unused_element
Future<void> _updateIndex(Asset asset, {bool remove = false}) async {
if (!_isInitialized) return;
await _lock.protect(() async {
_updateTickerIndex(asset, remove: remove);
});
}

void _updateTickerIndex(Asset asset, {bool remove = false}) {
if (remove) {
_tickerIndex[asset.id.id]?.remove(asset);
if (_tickerIndex[asset.id.id]?.isEmpty == true) {
_tickerIndex.remove(asset.id.id);
}
} else {
(_tickerIndex[asset.id.id] ??= {}).add(asset);
}
}
}

/// Shorthand extension for accessing assets by ticker directly from Asset class
@Deprecated(_deprecatedMessage)
extension AssetTickerShortExtension on Asset {
/// Static helper to find assets by ticker. Optionally accepts a specific
/// SDK instance. Passing the SDK is recommended if available.
///
/// NB: Currently there are no instances where we have multiple asset IDs with
/// the same ticker, however this has been the case in the past and may be
/// in the future again.
///
/// Example:
/// ```dart
/// final btcAssets = Asset.byTicker('BTC', _sdk /* sdk is optional, but recommended if available */);
/// print('Found ${btcAssets.length} BTC assets');
/// ```
@Deprecated(_deprecatedMessage)
static Set<Asset> byTicker(String ticker, [KomodoDefiSdk? sdk]) {
return (sdk ?? KomodoDefiSdk.global).assets.assetsFromTicker(ticker);
}
}

/// Extension for backwards compatibility with pubkey operations
@Deprecated(_deprecatedMessage)
extension AssetPubkeysExtension on Asset {
/// Fetches pubkeys for this asset. Optionally accepts a
/// specific SDK instance. Passing the SDK is recommended if available.
///
/// Example:
/// ```dart
/// final btcAsset = Asset.byTicker('BTC').first;
/// final pubkeys = await btcAsset.getPubkeys();
/// print('BTC addresses: ${pubkeys.keys.map((k) => k.address).join(", ")}');
/// ```
@Deprecated(_deprecatedMessage)
Future<AssetPubkeys> getPubkeys([KomodoDefiSdk? sdk]) {
return (sdk ?? KomodoDefiSdk.global).pubkeys.getPubkeys(this);
}
}
7 changes: 7 additions & 0 deletions packages/komodo_defi_sdk/lib/src/komodo_defi_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ class KomodoDefiSdk with SecureRpcPasswordMixin {
final IKdfHostConfig? _hostConfig;
final KomodoDefiSdkConfig _config;

/// The global instance of the [KomodoDefiSdk].
///
/// Avoid using this unless the SDK instance is not available in the context
/// from which it is being accessed. This allows us to keep the flexibility
/// for future expansions to support multiple SDK instances at once. However,
/// there are no plans to support this at the moment, but it will reduce the
/// work needed to support it in the future.
static KomodoDefiSdk get global => _instance!;

KomodoDefiFramework? _kdfFramework;
Expand Down

0 comments on commit 0643805

Please sign in to comment.