Updated on 2026-08-14

This commit is contained in:
Tangem 2024-05-30 15:48:27 +05:00
parent fd128f3bd7
commit 8b0f0e589e
11 changed files with 77 additions and 46 deletions

View file

@ -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,
)
}

View file

@ -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(

View file

@ -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 {

View file

@ -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<CryptoCurrency.Token>) {
if (tokens.isEmpty()) return

View file

@ -253,4 +253,7 @@ interface WalletManagersFacade {
currency: CryptoCurrency,
signer: CommonSigner,
): SimpleResult
/** Indicates UTXO consolidation availability */
suspend fun checkUtxoConsolidationAvailability(userWalletId: UserWalletId, network: Network): Boolean
}

View file

@ -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

View file

@ -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()
}

View file

@ -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

View file

@ -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<NetworkAddress.Address>?,
): Either<ValidateAddressError, Unit> = 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()
}
}
}

View file

@ -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.

View file

@ -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<Throwable, Boolean> = withContext(dispatchers.io) {
Either.catch {
walletAddressServiceRepository.validateAddress(userWalletId, network, address)
}
}
}