From 6f47c78b2337239b73c1a59fc1fbf1ba1031ba3e Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 10 Jul 2025 17:02:30 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/di/domain/StakingDomainModule.kt | 8 ++++++++ .../data/staking/DefaultStakingRepository.kt | 9 +++++++++ .../data/staking/utils/StakingIdFactory.kt | 2 ++ .../staking/GetActionRequirementAmountUseCase.kt | 16 ++++++++++++++++ .../staking/repositories/StakingRepository.kt | 7 +++++++ .../tokens/repository/MockStakingRepository.kt | 2 ++ .../impl/presentation/model/StakingModel.kt | 15 ++++++++++++++- .../presentation/state/InnerYieldBalanceState.kt | 1 + .../state/converters/YieldBalancesConverter.kt | 1 + .../previewdata/InitialStakingStatePreview.kt | 1 + gradle/tangem_dependencies.toml | 2 +- 11 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 domain/staking/src/main/java/com/tangem/domain/staking/GetActionRequirementAmountUseCase.kt 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 22f61dc1f1..c852c1ff14 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 @@ -224,4 +224,12 @@ internal object StakingDomainModule { ): CheckAccountInitializedUseCase { return CheckAccountInitializedUseCase(walletManagersFacade) } + + @Provides + @Singleton + fun provideGetActionRequirementAmountUseCase( + stakingRepository: StakingRepository, + ): GetActionRequirementAmountUseCase { + return GetActionRequirementAmountUseCase(stakingRepository) + } } \ 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 4c145ce44c..ac813e234c 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 @@ -72,6 +72,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeoutOrNull import timber.log.Timber +import java.math.BigDecimal import kotlin.time.Duration.Companion.seconds @Suppress("LargeClass", "LongParameterList", "TooManyFunctions") @@ -662,6 +663,14 @@ internal class DefaultStakingRepository( } } + override fun getActionRequirementAmount(integrationId: String, stakingActionType: StakingActionType): BigDecimal? { + return when { + stakingIdFactory.isPolygonIntegrationId(integrationId) && + stakingActionType == StakingActionType.CLAIM_REWARDS -> BigDecimal.ONE + else -> null + } + } + private suspend fun createActionRequestBody( userWalletId: UserWalletId, network: Network, diff --git a/data/staking/src/main/java/com/tangem/data/staking/utils/StakingIdFactory.kt b/data/staking/src/main/java/com/tangem/data/staking/utils/StakingIdFactory.kt index d1b760b601..b27a5c5061 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/utils/StakingIdFactory.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/utils/StakingIdFactory.kt @@ -35,6 +35,8 @@ internal class StakingIdFactory @Inject constructor( return integrationIdMap[integrationKey] } + fun isPolygonIntegrationId(integrationId: String): Boolean = integrationId == ETHEREUM_POLYGON_INTEGRATION_ID + @Suppress("UnusedPrivateMember", "unused") companion object { diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/GetActionRequirementAmountUseCase.kt b/domain/staking/src/main/java/com/tangem/domain/staking/GetActionRequirementAmountUseCase.kt new file mode 100644 index 0000000000..34d0c03b27 --- /dev/null +++ b/domain/staking/src/main/java/com/tangem/domain/staking/GetActionRequirementAmountUseCase.kt @@ -0,0 +1,16 @@ +package com.tangem.domain.staking + +import arrow.core.Either +import com.tangem.domain.staking.model.stakekit.action.StakingActionType +import com.tangem.domain.staking.repositories.StakingRepository +import java.math.BigDecimal + +class GetActionRequirementAmountUseCase( + private val stakingRepository: StakingRepository, +) { + + operator fun invoke(integrationId: String, actionType: StakingActionType): Either = + Either.catch { + stakingRepository.getActionRequirementAmount(integrationId, actionType) + } +} \ 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 e399fcd26c..cbb5d358d6 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 @@ -14,11 +14,13 @@ 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.wallets.models.UserWalletId import kotlinx.coroutines.flow.Flow +import java.math.BigDecimal @Suppress("TooManyFunctions") interface StakingRepository { @@ -100,4 +102,9 @@ interface StakingRepository { fun getStakingApproval(cryptoCurrency: CryptoCurrency): StakingApproval suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean + + /** + * Return action requirement amount + */ + fun getActionRequirementAmount(integrationId: String, stakingActionType: StakingActionType): BigDecimal? } \ 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 303da59cda..19b368f075 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 @@ -188,6 +188,8 @@ class MockStakingRepository : StakingRepository { override fun getStakingApproval(cryptoCurrency: CryptoCurrency): StakingApproval = StakingApproval.Empty override suspend fun isAnyTokenStaked(userWalletId: UserWalletId): Boolean = false + override fun getActionRequirementAmount(integrationId: String, stakingActionType: StakingActionType): BigDecimal? = + null private companion object { val yield = Yield( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt index 2454768e9c..895a139203 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt @@ -37,6 +37,7 @@ import com.tangem.domain.staking.model.StakingApproval 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 import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction import com.tangem.domain.staking.utils.getValidatorsCount import com.tangem.domain.tokens.* @@ -120,6 +121,7 @@ internal class StakingModel @Inject constructor( private val getActionsUseCase: GetActionsUseCase, private val getYieldUseCase: GetYieldUseCase, private val checkAccountInitializedUseCase: CheckAccountInitializedUseCase, + private val getActionRequirementAmountUseCase: GetActionRequirementAmountUseCase, private val paramsInterceptorHolder: ParamsInterceptorHolder, private val shareManager: ShareManager, @DelayedWork private val coroutineScope: CoroutineScope, @@ -527,9 +529,20 @@ internal class StakingModel @Inject constructor( val rewardPendingActionConstraints = yieldBalance?.reward?.rewardConstraints if (rewardBlockType == RewardBlockType.RewardsRequirementsError) { + val minimumAmount = rewardPendingActionConstraints?.amountArg?.minimum + // Temporary fix, until StakeKit adds minimum requirement amount to balance response + val minimumAmountValue = if (minimumAmount == null && yieldBalance.integrationId != null) { + getActionRequirementAmountUseCase.invoke( + integrationId = yieldBalance.integrationId, + actionType = StakingActionType.CLAIM_REWARDS, + ).getOrNull() + } else { + minimumAmount + } + stakingEventFactory.createStakingRewardsMinimumRequirementsErrorAlert( cryptoCurrencyName = cryptoCurrencyStatus.currency.name, - cryptoAmountValue = rewardPendingActionConstraints?.amountArg?.minimum?.format { + cryptoAmountValue = minimumAmountValue?.format { crypto(cryptoCurrencyStatus.currency) }.orEmpty(), ) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt index db102751d3..a4b3ea96fd 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt @@ -9,6 +9,7 @@ import java.math.BigDecimal @Immutable internal sealed class InnerYieldBalanceState { data class Data( + val integrationId: String?, val reward: YieldReward, val isActionable: Boolean, val balances: ImmutableList, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt index 9d5d52d214..ee906adb33 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt @@ -50,6 +50,7 @@ internal class YieldBalancesConverter( ?.firstOrNull { it.type == StakingActionType.CLAIM_REWARDS } InnerYieldBalanceState.Data( + integrationId = yieldBalance?.integrationId, reward = YieldReward( rewardsCrypto = cryptoRewardsValue.format { crypto(cryptoCurrency) }, rewardsFiat = fiatRewardsValue.format { 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 1c9a799920..d7af6496e2 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 @@ -64,6 +64,7 @@ internal object InitialStakingStatePreview { val stateWithYield = defaultState.copy( yieldBalance = InnerYieldBalanceState.Data( + integrationId = null, reward = YieldReward( rewardsFiat = "100 $", rewardsCrypto = "100 SOL", diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 29b3a90433..448f0a8772 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,7 +5,7 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "releases-5.26.0-1105" +tangemBlockchainSdk = "releases-5.26.0-1107" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "releases-5.26.0-488" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^