From 8b0f0e589edfe150efd6a81649ce653cb0da65dc Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 30 May 2024 15:48:27 +0500 Subject: [PATCH 1/4] Updated on 2026-08-14 --- .../tap/di/domain/WalletsDomainModule.kt | 7 ++- .../DefaultWalletAddressServiceRepository.kt | 4 +- .../data/wallets/di/WalletsDataModule.kt | 11 ----- .../DefaultWalletManagersFacade.kt | 11 +++++ .../walletmanager/WalletManagersFacade.kt | 3 ++ .../WalletAddressServiceRepository.kt | 2 +- .../transaction/error/ValidateAddressError.kt | 7 +++ .../usecase/ParseSharedAddressUseCase.kt | 4 +- .../usecase/ValidateWalletAddressUseCase.kt | 43 +++++++++++++++++++ .../usecase/ValidateWalletMemoUseCase.kt | 4 +- .../usecase/ValidateWalletAddressUseCase.kt | 27 ------------ 11 files changed, 77 insertions(+), 46 deletions(-) rename data/{wallets/src/main/java/com/tangem/data/wallets => transaction/src/main/java/com/tangem/data/transaction}/DefaultWalletAddressServiceRepository.kt (97%) rename domain/{wallets/src/main/java/com/tangem/domain/wallets/repository => transaction/src/main/java/com/tangem/domain/transaction}/WalletAddressServiceRepository.kt (91%) create mode 100644 domain/transaction/src/main/java/com/tangem/domain/transaction/error/ValidateAddressError.kt rename domain/{wallets/src/main/java/com/tangem/domain/wallets => transaction/src/main/java/com/tangem/domain/transaction}/usecase/ParseSharedAddressUseCase.kt (85%) create mode 100644 domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt rename domain/{wallets/src/main/java/com/tangem/domain/wallets => transaction/src/main/java/com/tangem/domain/transaction}/usecase/ValidateWalletMemoUseCase.kt (77%) delete mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ValidateWalletAddressUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index 2f5322f914..c539df5afc 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -3,7 +3,10 @@ package com.tangem.tap.di.domain import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.repository.WalletAddressServiceRepository +import com.tangem.domain.transaction.WalletAddressServiceRepository +import com.tangem.domain.transaction.usecase.ParseSharedAddressUseCase +import com.tangem.domain.transaction.usecase.ValidateWalletAddressUseCase +import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.* @@ -126,10 +129,12 @@ internal object WalletsDomainModule { @Singleton fun providesValidateWalletAddressUseCase( walletAddressServiceRepository: WalletAddressServiceRepository, + walletManagersFacade: WalletManagersFacade, dispatchers: CoroutineDispatcherProvider, ): ValidateWalletAddressUseCase { return ValidateWalletAddressUseCase( walletAddressServiceRepository = walletAddressServiceRepository, + walletManagersFacade = walletManagersFacade, dispatchers = dispatchers, ) } diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletAddressServiceRepository.kt b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultWalletAddressServiceRepository.kt similarity index 97% rename from data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletAddressServiceRepository.kt rename to data/transaction/src/main/java/com/tangem/data/transaction/DefaultWalletAddressServiceRepository.kt index 6831cc8ae4..00dc557554 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletAddressServiceRepository.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultWalletAddressServiceRepository.kt @@ -1,15 +1,15 @@ -package com.tangem.data.wallets +package com.tangem.data.transaction import android.net.Uri import androidx.core.text.isDigitsOnly import com.tangem.blockchain.blockchains.near.NearWalletManager import com.tangem.blockchain.common.Blockchain import com.tangem.domain.tokens.model.Network +import com.tangem.domain.transaction.WalletAddressServiceRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.ParsedQrCode import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.models.errors.ParsedQrCodeErrors -import com.tangem.domain.wallets.repository.WalletAddressServiceRepository import java.math.BigInteger class DefaultWalletAddressServiceRepository( diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt b/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt index 9748691618..c41bb99652 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt @@ -1,12 +1,9 @@ package com.tangem.data.wallets.di import com.tangem.data.wallets.DefaultWalletNamesMigrationRepository -import com.tangem.data.wallets.DefaultWalletAddressServiceRepository import com.tangem.data.wallets.DefaultWalletsRepository import com.tangem.datasource.local.preferences.AppPreferencesStore -import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository -import com.tangem.domain.wallets.repository.WalletAddressServiceRepository import com.tangem.domain.wallets.repository.WalletsRepository import dagger.Module import dagger.Provides @@ -24,14 +21,6 @@ internal object WalletsDataModule { return DefaultWalletsRepository(appPreferencesStore = appPreferencesStore) } - @Provides - @Singleton - fun providesWalletAddressServiceRepository( - walletManagersFacade: WalletManagersFacade, - ): WalletAddressServiceRepository { - return DefaultWalletAddressServiceRepository(walletManagersFacade) - } - @Provides @Singleton fun provideMigrateNamesRepository(appPreferencesStore: AppPreferencesStore): WalletNamesMigrationRepository { diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index c15246cb89..205ea91ce0 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -611,6 +611,17 @@ class DefaultWalletManagersFacade( return walletManager.fulfillRequirements(currencyType, signer) } + override suspend fun checkUtxoConsolidationAvailability(userWalletId: UserWalletId, network: Network): Boolean { + val blockchain = Blockchain.fromId(network.id.value) + val walletManager = getOrCreateWalletManager( + userWalletId = userWalletId, + blockchain = blockchain, + derivationPath = network.derivationPath.value, + ) ?: return false + + return walletManager.allowUtxoConsolidation + } + private fun updateWalletManagerTokensIfNeeded(walletManager: WalletManager, tokens: Set) { if (tokens.isEmpty()) return diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt index 5c80c0db3d..14f5fa53fa 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt @@ -253,4 +253,7 @@ interface WalletManagersFacade { currency: CryptoCurrency, signer: CommonSigner, ): SimpleResult + + /** Indicates UTXO consolidation availability */ + suspend fun checkUtxoConsolidationAvailability(userWalletId: UserWalletId, network: Network): Boolean } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletAddressServiceRepository.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/WalletAddressServiceRepository.kt similarity index 91% rename from domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletAddressServiceRepository.kt rename to domain/transaction/src/main/java/com/tangem/domain/transaction/WalletAddressServiceRepository.kt index 624ad44419..8d09e3b248 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletAddressServiceRepository.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/WalletAddressServiceRepository.kt @@ -1,4 +1,4 @@ -package com.tangem.domain.wallets.repository +package com.tangem.domain.transaction import com.tangem.domain.tokens.model.Network import com.tangem.domain.wallets.models.ParsedQrCode diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/error/ValidateAddressError.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/ValidateAddressError.kt new file mode 100644 index 0000000000..75262c24e2 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/ValidateAddressError.kt @@ -0,0 +1,7 @@ +package com.tangem.domain.transaction.error + +sealed class ValidateAddressError { + data object AddressInWallet : ValidateAddressError() + data object InvalidAddress : ValidateAddressError() + data class DataError(val throwable: Throwable) : ValidateAddressError() +} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ParseSharedAddressUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ParseSharedAddressUseCase.kt similarity index 85% rename from domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ParseSharedAddressUseCase.kt rename to domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ParseSharedAddressUseCase.kt index 8d03b6ab6d..eb5f1e1c89 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ParseSharedAddressUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ParseSharedAddressUseCase.kt @@ -1,9 +1,9 @@ -package com.tangem.domain.wallets.usecase +package com.tangem.domain.transaction.usecase import arrow.core.Either import com.tangem.domain.tokens.model.Network +import com.tangem.domain.transaction.WalletAddressServiceRepository import com.tangem.domain.wallets.models.ParsedQrCode -import com.tangem.domain.wallets.repository.WalletAddressServiceRepository import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt new file mode 100644 index 0000000000..9d9de200e8 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt @@ -0,0 +1,43 @@ +package com.tangem.domain.transaction.usecase + +import arrow.core.Either +import arrow.core.left +import arrow.core.right +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.NetworkAddress +import com.tangem.domain.transaction.WalletAddressServiceRepository +import com.tangem.domain.transaction.error.ValidateAddressError +import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext + +/** + * Use case for validating wallet address. + */ +class ValidateWalletAddressUseCase( + private val walletAddressServiceRepository: WalletAddressServiceRepository, + private val walletManagersFacade: WalletManagersFacade, + private val dispatchers: CoroutineDispatcherProvider, +) { + + suspend operator fun invoke( + userWalletId: UserWalletId, + network: Network, + address: String, + currencyAddress: Set?, + ): Either = withContext(dispatchers.io) { + val isUtxoConsolidationAvailable = + walletManagersFacade.checkUtxoConsolidationAvailability(userWalletId, network) + val isCurrentAddress = currencyAddress?.any { it.value == address } ?: true + + val isForbidSelfSend = isCurrentAddress && !isUtxoConsolidationAvailable + val isValidAddress = walletAddressServiceRepository.validateAddress(userWalletId, network, address) + + when { + !isValidAddress -> ValidateAddressError.InvalidAddress.left() + isForbidSelfSend -> ValidateAddressError.AddressInWallet.left() + else -> Unit.right() + } + } +} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ValidateWalletMemoUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletMemoUseCase.kt similarity index 77% rename from domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ValidateWalletMemoUseCase.kt rename to domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletMemoUseCase.kt index 754819852b..d4d5ab22e8 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ValidateWalletMemoUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletMemoUseCase.kt @@ -1,8 +1,8 @@ -package com.tangem.domain.wallets.usecase +package com.tangem.domain.transaction.usecase import arrow.core.Either import com.tangem.domain.tokens.model.Network -import com.tangem.domain.wallets.repository.WalletAddressServiceRepository +import com.tangem.domain.transaction.WalletAddressServiceRepository /** * Use case for validating wallet memo. diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ValidateWalletAddressUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ValidateWalletAddressUseCase.kt deleted file mode 100644 index 149b12030d..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ValidateWalletAddressUseCase.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.tangem.domain.wallets.usecase - -import arrow.core.Either -import com.tangem.domain.tokens.model.Network -import com.tangem.domain.wallets.models.UserWalletId -import com.tangem.domain.wallets.repository.WalletAddressServiceRepository -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.withContext - -/** - * Use case for validating wallet address. - */ -class ValidateWalletAddressUseCase( - private val walletAddressServiceRepository: WalletAddressServiceRepository, - private val dispatchers: CoroutineDispatcherProvider, -) { - - suspend operator fun invoke( - userWalletId: UserWalletId, - network: Network, - address: String, - ): Either = withContext(dispatchers.io) { - Either.catch { - walletAddressServiceRepository.validateAddress(userWalletId, network, address) - } - } -} \ No newline at end of file From f94370c41c67fd0d72e1db923e8774d6198d0cf9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 3 Jun 2024 15:03:36 +0500 Subject: [PATCH 2/4] Updated on 2026-08-14 --- .../tap/di/domain/TransactionDomainModule.kt | 26 ++++--- .../transaction/di/TransactionDataModule.kt | 10 +++ .../DefaultWalletManagersFacade.kt | 4 +- .../IsUtxoConsolidationAvailableUseCase.kt | 19 +++++ .../state/recipient/RecipientSendFactory.kt | 47 +++++++----- .../SendRecipientWalletListConverter.kt | 20 ++++- .../presentation/viewmodel/SendViewModel.kt | 75 +++++++++++-------- 7 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/IsUtxoConsolidationAvailableUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt index bb6a62fc78..9635e67a29 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt @@ -11,15 +11,15 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import dagger.Module import dagger.Provides import dagger.hilt.InstallIn -import dagger.hilt.android.components.ViewModelComponent -import dagger.hilt.android.scopes.ViewModelScoped +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton @Module -@InstallIn(ViewModelComponent::class) +@InstallIn(SingletonComponent::class) internal object TransactionDomainModule { @Provides - @ViewModelScoped + @Singleton fun provideGetFeeUseCase(walletManagersFacade: WalletManagersFacade): GetFeeUseCase { return GetFeeUseCase( walletManagersFacade = walletManagersFacade, @@ -28,7 +28,7 @@ internal object TransactionDomainModule { } @Provides - @ViewModelScoped + @Singleton fun provideSendTransactionUseCase( cardSdkConfigRepository: CardSdkConfigRepository, transactionRepository: TransactionRepository, @@ -43,7 +43,7 @@ internal object TransactionDomainModule { } @Provides - @ViewModelScoped + @Singleton fun provideAssociateAssetUseCase( cardSdkConfigRepository: CardSdkConfigRepository, walletManagersFacade: WalletManagersFacade, @@ -59,20 +59,28 @@ internal object TransactionDomainModule { } @Provides - @ViewModelScoped + @Singleton fun provideCreateTransactionUseCase(transactionRepository: TransactionRepository): CreateTransactionUseCase { return CreateTransactionUseCase(transactionRepository) } @Provides - @ViewModelScoped + @Singleton fun provideIsFeeApproximateUseCase(feeRepository: FeeRepository): IsFeeApproximateUseCase { return IsFeeApproximateUseCase(feeRepository) } @Provides - @ViewModelScoped + @Singleton fun provideValidateTransactionUseCase(transactionRepository: TransactionRepository): ValidateTransactionUseCase { return ValidateTransactionUseCase(transactionRepository) } + + @Provides + @Singleton + fun provideIsUtxoConsolidationAvailableUseCase( + walletManagersFacade: WalletManagersFacade, + ): IsUtxoConsolidationAvailableUseCase { + return IsUtxoConsolidationAvailableUseCase(walletManagersFacade) + } } \ No newline at end of file diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt b/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt index a6d7043d91..7a1b7db59c 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt @@ -2,9 +2,11 @@ package com.tangem.data.transaction.di import com.tangem.data.transaction.DefaultFeeRepository import com.tangem.data.transaction.DefaultTransactionRepository +import com.tangem.data.transaction.DefaultWalletAddressServiceRepository import com.tangem.datasource.local.walletmanager.WalletManagersStore import com.tangem.domain.transaction.FeeRepository import com.tangem.domain.transaction.TransactionRepository +import com.tangem.domain.transaction.WalletAddressServiceRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module @@ -36,4 +38,12 @@ internal object TransactionDataModule { fun providesFeeRepository(): FeeRepository { return DefaultFeeRepository() } + + @Provides + @Singleton + fun providesWalletAddressServiceRepository( + walletManagersFacade: WalletManagersFacade, + ): WalletAddressServiceRepository { + return DefaultWalletAddressServiceRepository(walletManagersFacade) + } } \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index 205ea91ce0..6c5f931d5e 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -13,9 +13,9 @@ import com.tangem.blockchain.common.pagination.Page import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.blockchain.common.trustlines.AssetRequirementsManager -import com.tangem.blockchain.common.txhistory.TransactionHistoryRequest import com.tangem.blockchain.extensions.Result import com.tangem.blockchain.extensions.SimpleResult +import com.tangem.blockchain.transactionhistory.models.TransactionHistoryRequest import com.tangem.blockchainsdk.BlockchainSDKFactory import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.datasource.asset.loader.AssetLoader @@ -619,7 +619,7 @@ class DefaultWalletManagersFacade( derivationPath = network.derivationPath.value, ) ?: return false - return walletManager.allowUtxoConsolidation + return (walletManager as? UtxoBlockchainManager)?.allowConsolidation == true } private fun updateWalletManagerTokensIfNeeded(walletManager: WalletManager, tokens: Set) { diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/IsUtxoConsolidationAvailableUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/IsUtxoConsolidationAvailableUseCase.kt new file mode 100644 index 0000000000..90839203b0 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/IsUtxoConsolidationAvailableUseCase.kt @@ -0,0 +1,19 @@ +package com.tangem.domain.transaction.usecase + +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.wallets.models.UserWalletId + +/** + * Gets UTXO consolidation availability + */ +class IsUtxoConsolidationAvailableUseCase( + private val walletManagersFacade: WalletManagersFacade, +) { + + suspend fun invokeSync(userWalletId: UserWalletId, network: Network) = + walletManagersFacade.checkUtxoConsolidationAvailability( + userWalletId = userWalletId, + network = network, + ) +} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/RecipientSendFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/RecipientSendFactory.kt index 5fcb985783..c3fdbfd71b 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/RecipientSendFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/RecipientSendFactory.kt @@ -1,11 +1,13 @@ package com.tangem.features.send.impl.presentation.state.recipient +import arrow.core.Either import arrow.core.getOrElse import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.txhistory.models.TxHistoryItem -import com.tangem.domain.wallets.usecase.ValidateWalletMemoUseCase +import com.tangem.domain.transaction.error.ValidateAddressError +import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase import com.tangem.features.send.impl.R import com.tangem.features.send.impl.presentation.domain.AvailableWallet import com.tangem.features.send.impl.presentation.state.SendUiState @@ -18,10 +20,14 @@ internal class RecipientSendFactory( private val stateRouterProvider: Provider, private val currentStateProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, + private val isUtxoConsolidationAvailableProvider: Provider, private val validateWalletMemoUseCase: ValidateWalletMemoUseCase, ) { private val recipientWalletListStateConverter by lazy(LazyThreadSafetyMode.NONE) { - SendRecipientWalletListConverter() + SendRecipientWalletListConverter( + cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider, + isUtxoConsolidationAvailableProvider = isUtxoConsolidationAvailableProvider, + ) } private val recipientHistoryListStateConverter by lazy(LazyThreadSafetyMode.NONE) { SendRecipientHistoryListConverter( @@ -60,7 +66,10 @@ internal class RecipientSendFactory( ) } - fun getOnRecipientAddressValidState(value: String, isValidAddress: Boolean): SendUiState { + fun getOnRecipientAddressValidState( + value: String, + maybeValidAddress: Either, + ): SendUiState { val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val state = currentStateProvider() val isEditState = stateRouterProvider().isEditState @@ -73,21 +82,28 @@ internal class RecipientSendFactory( Timber.e("Failed to validateWalletMemoUseCase: $it") false } - val isAddressInWallet = cryptoCurrencyStatus.value.networkAddress?.availableAddresses - ?.any { it.value == value } ?: true return state.copyWrapped( isEditState = isEditState, recipientState = recipientState.copy( - isPrimaryButtonEnabled = isValidMemo && isValidAddress && !isAddressInWallet, + isPrimaryButtonEnabled = isValidMemo && maybeValidAddress.isRight(), isValidating = false, addressTextField = recipientState.addressTextField.copy( - error = when { - !isValidAddress -> resourceReference(R.string.send_recipient_address_error) - isAddressInWallet -> resourceReference(R.string.send_error_address_same_as_wallet) - else -> null - }, - isError = value.isNotEmpty() && !isValidAddress || isAddressInWallet, + error = maybeValidAddress.fold( + ifLeft = { + when (it) { + ValidateAddressError.InvalidAddress -> resourceReference( + R.string.send_recipient_address_error, + ) + ValidateAddressError.AddressInWallet -> resourceReference( + R.string.send_error_address_same_as_wallet, + ) + else -> null + } + }, + ifRight = { null }, + ), + isError = value.isNotEmpty() && maybeValidAddress.isLeft(), ), ), ) @@ -131,13 +147,11 @@ internal class RecipientSendFactory( Timber.e("Failed to validateWalletMemoUseCase: $it") false } - val isAddressInWallet = cryptoCurrencyStatus.value.networkAddress?.availableAddresses - ?.any { it.value == value } ?: true return state.copyWrapped( isEditState = isEditState, recipientState = recipientState.copy( - isPrimaryButtonEnabled = isValidMemo && isValidAddress && !isAddressInWallet, + isPrimaryButtonEnabled = isValidMemo && isValidAddress, isValidating = false, memoTextField = recipientState.memoTextField?.copy( isError = value.isNotEmpty() && !isValidMemo, @@ -162,11 +176,10 @@ internal class RecipientSendFactory( ) } - fun getHiddenRecentListState(isAddressInWallet: Boolean, isValidAddress: Boolean): SendUiState { + fun getHiddenRecentListState(isNotValid: Boolean): SendUiState { val state = currentStateProvider() val isEditState = stateRouterProvider().isEditState val recipientState = state.getRecipientState(isEditState) ?: return state - val isNotValid = isAddressInWallet || !isValidAddress return state.copyWrapped( isEditState = isEditState, recipientState = recipientState.copy( diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientWalletListConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientWalletListConverter.kt index 35d56f9846..6ac1a69d3f 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientWalletListConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientWalletListConverter.kt @@ -1,16 +1,22 @@ package com.tangem.features.send.impl.presentation.state.recipient import com.tangem.core.ui.extensions.TextReference +import com.tangem.domain.tokens.model.CryptoCurrency +import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.domain.AvailableWallet import com.tangem.features.send.impl.presentation.domain.SendRecipientListContent import com.tangem.features.send.impl.presentation.state.recipient.utils.WALLET_DEFAULT_COUNT import com.tangem.features.send.impl.presentation.state.recipient.utils.WALLET_KEY_TAG import com.tangem.features.send.impl.presentation.state.recipient.utils.emptyListState +import com.tangem.utils.Provider import com.tangem.utils.converter.Converter import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList -internal class SendRecipientWalletListConverter : +internal class SendRecipientWalletListConverter( + private val cryptoCurrencyStatusProvider: Provider, + private val isUtxoConsolidationAvailableProvider: Provider, +) : Converter, PersistentList> { override fun convert(value: List): PersistentList { return value.filterWallets().ifEmpty { @@ -20,8 +26,18 @@ internal class SendRecipientWalletListConverter : private fun List.filterWallets(): PersistentList { var walletsCounter = 0 + val currentAddress: String = runCatching { + cryptoCurrencyStatusProvider().value.networkAddress?.defaultAddress?.value + }.getOrNull().orEmpty() + return this.filterNotNull() - .filter { it.address.isNotBlank() } + .filter { + val isCoin = it.cryptoCurrency is CryptoCurrency.Coin + val isNotSameAddress = it.address != currentAddress + val isNotBlankAddress = it.address.isNotBlank() + + isNotBlankAddress && isCoin && (isNotSameAddress || isUtxoConsolidationAvailableProvider()) + } .groupBy { item -> item.name } .values.map { wallets -> val groupedByWallet = wallets.groupBy { it.userWalletId } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index d07fa04c51..bcf4954db8 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -7,6 +7,7 @@ import androidx.compose.runtime.setValue import androidx.lifecycle.* import arrow.core.Either import arrow.core.getOrElse +import arrow.core.left import com.tangem.blockchain.common.TransactionData import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.core.analytics.api.AnalyticsEventHandler @@ -34,10 +35,11 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.txhistory.usecase.GetFixedTxHistoryItemsUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.transaction.error.ValidateAddressError import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.GetWalletsUseCase -import com.tangem.domain.wallets.usecase.ValidateWalletAddressUseCase -import com.tangem.domain.wallets.usecase.ValidateWalletMemoUseCase +import com.tangem.domain.transaction.usecase.ValidateWalletAddressUseCase +import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase import com.tangem.features.send.api.navigation.SendRouter import com.tangem.features.send.impl.navigation.InnerSendRouter import com.tangem.features.send.impl.presentation.analytics.EnterAddressSource @@ -93,6 +95,7 @@ internal class SendViewModel @Inject constructor( private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase, private val updateDelayedCurrencyStatusUseCase: UpdateDelayedNetworkStatusUseCase, private val fetchPendingTransactionsUseCase: FetchPendingTransactionsUseCase, + private val isUtxoConsolidationAvailableUseCase: IsUtxoConsolidationAvailableUseCase, @DelayedWork private val coroutineScope: CoroutineScope, validateTransactionUseCase: ValidateTransactionUseCase, currencyChecksRepository: CurrencyChecksRepository, @@ -135,6 +138,7 @@ internal class SendViewModel @Inject constructor( stateRouterProvider = Provider { stateRouter }, currentStateProvider = Provider { uiState }, cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, + isUtxoConsolidationAvailableProvider = Provider { isUtxoConsolidationAvailable }, validateWalletMemoUseCase = validateWalletMemoUseCase, ) @@ -198,6 +202,7 @@ internal class SendViewModel @Inject constructor( private var userWallet: UserWallet by Delegates.notNull() private var userWallets: List = emptyList() private var isAmountSubtractAvailable: Boolean = false + private var isUtxoConsolidationAvailable: Boolean = false private var isTapHelpPreviewEnabled: Boolean = false private var coinCryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull() private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull() @@ -248,6 +253,7 @@ internal class SendViewModel @Inject constructor( ifRight = { wallet -> userWallet = wallet checkIfSubtractAvailable() + checkIfUtxoConsolidationAvailable() val isSingleWalletWithToken = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() val isMultiCurrency = wallet.isMultiCurrency @@ -424,9 +430,6 @@ internal class SendViewModel @Inject constructor( } private suspend fun List.toAvailableWallets(): List { - val currentAddress: String = kotlin.runCatching { - cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value - }.getOrNull().orEmpty() return filterNot { it.isLocked } .mapNotNull { wallet -> val addresses = if (!wallet.isMultiCurrency) { @@ -440,16 +443,14 @@ internal class SendViewModel @Inject constructor( } else { getNetworkAddressesUseCase.invokeSync(wallet.walletId, cryptoCurrency.network) } - addresses - ?.filter { it.address != currentAddress && it.cryptoCurrency is CryptoCurrency.Coin } - ?.map { (cryptoCurrency, address) -> - AvailableWallet( - name = wallet.name, - address = address, - cryptoCurrency = cryptoCurrency, - userWalletId = wallet.walletId, - ) - } + addresses?.map { (cryptoCurrency, address) -> + AvailableWallet( + name = wallet.name, + address = address, + cryptoCurrency = cryptoCurrency, + userWalletId = wallet.walletId, + ) + } }.flatten() } @@ -624,8 +625,15 @@ internal class SendViewModel @Inject constructor( uiState = recipientStateFactory.getOnRecipientAddressValidationStarted() val isValidAddress = validateAddress(value) uiState = recipientStateFactory.getOnRecipientAddressValidState(value, isValidAddress) - type?.let { analyticsEventHandler.send(SendAnalyticEvents.AddressEntered(it, isValidAddress)) } - autoNextFromRecipient(type, isValidAddress) + type?.let { + analyticsEventHandler.send( + SendAnalyticEvents.AddressEntered( + it, + isValidAddress.isRight(), + ), + ) + } + autoNextFromRecipient(type, isValidAddress.isRight()) } }.saveIn(addressValidationJobHolder) } @@ -636,23 +644,22 @@ internal class SendViewModel @Inject constructor( uiState = recipientStateFactory.getOnRecipientMemoValueChange(value, isValuePasted) uiState = recipientStateFactory.getOnRecipientAddressValidationStarted() val recipientState = uiState.getRecipientState(stateRouter.isEditState) - val isValidAddress = validateAddress(recipientState?.addressTextField?.value.orEmpty()) - uiState = recipientStateFactory.getOnRecipientMemoValidState(value, isValidAddress) + val maybeValidAddress = validateAddress(recipientState?.addressTextField?.value.orEmpty()) + uiState = recipientStateFactory.getOnRecipientMemoValidState(value, maybeValidAddress.isRight()) } }.saveIn(memoValidationJobHolder) } - private suspend fun validateAddress(value: String): Boolean = runCatching { - val isValidAddress = validateWalletAddressUseCase( + private suspend fun validateAddress(value: String): Either = runCatching { + val maybeValidAddress = validateWalletAddressUseCase( userWalletId = userWalletId, network = cryptoCurrency.network, address = value, - ).getOrElse { false } - val isAddressInWallet = cryptoCurrencyStatus.value.networkAddress?.availableAddresses - ?.any { it.value == value } ?: true - onEnteredValidAddress(isValidAddress, isAddressInWallet) - return isValidAddress - }.getOrElse { false } + currencyAddress = cryptoCurrencyStatus.value.networkAddress?.availableAddresses, + ) + onEnteredValidAddress(maybeValidAddress.isLeft()) + maybeValidAddress + }.getOrElse { ValidateAddressError.DataError(it).left() } private suspend fun checkIfXrpAddressValue(value: String): Boolean { return BlockchainUtils.decodeRippleXAddress(value, cryptoCurrency.network.id.value)?.let { decodedAddress -> @@ -665,11 +672,8 @@ internal class SendViewModel @Inject constructor( } ?: false } - private fun onEnteredValidAddress(isValidAddress: Boolean, isAddressInWallet: Boolean) { - uiState = recipientStateFactory.getHiddenRecentListState( - isAddressInWallet = isAddressInWallet, - isValidAddress = isValidAddress, - ) + private fun onEnteredValidAddress(isNotValid: Boolean) { + uiState = recipientStateFactory.getHiddenRecentListState(isNotValid = isNotValid) } private fun autoNextFromRecipient(type: EnterAddressSource?, isValidAddress: Boolean) { @@ -739,6 +743,13 @@ internal class SendViewModel @Inject constructor( ) } + private suspend fun checkIfUtxoConsolidationAvailable() { + isUtxoConsolidationAvailable = isUtxoConsolidationAvailableUseCase.invokeSync( + userWalletId = userWalletId, + network = cryptoCurrency.network, + ) + } + private suspend fun callFeeUseCase(): Either? { val isFromConfirmation = stateRouter.currentState.value.isFromConfirmation val amountState = uiState.getAmountState(isFromConfirmation) ?: return null From f9d98374b1bf9afe1b08fff38e294c53386959da Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 3 Jun 2024 15:03:54 +0500 Subject: [PATCH 3/4] Updated on 2026-08-14 --- .../walletmanager/utils/SdkTransactionHistoryItemConverter.kt | 4 ++-- .../utils/SdkTransactionHistoryStateConverter.kt | 4 ++-- .../domain/walletmanager/utils/SdkTransactionTypeConverter.kt | 2 +- gradle/dependencies.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt index 5999db6ea0..a429859de4 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryItemConverter.kt @@ -1,10 +1,10 @@ package com.tangem.domain.walletmanager.utils -import com.tangem.blockchain.common.txhistory.TransactionHistoryItem +import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem import com.tangem.domain.txhistory.models.TxHistoryItem import com.tangem.domain.walletmanager.model.SmartContractMethod import com.tangem.utils.converter.Converter -import com.tangem.blockchain.common.txhistory.TransactionHistoryItem as SdkTransactionHistoryItem +import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem as SdkTransactionHistoryItem internal class SdkTransactionHistoryItemConverter( smartContractMethods: Map, diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryStateConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryStateConverter.kt index 6750e05410..6532b6338f 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryStateConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionHistoryStateConverter.kt @@ -1,9 +1,9 @@ package com.tangem.domain.walletmanager.utils -import com.tangem.blockchain.common.txhistory.TransactionHistoryState +import com.tangem.blockchain.transactionhistory.TransactionHistoryState import com.tangem.domain.txhistory.models.TxHistoryState import com.tangem.utils.converter.Converter -import com.tangem.blockchain.common.txhistory.TransactionHistoryState as SdkTransactionHistoryState +import com.tangem.blockchain.transactionhistory.TransactionHistoryState as SdkTransactionHistoryState internal class SdkTransactionHistoryStateConverter : Converter { diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt index a416bf6085..c0ebfa9a66 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkTransactionTypeConverter.kt @@ -1,6 +1,6 @@ package com.tangem.domain.walletmanager.utils -import com.tangem.blockchain.common.txhistory.TransactionHistoryItem +import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem import com.tangem.domain.txhistory.models.TxHistoryItem import com.tangem.domain.walletmanager.model.SmartContractMethod import com.tangem.utils.converter.Converter diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 78995e86ad..b39d711a8d 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -87,7 +87,7 @@ markdown = "0.7.2" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-652" +tangemBlockchainSdk = "develop-654" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-359" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ From e0dd5081c2700264e8271d6bd454ffc7ec4ef85a Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 3 Jun 2024 15:23:34 +0500 Subject: [PATCH 4/4] Updated on 2026-08-14 --- .../tap/di/domain/WalletsDomainModule.kt | 2 -- .../DefaultWalletAddressServiceRepository.kt | 28 +++++++++++-------- .../transaction/di/TransactionDataModule.kt | 6 +++- .../walletmanager/WalletManagersFacade.kt | 7 ++++- .../usecase/ValidateWalletAddressUseCase.kt | 7 ++--- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index c539df5afc..3dfc085c10 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -130,12 +130,10 @@ internal object WalletsDomainModule { fun providesValidateWalletAddressUseCase( walletAddressServiceRepository: WalletAddressServiceRepository, walletManagersFacade: WalletManagersFacade, - dispatchers: CoroutineDispatcherProvider, ): ValidateWalletAddressUseCase { return ValidateWalletAddressUseCase( walletAddressServiceRepository = walletAddressServiceRepository, walletManagersFacade = walletManagersFacade, - dispatchers = dispatchers, ) } diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultWalletAddressServiceRepository.kt b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultWalletAddressServiceRepository.kt index 00dc557554..4d0bd6ac5e 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultWalletAddressServiceRepository.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultWalletAddressServiceRepository.kt @@ -10,26 +10,30 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.ParsedQrCode import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.models.errors.ParsedQrCodeErrors +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext import java.math.BigInteger class DefaultWalletAddressServiceRepository( private val walletManagersFacade: WalletManagersFacade, + private val dispatchers: CoroutineDispatcherProvider, ) : WalletAddressServiceRepository { - override suspend fun validateAddress(userWalletId: UserWalletId, network: Network, address: String): Boolean { - val blockchain = Blockchain.fromId(network.id.value) + override suspend fun validateAddress(userWalletId: UserWalletId, network: Network, address: String): Boolean = + withContext(dispatchers.io) { + val blockchain = Blockchain.fromId(network.id.value) - return if (blockchain.isNear()) { - val walletManager = walletManagersFacade.getOrCreateWalletManager( - userWalletId = userWalletId, - blockchain = blockchain, - derivationPath = network.derivationPath.value, - ) ?: return false - (walletManager as? NearWalletManager)?.validateAddress(address) ?: false - } else { - blockchain.validateAddress(address) + if (blockchain.isNear()) { + val walletManager = walletManagersFacade.getOrCreateWalletManager( + userWalletId = userWalletId, + blockchain = blockchain, + derivationPath = network.derivationPath.value, + ) ?: return@withContext false + (walletManager as? NearWalletManager)?.validateAddress(address) ?: false + } else { + blockchain.validateAddress(address) + } } - } override fun validateMemo(network: Network, memo: String): Boolean { if (memo.isEmpty()) return true diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt b/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt index 7a1b7db59c..d5fffe95ed 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/di/TransactionDataModule.kt @@ -43,7 +43,11 @@ internal object TransactionDataModule { @Singleton fun providesWalletAddressServiceRepository( walletManagersFacade: WalletManagersFacade, + coroutineDispatcherProvider: CoroutineDispatcherProvider, ): WalletAddressServiceRepository { - return DefaultWalletAddressServiceRepository(walletManagersFacade) + return DefaultWalletAddressServiceRepository( + walletManagersFacade = walletManagersFacade, + dispatchers = coroutineDispatcherProvider, + ) } } \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt index 14f5fa53fa..9e1c59ea3d 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/WalletManagersFacade.kt @@ -254,6 +254,11 @@ interface WalletManagersFacade { signer: CommonSigner, ): SimpleResult - /** Indicates UTXO consolidation availability */ + /** + * Indicates UTXO consolidation availability + * + * @param userWalletId selected user wallet + * @param network availability for network + */ suspend fun checkUtxoConsolidationAvailability(userWalletId: UserWalletId, network: Network): Boolean } \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt index 9d9de200e8..7db3a825f7 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/ValidateWalletAddressUseCase.kt @@ -9,8 +9,6 @@ import com.tangem.domain.transaction.WalletAddressServiceRepository import com.tangem.domain.transaction.error.ValidateAddressError import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWalletId -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.withContext /** * Use case for validating wallet address. @@ -18,7 +16,6 @@ import kotlinx.coroutines.withContext class ValidateWalletAddressUseCase( private val walletAddressServiceRepository: WalletAddressServiceRepository, private val walletManagersFacade: WalletManagersFacade, - private val dispatchers: CoroutineDispatcherProvider, ) { suspend operator fun invoke( @@ -26,7 +23,7 @@ class ValidateWalletAddressUseCase( network: Network, address: String, currencyAddress: Set?, - ): Either = withContext(dispatchers.io) { + ): Either { val isUtxoConsolidationAvailable = walletManagersFacade.checkUtxoConsolidationAvailability(userWalletId, network) val isCurrentAddress = currencyAddress?.any { it.value == address } ?: true @@ -34,7 +31,7 @@ class ValidateWalletAddressUseCase( val isForbidSelfSend = isCurrentAddress && !isUtxoConsolidationAvailable val isValidAddress = walletAddressServiceRepository.validateAddress(userWalletId, network, address) - when { + return when { !isValidAddress -> ValidateAddressError.InvalidAddress.left() isForbidSelfSend -> ValidateAddressError.AddressInWallet.left() else -> Unit.right()