Updated on 2026-08-14
This commit is contained in:
parent
eb9b7f0cae
commit
1715bcd79c
11 changed files with 96 additions and 293 deletions
|
|
@ -8,7 +8,6 @@ import com.tangem.datasource.local.network.NetworksStatusesStore
|
|||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.quote.QuotesStore
|
||||
import com.tangem.datasource.local.token.ExpressAssetsStore
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.tokens.repository.*
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
|
|
@ -28,7 +27,7 @@ internal object TokensDataModule {
|
|||
fun provideCurrenciesRepository(
|
||||
tangemTechApi: TangemTechApi,
|
||||
tangemExpressApi: TangemExpressApi,
|
||||
userTokensStore: UserTokensStore,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
expressAssetsStore: ExpressAssetsStore,
|
||||
|
|
@ -38,7 +37,7 @@ internal object TokensDataModule {
|
|||
return DefaultCurrenciesRepository(
|
||||
tangemTechApi = tangemTechApi,
|
||||
tangemExpressApi = tangemExpressApi,
|
||||
userTokensStore = userTokensStore,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
userWalletsStore = userWalletsStore,
|
||||
expressAssetsStore = expressAssetsStore,
|
||||
|
|
@ -71,7 +70,7 @@ internal object TokensDataModule {
|
|||
networksStatusesStore: NetworksStatusesStore,
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
userTokensStore: UserTokensStore,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
cacheRegistry: CacheRegistry,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): NetworksRepository {
|
||||
|
|
@ -79,7 +78,7 @@ internal object TokensDataModule {
|
|||
networksStatusesStore = networksStatusesStore,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
userWalletsStore = userWalletsStore,
|
||||
userTokensStore = userTokensStore,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
cacheRegistry = cacheRegistry,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,12 @@ import com.tangem.datasource.api.express.models.request.AssetsRequestBody
|
|||
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.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.datasource.local.token.ExpressAssetsStore
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.common.util.hasDerivation
|
||||
|
|
@ -46,11 +50,11 @@ import com.tangem.blockchain.common.FeePaidCurrency as FeePaidSdkCurrency
|
|||
internal class DefaultCurrenciesRepository(
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val tangemExpressApi: TangemExpressApi,
|
||||
private val userTokensStore: UserTokensStore,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val expressAssetsStore: ExpressAssetsStore,
|
||||
private val cacheRegistry: CacheRegistry,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : CurrenciesRepository {
|
||||
|
||||
|
|
@ -86,7 +90,7 @@ internal class DefaultCurrenciesRepository(
|
|||
override suspend fun addCurrencies(userWalletId: UserWalletId, currencies: List<CryptoCurrency>) {
|
||||
return withContext(dispatchers.io) {
|
||||
val savedCurrencies = requireNotNull(
|
||||
value = userTokensStore.getSyncOrNull(userWalletId),
|
||||
value = getSavedUserTokensResponseSync(key = userWalletId),
|
||||
lazyMessage = { "Saved tokens empty. Can not perform add currencies action" },
|
||||
)
|
||||
|
||||
|
|
@ -141,7 +145,7 @@ internal class DefaultCurrenciesRepository(
|
|||
override suspend fun removeCurrency(userWalletId: UserWalletId, currency: CryptoCurrency) =
|
||||
withContext(dispatchers.io) {
|
||||
val savedCurrencies = requireNotNull(
|
||||
value = userTokensStore.getSyncOrNull(userWalletId),
|
||||
value = getSavedUserTokensResponseSync(key = userWalletId),
|
||||
lazyMessage = { "Saved tokens empty. Can not perform remove currency action" },
|
||||
)
|
||||
|
||||
|
|
@ -163,7 +167,7 @@ internal class DefaultCurrenciesRepository(
|
|||
override suspend fun removeCurrencies(userWalletId: UserWalletId, currencies: List<CryptoCurrency>) {
|
||||
return withContext(dispatchers.io) {
|
||||
val savedCurrencies = requireNotNull(
|
||||
value = userTokensStore.getSyncOrNull(userWalletId),
|
||||
value = getSavedUserTokensResponseSync(key = userWalletId),
|
||||
lazyMessage = { "Saved tokens empty. Can not perform remove currencies action" },
|
||||
)
|
||||
|
||||
|
|
@ -276,9 +280,12 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
fetchTokensIfCacheExpired(userWallet, refresh)
|
||||
|
||||
val storedTokens = requireNotNull(userTokensStore.getSyncOrNull(userWallet.walletId)) {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
}
|
||||
val storedTokens = requireNotNull(
|
||||
value = getSavedUserTokensResponseSync(key = userWallet.walletId),
|
||||
lazyMessage = {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
},
|
||||
)
|
||||
|
||||
responseCurrenciesFactory.createCurrencies(storedTokens, userWallet.scanResponse)
|
||||
}
|
||||
|
|
@ -290,9 +297,12 @@ internal class DefaultCurrenciesRepository(
|
|||
val userWallet = getUserWallet(userWalletId)
|
||||
ensureIsCorrectUserWallet(userWallet, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
val response = requireNotNull(userTokensStore.getSyncOrNull(userWalletId)) {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
}
|
||||
val response = requireNotNull(
|
||||
value = getSavedUserTokensResponseSync(key = userWalletId),
|
||||
lazyMessage = {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
},
|
||||
)
|
||||
|
||||
responseCurrenciesFactory.createCurrency(
|
||||
currencyId = id,
|
||||
|
|
@ -312,9 +322,12 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
fetchTokensIfCacheExpired(userWallet = userWallet, refresh = false)
|
||||
|
||||
val storedTokens = requireNotNull(userTokensStore.getSyncOrNull(userWallet.walletId)) {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
}
|
||||
val storedTokens = requireNotNull(
|
||||
value = getSavedUserTokensResponseSync(key = userWalletId),
|
||||
lazyMessage = {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
},
|
||||
)
|
||||
val blockchain = Blockchain.fromId(networkId.value)
|
||||
val blockchainNetworkId = blockchain.toNetworkId()
|
||||
val coinId = blockchain.toCoinId()
|
||||
|
|
@ -335,7 +348,7 @@ internal class DefaultCurrenciesRepository(
|
|||
ensureIsCorrectUserWallet(userWalletId, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
launch(dispatchers.io) {
|
||||
userTokensStore.get(userWalletId)
|
||||
getSavedUserTokensResponse(userWalletId)
|
||||
.map { it.group == UserTokensResponse.GroupType.NETWORK }
|
||||
.collect(::send)
|
||||
}
|
||||
|
|
@ -347,7 +360,7 @@ internal class DefaultCurrenciesRepository(
|
|||
ensureIsCorrectUserWallet(userWalletId, isMultiCurrencyWalletExpected = true)
|
||||
|
||||
launch(dispatchers.io) {
|
||||
userTokensStore.get(userWalletId)
|
||||
getSavedUserTokensResponse(userWalletId)
|
||||
.map { it.sort == UserTokensResponse.SortType.BALANCE }
|
||||
.collect(::send)
|
||||
}
|
||||
|
|
@ -461,9 +474,14 @@ internal class DefaultCurrenciesRepository(
|
|||
val userWallet = getUserWallet(userWalletId)
|
||||
fetchTokensIfCacheExpired(userWallet, refresh = false)
|
||||
|
||||
val storedTokens = requireNotNull(userTokensStore.getSyncOrNull(userWallet.walletId)) {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
}
|
||||
val storedTokens = requireNotNull(
|
||||
value = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWallet.walletId.stringValue),
|
||||
),
|
||||
lazyMessage = {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
},
|
||||
)
|
||||
|
||||
return storedTokens.tokens.any {
|
||||
it.contractAddress != null &&
|
||||
|
|
@ -473,7 +491,7 @@ internal class DefaultCurrenciesRepository(
|
|||
}
|
||||
|
||||
private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow<List<CryptoCurrency>> {
|
||||
return userTokensStore.get(userWallet.walletId).map { storedTokens ->
|
||||
return getSavedUserTokensResponse(userWallet.walletId).map { storedTokens ->
|
||||
responseCurrenciesFactory.createCurrencies(
|
||||
response = storedTokens,
|
||||
scanResponse = userWallet.scanResponse,
|
||||
|
|
@ -517,17 +535,26 @@ internal class DefaultCurrenciesRepository(
|
|||
.let { customTokensMerger.mergeIfPresented(userWalletId, response) }
|
||||
.let(userTokensBackwardCompatibility::applyCompatibilityAndGetUpdated)
|
||||
|
||||
userTokensStore.store(userWallet.walletId, compatibleUserTokensResponse)
|
||||
appPreferencesStore.storeObject(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId = userWallet.walletId.stringValue),
|
||||
value = compatibleUserTokensResponse,
|
||||
)
|
||||
|
||||
fetchExchangeableUserMarketCoinsByIds(userWalletId, compatibleUserTokensResponse)
|
||||
}
|
||||
|
||||
private suspend fun checkIsEmptyDemoWallet(userWallet: UserWallet): Boolean {
|
||||
return demoConfig.isDemoCardId(userWallet.cardId) && userTokensStore.getSyncOrNull(userWallet.walletId) == null
|
||||
val response = getSavedUserTokensResponseSync(key = userWallet.walletId)
|
||||
|
||||
return demoConfig.isDemoCardId(userWallet.cardId) && response == null
|
||||
}
|
||||
|
||||
private suspend fun storeAndPushTokens(userWalletId: UserWalletId, response: UserTokensResponse) {
|
||||
val compatibleUserTokensResponse = userTokensBackwardCompatibility.applyCompatibilityAndGetUpdated(response)
|
||||
userTokensStore.store(userWalletId, compatibleUserTokensResponse)
|
||||
appPreferencesStore.storeObject(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId = userWalletId.stringValue),
|
||||
value = compatibleUserTokensResponse,
|
||||
)
|
||||
|
||||
pushTokens(userWalletId, response)
|
||||
}
|
||||
|
|
@ -561,8 +588,9 @@ internal class DefaultCurrenciesRepository(
|
|||
|
||||
private suspend fun handleFetchTokensError(userWallet: UserWallet, e: ApiResponseError): UserTokensResponse {
|
||||
val userWalletId = userWallet.walletId
|
||||
val response = userTokensStore.getSyncOrNull(userWalletId)
|
||||
?: createDefaultUserTokensResponse(userWallet)
|
||||
val response = appPreferencesStore.getObjectSyncOrNull(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
) ?: createDefaultUserTokensResponse(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")
|
||||
|
|
@ -622,4 +650,16 @@ 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()
|
||||
}
|
||||
|
||||
private suspend fun getSavedUserTokensResponseSync(key: UserWalletId): UserTokensResponse? {
|
||||
return appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(key.stringValue),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,8 +8,11 @@ import com.tangem.data.common.cache.CacheRegistry
|
|||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||
import com.tangem.data.tokens.utils.CardCryptoCurrenciesFactory
|
||||
import com.tangem.data.tokens.utils.NetworkStatusFactory
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.network.NetworksStatusesStore
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
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.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.core.lce.LceFlow
|
||||
|
|
@ -33,7 +36,7 @@ internal class DefaultNetworksRepository(
|
|||
private val networksStatusesStore: NetworksStatusesStore,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val userTokensStore: UserTokensStore,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val cacheRegistry: CacheRegistry,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : NetworksRepository {
|
||||
|
|
@ -300,9 +303,14 @@ internal class DefaultNetworksRepository(
|
|||
}
|
||||
|
||||
return if (userWallet.isMultiCurrency) {
|
||||
val response = requireNotNull(userTokensStore.getSyncOrNull(userWalletId)) {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
}
|
||||
val response = requireNotNull(
|
||||
value = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
),
|
||||
lazyMessage = {
|
||||
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
|
||||
},
|
||||
)
|
||||
|
||||
responseCurrenciesFactory.createCurrencies(response, userWallet.scanResponse).asSequence()
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue