diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt index 2c74eba8ba..b9292c096c 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt @@ -55,12 +55,16 @@ internal class DefaultWalletCurrenciesManager( currenciesToAdd: List, ): CompletionResult = withContext(Dispatchers.Default) { val card = userWallet.scanResponse.card - val newCurrencies = (getSavedCurrencies(userWallet.walletId) + currenciesToAdd) - .addMissingBlockchains(card) + val currenciesToAddWithMissingBlockchains = currenciesToAdd.addMissingBlockchainsIfNeeded(card) - updateWalletStores(userWallet, newCurrencies.toBlockchainNetworks()) + updateWalletStores( + userWallet = userWallet, + blockchainNetworks = currenciesToAddWithMissingBlockchains + .toBlockchainNetworks() + .addSameBlockchainTokens(userWallet.walletId), + ) .map { - saveUserCurrencies(card, newCurrencies) + saveUserCurrencies(card, getSavedCurrencies(userWallet.walletId)) } .flatMap { updateWalletStoresAmounts( @@ -114,7 +118,38 @@ internal class DefaultWalletCurrenciesManager( } } - private fun List.addMissingBlockchains(card: CardDTO): List { + // TODO: Need refactoring + private suspend fun List.addSameBlockchainTokens( + userWalletId: UserWalletId, + ): List { + val networks = arrayListOf() + val savedWalletStores = withContext(Dispatchers.Default) { + walletStoresRepository.getSync(userWalletId) + } + + this.forEach { network -> + val walletStore = savedWalletStores.firstOrNull { + it.blockchain == network.blockchain && it.derivationPath?.rawPath == network.derivationPath + } + + if (walletStore != null) { + val tokens = walletStore.walletsData + .asSequence() + .map { it.currency } + .filterIsInstance() + .map { it.token } + .toList() + + networks.add(network.copy(tokens = tokens + network.tokens.toSet())) + } else { + networks.add(network) + } + } + + return networks + } + + private fun List.addMissingBlockchainsIfNeeded(card: CardDTO): List { if (this.isEmpty()) return this val currencies = this.asSequence() @@ -165,7 +200,6 @@ internal class DefaultWalletCurrenciesManager( userWallet: UserWallet, blockchainNetworks: List, ): CompletionResult { - val userWalletId = userWallet.walletId return blockchainNetworks .map { blockchainNetwork -> walletManagersRepository.findOrMakeMultiCurrencyWalletManager( @@ -174,7 +208,7 @@ internal class DefaultWalletCurrenciesManager( ) .flatMap { walletManager -> walletStoresRepository.storeOrUpdate( - userWalletId = userWalletId, + userWalletId = userWallet.walletId, walletStore = WalletStoreBuilder(userWallet, blockchainNetwork) .walletManager(walletManager) .build(), diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt index c6519653d2..1080f7529f 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt @@ -442,7 +442,7 @@ internal class DefaultWalletAmountsRepository( .toMutableList() .apply { replaceByOrAdd(walletManager) { - it.wallet.blockchain == it.wallet.blockchain + it.wallet.blockchain == walletManager.wallet.blockchain } } diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt index 1758c2fbf9..d9579349d6 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletManagersRepository.kt @@ -7,8 +7,8 @@ import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.WalletManagerFactory import com.tangem.common.CompletionResult import com.tangem.common.catching +import com.tangem.common.doOnSuccess import com.tangem.common.hdWallet.DerivationPath -import com.tangem.common.map import com.tangem.common.mapFailure import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse @@ -22,7 +22,7 @@ import com.tangem.tap.domain.walletStores.WalletStoresError import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository import com.tangem.tap.domain.walletStores.storage.WalletManagerStorage import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.withContext import timber.log.Timber @@ -93,10 +93,7 @@ internal class DefaultWalletManagersRepository( scanResponse = scanResponse, blockchainNetwork = blockchainNetwork, ) - .map { updatedWalletManager -> - store(userWallet.walletId, updatedWalletManager) - updatedWalletManager - } + .doOnSuccess { store(userWallet.walletId, it) } } else -> { val error = WalletStoresError.WalletManagerNotCreated(blockchain) @@ -158,8 +155,9 @@ internal class DefaultWalletManagersRepository( return catching { val tokens = blockchainNetwork?.tokens ?: listOfNotNull(scanResponse.cardTypesResolver.getPrimaryToken()) - if (tokens != cardTokens) { - cardTokens.clear() + if (tokens != walletManager.cardTokens) { + walletManager.cardTokens.clear() + walletManager.wallet.removeAllTokens() if (tokens.isNotEmpty()) { walletManager.cardTokens.addAll(tokens) } @@ -181,13 +179,16 @@ internal class DefaultWalletManagersRepository( userWalletId: UserWalletId, blockchain: Blockchain?, ): WalletManager? { - return walletManagersStorage.getAll().first()[userWalletId]?.let { userWalletManagers -> - if (blockchain == null) { - userWalletManagers.firstOrNull() - } else { - userWalletManagers.find { it.wallet.blockchain == blockchain } + return walletManagersStorage.getAll() + .firstOrNull() + ?.get(userWalletId) + ?.let { userWalletManagers -> + if (blockchain == null) { + userWalletManagers.firstOrNull() + } else { + userWalletManagers.firstOrNull { it.wallet.blockchain == blockchain } + } } - } } private fun getDerivationParams(derivationPath: String?, card: CardDTO): DerivationParams? { diff --git a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt index 715f99415a..250bf73562 100644 --- a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt @@ -23,9 +23,12 @@ import com.tangem.tap.domain.extensions.makeWalletManagerForApp import com.tangem.tap.domain.model.builders.UserWalletIdBuilder import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.userWalletsListManager +import com.tangem.tap.walletCurrenciesManager import kotlinx.coroutines.delay import org.rekotlin.Action import java.math.BigDecimal +import com.tangem.tap.features.wallet.models.Currency as WalletCurrency class UserWalletManagerImpl( private val appStateHolder: AppStateHolder, @@ -106,14 +109,21 @@ class UserWalletManagerImpl( val card = requireNotNull(appStateHolder.getActualCard()) { "card not found" } val blockchain = requireNotNull(Blockchain.fromNetworkId(currency.networkId)) { "blockchain not found" } val blockchainNetwork = BlockchainNetwork(blockchain, card) - val walletManager = getOrCreateBlockchain(blockchainNetwork, blockchain) - if (currency is NonNativeToken && - !walletManager.cardTokens.contains(currency.toSdkToken()) - ) { - val action = addNonNativeTokenToWalletAction(currency, card, blockchain) - val mainStore = requireNotNull(appStateHolder.mainStore) { "mainStore is null" } - mainStore.dispatchOnMain(action) - delay(DELAY_UPDATE_WALLET) + + val selectedUserWallet = userWalletsListManager.selectedUserWalletSync + if (selectedUserWallet != null) { + walletCurrenciesManager.addCurrencies( + userWallet = selectedUserWallet, + currenciesToAdd = listOf(currency.toWalletCurrency(blockchainNetwork)), + ) + } else { + val walletManager = getOrCreateBlockchain(blockchainNetwork, blockchain) + if (currency is NonNativeToken && !walletManager.cardTokens.contains(currency.toSdkToken())) { + val action = addNonNativeTokenToWalletAction(currency, card, blockchain) + val mainStore = requireNotNull(appStateHolder.mainStore) { "mainStore is null" } + mainStore.dispatchOnMain(action) + delay(DELAY_UPDATE_WALLET) + } } } @@ -271,4 +281,18 @@ private fun NonNativeToken.toSdkToken(): Token { contractAddress = this.contractAddress, decimals = this.decimalCount, ) +} + +private fun Currency.toWalletCurrency(network: BlockchainNetwork): WalletCurrency { + return when (this) { + is NativeToken -> WalletCurrency.Blockchain( + blockchain = network.blockchain, + derivationPath = network.derivationPath, + ) + is NonNativeToken -> WalletCurrency.Token( + token = this.toSdkToken(), + blockchain = network.blockchain, + derivationPath = network.derivationPath, + ) + } } \ No newline at end of file