Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-10 13:31:07 +04:00
parent 49cf3b9cef
commit e17029ce9b
27 changed files with 184 additions and 207 deletions

View file

@ -6,9 +6,9 @@ import com.tangem.blockchainsdk.utils.toNetworkId
import com.tangem.data.common.account.WalletAccountsFetcher
import com.tangem.data.common.tokens.getDefaultWalletBlockchains
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.card.common.util.cardTypesResolver
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
@ -29,7 +29,7 @@ import com.tangem.domain.models.wallet.isMultiCurrency
internal class DefaultCardCryptoCurrencyFactory(
private val demoConfig: DemoConfig,
private val excludedBlockchains: ExcludedBlockchains,
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val accountsFeatureToggles: AccountsFeatureToggles,
private val walletAccountsFetcher: WalletAccountsFetcher,
private val userTokensResponseStore: UserTokensResponseStore,
@ -42,7 +42,7 @@ internal class DefaultCardCryptoCurrencyFactory(
userWalletId: UserWalletId,
networks: Set<Network>,
): Map<Network, List<CryptoCurrency>> {
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(id = userWalletId)
// multi-currency wallet
if (userWallet !is UserWallet.Cold || userWallet.isMultiCurrency) {
@ -67,7 +67,7 @@ internal class DefaultCardCryptoCurrencyFactory(
}
override suspend fun createByRawId(userWalletId: UserWalletId, network: Network.RawID): List<CryptoCurrency> {
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(id = userWalletId)
val blockchain = network.toBlockchain()

View file

@ -11,8 +11,8 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.api.tangemTech.models.WalletType
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -24,7 +24,7 @@ import timber.log.Timber
@Suppress("LongParameterList")
class UserTokensSaver(
private val tangemTechApi: TangemTechApi,
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val userTokensResponseStore: UserTokensResponseStore,
private val dispatchers: CoroutineDispatcherProvider,
private val addressesEnricher: UserTokensResponseAddressesEnricher,
@ -59,7 +59,7 @@ class UserTokensSaver(
useEnricher: Boolean = true,
onFailSend: () -> Unit = {},
) = withContext(dispatchers.io) {
val userWallet = userWalletsStore.getSyncOrNull(key = userWalletId)
val userWallet = userWalletsListRepository.getSyncOrNull(id = userWalletId)
if (userWallet == null) {
Timber.e("UserWallet with id $userWalletId not found. Cannot push tokens.")

View file

@ -13,8 +13,8 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.repository.WalletsRepository
@ -36,7 +36,7 @@ internal object DataCommonModule {
@Singleton
fun provideCardCryptoCurrencyFactory(
excludedBlockchains: ExcludedBlockchains,
userWalletsStore: UserWalletsStore,
userWalletsListRepository: UserWalletsListRepository,
accountsFeatureToggles: AccountsFeatureToggles,
walletAccountsFetcher: WalletAccountsFetcher,
userTokensResponseStore: UserTokensResponseStore,
@ -45,7 +45,7 @@ internal object DataCommonModule {
return DefaultCardCryptoCurrencyFactory(
demoConfig = DemoConfig,
excludedBlockchains = excludedBlockchains,
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
accountsFeatureToggles = accountsFeatureToggles,
walletAccountsFetcher = walletAccountsFetcher,
userTokensResponseStore = userTokensResponseStore,
@ -71,7 +71,7 @@ internal object DataCommonModule {
@Singleton
fun provideUserTokensSaver(
tangemTechApi: TangemTechApi,
userWalletsStore: UserWalletsStore,
userWalletsListRepository: UserWalletsListRepository,
userTokensResponseStore: UserTokensResponseStore,
dispatchers: CoroutineDispatcherProvider,
addressesEnricher: UserTokensResponseAddressesEnricher,
@ -81,7 +81,7 @@ internal object DataCommonModule {
): UserTokensSaver {
return UserTokensSaver(
tangemTechApi = tangemTechApi,
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
userTokensResponseStore = userTokensResponseStore,
dispatchers = dispatchers,
addressesEnricher = addressesEnricher,
@ -109,13 +109,13 @@ internal object DataCommonModule {
@Provides
@Singleton
fun provideWalletServerBinder(
userWalletsStore: UserWalletsStore,
userWalletsListRepository: UserWalletsListRepository,
appsFlyerStore: AppsFlyerStore,
tangemTechApi: TangemTechApi,
dispatchers: CoroutineDispatcherProvider,
): WalletServerBinder {
return DefaultWalletServerBinder(
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
appsFlyerStore = appsFlyerStore,
tangemTechApi = tangemTechApi,
dispatchers = dispatchers,

View file

@ -4,21 +4,21 @@ import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.converters.WalletIdBodyConverter
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.withContext
internal class DefaultWalletServerBinder(
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val appsFlyerStore: AppsFlyerStore,
private val tangemTechApi: TangemTechApi,
private val dispatchers: CoroutineDispatcherProvider,
) : WalletServerBinder {
override suspend fun bind(userWalletId: UserWalletId): ApiResponse<Unit>? {
val userWallet = userWalletsStore.getSyncOrNull(key = userWalletId) ?: return null
val userWallet = userWalletsListRepository.getSyncOrNull(id = userWalletId) ?: return null
return bind(userWallet)
}

View file

@ -12,10 +12,10 @@ import com.tangem.data.common.account.WalletAccountsFetcher
import com.tangem.data.common.network.NetworkFactory
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.card.common.util.cardTypesResolver
import com.tangem.domain.card.configs.GenericCardConfig
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
@ -36,7 +36,7 @@ import org.junit.jupiter.params.ParameterizedTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class DefaultCardCryptoCurrencyFactoryTest {
private val userWalletsStore: UserWalletsStore = mockk()
private val userWalletsListRepository: UserWalletsListRepository = mockk()
private val userTokensResponseStore: UserTokensResponseStore = mockk()
private val excludedBlockchains = ExcludedBlockchains()
private val accountsFeatureToggles = mockk<AccountsFeatureToggles>()
@ -45,7 +45,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
private val factory = DefaultCardCryptoCurrencyFactory(
demoConfig = DemoConfig,
excludedBlockchains = excludedBlockchains,
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
userTokensResponseStore = userTokensResponseStore,
responseCryptoCurrenciesFactory = ResponseCryptoCurrenciesFactory(
networkFactory = NetworkFactory(excludedBlockchains = excludedBlockchains),
@ -63,7 +63,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
@BeforeEach
fun init() {
clearMocks(userWalletsStore, userTokensResponseStore, accountsFeatureToggles, walletAccountsFetcher, iconUri)
clearMocks(userWalletsListRepository, userTokensResponseStore, accountsFeatureToggles, walletAccountsFetcher, iconUri)
mockkStatic(Uri::class)
every { Uri.parse(any()) } returns iconUri
@ -82,7 +82,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
val network = ethereum.network
every { accountsFeatureToggles.isFeatureEnabled } returns false
coEvery { userWalletsStore.getSyncStrict(key = userWallet.walletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncStrict(id = userWallet.walletId) } returns userWallet
coEvery { userTokensResponseStore.getSyncOrNull(userWallet.walletId) } returns userTokensResponse
// Act
@ -94,7 +94,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
Truth.assertThat(actual).isEqualTo(expected)
coVerifyOrder {
userWalletsStore.getSyncStrict(key = userWallet.walletId)
userWalletsListRepository.getSyncStrict(id = userWallet.walletId)
userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId)
}
}
@ -131,7 +131,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
// Arrange
val userWallet = createSingleWallet()
coEvery { userWalletsStore.getSyncStrict(key = userWallet.walletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncStrict(id = userWallet.walletId) } returns userWallet
// Act
val actual = factory.create(userWalletId = userWallet.walletId, network = model.network)
@ -142,7 +142,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
Truth.assertThat(actual).isEqualTo(expected)
coVerifyOrder {
userWalletsStore.getSyncStrict(key = userWallet.walletId)
userWalletsListRepository.getSyncStrict(id = userWallet.walletId)
userWallet.scanResponse.cardTypesResolver.getBlockchain()
}
@ -169,7 +169,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
// Arrange
val userWallet = MockUserWalletFactory.createSingleWalletWithToken()
coEvery { userWalletsStore.getSyncStrict(key = userWallet.walletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncStrict(id = userWallet.walletId) } returns userWallet
// Act
val actual = factory.create(userWalletId = userWallet.walletId, network = model.network)
@ -186,7 +186,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest {
Truth.assertThat(actual).isEqualTo(expected)
coVerifyOrder {
userWalletsStore.getSyncStrict(key = userWallet.walletId)
userWalletsListRepository.getSyncStrict(id = userWallet.walletId)
userWallet.scanResponse.cardTypesResolver.getBlockchain()
}

View file

@ -8,8 +8,8 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.api.tangemTech.models.WalletType
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
@ -23,7 +23,7 @@ import org.junit.jupiter.api.TestInstance
class UserTokensSaverTest {
private val tangemTechApi: TangemTechApi = mockk()
private val userWalletsStore: UserWalletsStore = mockk(relaxUnitFun = true)
private val userWalletsListRepository: UserWalletsListRepository = mockk(relaxUnitFun = true)
private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxed = true)
private val enricher: UserTokensResponseAddressesEnricher = mockk()
private val accountsFeatureToggles = mockk<AccountsFeatureToggles> {
@ -34,7 +34,7 @@ class UserTokensSaverTest {
private val userTokensSaver: UserTokensSaver = UserTokensSaver(
tangemTechApi = tangemTechApi,
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
userTokensResponseStore = userTokensResponseStore,
dispatchers = TestingCoroutineDispatcherProvider(),
addressesEnricher = enricher,
@ -48,7 +48,7 @@ class UserTokensSaverTest {
fun resetMocks() {
clearMocks(
tangemTechApi,
userWalletsStore,
userWalletsListRepository,
userTokensResponseStore,
enricher,
walletServerBinder,
@ -119,7 +119,7 @@ class UserTokensSaverTest {
var onFailSendCalled = false
every { accountsFeatureToggles.isFeatureEnabled } returns true
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
coEvery { enricher(userWalletId, response) } returns enrichedResponse
coEvery { tangemTechApi.saveTokens(any(), any()) } returns ApiResponse.Error(error) as ApiResponse<Unit>
@ -165,7 +165,7 @@ class UserTokensSaverTest {
walletType = WalletType.COLD,
)
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
coEvery { enricher(userWalletId, response) } returns enrichedResponse
coEvery {
tangemTechApi.saveTokens(userWalletId.stringValue, enrichedResponse)

View file

@ -7,7 +7,7 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.WalletIdBody
import com.tangem.datasource.api.tangemTech.models.WalletType
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.wallets.models.AppsFlyerConversionData
@ -26,13 +26,13 @@ import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class DefaultWalletServerBinderTest {
private val userWalletsStore: UserWalletsStore = mockk()
private val userWalletsListRepository: UserWalletsListRepository = mockk()
private val appsFlyerStore: AppsFlyerStore = mockk()
private val tangemTechApi: TangemTechApi = mockk()
private val dispatchers: CoroutineDispatcherProvider = TestingCoroutineDispatcherProvider()
private val binder = DefaultWalletServerBinder(
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
appsFlyerStore = appsFlyerStore,
tangemTechApi = tangemTechApi,
dispatchers = dispatchers
@ -47,7 +47,7 @@ internal class DefaultWalletServerBinderTest {
@AfterEach
fun tearDown() {
clearMocks(userWalletsStore, appsFlyerStore, tangemTechApi)
clearMocks(userWalletsListRepository, appsFlyerStore, tangemTechApi)
}
@Nested
@ -65,7 +65,7 @@ internal class DefaultWalletServerBinderTest {
)
val apiResponse = ApiResponse.Success(Unit)
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
coEvery { appsFlyerStore.get() } returns conversionData
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
@ -74,22 +74,22 @@ internal class DefaultWalletServerBinderTest {
Truth.assertThat(actual).isEqualTo(apiResponse)
coVerifyOrder {
userWalletsStore.getSyncOrNull(userWalletId)
userWalletsListRepository.getSyncOrNull(userWalletId)
appsFlyerStore.get()
tangemTechApi.createWallet(requestBody)
}
}
@Test
fun `bind will skipped if userWalletsStore returns null`() = runTest {
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns null
fun `bind will skipped if userWalletsListRepository returns null`() = runTest {
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns null
val actual = binder.bind(userWalletId = userWalletId)
Truth.assertThat(actual).isEqualTo(null)
coVerifyOrder {
userWalletsStore.getSyncOrNull(userWalletId)
userWalletsListRepository.getSyncOrNull(userWalletId)
}
coVerify(inverse = true) {
@ -107,7 +107,7 @@ internal class DefaultWalletServerBinderTest {
)
val apiResponse = ApiResponse.Success(Unit)
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
coEvery { appsFlyerStore.get() } returns null
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
@ -116,7 +116,7 @@ internal class DefaultWalletServerBinderTest {
Truth.assertThat(actual).isEqualTo(apiResponse)
coVerifyOrder {
userWalletsStore.getSyncOrNull(userWalletId)
userWalletsListRepository.getSyncOrNull(userWalletId)
appsFlyerStore.get()
tangemTechApi.createWallet(requestBody)
}
@ -133,7 +133,7 @@ internal class DefaultWalletServerBinderTest {
)
val apiResponse = ApiResponse.Error(ApiResponseError.TimeoutException()) as ApiResponse<Unit>
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
coEvery { appsFlyerStore.get() } returns conversionData
coEvery { tangemTechApi.createWallet(requestBody) } returns apiResponse
@ -142,7 +142,7 @@ internal class DefaultWalletServerBinderTest {
Truth.assertThat(actual).isEqualTo(apiResponse)
coVerifyOrder {
userWalletsStore.getSyncOrNull(userWalletId)
userWalletsListRepository.getSyncOrNull(userWalletId)
appsFlyerStore.get()
tangemTechApi.createWallet(requestBody)
}