Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-29 15:05:35 +02:00
parent 721ab042e0
commit 7d599256d1
27 changed files with 366 additions and 454 deletions

View file

@ -2,9 +2,7 @@ package com.tangem.datasource.api.ethpool
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.ethpool.models.request.P2PEthPoolBroadcastRequest
import com.tangem.datasource.api.ethpool.models.request.P2PEthPoolDepositRequest
import com.tangem.datasource.api.ethpool.models.request.P2PEthPoolUnstakeRequest
import com.tangem.datasource.api.ethpool.models.request.P2PEthPoolWithdrawRequest
import com.tangem.datasource.api.ethpool.models.request.P2PEthPoolTransactionRequest
import com.tangem.datasource.api.ethpool.models.response.*
import retrofit2.http.*
@ -31,13 +29,13 @@ interface P2PEthPoolApi {
* Create unsigned transaction for depositing ETH into a vault.
*
* @param network Ethereum pool network: "mainnet" or "hoodi"
* @param body Deposit parameters (delegator address, vault address, amount)
* @param body Transaction parameters (delegator address, vault address, amount)
*/
@POST("api/v1/staking/pool/{network}/staking/deposit")
suspend fun createDepositTransaction(
@Path("network") network: String,
@Body body: P2PEthPoolDepositRequest,
): ApiResponse<P2PEthPoolResponse<P2PEthPoolDepositResponse>>
@Body body: P2PEthPoolTransactionRequest,
): ApiResponse<P2PEthPoolResponse<P2PEthPoolTransactionResponse>>
/**
* Prepare unstake transaction
@ -45,13 +43,13 @@ interface P2PEthPoolApi {
* Create unsigned transaction to initiate unstaking process.
*
* @param network Ethereum pool network: "mainnet" or "hoodi"
* @param body Unstake parameters (staker public key, stake transaction hash)
* @param body Transaction parameters (delegator address, vault address, amount)
*/
@POST("api/v1/staking/pool/{network}/staking/unstake")
suspend fun createUnstakeTransaction(
@Path("network") network: String,
@Body body: P2PEthPoolUnstakeRequest,
): ApiResponse<P2PEthPoolResponse<P2PEthPoolUnstakeResponse>>
@Body body: P2PEthPoolTransactionRequest,
): ApiResponse<P2PEthPoolResponse<P2PEthPoolTransactionResponse>>
/**
* Prepare withdrawal transaction
@ -59,13 +57,13 @@ interface P2PEthPoolApi {
* Create unsigned transaction to withdraw available funds from exit queue.
*
* @param network Ethereum pool network: "mainnet" or "hoodi"
* @param body Withdrawal parameters (staker address)
* @param body Transaction parameters (delegator address, vault address, amount)
*/
@POST("api/v1/staking/pool/{network}/staking/withdraw")
suspend fun createWithdrawTransaction(
@Path("network") network: String,
@Body body: P2PEthPoolWithdrawRequest,
): ApiResponse<P2PEthPoolResponse<P2PEthPoolWithdrawResponse>>
@Body body: P2PEthPoolTransactionRequest,
): ApiResponse<P2PEthPoolResponse<P2PEthPoolTransactionResponse>>
/**
* Broadcast signed transaction
@ -107,6 +105,7 @@ interface P2PEthPoolApi {
* @param vaultAddress Ethereum address of the vault
* @param period Optional period filter (30, 60, or 90 days)
*/
// TODO p2p not used, consider removing this method
@GET("api/v1/staking/pool/{network}/account/{delegatorAddress}/vault/{vaultAddress}/rewards")
suspend fun getRewards(
@Path("network") network: String,

View file

@ -1,19 +0,0 @@
package com.tangem.datasource.api.ethpool.models.request
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
* Request body for creating deposit transaction
*
* Used in: POST /api/v1/staking/pool/{network}/staking/deposit
*/
@JsonClass(generateAdapter = true)
data class P2PEthPoolDepositRequest(
@Json(name = "delegatorAddress")
val delegatorAddress: String,
@Json(name = "vaultAddress")
val vaultAddress: String,
@Json(name = "amount")
val amount: Double,
)

View file

@ -0,0 +1,23 @@
package com.tangem.datasource.api.ethpool.models.request
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.math.BigDecimal
/**
* Unified request body for creating staking transactions (deposit, unstake, withdraw)
*
* Used in:
* - POST /api/v1/staking/pool/{network}/staking/deposit
* - POST /api/v1/staking/pool/{network}/staking/unstake
* - POST /api/v1/staking/pool/{network}/staking/withdraw
*/
@JsonClass(generateAdapter = true)
data class P2PEthPoolTransactionRequest(
@Json(name = "delegatorAddress")
val delegatorAddress: String,
@Json(name = "vaultAddress")
val vaultAddress: String,
@Json(name = "amount")
val amount: BigDecimal,
)

View file

@ -1,20 +0,0 @@
package com.tangem.datasource.api.ethpool.models.request
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
* Request body for creating unstake transaction
*
* Used in: POST /api/v1/staking/pool/{network}/staking/unstake
*
* Note: Documentation seems to contain Bitcoin-related fields (possibly copy-paste error).
* Using as-is per specification.
*/
@JsonClass(generateAdapter = true)
data class P2PEthPoolUnstakeRequest(
@Json(name = "stakerPublicKey")
val stakerPublicKey: String,
@Json(name = "stakeTransactionHash")
val stakeTransactionHash: String,
)

View file

@ -1,15 +0,0 @@
package com.tangem.datasource.api.ethpool.models.request
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
* Request body for creating withdrawal transaction
*
* Used in: POST /api/v1/staking/pool/{network}/staking/withdraw
*/
@JsonClass(generateAdapter = true)
data class P2PEthPoolWithdrawRequest(
@Json(name = "stakerAddress")
val stakerAddress: String,
)

View file

@ -34,7 +34,7 @@ data class P2PEthPoolStakeDTO(
@JsonClass(generateAdapter = true)
data class P2PEthPoolExitQueueDTO(
@Json(name = "total")
val total: Double,
val total: BigDecimal,
@Json(name = "requests")
val requests: List<P2PEthPoolExitRequestDTO>,
)
@ -44,11 +44,11 @@ data class P2PEthPoolExitRequestDTO(
@Json(name = "ticket")
val ticket: String,
@Json(name = "totalAssets")
val totalAssets: Double,
val totalAssets: BigDecimal,
@Json(name = "timestamp")
val timestamp: Long,
@Json(name = "withdrawalTimestamp")
val withdrawalTimestamp: Long,
val withdrawalTimestamp: Long?,
@Json(name = "isClaimable")
val isClaimable: Boolean,
)

View file

@ -1,22 +0,0 @@
package com.tangem.datasource.api.ethpool.models.response
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.joda.time.DateTime
/**
* Response for POST /api/v1/staking/pool/{network}/staking/deposit
*/
@JsonClass(generateAdapter = true)
data class P2PEthPoolDepositResponse(
@Json(name = "amount")
val amount: Double,
@Json(name = "vaultAddress")
val vaultAddress: String,
@Json(name = "delegatorAddress")
val delegatorAddress: String,
@Json(name = "unsignedTransaction")
val unsignedTransaction: P2PEthPoolUnsignedTxDTO,
@Json(name = "createdAt")
val createdAt: DateTime,
)

View file

@ -3,14 +3,20 @@ package com.tangem.datasource.api.ethpool.models.response
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.joda.time.DateTime
import java.math.BigDecimal
/**
* Response for POST /api/v1/staking/pool/{network}/staking/withdraw
* Unified response for staking transactions (deposit, unstake, withdraw)
*
* Response for:
* - POST /api/v1/staking/pool/{network}/staking/deposit
* - POST /api/v1/staking/pool/{network}/staking/unstake
* - POST /api/v1/staking/pool/{network}/staking/withdraw
*/
@JsonClass(generateAdapter = true)
data class P2PEthPoolWithdrawResponse(
data class P2PEthPoolTransactionResponse(
@Json(name = "amount")
val amount: Double,
val amount: BigDecimal,
@Json(name = "vaultAddress")
val vaultAddress: String,
@Json(name = "delegatorAddress")
@ -20,5 +26,5 @@ data class P2PEthPoolWithdrawResponse(
@Json(name = "createdAt")
val createdAt: DateTime,
@Json(name = "tickets")
val tickets: List<String>,
val tickets: List<String>? = null,
)

View file

@ -1,22 +0,0 @@
package com.tangem.datasource.api.ethpool.models.response
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
* Response for POST /api/v1/staking/pool/{network}/staking/unstake
*
* Note: Contains Bitcoin-related fields (likely documentation error).
* Using as-is per specification.
*/
@JsonClass(generateAdapter = true)
data class P2PEthPoolUnstakeResponse(
@Json(name = "stakerPublicKey")
val stakerPublicKey: String,
@Json(name = "stakeTransactionHash")
val stakeTransactionHash: String,
@Json(name = "unstakeTransactionHex")
val unstakeTransactionHex: String, // unsigned
@Json(name = "unstakeFee")
val unstakeFee: Double,
)

View file

@ -38,6 +38,8 @@ internal object NetworkModule {
private const val TANGEM_TECH_MARKETS_SERVICE_TIMEOUT_SECONDS = 60L
private const val STAKE_KIT_API_TIMEOUT_SECONDS = 60L
private const val P2P_ETH_POOL_API_TIMEOUT_SECONDS = 60L
@Provides
@Singleton
fun provideApiConfigManager(
@ -82,6 +84,12 @@ internal object NetworkModule {
return retrofitApiBuilder.build(
apiConfigId = ApiConfig.ID.P2PEthPool,
applyTimeoutAnnotations = false,
timeouts = Timeouts(
callTimeoutSeconds = P2P_ETH_POOL_API_TIMEOUT_SECONDS,
connectTimeoutSeconds = P2P_ETH_POOL_API_TIMEOUT_SECONDS,
readTimeoutSeconds = P2P_ETH_POOL_API_TIMEOUT_SECONDS,
writeTimeoutSeconds = P2P_ETH_POOL_API_TIMEOUT_SECONDS,
),
)
}