Updated on 2026-08-14
This commit is contained in:
parent
9bf6583723
commit
3631ceda60
4 changed files with 76 additions and 9 deletions
|
|
@ -4,6 +4,8 @@ import com.tangem.domain.models.account.Account
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
typealias AccountCryptoCurrencyStatuses = Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>>
|
||||
|
||||
/**
|
||||
* Combines an [Account] with its corresponding [CryptoCurrencyStatus].
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2,13 +2,17 @@ package com.tangem.domain.account.status.usecase
|
|||
|
||||
import arrow.core.Option
|
||||
import arrow.core.none
|
||||
import arrow.core.some
|
||||
import arrow.core.toOption
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatus
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatuses
|
||||
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.utils.AccountCryptoCurrencyStatusFinder
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -50,15 +54,28 @@ class GetAccountCurrencyStatusUseCase(
|
|||
currencyId: CryptoCurrency.ID,
|
||||
network: Network?,
|
||||
): Option<AccountCryptoCurrencyStatus> {
|
||||
val accountStatusList = singleAccountStatusListSupplier.getSyncOrNull(
|
||||
params = SingleAccountStatusListProducer.Params(userWalletId),
|
||||
) ?: return none()
|
||||
val accountStatusList = getAccountStatusListSync(userWalletId) ?: return none()
|
||||
|
||||
return accountStatusList
|
||||
.toAccountCryptoCurrencyStatus(currencyId, network)
|
||||
.toOption()
|
||||
}
|
||||
|
||||
suspend fun invokeSync(
|
||||
userWalletId: UserWalletId,
|
||||
currencies: List<CryptoCurrency>,
|
||||
): Option<AccountCryptoCurrencyStatuses> {
|
||||
if (currencies.isEmpty()) return emptyMap<Account.CryptoPortfolio, List<CryptoCurrencyStatus>>().some()
|
||||
|
||||
val accountStatusList = getAccountStatusListSync(userWalletId) ?: return none()
|
||||
|
||||
return AccountCryptoCurrencyStatusFinder(
|
||||
accountStatusList = accountStatusList,
|
||||
currencies = currencies,
|
||||
)
|
||||
.toOption()
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the status of a specific cryptocurrency for a given user wallet as a [Flow].
|
||||
*
|
||||
|
|
@ -91,6 +108,12 @@ class GetAccountCurrencyStatusUseCase(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun getAccountStatusListSync(userWalletId: UserWalletId): AccountStatusList? {
|
||||
return singleAccountStatusListSupplier.getSyncOrNull(
|
||||
params = SingleAccountStatusListProducer.Params(userWalletId),
|
||||
)
|
||||
}
|
||||
|
||||
private fun AccountStatusList.toAccountCryptoCurrencyStatus(
|
||||
currencyId: CryptoCurrency.ID,
|
||||
network: Network?,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatus
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatuses
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
|
|
@ -50,6 +51,26 @@ internal object AccountCryptoCurrencyStatusFinder {
|
|||
.firstOrNull()
|
||||
}
|
||||
|
||||
operator fun invoke(
|
||||
accountStatusList: AccountStatusList,
|
||||
currencies: List<CryptoCurrency>,
|
||||
): AccountCryptoCurrencyStatuses {
|
||||
if (currencies.isEmpty()) return emptyMap()
|
||||
|
||||
val currencyIds = currencies.map(CryptoCurrency::id).toSet()
|
||||
val networks = currencies.map(CryptoCurrency::network).distinct()
|
||||
|
||||
return accountStatusList.getExpectedAccountStatuses(networks)
|
||||
.asSequence()
|
||||
.filterIsInstance<AccountStatus.CryptoPortfolio>()
|
||||
.associate { accountStatus ->
|
||||
val statuses = accountStatus.flattenCurrencies()
|
||||
.filter { it.currency.id in currencyIds }
|
||||
|
||||
accountStatus.account to statuses
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the expected account statuses based on the provided [network].
|
||||
* If the [network] is null, all account statuses are returned.
|
||||
|
|
@ -79,6 +100,20 @@ internal object AccountCryptoCurrencyStatusFinder {
|
|||
}
|
||||
}
|
||||
|
||||
private fun AccountStatusList.getExpectedAccountStatuses(networks: List<Network>): List<AccountStatus> {
|
||||
val possibleAccountIndexes = networks.mapNotNull { it.getAccountIndexOrNull() }
|
||||
|
||||
if (possibleAccountIndexes.isEmpty()) return this@getExpectedAccountStatuses.accountStatuses
|
||||
|
||||
val accountStatuses = this@getExpectedAccountStatuses.accountStatuses.filter {
|
||||
val cryptoPortfolio = it.account as? Account.CryptoPortfolio ?: return@filter false
|
||||
|
||||
cryptoPortfolio.derivationIndex.value in possibleAccountIndexes
|
||||
}
|
||||
|
||||
return accountStatuses + listOf(mainAccount)
|
||||
}
|
||||
|
||||
private fun Network.getAccountIndexOrNull(): Int? {
|
||||
val blockchain = Blockchain.fromNetworkId(networkId = rawId) ?: return null
|
||||
val recognizer = AccountNodeRecognizer(blockchain)
|
||||
|
|
|
|||
|
|
@ -29,12 +29,19 @@ internal class AvailableToAddDataConverter @Inject constructor(
|
|||
marketParams: TokenMarketParams,
|
||||
): AvailableToAddData {
|
||||
suspend fun AccountStatus.getAvailableToAddAccount(wallet: UserWallet): AvailableToAddAccount {
|
||||
val addedNetworks = availableNetworks
|
||||
val currencies = availableNetworks
|
||||
.mapNotNull { createCryptoCurrency(wallet, it, marketParams, this.account) }
|
||||
// todo account poor performance, investigate, e.g 20 accounts and USDC token for adding
|
||||
.mapNotNull { getAccountCurrencyStatusUseCase.invokeSync(wallet.walletId, it) }
|
||||
.mapNotNull { it.getOrNull()?.status?.currency?.network }
|
||||
.toSet()
|
||||
|
||||
val addedNetworks = getAccountCurrencyStatusUseCase.invokeSync(wallet.walletId, currencies)
|
||||
.fold(
|
||||
ifEmpty = { emptySet() },
|
||||
ifSome = { map ->
|
||||
map.values.flatMapTo(hashSetOf()) { statuses ->
|
||||
statuses.map { it.currency.network }
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return AvailableToAddAccount(
|
||||
account = this,
|
||||
availableNetworks = availableNetworks,
|
||||
|
|
@ -62,7 +69,7 @@ internal class AvailableToAddDataConverter @Inject constructor(
|
|||
|
||||
val availableToAddWallets: Map<UserWalletId, AvailableToAddWallet> = balances
|
||||
.map {
|
||||
val (wallet, balance) = it
|
||||
val (wallet, _) = it
|
||||
val availableToAddWallet = getAvailableToAddWallet(it)
|
||||
wallet.walletId to availableToAddWallet
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue