Updated on 2026-08-14
This commit is contained in:
commit
1bf78a1f1a
13 changed files with 159 additions and 61 deletions
|
|
@ -22,6 +22,7 @@ dependencies {
|
||||||
implementation(projects.domain.tokens.models)
|
implementation(projects.domain.tokens.models)
|
||||||
implementation(projects.domain.staking)
|
implementation(projects.domain.staking)
|
||||||
implementation(projects.domain.wallets.models)
|
implementation(projects.domain.wallets.models)
|
||||||
|
implementation(projects.domain.legacy)
|
||||||
|
|
||||||
/** Feature Api modules */
|
/** Feature Api modules */
|
||||||
implementation(projects.features.staking.api)
|
implementation(projects.features.staking.api)
|
||||||
|
|
@ -40,6 +41,8 @@ dependencies {
|
||||||
|
|
||||||
|
|
||||||
implementation(projects.libs.blockchainSdk)
|
implementation(projects.libs.blockchainSdk)
|
||||||
|
|
||||||
|
implementation(deps.tangem.card.core)
|
||||||
implementation(deps.tangem.blockchain) {
|
implementation(deps.tangem.blockchain) {
|
||||||
exclude(module = "joda-time")
|
exclude(module = "joda-time")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package com.tangem.data.staking
|
package com.tangem.data.staking
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
import arrow.core.raise.catch
|
import arrow.core.raise.catch
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchainsdk.utils.toCoinId
|
import com.tangem.blockchainsdk.utils.toCoinId
|
||||||
|
import com.tangem.common.extensions.toCompressedPublicKey
|
||||||
import com.tangem.data.common.cache.CacheRegistry
|
import com.tangem.data.common.cache.CacheRegistry
|
||||||
import com.tangem.data.staking.converters.*
|
import com.tangem.data.staking.converters.*
|
||||||
import com.tangem.data.staking.converters.action.ActionStatusConverter
|
import com.tangem.data.staking.converters.action.ActionStatusConverter
|
||||||
|
|
@ -23,7 +25,10 @@ import com.tangem.datasource.local.token.StakingBalanceStore
|
||||||
import com.tangem.datasource.local.token.StakingYieldsStore
|
import com.tangem.datasource.local.token.StakingYieldsStore
|
||||||
import com.tangem.domain.core.lce.LceFlow
|
import com.tangem.domain.core.lce.LceFlow
|
||||||
import com.tangem.domain.core.lce.lceFlow
|
import com.tangem.domain.core.lce.lceFlow
|
||||||
import com.tangem.domain.staking.model.*
|
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.Yield
|
||||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||||
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
|
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
|
||||||
|
|
@ -37,10 +42,10 @@ import com.tangem.domain.staking.repositories.StakingRepository
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
import com.tangem.domain.tokens.model.CryptoCurrencyAddress
|
||||||
import com.tangem.domain.tokens.model.Network
|
import com.tangem.domain.tokens.model.Network
|
||||||
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.toFormattedString
|
|
||||||
import kotlinx.coroutines.NonCancellable
|
import kotlinx.coroutines.NonCancellable
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -55,6 +60,7 @@ internal class DefaultStakingRepository(
|
||||||
private val cacheRegistry: CacheRegistry,
|
private val cacheRegistry: CacheRegistry,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val stakingFeatureToggle: StakingFeatureToggles,
|
private val stakingFeatureToggle: StakingFeatureToggles,
|
||||||
|
private val walletManagersFacade: WalletManagersFacade,
|
||||||
) : StakingRepository {
|
) : StakingRepository {
|
||||||
|
|
||||||
private val stakingNetworkTypeConverter = StakingNetworkTypeConverter()
|
private val stakingNetworkTypeConverter = StakingNetworkTypeConverter()
|
||||||
|
|
@ -160,11 +166,27 @@ internal class DefaultStakingRepository(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createAction(params: ActionParams): StakingAction {
|
override suspend fun createAction(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): StakingAction {
|
||||||
return withContext(dispatchers.io) {
|
return withContext(dispatchers.io) {
|
||||||
val response = when (params.actionCommonType) {
|
val response = when (params.actionCommonType) {
|
||||||
StakingActionCommonType.ENTER -> stakeKitApi.createEnterAction(createActionRequestBody(params))
|
StakingActionCommonType.ENTER -> stakeKitApi.createEnterAction(
|
||||||
StakingActionCommonType.EXIT -> stakeKitApi.createExitAction(createActionRequestBody(params))
|
createActionRequestBody(
|
||||||
|
userWalletId,
|
||||||
|
network,
|
||||||
|
params,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
StakingActionCommonType.EXIT -> stakeKitApi.createExitAction(
|
||||||
|
createActionRequestBody(
|
||||||
|
userWalletId,
|
||||||
|
network,
|
||||||
|
params,
|
||||||
|
),
|
||||||
|
)
|
||||||
StakingActionCommonType.PENDING -> stakeKitApi.createPendingAction(
|
StakingActionCommonType.PENDING -> stakeKitApi.createPendingAction(
|
||||||
createPendingActionRequestBody(params),
|
createPendingActionRequestBody(params),
|
||||||
)
|
)
|
||||||
|
|
@ -174,11 +196,27 @@ internal class DefaultStakingRepository(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun estimateGas(params: ActionParams): StakingGasEstimate {
|
override suspend fun estimateGas(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): StakingGasEstimate {
|
||||||
return withContext(dispatchers.io) {
|
return withContext(dispatchers.io) {
|
||||||
val gasEstimateDTO = when (params.actionCommonType) {
|
val gasEstimateDTO = when (params.actionCommonType) {
|
||||||
StakingActionCommonType.ENTER -> stakeKitApi.estimateGasOnEnter(createActionRequestBody(params))
|
StakingActionCommonType.ENTER -> stakeKitApi.estimateGasOnEnter(
|
||||||
StakingActionCommonType.EXIT -> stakeKitApi.estimateGasOnExit(createActionRequestBody(params))
|
createActionRequestBody(
|
||||||
|
userWalletId,
|
||||||
|
network,
|
||||||
|
params,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
StakingActionCommonType.EXIT -> stakeKitApi.estimateGasOnExit(
|
||||||
|
createActionRequestBody(
|
||||||
|
userWalletId,
|
||||||
|
network,
|
||||||
|
params,
|
||||||
|
),
|
||||||
|
)
|
||||||
StakingActionCommonType.PENDING -> stakeKitApi.estimateGasOnPending(
|
StakingActionCommonType.PENDING -> stakeKitApi.estimateGasOnPending(
|
||||||
createPendingActionRequestBody(params),
|
createPendingActionRequestBody(params),
|
||||||
)
|
)
|
||||||
|
|
@ -435,12 +473,19 @@ internal class DefaultStakingRepository(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createActionRequestBody(params: ActionParams): ActionRequestBody {
|
private suspend fun createActionRequestBody(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): ActionRequestBody {
|
||||||
return ActionRequestBody(
|
return ActionRequestBody(
|
||||||
integrationId = params.integrationId,
|
integrationId = params.integrationId,
|
||||||
addresses = Address(params.address),
|
addresses = Address(
|
||||||
|
address = params.address,
|
||||||
|
additionalAddresses = createAdditionalAddresses(userWalletId, network, params),
|
||||||
|
),
|
||||||
args = ActionRequestBodyArgs(
|
args = ActionRequestBodyArgs(
|
||||||
amount = params.amount.toFormattedString(params.token.decimals),
|
amount = params.amount.toPlainString(),
|
||||||
inputToken = tokenConverter.convertBack(params.token),
|
inputToken = tokenConverter.convertBack(params.token),
|
||||||
validatorAddress = params.validatorAddress,
|
validatorAddress = params.validatorAddress,
|
||||||
),
|
),
|
||||||
|
|
@ -453,12 +498,29 @@ internal class DefaultStakingRepository(
|
||||||
type = params.type ?: StakingActionType.UNKNOWN,
|
type = params.type ?: StakingActionType.UNKNOWN,
|
||||||
passthrough = params.passthrough.orEmpty(),
|
passthrough = params.passthrough.orEmpty(),
|
||||||
args = ActionRequestBodyArgs(
|
args = ActionRequestBodyArgs(
|
||||||
amount = params.amount.toFormattedString(params.token.decimals),
|
amount = params.amount.toPlainString(),
|
||||||
validatorAddress = params.validatorAddress,
|
validatorAddress = params.validatorAddress,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun createAdditionalAddresses(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): Address.AdditionalAddresses? {
|
||||||
|
val selectedWallet = walletManagersFacade.getOrCreateWalletManager(userWalletId, network)
|
||||||
|
return when (params.token.network) {
|
||||||
|
NetworkType.COSMOS -> Address.AdditionalAddresses(
|
||||||
|
cosmosPubKey = Base64.encodeToString(
|
||||||
|
/* input = */ selectedWallet?.wallet?.publicKey?.blockchainKey?.toCompressedPublicKey(),
|
||||||
|
/* flags = */ Base64.NO_WRAP,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun isStakeMoreAvailable(networkId: Network.ID): Boolean {
|
override fun isStakeMoreAvailable(networkId: Network.ID): Boolean {
|
||||||
val blockchain = Blockchain.fromId(networkId.value)
|
val blockchain = Blockchain.fromId(networkId.value)
|
||||||
return when (blockchain) {
|
return when (blockchain) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import com.tangem.datasource.local.token.StakingBalanceStore
|
||||||
import com.tangem.datasource.local.token.StakingYieldsStore
|
import com.tangem.datasource.local.token.StakingYieldsStore
|
||||||
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
||||||
import com.tangem.domain.staking.repositories.StakingRepository
|
import com.tangem.domain.staking.repositories.StakingRepository
|
||||||
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
|
@ -35,6 +36,7 @@ internal object StakingDataModule {
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
stakingFeatureToggle: StakingFeatureToggles,
|
stakingFeatureToggle: StakingFeatureToggles,
|
||||||
cacheRegistry: CacheRegistry,
|
cacheRegistry: CacheRegistry,
|
||||||
|
walletManagersFacade: WalletManagersFacade,
|
||||||
): StakingRepository {
|
): StakingRepository {
|
||||||
return DefaultStakingRepository(
|
return DefaultStakingRepository(
|
||||||
stakeKitApi = stakeKitApi,
|
stakeKitApi = stakeKitApi,
|
||||||
|
|
@ -44,6 +46,7 @@ internal object StakingDataModule {
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
cacheRegistry = cacheRegistry,
|
cacheRegistry = cacheRegistry,
|
||||||
stakingFeatureToggle = stakingFeatureToggle,
|
stakingFeatureToggle = stakingFeatureToggle,
|
||||||
|
walletManagersFacade = walletManagersFacade,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ data class ActionParams(
|
||||||
val address: String,
|
val address: String,
|
||||||
val validatorAddress: String,
|
val validatorAddress: String,
|
||||||
val token: Token,
|
val token: Token,
|
||||||
|
val publicKey: String? = null,
|
||||||
val passthrough: String? = null,
|
val passthrough: String? = null,
|
||||||
val type: StakingActionType? = null,
|
val type: StakingActionType? = null,
|
||||||
)
|
)
|
||||||
|
|
@ -6,6 +6,8 @@ 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.StakingGasEstimate
|
||||||
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
||||||
import com.tangem.domain.staking.repositories.StakingRepository
|
import com.tangem.domain.staking.repositories.StakingRepository
|
||||||
|
import com.tangem.domain.tokens.model.Network
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use case for staking gas estimation.
|
* Use case for staking gas estimation.
|
||||||
|
|
@ -15,9 +17,13 @@ class EstimateGasUseCase(
|
||||||
private val stakingErrorResolver: StakingErrorResolver,
|
private val stakingErrorResolver: StakingErrorResolver,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke(params: ActionParams): Either<StakingError, StakingGasEstimate> {
|
suspend operator fun invoke(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): Either<StakingError, StakingGasEstimate> {
|
||||||
return Either.catch {
|
return Either.catch {
|
||||||
stakingRepository.estimateGas(params)
|
stakingRepository.estimateGas(userWalletId, network, params)
|
||||||
}.mapLeft {
|
}.mapLeft {
|
||||||
stakingErrorResolver.resolve(it)
|
stakingErrorResolver.resolve(it)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import com.tangem.domain.staking.model.stakekit.transaction.ActionParams
|
||||||
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
|
import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
|
||||||
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
import com.tangem.domain.staking.repositories.StakingErrorResolver
|
||||||
import com.tangem.domain.staking.repositories.StakingRepository
|
import com.tangem.domain.staking.repositories.StakingRepository
|
||||||
|
import com.tangem.domain.tokens.model.Network
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,9 +18,13 @@ class GetStakingTransactionUseCase(
|
||||||
private val stakingErrorResolver: StakingErrorResolver,
|
private val stakingErrorResolver: StakingErrorResolver,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke(params: ActionParams): Either<StakingError, StakingTransaction> {
|
suspend operator fun invoke(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): Either<StakingError, StakingTransaction> {
|
||||||
return Either.catch {
|
return Either.catch {
|
||||||
val createAction = stakingRepository.createAction(params)
|
val createAction = stakingRepository.createAction(userWalletId, network, params)
|
||||||
|
|
||||||
// workaround, sometimes transaction is not created immediately after actions/enter
|
// workaround, sometimes transaction is not created immediately after actions/enter
|
||||||
delay(PATCH_TRANSACTION_REQUEST_DELAY)
|
delay(PATCH_TRANSACTION_REQUEST_DELAY)
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,9 @@ interface StakingRepository {
|
||||||
addresses: List<CryptoCurrencyAddress>,
|
addresses: List<CryptoCurrencyAddress>,
|
||||||
): YieldBalanceList
|
): YieldBalanceList
|
||||||
|
|
||||||
suspend fun createAction(params: ActionParams): StakingAction
|
suspend fun createAction(userWalletId: UserWalletId, network: Network, params: ActionParams): StakingAction
|
||||||
|
|
||||||
suspend fun estimateGas(params: ActionParams): StakingGasEstimate
|
suspend fun estimateGas(userWalletId: UserWalletId, network: Network, params: ActionParams): StakingGasEstimate
|
||||||
|
|
||||||
suspend fun constructTransaction(transactionId: String): StakingTransaction
|
suspend fun constructTransaction(transactionId: String): StakingTransaction
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,11 @@ class MockStakingRepository : StakingRepository {
|
||||||
balances = listOf(YieldBalance.Error),
|
balances = listOf(YieldBalance.Error),
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun createAction(params: ActionParams): StakingAction {
|
override suspend fun createAction(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): StakingAction {
|
||||||
return StakingAction(
|
return StakingAction(
|
||||||
id = "quis",
|
id = "quis",
|
||||||
integrationId = "persequeris",
|
integrationId = "persequeris",
|
||||||
|
|
@ -182,7 +186,11 @@ class MockStakingRepository : StakingRepository {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun estimateGas(params: ActionParams): StakingGasEstimate {
|
override suspend fun estimateGas(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
network: Network,
|
||||||
|
params: ActionParams,
|
||||||
|
): StakingGasEstimate {
|
||||||
return StakingGasEstimate(
|
return StakingGasEstimate(
|
||||||
amount = BigDecimal(0.0001),
|
amount = BigDecimal(0.0001),
|
||||||
token = Token(
|
token = Token(
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,6 @@ internal class YieldBalancesConverter(
|
||||||
private fun BalanceType.toGroup() = when (this) {
|
private fun BalanceType.toGroup() = when (this) {
|
||||||
BalanceType.PREPARING,
|
BalanceType.PREPARING,
|
||||||
BalanceType.STAKED,
|
BalanceType.STAKED,
|
||||||
BalanceType.REWARDS,
|
|
||||||
BalanceType.AVAILABLE,
|
BalanceType.AVAILABLE,
|
||||||
BalanceType.LOCKED,
|
BalanceType.LOCKED,
|
||||||
-> BalanceGroupType.ACTIVE
|
-> BalanceGroupType.ACTIVE
|
||||||
|
|
@ -121,6 +120,7 @@ internal class YieldBalancesConverter(
|
||||||
BalanceType.UNLOCKING,
|
BalanceType.UNLOCKING,
|
||||||
BalanceType.UNSTAKED,
|
BalanceType.UNSTAKED,
|
||||||
-> BalanceGroupType.UNSTAKED
|
-> BalanceGroupType.UNSTAKED
|
||||||
|
BalanceType.REWARDS,
|
||||||
BalanceType.UNKNOWN,
|
BalanceType.UNKNOWN,
|
||||||
-> BalanceGroupType.UNKNOWN
|
-> BalanceGroupType.UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,11 @@ internal class AmountChangeStateTransformer(
|
||||||
private val value: String,
|
private val value: String,
|
||||||
) : Transformer<StakingUiState> {
|
) : Transformer<StakingUiState> {
|
||||||
|
|
||||||
private val amountRequirementStateTransformer by lazy(LazyThreadSafetyMode.NONE) {
|
private val amountRequirementStateTransformer = AmountRequirementStateTransformer(
|
||||||
AmountRequirementStateTransformer(
|
cryptoCurrencyStatus,
|
||||||
cryptoCurrencyStatus,
|
yield,
|
||||||
yield,
|
value,
|
||||||
value,
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||||
val updatedAmountState = AmountFieldChangeTransformer(
|
val updatedAmountState = AmountFieldChangeTransformer(
|
||||||
|
|
|
||||||
|
|
@ -12,16 +12,13 @@ internal class AmountMaxValueStateTransformer(
|
||||||
private val yield: Yield,
|
private val yield: Yield,
|
||||||
) : Transformer<StakingUiState> {
|
) : Transformer<StakingUiState> {
|
||||||
|
|
||||||
private val amountRequirementStateTransformer by lazy(LazyThreadSafetyMode.NONE) {
|
private val amountRequirementStateTransformer = AmountRequirementStateTransformer(
|
||||||
val value = cryptoCurrencyStatus.value.amount
|
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||||
|
yield = yield,
|
||||||
|
value = cryptoCurrencyStatus.value.amount
|
||||||
?.parseBigDecimal(cryptoCurrencyStatus.currency.decimals)
|
?.parseBigDecimal(cryptoCurrencyStatus.currency.decimals)
|
||||||
.orEmpty()
|
.orEmpty(),
|
||||||
AmountRequirementStateTransformer(
|
)
|
||||||
cryptoCurrencyStatus,
|
|
||||||
yield,
|
|
||||||
value,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||||
val updatedAmountState = AmountFieldMaxAmountTransformer(cryptoCurrencyStatus).transform(prevState.amountState)
|
val updatedAmountState = AmountFieldMaxAmountTransformer(cryptoCurrencyStatus).transform(prevState.amountState)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.wrappedList
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||||
import com.tangem.core.ui.utils.parseToBigDecimal
|
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||||
|
import com.tangem.domain.staking.model.stakekit.AddressArgument
|
||||||
import com.tangem.domain.staking.model.stakekit.Yield
|
import com.tangem.domain.staking.model.stakekit.Yield
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
import com.tangem.features.staking.impl.R
|
import com.tangem.features.staking.impl.R
|
||||||
|
|
@ -18,38 +19,47 @@ internal class AmountRequirementStateTransformer(
|
||||||
) : Transformer<AmountState> {
|
) : Transformer<AmountState> {
|
||||||
override fun transform(prevState: AmountState): AmountState {
|
override fun transform(prevState: AmountState): AmountState {
|
||||||
val amountRequirements = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]
|
val amountRequirements = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]
|
||||||
val amountDecimal = value.parseToBigDecimal(cryptoCurrencyStatus.currency.decimals)
|
|
||||||
|
|
||||||
return if (prevState !is AmountState.Data || amountRequirements == null) {
|
return if (prevState !is AmountState.Data || amountRequirements == null) {
|
||||||
prevState
|
prevState
|
||||||
} else {
|
} else {
|
||||||
val isAlreadyErrorState = prevState.amountTextField.isError
|
updateWithError(prevState, amountRequirements)
|
||||||
val isAmountRequired = amountRequirements.required
|
}
|
||||||
val isAmountZero = amountDecimal.isZero()
|
}
|
||||||
val isExceedsRequirements =
|
|
||||||
amountRequirements.maximum?.compareTo(amountDecimal) == -1 ||
|
|
||||||
amountRequirements.minimum?.compareTo(amountDecimal) == 1
|
|
||||||
|
|
||||||
val isRequirementError = !isAmountZero && isAmountRequired && isExceedsRequirements && !isAlreadyErrorState
|
private fun updateWithError(prevState: AmountState.Data, amountRequirements: AddressArgument): AmountState {
|
||||||
if (isRequirementError) {
|
val isRequirementError = isRequirementError(prevState, amountRequirements)
|
||||||
prevState.copy(
|
return if (isRequirementError) {
|
||||||
amountTextField = prevState.amountTextField.copy(
|
prevState.copy(
|
||||||
isError = true,
|
amountTextField = prevState.amountTextField.copy(
|
||||||
error = resourceReference(
|
isError = true,
|
||||||
R.string.staking_amount_requirement_error,
|
error = resourceReference(
|
||||||
wrappedList(
|
R.string.staking_amount_requirement_error,
|
||||||
BigDecimalFormatter.formatCryptoAmount(
|
wrappedList(
|
||||||
amountRequirements.minimum,
|
BigDecimalFormatter.formatCryptoAmount(
|
||||||
cryptoCurrencyStatus.currency.symbol,
|
amountRequirements.minimum,
|
||||||
cryptoCurrencyStatus.currency.decimals,
|
cryptoCurrencyStatus.currency.symbol,
|
||||||
),
|
cryptoCurrencyStatus.currency.decimals,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
} else {
|
)
|
||||||
prevState
|
} else {
|
||||||
}
|
prevState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isRequirementError(prevState: AmountState.Data, amountRequirements: AddressArgument): Boolean {
|
||||||
|
val amountDecimal = value.parseToBigDecimal(cryptoCurrencyStatus.currency.decimals)
|
||||||
|
|
||||||
|
val isAlreadyErrorState = prevState.amountTextField.isError
|
||||||
|
val isAmountRequired = amountRequirements.required
|
||||||
|
val isAmountZero = amountDecimal.isZero()
|
||||||
|
val isExceedsRequirements =
|
||||||
|
amountRequirements.maximum?.compareTo(amountDecimal) == -1 ||
|
||||||
|
amountRequirements.minimum?.compareTo(amountDecimal) == 1
|
||||||
|
|
||||||
|
return !isAmountZero && isAmountRequired && isExceedsRequirements && !isAlreadyErrorState
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +120,8 @@ internal class StakingViewModel @Inject constructor(
|
||||||
val pendingActions = confirmationState.pendingActions
|
val pendingActions = confirmationState.pendingActions
|
||||||
|
|
||||||
val stakingTransaction = getStakingTransactionUseCase(
|
val stakingTransaction = getStakingTransactionUseCase(
|
||||||
|
userWalletId = userWalletId,
|
||||||
|
network = cryptoCurrencyStatus.currency.network,
|
||||||
params = ActionParams(
|
params = ActionParams(
|
||||||
actionCommonType = getStakingCommonType(),
|
actionCommonType = getStakingCommonType(),
|
||||||
integrationId = yield.id,
|
integrationId = yield.id,
|
||||||
|
|
@ -158,6 +160,8 @@ internal class StakingViewModel @Inject constructor(
|
||||||
val cryptoCurrencyValue = cryptoCurrencyStatus.value
|
val cryptoCurrencyValue = cryptoCurrencyStatus.value
|
||||||
|
|
||||||
val stakingGasEstimate = estimateGasUseCase(
|
val stakingGasEstimate = estimateGasUseCase(
|
||||||
|
userWalletId = userWalletId,
|
||||||
|
network = cryptoCurrencyStatus.currency.network,
|
||||||
params = ActionParams(
|
params = ActionParams(
|
||||||
actionCommonType = getStakingCommonType(),
|
actionCommonType = getStakingCommonType(),
|
||||||
integrationId = yield.id,
|
integrationId = yield.id,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue