diff --git a/packages/komodo_defi_sdk/lib/src/activation/activation_manager.dart b/packages/komodo_defi_sdk/lib/src/activation/activation_manager.dart index 3132dbf1..f1254602 100644 --- a/packages/komodo_defi_sdk/lib/src/activation/activation_manager.dart +++ b/packages/komodo_defi_sdk/lib/src/activation/activation_manager.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:komodo_defi_local_auth/komodo_defi_local_auth.dart'; +import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart'; import 'package:komodo_defi_sdk/src/_internal_exports.dart'; import 'package:komodo_defi_sdk/src/balances/balance_manager.dart'; import 'package:komodo_defi_types/komodo_defi_types.dart'; @@ -17,13 +18,12 @@ class ActivationManager { this._customTokenHistory, this._assetLookup, this._balanceManager, - ) : _activator = ActivationStrategyFactory.createStrategy(_client); + ); final ApiClient _client; final KomodoDefiLocalAuth _auth; final AssetHistoryStorage _assetHistory; final CustomAssetHistoryStorage _customTokenHistory; - final SmartAssetActivator _activator; final IAssetLookup _assetLookup; final IBalanceManager _balanceManager; final _activationMutex = Mutex(); @@ -97,7 +97,19 @@ class ActivationManager { ); try { - await for (final progress in _activator.activate( + // Get the current user's auth options to retrieve privKeyPolicy + final currentUser = await _auth.currentUser; + final privKeyPolicy = + currentUser?.walletId.authOptions.privKeyPolicy ?? + PrivateKeyPolicy.contextPrivKey; + + // Create activator with the user's privKeyPolicy + final activator = ActivationStrategyFactory.createStrategy( + _client, + privKeyPolicy, + ); + + await for (final progress in activator.activate( parentAsset ?? group.primary, group.children?.toList(), )) { diff --git a/packages/komodo_defi_sdk/lib/src/activation/base_strategies/activation_strategy_factory.dart b/packages/komodo_defi_sdk/lib/src/activation/base_strategies/activation_strategy_factory.dart index e67e3575..2d17c678 100644 --- a/packages/komodo_defi_sdk/lib/src/activation/base_strategies/activation_strategy_factory.dart +++ b/packages/komodo_defi_sdk/lib/src/activation/base_strategies/activation_strategy_factory.dart @@ -1,19 +1,23 @@ +import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart'; import 'package:komodo_defi_sdk/src/activation/_activation.dart'; import 'package:komodo_defi_types/komodo_defi_types.dart'; /// Factory for creating the complete activation strategy stack class ActivationStrategyFactory { - static SmartAssetActivator createStrategy(ApiClient client) { + static SmartAssetActivator createStrategy( + ApiClient client, + PrivateKeyPolicy privKeyPolicy, + ) { return SmartAssetActivator( client, CompositeAssetActivator(client, [ // BCH strategy needs to be before UTXO strategy to handle the special case // BchActivationStrategy(client), - UtxoActivationStrategy(client), + UtxoActivationStrategy(client, privKeyPolicy), Erc20ActivationStrategy(client), // SlpActivationStrategy(client), TendermintActivationStrategy(client), - QtumActivationStrategy(client), + QtumActivationStrategy(client, privKeyPolicy), ZhtlcActivationStrategy(client), CustomErc20ActivationStrategy(client), ]), diff --git a/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/qtum_activation_strategy.dart b/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/qtum_activation_strategy.dart index 0c56f16d..9f4b80ea 100644 --- a/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/qtum_activation_strategy.dart +++ b/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/qtum_activation_strategy.dart @@ -1,8 +1,11 @@ +import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart'; import 'package:komodo_defi_sdk/src/activation/_activation.dart'; import 'package:komodo_defi_types/komodo_defi_types.dart'; class QtumActivationStrategy extends ProtocolActivationStrategy { - const QtumActivationStrategy(super.client); + const QtumActivationStrategy(super.client, this.privKeyPolicy); + + final PrivateKeyPolicy privKeyPolicy; @override Set get supportedProtocols => {CoinSubClass.qrc20}; @@ -34,7 +37,9 @@ class QtumActivationStrategy extends ProtocolActivationStrategy { try { final taskResponse = await client.rpc.qtum.enableQtumInit( ticker: asset.id.id, - params: asset.protocol.defaultActivationParams(), + params: asset.protocol.defaultActivationParams( + privKeyPolicy: privKeyPolicy, + ), ); var isComplete = false; @@ -100,7 +105,7 @@ class QtumActivationStrategy extends ProtocolActivationStrategy { } ({String status, double percentage, String step, Map info}) - _parseQtumStatus(String status) { + _parseQtumStatus(String status) { switch (status) { case 'ConnectingNodes': return ( diff --git a/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/utxo_activation_strategy.dart b/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/utxo_activation_strategy.dart index a3fe2c7f..255959bd 100644 --- a/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/utxo_activation_strategy.dart +++ b/packages/komodo_defi_sdk/lib/src/activation/protocol_strategies/utxo_activation_strategy.dart @@ -1,15 +1,18 @@ +import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart'; import 'package:komodo_defi_sdk/src/activation/_activation.dart'; import 'package:komodo_defi_types/komodo_defi_types.dart'; class UtxoActivationStrategy extends ProtocolActivationStrategy { - const UtxoActivationStrategy(super.client); + const UtxoActivationStrategy(super.client, this.privKeyPolicy); + + final PrivateKeyPolicy privKeyPolicy; @override Set get supportedProtocols => { - CoinSubClass.utxo, - CoinSubClass.smartChain, - // CoinSubClass.smartBch, - }; + CoinSubClass.utxo, + CoinSubClass.smartChain, + // CoinSubClass.smartBch, + }; @override bool get supportsBatchActivation => false; @@ -32,7 +35,11 @@ class UtxoActivationStrategy extends ProtocolActivationStrategy { stepCount: 5, additionalInfo: { 'chainType': protocol.subClass.formatted, - 'mode': protocol.defaultActivationParams().mode?.rpc, + 'mode': + protocol + .defaultActivationParams(privKeyPolicy: privKeyPolicy) + .mode + ?.rpc, 'txVersion': protocol.txVersion, 'pubtype': protocol.pubtype, }, @@ -51,7 +58,7 @@ class UtxoActivationStrategy extends ProtocolActivationStrategy { final taskResponse = await client.rpc.utxo.enableUtxoInit( ticker: asset.id.id, - params: protocol.defaultActivationParams(), + params: protocol.defaultActivationParams(privKeyPolicy: privKeyPolicy), ); yield ActivationProgress( @@ -131,7 +138,7 @@ class UtxoActivationStrategy extends ProtocolActivationStrategy { } ({String status, double percentage, String step, Map info}) - _parseUtxoStatus(String status) { + _parseUtxoStatus(String status) { switch (status) { case 'ConnectingElectrum': return ( diff --git a/packages/komodo_defi_types/lib/src/auth/auth_options.dart b/packages/komodo_defi_types/lib/src/auth/auth_options.dart index 69d03cd4..8bb9785b 100644 --- a/packages/komodo_defi_types/lib/src/auth/auth_options.dart +++ b/packages/komodo_defi_types/lib/src/auth/auth_options.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart'; import 'package:komodo_defi_types/komodo_defi_type_utils.dart'; import 'package:komodo_defi_types/komodo_defi_types.dart'; @@ -6,6 +7,7 @@ class AuthOptions extends Equatable { const AuthOptions({ required this.derivationMethod, this.allowWeakPassword = false, + this.privKeyPolicy = PrivateKeyPolicy.contextPrivKey, }); factory AuthOptions.fromJson(JsonMap json) { @@ -13,19 +15,25 @@ class AuthOptions extends Equatable { derivationMethod: DerivationMethod.parse(json.value('derivation_method')), allowWeakPassword: json.valueOrNull('allow_weak_password') ?? false, + privKeyPolicy: json.valueOrNull('priv_key_policy') == 'Trezor' + ? PrivateKeyPolicy.trezor + : PrivateKeyPolicy.contextPrivKey, ); } final DerivationMethod derivationMethod; final bool allowWeakPassword; + final PrivateKeyPolicy privKeyPolicy; JsonMap toJson() { return { 'derivation_method': derivationMethod.toString(), 'allow_weak_password': allowWeakPassword, + 'priv_key_policy': privKeyPolicy.id, }; } @override - List get props => [derivationMethod, allowWeakPassword]; + List get props => + [derivationMethod, allowWeakPassword, privKeyPolicy]; } diff --git a/packages/komodo_defi_types/lib/src/coin_classes/protocol_class.dart b/packages/komodo_defi_types/lib/src/coin_classes/protocol_class.dart index f613c661..fac51d59 100644 --- a/packages/komodo_defi_types/lib/src/coin_classes/protocol_class.dart +++ b/packages/komodo_defi_types/lib/src/coin_classes/protocol_class.dart @@ -17,25 +17,23 @@ abstract class ProtocolClass with ExplorerUrlMixin implements Equatable { factory ProtocolClass.fromJson(JsonMap json, {CoinSubClass? requestedType}) { final primaryType = requestedType ?? CoinSubClass.parse(json.value('type')); - final otherTypes = - json + final otherTypes = json .valueOrNull>('other_types') ?.map((type) => CoinSubClass.parse(type as String)) .toList() ?? []; // If a specific type is requested, update the config - final configToUse = - requestedType != null && requestedType != primaryType - ? (JsonMap.from(json) - ..['type'] = requestedType.toString().split('.').last) - : json; + final configToUse = requestedType != null && requestedType != primaryType + ? (JsonMap.of(json) + ..['type'] = requestedType.toString().split('.').last) + : json; try { return switch (primaryType) { CoinSubClass.utxo || CoinSubClass.smartChain => UtxoProtocol.fromJson( - configToUse, - supportedProtocols: otherTypes, - ), + configToUse, + supportedProtocols: otherTypes, + ), // SLP is no longer supported by its own protocol (BCH) // CoinSubClass.slp => SlpProtocol.fromJson( // configToUse, @@ -55,19 +53,23 @@ abstract class ProtocolClass with ExplorerUrlMixin implements Equatable { CoinSubClass.ewt || CoinSubClass.hecoChain || CoinSubClass.rskSmartBitcoin || - CoinSubClass.erc20 => Erc20Protocol.fromJson(json), + CoinSubClass.erc20 => + Erc20Protocol.fromJson(json), CoinSubClass.qrc20 => QtumProtocol.fromJson(json), CoinSubClass.zhtlc => ZhtlcProtocol.fromJson(json), CoinSubClass.tendermintToken || - CoinSubClass.tendermint => TendermintProtocol.fromJson( - configToUse, - supportedProtocols: otherTypes, - ), + CoinSubClass.tendermint => + TendermintProtocol.fromJson( + configToUse, + supportedProtocols: otherTypes, + ), CoinSubClass.sia => SiaProtocol.fromJson( - configToUse, - supportedProtocols: otherTypes, - ), - CoinSubClass.slp || CoinSubClass.smartBch || CoinSubClass.unknown => + configToUse, + supportedProtocols: otherTypes, + ), + CoinSubClass.slp || + CoinSubClass.smartBch || + CoinSubClass.unknown => throw UnsupportedProtocolException( 'Unsupported protocol type: ${primaryType.formatted}', ), @@ -110,13 +112,14 @@ abstract class ProtocolClass with ExplorerUrlMixin implements Equatable { /// Convert protocol back to JSON representation JsonMap toJson() => { - ...config, - 'sub_class': subClass.toString().split('.').last, - 'is_custom_token': isCustomToken, - if (supportedProtocols.isNotEmpty) - 'other_types': - supportedProtocols.map((p) => p.toString().split('.').last).toList(), - }; + ...config, + 'sub_class': subClass.toString().split('.').last, + 'is_custom_token': isCustomToken, + if (supportedProtocols.isNotEmpty) + 'other_types': supportedProtocols + .map((p) => p.toString().split('.').last) + .toList(), + }; /// Check if this protocol supports a given protocol type bool supportsProtocolType(CoinSubClass type) { @@ -133,20 +136,24 @@ abstract class ProtocolClass with ExplorerUrlMixin implements Equatable { return ProtocolClass.fromJson(variantConfig); } - ActivationParams defaultActivationParams() => - ActivationParams.fromConfigJson(config); + ActivationParams defaultActivationParams({ + PrivateKeyPolicy privKeyPolicy = PrivateKeyPolicy.contextPrivKey, + }) => + ActivationParams.fromConfigJson(config).genericCopyWith( + privKeyPolicy: privKeyPolicy, + ); String? get contractAddress => config.valueOrNull('contract_address'); @override List get props => [ - subClass, - supportedProtocols, - isCustomToken, - requiresHdWallet, - derivationPath, - isTestnet, - ]; + subClass, + supportedProtocols, + isCustomToken, + requiresHdWallet, + derivationPath, + isTestnet, + ]; @override bool? get stringify => false; diff --git a/packages/komodo_defi_types/lib/src/protocols/erc20/erc20_protocol.dart b/packages/komodo_defi_types/lib/src/protocols/erc20/erc20_protocol.dart index d629b9b4..21119c0b 100644 --- a/packages/komodo_defi_types/lib/src/protocols/erc20/erc20_protocol.dart +++ b/packages/komodo_defi_types/lib/src/protocols/erc20/erc20_protocol.dart @@ -25,7 +25,13 @@ class Erc20Protocol extends ProtocolClass { bool get requiresHdWallet => false; @override - ActivationParams defaultActivationParams([List? childTokens]) { + ActivationParams defaultActivationParams({PrivateKeyPolicy? privKeyPolicy}) { + // For ERC20, we typically don't need child tokens in the default case + // If you need to support child tokens, you can add an overloaded method + return Erc20ActivationParams.fromJsonConfig(super.config); + } + + ActivationParams activationParamsWithTokens([List? childTokens]) { return childTokens == null ? Erc20ActivationParams.fromJsonConfig(super.config) : EthWithTokensActivationParams.fromJson(config).copyWith( diff --git a/packages/komodo_defi_types/lib/src/protocols/utxo/utxo_protocol.dart b/packages/komodo_defi_types/lib/src/protocols/utxo/utxo_protocol.dart index 3f577cec..77373887 100644 --- a/packages/komodo_defi_types/lib/src/protocols/utxo/utxo_protocol.dart +++ b/packages/komodo_defi_types/lib/src/protocols/utxo/utxo_protocol.dart @@ -28,10 +28,13 @@ class UtxoProtocol extends ProtocolClass { // than adding the activation parameters to the protocol. // Hint: It may be useful to refactor `[ActivationStrategy.supportsAssetType]` // to be async. - UtxoActivationParams defaultActivationParams() { + UtxoActivationParams defaultActivationParams({ + PrivateKeyPolicy privKeyPolicy = PrivateKeyPolicy.contextPrivKey, + }) { return UtxoActivationParams.fromJson(config) .copyWith( txHistory: true, + privKeyPolicy: privKeyPolicy, ) .copyWithHd( minAddressesNumber: 1,