Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-18 12:36:46 +05:00
parent 26201c5c0b
commit 0be1358760
39 changed files with 581 additions and 124 deletions

View file

@ -12,6 +12,7 @@ android {
}
dependencies {
api(projects.domain.account)
api(projects.domain.card)
api(projects.domain.core)
api(projects.domain.common)
api(projects.domain.express)

View file

@ -8,6 +8,7 @@ import com.tangem.domain.account.status.utils.CryptoCurrencyBalanceFetcher
import com.tangem.domain.account.status.utils.CryptoCurrencyMetadataCleaner
import com.tangem.domain.account.supplier.MultiAccountListSupplier
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.card.IsWalletBackupProblematicUseCase
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
import com.tangem.domain.express.ExpressServiceFetcher
@ -24,6 +25,7 @@ import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.derivations.DerivationsRepository
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
@ -50,6 +52,20 @@ internal object AccountStatusUseCaseModule {
)
}
@Provides
@Singleton
fun provideGetBackupProblematicWalletForAddressUseCase(
getAccountCurrencyByAddressUseCase: GetAccountCurrencyByAddressUseCase,
getUserWalletUseCase: GetUserWalletUseCase,
isWalletBackupProblematicUseCase: IsWalletBackupProblematicUseCase,
): GetBackupProblematicWalletForAddressUseCase {
return GetBackupProblematicWalletForAddressUseCase(
getAccountCurrencyByAddressUseCase = getAccountCurrencyByAddressUseCase,
getUserWalletUseCase = getUserWalletUseCase,
isWalletBackupProblematicUseCase = isWalletBackupProblematicUseCase,
)
}
@Provides
@Singleton
fun provideIsAccountsModeEnabledUseCase(

View file

@ -0,0 +1,24 @@
package com.tangem.domain.account.status.usecase
import com.tangem.domain.card.IsWalletBackupProblematicUseCase
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
/**
* Resolves [address] to one of the user's own wallets and returns its [UserWalletId] when that wallet
* has a backup error (e.g. a CardLinked card), or `null` otherwise.
*
* Shared by the send and swap flows to block topping up a wallet with a backup problem.
*/
class GetBackupProblematicWalletForAddressUseCase(
private val getAccountCurrencyByAddressUseCase: GetAccountCurrencyByAddressUseCase,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val isWalletBackupProblematicUseCase: IsWalletBackupProblematicUseCase,
) {
suspend operator fun invoke(address: String): UserWalletId? {
val walletId = getAccountCurrencyByAddressUseCase(address).getOrNull()?.account?.userWalletId ?: return null
val wallet = getUserWalletUseCase(walletId).getOrNull() ?: return null
return walletId.takeIf { isWalletBackupProblematicUseCase(wallet) }
}
}

View file

@ -0,0 +1,82 @@
package com.tangem.domain.account.status.usecase
import arrow.core.left
import arrow.core.none
import arrow.core.right
import arrow.core.some
import com.google.common.truth.Truth.assertThat
import com.tangem.domain.account.status.model.AccountCryptoCurrency
import com.tangem.domain.card.IsWalletBackupProblematicUseCase
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.wallets.models.GetUserWalletError
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import io.mockk.clearMocks
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class GetBackupProblematicWalletForAddressUseCaseTest {
private val getAccountCurrencyByAddressUseCase: GetAccountCurrencyByAddressUseCase = mockk()
private val getUserWalletUseCase: GetUserWalletUseCase = mockk()
private val isWalletBackupProblematicUseCase: IsWalletBackupProblematicUseCase = mockk()
private val useCase = GetBackupProblematicWalletForAddressUseCase(
getAccountCurrencyByAddressUseCase = getAccountCurrencyByAddressUseCase,
getUserWalletUseCase = getUserWalletUseCase,
isWalletBackupProblematicUseCase = isWalletBackupProblematicUseCase,
)
@AfterEach
fun tearDown() {
clearMocks(getAccountCurrencyByAddressUseCase, getUserWalletUseCase, isWalletBackupProblematicUseCase)
}
@Test
fun `returns null when address is not resolved to an account`() = runTest {
coEvery { getAccountCurrencyByAddressUseCase(ADDRESS) } returns none()
assertThat(useCase(ADDRESS)).isNull()
}
@Test
fun `returns null when destination wallet is not found`() = runTest {
coEvery { getAccountCurrencyByAddressUseCase(ADDRESS) } returns accountCurrency.some()
every { getUserWalletUseCase(walletId) } returns GetUserWalletError.UserWalletNotFound.left()
assertThat(useCase(ADDRESS)).isNull()
}
@Test
fun `returns null when destination wallet is not problematic`() = runTest {
coEvery { getAccountCurrencyByAddressUseCase(ADDRESS) } returns accountCurrency.some()
every { getUserWalletUseCase(walletId) } returns userWallet.right()
every { isWalletBackupProblematicUseCase(userWallet) } returns false
assertThat(useCase(ADDRESS)).isNull()
}
@Test
fun `returns wallet id when destination wallet is problematic`() = runTest {
coEvery { getAccountCurrencyByAddressUseCase(ADDRESS) } returns accountCurrency.some()
every { getUserWalletUseCase(walletId) } returns userWallet.right()
every { isWalletBackupProblematicUseCase(userWallet) } returns true
assertThat(useCase(ADDRESS)).isEqualTo(walletId)
}
private companion object {
const val ADDRESS = "0x1234567890abcdef"
val walletId = UserWalletId("011")
val userWallet = mockk<UserWallet>()
val accountCurrency = mockk<AccountCryptoCurrency> {
every { account } returns mockk { every { userWalletId } returns walletId }
}
}
}