Updated on 2026-08-14
This commit is contained in:
parent
8491f524b9
commit
3519edfbfd
6 changed files with 154 additions and 2 deletions
|
|
@ -356,4 +356,18 @@ internal object TokensDomainModule {
|
|||
networksRepository = networksRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetWalletTotalBalanceUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
): GetWalletTotalBalanceUseCase {
|
||||
return GetWalletTotalBalanceUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
networksRepository = networksRepository,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -173,6 +173,23 @@ internal class DefaultCurrenciesRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getWalletCurrenciesUpdates(userWalletId: UserWalletId): LceFlow<Throwable, List<CryptoCurrency>> {
|
||||
return lceFlow {
|
||||
val userWallet = catch({ getUserWallet(userWalletId) }) {
|
||||
raise(it)
|
||||
}
|
||||
|
||||
if (userWallet.isMultiCurrency) {
|
||||
getMultiCurrencyWalletCurrenciesUpdatesLce(userWalletId).collect(::send)
|
||||
} else {
|
||||
val currency = catch({ getSingleCurrencyWalletPrimaryCurrency(userWalletId) }) {
|
||||
raise(it)
|
||||
}
|
||||
send(listOf(currency))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getSingleCurrencyWalletPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency {
|
||||
return withContext(dispatchers.io) {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
package com.tangem.domain.tokens
|
||||
|
||||
import arrow.core.raise.ensureNotNull
|
||||
import arrow.core.toNonEmptyListOrNull
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.lce.LceFlow
|
||||
import com.tangem.domain.core.lce.lce
|
||||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.TotalFiatBalance
|
||||
import com.tangem.domain.tokens.operations.CurrenciesStatusesLceOperations
|
||||
import com.tangem.domain.tokens.operations.TokenListFiatBalanceOperations
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.transform
|
||||
|
||||
class GetWalletTotalBalanceUseCase(
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val quotesRepository: QuotesRepository,
|
||||
private val networksRepository: NetworksRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWallestIds: Collection<UserWalletId>,
|
||||
): LceFlow<TokenListError, Map<UserWalletId, TotalFiatBalance>> {
|
||||
val flows = userWallestIds.distinct()
|
||||
.map { userWalletId ->
|
||||
invoke(userWalletId).map { maybeBalance ->
|
||||
userWalletId to maybeBalance
|
||||
}
|
||||
}
|
||||
|
||||
return combine(flows) { balances ->
|
||||
lce {
|
||||
balances.associate { (userWalletId, maybeBalance) ->
|
||||
userWalletId to maybeBalance.bind()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend operator fun invoke(userWalletId: UserWalletId): LceFlow<TokenListError, TotalFiatBalance> {
|
||||
val currenciesStatuses = getStatuses(userWalletId)
|
||||
|
||||
return currenciesStatuses.transform { maybeStatuses ->
|
||||
val balance = createBalance(maybeStatuses)
|
||||
|
||||
emit(balance)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createBalance(
|
||||
maybeStatuses: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||
): Lce<TokenListError, TotalFiatBalance> = lce {
|
||||
val statuses = maybeStatuses.bind()
|
||||
|
||||
val operations = TokenListFiatBalanceOperations(
|
||||
currencies = ensureNotNull(statuses.toNonEmptyListOrNull()) { lceLoading() },
|
||||
isAnyTokenLoading = false,
|
||||
)
|
||||
|
||||
operations.calculateFiatBalance()
|
||||
}
|
||||
|
||||
private fun getStatuses(userWalletId: UserWalletId): LceFlow<TokenListError, List<CryptoCurrencyStatus>> {
|
||||
val operations = CurrenciesStatusesLceOperations(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
networksRepository = networksRepository,
|
||||
)
|
||||
|
||||
return operations.getCurrenciesStatuses(
|
||||
userWalletId = userWalletId,
|
||||
isSingleCurrencyWalletsAllowed = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -21,8 +21,25 @@ internal class CurrenciesStatusesLceOperations(
|
|||
private val networksRepository: NetworksRepository,
|
||||
) {
|
||||
|
||||
fun getCurrenciesStatuses(userWalletId: UserWalletId): LceFlow<TokenListError, List<CryptoCurrencyStatus>> {
|
||||
return getMultiCurrencyWalletCurrencies(userWalletId).transform transform@{ maybeCurrencies ->
|
||||
fun getCurrenciesStatuses(
|
||||
userWalletId: UserWalletId,
|
||||
isSingleCurrencyWalletsAllowed: Boolean = false,
|
||||
): LceFlow<TokenListError, List<CryptoCurrencyStatus>> {
|
||||
return transformToCurrenciesStatuses(
|
||||
userWalletId = userWalletId,
|
||||
flow = if (isSingleCurrencyWalletsAllowed) {
|
||||
getWalletCurrenies(userWalletId)
|
||||
} else {
|
||||
getMultiCurrencyWalletCurrencies(userWalletId)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun transformToCurrenciesStatuses(
|
||||
userWalletId: UserWalletId,
|
||||
flow: LceFlow<TokenListError, List<CryptoCurrency>>,
|
||||
): LceFlow<TokenListError, List<CryptoCurrencyStatus>> {
|
||||
return flow.transform transform@{ maybeCurrencies ->
|
||||
val nonEmptyCurrencies = maybeCurrencies.fold(
|
||||
ifLoading = { maybeContent ->
|
||||
emit(createLoadingCurrenciesStatuses(maybeContent))
|
||||
|
|
@ -74,6 +91,13 @@ internal class CurrenciesStatusesLceOperations(
|
|||
return statuses
|
||||
}
|
||||
|
||||
private fun getWalletCurrenies(userWalletId: UserWalletId): LceFlow<TokenListError, List<CryptoCurrency>> {
|
||||
return currenciesRepository.getWalletCurrenciesUpdates(userWalletId)
|
||||
.map { maybeCurrencies ->
|
||||
maybeCurrencies.mapError { TokenListError.DataError(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMultiCurrencyWalletCurrencies(
|
||||
userWalletId: UserWalletId,
|
||||
): LceFlow<TokenListError, List<CryptoCurrency>> {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,17 @@ interface CurrenciesRepository {
|
|||
*/
|
||||
suspend fun removeCurrencies(userWalletId: UserWalletId, currencies: List<CryptoCurrency>)
|
||||
|
||||
/**
|
||||
* Retrieves the list of cryptocurrencies within a user wallet.
|
||||
*
|
||||
* This method returns a list of cryptocurrencies associated with the user wallet regardless of whether
|
||||
* it is a multi-currency or single-currency wallet.
|
||||
*
|
||||
* @param userWalletId The unique identifier of the user wallet.
|
||||
* @return A list of [CryptoCurrency].
|
||||
*/
|
||||
fun getWalletCurrenciesUpdates(userWalletId: UserWalletId): LceFlow<Throwable, List<CryptoCurrency>>
|
||||
|
||||
/**
|
||||
* Retrieves the primary cryptocurrency for a specific single-currency user wallet.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ internal class MockCurrenciesRepository(
|
|||
|
||||
override suspend fun removeCurrencies(userWalletId: UserWalletId, currencies: List<CryptoCurrency>) = Unit
|
||||
|
||||
override fun getWalletCurrenciesUpdates(userWalletId: UserWalletId): LceFlow<Throwable, List<CryptoCurrency>> {
|
||||
return emptyFlow()
|
||||
}
|
||||
|
||||
override suspend fun getMultiCurrencyWalletCurrenciesSync(
|
||||
userWalletId: UserWalletId,
|
||||
refresh: Boolean,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue