Updated on 2026-08-14
This commit is contained in:
parent
983b9b253d
commit
0ab1c7507a
18 changed files with 188 additions and 193 deletions
|
|
@ -21,6 +21,7 @@ import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
|||
import com.tangem.datasource.local.config.issuers.IssuersConfigStorage
|
||||
import com.tangem.datasource.local.logs.AppLogsStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
||||
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
|
||||
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
||||
|
|
@ -145,4 +146,6 @@ interface ApplicationEntryPoint {
|
|||
fun getColdUserWalletBuilderFactory(): ColdUserWalletBuilder.Factory
|
||||
|
||||
fun getApiConfigsManager(): ApiConfigsManager
|
||||
|
||||
fun getUserTokensResponseStore(): UserTokensResponseStore
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
|||
import com.tangem.datasource.local.config.issuers.IssuersConfigStorage
|
||||
import com.tangem.datasource.local.logs.AppLogsStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.utils.NetworkLogsSaveInterceptor
|
||||
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
||||
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
|
||||
|
|
@ -232,6 +233,9 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
private val apiConfigsManager: ApiConfigsManager
|
||||
get() = entryPoint.getApiConfigsManager()
|
||||
|
||||
private val userTokensResponseStore: UserTokensResponseStore
|
||||
get() = entryPoint.getUserTokensResponseStore()
|
||||
|
||||
// endregion
|
||||
|
||||
private val appScope = MainScope()
|
||||
|
|
@ -320,7 +324,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
}
|
||||
|
||||
derivationsFinder = DerivationsFinder(
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
|
|
@ -370,6 +374,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
|
|||
uiMessageSender = uiMessageSender,
|
||||
onlineCardVerifier = onlineCardVerifier,
|
||||
coldUserWalletBuilderFactory = coldUserWalletBuilderFactory,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ import com.tangem.core.ui.R
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.toWrappedList
|
||||
import com.tangem.core.ui.message.dialog.Dialogs
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.domain.common.util.twinsIsTwinned
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
|
|
@ -258,10 +255,10 @@ internal class LegacyScanProcessor @Inject constructor(
|
|||
onSuccess()
|
||||
return
|
||||
}
|
||||
val appPrefStoreStore = store.inject(DaggerGraphState::appPreferencesStore)
|
||||
val tokens = appPrefStoreStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
)
|
||||
|
||||
val userTokensResponseStore = store.inject(DaggerGraphState::userTokensResponseStore)
|
||||
val tokens = userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
||||
|
||||
if (scanResponse.card.isAccessCodeSet && tokens == null) {
|
||||
store.dispatchDialogShow(
|
||||
AppDialog.WalletAlreadyWasUsedDialog(
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchain.common.derivation.DerivationStyle
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
|
|
@ -25,7 +22,7 @@ internal data class BlockchainToDerive(
|
|||
|
||||
// FIXME: May be move to DI, currently unnecessary
|
||||
internal class DerivationsFinder(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val userTokensResponseStore: UserTokensResponseStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
|
||||
|
|
@ -67,10 +64,7 @@ internal class DerivationsFinder(
|
|||
}
|
||||
|
||||
private suspend fun getBlockchains(userWalletId: UserWalletId): MutableSet<BlockchainToDerive> {
|
||||
val responseTokens = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
)
|
||||
?.tokens
|
||||
val responseTokens = userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)?.tokens
|
||||
?: return hashSetOf()
|
||||
|
||||
return responseTokens.asSequence()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.datasource.connection.NetworkConnectionManager
|
|||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.datasource.local.config.issuers.IssuersConfigStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
||||
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
||||
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
|
||||
|
|
@ -79,4 +80,5 @@ data class DaggerGraphState(
|
|||
val onlineCardVerifier: OnlineCardVerifier? = null,
|
||||
val cardArworksProvider: CardArtworksProvider? = null,
|
||||
val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory? = null,
|
||||
val userTokensResponseStore: UserTokensResponseStore? = null,
|
||||
) : StateType
|
||||
|
|
@ -151,8 +151,6 @@ object PreferencesKeys {
|
|||
fun getShouldShowInitialPermissionScreen(permission: String) =
|
||||
booleanPreferencesKey("shouldShowInitialPushPermissionScreen_$permission")
|
||||
// endregion
|
||||
|
||||
fun getUserTokensKey(userWalletId: String) = stringPreferencesKey(name = "user_tokens_$userWalletId")
|
||||
}
|
||||
|
||||
/** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore<Preferences> */
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObject
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Default implementation of [UserTokensResponseStore]
|
||||
|
|
@ -17,9 +20,24 @@ internal class DefaultUserTokensResponseStore(
|
|||
private val appPreferencesStore: AppPreferencesStore,
|
||||
) : UserTokensResponseStore {
|
||||
|
||||
override suspend fun getSyncOrNull(userWalletId: UserWalletId): UserTokensResponse? {
|
||||
return appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId = userWalletId.stringValue),
|
||||
override fun get(userWalletId: UserWalletId): Flow<UserTokensResponse?> {
|
||||
return appPreferencesStore.getObject<UserTokensResponse>(
|
||||
key = createPreferencesKey(userWalletId = userWalletId.stringValue),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getSyncOrNull(userWalletId: UserWalletId): UserTokensResponse? {
|
||||
return appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = createPreferencesKey(userWalletId = userWalletId.stringValue),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun store(userWalletId: UserWalletId, response: UserTokensResponse) {
|
||||
appPreferencesStore.storeObject(
|
||||
key = createPreferencesKey(userWalletId = userWalletId.stringValue),
|
||||
value = response,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createPreferencesKey(userWalletId: String) = stringPreferencesKey(name = "user_tokens_$userWalletId")
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.datasource.local.token
|
|||
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Store of [UserTokensResponse]
|
||||
|
|
@ -10,6 +11,10 @@ import com.tangem.domain.wallets.models.UserWalletId
|
|||
*/
|
||||
interface UserTokensResponseStore {
|
||||
|
||||
fun get(userWalletId: UserWalletId): Flow<UserTokensResponse?>
|
||||
|
||||
/** Get [UserTokensResponse] synchronously by [userWalletId] or null */
|
||||
suspend fun getSyncOrNull(userWalletId: UserWalletId): UserTokensResponse?
|
||||
|
||||
suspend fun store(userWalletId: UserWalletId, response: UserTokensResponse)
|
||||
}
|
||||
|
|
@ -4,17 +4,15 @@ import com.tangem.data.common.api.safeApiCall
|
|||
import com.tangem.data.common.tokens.UserTokensBackwardCompatibility
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
||||
class UserTokensSaver constructor(
|
||||
class UserTokensSaver(
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val userTokensResponseStore: UserTokensResponseStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val userTokensResponseAddressesEnricher: UserTokensResponseAddressesEnricher,
|
||||
) {
|
||||
|
|
@ -31,10 +29,8 @@ class UserTokensSaver constructor(
|
|||
} else {
|
||||
compatibleUserTokensResponse
|
||||
}
|
||||
appPreferencesStore.storeObject(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId = userWalletId.stringValue),
|
||||
value = enrichedUserTokensResponse,
|
||||
)
|
||||
|
||||
userTokensResponseStore.store(userWalletId = userWalletId, response = enrichedUserTokensResponse)
|
||||
}
|
||||
|
||||
suspend fun storeAndPush(userWalletId: UserWalletId, response: UserTokensResponse) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.data.common.currency.UserTokensSaver
|
|||
import com.tangem.data.common.quote.DefaultQuotesFetcher
|
||||
import com.tangem.data.common.quote.QuotesFetcher
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
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.demo.DemoConfig
|
||||
|
|
@ -61,13 +60,13 @@ internal object DataCommonModule {
|
|||
@Singleton
|
||||
fun provideUserTokensSaver(
|
||||
tangemTechApi: TangemTechApi,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
userTokensResponseStore: UserTokensResponseStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
enricher: UserTokensResponseAddressesEnricher,
|
||||
): UserTokensSaver {
|
||||
return UserTokensSaver(
|
||||
tangemTechApi = tangemTechApi,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
dispatchers = dispatchers,
|
||||
userTokensResponseAddressesEnricher = enricher,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,51 +1,35 @@
|
|||
package com.tangem.data.common.currency
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class UserTokensSaverTest {
|
||||
|
||||
private val tangemTechApi: TangemTechApi = mockk()
|
||||
private val dataStore: DataStore<Preferences> = mockk(relaxed = true)
|
||||
private val appPreferenceStore = AppPreferencesStore(
|
||||
moshi = Moshi.Builder().build(),
|
||||
private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxed = true)
|
||||
private val enricher: UserTokensResponseAddressesEnricher = mockk()
|
||||
|
||||
private val userTokensSaver: UserTokensSaver = UserTokensSaver(
|
||||
tangemTechApi = tangemTechApi,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
userTokensResponseAddressesEnricher = enricher,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
preferencesDataStore = dataStore,
|
||||
)
|
||||
private val dispatchers: CoroutineDispatcherProvider = TestingCoroutineDispatcherProvider()
|
||||
private val userTokensResponseAddressesEnricher: UserTokensResponseAddressesEnricher = mockk()
|
||||
|
||||
private lateinit var userTokensSaver: UserTokensSaver
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
coEvery { dataStore.data } returns flowOf(mockk(relaxed = true))
|
||||
userTokensSaver = UserTokensSaver(
|
||||
tangemTechApi = tangemTechApi,
|
||||
appPreferencesStore = appPreferenceStore,
|
||||
dispatchers = dispatchers,
|
||||
userTokensResponseAddressesEnricher = userTokensResponseAddressesEnricher,
|
||||
)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
clearAllMocks()
|
||||
@BeforeEach
|
||||
fun resetMocks() {
|
||||
clearMocks(tangemTechApi, userTokensResponseStore, enricher)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -58,57 +42,30 @@ class UserTokensSaverTest {
|
|||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
val enrichedResponse = UserTokensResponse(
|
||||
version = 0,
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
sort = UserTokensResponse.SortType.MANUAL,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
coEvery { userTokensResponseAddressesEnricher(userWalletId, response) } returns enrichedResponse
|
||||
coEvery { dataStore.updateData(any()) } returns mockk(relaxed = true)
|
||||
|
||||
coEvery { enricher(userWalletId, response) } returns enrichedResponse
|
||||
|
||||
// WHEN
|
||||
userTokensSaver.store(userWalletId, response)
|
||||
|
||||
// THEN
|
||||
coVerify {
|
||||
dataStore.updateData(any())
|
||||
coVerifyOrder {
|
||||
enricher(userWalletId, response)
|
||||
userTokensResponseStore.store(userWalletId, enrichedResponse)
|
||||
}
|
||||
coVerify(exactly = 0) {
|
||||
|
||||
coVerify(inverse = true) {
|
||||
tangemTechApi.saveUserTokens(any(), any())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN user wallet id and response WHEN storeAndPush THEN should store and push enriched response`() = runTest {
|
||||
// GIVEN
|
||||
val userWalletId = UserWalletId("1234567890abcdef")
|
||||
val response = UserTokensResponse(
|
||||
version = 0,
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
val enrichedResponse = UserTokensResponse(
|
||||
version = 0,
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
coEvery { userTokensResponseAddressesEnricher(userWalletId, response) } returns enrichedResponse
|
||||
coEvery { dataStore.updateData(any()) } returns mockk(relaxed = true)
|
||||
coEvery { tangemTechApi.saveUserTokens(any(), any()) } returns ApiResponse.Success(Unit)
|
||||
|
||||
// WHEN
|
||||
userTokensSaver.storeAndPush(userWalletId, response)
|
||||
|
||||
// THEN
|
||||
coVerify {
|
||||
dataStore.updateData(any())
|
||||
tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN user wallet id and response WHEN push AND api call fails THEN should log error and call onFailSend`() =
|
||||
runTest {
|
||||
|
|
@ -123,14 +80,13 @@ class UserTokensSaverTest {
|
|||
val enrichedResponse = UserTokensResponse(
|
||||
version = 0,
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
sort = UserTokensResponse.SortType.MANUAL,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
val error = ApiResponseError.UnknownException(Exception("API Error"))
|
||||
var onFailSendCalled = false
|
||||
coEvery { userTokensResponseAddressesEnricher(userWalletId, response) } returns enrichedResponse
|
||||
coEvery { tangemTechApi.saveUserTokens(any(), any()) } returns
|
||||
ApiResponse.Error(error) as ApiResponse<Unit>
|
||||
coEvery { enricher(userWalletId, response) } returns enrichedResponse
|
||||
coEvery { tangemTechApi.saveUserTokens(any(), any()) } returns ApiResponse.Error(error) as ApiResponse<Unit>
|
||||
|
||||
// WHEN
|
||||
userTokensSaver.push(
|
||||
|
|
@ -140,12 +96,42 @@ class UserTokensSaverTest {
|
|||
)
|
||||
|
||||
// THEN
|
||||
coVerify {
|
||||
coVerifyOrder {
|
||||
enricher(userWalletId, response)
|
||||
tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse)
|
||||
}
|
||||
coVerify(exactly = 0) {
|
||||
dataStore.updateData(any())
|
||||
}
|
||||
|
||||
assert(onFailSendCalled) { "onFailSend callback should be called when API call fails" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN user wallet id and response WHEN storeAndPush THEN should store and push enriched response`() = runTest {
|
||||
// GIVEN
|
||||
val userWalletId = UserWalletId("1234567890abcdef")
|
||||
val response = UserTokensResponse(
|
||||
version = 0,
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
val enrichedResponse = UserTokensResponse(
|
||||
version = 0,
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
coEvery { enricher(userWalletId, response) } returns enrichedResponse
|
||||
coEvery {
|
||||
tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse)
|
||||
} returns ApiResponse.Success(Unit)
|
||||
|
||||
// WHEN
|
||||
userTokensSaver.storeAndPush(userWalletId, response)
|
||||
|
||||
// THEN
|
||||
coVerifyOrder {
|
||||
enricher(userWalletId, response)
|
||||
tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,10 +12,7 @@ import com.tangem.data.common.network.NetworkFactory
|
|||
import com.tangem.data.managetokens.utils.TokenAddressesConverter
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.extensions.canHandleBlockchain
|
||||
import com.tangem.domain.common.extensions.supportedBlockchains
|
||||
|
|
@ -35,7 +32,7 @@ import kotlinx.coroutines.withContext
|
|||
internal class DefaultCustomTokensRepository(
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val userTokensResponseStore: UserTokensResponseStore,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -71,9 +68,8 @@ internal class DefaultCustomTokensRepository(
|
|||
contractAddress: String?,
|
||||
): Boolean {
|
||||
return withContext(dispatchers.io) {
|
||||
val storedCurrencies = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
)
|
||||
val storedCurrencies = userTokensResponseStore.getSyncOrNull(userWalletId)
|
||||
|
||||
requireNotNull(storedCurrencies) {
|
||||
"User tokens not found for user wallet [$userWalletId] while checking if currency is not added"
|
||||
}
|
||||
|
|
@ -230,9 +226,8 @@ internal class DefaultCustomTokensRepository(
|
|||
contractAddress = currency.contractAddress,
|
||||
)
|
||||
}
|
||||
val storedCurrencies = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
)
|
||||
val storedCurrencies = userTokensResponseStore.getSyncOrNull(userWalletId)
|
||||
|
||||
requireNotNull(storedCurrencies) {
|
||||
"User tokens not found for user wallet [$userWalletId] while removing currency"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@ import com.tangem.datasource.api.common.response.getOrThrow
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.config.testnet.TestnetTokensStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.domain.common.extensions.canHandleBlockchain
|
||||
|
|
@ -46,7 +44,7 @@ internal class DefaultManageTokensRepository(
|
|||
private val tangemTechApi: TangemTechApi,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val manageTokensUpdateFetcher: ManageTokensUpdateFetcher,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val userTokensResponseStore: UserTokensResponseStore,
|
||||
private val testnetTokensStorage: TestnetTokensStorage,
|
||||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
|
|
@ -251,9 +249,7 @@ internal class DefaultManageTokensRepository(
|
|||
}
|
||||
|
||||
private suspend fun getSavedUserTokensResponseSync(key: UserWalletId): UserTokensResponse? {
|
||||
return appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(key.stringValue),
|
||||
)
|
||||
return userTokensResponseStore.getSyncOrNull(userWalletId = key)
|
||||
}
|
||||
|
||||
override suspend fun checkCurrencyUnsupportedState(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import com.tangem.data.managetokens.DefaultManageTokensRepository
|
|||
import com.tangem.data.managetokens.utils.ManageTokensUpdateFetcher
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.local.config.testnet.TestnetTokensStorage
|
||||
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.managetokens.repository.CustomTokensRepository
|
||||
import com.tangem.domain.managetokens.repository.ManageTokensRepository
|
||||
|
|
@ -31,7 +31,7 @@ internal object ManageTokensDataModule {
|
|||
tangemTechApi: TangemTechApi,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
manageTokensUpdateFetcher: ManageTokensUpdateFetcher,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
userTokensResponseStore: UserTokensResponseStore,
|
||||
testnetTokensStorage: TestnetTokensStorage,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
|
|
@ -42,7 +42,7 @@ internal object ManageTokensDataModule {
|
|||
tangemTechApi = tangemTechApi,
|
||||
userWalletsStore = userWalletsStore,
|
||||
manageTokensUpdateFetcher = manageTokensUpdateFetcher,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
testnetTokensStorage = testnetTokensStorage,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
|
|
@ -56,7 +56,7 @@ internal object ManageTokensDataModule {
|
|||
fun provideCustomTokensRepository(
|
||||
tangemTechApi: TangemTechApi,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
userTokensResponseStore: UserTokensResponseStore,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
|
|
@ -66,7 +66,7 @@ internal object ManageTokensDataModule {
|
|||
return DefaultCustomTokensRepository(
|
||||
tangemTechApi = tangemTechApi,
|
||||
userWalletsStore = userWalletsStore,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
dispatchers = dispatchers,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import com.tangem.datasource.exchangeservice.hotcrypto.HotCryptoResponseStore
|
|||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObject
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.extensions.canHandleBlockchain
|
||||
import com.tangem.domain.common.extensions.canHandleToken
|
||||
|
|
@ -58,6 +59,7 @@ internal class DefaultHotCryptoRepository(
|
|||
private val userWalletsStore: UserWalletsStore,
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val userTokensResponseStore: UserTokensResponseStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) : HotCryptoRepository {
|
||||
|
|
@ -103,9 +105,7 @@ internal class DefaultHotCryptoRepository(
|
|||
private fun getWalletsWithTokensFlow(): Flow<Map<UserWallet, List<UserTokensResponse.Token>>> {
|
||||
return userWalletsStore.userWallets.flatMapLatest { userWallets ->
|
||||
val flows = userWallets.map { userWallet ->
|
||||
appPreferencesStore.getObject<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWallet.walletId.stringValue),
|
||||
)
|
||||
userTokensResponseStore.get(userWalletId = userWallet.walletId)
|
||||
.map { userWallet to it?.tokens.orEmpty() }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.data.onramp.DefaultOnrampErrorResolver
|
|||
import com.tangem.data.onramp.DefaultOnrampRepository
|
||||
import com.tangem.data.onramp.DefaultOnrampTransactionRepository
|
||||
import com.tangem.data.onramp.converters.error.OnrampErrorConverter
|
||||
import com.tangem.domain.onramp.repositories.LegacyTopUpRepository
|
||||
import com.tangem.data.onramp.legacy.MercuryoTopUpRepository
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.api.express.models.response.ExpressErrorResponse
|
||||
|
|
@ -24,11 +23,9 @@ import com.tangem.datasource.local.onramp.pairs.OnrampPairsStore
|
|||
import com.tangem.datasource.local.onramp.paymentmethods.OnrampPaymentMethodsStore
|
||||
import com.tangem.datasource.local.onramp.quotes.OnrampQuotesStore
|
||||
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.onramp.repositories.HotCryptoRepository
|
||||
import com.tangem.domain.onramp.repositories.OnrampErrorResolver
|
||||
import com.tangem.domain.onramp.repositories.OnrampRepository
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
import com.tangem.domain.onramp.repositories.*
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
|
|
@ -104,6 +101,7 @@ internal object OnrampDataModule {
|
|||
appPreferencesStore: AppPreferencesStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
analyticsEventHandler: AnalyticsEventHandler,
|
||||
userTokensResponseStore: UserTokensResponseStore,
|
||||
): HotCryptoRepository {
|
||||
return DefaultHotCryptoRepository(
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
|
|
@ -113,6 +111,7 @@ internal object OnrampDataModule {
|
|||
appPreferencesStore = appPreferencesStore,
|
||||
dispatchers = dispatchers,
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.data.tokens.repository.DefaultPolkadotAccountHealthCheckReposi
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
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.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
|
|
@ -30,7 +31,7 @@ internal object TokensDataModule {
|
|||
@Singleton
|
||||
fun provideCurrenciesRepository(
|
||||
tangemTechApi: TangemTechApi,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
userTokensResponseStore: UserTokensResponseStore,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
cacheRegistry: CacheRegistry,
|
||||
|
|
@ -45,7 +46,7 @@ internal object TokensDataModule {
|
|||
userWalletsStore = userWalletsStore,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
cacheRegistry = cacheRegistry,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
expressServiceLoader = expressServiceLoader,
|
||||
dispatchers = dispatchers,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
|
|
|
|||
|
|
@ -14,10 +14,7 @@ import com.tangem.datasource.api.express.models.request.LeastTokenInfo
|
|||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObject
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.core.error.DataError
|
||||
|
|
@ -28,11 +25,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
|||
import com.tangem.domain.tokens.model.FeePaidCurrency
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.models.isLocked
|
||||
import com.tangem.domain.wallets.models.isMultiCurrency
|
||||
import com.tangem.domain.wallets.models.requireColdWallet
|
||||
import com.tangem.domain.wallets.models.*
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
|
@ -45,11 +38,11 @@ internal class DefaultCurrenciesRepository(
|
|||
private val userWalletsStore: UserWalletsStore,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val cacheRegistry: CacheRegistry,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val expressServiceLoader: ExpressServiceLoader,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||
private val userTokensSaver: UserTokensSaver,
|
||||
private val userTokensResponseStore: UserTokensResponseStore,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
) : CurrenciesRepository {
|
||||
|
||||
|
|
@ -96,7 +89,10 @@ internal class DefaultCurrenciesRepository(
|
|||
response = updatedResponse,
|
||||
)
|
||||
|
||||
fetchExpressAssetsByNetworkIds(userWalletId, updatedResponse)
|
||||
fetchExpressAssetsByNetworkIds(
|
||||
userWallet = userWalletsStore.getSyncStrict(key = userWalletId),
|
||||
userTokens = updatedResponse,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +115,11 @@ internal class DefaultCurrenciesRepository(
|
|||
userWalletId = userWalletId,
|
||||
response = updatedResponse,
|
||||
)
|
||||
fetchExpressAssetsByNetworkIds(userWalletId, updatedResponse)
|
||||
|
||||
fetchExpressAssetsByNetworkIds(
|
||||
userWallet = userWalletsStore.getSyncStrict(key = userWalletId),
|
||||
userTokens = updatedResponse,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
override fun getWalletCurrenciesUpdates(userWalletId: UserWalletId): Flow<List<CryptoCurrency>> {
|
||||
return channelFlow {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
|
||||
if (userWallet.isMultiCurrency) {
|
||||
getMultiCurrencyWalletCurrenciesUpdates(userWalletId).collect(::send)
|
||||
|
|
@ -222,13 +222,19 @@ internal class DefaultCurrenciesRepository(
|
|||
refresh: Boolean,
|
||||
): CryptoCurrency {
|
||||
return withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false)
|
||||
|
||||
val currency = cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(
|
||||
userWallet.requireColdWallet().scanResponse,
|
||||
)
|
||||
fetchExpressAssetsByNetworkIds(userWalletId, listOf(currency), refresh)
|
||||
|
||||
fetchExpressAssetsByNetworkIds(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrencies = listOf(currency),
|
||||
refresh = refresh,
|
||||
)
|
||||
|
||||
currency
|
||||
}
|
||||
}
|
||||
|
|
@ -238,7 +244,8 @@ internal class DefaultCurrenciesRepository(
|
|||
refresh: Boolean,
|
||||
): List<CryptoCurrency> {
|
||||
return withContext(dispatchers.io) {
|
||||
val scanResponse = getUserWallet(userWalletId).requireColdWallet().scanResponse
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
val scanResponse = userWallet.requireColdWallet().scanResponse
|
||||
|
||||
val currencies = if (scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
||||
cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(scanResponse = scanResponse)
|
||||
|
|
@ -248,7 +255,12 @@ internal class DefaultCurrenciesRepository(
|
|||
}
|
||||
}
|
||||
|
||||
fetchExpressAssetsByNetworkIds(userWalletId, currencies, refresh)
|
||||
fetchExpressAssetsByNetworkIds(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrencies = currencies,
|
||||
refresh = refresh,
|
||||
)
|
||||
|
||||
currencies
|
||||
}
|
||||
}
|
||||
|
|
@ -258,7 +270,7 @@ internal class DefaultCurrenciesRepository(
|
|||
id: CryptoCurrency.ID,
|
||||
): CryptoCurrency {
|
||||
return withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = false)
|
||||
|
||||
val currency = cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(
|
||||
|
|
@ -266,14 +278,14 @@ internal class DefaultCurrenciesRepository(
|
|||
)
|
||||
.find { it.id == id }
|
||||
requireNotNull(currency) { "Unable to find currency with provided ID: $id" }
|
||||
fetchExpressAssetsByNetworkIds(userWalletId, listOf(currency))
|
||||
fetchExpressAssetsByNetworkIds(userWallet, listOf(currency))
|
||||
currency
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMultiCurrencyWalletCurrenciesUpdates(userWalletId: UserWalletId): Flow<List<CryptoCurrency>> {
|
||||
return channelFlow {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
getMultiCurrencyWalletCurrencies(userWallet)
|
||||
|
|
@ -290,7 +302,7 @@ internal class DefaultCurrenciesRepository(
|
|||
userWalletId: UserWalletId,
|
||||
refresh: Boolean,
|
||||
): List<CryptoCurrency> = withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
fetchTokensIfCacheExpired(userWallet, refresh)
|
||||
|
|
@ -307,7 +319,7 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
override suspend fun getMultiCurrencyWalletCachedCurrenciesSync(userWalletId: UserWalletId) =
|
||||
withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
val storedTokens = requireNotNull(
|
||||
|
|
@ -329,7 +341,7 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
override suspend fun getMultiCurrencyWalletCurrency(userWalletId: UserWalletId, id: String): CryptoCurrency =
|
||||
withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
val response = requireNotNull(
|
||||
|
|
@ -352,7 +364,7 @@ internal class DefaultCurrenciesRepository(
|
|||
derivationPath: Network.DerivationPath,
|
||||
): CryptoCurrency.Coin {
|
||||
return withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet = userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
fetchTokensIfCacheExpired(userWallet = userWallet, refresh = false)
|
||||
|
|
@ -382,7 +394,7 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
override fun isTokensGrouped(userWalletId: UserWalletId): Flow<Boolean> {
|
||||
return channelFlow {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
|
||||
if (userWallet.isMultiCurrency) {
|
||||
getSavedUserTokensResponse(userWalletId)
|
||||
|
|
@ -398,7 +410,7 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
override fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow<Boolean> {
|
||||
return channelFlow {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
|
||||
if (userWallet.isMultiCurrency) {
|
||||
getSavedUserTokensResponse(userWalletId)
|
||||
|
|
@ -470,7 +482,7 @@ internal class DefaultCurrenciesRepository(
|
|||
contractAddress: String,
|
||||
networkId: String,
|
||||
): CryptoCurrency.Token {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
val token = withContext(dispatchers.io) {
|
||||
val foundToken = tangemTechApi.getCoins(
|
||||
contractAddress = contractAddress,
|
||||
|
|
@ -599,7 +611,7 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
userTokensSaver.store(userWalletId, compatibleUserTokensResponse)
|
||||
|
||||
fetchExpressAssetsByNetworkIds(userWalletId, compatibleUserTokensResponse)
|
||||
fetchExpressAssetsByNetworkIds(userWallet, compatibleUserTokensResponse)
|
||||
}
|
||||
|
||||
private suspend fun checkIsEmptyDemoWallet(userWallet: UserWallet.Cold): Boolean {
|
||||
|
|
@ -608,7 +620,7 @@ internal class DefaultCurrenciesRepository(
|
|||
return demoConfig.isDemoCardId(userWallet.cardId) && response == null
|
||||
}
|
||||
|
||||
private suspend fun fetchExpressAssetsByNetworkIds(userWalletId: UserWalletId, userTokens: UserTokensResponse) {
|
||||
private suspend fun fetchExpressAssetsByNetworkIds(userWallet: UserWallet, userTokens: UserTokensResponse) {
|
||||
val tokens = userTokens.tokens.map { token ->
|
||||
LeastTokenInfo(
|
||||
contractAddress = token.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE,
|
||||
|
|
@ -617,12 +629,12 @@ internal class DefaultCurrenciesRepository(
|
|||
}
|
||||
|
||||
coroutineScope {
|
||||
launch { expressServiceLoader.update(getUserWallet(userWalletId), tokens) }
|
||||
launch { expressServiceLoader.update(userWallet, tokens) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchExpressAssetsByNetworkIds(
|
||||
userWalletId: UserWalletId,
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrencies: List<CryptoCurrency>,
|
||||
refresh: Boolean = false,
|
||||
) {
|
||||
|
|
@ -634,11 +646,11 @@ internal class DefaultCurrenciesRepository(
|
|||
)
|
||||
}
|
||||
cacheRegistry.invokeOnExpire(
|
||||
key = getAssetsCacheKey(userWalletId),
|
||||
key = getAssetsCacheKey(userWallet.walletId),
|
||||
skipCache = refresh,
|
||||
block = {
|
||||
coroutineScope {
|
||||
launch { expressServiceLoader.update(getUserWallet(userWalletId), tokens) }
|
||||
launch { expressServiceLoader.update(userWallet, tokens) }
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
@ -648,9 +660,8 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
private suspend fun handleFetchTokensError(userWallet: UserWallet, e: ApiResponseError): UserTokensResponse {
|
||||
val userWalletId = userWallet.walletId
|
||||
val response = appPreferencesStore.getObjectSyncOrNull(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
) ?: createDefaultUserTokensResponse(userWallet)
|
||||
val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId)
|
||||
?: createDefaultUserTokensResponse(userWallet = userWallet)
|
||||
|
||||
if (e is ApiResponseError.HttpException && e.code == ApiResponseError.HttpException.Code.NOT_FOUND) {
|
||||
Timber.w(e, "Requested currencies could not be found in the remote store for: $userWalletId")
|
||||
|
|
@ -666,20 +677,14 @@ internal class DefaultCurrenciesRepository(
|
|||
private fun createDefaultUserTokensResponse(userWallet: UserWallet) =
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyCard(
|
||||
userWallet.requireColdWallet().scanResponse,
|
||||
userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
||||
),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
|
||||
private fun getUserWallet(userWalletId: UserWalletId): UserWallet {
|
||||
return requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) {
|
||||
"Unable to find a user wallet with provided ID: $userWalletId"
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureIsCorrectUserWallet(userWalletId: UserWalletId, isMultiCurrencyWalletExpected: Boolean) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
|
||||
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected)
|
||||
}
|
||||
|
|
@ -708,14 +713,10 @@ internal class DefaultCurrenciesRepository(
|
|||
private fun getTokensCacheKey(userWalletId: UserWalletId): String = "tokens_cache_key_${userWalletId.stringValue}"
|
||||
|
||||
private fun getSavedUserTokensResponse(key: UserWalletId): Flow<UserTokensResponse> {
|
||||
return appPreferencesStore
|
||||
.getObject<UserTokensResponse>(PreferencesKeys.getUserTokensKey(userWalletId = key.stringValue))
|
||||
.filterNotNull()
|
||||
return userTokensResponseStore.get(userWalletId = key).filterNotNull()
|
||||
}
|
||||
|
||||
private suspend fun getSavedUserTokensResponseSync(key: UserWalletId): UserTokensResponse? {
|
||||
return appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(key.stringValue),
|
||||
)
|
||||
return userTokensResponseStore.getSyncOrNull(userWalletId = key)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue