From e736f86583fef0dc47217244e755e42f81ee94a8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 30 May 2025 12:29:21 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/datasource/di/QuotesStoreModule.kt | 54 ------ .../local/quote/DefaultQuotesStore.kt | 128 ------------- .../datasource/local/quote/QuotesStore.kt | 24 --- data/quotes/build.gradle.kts | 1 + .../data/quotes/di/QuoteSupplierModule.kt | 19 -- .../tangem/data/quotes/di/QuotesDataModule.kt | 45 ++++- .../tangem/data/tokens/di/TokensDataModule.kt | 21 -- .../repository/DefaultQuotesRepository.kt | 180 ------------------ .../tokens/repository/QuotesRepository.kt | 55 ------ 9 files changed, 42 insertions(+), 485 deletions(-) delete mode 100644 core/datasource/src/main/java/com/tangem/datasource/di/QuotesStoreModule.kt delete mode 100644 core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt delete mode 100644 core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt delete mode 100644 data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt delete mode 100644 domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/QuotesStoreModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/QuotesStoreModule.kt deleted file mode 100644 index 48e2d14670..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/di/QuotesStoreModule.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.tangem.datasource.di - -import android.content.Context -import androidx.datastore.core.DataStore -import androidx.datastore.core.DataStoreFactory -import androidx.datastore.dataStoreFile -import com.squareup.moshi.Moshi -import com.tangem.datasource.api.tangemTech.models.QuotesResponse -import com.tangem.datasource.local.datastore.RuntimeSharedStore -import com.tangem.datasource.local.quote.DefaultQuotesStore -import com.tangem.datasource.local.quote.QuotesStore -import com.tangem.datasource.utils.MoshiDataStoreSerializer -import com.tangem.datasource.utils.mapWithStringKeyTypes -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal object QuotesStoreModule { - - @Provides - @Singleton - fun providePersistenceQuotesStore( - @NetworkMoshi moshi: Moshi, - @ApplicationContext context: Context, - dispatchers: CoroutineDispatcherProvider, - ): DataStore> { - return DataStoreFactory.create( - serializer = MoshiDataStoreSerializer( - moshi = moshi, - types = mapWithStringKeyTypes(), - defaultValue = emptyMap(), - ), - produceFile = { context.dataStoreFile(fileName = "quotes") }, - scope = CoroutineScope(context = dispatchers.io + SupervisorJob()), - ) - } - - @Provides - @Singleton - fun provideQuotesStore(persistenceStore: DataStore>): QuotesStore { - return DefaultQuotesStore( - persistenceStore = persistenceStore, - runtimeStore = RuntimeSharedStore(), - ) - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt deleted file mode 100644 index 6723892d8a..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt +++ /dev/null @@ -1,128 +0,0 @@ -package com.tangem.datasource.local.quote - -import androidx.datastore.core.DataStore -import com.tangem.datasource.api.tangemTech.models.QuotesResponse -import com.tangem.datasource.local.datastore.RuntimeSharedStore -import com.tangem.datasource.local.quote.converter.QuoteConverter -import com.tangem.domain.models.StatusSource -import com.tangem.domain.models.currency.CryptoCurrency -import com.tangem.domain.tokens.model.Quote -import com.tangem.utils.extensions.addOrReplace -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch - -internal typealias QuotesByCurrencyId = Map - -/** - * Default implementation of [QuotesStore] - * - * @property persistenceStore persistence quotes store - * @property runtimeStore runtime quotes store - */ -internal class DefaultQuotesStore( - private val persistenceStore: DataStore, - private val runtimeStore: RuntimeSharedStore>, -) : QuotesStore { - - override fun get(currenciesIds: Set): Flow> = channelFlow { - val cachedQuotes = getCachedQuotes(currenciesIds = currenciesIds) - - if (cachedQuotes.isNotEmpty()) { - send(cachedQuotes) - } - - runtimeStore.get() - .onEach { - val mergedQuotes = mergeQuotes( - currenciesIds = currenciesIds, - cachedQuotes = cachedQuotes, - runtimeQuotes = it, - ) - - send(element = mergedQuotes) - } - .launchIn(scope = this) - } - - override suspend fun getSync(currenciesIds: Set): Set { - val runtimeQuotes = runtimeStore.getSyncOrNull() - val cachedQuotes = getCachedQuotes(currenciesIds = currenciesIds) - - if (runtimeQuotes.isNullOrEmpty() && cachedQuotes.isEmpty()) return emptySet() - - return mergeQuotes( - currenciesIds = currenciesIds, - cachedQuotes = cachedQuotes, - runtimeQuotes = runtimeQuotes.orEmpty(), - ) - } - - override suspend fun store(response: QuotesResponse) { - coroutineScope { - launch { - storeInRuntimeStore( - values = QuoteConverter(isCached = false).convertSet(input = response.quotes.entries), - ) - } - launch { storeInPersistenceStore(response = response) } - } - } - - override suspend fun storeEmptyQuotes(currenciesIds: Set) { - storeInRuntimeStore(values = currenciesIds.map(Quote::Empty).toSet()) - } - - override suspend fun refresh(currenciesIds: Set) { - val currentStatuses = getSync(currenciesIds) - - storeInRuntimeStore( - values = currentStatuses.mapTo(hashSetOf()) { quote -> - when (quote) { - is Quote.Empty -> quote - is Quote.Value -> quote.copy(source = StatusSource.CACHE) - } - }, - ) - } - - private suspend fun getCachedQuotes(currenciesIds: Set): Set { - val ids = currenciesIds.map(CryptoCurrency.RawID::value).toSet() - val cachedQuotes = persistenceStore.data.firstOrNull().orEmpty().filterKeys { it in ids } - - return QuoteConverter(isCached = true).convertSet(input = cachedQuotes.entries) - } - - private fun mergeQuotes( - currenciesIds: Set, - cachedQuotes: Set, - runtimeQuotes: Set, - ): Set { - return currenciesIds - .mapTo(hashSetOf()) { currencyId -> - val runtimeQuote = runtimeQuotes.firstOrNull { it.rawCurrencyId == currencyId } - - if (runtimeQuote == null || runtimeQuote is Quote.Empty) { - getCachedQuoteIfPossible(cachedStatuses = cachedQuotes, currencyId = currencyId) - } else { - runtimeQuote - } - } - } - - private fun getCachedQuoteIfPossible(cachedStatuses: Set, currencyId: CryptoCurrency.RawID): Quote { - return cachedStatuses.firstOrNull { it.rawCurrencyId == currencyId } - ?.copy(source = StatusSource.ONLY_CACHE) - ?: Quote.Empty(currencyId) - } - - private suspend fun storeInRuntimeStore(values: Set) { - runtimeStore.update(default = emptySet()) { saved -> - saved.addOrReplace(items = values) { prev, new -> prev.rawCurrencyId == new.rawCurrencyId } - } - } - - private suspend fun storeInPersistenceStore(response: QuotesResponse) { - persistenceStore.updateData { storedQuotes -> storedQuotes + response.quotes } - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt deleted file mode 100644 index 3534651b8d..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.datasource.local.quote - -import com.tangem.datasource.api.tangemTech.models.QuotesResponse -import com.tangem.domain.models.currency.CryptoCurrency -import com.tangem.domain.tokens.model.Quote -import kotlinx.coroutines.flow.Flow - -/** Quotes store */ -interface QuotesStore { - - /** Get flow of quotes for [currenciesIds] */ - fun get(currenciesIds: Set): Flow> - - /** Get quotes for [currenciesIds] synchronously */ - suspend fun getSync(currenciesIds: Set): Set - - /** Store [response] from remote */ - suspend fun store(response: QuotesResponse) - - /** Store [Quote.Empty] for [currenciesIds] */ - suspend fun storeEmptyQuotes(currenciesIds: Set) - - suspend fun refresh(currenciesIds: Set) -} \ No newline at end of file diff --git a/data/quotes/build.gradle.kts b/data/quotes/build.gradle.kts index 9005f39528..368d9b3bef 100644 --- a/data/quotes/build.gradle.kts +++ b/data/quotes/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { implementation(projects.domain.wallets.models) implementation(deps.androidx.datastore) + implementation(deps.moshi.kotlin) implementation(deps.timber) implementation(deps.hilt.android) diff --git a/data/quotes/src/main/java/com/tangem/data/quotes/di/QuoteSupplierModule.kt b/data/quotes/src/main/java/com/tangem/data/quotes/di/QuoteSupplierModule.kt index af8188e5bc..c31b91a7c7 100644 --- a/data/quotes/src/main/java/com/tangem/data/quotes/di/QuoteSupplierModule.kt +++ b/data/quotes/src/main/java/com/tangem/data/quotes/di/QuoteSupplierModule.kt @@ -1,13 +1,7 @@ package com.tangem.data.quotes.di -import androidx.datastore.core.DataStore -import com.tangem.data.quotes.store.CurrencyIdWithQuote -import com.tangem.data.quotes.store.DefaultQuotesStoreV2 -import com.tangem.data.quotes.store.QuotesStoreV2 -import com.tangem.datasource.local.datastore.RuntimeSharedStore import com.tangem.domain.quotes.single.SingleQuoteProducer import com.tangem.domain.quotes.single.SingleQuoteSupplier -import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -18,19 +12,6 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) internal object QuoteSupplierModule { - @Provides - @Singleton - fun provideQuotesStoreV2( - persistenceQuotesStore: DataStore, - dispatchers: CoroutineDispatcherProvider, - ): QuotesStoreV2 { - return DefaultQuotesStoreV2( - runtimeStore = RuntimeSharedStore(), - persistenceDataStore = persistenceQuotesStore, - dispatchers = dispatchers, - ) - } - @Provides @Singleton fun provideSingleQuoteSupplier(factory: SingleQuoteProducer.Factory): SingleQuoteSupplier { diff --git a/data/quotes/src/main/java/com/tangem/data/quotes/di/QuotesDataModule.kt b/data/quotes/src/main/java/com/tangem/data/quotes/di/QuotesDataModule.kt index e3c96931a8..58803a1a56 100644 --- a/data/quotes/src/main/java/com/tangem/data/quotes/di/QuotesDataModule.kt +++ b/data/quotes/src/main/java/com/tangem/data/quotes/di/QuotesDataModule.kt @@ -1,18 +1,55 @@ package com.tangem.data.quotes.di +import android.content.Context +import androidx.datastore.core.DataStoreFactory +import androidx.datastore.dataStoreFile +import com.squareup.moshi.Moshi import com.tangem.data.quotes.DefaultQuotesRepositoryV2 +import com.tangem.data.quotes.store.DefaultQuotesStoreV2 +import com.tangem.data.quotes.store.QuotesStoreV2 +import com.tangem.datasource.api.tangemTech.models.QuotesResponse +import com.tangem.datasource.di.NetworkMoshi +import com.tangem.datasource.local.datastore.RuntimeSharedStore +import com.tangem.datasource.utils.MoshiDataStoreSerializer +import com.tangem.datasource.utils.mapWithStringKeyTypes import com.tangem.domain.quotes.QuotesRepositoryV2 -import dagger.Binds +import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module +import dagger.Provides import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -internal interface QuotesDataModule { +internal object QuotesDataModule { - @Binds @Singleton - fun bindQuotesRepositoryV2(impl: DefaultQuotesRepositoryV2): QuotesRepositoryV2 + @Provides + fun provideQuotesStoreV2( + @NetworkMoshi moshi: Moshi, + @ApplicationContext context: Context, + dispatchers: CoroutineDispatcherProvider, + ): QuotesStoreV2 { + return DefaultQuotesStoreV2( + runtimeStore = RuntimeSharedStore(), + persistenceDataStore = DataStoreFactory.create( + serializer = MoshiDataStoreSerializer( + moshi = moshi, + types = mapWithStringKeyTypes(), + defaultValue = emptyMap(), + ), + produceFile = { context.dataStoreFile(fileName = "quotes") }, + scope = CoroutineScope(context = dispatchers.io + SupervisorJob()), + ), + dispatchers = dispatchers, + ) + } + + @Singleton + @Provides + fun providesQuotesRepositoryV2(impl: DefaultQuotesRepositoryV2): QuotesRepositoryV2 = impl } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt index 7abad62119..eece90d80a 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt @@ -7,16 +7,13 @@ import com.tangem.data.common.currency.UserTokensSaver import com.tangem.data.tokens.repository.DefaultCurrenciesRepository import com.tangem.data.tokens.repository.DefaultCurrencyChecksRepository import com.tangem.data.tokens.repository.DefaultPolkadotAccountHealthCheckRepository -import com.tangem.data.tokens.repository.DefaultQuotesRepository 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.quote.QuotesStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.CurrencyChecksRepository import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository -import com.tangem.domain.tokens.repository.QuotesRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module @@ -57,24 +54,6 @@ internal object TokensDataModule { ) } - @Provides - @Singleton - fun provideQuotesRepository( - tangemTechApi: TangemTechApi, - appPreferencesStore: AppPreferencesStore, - quotesStore: QuotesStore, - cacheRegistry: CacheRegistry, - dispatchers: CoroutineDispatcherProvider, - ): QuotesRepository { - return DefaultQuotesRepository( - tangemTechApi = tangemTechApi, - appPreferencesStore = appPreferencesStore, - quotesStore = quotesStore, - cacheRegistry = cacheRegistry, - dispatchers = dispatchers, - ) - } - @Provides @Singleton fun provideCurrencyChecksRepository( diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt deleted file mode 100644 index 31852a60bf..0000000000 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt +++ /dev/null @@ -1,180 +0,0 @@ -package com.tangem.data.tokens.repository - -import com.tangem.data.common.api.safeApiCallWithTimeout -import com.tangem.data.common.cache.CacheRegistry -import com.tangem.data.tokens.utils.QuotesUnsupportedCurrenciesIdAdapter -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse -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.quote.QuotesStore -import com.tangem.domain.models.currency.CryptoCurrency -import com.tangem.domain.tokens.model.Quote -import com.tangem.domain.tokens.repository.QuotesRepository -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext -import timber.log.Timber - -internal class DefaultQuotesRepository( - private val tangemTechApi: TangemTechApi, - private val appPreferencesStore: AppPreferencesStore, - private val quotesStore: QuotesStore, - private val cacheRegistry: CacheRegistry, - private val dispatchers: CoroutineDispatcherProvider, -) : QuotesRepository { - - private val quotesUnsupportedCurrenciesAdapter = QuotesUnsupportedCurrenciesIdAdapter() - - @Volatile - private var quotesFetchedForAppCurrency: String? = null - private val mutex = Mutex() - - @OptIn(ExperimentalCoroutinesApi::class) - override fun getQuotesUpdates(currenciesIds: Set): Flow> { - return appPreferencesStore.getObject( - key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY, - ) - .distinctUntilChanged() - .filterNotNull() - .flatMapLatest { appCurrency -> - fetchExpiredQuotes( - currenciesIds = currenciesIds, - appCurrencyId = appCurrency.id, - refresh = false, - ) - - quotesStore.get(currenciesIds) - } - .flowOn(dispatchers.io) - } - - override suspend fun fetchQuotes(currenciesIds: Set, refresh: Boolean) { - withContext(dispatchers.io) { - val selectedAppCurrency = requireNotNull( - value = appPreferencesStore.getObjectSyncOrNull( - key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY, - ), - lazyMessage = { "Unable to get selected application currency to update quotes" }, - ) - - fetchExpiredQuotes(currenciesIds, selectedAppCurrency.id, refresh) - } - } - - @OptIn(ExperimentalCoroutinesApi::class) - override fun getQuotesUpdatesLegacy(currenciesIds: Set, refresh: Boolean): Flow> { - return appPreferencesStore.getObject( - key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY, - ) - .distinctUntilChanged() - .filterNotNull() - .flatMapLatest { appCurrency -> - fetchExpiredQuotes(currenciesIds, appCurrency.id, refresh = refresh) - quotesStore.get(currenciesIds) - } - .cancellable() - .flowOn(dispatchers.io) - } - - override suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set { - return withContext(dispatchers.io) { - val selectedAppCurrency = requireNotNull( - value = appPreferencesStore.getObjectSyncOrNull( - key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY, - ), - lazyMessage = { "Unable to get selected application currency to update quotes" }, - ) - - fetchExpiredQuotes(currenciesIds, selectedAppCurrency.id, refresh) - - quotesStore.getSync(currenciesIds) - } - } - - override suspend fun getQuoteSync(currencyId: CryptoCurrency.RawID): Quote? { - return withContext(dispatchers.io) { - val setOfCurrencyId = setOf(currencyId) - - quotesStore.getSync(setOfCurrencyId).firstOrNull() - } - } - - private suspend fun fetchExpiredQuotes( - currenciesIds: Set, - appCurrencyId: String, - refresh: Boolean, - ) { - // TODO("[REDACTED_JIRA]") need refactor working with quotesFetchedForAppCurrency, - // it changes after filterExpiredCurrenciesIds - // calls with different coroutines and lead to fetchQuotes - mutex.withLock { - if (refresh) { - quotesStore.refresh(currenciesIds) - } - - val expiredCurrenciesIds = filterExpiredCurrenciesIds( - currenciesIds = currenciesIds, - appCurrencyId = appCurrencyId, - refresh = refresh || quotesFetchedForAppCurrency != appCurrencyId, - ) - if (expiredCurrenciesIds.isEmpty()) return - - quotesFetchedForAppCurrency = appCurrencyId - - fetchQuotes(expiredCurrenciesIds, appCurrencyId) - } - } - - private suspend fun fetchQuotes(rawCurrenciesIds: Set, appCurrencyId: String) { - val replacementIdsResult = quotesUnsupportedCurrenciesAdapter.replaceUnsupportedCurrencies( - rawCurrenciesIds.map { it.value }.toSet(), - ) - - safeApiCallWithTimeout( - call = { - val coinIds = replacementIdsResult.idsForRequest.joinToString(separator = ",") - val response = tangemTechApi.getQuotes(appCurrencyId, coinIds).bind() - - val updatedResponse = quotesUnsupportedCurrenciesAdapter.getResponseWithUnsupportedCurrencies( - response = response, - filteredIds = replacementIdsResult.idsFiltered, - ) - - quotesStore.store(updatedResponse) - }, - onError = { error -> - Timber.e(error) - - cacheRegistry.invalidate(rawCurrenciesIds.map { getQuoteCacheKey(it, appCurrencyId) }) - quotesStore.storeEmptyQuotes(currenciesIds = rawCurrenciesIds) - }, - ) - } - - private suspend fun filterExpiredCurrenciesIds( - currenciesIds: Set, - appCurrencyId: String, - refresh: Boolean, - ): Set { - return currenciesIds.fold(hashSetOf()) { acc, currencyId -> - if (currencyId !in acc) { - cacheRegistry.invokeOnExpire( - key = getQuoteCacheKey(currencyId, appCurrencyId), - skipCache = refresh, - block = { acc.add(currencyId) }, - ) - } - acc - } - } - - private fun getQuoteCacheKey(rawCurrencyId: CryptoCurrency.RawID, appCurrencyId: String): String { - return "quote_${rawCurrencyId.value}_$appCurrencyId" - } -} \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt deleted file mode 100644 index 139e433b01..0000000000 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/QuotesRepository.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.tangem.domain.tokens.repository - -import com.tangem.domain.models.currency.CryptoCurrency -import com.tangem.domain.tokens.model.Quote -import kotlinx.coroutines.flow.Flow - -/** - * Repository for everything related to the quotes of tokens - * */ -interface QuotesRepository { - - /** - * Retrieves updates of quotes for a set of specified cryptocurrencies, - * identified by their unique IDs from the local cache. - * - * To fetch and populate the cache with quotes, use [fetchQuotes]. - * - * @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved. - * @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies. - */ - fun getQuotesUpdates(currenciesIds: Set): Flow> - - /** - * Fetches quotes for a set of specified cryptocurrencies, identified by their unique IDs. - * - * Fetched quotes are stored in the local cache and can be retrieved by calling [getQuotesUpdates]. - * - * @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved. - * @param refresh A boolean flag indicating whether the data should be refreshed. - * */ - suspend fun fetchQuotes(currenciesIds: Set, refresh: Boolean = false) - - /** - * Retrieves updates of quotes for a set of specified cryptocurrencies, identified by their unique IDs. - * - * Loads remote quotes if they have expired or if [refresh] is `true`. - * - * @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved. - * @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies. - */ - fun getQuotesUpdatesLegacy(currenciesIds: Set, refresh: Boolean = false): Flow> - - /** - * Retrieves quotes for a set of specified cryptocurrencies, identified by their unique IDs. - * - * Loads remote quotes if they have expired or if [refresh] is `true`. - * - * @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved. - * @param refresh A boolean flag indicating whether the data should be refreshed. - * @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies. - */ - suspend fun getQuotesSync(currenciesIds: Set, refresh: Boolean): Set - - suspend fun getQuoteSync(currencyId: CryptoCurrency.RawID): Quote? -} \ No newline at end of file