Updated on 2026-08-14
This commit is contained in:
parent
5b832e2591
commit
69deadf5fe
3 changed files with 147 additions and 52 deletions
|
|
@ -3,19 +3,14 @@ package com.tangem.domain.account.status.usecase
|
|||
import arrow.core.Option
|
||||
import arrow.core.none
|
||||
import arrow.core.toOption
|
||||
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.producer.SingleAccountStatusListProducer
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.account.status.utils.AccountCryptoCurrencyStatusFinder
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.lib.crypto.derivation.AccountNodeRecognizer
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
|
|
@ -100,51 +95,10 @@ class GetAccountCurrencyStatusUseCase(
|
|||
currencyId: CryptoCurrency.ID,
|
||||
network: Network?,
|
||||
): AccountCryptoCurrencyStatus? {
|
||||
return getExpectedAccountStatuses(network)
|
||||
.asSequence()
|
||||
.filterIsInstance<AccountStatus.CryptoPortfolio>()
|
||||
.mapNotNull { accountStatus ->
|
||||
val status = accountStatus.flattenCurrencies().firstOrNull { it.currency.id == currencyId }
|
||||
?: return@mapNotNull null
|
||||
|
||||
AccountCryptoCurrencyStatus(account = accountStatus.account, status = status)
|
||||
}
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the expected account statuses based on the provided [network].
|
||||
* If the [network] is null, all account statuses are returned.
|
||||
* If the network has a specific derivation index, it filters the accounts accordingly.
|
||||
*
|
||||
* @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<AccountStatus> {
|
||||
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)
|
||||
// currency only in the account with specific derivation index or in the main account
|
||||
else -> {
|
||||
val accountStatus = accountStatuses.firstOrNull {
|
||||
val cryptoPortfolio = it.account as? Account.CryptoPortfolio ?: return@firstOrNull false
|
||||
|
||||
cryptoPortfolio.derivationIndex.value == possibleAccountIndex
|
||||
}
|
||||
|
||||
setOfNotNull(accountStatus, mainAccount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Network.getAccountIndexOrNull(): Int? {
|
||||
val blockchain = Blockchain.fromNetworkId(networkId = rawId) ?: return null
|
||||
val recognizer = AccountNodeRecognizer(blockchain)
|
||||
|
||||
return recognizer.recognize(derivationPath)?.toInt()
|
||||
return AccountCryptoCurrencyStatusFinder(
|
||||
accountStatusList = this,
|
||||
currencyId = currencyId,
|
||||
network = network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.tangem.domain.account.status.usecase
|
||||
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
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.AccountId
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
/**
|
||||
* Use case to retrieve the available actions for a specific cryptocurrency associated with an account.
|
||||
*
|
||||
* @property accountsCRUDRepository repository for account CRUD operations.
|
||||
* @property singleAccountStatusListSupplier supplier to get the list of account statuses.
|
||||
* @property getCryptoCurrencyActionsUseCase use case to get the actions for a specific cryptocurrency status.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class GetCryptoCurrencyActionsUseCaseV2(
|
||||
private val accountsCRUDRepository: AccountsCRUDRepository,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
) {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
operator fun invoke(accountId: AccountId, currency: CryptoCurrency): Flow<TokenActionsState> {
|
||||
return singleAccountStatusListSupplier(
|
||||
params = SingleAccountStatusListProducer.Params(userWalletId = accountId.userWalletId),
|
||||
)
|
||||
.transformLatest { accountStatusList ->
|
||||
val accountCurrencyStatus = AccountCryptoCurrencyStatusFinder(
|
||||
accountStatusList = accountStatusList,
|
||||
currency = currency,
|
||||
)
|
||||
|
||||
if (accountCurrencyStatus != null) {
|
||||
val userWallet = accountsCRUDRepository.getUserWallet(userWalletId = accountId.userWalletId)
|
||||
val actionsFlow = getCryptoCurrencyActionsUseCase(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrencyStatus = accountCurrencyStatus.status,
|
||||
)
|
||||
|
||||
emitAll(actionsFlow)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package com.tangem.domain.account.status.utils
|
||||
|
||||
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.models.account.Account
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.lib.crypto.derivation.AccountNodeRecognizer
|
||||
|
||||
/**
|
||||
* Finds the status of a specific cryptocurrency associated with an account from the provided account status list.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal object AccountCryptoCurrencyStatusFinder {
|
||||
|
||||
/**
|
||||
* Retrieves the [AccountCryptoCurrencyStatus] for the specified [currency] from the given [accountStatusList].
|
||||
*
|
||||
* @param accountStatusList the list of account statuses to search within.
|
||||
* @param currency the cryptocurrency whose status is to be retrieved.
|
||||
* @return the [AccountCryptoCurrencyStatus] if found, otherwise null.
|
||||
*/
|
||||
operator fun invoke(accountStatusList: AccountStatusList, currency: CryptoCurrency): AccountCryptoCurrencyStatus? {
|
||||
return invoke(
|
||||
accountStatusList = accountStatusList,
|
||||
currencyId = currency.id,
|
||||
network = currency.network,
|
||||
)
|
||||
}
|
||||
|
||||
operator fun invoke(
|
||||
accountStatusList: AccountStatusList,
|
||||
currencyId: CryptoCurrency.ID,
|
||||
network: Network?,
|
||||
): AccountCryptoCurrencyStatus? {
|
||||
return accountStatusList.getExpectedAccountStatuses(network)
|
||||
.asSequence()
|
||||
.filterIsInstance<AccountStatus.CryptoPortfolio>()
|
||||
.mapNotNull { accountStatus ->
|
||||
val status = accountStatus.flattenCurrencies().firstOrNull { it.currency.id == currencyId }
|
||||
?: return@mapNotNull null
|
||||
|
||||
AccountCryptoCurrencyStatus(account = accountStatus.account, status = status)
|
||||
}
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the expected account statuses based on the provided [network].
|
||||
* If the [network] is null, all account statuses are returned.
|
||||
* If the network has a specific derivation index, it filters the accounts accordingly.
|
||||
*
|
||||
* @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<AccountStatus> {
|
||||
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)
|
||||
// currency only in the account with specific derivation index or in the main account
|
||||
else -> {
|
||||
val accountStatus = accountStatuses.firstOrNull {
|
||||
val cryptoPortfolio = it.account as? Account.CryptoPortfolio ?: return@firstOrNull false
|
||||
|
||||
cryptoPortfolio.derivationIndex.value == possibleAccountIndex
|
||||
}
|
||||
|
||||
setOfNotNull(accountStatus, mainAccount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Network.getAccountIndexOrNull(): Int? {
|
||||
val blockchain = Blockchain.fromNetworkId(networkId = rawId) ?: return null
|
||||
val recognizer = AccountNodeRecognizer(blockchain)
|
||||
|
||||
return recognizer.recognize(derivationPath)?.toInt()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue