diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt index 4d6ff9ca76..2d5bd551ac 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/StakeKitApi.kt @@ -51,12 +51,18 @@ interface StakeKitApi { @POST("actions/exit") suspend fun createExitAction(@Body body: ActionRequestBody): ApiResponse + @POST("actions/pending") + suspend fun createPendingAction(@Body body: PendingActionRequestBody): ApiResponse + @POST("actions/enter/estimate-gas") suspend fun estimateGasOnEnter(@Body body: ActionRequestBody): ApiResponse @POST("actions/exit/estimate-gas") suspend fun estimateGasOnExit(@Body body: ActionRequestBody): ApiResponse + @POST("actions/pending/estimate-gas") + suspend fun estimateGasOnPending(@Body body: PendingActionRequestBody): ApiResponse + @PATCH("transactions/{transactionId}") suspend fun constructTransaction( @Path("transactionId") transactionId: String, diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/ActionRequestBody.kt b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/ActionRequestBody.kt index e044b1f9a9..fa3ec28913 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/ActionRequestBody.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/stakekit/models/request/ActionRequestBody.kt @@ -4,6 +4,20 @@ import com.squareup.moshi.Json import com.tangem.datasource.api.stakekit.models.request.ConstructTransactionRequestBody.GasArgs import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO import com.tangem.datasource.api.stakekit.models.response.model.TokenDTO +import com.tangem.domain.staking.model.action.StakingActionType + +data class PendingActionRequestBody( + @Json(name = "type") + val type: StakingActionType, + @Json(name = "integrationId") + val integrationId: String, + @Json(name = "passthrough") + val passthrough: String, + @Json(name = "args") + val args: ActionRequestBodyArgs, + @Json(name = "gasArgs") + val gasArgs: GasArgs? = null, // used only in estimate_gas request +) data class ActionRequestBody( @Json(name = "integrationId") @@ -11,40 +25,39 @@ data class ActionRequestBody( @Json(name = "addresses") val addresses: Address, @Json(name = "args") - val args: EnterActionRequestBodyArgs, + val args: ActionRequestBodyArgs, @Json(name = "referralCode") val referralCode: String? = null, @Json(name = "gasArgs") val gasArgs: GasArgs? = null, // used only in estimate_gas request -) { +) - data class EnterActionRequestBodyArgs( - @Json(name = "amount") - val amount: String, - @Json(name = "validatorAddress") - val validatorAddress: String? = null, - @Json(name = "validatorAddresses") - val validatorAddresses: List? = null, - @Json(name = "providerId") - val providerId: String? = null, - @Json(name = "duration") - val duration: String? = null, - @Json(name = "nfts") - val nfts: List? = null, - @Json(name = "ledgerWalletAPICompatible") - val ledgerWalletAPICompatible: Boolean? = null, - @Json(name = "tronResource") - val tronResource: String? = null, - @Json(name = "signatureVerification") - val signatureVerification: SignatureVerification? = null, - @Json(name = "inputToken") - val inputToken: TokenDTO? = null, - ) +data class ActionRequestBodyArgs( + @Json(name = "amount") + val amount: String, + @Json(name = "validatorAddress") + val validatorAddress: String? = null, + @Json(name = "validatorAddresses") + val validatorAddresses: List? = null, + @Json(name = "providerId") + val providerId: String? = null, + @Json(name = "duration") + val duration: String? = null, + @Json(name = "nfts") + val nfts: List? = null, + @Json(name = "ledgerWalletAPICompatible") + val ledgerWalletAPICompatible: Boolean? = null, + @Json(name = "tronResource") + val tronResource: String? = null, + @Json(name = "signatureVerification") + val signatureVerification: SignatureVerification? = null, + @Json(name = "inputToken") + val inputToken: TokenDTO? = null, +) - data class SignatureVerification( - @Json(name = "message") - val message: String, - @Json(name = "signed") - val signed: String, - ) -} \ No newline at end of file +data class SignatureVerification( + @Json(name = "message") + val message: String, + @Json(name = "signed") + val signed: String, +) \ 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 cab788363d..646ff8d040 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 @@ -26,6 +26,7 @@ import com.tangem.domain.core.lce.lceFlow import com.tangem.domain.staking.model.* import com.tangem.domain.staking.model.action.StakingAction import com.tangem.domain.staking.model.action.StakingActionCommonType +import com.tangem.domain.staking.model.action.StakingActionType import com.tangem.domain.staking.model.transaction.ActionParams import com.tangem.domain.staking.model.transaction.StakingGasEstimate import com.tangem.domain.staking.model.transaction.StakingTransaction @@ -158,10 +159,12 @@ internal class DefaultStakingRepository( override suspend fun createAction(params: ActionParams): StakingAction { return withContext(dispatchers.io) { - val body = createActionRequestBody(params) val response = when (params.actionCommonType) { - StakingActionCommonType.ENTER -> stakeKitApi.createEnterAction(body) - StakingActionCommonType.EXIT -> stakeKitApi.createExitAction(body) + StakingActionCommonType.ENTER -> stakeKitApi.createEnterAction(createActionRequestBody(params)) + StakingActionCommonType.EXIT -> stakeKitApi.createExitAction(createActionRequestBody(params)) + StakingActionCommonType.PENDING -> stakeKitApi.createPendingAction( + createPendingActionRequestBody(params), + ) } enterActionResponseConverter.convert(response.getOrThrow()) @@ -170,11 +173,12 @@ internal class DefaultStakingRepository( override suspend fun estimateGas(params: ActionParams): StakingGasEstimate { return withContext(dispatchers.io) { - val body = createActionRequestBody(params) - val gasEstimateDTO = when (params.actionCommonType) { - StakingActionCommonType.ENTER -> stakeKitApi.estimateGasOnEnter(body) - StakingActionCommonType.EXIT -> stakeKitApi.estimateGasOnExit(body) + StakingActionCommonType.ENTER -> stakeKitApi.estimateGasOnEnter(createActionRequestBody(params)) + StakingActionCommonType.EXIT -> stakeKitApi.estimateGasOnExit(createActionRequestBody(params)) + StakingActionCommonType.PENDING -> stakeKitApi.estimateGasOnPending( + createPendingActionRequestBody(params), + ) } gasEstimateConverter.convert(gasEstimateDTO.getOrThrow()) @@ -432,7 +436,7 @@ internal class DefaultStakingRepository( return ActionRequestBody( integrationId = params.integrationId, addresses = Address(params.address), - args = ActionRequestBody.EnterActionRequestBodyArgs( + args = ActionRequestBodyArgs( amount = params.amount.toFormattedString(params.token.decimals), inputToken = tokenConverter.convertBack(params.token), validatorAddress = params.validatorAddress, @@ -440,6 +444,18 @@ internal class DefaultStakingRepository( ) } + private fun createPendingActionRequestBody(params: ActionParams): PendingActionRequestBody { + return PendingActionRequestBody( + integrationId = params.integrationId, + type = params.type ?: StakingActionType.UNKNOWN, + passthrough = params.passthrough.orEmpty(), + args = ActionRequestBodyArgs( + amount = params.amount.toFormattedString(params.token.decimals), + validatorAddress = params.validatorAddress, + ), + ) + } + override fun isStakeMoreAvailable(networkId: Network.ID): Boolean { val blockchain = Blockchain.fromId(networkId.value) return when (blockchain) { diff --git a/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt b/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt index d0abdee20e..c3dd742fbe 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/converters/YieldBalanceConverter.kt @@ -1,5 +1,6 @@ package com.tangem.data.staking.converters +import com.tangem.data.staking.converters.action.PendingActionConverter import com.tangem.datasource.api.stakekit.models.response.model.BalanceDTO import com.tangem.domain.staking.model.BalanceItem import com.tangem.domain.staking.model.BalanceType @@ -9,6 +10,8 @@ import com.tangem.utils.converter.Converter internal class YieldBalanceConverter : Converter { + private val pendingActionConverter by lazy(LazyThreadSafetyMode.NONE) { PendingActionConverter() } + override fun convert(value: Data): YieldBalance { return if (value.balance.isEmpty()) { YieldBalance.Empty @@ -22,6 +25,7 @@ internal class YieldBalanceConverter : Converter { + + private val stakingActionTypeConverter by lazy(LazyThreadSafetyMode.NONE) { StakingActionTypeConverter() } + + override fun convert(value: BalanceDTO.PendingAction): PendingAction { + return PendingAction( + type = stakingActionTypeConverter.convert(value.type), + passthrough = value.passthrough, + args = with(value.args) { + PendingAction.PendingActionArgs( + amount = this?.amount?.let { + PendingAction.PendingActionArgs.Amount( + required = it.required, + minimum = it.minimum, + maximum = it.maximum, + ) + }, + duration = this?.duration?.let { + PendingAction.PendingActionArgs.Duration( + required = it.required, + minimum = it.minimum, + maximum = it.maximum, + ) + }, + validatorAddress = this?.validatorAddress?.required, + validatorAddresses = this?.validatorAddresses?.required, + tronResource = this?.tronResource?.let { + PendingAction.PendingActionArgs.TronResource( + required = it.required, + options = it.options, + ) + }, + signatureVerification = this?.signatureVerification?.required, + ) + }, + ) + } +} \ No newline at end of file diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/YieldBalance.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/YieldBalance.kt index 6ed53d2486..b82ff8bf02 100644 --- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/YieldBalance.kt +++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/YieldBalance.kt @@ -1,5 +1,6 @@ package com.tangem.domain.staking.model +import com.tangem.domain.staking.model.action.StakingActionType import java.math.BigDecimal sealed class YieldBalance { @@ -36,8 +37,41 @@ data class BalanceItem( val pricePerShare: BigDecimal, val rawCurrencyId: String?, val validatorAddress: String?, + val pendingActions: List, ) +data class PendingAction( + val type: StakingActionType, + val passthrough: String, + val args: PendingActionArgs?, +) { + data class PendingActionArgs( + val amount: Amount?, + val duration: Duration?, + val validatorAddress: Boolean?, + val validatorAddresses: Boolean?, + val tronResource: TronResource?, + val signatureVerification: Boolean?, + ) { + data class Amount( + val required: Boolean, + val minimum: BigDecimal?, + val maximum: BigDecimal?, + ) + + data class Duration( + val required: Boolean, + val minimum: Int?, + val maximum: Int?, + ) + + data class TronResource( + val required: Boolean, + val options: List, + ) + } +} + enum class BalanceType { AVAILABLE, STAKED, diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/action/StakingActionCommonType.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/action/StakingActionCommonType.kt index 59f5e782d9..56e96d2caa 100644 --- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/action/StakingActionCommonType.kt +++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/action/StakingActionCommonType.kt @@ -3,4 +3,5 @@ package com.tangem.domain.staking.model.action enum class StakingActionCommonType { ENTER, EXIT, + PENDING, } \ No newline at end of file diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/transaction/ActionParams.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/transaction/ActionParams.kt index ab5aa8f530..0d84c4146a 100644 --- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/transaction/ActionParams.kt +++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/transaction/ActionParams.kt @@ -2,6 +2,7 @@ package com.tangem.domain.staking.model.transaction import com.tangem.domain.staking.model.Token import com.tangem.domain.staking.model.action.StakingActionCommonType +import com.tangem.domain.staking.model.action.StakingActionType import java.math.BigDecimal data class ActionParams( @@ -11,4 +12,6 @@ data class ActionParams( val address: String, val validatorAddress: String, val token: Token, + val passthrough: String? = null, + val type: StakingActionType? = null, ) \ No newline at end of file