From 9ea256e5577b8d6dd3e3e4edc9f9353916b9f46b Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 16 Dec 2025 12:18:53 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/YieldSupplyDomainModule.kt | 13 +++++++-- .../res/drawable/ic_analytics_up_mini_24.xml | 13 +++++++++ domain/account/build.gradle.kts | 1 + domain/tokens/build.gradle.kts | 1 + .../tokens/GetCryptoCurrencyActionsUseCase.kt | 13 +++++++-- .../tokens/actions/BaseActionsFactory.kt | 10 +++++++ .../tokens/actions/CommonActionsFactory.kt | 7 +++++ .../actions/OutdatedDataActionsFactory.kt | 7 +++++ .../domain/tokens/model/TokenActionsState.kt | 5 ++++ .../supply/models/YieldSupplyAvailability.kt | 10 +++++++ .../YieldSupplyGetAvailabilityUseCase.kt | 26 +++++++++++++++++ features/markets/impl/build.gradle.kts | 2 ++ .../impl/analytics/PortfolioAnalyticsEvent.kt | 1 + .../impl/loader/PortfolioDataLoader.kt | 9 +++++- .../impl/model/PortfolioTokenUMConverter.kt | 9 ++++-- .../impl/model/TokenActionsHandler.kt | 29 ++++++++++++++++++- .../portfolio/impl/ui/state/QuickActionUM.kt | 9 ++++++ .../impl/ui/state/TokenActionsBSContentUM.kt | 4 +++ .../MultiWalletCurrencyActionsConverter.kt | 6 ++++ 19 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 core/ui/src/main/res/drawable/ic_analytics_up_mini_24.xml create mode 100644 domain/yield-supply/models/src/main/java/com/tangem/domain/yield/supply/models/YieldSupplyAvailability.kt create mode 100644 domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetAvailabilityUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt index b8c7e6dfc7..3301b9c21a 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt @@ -1,10 +1,10 @@ package com.tangem.tap.di.domain import com.tangem.domain.blockaid.BlockAidGasEstimate -import com.tangem.domain.transaction.FeeRepository -import com.tangem.domain.transaction.error.FeeErrorResolver import com.tangem.domain.quotes.QuotesRepository import com.tangem.domain.tokens.repository.CurrenciesRepository +import com.tangem.domain.transaction.FeeRepository +import com.tangem.domain.transaction.error.FeeErrorResolver import com.tangem.domain.yield.supply.YieldSupplyErrorResolver import com.tangem.domain.yield.supply.YieldSupplyRepository import com.tangem.domain.yield.supply.YieldSupplyTransactionRepository @@ -16,6 +16,7 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import javax.inject.Singleton +@Suppress("TooManyFunctions") @Module @InstallIn(SingletonComponent::class) internal object YieldSupplyDomainModule { @@ -225,4 +226,12 @@ internal object YieldSupplyDomainModule { fun provideYieldSupplyGetDustMinAmountUseCase(): YieldSupplyGetDustMinAmountUseCase { return YieldSupplyGetDustMinAmountUseCase() } + + @Provides + @Singleton + fun provideYieldSupplyGetAvailabilityUseCase( + yieldSupplyRepository: YieldSupplyRepository, + ): YieldSupplyGetAvailabilityUseCase { + return YieldSupplyGetAvailabilityUseCase(yieldSupplyRepository) + } } \ No newline at end of file diff --git a/core/ui/src/main/res/drawable/ic_analytics_up_mini_24.xml b/core/ui/src/main/res/drawable/ic_analytics_up_mini_24.xml new file mode 100644 index 0000000000..b7e8d62dff --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_analytics_up_mini_24.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/domain/account/build.gradle.kts b/domain/account/build.gradle.kts index da17a216f8..0d035a8fe5 100644 --- a/domain/account/build.gradle.kts +++ b/domain/account/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { api(projects.domain.core) api(projects.domain.models) api(projects.domain.wallets.models) + api(projects.domain.yieldSupply.models) implementation(deps.arrow.core) implementation(deps.kotlin.coroutines) diff --git a/domain/tokens/build.gradle.kts b/domain/tokens/build.gradle.kts index 68bfb40179..005eba3ef1 100644 --- a/domain/tokens/build.gradle.kts +++ b/domain/tokens/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { implementation(projects.domain.promo) implementation(projects.domain.networks) implementation(projects.domain.quotes) + implementation(projects.domain.yieldSupply.models) /** Project - Api */ implementation(projects.features.staking.api) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt index e219fbf94c..3fa0898e2b 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt @@ -17,6 +17,7 @@ import com.tangem.domain.tokens.actions.OutdatedDataActionsFactory import com.tangem.domain.tokens.actions.UnreachableActionsFactory import com.tangem.domain.tokens.model.TokenActionsState import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.yield.supply.models.YieldSupplyAvailability import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.* @@ -54,7 +55,11 @@ class GetCryptoCurrencyActionsUseCase( ) @OptIn(ExperimentalCoroutinesApi::class) - operator fun invoke(userWallet: UserWallet, cryptoCurrencyStatus: CryptoCurrencyStatus): Flow { + operator fun invoke( + userWallet: UserWallet, + cryptoCurrencyStatus: CryptoCurrencyStatus, + yieldSupplyAvailability: YieldSupplyAvailability = YieldSupplyAvailability.Unavailable, + ): Flow { return when { cryptoCurrencyStatus.value is CryptoCurrencyStatus.MissedDerivation -> { flowOf(value = MissedDerivationsActionsFactory.create()) @@ -74,11 +79,12 @@ class GetCryptoCurrencyActionsUseCase( userWalletId = userWallet.walletId, currency = cryptoCurrencyStatus.currency, ) - .mapLatest { + .mapLatest { stakingAvailability -> outdatedDataActionsFactory.create( userWallet = userWallet, cryptoCurrencyStatus = cryptoCurrencyStatus, - stakingAvailability = it, + stakingAvailability = stakingAvailability, + yieldSupplyAvailability = yieldSupplyAvailability, ) } } @@ -94,6 +100,7 @@ class GetCryptoCurrencyActionsUseCase( userWallet = userWallet, cryptoCurrencyStatus = cryptoCurrencyStatus, stakingAvailability = stakingAvailability, + yieldSupplyAvailability = yieldSupplyAvailability, shouldShowSwapStories = swapStoryContent != null, ) } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt index d18e2e36f4..c3850162db 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt @@ -11,6 +11,7 @@ import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason import com.tangem.domain.tokens.model.TokenActionsState.ActionState import com.tangem.domain.transaction.models.AssetRequirementsCondition import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.yield.supply.models.YieldSupplyAvailability import kotlinx.coroutines.Deferred import kotlinx.coroutines.withTimeoutOrNull @@ -193,4 +194,13 @@ internal open class BaseActionsFactory( is AssetRequirementsCondition.RequiredTrustline -> ScenarioUnavailabilityReason.TrustlineRequired } } + + protected fun ActionAvailabilityBuilder.addYieldSupplyAction(yieldSupplyAvailability: YieldSupplyAvailability) { + if (yieldSupplyAvailability is YieldSupplyAvailability.Available) { + ActionState.YieldMode( + unavailabilityReason = ScenarioUnavailabilityReason.None, + apy = yieldSupplyAvailability.apy, + ).addByReason() + } + } } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/CommonActionsFactory.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/CommonActionsFactory.kt index bef54bd155..3fb574d9e2 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/CommonActionsFactory.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/CommonActionsFactory.kt @@ -9,6 +9,7 @@ import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason import com.tangem.domain.tokens.model.TokenActionsState.ActionState import com.tangem.domain.transaction.models.AssetRequirementsCondition import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.yield.supply.models.YieldSupplyAvailability import kotlinx.coroutines.Deferred import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope @@ -32,12 +33,14 @@ internal class CommonActionsFactory( * @param userWallet the user's cold wallet * @param cryptoCurrencyStatus the status of the cryptocurrency * @param stakingAvailability the staking availability for the cryptocurrency + * @param yieldSupplyAvailability the yield supply availability for the cryptocurrency * @param shouldShowSwapStories a flag indicating whether to show swap stories */ suspend fun create( userWallet: UserWallet, cryptoCurrencyStatus: CryptoCurrencyStatus, stakingAvailability: StakingAvailability, + yieldSupplyAvailability: YieldSupplyAvailability, shouldShowSwapStories: Boolean, ): Set = coroutineScope { val isAddressAvailable = isAddressAvailable(cryptoCurrencyStatus.value.networkAddress) @@ -128,6 +131,10 @@ internal class CommonActionsFactory( // region HideToken addHideTokenAction() // endregion + + // region YieldMode + addYieldSupplyAction(yieldSupplyAvailability) + // endregion } } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/OutdatedDataActionsFactory.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/OutdatedDataActionsFactory.kt index f6ff91d2fd..308a2812bd 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/OutdatedDataActionsFactory.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/OutdatedDataActionsFactory.kt @@ -8,6 +8,7 @@ import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason import com.tangem.domain.tokens.model.TokenActionsState.ActionState import com.tangem.domain.walletmanager.WalletManagersFacade +import com.tangem.domain.yield.supply.models.YieldSupplyAvailability import kotlinx.coroutines.Deferred import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope @@ -31,11 +32,13 @@ internal class OutdatedDataActionsFactory( * @param userWallet the user's cold wallet * @param cryptoCurrencyStatus the status of the cryptocurrency * @param stakingAvailability the staking availability for the cryptocurrency + * @param yieldSupplyAvailability the yield supply availability for the cryptocurrency */ suspend fun create( userWallet: UserWallet, cryptoCurrencyStatus: CryptoCurrencyStatus, stakingAvailability: StakingAvailability, + yieldSupplyAvailability: YieldSupplyAvailability, ): Set = coroutineScope { val sources = cryptoCurrencyStatus.value.sources @@ -129,6 +132,10 @@ internal class OutdatedDataActionsFactory( // region HideToken addHideTokenAction() // endregion + + // region Yield Mode + addYieldSupplyAction(yieldSupplyAvailability) + // endregion } } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/model/TokenActionsState.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/model/TokenActionsState.kt index 1260157432..1cea4893f6 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/model/TokenActionsState.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/model/TokenActionsState.kt @@ -34,6 +34,11 @@ data class TokenActionsState( data class Send(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState() + data class YieldMode( + override val unavailabilityReason: ScenarioUnavailabilityReason, + val apy: String, + ) : ActionState() + data class Analytics(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState() data class HideToken(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState() diff --git a/domain/yield-supply/models/src/main/java/com/tangem/domain/yield/supply/models/YieldSupplyAvailability.kt b/domain/yield-supply/models/src/main/java/com/tangem/domain/yield/supply/models/YieldSupplyAvailability.kt new file mode 100644 index 0000000000..aa74eb5448 --- /dev/null +++ b/domain/yield-supply/models/src/main/java/com/tangem/domain/yield/supply/models/YieldSupplyAvailability.kt @@ -0,0 +1,10 @@ +package com.tangem.domain.yield.supply.models + +/** + * Represents the availability of yield supply for a given asset. + */ +sealed class YieldSupplyAvailability { + data class Available(val apy: String) : YieldSupplyAvailability() + + data object Unavailable : YieldSupplyAvailability() +} \ No newline at end of file diff --git a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetAvailabilityUseCase.kt b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetAvailabilityUseCase.kt new file mode 100644 index 0000000000..db9db0ea7e --- /dev/null +++ b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetAvailabilityUseCase.kt @@ -0,0 +1,26 @@ +package com.tangem.domain.yield.supply.usecase + +import arrow.core.Either +import com.tangem.domain.models.currency.CryptoCurrency +import com.tangem.domain.models.currency.yieldSupplyKey +import com.tangem.domain.yield.supply.YieldSupplyRepository +import com.tangem.domain.yield.supply.models.YieldSupplyAvailability + +class YieldSupplyGetAvailabilityUseCase( + private val yieldSupplyRepository: YieldSupplyRepository, +) { + + suspend operator fun invoke(currency: CryptoCurrency): Either = Either.catch { + val tokenCurrency = currency as? CryptoCurrency.Token ?: return@catch YieldSupplyAvailability.Unavailable + + val tokens = yieldSupplyRepository.getCachedMarkets().orEmpty() + val cachedStatus = tokens.firstOrNull { it.yieldSupplyKey == tokenCurrency.yieldSupplyKey() } + val yieldSupplyToken = cachedStatus ?: yieldSupplyRepository.getTokenStatus(tokenCurrency) + + if (yieldSupplyToken.isActive) { + YieldSupplyAvailability.Available(yieldSupplyToken.apy.toString()) + } else { + YieldSupplyAvailability.Unavailable + } + } +} \ No newline at end of file diff --git a/features/markets/impl/build.gradle.kts b/features/markets/impl/build.gradle.kts index ac6adcc8fb..24d38f3109 100644 --- a/features/markets/impl/build.gradle.kts +++ b/features/markets/impl/build.gradle.kts @@ -45,6 +45,8 @@ dependencies { implementation(projects.domain.settings) implementation(projects.domain.notifications.models) implementation(projects.domain.transaction) + implementation(projects.domain.yieldSupply.models) + implementation(projects.domain.yieldSupply) // FIXME [REDACTED_TASK_KEY] // Remove the "Buy" and "Sell" actions from the redux middleware. diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt index 772d83f651..a547351b4c 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt @@ -47,6 +47,7 @@ internal class PortfolioAnalyticsEvent( TokenActionsBSContentUM.Action.Receive -> "Button - Receive" TokenActionsBSContentUM.Action.Exchange -> "Button - Swap" TokenActionsBSContentUM.Action.Stake -> "Button - Stake" + TokenActionsBSContentUM.Action.YieldMode -> "Button - Yield Mode" else -> "error" }, params = buildMap { diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt index ff72822f09..d5522e7218 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt @@ -1,5 +1,6 @@ package com.tangem.features.markets.portfolio.impl.loader +import arrow.core.getOrElse import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.core.lce.Lce @@ -11,6 +12,8 @@ import com.tangem.domain.tokens.GetAllWalletsCryptoCurrencyStatusesUseCase import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase import com.tangem.domain.tokens.GetWalletTotalBalanceUseCase import com.tangem.domain.tokens.error.TokenListError +import com.tangem.domain.yield.supply.models.YieldSupplyAvailability +import com.tangem.domain.yield.supply.usecase.YieldSupplyGetAvailabilityUseCase import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.* import javax.inject.Inject @@ -30,6 +33,7 @@ internal class PortfolioDataLoader @Inject constructor( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, private val getWalletTotalBalanceUseCase: GetWalletTotalBalanceUseCase, + private val yieldSupplyGetAvailabilityUseCase: YieldSupplyGetAvailabilityUseCase, private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase, ) { @@ -72,7 +76,10 @@ internal class PortfolioDataLoader @Inject constructor( .flatMapLatest { walletsWithStatuses -> val actionsFlows = walletsWithStatuses.flatMap { (wallet, statuses) -> statuses.map { status -> - getCryptoCurrencyActionsUseCase(wallet, status) + val yieldSupplyAvailability = yieldSupplyGetAvailabilityUseCase(status.currency).getOrElse { + YieldSupplyAvailability.Unavailable + } + getCryptoCurrencyActionsUseCase(wallet, status, yieldSupplyAvailability) .map { PortfolioData.CryptoCurrencyData( userWallet = wallet, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt index ce68f5550d..b64ee6bf1f 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt @@ -71,8 +71,8 @@ internal class PortfolioTokenUMConverter( ): PortfolioTokenUM.QuickActions { return PortfolioTokenUM.QuickActions( actions = toQuickActions(cryptoData.actions), - onQuickActionClick = { - when (it) { + onQuickActionClick = { quickActionUM -> + when (quickActionUM) { QuickActionUM.Buy -> tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.Buy, cryptoCurrencyData = cryptoData, @@ -89,6 +89,10 @@ internal class PortfolioTokenUMConverter( action = TokenActionsBSContentUM.Action.Stake, cryptoCurrencyData = cryptoData, ) + is QuickActionUM.YieldMode -> tokenActionsHandler.handle( + action = TokenActionsBSContentUM.Action.YieldMode, + cryptoCurrencyData = cryptoData, + ) } }, onQuickActionLongClick = { @@ -110,6 +114,7 @@ internal class PortfolioTokenUMConverter( is TokenActionsState.ActionState.Swap -> QuickActionUM.Exchange(showBadge = action.showBadge) is TokenActionsState.ActionState.Receive -> QuickActionUM.Receive is TokenActionsState.ActionState.Stake -> QuickActionUM.Stake + is TokenActionsState.ActionState.YieldMode -> QuickActionUM.YieldMode(apy = action.apy) else -> null }?.let(::add) } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt index c8f42a8843..7561518e9f 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt @@ -15,11 +15,11 @@ import com.tangem.core.ui.message.SnackbarMessage import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.models.network.Network +import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.onramp.model.OnrampSource import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.tokens.legacy.TradeCryptoAction import com.tangem.domain.tokens.model.TokenActionsState -import com.tangem.domain.models.wallet.UserWallet import com.tangem.features.markets.impl.R import com.tangem.features.markets.portfolio.impl.loader.PortfolioData import com.tangem.features.markets.portfolio.impl.ui.state.TokenActionsBSContentUM @@ -65,6 +65,7 @@ internal class TokenActionsHandler @AssistedInject constructor( TokenActionsBSContentUM.Action.Sell -> onSellClick(cryptoCurrencyData) TokenActionsBSContentUM.Action.Send -> onSendClick(cryptoCurrencyData) TokenActionsBSContentUM.Action.Stake -> onStakeClick(cryptoCurrencyData) + TokenActionsBSContentUM.Action.YieldMode -> onYieldModeClick(cryptoCurrencyData) } } @@ -178,6 +179,32 @@ internal class TokenActionsHandler @AssistedInject constructor( ) } + private fun onYieldModeClick(cryptoCurrencyData: PortfolioData.CryptoCurrencyData) { + val yieldSupplyApy = cryptoCurrencyData.actions.filterIsInstance() + .firstOrNull()?.apy ?: return + + val (userWalletId, cryptoCurrencyStatus) = cryptoCurrencyData.let { currencyData -> + currencyData.userWallet.walletId to currencyData.status + } + if (cryptoCurrencyStatus.value.yieldSupplyStatus?.isActive == true) { + router.push( + AppRoute.YieldSupplyActive( + userWalletId = userWalletId, + cryptoCurrency = cryptoCurrencyStatus.currency, + apy = yieldSupplyApy, + ), + ) + } else { + router.push( + AppRoute.YieldSupplyPromo( + userWalletId = userWalletId, + cryptoCurrency = cryptoCurrencyStatus.currency, + apy = yieldSupplyApy, + ), + ) + } + } + @AssistedFactory interface Factory { fun create( diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/QuickActionUM.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/QuickActionUM.kt index ffb485d08c..e0987c16e7 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/QuickActionUM.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/QuickActionUM.kt @@ -4,6 +4,7 @@ import androidx.annotation.DrawableRes import androidx.compose.runtime.Immutable import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.wrappedList import com.tangem.features.markets.impl.R @Immutable @@ -39,4 +40,12 @@ internal sealed class QuickActionUM( description = resourceReference(R.string.stake_token_description), icon = R.drawable.ic_staking_24, ) + + data class YieldMode( + private val apy: String, + ) : QuickActionUM( + title = resourceReference(R.string.yield_module_start_earning), + description = resourceReference(R.string.yield_module_main_screen_promo_banner_message, wrappedList(apy)), + icon = R.drawable.ic_analytics_up_mini_24, + ) } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/TokenActionsBSContentUM.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/TokenActionsBSContentUM.kt index 83450b1ebc..078c25562f 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/TokenActionsBSContentUM.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/state/TokenActionsBSContentUM.kt @@ -47,6 +47,10 @@ internal data class TokenActionsBSContentUM( text = resourceReference(R.string.common_stake), iconRes = R.drawable.ic_staking_24, ), + YieldMode( + text = resourceReference(R.string.yield_module_start_earning), + iconRes = R.drawable.ic_analytics_up_mini_24, + ), ; val order: Int = ordinal diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt index c6ef0d9981..ad35b058ea 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCurrencyActionsConverter.kt @@ -42,6 +42,7 @@ internal class MultiWalletCurrencyActionsConverter( } } + @Suppress("LongMethod") private fun mapTokenActionState( actionsState: TokenActionsState.ActionState, cryptoCurrencyStatus: CryptoCurrencyStatus, @@ -105,6 +106,11 @@ internal class MultiWalletCurrencyActionsConverter( icon = R.drawable.ic_analytics_24 action = { clickIntents.onAnalyticsClick(cryptoCurrencyStatus) } } + is TokenActionsState.ActionState.YieldMode -> { + title = resourceReference(R.string.yield_module_start_earning) + icon = R.drawable.ic_analytics_up_mini_24 + action = { /* no-op */ } + } } return TokenActionButtonConfig(