Updated on 2026-08-14
This commit is contained in:
parent
ae4c521813
commit
e56e411930
6 changed files with 75 additions and 76 deletions
|
|
@ -1,48 +1,49 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.domain.common.ThrottlerWithValues
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.math.BigDecimal
|
||||
|
||||
//TODO: refactoring: move to domain
|
||||
class RatesRepository {
|
||||
|
||||
private val tangemTechService: TangemTechService
|
||||
get() = store.state.domainNetworks.tangemTechService
|
||||
|
||||
class RatesRepository(
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) {
|
||||
private val throttler = ThrottlerWithValues<Currency, Result<BigDecimal>?>(60000)
|
||||
|
||||
suspend fun loadFiatRate(currencyId: String, coinsList: List<Currency>): Result<RatesResult> {
|
||||
// get and submit previous result of equivalents.
|
||||
val throttledResult = coinsList.filter { throttler.isStillThrottled(it) }.map {
|
||||
Pair(it, throttler.geValue(it))
|
||||
}
|
||||
|
||||
val currenciesToUpdate = coinsList.filter { !throttler.isStillThrottled(it) }
|
||||
val coinIds = currenciesToUpdate.mapNotNull { it.coinId }.distinct()
|
||||
if (coinIds.isEmpty()) return handleFiatRatesResult(throttledResult.toMap())
|
||||
|
||||
return when (val result = tangemTechService.rates(currencyId, coinIds)) {
|
||||
is Result.Success -> {
|
||||
val ratesResultList: Map<String, Result<BigDecimal>> = result.data.rates.mapValues {
|
||||
Result.Success(it.value.toBigDecimal())
|
||||
}
|
||||
val updatedCurrencies = throttledResult.toMap().toMutableMap()
|
||||
coinsList.forEach { currency ->
|
||||
ratesResultList[currency.coinId]?.let {
|
||||
updatedCurrencies[currency] = it
|
||||
throttler.updateThrottlingTo(currency)
|
||||
throttler.setValue(currency, it)
|
||||
}
|
||||
}
|
||||
handleFiatRatesResult(updatedCurrencies)
|
||||
suspend fun loadFiatRate(currencyId: String, coinsList: List<Currency>): Result<RatesResult> =
|
||||
withContext(dispatchers.io) {
|
||||
// get and submit previous result of equivalents.
|
||||
val throttledResult = coinsList.filter { throttler.isStillThrottled(it) }.map {
|
||||
Pair(it, throttler.geValue(it))
|
||||
}
|
||||
is Result.Failure -> Result.Failure(result.error)
|
||||
|
||||
val currenciesToUpdate = coinsList.filter { !throttler.isStillThrottled(it) }
|
||||
val coinIds = currenciesToUpdate.mapNotNull { it.coinId }.distinct()
|
||||
if (coinIds.isEmpty()) return@withContext handleFiatRatesResult(throttledResult.toMap())
|
||||
|
||||
runCatching { tangemTechApi.getRates(currencyId.lowercase(), coinIds.joinToString(",")) }
|
||||
.onSuccess { response ->
|
||||
val ratesResultList: Map<String, Result<BigDecimal>> = response.rates.mapValues {
|
||||
Result.Success(it.value.toBigDecimal())
|
||||
}
|
||||
val updatedCurrencies = throttledResult.toMap().toMutableMap()
|
||||
coinsList.forEach { currency ->
|
||||
ratesResultList[currency.coinId]?.let {
|
||||
updatedCurrencies[currency] = it
|
||||
throttler.updateThrottlingTo(currency)
|
||||
throttler.setValue(currency, it)
|
||||
}
|
||||
}
|
||||
return@withContext handleFiatRatesResult(updatedCurrencies)
|
||||
}
|
||||
.onFailure { Result.Failure(it) }
|
||||
|
||||
throw IllegalStateException("Unreachable code because runCatching must return result")
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleFiatRatesResult(rates: Map<Currency, Result<BigDecimal>?>): Result.Success<RatesResult> {
|
||||
val success = mutableMapOf<Currency, BigDecimal>()
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import com.tangem.tap.store
|
|||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.tap.userTokensRepository
|
||||
import com.tangem.tap.walletStoresManager
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
|
@ -43,7 +44,14 @@ import timber.log.Timber
|
|||
class TapWalletManager {
|
||||
val walletManagerFactory: WalletManagerFactory
|
||||
by lazy { WalletManagerFactory(blockchainSdkConfig) }
|
||||
val rates: RatesRepository = RatesRepository()
|
||||
|
||||
// TODO("After adding DI") get dependencies by DI
|
||||
val rates: RatesRepository by lazy {
|
||||
RatesRepository(
|
||||
tangemTechApi = store.state.domainNetworks.tangemTechService.api,
|
||||
dispatchers = AppCoroutineDispatcherProvider(),
|
||||
)
|
||||
}
|
||||
|
||||
private val blockchainSdkConfig by lazy {
|
||||
store.state.globalState.configManager?.config?.blockchainSdkConfig ?: BlockchainSdkConfig()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
|
|||
import com.tangem.tap.domain.walletStores.repository.implementation.DefaultWalletAmountsRepository
|
||||
import com.tangem.tap.domain.walletStores.repository.implementation.DefaultWalletManagersRepository
|
||||
import com.tangem.tap.domain.walletStores.repository.implementation.DefaultWalletStoresRepository
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
|
||||
fun WalletStoresRepository.Companion.provideDefaultImplementation(): WalletStoresRepository {
|
||||
return DefaultWalletStoresRepository()
|
||||
|
|
@ -22,5 +23,9 @@ fun WalletManagersRepository.Companion.provideDefaultImplementation(
|
|||
fun WalletAmountsRepository.Companion.provideDefaultImplementation(
|
||||
tangemTechService: TangemTechService,
|
||||
): WalletAmountsRepository {
|
||||
return DefaultWalletAmountsRepository(tangemTechService)
|
||||
// TODO("After adding DI") get dependencies by DI
|
||||
return DefaultWalletAmountsRepository(
|
||||
tangemTechApi = tangemTechService.api,
|
||||
dispatchers = AppCoroutineDispatcherProvider(),
|
||||
)
|
||||
}
|
||||
|
|
@ -14,8 +14,7 @@ import com.tangem.common.flatMap
|
|||
import com.tangem.common.flatMapOnFailure
|
||||
import com.tangem.common.fold
|
||||
import com.tangem.common.map
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
|
|
@ -34,10 +33,12 @@ import com.tangem.tap.domain.walletStores.repository.implementation.utils.update
|
|||
import com.tangem.tap.domain.walletStores.repository.implementation.utils.updateWithUnreachable
|
||||
import com.tangem.tap.domain.walletStores.storage.WalletManagerStorage
|
||||
import com.tangem.tap.domain.walletStores.storage.WalletStoresStorage
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.features.wallet.models.PendingTransactionType
|
||||
import com.tangem.tap.features.wallet.models.filterByCoin
|
||||
import com.tangem.tap.features.wallet.models.getPendingTransactions
|
||||
import com.tangem.tap.network.NetworkConnectivity
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
|
|
@ -47,7 +48,8 @@ import timber.log.Timber
|
|||
import java.math.BigDecimal
|
||||
|
||||
internal class DefaultWalletAmountsRepository(
|
||||
private val tangemTechService: TangemTechService,
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : WalletAmountsRepository {
|
||||
private val walletStoresStorage = WalletStoresStorage
|
||||
private val walletManagersStorage = WalletManagerStorage
|
||||
|
|
@ -119,39 +121,31 @@ internal class DefaultWalletAmountsRepository(
|
|||
|
||||
val coinsIds = currencies.mapNotNull { it.coinId }.distinct().toList()
|
||||
|
||||
val fiatRatesResult = withContext(Dispatchers.IO) {
|
||||
tangemTechService.rates(
|
||||
currency = fiatCurrency.code,
|
||||
ids = coinsIds,
|
||||
)
|
||||
}
|
||||
return withContext(dispatchers.io) {
|
||||
runCatching { tangemTechApi.getRates(fiatCurrency.code.lowercase(), coinsIds.joinToString(",")) }
|
||||
.onSuccess {
|
||||
updateWalletStoresWithFiatRates(walletStores = walletStores, fiatRates = it.rates)
|
||||
return@withContext CompletionResult.Success(Unit)
|
||||
}
|
||||
.onFailure {
|
||||
val error = WalletStoresError.FetchFiatRatesError(
|
||||
currencies = currencies.map(Currency::currencySymbol).toList(),
|
||||
cause = it,
|
||||
)
|
||||
|
||||
return when (fiatRatesResult) {
|
||||
is Result.Success -> {
|
||||
updateWalletStoresWithFiatRates(
|
||||
walletStores = walletStores,
|
||||
fiatRates = fiatRatesResult.data.rates,
|
||||
)
|
||||
|
||||
CompletionResult.Success(Unit)
|
||||
}
|
||||
is Result.Failure -> {
|
||||
val error = WalletStoresError.FetchFiatRatesError(
|
||||
currencies = currencies.map { it.currencySymbol }.toList(),
|
||||
cause = fiatRatesResult.error,
|
||||
)
|
||||
|
||||
Timber.e(
|
||||
error,
|
||||
"""
|
||||
Timber.e(
|
||||
error,
|
||||
"""
|
||||
Unable to fetch fiat rates
|
||||
|- User wallets ids: $walletsIds
|
||||
|- Coins ids: $coinsIds
|
||||
""".trimIndent(),
|
||||
)
|
||||
)
|
||||
|
||||
CompletionResult.Failure(error)
|
||||
}
|
||||
return@withContext CompletionResult.Failure(error)
|
||||
}
|
||||
|
||||
throw IllegalStateException("Unreachable code because runCatching must return result")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ interface TangemTechApi {
|
|||
): CoinsResponse
|
||||
|
||||
@GET("rates")
|
||||
suspend fun rates(
|
||||
suspend fun getRates(
|
||||
@Query("currencyId") currencyId: String,
|
||||
@Query("coinIds") coinIds: String,
|
||||
): RatesResponse
|
||||
|
|
|
|||
|
|
@ -41,15 +41,6 @@ class TangemTechService(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun rates(
|
||||
currency: String,
|
||||
ids: List<String>,
|
||||
): Result<RatesResponse> = withContext(Dispatchers.IO) {
|
||||
performRequest {
|
||||
api.rates(currency.lowercase(), ids.joinToString(","))
|
||||
}
|
||||
}
|
||||
|
||||
fun addHeaderInterceptors(interceptors: List<AddHeaderInterceptor>) {
|
||||
headerInterceptors.removeAll(interceptors)
|
||||
headerInterceptors.addAll(interceptors)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue