diff --git a/domain/account/src/main/java/com/tangem/domain/account/models/AccountStatusList.kt b/domain/account/src/main/java/com/tangem/domain/account/models/AccountStatusList.kt index 4d3b4dab0e..761ac72309 100644 --- a/domain/account/src/main/java/com/tangem/domain/account/models/AccountStatusList.kt +++ b/domain/account/src/main/java/com/tangem/domain/account/models/AccountStatusList.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable @Serializable data class AccountStatusList( val userWalletId: UserWalletId, - val accountStatuses: Set, + val accountStatuses: List, val totalAccounts: Int, val totalFiatBalance: TotalFiatBalance, ) { diff --git a/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt b/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt index 8a5f3346ec..78bb3226e7 100644 --- a/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt +++ b/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt @@ -4,9 +4,9 @@ import arrow.core.Option import arrow.core.none import com.tangem.domain.account.models.AccountStatusList import com.tangem.domain.account.producer.SingleAccountListProducer +import com.tangem.domain.account.repository.AccountsCRUDRepository import com.tangem.domain.account.status.utils.CryptoCurrencyStatusesFlowFactory import com.tangem.domain.account.supplier.SingleAccountListSupplier -import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.core.utils.lceContent import com.tangem.domain.models.StatusSource import com.tangem.domain.models.TokensGroupType @@ -31,6 +31,7 @@ import java.math.BigDecimal * Produces a flow of [AccountStatusList] for a single user wallet. * * @property params Parameters containing the user wallet ID. + * @property accountsCRUDRepository Repository for accessing account data. * @property singleAccountListSupplier Supplier to get the list of accounts for the user wallet. * @property cryptoCurrencyStatusesFlowFactory Factory to create flows of cryptocurrency statuses. * @property dispatchers Coroutine dispatcher provider for managing threading. @@ -40,7 +41,7 @@ import java.math.BigDecimal @OptIn(ExperimentalCoroutinesApi::class) internal class DefaultSingleAccountStatusListProducer @AssistedInject constructor( @Assisted private val params: SingleAccountStatusListProducer.Params, - private val userWalletsListRepository: UserWalletsListRepository, + private val accountsCRUDRepository: AccountsCRUDRepository, private val singleAccountListSupplier: SingleAccountListSupplier, private val cryptoCurrencyStatusesFlowFactory: CryptoCurrencyStatusesFlowFactory, private val dispatchers: CoroutineDispatcherProvider, @@ -61,9 +62,11 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo if (account.cryptoCurrencies.isEmpty()) { createEmptyAccountStatusFlow(account) } else { - val userWallet = userWalletsListRepository.userWalletsSync().first { - it.walletId == params.userWalletId - } + val userWallet = accountsCRUDRepository.getUserWallets() + .mapNotNull { wallets -> + wallets.find { it.walletId == params.userWalletId } + } + .first() getAccountStatusFlow( userWallet = userWallet, @@ -80,7 +83,7 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo AccountStatusList( userWalletId = accountList.userWalletId, - accountStatuses = accountStatuses.toSet(), + accountStatuses = accountStatuses.toList(), totalAccounts = accountList.totalAccounts, totalFiatBalance = TotalFiatBalanceCalculator.calculate(balances), ) diff --git a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/ManageCryptoCurrenciesUseCase.kt b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/ManageCryptoCurrenciesUseCase.kt index d37b6ac322..ca59ae9ed8 100644 --- a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/ManageCryptoCurrenciesUseCase.kt +++ b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/ManageCryptoCurrenciesUseCase.kt @@ -84,17 +84,24 @@ class ManageCryptoCurrenciesUseCase( account = account.copy(cryptoCurrencies = modifiedCurrencyList.total.toSet()), ) - derivePublicKeys(userWalletId = userWalletId, currencies = modifiedCurrencyList.added) + val isDerivingFailed = derivePublicKeys( + userWalletId = userWalletId, + currencies = modifiedCurrencyList.added, + ).isLeft() parallelUpdatingScope.launch { /* * If only removal of currencies happened, we need to sync tokens. Otherwise, tokens will be synced * when balances are refreshed for added currencies. */ - if (modifiedCurrencyList.added.isEmpty() && modifiedCurrencyList.removed.isNotEmpty()) { + val isOnlyRemoval = modifiedCurrencyList.added.isEmpty() && modifiedCurrencyList.removed.isNotEmpty() + + if (isDerivingFailed || isOnlyRemoval) { launch { accountsCRUDRepository.syncTokens(userWalletId) } } + if (isDerivingFailed) return@launch + cryptoCurrencyBalanceFetcher(userWalletId = userWalletId, currencies = modifiedCurrencyList.added) refreshExpress(userWalletId = userWalletId, currencies = modifiedCurrencyList.total) clearMetadata(userWalletId = userWalletId, currencies = modifiedCurrencyList.removed) @@ -204,14 +211,11 @@ class ManageCryptoCurrenciesUseCase( ) } - private suspend fun Raise.derivePublicKeys( + private suspend fun derivePublicKeys( userWalletId: UserWalletId, currencies: List, - ) { - catch( - block = { derivationsRepository.derivePublicKeys(userWalletId = userWalletId, currencies = currencies) }, - catch = ::raise, - ) + ): Either = Either.catch { + derivationsRepository.derivePublicKeys(userWalletId = userWalletId, currencies = currencies) } private fun List.groupByNetwork( diff --git a/domain/account/status/src/main/java/com/tangem/domain/account/status/utils/AccountCryptoCurrencyStatusFinder.kt b/domain/account/status/src/main/java/com/tangem/domain/account/status/utils/AccountCryptoCurrencyStatusFinder.kt index 6f29996eab..3d4f973735 100644 --- a/domain/account/status/src/main/java/com/tangem/domain/account/status/utils/AccountCryptoCurrencyStatusFinder.kt +++ b/domain/account/status/src/main/java/com/tangem/domain/account/status/utils/AccountCryptoCurrencyStatusFinder.kt @@ -58,14 +58,14 @@ internal object AccountCryptoCurrencyStatusFinder { * @param network the network to filter accounts by, can be null. * @return a set of [AccountStatus] that match the expected criteria. */ - private fun AccountStatusList.getExpectedAccountStatuses(network: Network?): Set { + private fun AccountStatusList.getExpectedAccountStatuses(network: Network?): List { val possibleAccountIndex = network?.getAccountIndexOrNull() return when (possibleAccountIndex) { // currency can be in any account null -> accountStatuses // currency only in the main account - DerivationIndex.Main.value -> setOf(mainAccount) + DerivationIndex.Main.value -> listOf(mainAccount) // currency only in the account with specific derivation index or in the main account else -> { val accountStatus = accountStatuses.firstOrNull { @@ -74,7 +74,7 @@ internal object AccountCryptoCurrencyStatusFinder { cryptoPortfolio.derivationIndex.value == possibleAccountIndex } - setOfNotNull(accountStatus, mainAccount) + listOfNotNull(accountStatus, mainAccount) } } } diff --git a/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducerTest.kt b/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducerTest.kt index 6601e4c64e..8ff3b59d4f 100644 --- a/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducerTest.kt +++ b/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducerTest.kt @@ -7,9 +7,9 @@ import com.tangem.common.test.utils.getEmittedValues import com.tangem.domain.account.models.AccountList import com.tangem.domain.account.models.AccountStatusList import com.tangem.domain.account.producer.SingleAccountListProducer +import com.tangem.domain.account.repository.AccountsCRUDRepository import com.tangem.domain.account.status.utils.CryptoCurrencyStatusesFlowFactory import com.tangem.domain.account.supplier.SingleAccountListSupplier -import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.core.utils.lceContent import com.tangem.domain.core.utils.lceLoading import com.tangem.domain.models.StatusSource @@ -38,7 +38,7 @@ import java.math.BigDecimal @TestInstance(TestInstance.Lifecycle.PER_CLASS) class DefaultSingleAccountStatusListProducerTest { - private val userWalletsListRepository: UserWalletsListRepository = mockk() + private val accountsCRUDRepository: AccountsCRUDRepository = mockk() private val singleAccountListSupplier: SingleAccountListSupplier = mockk() private val cryptoCurrencyStatusesFlowFactory: CryptoCurrencyStatusesFlowFactory = mockk() @@ -49,7 +49,7 @@ class DefaultSingleAccountStatusListProducerTest { private val producer = DefaultSingleAccountStatusListProducer( params = SingleAccountStatusListProducer.Params(userWalletId), - userWalletsListRepository = userWalletsListRepository, + accountsCRUDRepository = accountsCRUDRepository, singleAccountListSupplier = singleAccountListSupplier, cryptoCurrencyStatusesFlowFactory = cryptoCurrencyStatusesFlowFactory, dispatchers = TestingCoroutineDispatcherProvider(), @@ -57,7 +57,7 @@ class DefaultSingleAccountStatusListProducerTest { @AfterEach fun tearDown() { - clearMocks(singleAccountListSupplier, cryptoCurrencyStatusesFlowFactory) + clearMocks(accountsCRUDRepository, singleAccountListSupplier, cryptoCurrencyStatusesFlowFactory) } @Test @@ -75,7 +75,7 @@ class DefaultSingleAccountStatusListProducerTest { // Assert val expected = AccountStatusList( userWalletId = userWalletId, - accountStatuses = setOf( + accountStatuses = listOf( AccountStatus.CryptoPortfolio( account = accountList.mainAccount, tokenList = TokenList.Empty, @@ -110,7 +110,7 @@ class DefaultSingleAccountStatusListProducerTest { // Assert (first emission) val expected = AccountStatusList( userWalletId = userWalletId, - accountStatuses = setOf( + accountStatuses = listOf( AccountStatus.CryptoPortfolio( account = accountList.mainAccount, tokenList = TokenList.Empty, @@ -129,7 +129,7 @@ class DefaultSingleAccountStatusListProducerTest { // Assert (second emission) val expected2 = AccountStatusList( userWalletId = userWalletId, - accountStatuses = setOf( + accountStatuses = listOf( AccountStatus.CryptoPortfolio( account = updatedAccountList.mainAccount, tokenList = TokenList.Empty, @@ -159,7 +159,7 @@ class DefaultSingleAccountStatusListProducerTest { val expected = AccountStatusList( userWalletId = userWalletId, - accountStatuses = setOf( + accountStatuses = listOf( AccountStatus.CryptoPortfolio( account = accountList.mainAccount, tokenList = TokenList.Empty, @@ -198,7 +198,7 @@ class DefaultSingleAccountStatusListProducerTest { cryptoCurrencies = cryptoCurrencyFactory.ethereumAndStellar.toSet(), ) - coEvery { userWalletsListRepository.userWalletsSync() } returns listOf(userWallet) + coEvery { accountsCRUDRepository.getUserWallets() } returns flowOf(listOf(userWallet)) every { singleAccountListSupplier(params = SingleAccountListProducer.Params(userWalletId)) @@ -226,7 +226,7 @@ class DefaultSingleAccountStatusListProducerTest { // Assert val expected = AccountStatusList( userWalletId = userWalletId, - accountStatuses = setOf( + accountStatuses = listOf( AccountStatus.CryptoPortfolio( account = accountList.mainAccount, tokenList = TokenList.Ungrouped( diff --git a/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/usecase/GetAccountCurrencyStatusUseCaseTest.kt b/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/usecase/GetAccountCurrencyStatusUseCaseTest.kt index 7adf3a3264..2105cce1ee 100644 --- a/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/usecase/GetAccountCurrencyStatusUseCaseTest.kt +++ b/domain/account/status/src/test/kotlin/com/tangem/domain/account/status/usecase/GetAccountCurrencyStatusUseCaseTest.kt @@ -79,7 +79,7 @@ class GetAccountCurrencyStatusUseCaseTest { ) val accountStatusList = mockk(relaxed = true) { - every { this@mockk.accountStatuses } returns setOf(accountStatus) + every { this@mockk.accountStatuses } returns listOf(accountStatus) } coEvery { supplier.getSyncOrNull(supplierParams) } returns accountStatusList @@ -117,7 +117,7 @@ class GetAccountCurrencyStatusUseCaseTest { ) val accountStatusList = mockk(relaxed = true) { - every { this@mockk.accountStatuses } returns setOf(mainAccountStatus, accountStatus, mockk()) + every { this@mockk.accountStatuses } returns listOf(mainAccountStatus, accountStatus, mockk()) } coEvery { supplier.getSyncOrNull(supplierParams) } returns accountStatusList @@ -154,7 +154,7 @@ class GetAccountCurrencyStatusUseCaseTest { ) val accountStatusList = mockk(relaxed = true) { - every { this@mockk.accountStatuses } returns setOf(accountStatus) + every { this@mockk.accountStatuses } returns listOf(accountStatus) } coEvery { supplier.getSyncOrNull(supplierParams) } returns accountStatusList @@ -198,7 +198,7 @@ class GetAccountCurrencyStatusUseCaseTest { ) val accountStatusList = mockk(relaxed = true) { - every { this@mockk.accountStatuses } returns setOf(accountStatus) + every { this@mockk.accountStatuses } returns listOf(accountStatus) } coEvery { supplier(supplierParams) } returns flowOf(accountStatusList) @@ -237,7 +237,7 @@ class GetAccountCurrencyStatusUseCaseTest { ) val accountStatusList = mockk(relaxed = true) { - every { this@mockk.accountStatuses } returns setOf(mainAccountStatus, accountStatus, mockk()) + every { this@mockk.accountStatuses } returns listOf(mainAccountStatus, accountStatus, mockk()) } coEvery { supplier(supplierParams) } returns flowOf(accountStatusList) @@ -271,7 +271,7 @@ class GetAccountCurrencyStatusUseCaseTest { ) val accountStatusList = mockk(relaxed = true) { - every { this@mockk.accountStatuses } returns setOf(accountStatus) + every { this@mockk.accountStatuses } returns listOf(accountStatus) } coEvery { supplier(supplierParams) } returns flowOf(accountStatusList) diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/add/api/AvailableToAddData.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/add/api/AvailableToAddData.kt index 9ca10389a9..557fd53518 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/add/api/AvailableToAddData.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/add/api/AvailableToAddData.kt @@ -20,7 +20,7 @@ internal data class AvailableToAddData( internal data class AvailableToAddWallet( val userWallet: UserWallet, - val accounts: Set, + val accounts: List, val availableNetworks: Set, val availableToAddAccounts: Map, )