Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-25 14:31:22 +04:00
parent 59b02e2e7a
commit 167ac28598
7 changed files with 35 additions and 86 deletions

View file

@ -14,7 +14,6 @@ import com.tangem.blockchainsdk.utils.toCoinId
import com.tangem.blockchainsdk.utils.toMigratedCoinId
import com.tangem.common.extensions.hexToBytes
import com.tangem.common.extensions.toCompressedPublicKey
import com.tangem.data.staking.converters.YieldBalanceListConverter
import com.tangem.data.staking.converters.YieldConverter
import com.tangem.data.staking.converters.action.ActionStatusConverter
import com.tangem.data.staking.converters.action.EnterActionResponseConverter
@ -45,7 +44,6 @@ import com.tangem.domain.staking.model.StakingEntryInfo
import com.tangem.domain.staking.model.stakekit.NetworkType
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
import com.tangem.domain.staking.model.stakekit.action.StakingAction
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.staking.model.stakekit.action.StakingActionStatus
@ -401,15 +399,13 @@ internal class DefaultStakingRepository(
override suspend fun getMultiYieldBalanceSync(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): YieldBalanceList {
): List<YieldBalance>? {
val stakingIds = cryptoCurrencies.mapNotNull {
stakingIdFactory.create(userWalletId = userWalletId, currencyId = it.id, network = it.network)
}
return stakingBalanceStoreV2.getAllSyncOrNull(userWalletId)
?.filter { it.getStakingId() in stakingIds }
?.let { YieldBalanceListConverter.convert(value = it.toSet()) }
?: YieldBalanceList.Error
}
override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean {

View file

@ -1,16 +0,0 @@
package com.tangem.data.staking.converters
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
import com.tangem.utils.converter.Converter
internal object YieldBalanceListConverter : Converter<Set<YieldBalance>, YieldBalanceList> {
override fun convert(value: Set<YieldBalance>): YieldBalanceList {
return if (value.isEmpty()) {
YieldBalanceList.Empty
} else {
YieldBalanceList.Data(balances = value.toList())
}
}
}

View file

@ -1,23 +0,0 @@
package com.tangem.domain.staking.model.stakekit
sealed class YieldBalanceList {
data class Data(val balances: List<YieldBalance>) : YieldBalanceList() {
fun getBalance(address: String?, integrationId: String?): YieldBalance {
return balances.firstOrNull { yieldBalance ->
val data = yieldBalance as? YieldBalance.Data
val balance = data?.balance
val isCorrectAddress = address != null && address == data?.address
val isCorrectIntegration = integrationId != null && balance?.integrationId == integrationId
isCorrectIntegration && isCorrectAddress
} ?: YieldBalance.Error(integrationId = integrationId, address = address)
}
}
data object Empty : YieldBalanceList()
data object Error : YieldBalanceList()
}

View file

@ -5,20 +5,19 @@ import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.staking.model.StakingApproval
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.model.StakingEntryInfo
import com.tangem.domain.staking.model.stakekit.NetworkType
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
import com.tangem.domain.staking.model.stakekit.action.StakingAction
import com.tangem.domain.staking.model.stakekit.action.StakingActionStatus
import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.domain.staking.model.stakekit.transaction.ActionParams
import com.tangem.domain.staking.model.stakekit.transaction.StakingGasEstimate
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
import com.tangem.domain.models.wallet.UserWalletId
import kotlinx.coroutines.flow.Flow
import java.math.BigDecimal
@ -54,7 +53,7 @@ interface StakingRepository {
suspend fun getMultiYieldBalanceSync(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): YieldBalanceList
): List<YieldBalance>?
suspend fun createAction(userWalletId: UserWalletId, network: Network, params: ActionParams): StakingAction

View file

@ -19,7 +19,6 @@ import com.tangem.domain.quotes.QuotesRepository
import com.tangem.domain.quotes.single.SingleQuoteStatusProducer
import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
import com.tangem.domain.staking.repositories.StakingRepository
import com.tangem.domain.staking.single.SingleYieldBalanceProducer
import com.tangem.domain.staking.single.SingleYieldBalanceSupplier
@ -396,17 +395,21 @@ abstract class BaseCurrencyStatusOperations(
private suspend fun getYieldBalancesSync(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): Either<Error.EmptyYieldBalances, YieldBalanceList> {
): Either<Error.EmptyYieldBalances, List<YieldBalance>> {
return catch(
block = {
stakingRepository.getMultiYieldBalanceSync(
val balances = stakingRepository.getMultiYieldBalanceSync(
userWalletId = userWalletId,
cryptoCurrencies = cryptoCurrencies,
).right()
},
catch = {
Error.EmptyYieldBalances.left()
)
if (balances.isNullOrEmpty()) {
Error.EmptyYieldBalances.left()
} else {
balances.right()
}
},
catch = { Error.EmptyYieldBalances.left() },
)
}

View file

@ -14,6 +14,7 @@ import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
@ -24,7 +25,7 @@ import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
import com.tangem.domain.quotes.single.SingleQuoteStatusProducer
import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
import com.tangem.domain.staking.model.stakekit.YieldBalance.Unsupported.integrationId
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
import com.tangem.domain.staking.repositories.StakingRepository
import com.tangem.domain.staking.single.SingleYieldBalanceProducer
@ -36,7 +37,6 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations.Error
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.utils.extractAddress
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.extensions.addOrReplace
import com.tangem.utils.extensions.isSingleItem
import kotlinx.coroutines.*
@ -128,9 +128,9 @@ class CachedCurrenciesStatusesOperations(
val (networks, currenciesIds) = getIds(currencies)
fun createCurrenciesStatuses(
maybeQuotes: Either<TokenListError, Set<QuoteStatus>>?,
maybeNetworkStatuses: Either<TokenListError, Set<NetworkStatus>>?,
maybeYieldBalances: Either<TokenListError, YieldBalanceList>?,
maybeQuotes: Either<TokenListError, Set<QuoteStatus>>,
maybeNetworkStatuses: Either<TokenListError, Set<NetworkStatus>>,
maybeYieldBalances: Either<TokenListError, List<YieldBalance>>,
isUpdating: Boolean,
) = createCurrenciesStatuses(
currencies = currencies,
@ -229,7 +229,7 @@ class CachedCurrenciesStatusesOperations(
currencies: NonEmptyList<CryptoCurrency>,
maybeQuotes: Either<TokenListError, Set<QuoteStatus>>?,
maybeNetworkStatuses: Either<TokenListError, Set<NetworkStatus>>?,
maybeYieldBalances: Either<TokenListError, YieldBalanceList>?,
maybeYieldBalances: Either<TokenListError, List<YieldBalance>>?,
isUpdating: Boolean,
): Lce<TokenListError, List<CryptoCurrencyStatus>> = lce {
isLoading.set(isUpdating)
@ -264,20 +264,20 @@ class CachedCurrenciesStatusesOperations(
}
private fun findYieldBalanceOrNull(
yieldBalances: YieldBalanceList?,
yieldBalances: List<YieldBalance>?,
currency: CryptoCurrency,
networkStatus: NetworkStatus?,
): YieldBalance? {
if (yieldBalances !is YieldBalanceList.Data) return null
if (yieldBalances.isNullOrEmpty()) return null
val supportedIntegration = stakingRepository.getSupportedIntegrationId(currency.id)
if (supportedIntegration.isNullOrBlank()) return null
return yieldBalances.getBalance(
address = extractAddress(networkStatus),
integrationId = supportedIntegration,
)
val address = extractAddress(networkStatus)
return yieldBalances.firstOrNull { it.integrationId == supportedIntegration && it.address == address }
?: YieldBalance.Error(integrationId = supportedIntegration, address = address)
}
private fun getCurrencies(userWalletId: UserWalletId): EitherFlow<TokenListError, List<CryptoCurrency>> {
@ -369,7 +369,7 @@ class CachedCurrenciesStatusesOperations(
private fun getYieldsBalancesUpdates(
userWalletId: UserWalletId,
cryptoCurrencies: List<CryptoCurrency>,
): EitherFlow<TokenListError, YieldBalanceList> {
): EitherFlow<TokenListError, List<YieldBalance>> {
return channelFlow {
val state = MutableStateFlow(emptyList<YieldBalance>())
@ -394,18 +394,9 @@ class CachedCurrenciesStatusesOperations(
}
state
.onEach(::send)
.onEach { send(it.right()) }
.launchIn(scope = this)
}
.map<List<YieldBalance>, Either<TokenListError, YieldBalanceList>> { balances ->
val yieldBalanceList = if (balances.isEmpty()) {
YieldBalanceList.Empty
} else {
YieldBalanceList.Data(balances)
}
yieldBalanceList.right()
}
.distinctUntilChanged()
}

View file

@ -8,7 +8,7 @@ import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.NetworkStatus
import com.tangem.domain.models.quote.QuoteStatus
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
import com.tangem.domain.staking.model.stakekit.YieldBalance.Unsupported.integrationId
import com.tangem.domain.staking.repositories.StakingRepository
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations.Error
@ -52,12 +52,12 @@ class CurrencyStatusProxyCreator(
fun createCurrenciesStatuses(
currencies: NonEmptyList<CryptoCurrency>,
maybeQuotes: Either<Error, Set<QuoteStatus>>?,
maybeNetworkStatuses: Either<Error, Set<NetworkStatus>>?,
maybeYieldBalances: Either<Error, YieldBalanceList>?,
maybeNetworkStatuses: Either<Error, Set<NetworkStatus>>,
maybeYieldBalances: Either<Error, List<YieldBalance>>,
): Either<Error, List<CryptoCurrencyStatus>> = either {
var quotesRetrievingFailed = false
val networksStatuses = maybeNetworkStatuses?.bind()?.toNonEmptySetOrNull()
val networksStatuses = maybeNetworkStatuses.bind().toNonEmptySetOrNull()
val quoteStatuses: Set<QuoteStatus>? = maybeQuotes?.fold(
ifLeft = {
quotesRetrievingFailed = true
@ -71,7 +71,7 @@ class CurrencyStatusProxyCreator(
},
)
val yieldBalances = maybeYieldBalances?.getOrNull()
val yieldBalances = maybeYieldBalances.getOrNull()
currencies.map { currency ->
val quote = quoteStatuses?.firstOrNull { it.rawCurrencyId == currency.id.rawCurrencyId }
@ -80,13 +80,12 @@ class CurrencyStatusProxyCreator(
val supportedIntegration = stakingRepository.getSupportedIntegrationId(currency.id)
val yieldBalance = if (supportedIntegration.isNullOrEmpty().not()) {
(yieldBalances as? YieldBalanceList.Data)?.getBalance(
address = address,
integrationId = supportedIntegration,
)
yieldBalances?.firstOrNull { it.integrationId == supportedIntegration && it.address == address }
?: YieldBalance.Error(integrationId = supportedIntegration, address = address)
} else {
null
}
createCurrencyStatus(
currency = currency,
quoteStatus = quote,