Updated on 2026-08-14
This commit is contained in:
parent
66efd406cc
commit
90fea21f17
14 changed files with 103 additions and 398 deletions
|
|
@ -1,11 +1,11 @@
|
||||||
package com.tangem.tap.di.domain
|
package com.tangem.tap.di.domain
|
||||||
|
|
||||||
|
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
||||||
import com.tangem.domain.nft.*
|
import com.tangem.domain.nft.*
|
||||||
import com.tangem.domain.nft.repository.NFTRepository
|
import com.tangem.domain.nft.repository.NFTRepository
|
||||||
import com.tangem.domain.quotes.single.SingleQuoteFetcher
|
import com.tangem.domain.quotes.single.SingleQuoteFetcher
|
||||||
import com.tangem.domain.quotes.single.SingleQuoteSupplier
|
import com.tangem.domain.quotes.single.SingleQuoteSupplier
|
||||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
|
@ -74,10 +74,11 @@ internal object NFTDomainModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun providesGetNFTNetworkStatusUseCase(networksRepository: NetworksRepository): GetNFTNetworkStatusUseCase =
|
fun providesGetNFTNetworkStatusUseCase(
|
||||||
GetNFTNetworkStatusUseCase(
|
singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
|
||||||
networksRepository = networksRepository,
|
): GetNFTNetworkStatusUseCase {
|
||||||
)
|
return GetNFTNetworkStatusUseCase(singleNetworkStatusSupplier = singleNetworkStatusSupplier)
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.domain.exchange.RampStateManager
|
import com.tangem.domain.exchange.RampStateManager
|
||||||
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
||||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||||
|
import com.tangem.domain.networks.repository.NetworksRepository
|
||||||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||||
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
||||||
import com.tangem.domain.promo.PromoRepository
|
import com.tangem.domain.promo.PromoRepository
|
||||||
|
|
@ -18,7 +19,10 @@ import com.tangem.domain.tokens.*
|
||||||
import com.tangem.domain.tokens.operations.BaseCurrenciesStatusesOperations
|
import com.tangem.domain.tokens.operations.BaseCurrenciesStatusesOperations
|
||||||
import com.tangem.domain.tokens.operations.BaseCurrencyStatusOperations
|
import com.tangem.domain.tokens.operations.BaseCurrencyStatusOperations
|
||||||
import com.tangem.domain.tokens.operations.CachedCurrenciesStatusesOperations
|
import com.tangem.domain.tokens.operations.CachedCurrenciesStatusesOperations
|
||||||
import com.tangem.domain.tokens.repository.*
|
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.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.tap.domain.tokens.DefaultTokensFeatureToggles
|
import com.tangem.tap.domain.tokens.DefaultTokensFeatureToggles
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.tangem.data.networks.di
|
||||||
|
|
||||||
|
import androidx.datastore.core.DataStore
|
||||||
|
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||||
|
import com.tangem.data.networks.repository.DefaultNetworksRepository
|
||||||
|
import com.tangem.data.networks.store.DefaultNetworksStatusesStoreV2
|
||||||
|
import com.tangem.data.networks.store.NetworksStatusesStoreV2
|
||||||
|
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||||
|
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||||
|
import com.tangem.domain.networks.repository.NetworksRepository
|
||||||
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal object NetworkDataModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideNetworksStatusesStoreV2(
|
||||||
|
persistenceNetworksStatusesStore: DataStore<Map<String, Set<NetworkStatusDM>>>,
|
||||||
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
|
): NetworksStatusesStoreV2 {
|
||||||
|
return DefaultNetworksStatusesStoreV2(
|
||||||
|
runtimeStore = RuntimeSharedStore(),
|
||||||
|
persistenceDataStore = persistenceNetworksStatusesStore,
|
||||||
|
dispatchers = dispatchers,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideNetworkRepository(
|
||||||
|
cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
||||||
|
walletManagersFacade: WalletManagersFacade,
|
||||||
|
networksStatusesStoreV2: NetworksStatusesStoreV2,
|
||||||
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
|
): NetworksRepository {
|
||||||
|
return DefaultNetworksRepository(
|
||||||
|
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||||
|
walletManagersFacade = walletManagersFacade,
|
||||||
|
networksStatusesStore = networksStatusesStoreV2,
|
||||||
|
dispatchers = dispatchers,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,15 +1,9 @@
|
||||||
package com.tangem.data.networks.di
|
package com.tangem.data.networks.di
|
||||||
|
|
||||||
import androidx.datastore.core.DataStore
|
|
||||||
import com.tangem.data.networks.store.DefaultNetworksStatusesStoreV2
|
|
||||||
import com.tangem.data.networks.store.NetworksStatusesStoreV2
|
|
||||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
|
||||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
|
||||||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||||
import com.tangem.domain.networks.single.SingleNetworkStatusProducer
|
import com.tangem.domain.networks.single.SingleNetworkStatusProducer
|
||||||
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|
@ -20,19 +14,6 @@ import javax.inject.Singleton
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
internal object NetworkStatusSupplierModule {
|
internal object NetworkStatusSupplierModule {
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
fun provideNetworksStatusesStoreV2(
|
|
||||||
persistenceNetworksStatusesStore: DataStore<Map<String, Set<NetworkStatusDM>>>,
|
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
|
||||||
): NetworksStatusesStoreV2 {
|
|
||||||
return DefaultNetworksStatusesStoreV2(
|
|
||||||
runtimeStore = RuntimeSharedStore(),
|
|
||||||
persistenceDataStore = persistenceNetworksStatusesStore,
|
|
||||||
dispatchers = dispatchers,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideSingleNetworkStatusSupplier(factory: SingleNetworkStatusProducer.Factory): SingleNetworkStatusSupplier {
|
fun provideSingleNetworkStatusSupplier(factory: SingleNetworkStatusProducer.Factory): SingleNetworkStatusSupplier {
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,19 @@ package com.tangem.data.tokens.di
|
||||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||||
import com.tangem.data.common.cache.CacheRegistry
|
import com.tangem.data.common.cache.CacheRegistry
|
||||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||||
import com.tangem.data.tokens.repository.*
|
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.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
import com.tangem.datasource.exchangeservice.swap.ExpressServiceLoader
|
||||||
import com.tangem.datasource.local.network.NetworksStatusesStore
|
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.quote.QuotesStore
|
import com.tangem.datasource.local.quote.QuotesStore
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.domain.tokens.repository.*
|
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.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
|
@ -67,30 +72,6 @@ internal object TokensDataModule {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
fun provideNetworksRepository(
|
|
||||||
networksStatusesStore: NetworksStatusesStore,
|
|
||||||
walletManagersFacade: WalletManagersFacade,
|
|
||||||
userWalletsStore: UserWalletsStore,
|
|
||||||
appPreferencesStore: AppPreferencesStore,
|
|
||||||
cacheRegistry: CacheRegistry,
|
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
|
||||||
excludedBlockchains: ExcludedBlockchains,
|
|
||||||
cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
|
||||||
): NetworksRepository {
|
|
||||||
return DefaultNetworksRepository(
|
|
||||||
networksStatusesStore = networksStatusesStore,
|
|
||||||
walletManagersFacade = walletManagersFacade,
|
|
||||||
userWalletsStore = userWalletsStore,
|
|
||||||
appPreferencesStore = appPreferencesStore,
|
|
||||||
cacheRegistry = cacheRegistry,
|
|
||||||
dispatchers = dispatchers,
|
|
||||||
excludedBlockchains = excludedBlockchains,
|
|
||||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideCurrencyChecksRepository(
|
fun provideCurrencyChecksRepository(
|
||||||
|
|
|
||||||
|
|
@ -1,260 +0,0 @@
|
||||||
package com.tangem.data.tokens.repository
|
|
||||||
|
|
||||||
import com.tangem.blockchain.common.address.AddressType
|
|
||||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
|
||||||
import com.tangem.data.common.cache.CacheRegistry
|
|
||||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
|
||||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
|
||||||
import com.tangem.data.networks.utils.NetworkStatusFactory
|
|
||||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
|
||||||
import com.tangem.datasource.local.network.NetworksStatusesStore
|
|
||||||
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.tokens.model.CryptoCurrency
|
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
|
||||||
import com.tangem.domain.tokens.model.Network
|
|
||||||
import com.tangem.domain.tokens.model.NetworkStatus
|
|
||||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
|
||||||
import com.tangem.domain.walletmanager.model.UpdateWalletManagerResult
|
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|
||||||
import kotlinx.coroutines.*
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
||||||
import kotlinx.coroutines.flow.flowOn
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
|
||||||
internal class DefaultNetworksRepository(
|
|
||||||
private val networksStatusesStore: NetworksStatusesStore,
|
|
||||||
private val walletManagersFacade: WalletManagersFacade,
|
|
||||||
private val userWalletsStore: UserWalletsStore,
|
|
||||||
private val appPreferencesStore: AppPreferencesStore,
|
|
||||||
private val cacheRegistry: CacheRegistry,
|
|
||||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
|
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
|
||||||
excludedBlockchains: ExcludedBlockchains,
|
|
||||||
) : NetworksRepository {
|
|
||||||
|
|
||||||
private val responseCurrenciesFactory = ResponseCryptoCurrenciesFactory(excludedBlockchains)
|
|
||||||
|
|
||||||
override fun getNetworkStatusesUpdates(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
networks: Set<Network>,
|
|
||||||
): Flow<Set<NetworkStatus>> {
|
|
||||||
return networksStatusesStore.get(userWalletId, networks)
|
|
||||||
.distinctUntilChanged()
|
|
||||||
.flowOn(dispatchers.io)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun fetchNetworkStatuses(userWalletId: UserWalletId, networks: Set<Network>, refresh: Boolean) {
|
|
||||||
withContext(dispatchers.io) {
|
|
||||||
fetchNetworksStatusesIfCacheExpired(userWalletId, networks, refresh)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun fetchNetworkPendingTransactions(userWalletId: UserWalletId, networks: Set<Network>) {
|
|
||||||
val currencies = getCurrencies(userWalletId, networks)
|
|
||||||
withContext(dispatchers.io) {
|
|
||||||
fetchNetworksPendingTransactions(userWalletId, networks, currencies)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getNetworkStatusesSync(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
networks: Set<Network>,
|
|
||||||
refresh: Boolean,
|
|
||||||
): Set<NetworkStatus> = withContext(dispatchers.io) {
|
|
||||||
fetchNetworksStatusesIfCacheExpired(userWalletId, networks, refresh)
|
|
||||||
networksStatusesStore.getSyncOrNull(userWalletId).orEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getNetworkAddresses(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
network: Network,
|
|
||||||
): List<CryptoCurrencyAddress> = withContext(dispatchers.io) {
|
|
||||||
// Get list of currencies matching [network]
|
|
||||||
val currencies = getCurrencies(userWalletId)
|
|
||||||
.filter { currency -> network.id == currency.network.id }
|
|
||||||
|
|
||||||
// There is no currencies matching given [networks] in [userWalletId]
|
|
||||||
if (currencies.toList().isEmpty()) return@withContext emptyList()
|
|
||||||
|
|
||||||
currencies.toList().map { currency ->
|
|
||||||
CryptoCurrencyAddress(
|
|
||||||
cryptoCurrency = currency,
|
|
||||||
address = walletManagersFacade.getAddresses(userWalletId, currency.network)
|
|
||||||
.firstOrNull { it.type == AddressType.Default }
|
|
||||||
?.value.orEmpty(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun fetchNetworksStatusesIfCacheExpired(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
networks: Set<Network>,
|
|
||||||
refresh: Boolean,
|
|
||||||
) = coroutineScope {
|
|
||||||
if (refresh) {
|
|
||||||
networksStatusesStore.refresh(key = userWalletId, networks = networks)
|
|
||||||
}
|
|
||||||
|
|
||||||
val currencies = getCurrencies(userWalletId, networks)
|
|
||||||
val networksDeferred = networks.mapNotNull { network ->
|
|
||||||
coroutineScope {
|
|
||||||
val key = getNetworksStatusesCacheKey(userWalletId, network)
|
|
||||||
|
|
||||||
if (refresh || cacheRegistry.isExpired(key)) {
|
|
||||||
async {
|
|
||||||
cacheRegistry.invokeOnExpire(
|
|
||||||
key = key,
|
|
||||||
skipCache = refresh,
|
|
||||||
block = { fetchNetworkStatus(userWalletId, network, currencies) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
networksDeferred.awaitAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun fetchNetworksPendingTransactions(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
networks: Set<Network>,
|
|
||||||
currencies: Sequence<CryptoCurrency>,
|
|
||||||
) {
|
|
||||||
coroutineScope {
|
|
||||||
networks
|
|
||||||
.map { network ->
|
|
||||||
async {
|
|
||||||
fetchNetworkPendingTransactions(userWalletId, network, currencies)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.awaitAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun fetchNetworkStatus(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
network: Network,
|
|
||||||
currencies: Sequence<CryptoCurrency>,
|
|
||||||
) {
|
|
||||||
val networkCurrencies = currencies.filter { it.network == network }
|
|
||||||
|
|
||||||
val result = walletManagersFacade.update(
|
|
||||||
userWalletId = userWalletId,
|
|
||||||
network = network,
|
|
||||||
extraTokens = networkCurrencies
|
|
||||||
.filterIsInstance<CryptoCurrency.Token>()
|
|
||||||
.toSet(),
|
|
||||||
)
|
|
||||||
|
|
||||||
withContext(NonCancellable) {
|
|
||||||
invalidateCacheKeyIfNeeded(userWalletId, network, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
val networkStatus = NetworkStatusFactory.create(
|
|
||||||
network = network,
|
|
||||||
updatingResult = result,
|
|
||||||
addedCurrencies = networkCurrencies.toSet(),
|
|
||||||
)
|
|
||||||
|
|
||||||
networksStatusesStore.store(userWalletId, networkStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun fetchNetworkPendingTransactions(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
network: Network,
|
|
||||||
currencies: Sequence<CryptoCurrency>,
|
|
||||||
) {
|
|
||||||
val result = walletManagersFacade.updatePendingTransactions(
|
|
||||||
userWalletId = userWalletId,
|
|
||||||
network = network,
|
|
||||||
)
|
|
||||||
|
|
||||||
withContext(NonCancellable) {
|
|
||||||
invalidateCacheKeyIfNeeded(userWalletId, network, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
val networkStatus = NetworkStatusFactory.create(
|
|
||||||
network = network,
|
|
||||||
updatingResult = result,
|
|
||||||
addedCurrencies = currencies.toSet(),
|
|
||||||
)
|
|
||||||
|
|
||||||
networksStatusesStore.store(userWalletId, networkStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun getCurrencies(userWalletId: UserWalletId, networks: Set<Network>): Sequence<CryptoCurrency> {
|
|
||||||
val currencies = getCurrencies(userWalletId)
|
|
||||||
return currencies.filter { it.network in networks }
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun getCurrencies(userWalletId: UserWalletId): Sequence<CryptoCurrency> {
|
|
||||||
val userWallet = requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) {
|
|
||||||
"Unable to find user wallet with provided ID: $userWalletId"
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (userWallet.isMultiCurrency) {
|
|
||||||
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 {
|
|
||||||
if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
|
|
||||||
cardCryptoCurrencyFactory.createCurrenciesForSingleCurrencyCardWithToken(
|
|
||||||
scanResponse = userWallet.scanResponse,
|
|
||||||
)
|
|
||||||
.asSequence()
|
|
||||||
} else {
|
|
||||||
val currency = cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(
|
|
||||||
scanResponse = userWallet.scanResponse,
|
|
||||||
)
|
|
||||||
|
|
||||||
sequenceOf(currency)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun invalidateCacheKeyIfNeeded(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
network: Network,
|
|
||||||
result: UpdateWalletManagerResult,
|
|
||||||
) {
|
|
||||||
when (result) {
|
|
||||||
is UpdateWalletManagerResult.Verified,
|
|
||||||
is UpdateWalletManagerResult.NoAccount,
|
|
||||||
-> Unit
|
|
||||||
is UpdateWalletManagerResult.Unreachable,
|
|
||||||
is UpdateWalletManagerResult.MissedDerivation,
|
|
||||||
-> {
|
|
||||||
Timber.w(
|
|
||||||
"""
|
|
||||||
Invalidate network cache key
|
|
||||||
|- User wallet ID: $userWalletId
|
|
||||||
|- Network: ${network.id}
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
|
|
||||||
cacheRegistry.invalidate(getNetworksStatusesCacheKey(userWalletId, network))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getNetworksStatusesCacheKey(userWalletId: UserWalletId, network: Network): String {
|
|
||||||
return "network_status_${userWalletId}_${network.id.value}_${network.derivationPath.value}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,17 +10,24 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(deps.arrow.core)
|
// region Project – Core
|
||||||
implementation(deps.kotlin.coroutines)
|
|
||||||
|
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Project – Domain
|
||||||
implementation(projects.domain.core)
|
implementation(projects.domain.core)
|
||||||
implementation(projects.domain.models)
|
implementation(projects.domain.models)
|
||||||
|
implementation(projects.domain.networks)
|
||||||
implementation(projects.domain.nft.models)
|
implementation(projects.domain.nft.models)
|
||||||
|
implementation(projects.domain.quotes)
|
||||||
implementation(projects.domain.tokens)
|
implementation(projects.domain.tokens)
|
||||||
implementation(projects.domain.tokens.models)
|
implementation(projects.domain.tokens.models)
|
||||||
implementation(projects.domain.wallets.models)
|
implementation(projects.domain.wallets.models)
|
||||||
implementation(projects.domain.quotes)
|
// endregion
|
||||||
|
|
||||||
|
// region Others
|
||||||
|
implementation(deps.arrow.core)
|
||||||
|
implementation(deps.kotlin.coroutines)
|
||||||
|
// endregion
|
||||||
}
|
}
|
||||||
|
|
@ -1,15 +1,20 @@
|
||||||
package com.tangem.domain.nft
|
package com.tangem.domain.nft
|
||||||
|
|
||||||
|
import com.tangem.domain.networks.single.SingleNetworkStatusProducer
|
||||||
|
import com.tangem.domain.networks.single.SingleNetworkStatusSupplier
|
||||||
import com.tangem.domain.tokens.model.Network
|
import com.tangem.domain.tokens.model.Network
|
||||||
import com.tangem.domain.tokens.model.NetworkStatus
|
import com.tangem.domain.tokens.model.NetworkStatus
|
||||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
|
|
||||||
class GetNFTNetworkStatusUseCase(
|
class GetNFTNetworkStatusUseCase(
|
||||||
private val networksRepository: NetworksRepository,
|
private val singleNetworkStatusSupplier: SingleNetworkStatusSupplier,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke(userWalletId: UserWalletId, network: Network): NetworkStatus? = networksRepository
|
suspend operator fun invoke(userWalletId: UserWalletId, network: Network): NetworkStatus? {
|
||||||
.getNetworkStatusesSync(userWalletId, setOf(network), false)
|
return singleNetworkStatusSupplier(
|
||||||
.firstOrNull { it.network == network }
|
params = SingleNetworkStatusProducer.Params(userWalletId = userWalletId, network = network),
|
||||||
|
)
|
||||||
|
.firstOrNull()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package com.tangem.domain.tokens
|
package com.tangem.domain.tokens
|
||||||
|
|
||||||
|
import arrow.core.Either
|
||||||
|
import com.tangem.domain.networks.repository.NetworksRepository
|
||||||
import com.tangem.domain.tokens.model.Network
|
import com.tangem.domain.tokens.model.Network
|
||||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import kotlinx.coroutines.coroutineScope
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use case responsible for fetching current pending transactions
|
* Use case responsible for fetching current pending transactions
|
||||||
|
|
@ -14,9 +14,7 @@ class FetchPendingTransactionsUseCase(
|
||||||
private val networksRepository: NetworksRepository,
|
private val networksRepository: NetworksRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke(userWalletId: UserWalletId, networks: Set<Network>) {
|
suspend operator fun invoke(userWalletId: UserWalletId, network: Network) = Either.catch {
|
||||||
coroutineScope {
|
networksRepository.fetchPendingTransactions(userWalletId = userWalletId, network = network)
|
||||||
networksRepository.fetchNetworkPendingTransactions(userWalletId, networks)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package com.tangem.domain.tokens
|
package com.tangem.domain.tokens
|
||||||
|
|
||||||
|
import com.tangem.domain.networks.repository.NetworksRepository
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
||||||
import com.tangem.domain.tokens.model.Network
|
import com.tangem.domain.tokens.model.Network
|
||||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
class GetNetworkAddressesUseCase(
|
class GetNetworkAddressesUseCase(
|
||||||
internal val networksRepository: NetworksRepository,
|
private val networksRepository: NetworksRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun invokeSync(userWalletId: UserWalletId, network: Network): List<CryptoCurrencyAddress> {
|
suspend fun invokeSync(userWalletId: UserWalletId, network: Network): List<CryptoCurrencyAddress> {
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
package com.tangem.domain.tokens.repository
|
|
||||||
|
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
|
||||||
import com.tangem.domain.tokens.model.Network
|
|
||||||
import com.tangem.domain.tokens.model.NetworkStatus
|
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Repository for everything related to the blockchain networks
|
|
||||||
* */
|
|
||||||
interface NetworksRepository {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves updates of network statuses of specified blockchain networks for a specific user wallet.
|
|
||||||
*
|
|
||||||
* To fetch and populate the cache with network statuses, use [fetchNetworkStatuses].
|
|
||||||
*
|
|
||||||
* @param userWalletId The unique identifier of the user wallet.
|
|
||||||
* @param networks A set of network which statuses are to be retrieved.
|
|
||||||
*
|
|
||||||
* @return A [Flow] emitting a set of [NetworkStatus] objects corresponding to the specified networks.
|
|
||||||
* */
|
|
||||||
fun getNetworkStatusesUpdates(userWalletId: UserWalletId, networks: Set<Network>): Flow<Set<NetworkStatus>>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches network statuses of specified blockchain networks for a specific user wallet.
|
|
||||||
*
|
|
||||||
* Fetched network statuses are stored in the local cache and can be retrieved by calling
|
|
||||||
* [getNetworkStatusesUpdates].
|
|
||||||
*
|
|
||||||
* @param userWalletId The unique identifier of the user wallet.
|
|
||||||
* @param networks A set of network which statuses are to be retrieved.
|
|
||||||
* @param refresh A boolean flag indicating whether the data should be refreshed. Default is `false`.
|
|
||||||
* */
|
|
||||||
suspend fun fetchNetworkStatuses(userWalletId: UserWalletId, networks: Set<Network>, refresh: Boolean = false)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches pending transactions for given network
|
|
||||||
*
|
|
||||||
* @param userWalletId The unique identifier of the user wallet.
|
|
||||||
* @param networks A set of network which statuses are to be retrieved.
|
|
||||||
*/
|
|
||||||
suspend fun fetchNetworkPendingTransactions(userWalletId: UserWalletId, networks: Set<Network>)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves network statuses of specified blockchain networks for a specific user wallet.
|
|
||||||
*
|
|
||||||
* Loads remote network statuses if they have expired or if [refresh] is `true`.
|
|
||||||
*
|
|
||||||
* @param userWalletId The unique identifier of the user wallet.
|
|
||||||
* @param networks A set of network which statuses are to be retrieved.
|
|
||||||
* @param refresh A boolean flag indicating whether the data should be refreshed.
|
|
||||||
* @return A [Flow] emitting a set of [NetworkStatus] objects corresponding to the specified networks.
|
|
||||||
*/
|
|
||||||
suspend fun getNetworkStatusesSync(
|
|
||||||
userWalletId: UserWalletId,
|
|
||||||
networks: Set<Network>,
|
|
||||||
refresh: Boolean = false,
|
|
||||||
): Set<NetworkStatus>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns list of addresses and crypto currency info of added currencies of [network] in selected wallet [userWalletId]
|
|
||||||
*/
|
|
||||||
suspend fun getNetworkAddresses(userWalletId: UserWalletId, network: Network): List<CryptoCurrencyAddress>
|
|
||||||
}
|
|
||||||
|
|
@ -33,7 +33,7 @@ internal class SendBalanceUpdater @AssistedInject constructor(
|
||||||
async {
|
async {
|
||||||
fetchPendingTransactionsUseCase(
|
fetchPendingTransactionsUseCase(
|
||||||
userWalletId = userWallet.walletId,
|
userWalletId = userWallet.walletId,
|
||||||
networks = setOf(cryptoCurrency.network),
|
network = cryptoCurrency.network,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
// we should update tx history and network for new balances
|
// we should update tx history and network for new balances
|
||||||
|
|
|
||||||
|
|
@ -1037,7 +1037,10 @@ internal class SendModel @Inject constructor(
|
||||||
listOf(
|
listOf(
|
||||||
// we should update network to find pending tx after 1 sec
|
// we should update network to find pending tx after 1 sec
|
||||||
async {
|
async {
|
||||||
fetchPendingTransactionsUseCase(userWallet.walletId, setOf(cryptoCurrency.network))
|
fetchPendingTransactionsUseCase(
|
||||||
|
userWalletId = userWallet.walletId,
|
||||||
|
network = cryptoCurrency.network,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
// we should update tx history and network for new balance
|
// we should update tx history and network for new balance
|
||||||
async {
|
async {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ internal class StakingBalanceUpdater @AssistedInject constructor(
|
||||||
async {
|
async {
|
||||||
fetchPendingTransactionsUseCase(
|
fetchPendingTransactionsUseCase(
|
||||||
userWalletId = userWallet.walletId,
|
userWalletId = userWallet.walletId,
|
||||||
networks = setOf(cryptoCurrencyStatus.currency.network),
|
network = cryptoCurrencyStatus.currency.network,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
// we should update tx history and network for new balances
|
// we should update tx history and network for new balances
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue