From efc8c003bd1bea8a06c26c1fb7af1418c38dafed Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 2 Jul 2024 21:20:02 +0800 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/data/tokens/di/TokensDataModule.kt | 7 +- .../repository/DefaultCurrenciesRepository.kt | 82 ++++++++++--------- .../DefaultMarketCryptoCurrencyRepository.kt | 18 ++-- .../repository/DefaultTxHistoryRepository.kt | 23 +++--- .../DefaultWalletManagersFacade.kt | 63 ++++++++------ 5 files changed, 111 insertions(+), 82 deletions(-) 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 062692cd06..f31d0e4b5f 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 @@ -87,8 +87,11 @@ internal object TokensDataModule { @Provides @Singleton - fun provideDefaultMarketCoinsRepository(assetsStore: AssetsStore): MarketCryptoCurrencyRepository { - return DefaultMarketCryptoCurrencyRepository(assetsStore) + fun provideDefaultMarketCoinsRepository( + assetsStore: AssetsStore, + coroutineDispatcherProvider: CoroutineDispatcherProvider, + ): MarketCryptoCurrencyRepository { + return DefaultMarketCryptoCurrencyRepository(assetsStore, coroutineDispatcherProvider) } @Provides 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 89bb9aca17..9459984032 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 @@ -302,26 +302,28 @@ internal class DefaultCurrenciesRepository( networkId: Network.ID, derivationPath: Network.DerivationPath, ): CryptoCurrency.Coin { - val userWallet = getUserWallet(userWalletId) - ensureIsCorrectUserWallet(userWallet = userWallet, isMultiCurrencyWalletExpected = true) + return withContext(dispatchers.io) { + val userWallet = getUserWallet(userWalletId) + ensureIsCorrectUserWallet(userWallet = userWallet, isMultiCurrencyWalletExpected = true) - fetchTokensIfCacheExpired(userWallet = userWallet, refresh = false) + 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(userTokensStore.getSyncOrNull(userWallet.walletId)) { + "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() + + val storedCoin = storedTokens.tokens + .find { + it.networkId == blockchainNetworkId && it.id == coinId && it.derivationPath == derivationPath.value + } ?: error("Coin in this network $networkId not found") + + val coin = responseCurrenciesFactory.createCurrency(storedCoin, userWallet.scanResponse) + + coin as? CryptoCurrency.Coin ?: error("Unable to create currency") } - val blockchain = Blockchain.fromId(networkId.value) - val blockchainNetworkId = blockchain.toNetworkId() - val coinId = blockchain.toCoinId() - - val storedCoin = storedTokens.tokens - .find { - it.networkId == blockchainNetworkId && it.id == coinId && it.derivationPath == derivationPath.value - } ?: error("Coin in this network $networkId not found") - - val coin = responseCurrenciesFactory.createCurrency(storedCoin, userWallet.scanResponse) - - return coin as? CryptoCurrency.Coin ?: error("Unable to create currency") } override fun isTokensGrouped(userWalletId: UserWalletId): Flow { @@ -382,29 +384,31 @@ internal class DefaultCurrenciesRepository( } override suspend fun getFeePaidCurrency(userWalletId: UserWalletId, currency: CryptoCurrency): FeePaidCurrency { - val blockchain = Blockchain.fromId(currency.network.id.value) - return when (val feePaidCurrency = blockchain.feePaidCurrency()) { - FeePaidSdkCurrency.Coin -> FeePaidCurrency.Coin - FeePaidSdkCurrency.SameCurrency -> FeePaidCurrency.SameCurrency - is FeePaidSdkCurrency.Token -> { - val balance = walletManagersFacade.tokenBalance( - userWalletId = userWalletId, - network = currency.network, - name = feePaidCurrency.token.name, - symbol = feePaidCurrency.token.symbol, - contractAddress = feePaidCurrency.token.contractAddress, - decimals = feePaidCurrency.token.decimals, - id = feePaidCurrency.token.id, - ) - FeePaidCurrency.Token( - tokenId = getTokenId(network = currency.network, sdkToken = feePaidCurrency.token), - name = feePaidCurrency.token.name, - symbol = feePaidCurrency.token.symbol, - contractAddress = feePaidCurrency.token.contractAddress, - balance = balance, - ) + return withContext(dispatchers.io) { + val blockchain = Blockchain.fromId(currency.network.id.value) + when (val feePaidCurrency = blockchain.feePaidCurrency()) { + FeePaidSdkCurrency.Coin -> FeePaidCurrency.Coin + FeePaidSdkCurrency.SameCurrency -> FeePaidCurrency.SameCurrency + is FeePaidSdkCurrency.Token -> { + val balance = walletManagersFacade.tokenBalance( + userWalletId = userWalletId, + network = currency.network, + name = feePaidCurrency.token.name, + symbol = feePaidCurrency.token.symbol, + contractAddress = feePaidCurrency.token.contractAddress, + decimals = feePaidCurrency.token.decimals, + id = feePaidCurrency.token.id, + ) + FeePaidCurrency.Token( + tokenId = getTokenId(network = currency.network, sdkToken = feePaidCurrency.token), + name = feePaidCurrency.token.name, + symbol = feePaidCurrency.token.symbol, + contractAddress = feePaidCurrency.token.contractAddress, + balance = balance, + ) + } + is FeePaidSdkCurrency.FeeResource -> FeePaidCurrency.FeeResource(currency = feePaidCurrency.currency) } - is FeePaidSdkCurrency.FeeResource -> FeePaidCurrency.FeeResource(currency = feePaidCurrency.currency) } } diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt index a210d96273..d4a0f8fd29 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt @@ -5,9 +5,12 @@ import com.tangem.datasource.local.token.AssetsStore import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.repository.MarketCryptoCurrencyRepository import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.withContext class DefaultMarketCryptoCurrencyRepository( private val assetsStore: AssetsStore, + private val dispatchers: CoroutineDispatcherProvider, ) : MarketCryptoCurrencyRepository { override suspend fun isExchangeable(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean { @@ -15,11 +18,16 @@ class DefaultMarketCryptoCurrencyRepository( } private suspend fun getExchangeableFlag(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean { - val contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE + return withContext(dispatchers.io) { + val contractAddress = + (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress ?: EMPTY_CONTRACT_ADDRESS_VALUE - return assetsStore.getSyncOrNull(userWalletId)?.find { - it.network == cryptoCurrency.network.backendId && - it.contractAddress.equals(contractAddress, ignoreCase = true) - }?.exchangeAvailable ?: false + val asset = assetsStore.getSyncOrNull(userWalletId)?.find { + it.network == cryptoCurrency.network.backendId && + it.contractAddress.equals(contractAddress, ignoreCase = true) + } + + asset?.exchangeAvailable ?: false + } } } \ No newline at end of file diff --git a/data/txhistory/src/main/kotlin/com/tangem/data/txhistory/repository/DefaultTxHistoryRepository.kt b/data/txhistory/src/main/kotlin/com/tangem/data/txhistory/repository/DefaultTxHistoryRepository.kt index fb35baa42f..7d447a5359 100644 --- a/data/txhistory/src/main/kotlin/com/tangem/data/txhistory/repository/DefaultTxHistoryRepository.kt +++ b/data/txhistory/src/main/kotlin/com/tangem/data/txhistory/repository/DefaultTxHistoryRepository.kt @@ -35,16 +35,19 @@ class DefaultTxHistoryRepository( private val sdkPageConverter by lazy { SdkPageConverter() } override suspend fun getTxHistoryItemsCount(userWalletId: UserWalletId, currency: CryptoCurrency): Int { - val userWallet = getUserWallet(userWalletId) - val state = walletManagersFacade.getTxHistoryState( - userWalletId = userWallet.walletId, - currency = currency, - ) - return when (state) { - is TxHistoryState.Failed.FetchError -> throw TxHistoryStateError.DataError(state.exception) - is TxHistoryState.NotImplemented -> throw TxHistoryStateError.TxHistoryNotImplemented - is TxHistoryState.Success.Empty -> throw TxHistoryStateError.EmptyTxHistories - is TxHistoryState.Success.HasTransactions -> state.txCount + return withContext(dispatchers.io) { + val userWallet = getUserWallet(userWalletId) + val state = walletManagersFacade.getTxHistoryState( + userWalletId = userWallet.walletId, + currency = currency, + ) + + when (state) { + is TxHistoryState.Failed.FetchError -> throw TxHistoryStateError.DataError(state.exception) + is TxHistoryState.NotImplemented -> throw TxHistoryStateError.TxHistoryNotImplemented + is TxHistoryState.Success.Empty -> throw TxHistoryStateError.EmptyTxHistories + is TxHistoryState.Success.HasTransactions -> state.txCount + } } } diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index 5592329e84..25dae1f2dd 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -87,11 +87,13 @@ class DefaultWalletManagersFacade( Blockchain.fromId(it.id.value) to it.derivationPath.value } - walletManagersStore.remove(userWalletId) { walletManager -> - val wallet = walletManager.wallet - val blockchainToDerivationPath = wallet.blockchain to wallet.publicKey.derivationPath?.rawPath + withContext(dispatchers.io) { + walletManagersStore.remove(userWalletId) { walletManager -> + val wallet = walletManager.wallet + val blockchainToDerivationPath = wallet.blockchain to wallet.publicKey.derivationPath?.rawPath - blockchainToDerivationPath in blockchainsToDerivationPaths + blockchainToDerivationPath in blockchainsToDerivationPaths + } } } @@ -110,18 +112,20 @@ class DefaultWalletManagersFacade( network: Network, networkTokens: List, ) { - val walletManager = walletManagersStore.getSyncOrNull( - userWalletId = userWalletId, - blockchain = Blockchain.fromId(network.id.value), - derivationPath = network.derivationPath.value, - ) ?: return - val tokensToRemove = sdkTokenConverter.convertList(networkTokens) + withContext(dispatchers.io) { + val walletManager = walletManagersStore.getSyncOrNull( + userWalletId = userWalletId, + blockchain = Blockchain.fromId(network.id.value), + derivationPath = network.derivationPath.value, + ) ?: return@withContext + val tokensToRemove = sdkTokenConverter.convertList(networkTokens) - tokensToRemove.forEach { token -> - walletManager.removeToken(token) + tokensToRemove.forEach { token -> + walletManager.removeToken(token) + } + + walletManagersStore.store(userWalletId, walletManager) } - - walletManagersStore.store(userWalletId, walletManager) } override suspend fun updatePendingTransactions( @@ -576,12 +580,16 @@ class DefaultWalletManagersFacade( userWalletId: UserWalletId, currency: CryptoCurrency, ): AssetRequirementsCondition? { - val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = currency.network) - val currencyType = cryptoCurrencyTypeConverter.convert(currency) - if (walletManager !is AssetRequirementsManager || !walletManager.hasRequirements(currencyType)) return null + return withContext(dispatchers.io) { + val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = currency.network) + val currencyType = cryptoCurrencyTypeConverter.convert(currency) + if (walletManager !is AssetRequirementsManager || !walletManager.hasRequirements(currencyType)) { + return@withContext null + } - val condition = walletManager.requirementsCondition(currencyType) ?: return null - return requirementsConditionConverter.convert(condition) + val condition = walletManager.requirementsCondition(currencyType) ?: return@withContext null + requirementsConditionConverter.convert(condition) + } } override suspend fun associateAsset( @@ -589,15 +597,18 @@ class DefaultWalletManagersFacade( currency: CryptoCurrency, signer: CommonSigner, ): SimpleResult { - val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = currency.network) - val currencyType = cryptoCurrencyTypeConverter.convert(currency) + return withContext(dispatchers.io) { + val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = currency.network) + val currencyType = cryptoCurrencyTypeConverter.convert(currency) - if (walletManager !is AssetRequirementsManager) { - return SimpleResult.Failure( - BlockchainSdkError.CustomError("WalletManager is not implemented AssetRequirementsManager"), - ) + if (walletManager !is AssetRequirementsManager) { + return@withContext SimpleResult.Failure( + BlockchainSdkError.CustomError("WalletManager is not implemented AssetRequirementsManager"), + ) + } + + walletManager.fulfillRequirements(currencyType, signer) } - return walletManager.fulfillRequirements(currencyType, signer) } override suspend fun checkUtxoConsolidationAvailability(userWalletId: UserWalletId, network: Network): Boolean {