Updated on 2026-08-14
This commit is contained in:
parent
3aef6bf69c
commit
b340fc7e33
18 changed files with 357 additions and 107 deletions
|
|
@ -6,8 +6,8 @@ import com.tangem.data.common.network.NetworkFactory
|
|||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
|
|
@ -18,7 +18,7 @@ import javax.inject.Inject
|
|||
/**
|
||||
* Factory to create default [GetWalletAccountsResponse].
|
||||
*
|
||||
* @property userWalletsListRepository repository to get user wallet information
|
||||
* @property userWalletsStore store to get user wallet information
|
||||
* @property cryptoPortfolioCF converter factory to convert crypto portfolio accounts
|
||||
* @property userTokensResponseFactory factory to create [UserTokensResponse]
|
||||
* @property networkFactory factory to create network derivation path
|
||||
|
|
@ -26,14 +26,14 @@ import javax.inject.Inject
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultWalletAccountsResponseFactory @Inject constructor(
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val cryptoPortfolioCF: CryptoPortfolioConverter.Factory,
|
||||
private val userTokensResponseFactory: UserTokensResponseFactory,
|
||||
private val networkFactory: NetworkFactory,
|
||||
) {
|
||||
|
||||
suspend fun create(userWalletId: UserWalletId, userTokensResponse: UserTokensResponse?): GetWalletAccountsResponse {
|
||||
val userWallet = userWalletsListRepository.userWalletsSync().firstOrNull { it.walletId == userWalletId }
|
||||
fun create(userWalletId: UserWalletId, userTokensResponse: UserTokensResponse?): GetWalletAccountsResponse {
|
||||
val userWallet = userWalletsStore.getSyncOrNull(userWalletId)
|
||||
|
||||
val accountDTOs = userWallet?.let(::createDefaultAccountDTOs).orEmpty()
|
||||
val response = userTokensResponse.orDefault(userWallet = userWallet)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.tangem.data.common.currency.UserTokensResponseFactory
|
|||
import com.tangem.data.common.network.NetworkFactory
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -23,14 +23,14 @@ import org.junit.jupiter.api.TestInstance
|
|||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class DefaultWalletAccountsResponseFactoryTest {
|
||||
|
||||
private val userWalletsListRepository = mockk<UserWalletsListRepository>()
|
||||
private val userWalletsStore = mockk<UserWalletsStore>()
|
||||
private val cryptoPortfolioCF = mockk<CryptoPortfolioConverter.Factory>()
|
||||
private val cryptoPortfolioConverter = mockk<CryptoPortfolioConverter>()
|
||||
private val userTokensResponseFactory = mockk<UserTokensResponseFactory>()
|
||||
private val networkFactory = mockk<NetworkFactory>()
|
||||
|
||||
private val factory = DefaultWalletAccountsResponseFactory(
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
userWalletsStore = userWalletsStore,
|
||||
cryptoPortfolioCF = cryptoPortfolioCF,
|
||||
userTokensResponseFactory = userTokensResponseFactory,
|
||||
networkFactory = networkFactory,
|
||||
|
|
@ -46,7 +46,7 @@ class DefaultWalletAccountsResponseFactoryTest {
|
|||
@AfterEach
|
||||
fun tearDownEach() {
|
||||
clearMocks(
|
||||
userWalletsListRepository,
|
||||
userWalletsStore,
|
||||
cryptoPortfolioCF,
|
||||
cryptoPortfolioConverter,
|
||||
userTokensResponseFactory,
|
||||
|
|
@ -63,7 +63,7 @@ class DefaultWalletAccountsResponseFactoryTest {
|
|||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns emptyList()
|
||||
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns null
|
||||
every {
|
||||
userTokensResponseFactory.createDefaultResponse(
|
||||
userWallet = null,
|
||||
|
|
@ -88,7 +88,7 @@ class DefaultWalletAccountsResponseFactoryTest {
|
|||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerifyOrder {
|
||||
userWalletsListRepository.userWalletsSync()
|
||||
userWalletsStore.getSyncOrNull(userWalletId)
|
||||
userTokensResponseFactory.createDefaultResponse(
|
||||
userWallet = null,
|
||||
networkFactory = networkFactory,
|
||||
|
|
@ -107,7 +107,7 @@ class DefaultWalletAccountsResponseFactoryTest {
|
|||
val accounts = AccountList.empty(userWallet.walletId).accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns listOf(userWallet)
|
||||
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
||||
|
||||
val defaultResponse = UserTokensResponse(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
|
|
@ -142,7 +142,7 @@ class DefaultWalletAccountsResponseFactoryTest {
|
|||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerifyOrder {
|
||||
userWalletsListRepository.userWalletsSync()
|
||||
userWalletsStore.getSyncOrNull(userWalletId)
|
||||
cryptoPortfolioConverter.convertListBack(accounts)
|
||||
userTokensResponseFactory.createDefaultResponse(
|
||||
userWallet = userWallet,
|
||||
|
|
@ -162,7 +162,7 @@ class DefaultWalletAccountsResponseFactoryTest {
|
|||
val accounts = AccountList.empty(userWallet.walletId).accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns listOf(userWallet)
|
||||
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
||||
|
||||
val defaultResponse = UserTokensResponse(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
|
|
@ -203,7 +203,7 @@ class DefaultWalletAccountsResponseFactoryTest {
|
|||
every { walletId } returns userWalletId
|
||||
}
|
||||
val assignedTokens = listOf(mockk<CryptoCurrency.Token>(), mockk<CryptoCurrency.Token>())
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns listOf(userWallet)
|
||||
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
|
||||
val userTokensResponse = UserTokensResponse(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
|||
import com.tangem.domain.account.status.usecase.*
|
||||
import com.tangem.domain.account.status.utils.CryptoCurrencyBalanceFetcher
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
|
|
@ -34,12 +33,12 @@ internal object AccountStatusUseCaseModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun provideGetAccountCurrencyByAddressUseCase(
|
||||
userWalletsListRepository: UserWalletsListRepository,
|
||||
accountsCRUDRepository: AccountsCRUDRepository,
|
||||
multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
|
||||
singleAccountListSupplier: SingleAccountListSupplier,
|
||||
): GetAccountCurrencyByAddressUseCase {
|
||||
return GetAccountCurrencyByAddressUseCase(
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
accountsCRUDRepository = accountsCRUDRepository,
|
||||
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
|
||||
singleAccountListSupplier = singleAccountListSupplier,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,20 +3,23 @@ package com.tangem.domain.account.status.producer
|
|||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
/**
|
||||
* Produces a flow of [AccountStatusList] for multiple user wallets.
|
||||
*
|
||||
* @property params Parameters for the producer (currently unused).
|
||||
* @property userWalletsListRepository Repository to get the list of user wallets.
|
||||
* @property accountsCRUDRepository Repository to get the list of user wallets.
|
||||
* @property singleAccountStatusListSupplier Supplier to get the account status list for a single user wallet.
|
||||
* @property dispatchers Coroutine dispatcher provider for managing threading.
|
||||
*
|
||||
|
|
@ -24,7 +27,7 @@ import kotlinx.coroutines.flow.*
|
|||
*/
|
||||
internal class DefaultMultiAccountStatusListProducer @AssistedInject constructor(
|
||||
@Assisted val params: Unit,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val accountsCRUDRepository: AccountsCRUDRepository,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : MultiAccountStatusListProducer {
|
||||
|
|
@ -33,8 +36,7 @@ internal class DefaultMultiAccountStatusListProducer @AssistedInject constructor
|
|||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun produce(): Flow<List<AccountStatusList>> {
|
||||
return userWalletsListRepository.userWallets
|
||||
.filterNotNull()
|
||||
return accountsCRUDRepository.getUserWallets()
|
||||
.flatMapLatest { userWallets ->
|
||||
val flows = userWallets.map {
|
||||
singleAccountStatusListSupplier(
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
params = SingleAccountListProducer.Params(params.userWalletId),
|
||||
)
|
||||
|
||||
@Suppress("UnusedFlow")
|
||||
return accountListFlow.flatMapLatest { accountList ->
|
||||
val accountStatusFlows = accountList.accounts.mapNotNull { account ->
|
||||
if (account !is Account.CryptoPortfolio) return@mapNotNull null
|
||||
|
|
@ -62,11 +61,7 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
if (account.cryptoCurrencies.isEmpty()) {
|
||||
createEmptyAccountStatusFlow(account)
|
||||
} else {
|
||||
val userWallet = accountsCRUDRepository.getUserWallets()
|
||||
.mapNotNull { wallets ->
|
||||
wallets.find { it.walletId == params.userWalletId }
|
||||
}
|
||||
.first()
|
||||
val userWallet = accountsCRUDRepository.getUserWallet(userWalletId = params.userWalletId)
|
||||
|
||||
getAccountStatusFlow(
|
||||
userWallet = userWallet,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import arrow.core.raise.option
|
|||
import arrow.core.toNonEmptyListOrNull
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.account.producer.SingleAccountListProducer
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrency
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.getAddress
|
||||
|
|
@ -29,14 +29,14 @@ private typealias WalletIdWithNetworkId = Pair<UserWalletId, Network.ID>
|
|||
/**
|
||||
* Use case to retrieve an [AccountCryptoCurrency] based on a provided address.
|
||||
*
|
||||
* @property userWalletsListRepository Repository to access user wallets.
|
||||
* @property accountsCRUDRepository Repository to access user wallets.
|
||||
* @property multiNetworkStatusSupplier Supplier to get network status for multiple networks.
|
||||
* @property singleAccountListSupplier Supplier to get account lists for a single wallet.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class GetAccountCurrencyByAddressUseCase(
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val accountsCRUDRepository: AccountsCRUDRepository,
|
||||
private val multiNetworkStatusSupplier: MultiNetworkStatusSupplier,
|
||||
private val singleAccountListSupplier: SingleAccountListSupplier,
|
||||
) {
|
||||
|
|
@ -65,7 +65,7 @@ class GetAccountCurrencyByAddressUseCase(
|
|||
}
|
||||
|
||||
private fun OptionRaise.getUserWalletIds(): NonEmptyList<UserWalletId> {
|
||||
val userWalletIds = userWalletsListRepository.userWallets.value.orEmpty()
|
||||
val userWalletIds = accountsCRUDRepository.getUserWalletsSync()
|
||||
.filter(UserWallet::isMultiCurrency)
|
||||
.map(UserWallet::walletId)
|
||||
.toNonEmptyListOrNull()
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package com.tangem.domain.account.status.producer
|
|||
import com.google.common.truth.Truth
|
||||
import com.tangem.common.test.utils.getEmittedValues
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
|
|
@ -20,7 +20,7 @@ import org.junit.jupiter.api.TestInstance
|
|||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class DefaultMultiAccountStatusListProducerTest {
|
||||
|
||||
private val userWalletsListRepository: UserWalletsListRepository = mockk()
|
||||
private val accountsCRUDRepository: AccountsCRUDRepository = mockk()
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier = mockk()
|
||||
private val dispatchers = TestingCoroutineDispatcherProvider()
|
||||
|
||||
|
|
@ -36,14 +36,14 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
|
||||
private val producer = DefaultMultiAccountStatusListProducer(
|
||||
params = Unit,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
accountsCRUDRepository = accountsCRUDRepository,
|
||||
singleAccountStatusListSupplier = singleAccountStatusListSupplier,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
clearMocks(userWalletsListRepository, singleAccountStatusListSupplier)
|
||||
clearMocks(accountsCRUDRepository, singleAccountStatusListSupplier)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -52,7 +52,7 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
val wallets = listOf(userWallet1, userWallet2)
|
||||
val walletsFlow = MutableStateFlow(wallets)
|
||||
|
||||
every { userWalletsListRepository.userWallets } returns walletsFlow
|
||||
every { accountsCRUDRepository.getUserWallets() } returns walletsFlow
|
||||
val accountStatusList1 = mockk<AccountStatusList>()
|
||||
val accountStatusList2 = mockk<AccountStatusList>()
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
Truth.assertThat(actual).containsExactly(expected)
|
||||
|
||||
coVerify(ordering = Ordering.SEQUENCE) {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
singleAccountStatusListSupplier(
|
||||
params = SingleAccountStatusListProducer.Params(userWalletId1),
|
||||
)
|
||||
|
|
@ -90,7 +90,7 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
fun `produce returns empty flow if userWallets is empty list`() = runTest {
|
||||
// Arrange
|
||||
val walletsFlow = MutableStateFlow<List<UserWallet>>(emptyList())
|
||||
every { userWalletsListRepository.userWallets } returns walletsFlow
|
||||
every { accountsCRUDRepository.getUserWallets() } returns walletsFlow
|
||||
|
||||
// Act
|
||||
val actual = producer.produce().let(::getEmittedValues)
|
||||
|
|
@ -99,26 +99,27 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
Truth.assertThat(actual).isEmpty()
|
||||
|
||||
coVerify(ordering = Ordering.SEQUENCE) {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `produce returns empty flow if userWallets is null`() = runTest {
|
||||
// Arrange
|
||||
val walletsFlow = MutableStateFlow<List<UserWallet>?>(null)
|
||||
every { userWalletsListRepository.userWallets } returns walletsFlow
|
||||
|
||||
// Act
|
||||
val actual = producer.produce().let(::getEmittedValues)
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isEmpty()
|
||||
|
||||
coVerify(ordering = Ordering.SEQUENCE) {
|
||||
userWalletsListRepository.userWallets
|
||||
}
|
||||
}
|
||||
// TODO: uncomment after migration on UserWalletsListRepository
|
||||
// @Test
|
||||
// fun `produce returns empty flow if userWallets is null`() = runTest {
|
||||
// // Arrange
|
||||
// val walletsFlow = MutableStateFlow<List<UserWallet>?>(null)
|
||||
// every { accountsCRUDRepository.getUserWallets() } returns walletsFlow
|
||||
//
|
||||
// // Act
|
||||
// val actual = producer.produce().let(::getEmittedValues)
|
||||
//
|
||||
// // Assert
|
||||
// Truth.assertThat(actual).isEmpty()
|
||||
//
|
||||
// coVerify(ordering = Ordering.SEQUENCE) {
|
||||
// accountsCRUDRepository.getUserWallets()
|
||||
// }
|
||||
// }
|
||||
|
||||
@Test
|
||||
fun `flow will updated if userWallets are updated`() = runTest {
|
||||
|
|
@ -127,7 +128,7 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
val userWallet3 = mockk<UserWallet> { every { walletId } returns userWalletId3 }
|
||||
|
||||
val walletsFlow = MutableStateFlow(listOf(userWallet1, userWallet2))
|
||||
every { userWalletsListRepository.userWallets } returns walletsFlow
|
||||
every { accountsCRUDRepository.getUserWallets() } returns walletsFlow
|
||||
|
||||
val accountStatusList1 = mockk<AccountStatusList>()
|
||||
val accountStatusList2 = mockk<AccountStatusList>()
|
||||
|
|
@ -167,7 +168,7 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
Truth.assertThat(actual2).containsExactly(expected2)
|
||||
|
||||
coVerify(ordering = Ordering.SEQUENCE) {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
singleAccountStatusListSupplier(
|
||||
params = SingleAccountStatusListProducer.Params(userWalletId1),
|
||||
)
|
||||
|
|
@ -183,7 +184,7 @@ class DefaultMultiAccountStatusListProducerTest {
|
|||
singleAccountStatusListSupplier(
|
||||
params = SingleAccountStatusListProducer.Params(userWalletId3),
|
||||
)
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
singleAccountStatusListSupplier(
|
||||
params = SingleAccountStatusListProducer.Params(userWalletId1),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ class DefaultSingleAccountStatusListProducerTest {
|
|||
cryptoCurrencies = cryptoCurrencyFactory.ethereumAndStellar.toSet(),
|
||||
)
|
||||
|
||||
coEvery { accountsCRUDRepository.getUserWallets() } returns flowOf(listOf(userWallet))
|
||||
coEvery { accountsCRUDRepository.getUserWallet(userWalletId = userWalletId) } returns userWallet
|
||||
|
||||
every {
|
||||
singleAccountListSupplier(params = SingleAccountListProducer.Params(userWalletId))
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import com.tangem.common.test.utils.assertNone
|
|||
import com.tangem.common.test.utils.assertSome
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.account.producer.SingleAccountListProducer
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrency
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
|
|
@ -17,7 +17,6 @@ import com.tangem.domain.models.wallet.isMultiCurrency
|
|||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
|
@ -29,19 +28,19 @@ import org.junit.jupiter.api.TestInstance
|
|||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class GetAccountCurrencyByAddressUseCaseTest {
|
||||
|
||||
private val userWalletsListRepository: UserWalletsListRepository = mockk()
|
||||
private val accountsCRUDRepository: AccountsCRUDRepository = mockk()
|
||||
private val multiNetworkStatusSupplier: MultiNetworkStatusSupplier = mockk()
|
||||
private val singleAccountListSupplier: SingleAccountListSupplier = mockk()
|
||||
|
||||
private val useCase = GetAccountCurrencyByAddressUseCase(
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
accountsCRUDRepository = accountsCRUDRepository,
|
||||
multiNetworkStatusSupplier = multiNetworkStatusSupplier,
|
||||
singleAccountListSupplier = singleAccountListSupplier,
|
||||
)
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
clearMocks(userWalletsListRepository, multiNetworkStatusSupplier, singleAccountListSupplier)
|
||||
clearMocks(accountsCRUDRepository, multiNetworkStatusSupplier, singleAccountListSupplier)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -56,26 +55,27 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns None if userWalletIds is null`() = runTest {
|
||||
// Arrange
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(null)
|
||||
|
||||
// Act
|
||||
val actual = useCase(validAddress)
|
||||
|
||||
// Assert
|
||||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
}
|
||||
}
|
||||
// TODO: uncomment after migration on UserWalletsListRepository
|
||||
// @Test
|
||||
// fun `returns None if userWalletIds is null`() = runTest {
|
||||
// // Arrange
|
||||
// every { accountsCRUDRepository.getUserWalletsSync() } returns MutableStateFlow(null)
|
||||
//
|
||||
// // Act
|
||||
// val actual = useCase(validAddress)
|
||||
//
|
||||
// // Assert
|
||||
// assertNone(actual)
|
||||
//
|
||||
// coVerifySequence {
|
||||
// accountsCRUDRepository.getUserWalletsSync()
|
||||
// }
|
||||
// }
|
||||
|
||||
@Test
|
||||
fun `returns None if userWalletIds is empty list`() = runTest {
|
||||
// Arrange
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(emptyList())
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns emptyList()
|
||||
|
||||
// Act
|
||||
val actual = useCase(validAddress)
|
||||
|
|
@ -84,7 +84,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
every { isMultiCurrency } returns false
|
||||
}
|
||||
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(singleWallet))
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(singleWallet)
|
||||
|
||||
// Act
|
||||
val actual = useCase(validAddress)
|
||||
|
|
@ -104,14 +104,14 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns None if multiNetworkStatusSupplier returns null`() = runTest {
|
||||
// Arrange
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(multiUserWallet))
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(multiUserWallet)
|
||||
coEvery {
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
} returns null
|
||||
|
|
@ -123,7 +123,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
}
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
@Test
|
||||
fun `returns None if multiNetworkStatusSupplier returns empty list`() = runTest {
|
||||
// Arrange
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(multiUserWallet))
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(multiUserWallet)
|
||||
coEvery {
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
} returns emptySet()
|
||||
|
|
@ -143,7 +143,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
}
|
||||
}
|
||||
|
|
@ -156,7 +156,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
value = NetworkStatus.Unreachable(address = null),
|
||||
)
|
||||
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(multiUserWallet))
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(multiUserWallet)
|
||||
coEvery {
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
} returns setOf(networkStatus)
|
||||
|
|
@ -168,7 +168,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
}
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
value = NetworkStatus.Unreachable(address = validNetworkAddress),
|
||||
)
|
||||
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(multiUserWallet))
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(multiUserWallet)
|
||||
coEvery {
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
} returns setOf(networkStatus)
|
||||
|
|
@ -200,7 +200,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
singleAccountListSupplier.getSyncOrNull(
|
||||
params = SingleAccountListProducer.Params(userWalletId = userWalletId),
|
||||
|
|
@ -220,7 +220,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
)
|
||||
val accountList = AccountList.empty(userWalletId)
|
||||
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(multiUserWallet))
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(multiUserWallet)
|
||||
coEvery {
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
} returns setOf(networkStatus)
|
||||
|
|
@ -237,7 +237,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertNone(actual)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
singleAccountListSupplier.getSyncOrNull(
|
||||
params = SingleAccountListProducer.Params(userWalletId = userWalletId),
|
||||
|
|
@ -255,7 +255,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
)
|
||||
val accountList = AccountList.empty(userWalletId = userWalletId, cryptoCurrencies = setOf(currency))
|
||||
|
||||
every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(multiUserWallet))
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(multiUserWallet)
|
||||
coEvery {
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
} returns setOf(networkStatus)
|
||||
|
|
@ -273,7 +273,7 @@ class GetAccountCurrencyByAddressUseCaseTest {
|
|||
assertSome(actual, expected)
|
||||
|
||||
coVerifySequence {
|
||||
userWalletsListRepository.userWallets
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
multiNetworkStatusSupplier.getSyncOrNull(params = MultiNetworkStatusProducer.Params(userWalletId))
|
||||
singleAccountListSupplier.getSyncOrNull(
|
||||
params = SingleAccountListProducer.Params(userWalletId = userWalletId),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ sealed interface AccountStatus {
|
|||
/** The account associated with this status */
|
||||
val account: Account
|
||||
|
||||
/** Unique identifier of the account */
|
||||
val accountId: AccountId
|
||||
get() = account.accountId
|
||||
|
||||
/**
|
||||
* Represents the status of a crypto portfolio account
|
||||
*
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@ import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
|||
import com.tangem.feature.wallet.presentation.wallet.loaders.implementors.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class WalletContentLoaderFactory @Inject constructor(
|
||||
private val multiWalletContentLoaderFactory: MultiWalletContentLoaderFactory,
|
||||
private val singleWalletWithTokenContentLoaderFactory: SingleWalletWithTokenContentLoaderFactory,
|
||||
private val singleWalletWithTokenContentLoaderV2Factory: SingleWalletWithTokenContentLoaderV2.Factory,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val singleWalletContentLoaderFactory: SingleWalletContentLoaderFactory,
|
||||
private val singleWalletContentLoaderV2Factory: SingleWalletContentLoaderV2.Factory,
|
||||
|
|
@ -29,7 +31,11 @@ internal class WalletContentLoaderFactory @Inject constructor(
|
|||
multiWalletContentLoaderFactory.create(userWallet, clickIntents)
|
||||
}
|
||||
userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken() -> {
|
||||
singleWalletWithTokenContentLoaderFactory.create(userWallet, clickIntents)
|
||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
singleWalletWithTokenContentLoaderV2Factory.create(userWallet)
|
||||
} else {
|
||||
singleWalletWithTokenContentLoaderFactory.create(userWallet, clickIntents)
|
||||
}
|
||||
}
|
||||
userWallet is UserWallet.Cold && userWallet.scanResponse.cardTypesResolver.isVisaWallet() -> {
|
||||
visaWalletContentLoaderFactory.create(userWallet, clickIntents, isRefresh)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
||||
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
|
||||
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsSingleEventSender
|
||||
|
|
@ -16,8 +17,8 @@ import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenList
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
|
||||
@Deprecated("Use SingleWalletWithTokenContentLoaderV2 instead")
|
||||
@Suppress("LongParameterList")
|
||||
internal class SingleWalletWithTokenContentLoader(
|
||||
private val userWallet: UserWallet.Cold,
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
|||
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
|
||||
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsSingleEventSender
|
||||
|
|
@ -16,11 +17,11 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarnin
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO: Refactor
|
||||
@Suppress("LongParameterList")
|
||||
@Deprecated("Use SingleWalletWithTokenContentLoaderV2.Factory instead")
|
||||
@ModelScoped
|
||||
internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
|
||||
private val stateHolder: WalletStateController,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsSingleEventSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class SingleWalletWithTokenContentLoaderV2 @AssistedInject constructor(
|
||||
@Assisted private val userWallet: UserWallet.Cold,
|
||||
private val singleWalletWithTokenSubscriberFactory: SingleWalletWithTokenSubscriber.Factory,
|
||||
private val checkWalletWithFundsSubscriberFactory: CheckWalletWithFundsSubscriber.Factory,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val stateController: WalletStateController,
|
||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender,
|
||||
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
override fun create(): List<WalletSubscriber> = listOf(
|
||||
singleWalletWithTokenSubscriberFactory.create(userWallet),
|
||||
MultiWalletWarningsSubscriber(
|
||||
userWallet = userWallet,
|
||||
stateHolder = stateController,
|
||||
clickIntents = clickIntents,
|
||||
getMultiWalletWarningsFactory = getMultiWalletWarningsFactory,
|
||||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
walletWarningsSingleEventSender = walletWarningsSingleEventSender,
|
||||
),
|
||||
WalletDropDownItemsSubscriber(
|
||||
stateHolder = stateController,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
clickIntents = clickIntents,
|
||||
),
|
||||
checkWalletWithFundsSubscriberFactory.create(userWallet),
|
||||
)
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(userWallet: UserWallet.Cold): SingleWalletWithTokenContentLoaderV2
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.utils.getOrElse
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.tokenlist.TokenList
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTokenListErrorTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTokenListTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.TokenConverterParams
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Basic implementation of [WalletSubscriber] for wallet with accounts.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
|
||||
|
||||
abstract val accountDependencies: AccountDependencies
|
||||
abstract val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase
|
||||
abstract val stateController: WalletStateController
|
||||
abstract val clickIntents: WalletClickIntents
|
||||
|
||||
override val singleAccountStatusListSupplier: SingleAccountStatusListSupplier
|
||||
get() = accountDependencies.singleAccountStatusListSupplier
|
||||
|
||||
protected fun getAppCurrencyFlow(): Flow<AppCurrency> {
|
||||
return getSelectedAppCurrencyUseCase.invokeOrDefault()
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
protected fun updateState(
|
||||
accountList: AccountStatusList,
|
||||
appCurrency: AppCurrency,
|
||||
expandedAccounts: Set<AccountId>,
|
||||
isAccountMode: Boolean,
|
||||
yieldSupplyApyMap: Map<String, String> = emptyMap(),
|
||||
stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
|
||||
) {
|
||||
val accountFlattenCurrencies = accountList.flattenCurrencies()
|
||||
val mainAccount = accountList.mainAccount
|
||||
|
||||
when {
|
||||
!isAccountMode -> {
|
||||
val isMainAccountEmpty = mainAccount.tokenList.flattenCurrencies().isEmpty()
|
||||
val maybeTokenList = if (isMainAccountEmpty) {
|
||||
Lce.Error(TokenListError.EmptyTokens)
|
||||
} else {
|
||||
Lce.Content(mainAccount.tokenList)
|
||||
}
|
||||
|
||||
singleAccountTransform(
|
||||
maybeTokenList = maybeTokenList,
|
||||
appCurrency = appCurrency,
|
||||
portfolioId = PortfolioId(mainAccount.accountId),
|
||||
yieldSupplyApyMap = yieldSupplyApyMap,
|
||||
stakingApyMap = stakingApyMap,
|
||||
)
|
||||
}
|
||||
isAccountMode -> {
|
||||
val isAllAccountsEmpty = accountFlattenCurrencies.isEmpty()
|
||||
if (isAllAccountsEmpty) {
|
||||
stateController.update(
|
||||
SetTokenListErrorTransformer(
|
||||
selectedWallet = userWallet,
|
||||
error = TokenListError.EmptyTokens,
|
||||
appCurrency = appCurrency,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
val convertParams = TokenConverterParams.Account(accountList, expandedAccounts)
|
||||
|
||||
updateContent(convertParams, appCurrency, yieldSupplyApyMap, stakingApyMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun singleAccountTransform(
|
||||
maybeTokenList: Lce<TokenListError, TokenList>,
|
||||
appCurrency: AppCurrency,
|
||||
portfolioId: PortfolioId,
|
||||
yieldSupplyApyMap: Map<String, String> = emptyMap(),
|
||||
stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
|
||||
) {
|
||||
val tokenList = maybeTokenList.getOrElse(
|
||||
ifLoading = { maybeContent ->
|
||||
val isRefreshing = stateController.getWalletState(userWallet.walletId)
|
||||
?.pullToRefreshConfig
|
||||
?.isRefreshing == true
|
||||
|
||||
maybeContent
|
||||
?.takeIf { !isRefreshing }
|
||||
?: return
|
||||
},
|
||||
ifError = { e ->
|
||||
Timber.e("Failed to load token list: $e")
|
||||
stateController.update(
|
||||
SetTokenListErrorTransformer(
|
||||
selectedWallet = userWallet,
|
||||
error = e,
|
||||
appCurrency = appCurrency,
|
||||
),
|
||||
)
|
||||
return
|
||||
},
|
||||
)
|
||||
|
||||
updateContent(
|
||||
params = TokenConverterParams.Wallet(portfolioId, tokenList),
|
||||
appCurrency = appCurrency,
|
||||
yieldSupplyApyMap = yieldSupplyApyMap,
|
||||
stakingApyMap = stakingApyMap,
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateContent(
|
||||
params: TokenConverterParams,
|
||||
appCurrency: AppCurrency,
|
||||
yieldSupplyApyMap: Map<String, String> = emptyMap(),
|
||||
stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
|
||||
) {
|
||||
stateController.update(
|
||||
SetTokenListTransformer(
|
||||
params = params,
|
||||
userWallet = userWallet,
|
||||
appCurrency = appCurrency,
|
||||
clickIntents = clickIntents,
|
||||
yieldSupplyApyMap = yieldSupplyApyMap,
|
||||
stakingApyMap = stakingApyMap,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,9 @@ import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
|
|
@ -13,11 +16,12 @@ import kotlinx.coroutines.flow.*
|
|||
* @property userWallet The user wallet.
|
||||
* @property singleAccountStatusListSupplier Supplier for account status list.
|
||||
* @property walletWithFundsChecker The checker to notify when funds are detected.
|
||||
* @property dispatchers Coroutine dispatcher provider.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class CheckWalletWithFundsSubscriber(
|
||||
override val userWallet: UserWallet,
|
||||
internal class CheckWalletWithFundsSubscriber @AssistedInject constructor(
|
||||
@Assisted override val userWallet: UserWallet,
|
||||
override val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val walletWithFundsChecker: WalletWithFundsChecker,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -30,4 +34,9 @@ internal class CheckWalletWithFundsSubscriber(
|
|||
.onEach { walletWithFundsChecker.check(userWalletId = userWallet.walletId, currencies = it) }
|
||||
.flowOn(dispatchers.default)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(userWallet: UserWallet): CheckWalletWithFundsSubscriber
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Deprecated("Use SingleWalletWithTokenSubscriber instead")
|
||||
@Suppress("LongParameterList")
|
||||
internal class SingleWalletWithTokenListSubscriber(
|
||||
override val userWallet: UserWallet.Cold,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
||||
internal class SingleWalletWithTokenSubscriber @AssistedInject constructor(
|
||||
@Assisted override val userWallet: UserWallet.Cold,
|
||||
override val accountDependencies: AccountDependencies,
|
||||
override val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
override val stateController: WalletStateController,
|
||||
override val clickIntents: WalletClickIntents,
|
||||
) : BasicAccountListSubscriber() {
|
||||
|
||||
override fun create(coroutineScope: CoroutineScope): Flow<Unit> = combine(
|
||||
flow = getAccountStatusListFlow(),
|
||||
flow2 = getAppCurrencyFlow(),
|
||||
flow3 = accountDependencies.expandedAccountsHolder.expandedAccounts(userWallet),
|
||||
flow4 = accountDependencies.isAccountsModeEnabledUseCase(),
|
||||
transform = ::updateState,
|
||||
)
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(userWallet: UserWallet.Cold): SingleWalletWithTokenSubscriber
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue