diff --git a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt index a4b7ff17e4..388a7df7b7 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/StakingDomainModule.kt @@ -168,4 +168,16 @@ internal object StakingDomainModule { stakingErrorResolver = stakingErrorResolver, ) } + + @Provides + @Singleton + fun provideIsAnyTokenStakedUseCase( + stakingRepository: StakingRepository, + stakingErrorResolver: StakingErrorResolver, + ): IsAnyTokenStakedUseCase { + return IsAnyTokenStakedUseCase( + stakingRepository = stakingRepository, + stakingErrorResolver = stakingErrorResolver, + ) + } } \ No newline at end of file diff --git a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt index c17d722c51..65b43686b3 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/DefaultStakingRepository.kt @@ -37,10 +37,7 @@ 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.UnsubmittedTransactionMetadata -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.* 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.StakingActionType @@ -516,6 +513,16 @@ internal class DefaultStakingRepository( } } + override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean { + return withContext(dispatchers.io) { + stakingBalanceStore.getSyncOrNull(userWalletId) + ?.let { + it.isNotEmpty() && it.any { yieldBalance -> yieldBalance.balances.isNotEmpty() } + } + ?: false + } + } + private suspend fun createActionRequestBody( userWalletId: UserWalletId, network: Network, diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/IsAnyTokenStakedUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/IsAnyTokenStakedUseCase.kt new file mode 100644 index 0000000000..33f4c0bc1d --- /dev/null +++ b/domain/staking/src/main/java/com/tangem/domain/staking/IsAnyTokenStakedUseCase.kt @@ -0,0 +1,18 @@ +package com.tangem.domain.staking + +import arrow.core.Either +import com.tangem.domain.staking.model.stakekit.StakingError +import com.tangem.domain.staking.repositories.StakingErrorResolver +import com.tangem.domain.staking.repositories.StakingRepository +import com.tangem.domain.wallets.models.UserWalletId + +class IsAnyTokenStakedUseCase( + private val stakingRepository: StakingRepository, + private val stakingErrorResolver: StakingErrorResolver, +) { + suspend operator fun invoke(userWalletId: UserWalletId): Either { + return Either + .catch { stakingRepository.isAnyTokenStaked(userWalletId) } + .mapLeft { stakingErrorResolver.resolve(it) } + } +} \ No newline at end of file diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt index f95af53048..aa35ac2b58 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/repositories/StakingRepository.kt @@ -83,4 +83,6 @@ interface StakingRepository { /** Returns staking approval */ fun getStakingApproval(cryptoCurrency: CryptoCurrency): StakingApproval + + suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt index 3000900a10..f9a6856ac9 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockStakingRepository.kt @@ -252,4 +252,6 @@ class MockStakingRepository : StakingRepository { } override fun getStakingApproval(cryptoCurrency: CryptoCurrency): StakingApproval = StakingApproval.Empty + + override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean = false } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt index bdf349c499..ca9f2e192b 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingUiState.kt @@ -57,6 +57,7 @@ internal sealed class StakingStates { sealed class InitialInfoState : StakingStates() { data class Data( override val isPrimaryButtonEnabled: Boolean, + val showBanner: Boolean, val infoItems: ImmutableList, val aprRange: TextReference, val onInfoClick: (InfoType) -> Unit, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt index c23cb74fda..72872ce0da 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt @@ -15,6 +15,7 @@ import kotlinx.collections.immutable.persistentListOf internal object InitialStakingStatePreview { val defaultState = StakingStates.InitialInfoState.Data( isPrimaryButtonEnabled = true, + showBanner = true, aprRange = stringReference("2.54-5.12%"), infoItems = persistentListOf( RoundedListWithDividersItemData( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt index f07d45346e..1156fc73a4 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt @@ -36,6 +36,7 @@ internal class SetInitialDataStateTransformer( private val clickIntents: StakingClickIntents, private val yield: Yield, private val isApprovalNeeded: Boolean, + private val isAnyTokenStaked: Boolean, private val cryptoCurrencyStatusProvider: Provider, private val userWalletProvider: Provider, private val appCurrencyProvider: Provider, @@ -79,12 +80,14 @@ internal class SetInitialDataStateTransformer( } private fun createInitialInfoState(): StakingStates.InitialInfoState.Data { + val yieldBalance = yieldBalancesConverter.convert(Unit) return StakingStates.InitialInfoState.Data( isPrimaryButtonEnabled = !cryptoCurrencyStatusProvider().value.amount.isNullOrZero(), + showBanner = !isAnyTokenStaked && yieldBalance == InnerYieldBalanceState.Empty, aprRange = getAprRange(yield.validators), infoItems = getInfoItems(), onInfoClick = clickIntents::onInfoClick, - yieldBalance = yieldBalancesConverter.convert(Unit), + yieldBalance = yieldBalance, ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index 530716b3fe..c4dbbd814e 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -75,7 +75,7 @@ internal fun StakingInitialInfoContent( .background(TangemTheme.colors.background.secondary) .padding(horizontal = TangemTheme.dimens.spacing16), ) { - if (state.yieldBalance == InnerYieldBalanceState.Empty) { + if (state.showBanner) { item(key = BANNER_BLOCK_KEY) { Column( modifier = Modifier.animateItemPlacement(), diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt index 43da4818a4..6e833d5ebb 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt @@ -105,6 +105,7 @@ internal class StakingViewModel @Inject constructor( private val validateTransactionUseCase: ValidateTransactionUseCase, private val getCurrencyCheckUseCase: GetCurrencyCheckUseCase, private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase, + private val isAnyTokenStakedUseCase: IsAnyTokenStakedUseCase, @DelayedWork private val coroutineScope: CoroutineScope, savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver, StakingClickIntents { @@ -713,6 +714,7 @@ internal class StakingViewModel @Inject constructor( getCryptoCurrencyStatusSyncUseCase(userWalletId, cryptoCurrencyId).fold( ifRight = { feeCryptoCurrencyStatus = getFeePaidCryptoCurrencyStatusSyncUseCase(userWalletId, it).getOrNull() + val isAnyTokenStaked = isAnyTokenStakedUseCase(userWalletId).getOrNull() ?: false cryptoCurrencyStatus = it setupApprovalNeeded() @@ -723,6 +725,7 @@ internal class StakingViewModel @Inject constructor( clickIntents = this@StakingViewModel, yield = yield, isApprovalNeeded = stakingApproval is StakingApproval.Needed, + isAnyTokenStaked = isAnyTokenStaked, cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, userWalletProvider = Provider { userWallet }, appCurrencyProvider = Provider { appCurrency },