Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-18 15:41:05 +05:00
parent 9127624b78
commit a6598eccc8
16 changed files with 156 additions and 149 deletions

View file

@ -1,15 +1,9 @@
package com.tangem.tap.di.domain
import com.tangem.domain.staking.*
import com.tangem.domain.staking.repositories.P2PEthPoolRepository
import com.tangem.domain.staking.repositories.StakeKitActionRepository
import com.tangem.domain.staking.repositories.StakingErrorResolver
import com.tangem.domain.staking.repositories.StakeKitRepository
import com.tangem.domain.staking.repositories.StakingRepository
import com.tangem.domain.staking.repositories.StakeKitTransactionHashRepository
import com.tangem.domain.staking.repositories.*
import com.tangem.domain.staking.single.SingleYieldBalanceFetcher
import com.tangem.domain.staking.toggles.StakingFeatureToggles
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.walletmanager.WalletManagersFacade
import dagger.Module
import dagger.Provides
@ -238,10 +232,7 @@ internal object StakingDomainModule {
@Provides
@Singleton
fun provideStakingApyFlowUseCase(
stakeKitRepository: StakeKitRepository,
stakingFeatureToggles: StakingFeatureToggles,
): StakingApyFlowUseCase {
return StakingApyFlowUseCase(stakeKitRepository, stakingFeatureToggles)
fun provideStakingApyFlowUseCase(stakingRepository: StakingRepository): StakingAvailabilityListUseCase {
return StakingAvailabilityListUseCase(stakingRepository)
}
}

View file

@ -1,6 +1,5 @@
package com.tangem.common.ui.tokens
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.ui.R
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
@ -22,7 +21,8 @@ import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.currency.yieldSupplyKey
import com.tangem.domain.models.staking.YieldBalance
import com.tangem.domain.staking.model.isStakingSupported
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.model.StakingOption
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
import com.tangem.lib.crypto.BlockchainUtils
@ -44,7 +44,7 @@ import java.math.BigDecimal
class TokenItemStateConverter(
private val appCurrency: AppCurrency,
private val yieldModuleApyMap: Map<String, BigDecimal> = emptyMap(),
private val stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
private val stakingApyMap: Map<CryptoCurrency, StakingAvailability> = emptyMap(),
private val yieldSupplyPromoBannerKey: String? = null,
private val iconStateProvider: (CryptoCurrencyStatus) -> CurrencyIconState = {
CryptoCurrencyToIconStateConverter().convert(it)
@ -177,7 +177,7 @@ class TokenItemStateConverter(
private fun createTitleState(
currencyStatus: CryptoCurrencyStatus,
yieldModuleApyMap: Map<String, BigDecimal>,
stakingApyMap: Map<String, List<Yield.Validator>>,
stakingApyMap: Map<CryptoCurrency, StakingAvailability>,
onApyLabelClick: ((CryptoCurrencyStatus, ApySource, String) -> Unit)?,
): TokenItemState.TitleState {
return when (val value = currencyStatus.value) {
@ -217,7 +217,7 @@ class TokenItemStateConverter(
private fun resolveEarnApy(
cryptoCurrencyStatus: CryptoCurrencyStatus,
yieldModuleApyMap: Map<String, BigDecimal>,
stakingApyMap: Map<String, List<Yield.Validator>>,
stakingApyMap: Map<CryptoCurrency, StakingAvailability>,
): EarnApyInfo? {
val token = cryptoCurrencyStatus.currency as? CryptoCurrency.Token
if (token != null && yieldModuleApyMap.isNotEmpty()) {
@ -272,46 +272,42 @@ class TokenItemStateConverter(
private fun findStakingRate(
currencyStatus: CryptoCurrencyStatus,
stakingApyMap: Map<String, List<Yield.Validator>>,
stakingApyMap: Map<CryptoCurrency, StakingAvailability>,
): StakingLocalInfo {
val stakingKey = currencyStatus.currency.stakingKey()
val validators = stakingApyMap[stakingKey]
val stakingAvailability = stakingApyMap[currencyStatus.currency] as? StakingAvailability.Available
?: return StakingLocalInfo(rate = null, isActive = false, rewardType = null)
val yieldBalance = currencyStatus.value.yieldBalance
val hasStakedBalance = yieldBalance is YieldBalance.Data
val rateInfo: Pair<BigDecimal, Yield.RewardType?>? = if (hasStakedBalance) {
val validatorsByAddress = validators.associateBy { it.address }
yieldBalance.balance.items
.mapNotNull { it.validatorAddress }
.firstNotNullOfOrNull { address ->
val validator = validatorsByAddress[address]
validator?.rewardInfo?.rate?.let { rate ->
rate to validator.rewardInfo?.type
}
}
?: validators
val rateInfo = when (val stakingOptions = stakingAvailability.option) {
is StakingOption.P2P -> null // todo p2p
is StakingOption.StakeKit -> if (hasStakedBalance) {
val validatorsByAddress = stakingOptions.yield.validators.associateBy { it.address }
yieldBalance.balance.items
.mapNotNull { it.validatorAddress }
.firstNotNullOfOrNull { address ->
validatorsByAddress[address]?.rewardInfo
} ?: stakingOptions.yield.validators
.filter { it.preferred }
.mapNotNull { validator ->
validator.rewardInfo?.rate?.let { rate -> rate to validator.rewardInfo?.type }
validator.rewardInfo
}
.maxByOrNull { it.first }
} else {
validators
.filter { it.preferred }
.mapNotNull { validator ->
validator.rewardInfo?.rate?.let { rate ->
rate to validator.rewardInfo?.type
.maxByOrNull { it.rate }
} else {
stakingOptions.yield.validators
.filter { it.preferred }
.mapNotNull { validator ->
validator.rewardInfo
}
}
.maxByOrNull { it.first }
.maxByOrNull { it.rate }
}
}
return StakingLocalInfo(
rate = rateInfo?.first,
rate = rateInfo?.rate,
isActive = hasStakedBalance,
rewardType = rateInfo?.second,
rewardType = rateInfo?.type,
)
}
@ -450,18 +446,6 @@ class TokenItemStateConverter(
}
fun CryptoCurrencyStatus.Value.isFlickering(): Boolean = sources.total == StatusSource.CACHE
private fun CryptoCurrency.stakingKey(): String {
if (this is CryptoCurrency.Coin && !network.isStakingSupported) return ""
if (network.isStakingSupported && this !is CryptoCurrency.Coin) {
val isPolygonTokenOnEthereum = this is CryptoCurrency.Token &&
this.network.id.rawId.value == Blockchain.Ethereum.id &&
this.symbol == Blockchain.Polygon.currency
if (!isPolygonTokenOnEthereum) return ""
}
return "${id.rawCurrencyId}_$symbol"
}
}
private data class StakingLocalInfo(

View file

@ -68,6 +68,27 @@ fun CoroutineScope.launchOnCancellation(block: suspend () -> Unit) {
}
}
@Suppress("LongParameterList", "MagicNumber")
inline fun <T1, T2, T3, T4, T5, T6, R> combine6(
flow1: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
flow6: Flow<T6>,
crossinline transform: suspend (T1, T2, T3, T4, T5, T6) -> R,
): Flow<R> = combine(flow1, flow2, flow3, flow4, flow5, flow6) { arr ->
@Suppress("UNCHECKED_CAST")
transform(
arr[0] as T1,
arr[1] as T2,
arr[2] as T3,
arr[3] as T4,
arr[4] as T5,
arr[5] as T6,
)
}
@Suppress("LongParameterList", "MagicNumber")
inline fun <T1, T2, T3, T4, T5, T6, T7, R> combine7(
flow1: Flow<T1>,

View file

@ -1,36 +0,0 @@
package com.tangem.domain.staking.usecase
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.toCoinId
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.repositories.StakeKitRepository
import com.tangem.domain.staking.toggles.StakingFeatureToggles
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
/**
* Emits a map of Validators values per currency for staking.
*
* Return map:
* - key: currency staking key (network.backendId + "_" + symbol)
* - value: validators
*/
class StakingApyFlowUseCase(
private val stakeKitRepository: StakeKitRepository,
private val stakingFeatureToggles: StakingFeatureToggles,
) {
operator fun invoke(): Flow<Map<String, List<Yield.Validator>>> {
return stakeKitRepository.getEnabledYields()
.map { yields ->
yields.filterNot { yield ->
val isCardanoYield = yield.token.coinGeckoId == Blockchain.Cardano.toCoinId()
isCardanoYield && !stakingFeatureToggles.isCardanoStakingEnabled
}.associate { yield ->
val key = "${yield.token.coinGeckoId}_${yield.token.symbol}"
val apy = yield.validators
key to apy
}
}
}
}

View file

@ -0,0 +1,37 @@
package com.tangem.domain.staking.usecase
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.repositories.StakingRepository
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
/**
* Returns staking availability for a list of crypto currencies for a specific user wallet
*
* Return map:
* - key: crypto currency
* - value: staking availability for the currency
*/
class StakingAvailabilityListUseCase(
private val stakingRepository: StakingRepository,
) {
suspend fun invokeSync(
userWalletId: UserWalletId,
cryptoCurrencyList: List<CryptoCurrency>,
): Map<CryptoCurrency, StakingAvailability> {
return coroutineScope {
cryptoCurrencyList.map { cryptoCurrency ->
async {
cryptoCurrency to stakingRepository.getStakingAvailabilitySync(
userWalletId = userWalletId,
cryptoCurrency = cryptoCurrency,
)
}
}.awaitAll().toMap()
}
}
}

View file

@ -5,7 +5,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.nft.GetNFTCollectionsUseCase
import com.tangem.domain.promo.GetStoryContentUseCase
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.repository.WalletsRepository
@ -45,7 +45,7 @@ internal class MultiWalletContentLoader(
private val walletsRepository: WalletsRepository,
private val currenciesRepository: CurrenciesRepository,
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
@ -64,7 +64,7 @@ internal class MultiWalletContentLoader(
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
stakingApyFlowUseCase = stakingApyFlowUseCase,
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
).let(::add)

View file

@ -5,7 +5,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.nft.GetNFTCollectionsUseCase
import com.tangem.domain.promo.GetStoryContentUseCase
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.repository.WalletsRepository
@ -44,7 +44,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
private val getNFTCollectionsUseCase: GetNFTCollectionsUseCase,
private val currenciesRepository: CurrenciesRepository,
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
@ -70,7 +70,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
getNFTCollectionsUseCase = getNFTCollectionsUseCase,
currenciesRepository = currenciesRepository,
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
stakingApyFlowUseCase = stakingApyFlowUseCase,
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
hotWalletFeatureToggles = hotWalletFeatureToggles,
tangemPayFeatureToggles = tangemPayFeatureToggles,
tangemPayMainSubscriberFactory = tangemPayMainSubscriberFactory,

View file

@ -3,7 +3,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.promo.GetStoryContentUseCase
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
@ -34,7 +34,7 @@ internal class SingleWalletWithTokenContentLoader(
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
private val getStoryContentUseCase: GetStoryContentUseCase,
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
) : WalletContentLoader(id = userWallet.walletId) {
@ -50,7 +50,7 @@ internal class SingleWalletWithTokenContentLoader(
tokenListStore = tokenListStore,
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
stakingApyFlowUseCase = stakingApyFlowUseCase,
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
).let(::add)
MultiWalletWarningsSubscriber(

View file

@ -4,7 +4,7 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.promo.GetStoryContentUseCase
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
@ -35,7 +35,7 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
private val getStoryContentUseCase: GetStoryContentUseCase,
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
) {
@ -55,7 +55,7 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
getStoryContentUseCase = getStoryContentUseCase,
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
stakingApyFlowUseCase = stakingApyFlowUseCase,
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
hotWalletFeatureToggles = hotWalletFeatureToggles,
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
)

View file

@ -1,8 +1,9 @@
package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
@ -19,7 +20,7 @@ internal class SetTokenListTransformer(
private val appCurrency: AppCurrency,
private val clickIntents: WalletClickIntents,
private val yieldSupplyApyMap: Map<String, BigDecimal> = emptyMap(),
private val stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
private val stakingAvailabilityMap: Map<CryptoCurrency, StakingAvailability> = emptyMap(),
private val shouldShowMainPromo: Boolean,
) : WalletStateTransformer(userWallet.walletId) {
@ -64,7 +65,7 @@ internal class SetTokenListTransformer(
appCurrency = appCurrency,
clickIntents = clickIntents,
yieldModuleApyMap = yieldSupplyApyMap,
stakingApyMap = stakingApyMap,
stakingAvailabilityMap = stakingAvailabilityMap,
shouldShowMainPromo = shouldShowMainPromo,
).convert(value = this)
}

View file

@ -14,11 +14,12 @@ import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.models.tokenlist.TokenList.GroupedByNetwork.NetworkGroup
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState
@ -38,7 +39,7 @@ internal class TokenListStateConverter(
private val selectedWallet: UserWallet,
private val clickIntents: WalletClickIntents,
private val yieldModuleApyMap: Map<String, BigDecimal>,
private val stakingApyMap: Map<String, List<Yield.Validator>>,
private val stakingAvailabilityMap: Map<CryptoCurrency, StakingAvailability>,
private val shouldShowMainPromo: Boolean,
) : Converter<WalletTokensListState, WalletTokensListState> {
@ -72,7 +73,7 @@ internal class TokenListStateConverter(
appCurrency = appCurrency,
yieldModuleApyMap = yieldModuleApyMap,
yieldSupplyPromoBannerKey = yieldSupplyPromoBannerKeyConverter.convert(params),
stakingApyMap = stakingApyMap,
stakingApyMap = stakingAvailabilityMap,
onItemClick = { _, status -> onTokenClick(accountId, status) },
onItemLongClick = { _, status -> onTokenLongClick(accountId, status) },
onApyLabelClick = { status, apySource, apy -> onApyLabelClick(status, apySource, apy) },

View file

@ -1,15 +1,15 @@
package com.tangem.feature.wallet.presentation.wallet.subscribers
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
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.utils.coroutines.combine7
import com.tangem.utils.coroutines.combine6
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@ -31,29 +31,36 @@ internal class AccountListSubscriber @AssistedInject constructor(
override val stateController: WalletStateController,
override val clickIntents: WalletClickIntents,
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
) : BasicAccountListSubscriber() {
override fun create(coroutineScope: CoroutineScope): Flow<*> = combine7(
override fun create(coroutineScope: CoroutineScope): Flow<*> = combine6(
flow1 = getAccountStatusListFlow(),
flow2 = getAppCurrencyFlow(),
flow3 = accountDependencies.expandedAccountsHolder.expandedAccounts(userWallet),
flow4 = accountDependencies.isAccountsModeEnabledUseCase(),
flow5 = yieldSupplyApyFlow(),
flow6 = stakingApyFlow(),
flow7 = yieldSupplyGetShouldShowMainPromoFlow(),
transform = ::updateState,
)
flow6 = yieldSupplyGetShouldShowMainPromoFlow(),
) { accountList, appCurrency, expandedAccounts, isAccountMode, yieldSupplyApyMap, shouldShowMainPromo ->
updateState(
accountList = accountList,
appCurrency = appCurrency,
expandedAccounts = expandedAccounts,
isAccountMode = isAccountMode,
yieldSupplyApyMap = yieldSupplyApyMap,
stakingAvailabilityMap = stakingAvailabilityListUseCase.invokeSync(
userWalletId = userWallet.walletId,
cryptoCurrencyList = accountList.flattenCurrencies().map(CryptoCurrencyStatus::currency),
),
shouldShowMainPromo = shouldShowMainPromo,
)
}
private fun yieldSupplyApyFlow(): Flow<Map<String, BigDecimal>> {
return yieldSupplyApyFlowUseCase().distinctUntilChanged()
}
private fun stakingApyFlow(): Flow<Map<String, List<Yield.Validator>>> {
return stakingApyFlowUseCase().distinctUntilChanged()
}
private fun yieldSupplyGetShouldShowMainPromoFlow(): Flow<Boolean> {
return yieldSupplyGetShouldShowMainPromoUseCase().distinctUntilChanged()
}

View file

@ -8,8 +8,9 @@ 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.currency.CryptoCurrency
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.StakingAvailability
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
@ -48,7 +49,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
expandedAccounts: Set<AccountId>,
isAccountMode: Boolean,
yieldSupplyApyMap: Map<String, BigDecimal> = emptyMap(),
stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
stakingAvailabilityMap: Map<CryptoCurrency, StakingAvailability> = emptyMap(),
shouldShowMainPromo: Boolean = false,
) {
val accountFlattenCurrencies = accountList.flattenCurrencies()
@ -68,7 +69,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
appCurrency = appCurrency,
portfolioId = PortfolioId(mainAccount.accountId),
yieldSupplyApyMap = yieldSupplyApyMap,
stakingApyMap = stakingApyMap,
stakingAvailabilityMap = stakingAvailabilityMap,
shouldShowMainPromo = shouldShowMainPromo,
)
}
@ -89,7 +90,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
params = convertParams,
appCurrency = appCurrency,
yieldSupplyApyMap = yieldSupplyApyMap,
stakingApyMap = stakingApyMap,
stakingAvailabilityMap = stakingAvailabilityMap,
shouldShowMainPromo = shouldShowMainPromo,
)
}
@ -102,7 +103,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
appCurrency: AppCurrency,
portfolioId: PortfolioId,
yieldSupplyApyMap: Map<String, BigDecimal> = emptyMap(),
stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
stakingAvailabilityMap: Map<CryptoCurrency, StakingAvailability> = emptyMap(),
shouldShowMainPromo: Boolean,
) {
val tokenList = maybeTokenList.getOrElse(
@ -132,7 +133,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
params = TokenConverterParams.Wallet(portfolioId, tokenList),
appCurrency = appCurrency,
yieldSupplyApyMap = yieldSupplyApyMap,
stakingApyMap = stakingApyMap,
stakingAvailabilityMap = stakingAvailabilityMap,
shouldShowMainPromo = shouldShowMainPromo,
)
}
@ -141,7 +142,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
params: TokenConverterParams,
appCurrency: AppCurrency,
yieldSupplyApyMap: Map<String, BigDecimal> = emptyMap(),
stakingApyMap: Map<String, List<Yield.Validator>> = emptyMap(),
stakingAvailabilityMap: Map<CryptoCurrency, StakingAvailability> = emptyMap(),
shouldShowMainPromo: Boolean,
) {
stateController.update(
@ -151,7 +152,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
appCurrency = appCurrency,
clickIntents = clickIntents,
yieldSupplyApyMap = yieldSupplyApyMap,
stakingApyMap = stakingApyMap,
stakingAvailabilityMap = stakingAvailabilityMap,
shouldShowMainPromo = shouldShowMainPromo,
),
)

View file

@ -8,11 +8,12 @@ import com.tangem.domain.core.lce.LceFlow
import com.tangem.domain.core.utils.getOrElse
import com.tangem.domain.models.PortfolioId
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
@ -41,7 +42,7 @@ internal abstract class BasicTokenListSubscriber(
private val walletWithFundsChecker: WalletWithFundsChecker,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
private val stakingApyFlowUseCase: StakingApyFlowUseCase,
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
) : WalletSubscriber() {
@ -71,9 +72,8 @@ internal abstract class BasicTokenListSubscriber(
},
flow2 = appCurrencyFlow(),
flow3 = yieldSupplyApyFlow(),
flow4 = stakingApyFlow(),
flow5 = yieldSupplyGetShouldShowMainPromoFlow(),
transform = { maybeTokenList, appCurrency, yieldSupplyApyMap, stakingApyMap, shouldShowMainPromo ->
flow4 = yieldSupplyGetShouldShowMainPromoFlow(),
transform = { maybeTokenList, appCurrency, yieldSupplyApyMap, shouldShowMainPromo ->
val tokenList = maybeTokenList.getOrElse(
ifLoading = { maybeContent ->
val isRefreshing = stateHolder.getWalletState(userWallet.walletId)
@ -101,7 +101,10 @@ internal abstract class BasicTokenListSubscriber(
params = TokenConverterParams.Wallet(PortfolioId(userWallet.walletId), tokenList),
appCurrency = appCurrency,
yieldSupplyApyMap = yieldSupplyApyMap,
stakingApyMap = stakingApyMap,
stakingAvailabilityMap = stakingAvailabilityListUseCase.invokeSync(
userWalletId = userWallet.walletId,
cryptoCurrencyList = tokenList.flattenCurrencies().map(CryptoCurrencyStatus::currency),
),
shouldShowMainPromo = shouldShowMainPromo,
)
@ -128,7 +131,7 @@ internal abstract class BasicTokenListSubscriber(
params: TokenConverterParams,
appCurrency: AppCurrency,
yieldSupplyApyMap: Map<String, BigDecimal>,
stakingApyMap: Map<String, List<Yield.Validator>>,
stakingAvailabilityMap: Map<CryptoCurrency, StakingAvailability>,
shouldShowMainPromo: Boolean,
) {
stateHolder.update(
@ -138,7 +141,7 @@ internal abstract class BasicTokenListSubscriber(
appCurrency = appCurrency,
clickIntents = clickIntents,
yieldSupplyApyMap = yieldSupplyApyMap,
stakingApyMap = stakingApyMap,
stakingAvailabilityMap = stakingAvailabilityMap,
shouldShowMainPromo = shouldShowMainPromo,
),
)
@ -156,9 +159,6 @@ internal abstract class BasicTokenListSubscriber(
private fun yieldSupplyApyFlow(): Flow<Map<String, BigDecimal>> = yieldSupplyApyFlowUseCase()
.distinctUntilChanged()
private fun stakingApyFlow(): Flow<Map<String, List<Yield.Validator>>> = stakingApyFlowUseCase()
.distinctUntilChanged()
private fun yieldSupplyGetShouldShowMainPromoFlow(): Flow<Boolean> = yieldSupplyGetShouldShowMainPromoUseCase()
.distinctUntilChanged()
}

View file

@ -8,7 +8,7 @@ import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
@ -32,7 +32,7 @@ internal class MultiWalletTokenListSubscriber(
walletWithFundsChecker: WalletWithFundsChecker,
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
stakingApyFlowUseCase: StakingApyFlowUseCase,
stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
) : BasicTokenListSubscriber(
userWallet = userWallet,
@ -42,7 +42,7 @@ internal class MultiWalletTokenListSubscriber(
walletWithFundsChecker = walletWithFundsChecker,
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
stakingApyFlowUseCase = stakingApyFlowUseCase,
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
) {

View file

@ -5,7 +5,7 @@ import com.tangem.domain.core.lce.Lce
import com.tangem.domain.core.lce.LceFlow
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.staking.usecase.StakingApyFlowUseCase
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
@ -27,7 +27,7 @@ internal class SingleWalletWithTokenListSubscriber(
walletWithFundsChecker: WalletWithFundsChecker,
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
stakingApyFlowUseCase: StakingApyFlowUseCase,
stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
) : BasicTokenListSubscriber(
userWallet = userWallet,
@ -37,7 +37,7 @@ internal class SingleWalletWithTokenListSubscriber(
walletWithFundsChecker = walletWithFundsChecker,
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
stakingApyFlowUseCase = stakingApyFlowUseCase,
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
) {