diff --git a/lib/bloc/coins_bloc/coins_repo.dart b/lib/bloc/coins_bloc/coins_repo.dart index 4120a7c1fb..387cf0ac87 100644 --- a/lib/bloc/coins_bloc/coins_repo.dart +++ b/lib/bloc/coins_bloc/coins_repo.dart @@ -27,6 +27,7 @@ import 'package:web_dex/mm2/mm2_api/rpc/withdraw/withdraw_request.dart'; import 'package:web_dex/model/cex_price.dart'; import 'package:web_dex/model/coin.dart'; import 'package:web_dex/model/kdf_auth_metadata_extension.dart'; +import 'package:web_dex/model/wallet.dart'; import 'package:web_dex/model/text_error.dart'; import 'package:web_dex/model/withdraw_details/withdraw_details.dart'; import 'package:web_dex/services/arrr_activation/arrr_activation_service.dart'; @@ -67,6 +68,8 @@ class CoinsRepo { final ArrrActivationService _arrrActivationService; final _log = Logger('CoinsRepo'); + static const _unsupportedTrezorSiaMessage = + 'SIA is not supported for Trezor wallets in this release.'; /// { acc: { abbr: address }}, used in Fiat Page final Map> _addressCache = {}; @@ -383,6 +386,31 @@ class CoinsRepo { return; } + final walletType = (await _kdfSdk.currentWallet())?.config.type; + if (walletType == WalletType.trezor) { + final unsupportedSiaAssets = + assets.where((asset) => asset.id.subClass == CoinSubClass.sia); + if (unsupportedSiaAssets.isNotEmpty) { + _log.warning( + 'Skipping unsupported Trezor SIA activation for ' + '${unsupportedSiaAssets.map((a) => a.id.id).join(', ')}: ' + '$_unsupportedTrezorSiaMessage', + ); + for (final siaAsset in unsupportedSiaAssets) { + _broadcastAsset( + _assetToCoinWithoutAddress(siaAsset) + .copyWith(state: CoinState.suspended), + ); + } + } + assets = assets + .where((asset) => asset.id.subClass != CoinSubClass.sia) + .toList(); + if (assets.isEmpty) { + return; + } + } + // Debug logging for activation if (kDebugElectrumLogs) { final coinIdList = assets.map((e) => e.id.id).join(', '); diff --git a/lib/bloc/coins_manager/coins_manager_bloc.dart b/lib/bloc/coins_manager/coins_manager_bloc.dart index 2b0da74164..b64f28739f 100644 --- a/lib/bloc/coins_manager/coins_manager_bloc.dart +++ b/lib/bloc/coins_manager/coins_manager_bloc.dart @@ -15,6 +15,7 @@ import 'package:web_dex/bloc/settings/settings_repository.dart'; import 'package:web_dex/blocs/trading_entities_bloc.dart'; import 'package:web_dex/model/coin.dart'; import 'package:web_dex/model/coin_utils.dart'; +import 'package:web_dex/model/wallet.dart'; import 'package:web_dex/shared/utils/extensions/kdf_user_extensions.dart'; import 'package:web_dex/router/state/wallet_state.dart'; import 'package:web_dex/views/wallet/coins_manager/coins_manager_helpers.dart'; @@ -68,13 +69,17 @@ class CoinsManagerBloc extends Bloc { ) async { final List filters = []; - final mergedCoinsList = _mergeCoinLists( + final originalCoins = await _filterUnsupportedHardwareCoins( await _getOriginalCoinList( _coinsRepo, event.action, cachedKnownCoinsMap: _cachedKnownCoinsMap, cachedWalletCoins: _cachedWalletCoins, ), + event.action, + ); + final mergedCoinsList = _mergeCoinLists( + originalCoins, state.coins, ).toList(); @@ -86,8 +91,15 @@ class CoinsManagerBloc extends Bloc { state.selectedCoins, event.action, ); + final visibleSelectedCoins = await _filterUnsupportedHardwareCoins( + selectedCoins, + event.action, + ); - final uniqueCombinedList = {...mergedCoinsList, ...selectedCoins}; + final uniqueCombinedList = { + ...mergedCoinsList, + ...visibleSelectedCoins, + }; final testFilteredCoins = await _filterTestCoinsIfNeeded( uniqueCombinedList.toList(), @@ -111,7 +123,7 @@ class CoinsManagerBloc extends Bloc { state.copyWith( coins: sortedCoins.unique((coin) => coin.id), action: event.action, - selectedCoins: selectedCoins, + selectedCoins: visibleSelectedCoins, ), ); } @@ -147,11 +159,14 @@ class CoinsManagerBloc extends Bloc { _cachedTestCoinsEnabled = (await _settingsRepository.loadSettings()).testCoinsEnabled; - final List coins = await _getOriginalCoinList( - _coinsRepo, + final List coins = await _filterUnsupportedHardwareCoins( + await _getOriginalCoinList( + _coinsRepo, + event.action, + cachedKnownCoinsMap: _cachedKnownCoinsMap, + cachedWalletCoins: _cachedWalletCoins, + ), event.action, - cachedKnownCoinsMap: _cachedKnownCoinsMap, - cachedWalletCoins: _cachedWalletCoins, ); // Add wallet coins to selected coins if in add mode so that they @@ -164,9 +179,13 @@ class CoinsManagerBloc extends Bloc { : [], event.action, ); + final visibleSelectedCoins = await _filterUnsupportedHardwareCoins( + selectedCoins, + event.action, + ); final filteredCoins = await _filterTestCoinsIfNeeded( - {...coins, ...selectedCoins}.toList(), + {...coins, ...visibleSelectedCoins}.toList(), ); final sortedCoins = _sortCoins(filteredCoins, event.action, state.sortData); @@ -174,7 +193,7 @@ class CoinsManagerBloc extends Bloc { state.copyWith( coins: sortedCoins.unique((coin) => coin.id), action: event.action, - selectedCoins: selectedCoins, + selectedCoins: visibleSelectedCoins, ), ); } @@ -185,9 +204,7 @@ class CoinsManagerBloc extends Bloc { ) { final List newTypes = state.selectedCoinTypes.contains(event.type) - ? state.selectedCoinTypes - .where((type) => type != event.type) - .toList() + ? state.selectedCoinTypes.where((type) => type != event.type).toList() : [...state.selectedCoinTypes, event.type]; emit(state.copyWith(selectedCoinTypes: newTypes)); @@ -249,10 +266,12 @@ class CoinsManagerBloc extends Bloc { } on ZhtlcActivationCancelled { // Revert optimistic selection and show a friendly message selectedCoins.remove(coin); - emit(state.copyWith( - selectedCoins: selectedCoins.toList(), - errorMessage: 'Activation canceled.', - )); + emit( + state.copyWith( + selectedCoins: selectedCoins.toList(), + errorMessage: 'Activation canceled.', + ), + ); return; } } else { @@ -358,12 +377,26 @@ class CoinsManagerBloc extends Bloc { List _filterByType(List coins) { return coins - .where( - (coin) => state.selectedCoinTypes.contains(coin.id.subClass), - ) + .where((coin) => state.selectedCoinTypes.contains(coin.id.subClass)) .toList(); } + Future> _filterUnsupportedHardwareCoins( + List coins, + CoinsManagerAction action, + ) async { + if (action != CoinsManagerAction.add) { + return coins; + } + + final currentWalletType = (await _sdk.auth.currentUser)?.wallet.config.type; + if (currentWalletType != WalletType.trezor) { + return coins; + } + + return coins.where((coin) => coin.id.subClass != CoinSubClass.sia).toList(); + } + /// Merges wallet coins into selected coins list when in add mode Future> _mergeWalletCoinsIfNeeded( List selectedCoins, @@ -383,8 +416,9 @@ class CoinsManagerBloc extends Bloc { // This ensures toggles remain OFF if auto-activation was bypassed. if (walletCoin.id.subClass == CoinSubClass.zhtlc) { try { - final saved = - await _sdk.activationConfigService.getSavedZhtlc(walletCoin.id); + final saved = await _sdk.activationConfigService.getSavedZhtlc( + walletCoin.id, + ); if (saved == null) { continue; } diff --git a/lib/bloc/withdraw_form/withdraw_form_bloc.dart b/lib/bloc/withdraw_form/withdraw_form_bloc.dart index 3712f4076e..2ab56ffa73 100644 --- a/lib/bloc/withdraw_form/withdraw_form_bloc.dart +++ b/lib/bloc/withdraw_form/withdraw_form_bloc.dart @@ -24,6 +24,8 @@ import 'package:decimal/decimal.dart'; class WithdrawFormBloc extends Bloc { static final Logger _logger = Logger('WithdrawFormBloc'); + static const _unsupportedSiaHardwareWalletMessage = + 'SIA is not supported for hardware wallets in this release.'; final KomodoDefiSdk _sdk; final WalletType? _walletType; @@ -589,6 +591,17 @@ class WithdrawFormBloc extends Bloc { Emitter emit, ) async { if (state.hasValidationErrors) return; + if (_isUnsupportedSiaHardwareWalletFlow) { + emit( + state.copyWith( + previewError: () => + TextError(error: _unsupportedSiaHardwareWalletMessage), + isSending: false, + isAwaitingTrezorConfirmation: false, + ), + ); + return; + } try { emit( @@ -650,6 +663,17 @@ class WithdrawFormBloc extends Bloc { Emitter emit, ) async { if (state.hasValidationErrors) return; + if (_isUnsupportedSiaHardwareWalletFlow) { + emit( + state.copyWith( + transactionError: () => + TextError(error: _unsupportedSiaHardwareWalletMessage), + isSending: false, + isAwaitingTrezorConfirmation: false, + ), + ); + return; + } try { emit( @@ -736,6 +760,9 @@ class WithdrawFormBloc extends Bloc { } } + bool get _isUnsupportedSiaHardwareWalletFlow => + _walletType == WalletType.trezor && state.asset.protocol is SiaProtocol; + void _onCancelled( WithdrawFormCancelled event, Emitter emit, diff --git a/sdk b/sdk index 47b69e0f75..482ca5feb5 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit 47b69e0f75f430385712722f402cf7bba0cf33ed +Subproject commit 482ca5feb53960ded40788873f41d291bb317906