Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-02 22:46:13 +04:00
parent 699606ad3e
commit 42b4c894bb
3 changed files with 37 additions and 20 deletions

View file

@ -16,6 +16,7 @@ import com.tangem.data.account.store.ArchivedAccountsStoreFactory
import com.tangem.data.account.tokens.DefaultMainAccountTokensMigration
import com.tangem.data.common.account.WalletAccountsFetcher
import com.tangem.data.common.account.WalletAccountsSaver
import com.tangem.data.common.cache.etag.ETagsStore
import com.tangem.data.common.currency.UserTokensSaver
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.di.NetworkMoshi
@ -117,11 +118,15 @@ internal object AccountDataModule {
accountsResponseStoreFactory: AccountsResponseStoreFactory,
userTokensSaver: UserTokensSaver,
accountTokenMigrationStore: AccountTokenMigrationStore,
eTagsStore: ETagsStore,
dispatchers: CoroutineDispatcherProvider,
): DefaultMainAccountTokensMigration {
return DefaultMainAccountTokensMigration(
accountsResponseStoreFactory = accountsResponseStoreFactory,
accountTokenMigrationStore = accountTokenMigrationStore,
userTokensSaver = userTokensSaver,
eTagsStore = eTagsStore,
dispatchers = dispatchers,
)
}
}

View file

@ -11,6 +11,7 @@ import com.tangem.data.account.converter.AccountNameConverter
import com.tangem.data.account.converter.toDerivationIndex
import com.tangem.data.account.store.AccountsResponseStoreFactory
import com.tangem.data.account.utils.assignTokens
import com.tangem.data.common.cache.etag.ETagsStore
import com.tangem.data.common.currency.UserTokensSaver
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
@ -22,6 +23,10 @@ import com.tangem.domain.account.tokens.MainAccountTokensMigration
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.lib.crypto.derivation.AccountNodeRecognizer
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import timber.log.Timber
/**
@ -37,8 +42,12 @@ internal class DefaultMainAccountTokensMigration(
private val accountsResponseStoreFactory: AccountsResponseStoreFactory,
private val accountTokenMigrationStore: AccountTokenMigrationStore,
private val userTokensSaver: UserTokensSaver,
private val eTagsStore: ETagsStore,
dispatchers: CoroutineDispatcherProvider,
) : MainAccountTokensMigration {
private val coroutineScope = CoroutineScope(dispatchers.default + SupervisorJob())
internal suspend fun migrate(userWalletId: UserWalletId): Either<Throwable, GetWalletAccountsResponse> = either {
val store = accountsResponseStoreFactory.create(userWalletId)
val response = store.getSyncOrNull()
@ -89,16 +98,7 @@ internal class DefaultMainAccountTokensMigration(
store.updateData { updatedResponse }
val userTokensResponse = updatedResponse.toUserTokensResponse()
userTokensSaver.pushWithRetryer(
userWalletId = userWalletId,
response = userTokensResponse,
onFailSend = {
val exception = IllegalStateException("Failed to push updated tokens after migration")
Timber.e(exception)
raise(exception)
},
)
pushTokens(userWalletId, updatedResponse)
return@either updatedResponse
}
@ -151,16 +151,7 @@ internal class DefaultMainAccountTokensMigration(
val selectedAccountName = AccountNameConverter.convertBack(selectedAccount.name)
accountTokenMigrationStore.store(userWalletId, mainAccountName to selectedAccountName)
val userTokensResponse = updatedResponse.toUserTokensResponse()
userTokensSaver.pushWithRetryer(
userWalletId = userWalletId,
response = userTokensResponse,
onFailSend = {
val exception = IllegalStateException("Failed to push updated tokens after migration")
Timber.e(exception)
raise(exception)
},
)
pushTokens(userWalletId, updatedResponse)
}
private fun Raise<Throwable>.findAccount(
@ -232,4 +223,20 @@ internal class DefaultMainAccountTokensMigration(
accountNodeValue == derivationIndex.value.toLong()
}
}
private suspend fun Raise<Throwable>.pushTokens(userWalletId: UserWalletId, response: GetWalletAccountsResponse) {
val userTokensResponse = response.toUserTokensResponse()
userTokensSaver.pushWithRetryer(
userWalletId = userWalletId,
response = userTokensResponse,
onFailSend = {
coroutineScope.launch {
eTagsStore.clear(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts)
}
val exception = IllegalStateException("Failed to push updated tokens after migration")
Timber.e(exception)
raise(exception)
},
)
}
}

View file

@ -6,6 +6,7 @@ import com.tangem.data.account.converter.createWalletAccountDTO
import com.tangem.data.account.store.AccountsResponseStore
import com.tangem.data.account.store.AccountsResponseStoreFactory
import com.tangem.data.account.tokens.DefaultMainAccountTokensMigration
import com.tangem.data.common.cache.etag.ETagsStore
import com.tangem.data.common.currency.UserTokensSaver
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
@ -17,6 +18,7 @@ import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.test.core.assertEither
import com.tangem.test.core.assertEitherLeft
import com.tangem.test.core.assertEitherRight
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
@ -34,11 +36,14 @@ class DefaultMainAccountTokensMigrationTest {
private val accountsResponseStoreFlow = MutableStateFlow<GetWalletAccountsResponse?>(value = null)
private val accountTokenMigrationStore = mockk<AccountTokenMigrationStore>(relaxUnitFun = true)
private val userTokensSaver = mockk<UserTokensSaver>(relaxUnitFun = true)
private val eTagsStore = mockk<ETagsStore>(relaxUnitFun = true)
private val migration = DefaultMainAccountTokensMigration(
accountsResponseStoreFactory = accountsResponseStoreFactory,
accountTokenMigrationStore = accountTokenMigrationStore,
userTokensSaver = userTokensSaver,
eTagsStore = eTagsStore,
dispatchers = TestingCoroutineDispatcherProvider(),
)
private val userWalletId = UserWalletId("011")