diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt index 9a76813cab..28bc7cb1f9 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt @@ -113,6 +113,7 @@ private fun handleOtherCardsAction(action: Action) { } scope.launch { + // TODO: Use new repo [REDACTED_JIRA] userTokensRepository.saveUserTokens( card = result.data.card, tokens = blockchainNetworks.toCurrencies(), diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index b255ab3536..2ab9ded42f 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -135,6 +135,7 @@ private fun handleWalletAction(action: Action) { } scope.launch { + // TODO: Use new repo [REDACTED_JIRA] userTokensRepository.saveUserTokens( card = result.data.card, tokens = blockchainNetworks.toCurrencies(), diff --git a/data/tokens/build.gradle.kts b/data/tokens/build.gradle.kts index 37aab60a23..d36f42d591 100644 --- a/data/tokens/build.gradle.kts +++ b/data/tokens/build.gradle.kts @@ -41,4 +41,5 @@ dependencies { implementation(deps.moshi.kotlin) implementation(deps.jodatime) implementation(deps.timber) + implementation(deps.retrofit) // For HttpException } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 5dda8b7e59..e29095c31d 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import retrofit2.HttpException import timber.log.Timber internal class DefaultCurrenciesRepository( @@ -252,14 +253,19 @@ internal class DefaultCurrenciesRepository( } private suspend fun fetchTokens(userWallet: UserWallet) { - try { - val response = tangemTechApi.getUserTokens(userWallet.walletId.stringValue) + val userWalletId = userWallet.walletId - userTokensStore.store(userWallet.walletId, response) - fetchUserMarketCoinsByIds(userWallet.walletId, response) - } catch (e: Throwable) { - handleFetchTokensErrorOrThrow(userWallet, e) + val response = try { + with(tangemTechApi.getUserTokens(userWalletId.stringValue)) { + // The response may contain repeated tokens + copy(tokens = tokens.distinct()) + } + } catch (e: HttpException) { + handleCurrenciesNotFoundOrThrow(userWallet, e) } + + userTokensStore.store(userWallet.walletId, response) + fetchUserMarketCoinsByIds(userWalletId, response) } private suspend fun storeAndPushTokens(userWalletId: UserWalletId, response: UserTokensResponse) { @@ -269,30 +275,38 @@ internal class DefaultCurrenciesRepository( private suspend fun fetchUserMarketCoinsByIds(userWalletId: UserWalletId, userTokens: UserTokensResponse) { try { - val response = tangemTechApi.getCoins( - networkIds = userTokens.tokens.joinToString(separator = ",") { it.networkId }, - ) + val networkIds = userTokens.tokens.joinToString(separator = ",") { it.networkId } + val response = tangemTechApi.getCoins(networkIds) + userMarketCoinsStore.store(userWalletId, response) } catch (e: Throwable) { - Timber.e("Unable to fetch user market coins for: ${userWalletId.stringValue} ${e.message}") + Timber.e(e, "Unable to fetch user market coins for: ${userWalletId.stringValue}") } } - private suspend fun handleFetchTokensErrorOrThrow(userWallet: UserWallet, error: Throwable) { - val errorMessage = error.message ?: throw error + private suspend fun handleCurrenciesNotFoundOrThrow( + userWallet: UserWallet, + httpException: HttpException, + ): UserTokensResponse { + val userWalletId = userWallet.walletId - if (NOT_FOUND_HTTP_CODE in errorMessage) { - val response = userTokensStore.getSyncOrNull(userWallet.walletId) - ?: userTokensResponseFactory.createUserTokensResponse( - currencies = cardCurrenciesFactory.createDefaultCoinsForMultiCurrencyCard(userWallet.scanResponse), - isGroupedByNetwork = false, - isSortedByBalance = false, - ) - - tangemTechApi.saveUserTokens(userWallet.walletId.stringValue, response) - } else { - Timber.e(error, "Unable to fetch currencies for: ${userWallet.walletId}") + if (httpException.code() != NOT_FOUND_HTTP_CODE) { + Timber.e(httpException, "Unable to fetch currencies for: $userWalletId") + throw httpException } + + Timber.d("Requested currencies could not be found in the remote store for: $userWalletId") + + val response = userTokensStore.getSyncOrNull(userWalletId) + ?: userTokensResponseFactory.createUserTokensResponse( + currencies = cardCurrenciesFactory.createDefaultCoinsForMultiCurrencyCard(userWallet.scanResponse), + isGroupedByNetwork = false, + isSortedByBalance = false, + ) + + tangemTechApi.saveUserTokens(userWalletId.stringValue, response) + + return response } private suspend fun getUserWallet(userWalletId: UserWalletId): UserWallet { @@ -331,6 +345,6 @@ internal class DefaultCurrenciesRepository( private fun getTokensCacheKey(userWalletId: UserWalletId): String = "tokens_cache_key_${userWalletId.stringValue}" private companion object { - const val NOT_FOUND_HTTP_CODE = "404" + const val NOT_FOUND_HTTP_CODE = 404 } } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCryptoCurrenciesFactory.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCryptoCurrenciesFactory.kt index 3a7208bcde..b46fac6953 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCryptoCurrenciesFactory.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/utils/ResponseCryptoCurrenciesFactory.kt @@ -32,7 +32,11 @@ internal class ResponseCryptoCurrenciesFactory(private val demoConfig: DemoConfi } fun createCurrencies(response: UserTokensResponse, scanResponse: ScanResponse): List { - return response.tokens.mapNotNull { createCurrency(it, scanResponse) } + return response.tokens + .asSequence() + .mapNotNull { createCurrency(it, scanResponse) } + .distinctBy { it.id } + .toList() } fun createCurrency(responseToken: UserTokensResponse.Token, scanResponse: ScanResponse): CryptoCurrency? {