---
## Overview Ton
*Source: [https://docs.p2p.org/docs/overview-ton.md](https://docs.p2p.org/docs/overview-ton.md)*
# Overview
Staking within the TON network using the Staking API is possible in several ways:
* via a Single Nominator Pool — for high-stake validators that nominate themselves.
* via Ton Whales Pools — along with multiple nominators.
For both flows, the staking process consists of the same steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For TON, there are the following networks available:
* `mainnet` — mainnet.
* `testnet` — Testnet environment.
## What's Next?
* [Getting Started](doc:staking-ton).
* [Withdrawal](doc:withdrawal-ton).
* [Sign and Broadcast Transaction](doc:signing-transaction-ton).
* [Staking API](ref:ton-staking-single-nominator-stake) reference.
---
## Unified Api Story Protocol
*Source: [https://docs.p2p.org/docs/unified-api-story-protocol.md](https://docs.p2p.org/docs/unified-api-story-protocol.md)*
# Story Protocol
> ℹ️ Exclusive access: public rollout coming soon
>
> This network is available with exclusive access only. To integrate with the Story Protocol, please [contact us](doc:contacts).
---
## Polkadot Pool Unbond
*Source: [https://docs.p2p.org/reference/polkadot-pool-unbond.md](https://docs.p2p.org/reference/polkadot-pool-unbond.md)*
# Create Unbond Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/staking/pool/unbond": {
"post": {
"operationId": "polkadot-pool-unbond",
"summary": "Create Unbond Request",
"description": "Unbonding tokens within a Polkadot nomination pool where a user has membership refers to the process of withdrawing or releasing tokens that were previously staked or bonded.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"amount": {
"type": "number",
"description": "Amount of tokens to unbond (in usual DOTs/KSMs/WNDs).",
"example": 3
}
},
"required": [
"stashAccountAddress",
"amount"
],
"x-readme-ref-name": "PoolUnbondRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xac0406000b0030ef7dba0203ded255321b86f5f975cf04fd0e9d2b1d941469d469dcc93b89441cdfe6c39f7b"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"amount": {
"type": "number",
"description": "Amount of tokens for bond operations (in usual DOTs/KSMs/WNDs).",
"example": 3
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"unsignedTransaction",
"amount",
"createdAt"
],
"x-readme-ref-name": "PolkadotUnsignedPoolTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119110
},
"message": {
"type": "string",
"default": "The request could not be performed because the requested amount of tokens to unbond exceeds the bonded amount. Please specify the correct amount."
},
"name": {
"type": "string",
"default": "NotEnoughBonedAmountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NotEnoughBonedAmountException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"NotEnoughBonedAmountException": {
"value": {
"error": {
"code": 107110,
"message": "The request could not be performed because the requested amount of tokens to unbond exceeds the bonded amount. Please specify the correct amount.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119135
},
"message": {
"type": "string",
"default": "The unbond request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "UnbondException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "UnbondException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"UnbondException": {
"value": {
"error": {
"code": 107135,
"message": "The unbond request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Signing Transaction Ton
*Source: [https://docs.p2p.org/docs/signing-transaction-ton.md](https://docs.p2p.org/docs/signing-transaction-ton.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the TON network:
1. Initialize the service by installing dependencies from [this repository](https://github.com/AnnaBarotova/ton-sign).
2. In the *ton-sign.ts* file, specify the staker account's seed phrase and prepare unsigned transactions in Base64 encrypted format.
3. Sign the transaction using the code.
4. Finally, send the signed transaction to the TON network by making a POST request to [/api/v1/ton/\{network}/transactions/broadcast](ref:ton-staking-broadcast).
Example request (for the `testnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/ton/testnet/transactions/broadcast \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"walletVersion": "V4",
"unsignedTransaction": "te6ccgEBAQEABgAACCiAmCM=",
"signature": "te6ccgEBAQEABgAACCiAmCM=",
"publicKey": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
}
'
```
* `signedTransaction` — signed transactionin the hexadecimal format which needs to be broadcasted to the network.
* `signature` — external message signature, which has to be signed with the private key.
* `publicKey` — public key of the nominator for the TON network.
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain.
Example response:
```json
{
"error": null,
"result": {
"transactionHash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
}
}
```
* `transactionHash` — hash of the transaction.
# What's Next?
* [Getting Started](doc:staking-ton).
* [Withdrawal](doc:withdrawal-ton).
* [Staking API](ref:ton-staking-single-nominator-stake) reference.
---
## Get Babylon Transaction Status
*Source: [https://docs.p2p.org/reference/get-babylon-transaction-status.md](https://docs.p2p.org/reference/get-babylon-transaction-status.md)*
# Check Transaction Status
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon/{network}/transaction/status/{transactionHash}": {
"get": {
"operationId": "get-babylon-transaction-status",
"summary": "Check Transaction Status",
"description": "Check the status of the transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "babylon-mainnet",
"description": "
Babylon network:
`mainnet` — Babylon mainnet.
`babylon-testnet` — Babylon testnet.
",
"schema": {
"enum": [
"babylon-testnet",
"babylon-mainnet"
],
"type": "string"
}
},
{
"name": "transactionHash",
"required": true,
"in": "path",
"example": "EDDA3AE81ACBF56CB1F154F4957779C04F10B6F4C23B13597EFFC61FE05A02D2",
"description": "Hash of the transaction.",
"schema": {
"format": "[A-Z0-9]{64}",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"failed"
],
"description": "Transaction status."
},
"blockId": {
"type": "number",
"description": "Unique identifier of the block in which the transaction has been included."
},
"fee": {
"type": "number",
"description": "Total fee in SEI charged for processing the transaction."
},
"gas": {
"description": "Computational effort required to execute the transaction measured in gas units.",
"allOf": [
{
"type": "object",
"properties": {
"used": {
"type": "number",
"description": "Amount of gas spent for the transaction."
},
"wanted": {
"type": "number",
"description": "Maximum gas limit for the transaction."
}
},
"required": [
"used",
"wanted"
],
"x-readme-ref-name": "Gas"
}
]
},
"transactionHash": {
"type": "string",
"pattern": "[A-Z0-9]{64}",
"description": "Hash of the transaction."
}
},
"required": [
"status",
"blockId",
"fee",
"gas",
"transactionHash"
],
"x-readme-ref-name": "TransactionStatusResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124102
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided is not valid."
},
"name": {
"type": "string",
"default": "InvalidTransactionHashException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidTransactionHashException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110110
},
"message": {
"type": "string",
"default": "The transaction status could not be obtained because the transaction has been already broadcasted."
},
"name": {
"type": "string",
"default": "TransactionAlreadyBroadcastException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionAlreadyBroadcastException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 110107,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"InvalidTransactionHashException": {
"value": {
"error": {
"code": 110111,
"message": "The transaction status could not be obtained because the transaction hash provided is invalid. Please check the transaction hash satisfies the regular expression undefined format and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"TransactionAlreadyBroadcastException": {
"value": {
"error": {
"code": 110110,
"message": "The transaction status could not be obtained because the transaction has been already broadcasted.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110108
},
"message": {
"type": "string",
"default": "The transaction status could not be obtained because the internal server error occurred."
},
"name": {
"type": "string",
"default": "GetTransactionStatusFailedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetTransactionStatusFailedException"
}
]
}
}
},
"examples": {
"GetTransactionStatusFailedException": {
"value": {
"error": {
"code": 110108,
"message": "The transaction status could not be obtained because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Babylon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Staking Polkadot
*Source: [https://docs.p2p.org/docs/staking-polkadot.md](https://docs.p2p.org/docs/staking-polkadot.md)*
# Getting Started
There are two ways to start staking on the Polkadot network using the Staking API with a public node:
* Stake directly.
* Stake via a nomination pool.
[Get an authentication token](doc:authentication) to start using Staking API. For staking, it is essential to keep a minimum deposit of 1 DOT on the account.
A request example is provided using [cURL](https://curl.se/).
# Staking directly
## 1. Create Bond Request
1. Send a POST request to [/api/v1/polkadot/\{network}/staking/bond](ref:polkadot-staking-bond). Note that there is a [dynamic minimum threshold to stake](https://wiki.polkadot.network/docs/learn-staking).
Example request (for `westend` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/bond \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE",
"rewardDestinationType": "account",
"rewardDestination": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE",
"amount": 1,
"extended": true
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `rewardDestinationType` — rewards destination type:
* `staked` — rewards will be sent to the stash account and added to the current bond (compounding rewards).
* `stash` — rewards will be sent to the stash account as a transferrable balance (not compounding rewards).
* `account` — rewards will be sent to any account specified as a transferrable balance.
* `rewardDestination` — rewards destination account address.
* `amount` — amount of tokens to bond. DOT is used for the main network, KSM for Kusama, and WND for Westend.
* `extended` — optional boolean parameter (`true` or `false`) indicating whether to include additional metadata in the response. This information may be crucial for integrating with custodial platforms, offline signers, or advanced transaction builders.
Example response (for `extended` parameter set to `true`):
```json
{
"result": {
"unsignedTransaction": "0xa8040600070010a5d4e803f690e412f0f0d6a963b89e78f9f44015c8909b2ee57836fff9a739e56897d51b",
"unsignedTransactionSerialized": "7b2261646472657373223a223548647a67....",
"unsignedTransactionPayload": "0x0600070010a5d4e803f690e412f0f0d6a963b89e78f9f44015c8909b2ee57836fff9a739e56897d51b",
"unsignedTransactionObject": {
"blockHash": "0xe9ee44203904ee47859882a6944bb9cb57a28a21146d699f0f731076f3beffe2",
"eraPeriod": 64,
"genesisHash": "0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e",
"metadataRpc": "0x6d6574610e150f000c1c73705f636f72...",
"method": {
"args": {
"value": "1,000,000,000,000",
"payee": {
"Account": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE"
}
},
"method": "bond",
"section": "staking"
},
"nonce": 1,
"specVersion": 1018001,
"transactionVersion": 27,
"tip": 0
},
"stashAccountAddress": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE",
"rewardDestinationType": "account",
"rewardDestination": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE",
"amount": 1,
"createdAt": "2025-04-02T15:38:35.826Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.
* `unsignedTransactionSerialized` — unsigned serialized transaction.
* `unsignedTransactionObject` — full decoded transaction structure with all metadata:
* `blockHash`— hash of the checkpoint block in which the transaction was included.
* `eraPeriod` — validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid.
* `currentEra` — current staking era of the transaction.
* `genesisHash` — hash of the genesis block.
* `metadataRpc` — serialized metadata used for offline decoding and transaction signing.
* `method` is the list of data fields containing information on the method called to construct a transaction.
* `nonce` — nonce of the transaction.
* `specVersion` — current version of the chain specification for the runtime.
* `transactionVersion` — current version of the transaction format.
* `tip` — optional fee used to increase the transaction priority.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `rewardDestinationType` — rewards destination type:
* `staked` — rewards will be sent to the stash account and added to the current bond (compounding rewards).
* `stash` — rewards will be sent to the stash account as a transferrable balance (not compounding rewards).
* `account` — rewards will be sent to any account specified as a transferrable balance.
* `rewardDestination` — rewards destination account address.
* `amount` — amount of tokens to bond. DOT is used for the main network, KSM for Kusama, and WND for Westend.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
## 2. Create Nomination Request
1. Send a POST request to [/api/v1/polkadot/\{network}/staking/nominate](ref:polkadot-staking-nominate) to select validators within the Polkadot network.
Example request (for `westend` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/nominate \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"extended": false
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `extended` — optional boolean parameter (`true` or `false`) indicating whether to include additional metadata in the response.
Example response (for `extended` request parameter set to `false`):
```json
{
"result": {
"unsignedTransaction": "0x2102040605100096b33e0a9647f13198ad16a2812c549a363646a3a7ddbdcc5590f5839c408c6200767f36484b1e2acf5c265c7a64bfb46e95259c66a8189bbcd216195def43685200c21ad1e5198cc0dc3b0f9f43a50f292678f63235ea321e59385d7ee45a7208360018164fa6f9ce28792fb781185e8de4e6eaae34c0f545e5864952fe23c183df0c",
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"targets": [
"5FUJHYEzKpVJfNbtXmR9HFqmcSEz6ak7ZUhBECz7GpsFkSYR",
"5Ek5JCnrRsyUGYNRaEvkufG1i1EUxEE9cytuWBBjA9oNZVsf",
"5GTD7ZeD823BjpmZBCSzBQp7cvHR1Gunq7oDkurZr9zUev2n",
"5CcHdjf6sPcEkTmXFzF2CfH7MFrVHyY5PZtSm1eZsxgsj1KC"
],
"createdAt": "2023-09-18T14:49:23.998Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `targets` — addresses of validators selected in the targets.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
## 3. Add Proxy Account — optional step
It is possible to add a staking proxy to utilize the main stash account less frequently. It allows delegating your staking rights to another account, which can then sign transactions on your behalf. The original account retains all of its rights, and the proxy account can be removed at any time.
1. Send a POST request to [/api/v1/polkadot/\{network}/account/add](ref:polkadot-account-add).
Example request (for `westend` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/account/add \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"proxyAccountAddress": "5Ggpg3JepXM3ZrktNpoc5QA1sKaFVpUPWMRr7jppiMxTuU75",
"extended": false
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding; a proxied address that transfers rights to a proxy account.
* `proxyAccountAddress` — address that receives rights from the proxied account.
* `extended` — optional boolean parameter (`true` or `false`) indicating whether to include additional metadata.
Example response (for `extended` request parameter set to `false`):
```json
{
"result": {
"unsignedTransaction": "0xa404160100cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c0200000000",
"createdAt": "2023-09-18T14:49:23.998Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
# Staking via a nomination pool
## 1. Create Bond Request
1. Create a bond request by sending a POST request to [/api/v1/polkadot/\{network}/staking/pool/bond](ref:polkadot-pool-bond). The P2P.org pool ID on Polkadot mainnet is **238**.
Example request (for `westend` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/pool/bond \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"poolId": 238,
"amount": 3,
"extended": true
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `poolId` — ID of the nomination pool.
* `amount` — amount of tokens to bond. DOT is used for the main network, KSM for Kusama, and WND for Westend.
* `extended` — optional boolean parameter (`true` or `false`) indicating whether to include additional metadata in the response. This information may be crucial for integrating with custodial platforms, offline signers, or advanced transaction builders.
Example response (for `extended` parameter set to `true`):
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"unsignedTransactionSerialized": "7b2261646472657373223a223548647a67....",
"unsignedTransactionPayload": "0x0600070010a5d4e803f690e412f0f0d6a963b89e78f9f44015c8909b2ee57836fff9a739e56897d51b",
"unsignedTransactionObject": {
"blockHash": "0xe9ee44203904ee47859882a6944bb9cb57a28a21146d699f0f731076f3beffe2",
"eraPeriod": 64,
"genesisHash": "0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e",
"metadataRpc": "0x6d6574610e150f000c1c73705f636f72...",
"method": {
"args": {
"value": "3,000,000,000,000",
"payee": {
"Account": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE"
}
},
"method": "bond",
"section": "staking"
},
"nonce": 1,
"specVersion": 1018001,
"transactionVersion": 27,
"tip": 0
},
"stashAccountAddress": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE",
"rewardDestinationType": "account",
"rewardDestination": "5HdzgJMcKFwCeiso1izCWGLyVLk9YFztVFjK4rCadNXz6ztE",
"amount": 3,
"createdAt": "2025-04-02T15:38:35.826Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.
* `unsignedTransactionSerialized` — unsigned serialized transaction.
* `unsignedTransactionObject` — full decoded transaction structure with all metadata:
* `blockHash`— hash of the checkpoint block in which the transaction was included.
* `eraPeriod` — validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid.
* `currentEra` — current staking era of the transaction.
* `genesisHash` — hash of the genesis block.
* `metadataRpc` — serialized metadata used for offline decoding and transaction signing.
* `method` is the list of data fields containing information on the method called to construct a transaction.
* `nonce` — nonce of the transaction.
* `specVersion` — current version of the chain specification for the runtime.
* `transactionVersion` — current version of the transaction format.
* `tip` — optional fee used to increase the transaction priority.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `rewardDestinationType` — rewards destination type:
* `staked` — rewards will be sent to the stash account and added to the current bond (compounding rewards).
* `stash` — rewards will be sent to the stash account as a transferrable balance (not compounding rewards).
* `account` — rewards will be sent to any account specified as a transferrable balance.
* `rewardDestination` — rewards destination account address.
* `amount` — amount of tokens to bond. DOT is used for the main network, KSM for Kusama, and WND for Westend.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
## 2. Create Set Permission Request
1. Grant permission to the pool for managing rewards on your behalf by sending a POST request to [api/v1/polkadot/\{network}/staking/pool/set-claim-permission](ref:polkadot-pool-set-claim-permission).
Example request (for `westend` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/pool/set-claim-permission \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"permission": "PermissionlessAll",
"extended": false
}
'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `permission` — state of the permission to grant:
* `Permissioned` — only you can claim, bond or withdraw rewards. If this level of permission is set, an additional [Claiming Payout request](doc:staking-polkadot-public#3-create-claim-payout-request) is needed.
* `PermissionlessCompound` — compounding of rewards (claim and then bond) on your behalf is permitted.
* `PermissionlessWithdraw` — withdrawing of rewards (claim and then keep as a free balance) on your behalf is permitted.
* `PermissionlessAll` — claiming, bonding and withdrawing rewards on your behalf are permitted.
* `extended` — optional boolean parameter (`true` or `false`) indicating whether to include additional metadata in the response.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000",
"createdAt": "2023-08-24T08:23:18.830Z"
},
"error": {}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
## 3. Create Claim Payout Request
Unlike direct staking, after the rewards is distributed to the nomination pool by a validator, each pool member has to claim their part manually. Since that, to bond, compound or withdraw your rewards, you may need to perform an additional claiming payout request.
Whether it is required depends on the claim rewards permissions you [set in the step 2](doc:staking-polkadot-public#2-create-set-permission-request):
* For `PermissionlessAll`, the step is optional.
* For `Permissioned`, the step is necessary, as you are the only who can claim the rewards.
* For `PermissionlessCompound` and `PermissionlessWithdraw`, the step is required if you want to withdraw and compound your rewards accordingly.
To create claim payout request:
1. Send a POST request to [/api/v1/polkadot/\{network}/staking/pool/claim-payout](ref:polkadot-pool-claim-payout).
Example request (for `westend` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/pool/claim-payout \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"extended": false
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `extended` — optional boolean parameter (`true` or `false`) indicating whether to include additional metadata in the response.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xa404160100cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c0200000000",
"createdAt": "2023-08-24T08:23:18.830Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
# What's Next?
* [Staking API](ref:polkadot-transaction-status) reference.
* [Withdrawal](doc:withdrawal-polkadot).
---
## Babylon Unstake
*Source: [https://docs.p2p.org/reference/babylon-unstake.md](https://docs.p2p.org/reference/babylon-unstake.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon-btc/{network}/staking/unstake": {
"post": {
"operationId": "babylon-unstake",
"summary": "Create Unstake Request",
"description": "Unstake locked assets within the Bitcoin network before the expiration of their time-lock period.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Babylon network:
`mainnet` — Babylon main production environment and Bitcoin mainnet (only locking BTC is currently available).
`testnet` — Babylon testing environment and Bitcoin testnet called sigNet.
",
"schema": {
"enum": [
"testnet",
"mainnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stakerPublicKey": {
"type": "string",
"description": "Staker public key.",
"example": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
},
"stakeTransactionHash": {
"type": "string",
"description": "Hash of the initial staking transaction.",
"example": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028"
}
},
"required": [
"stakerPublicKey",
"stakeTransactionHash"
],
"x-readme-ref-name": "UnstakeRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"stakerPublicKey": {
"type": "string",
"description": "Staker public key.",
"example": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
},
"stakeTransactionHash": {
"type": "string",
"description": "Staker taproot address.",
"example": ""
},
"unstakeTransactionHex": {
"type": "string",
"description": "Unsigned transaction for the unstake request in the hexadecimal format. Sign the transaction to consequently broadcast it to the Bitcoin blockchain.",
"example": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000"
},
"unstakeFee": {
"type": "number",
"description": "Total fee in SATOSHI charged for unlocking the staked assets and processing the transaction (1 BTC = 10⁸ SATOSHI).",
"example": 1000
}
},
"required": [
"stakerPublicKey",
"stakeTransactionHash",
"unstakeTransactionHex",
"unstakeFee"
],
"x-readme-ref-name": "UnstakeResponseDto"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 120102
},
"message": {
"type": "string",
"default": "The requested transaction is not a stake transaction"
},
"name": {
"type": "string",
"default": "TransactionIsNotStake"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionIsNotStake"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 120100,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"TransactionIsNotStake": {
"value": {
"error": {
"code": 120102,
"message": "The requested transaction is not a stake transaction",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 120100,
"message": "The requested transaction was not found.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Babylon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Create Celestia Redelegate To Transaction
*Source: [https://docs.p2p.org/reference/create-celestia-redelegate-to-transaction.md](https://docs.p2p.org/reference/create-celestia-redelegate-to-transaction.md)*
# Create Redelegate To Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/celestia/{network}/staking/redelegate/to": {
"post": {
"operationId": "create-celestia-redelegate-to-transaction",
"summary": "Create Redelegate To Request",
"description": "Create redelegate to default validator request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "celestia-mainnet-beta",
"description": "
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stashAccountAddress": {
"type": "string",
"description": "Proxied account is an address that transfers rights to a proxy account. The original account retains all of its rights, and the proxy account can be removed at any time.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"proxyAccountAddress": {
"type": "string",
"description": "Proxy account is an address that receives proxied account rights.",
"example": "5Ca1Bqfzc4DdU6zMXLu5UhpRtdX5EzCseDXW9YisVm25ATeJ"
}
},
"required": [
"stashAccountAddress",
"proxyAccountAddress"
],
"x-readme-ref-name": "AvailRemoveRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000"
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "AvailTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119107
},
"message": {
"type": "string",
"default": "The proxy account address provided could not be found. Please specify the correct address."
},
"name": {
"type": "string",
"default": "ProxyNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ProxyNotFoundException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 119101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Avail address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"ProxyNotFoundException": {
"value": {
"error": {
"code": 119107,
"message": "The proxy account address provided could not be found. Please specify the correct address.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119121
},
"message": {
"type": "string",
"default": "The proxy account address could not be removed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "RemoveException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "RemoveException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"RemoveException": {
"value": {
"error": {
"code": 119121,
"message": "The proxy account address could not be removed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Overview Avail
*Source: [https://docs.p2p.org/docs/overview-avail.md](https://docs.p2p.org/docs/overview-avail.md)*
# Overview
Staking on the Avail network, also referred to bonding, using the Staking API is possible in two ways:
* By staking directly.
* By staking via a nomination pool.
The [direct staking](doc:staking-avail#staking-directly) process consists of several steps:
1. Create a bond request: submit a bond to the Avail network.
2. Create a nomination request: select validators within the Avail network.
3. Add a staking proxy: delegate your staking rights to another account, which can then sign transactions on your behalf (optional).
To [stake via a nomination pool](doc:staking-avail#staking-via-a-nomination-pool):
1. Create a claim permission request to allow your nomination pool to bond and nominate on your behalf.
2. Create a bond request to the Avail network.
3. Create a claim payout request.
[Get an authentication token](doc:authentication) to start using Staking API in any of the flows.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For Avail, there are several networks available:
* `mainnet` — Avail mainnet.
* `testnet` — Turing environment.
## What's Next?
* [Getting Started](doc:staking-avail).
* [Withdrawal](doc:withdrawal-avail).
* [Sign and Broadcast Transaction](doc:signing-transaction-avail).
* [Staking API](ref:avail-transaction-status) reference.
---
## Data Network Stake
*Source: [https://docs.p2p.org/reference/data-network-stake.md](https://docs.p2p.org/reference/data-network-stake.md)*
# Get Network Stake
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/network/stake": {
"get": {
"operationId": "data-network-stake",
"summary": "Get Network Stake",
"description": "Method to retrieve network stake by staking period.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"polygon",
"sui",
"avail",
"ethereum"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stakingPeriodNumber": {
"type": "number",
"description": "Unique identifier for the current staking period.",
"example": 1227
},
"stakingPeriodStart": {
"format": "date-time",
"type": "string",
"description": "Timestamp of the staking period start in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
},
"stakingPeriodEnd": {
"format": "date-time",
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
},
"stake": {
"type": "number",
"description": "Stake for the current staking period",
"example": 665113860
},
"currency": {
"type": "string",
"enum": [
"ETH",
"SOL",
"DOT",
"KSM",
"GLMR",
"VARA",
"ATOM",
"MATIC",
"SUI",
"AVAIL",
"TON",
"NEAR",
"ADA"
],
"description": "Reward currency.",
"example": "DOT"
},
"updatedAt": {
"format": "date-time",
"type": "string",
"description": "Timestamp of the last update to this data.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"stakingPeriodNumber",
"stakingPeriodStart",
"stakingPeriodEnd",
"stake",
"currency",
"updatedAt"
],
"x-readme-ref-name": "GetNetworkStakeResponse"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetNetworkStakeListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115207
},
"message": {
"type": "string",
"default": "The data for the parameters provided could not be found."
},
"name": {
"type": "string",
"default": "GetNetworkStatsHistoryNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetNetworkStatsHistoryNotFoundException"
}
]
}
}
},
"examples": {
"GetNetworkStatsHistoryNotFoundException": {
"value": {
"error": {
"code": 115200,
"message": "The data for the parameters provided could not be found.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115206
},
"message": {
"type": "string",
"default": "The request could not be performed because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetNetworkStatsHistoryException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetNetworkStatsHistoryException"
}
]
}
}
},
"examples": {
"GetNetworkStatsHistoryException": {
"value": {
"error": {
"code": 115206,
"message": "The request could not be performed because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Network"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Polkadot Pool Withdraw Unbonded
*Source: [https://docs.p2p.org/reference/polkadot-pool-withdraw-unbonded.md](https://docs.p2p.org/reference/polkadot-pool-withdraw-unbonded.md)*
# Withdraw Unbonded Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/staking/pool/withdraw-unbonded": {
"post": {
"operationId": "polkadot-pool-withdraw-unbonded",
"summary": "Withdraw Unbonded Request",
"description": "Withdrawing tokens within the Polkadot network that were previously unbonded and the following exiting the nomination pool.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"poolId": {
"type": "number",
"description": "ID of the nomination pool.",
"example": 1
}
},
"required": [
"stashAccountAddress",
"poolId"
],
"x-readme-ref-name": "PoolWithdrawUnbondedRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action."
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format."
}
},
"required": [
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "PoolWithdrawalTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119103
},
"message": {
"type": "string",
"default": "The transaction could not be found. Please specify the correct transaction data."
},
"name": {
"type": "string",
"default": "BondNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119105
},
"message": {
"type": "string",
"default": "The request could not be performed because the controller address does not correspond to the provided one."
},
"name": {
"type": "string",
"default": "WrongControllerException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongControllerException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 107139
},
"message": {
"type": "string",
"default": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool."
},
"name": {
"type": "string",
"default": "PolkadotPoolDoesNotExistsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PolkadotPoolDoesNotExistsException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"BondNotFoundException": {
"value": {
"error": {
"code": 107103,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"WrongControllerException": {
"value": {
"error": {
"code": 107105,
"message": "The request could not be performed because the controller address does not correspond to the provided one.",
"type": "client"
},
"result": null
}
},
"PolkadotPoolDoesNotExistsException": {
"value": {
"error": {
"code": 107139,
"message": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119136
},
"message": {
"type": "string",
"default": "The withdrawal request could not be performed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "WithdrawUnbondedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WithdrawUnbondedException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"WithdrawUnbondedException": {
"value": {
"error": {
"code": 107136,
"message": "The withdrawal request could not be performed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Aptos Transaction Status
*Source: [https://docs.p2p.org/reference/aptos-transaction-status.md](https://docs.p2p.org/reference/aptos-transaction-status.md)*
# Get Transaction Status
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/aptos/{network}/transaction/status/{transactionHash}": {
"get": {
"operationId": "aptos-transaction-status",
"summary": "Get Transaction Status",
"description": "Check the status of the transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Aptos network:
`mainnet` — Aptos mainnet.
`testnet` — Aptos devnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
},
{
"name": "transactionHash",
"required": true,
"in": "path",
"description": "Transaction hash.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
},
"gas": {
"description": "Computational effort required to execute the transaction, measured in gas units.",
"allOf": [
{
"type": "object",
"properties": {
"unitPrice": {
"type": "number",
"description": "Price per unit of gas in Octas for processing the Aptos transaction.",
"example": 100,
"minimum": 0
},
"maxGasLimit": {
"type": "number",
"description": "Maximum gas limit for the transaction.",
"example": 100,
"minimum": 0
},
"used": {
"type": "number",
"description": "Amount of gas spent for the transaction.",
"example": 100,
"minimum": 0
}
},
"required": [
"unitPrice",
"maxGasLimit"
],
"x-readme-ref-name": "GasDataDto"
}
]
},
"senderAddress": {
"type": "string",
"description": "Address of the transaction sender.",
"example": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a"
},
"sequenceNumber": {
"type": "number",
"description": "Number of transactions that have been submitted and committed on chain from the sender account.",
"example": 42,
"minimum": 0
},
"status": {
"type": "string",
"enum": [
"failed",
"pending",
"success"
],
"description": "Status of the transaction.",
"example": "success"
},
"transactionHash": {
"type": "string",
"description": "Hash of the transaction.",
"example": "0x8d80b8ed85b578eeb873731101a926221701ee48218f6c9b83895f7ac1535641"
}
},
"required": [
"gas",
"senderAddress",
"sequenceNumber",
"status",
"transactionHash"
],
"x-readme-ref-name": "GetTransactionStatusResponseDto"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124102
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided is not valid."
},
"name": {
"type": "string",
"default": "InvalidTransactionHashException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidTransactionHashException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
}
]
}
}
},
"examples": {
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 124100,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"InvalidTransactionHashException": {
"value": {
"error": {
"code": 124102,
"message": "The request could not be performed because the transaction hash provided is not valid.",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 124103,
"message": "The request could not be performed because the transaction hash provided does not exist.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Aptos"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Eth Increment Request Create
*Source: [https://docs.p2p.org/reference/eth-increment-request-create.md](https://docs.p2p.org/reference/eth-increment-request-create.md)*
# Create Staking Increment Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/direct/increment-request/create": {
"post": {
"operationId": "eth-increment-request-create",
"summary": "Create Staking Increment Request",
"description": "Set up a new increment request.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"example": "8c48cd8d-99cb-4149-8975-f0822fe46d06",
"description": "Arbitrary UUID. You can later use that UUID to check the status of the set-up operation."
},
"withdrawalAddress": {
"type": "string",
"description": "Withdrawal address for the validators.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"pubkeys": {
"description": "List of validator public keys.",
"example": [
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
],
"items": {
"type": "string"
},
"type": "array"
},
"amountPerValidator": {
"type": "number",
"description": "Amount of tokens to stake in Gwei per validator.",
"example": "1000000000",
"minimum": 1000000000,
"maximum": 2016000000000
}
},
"required": [
"id",
"pubkeys",
"amountPerValidator"
],
"x-readme-ref-name": "CreateIncrementRequestRequest"
}
}
}
},
"responses": {
"201": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"type": "boolean",
"example": true
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103139
},
"message": {
"type": "string",
"default": "Increment request with this ID already exists"
},
"name": {
"type": "string",
"default": "IncrementRequestIdAlreadyExistException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "IncrementRequestIdAlreadyExistException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103106
},
"message": {
"type": "string",
"default": "The transaction could not be created because one or more validators are not participating currently in the validator activities."
},
"name": {
"type": "string",
"default": "ValidatorNotActiveException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorNotActiveException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103152
},
"message": {
"type": "string",
"default": "Error while pubkeys has duplicates"
},
"name": {
"type": "string",
"default": "PubkeysDuplicatesException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PubkeysDuplicatesException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103147
},
"message": {
"type": "string",
"default": "The transaction could not be created because the validator is not consolidated."
},
"name": {
"type": "string",
"default": "ValidatorNotConsolidatedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorNotConsolidatedException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103154
},
"message": {
"type": "string",
"default": "Error while pubkeys is not for direct stake flow"
},
"name": {
"type": "string",
"default": "IncrementOnlyDirectStakeValidatorsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "IncrementOnlyDirectStakeValidatorsException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"IncrementRequestIdAlreadyExistException": {
"value": {
"error": {
"code": 103139,
"message": "Increment request with this ID already exists.",
"type": "client"
},
"result": null
}
},
"ValidatorNotActiveException": {
"value": {
"error": {
"code": 103106,
"message": "The transaction could not be created because one or more validators are not participating currently in the validator activities.",
"type": "client"
},
"result": null
}
},
"PubkeysDuplicatesException": {
"value": {
"error": {
"code": 103152,
"message": "Error while pubkeys has duplicates",
"type": "client"
},
"result": null
}
},
"ValidatorNotConsolidatedException": {
"value": {
"error": {
"code": 103147,
"message": "The transaction could not be created because the validator is not consolidated.",
"type": "client"
},
"result": null
}
},
"IncrementOnlyDirectStakeValidatorsException": {
"value": {
"error": {
"code": 103154,
"message": "Error while pubkeys is not for direct stake flow",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103141
},
"message": {
"type": "string",
"default": "Error while sending increment request"
},
"name": {
"type": "string",
"default": "IncrementRequestSendException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "IncrementRequestSendException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"IncrementRequestSendException": {
"value": {
"error": {
"code": 103141,
"message": "Error while sending increment request",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Ethereum"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Overview Polkadot
*Source: [https://docs.p2p.org/docs/overview-polkadot.md](https://docs.p2p.org/docs/overview-polkadot.md)*
# Overview
Staking on the Polkadot network, also referred to bonding, using the Staking API is possible in two ways:
* By staking directly.
* By staking via a nomination pool.
The [direct staking](doc:staking-polkadot-public#staking-directly) process consists of several steps:
1. Create a bond request: submit a bond to the Polkadot network.
2. Create a nomination request: select validators within the Polkadot network.
3. Add a staking proxy: delegate your staking rights to another account, which can then sign transactions on your behalf (optional).
To [stake via a nomination pool](doc:staking-polkadot-public#staking-via-a-nomination-pool):
1. Create a claim permission request to allow your nomination pool to bond and nominate on your behalf.
2. Create a bond request to the Polkadot network.
3. Create a claim payout request.
[Get an authentication token](doc:authentication) to start using Staking API in any of the flows.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For Polkadot, there are several networks available:
* `mainnet` — Polkadot mainnet.
* `kusama` — Kusama mainnet.
* `westend` — Testnet environment.
## What's Next?
* [Getting Started](doc:staking-polkadot-public).
* [Withdrawal](doc:withdrawal-polkadot).
* [Sign and Broadcast Transaction](doc:signing-transaction-polkadot).
* [Staking API](ref:polkadot-transaction-status) reference.
---
## Aptos Staking Delegated Reactivate
*Source: [https://docs.p2p.org/reference/aptos-staking-delegated-reactivate.md](https://docs.p2p.org/reference/aptos-staking-delegated-reactivate.md)*
# Create Reactivate Stake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/aptos/{network}/staking/delegated/reactivate": {
"post": {
"operationId": "aptos-staking-delegated-reactivate",
"summary": "Create Reactivate Stake Request",
"description": "Construct a serialized transaction to reactivate undelegated tokens and stake them again in the delegation pool.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Aptos network:
`mainnet` — Aptos mainnet.
`testnet` — Aptos devnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"amount": {
"format": "datetime",
"type": "string",
"description": "Amount of tokens to reactivate in Octas (1 APT = 10⁸ Octas).",
"example": 1100000000,
"nullable": false
},
"delegatorAddress": {
"type": "string",
"description": "Delegator account address.",
"nullable": false,
"example": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a"
},
"gas": {
"description": "Computational effort required to execute the transaction, measured in gas units.",
"nullable": false,
"allOf": [
{
"type": "object",
"properties": {
"unitPrice": {
"type": "number",
"description": "Price per unit of gas in Octas for processing the Aptos transaction.",
"example": 100,
"minimum": 0
},
"maxGasLimit": {
"type": "number",
"description": "Maximum gas limit for the transaction.",
"example": 100,
"minimum": 0
},
"used": {
"type": "number",
"description": "Amount of gas spent for the transaction.",
"example": 100,
"minimum": 0
}
},
"required": [
"unitPrice",
"maxGasLimit"
],
"x-readme-ref-name": "GasDataDto"
}
]
}
},
"required": [
"amount",
"delegatorAddress",
"gas"
],
"x-readme-ref-name": "CreateReactivateTransactionRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"amount": {
"format": "datetime",
"type": "string",
"description": "Amount of tokens to stake in Octas (1 APT = 10⁸ Octas).",
"example": 1100000000,
"nullable": false
},
"delegatorAddress": {
"type": "string",
"description": "Delegator account address.",
"nullable": false,
"example": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a"
},
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa571a5bc9b1bfd5fe58e6e09a5be251a3299985494d022959ce206f1f23f752e21000000000000000200000000000000000000000000000000000000000000000000000000000000010f64656c65676174696f6e5f706f6f6c096164645f7374616b650002207a2ddb6af66beb0d9987c6c9010cb9053454f067e16775a8ecf19961195c3d28080100000000000000400d0300000000006400000000000000e5742068000000000200",
"nullable": false
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z",
"nullable": false
}
},
"required": [
"amount",
"delegatorAddress",
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "CreateReactivateTransactionResponseDto"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124106
},
"message": {
"type": "string",
"default": "The request could not be performed because the gas unit price provided is too low."
},
"name": {
"type": "string",
"default": "GasUnitPriceTooLowException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GasUnitPriceTooLowException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124109
},
"message": {
"type": "string",
"default": "The request could not be performed because the account does not have enough balance to perform the transaction."
},
"name": {
"type": "string",
"default": "InsufficientBalanceException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientBalanceException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124108
},
"message": {
"type": "string",
"default": "The request could not be performed because the delegator address provided is not valid."
},
"name": {
"type": "string",
"default": "InvalidDelegatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidDelegatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124107
},
"message": {
"type": "string",
"default": "The request could not be performed because the max gas amount provided is too low."
},
"name": {
"type": "string",
"default": "MaxGasAmountTooLowException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "MaxGasAmountTooLowException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124110
},
"message": {
"type": "string",
"default": "The request could not be performed because the simulation of the transaction failed. Reason: %s."
},
"name": {
"type": "string",
"default": "SimulateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SimulateTransactionException"
}
]
}
}
},
"examples": {
"GasUnitPriceTooLowException": {
"value": {
"error": {
"code": 124106,
"message": "The request could not be performed because the gas unit price provided is too low.",
"type": "client"
},
"result": null
}
},
"InsufficientBalanceException": {
"value": {
"error": {
"code": 124109,
"message": "The request could not be performed because the account does not have enough balance to perform the transaction.",
"type": "client"
},
"result": null
}
},
"InvalidDelegatorAddressException": {
"value": {
"error": {
"code": 124108,
"message": "The request could not be performed because the delegator address provided is not valid.",
"type": "client"
},
"result": null
}
},
"MaxGasAmountTooLowException": {
"value": {
"error": {
"code": 124107,
"message": "The request could not be performed because the max gas amount provided is too low.",
"type": "client"
},
"result": null
}
},
"SimulateTransactionException": {
"value": {
"error": {
"code": 124110,
"message": "The request could not be performed because the simulation of the transaction failed. Reason: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Aptos"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Polkadot Account Add
*Source: [https://docs.p2p.org/reference/polkadot-account-add.md](https://docs.p2p.org/reference/polkadot-account-add.md)*
# Add Staking Proxy Account
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/account/add": {
"post": {
"operationId": "polkadot-account-add",
"summary": "Add Staking Proxy Account",
"description": "Adding a staking proxy account allows users to utilize an account less frequently while maintaining active participation in the Polkadot network based on the weight of tokens held within that account.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Proxied account is an address that transfers rights to a proxy account. The original account retains all of its rights, and the proxy account can be removed at any time.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"proxyAccountAddress": {
"type": "string",
"description": "Proxy account is an address that receives proxied account rights.",
"example": "5Ggpg3JepXM3ZrktNpoc5QA1sKaFVpUPWMRr7jppiMxTuU75"
}
},
"required": [
"stashAccountAddress",
"proxyAccountAddress"
],
"x-readme-ref-name": "AddRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "TransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119120
},
"message": {
"type": "string",
"default": "The proxy account address could not be added because the internal server error occurred."
},
"name": {
"type": "string",
"default": "AddException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124109
},
"message": {
"type": "string",
"default": "The request could not be performed because the account does not have enough balance to perform the transaction."
},
"name": {
"type": "string",
"default": "InsufficientBalanceException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientBalanceException"
}
]
}
}
},
"examples": {
"AddException": {
"value": {
"error": {
"code": 107120,
"message": "The proxy account address could not be added because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"InsufficientBalanceException": {
"value": {
"error": {
"code": 107102,
"message": "The request could not be performed because the amount of tokens on account is insufficient. Please check that the balance is more than undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Broadcast Sei Transaction
*Source: [https://docs.p2p.org/reference/broadcast-sei-transaction.md](https://docs.p2p.org/reference/broadcast-sei-transaction.md)*
# Broadcast Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/sei/{network}/transaction/send": {
"post": {
"operationId": "broadcast-sei-transaction",
"summary": "Broadcast Transaction",
"description": "Broadcast transaction to the Sei network.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "pacific-1",
"description": "
Sei network:
`pacific-1` — Sei mainnet.
`atlantic-2` — Sei testnet.
",
"schema": {
"enum": [
"pacific-1",
"atlantic-2"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"signedTransaction": {
"type": "string",
"description": "Signed transaction in Base64 encrypted format which needs to be broadcast to the network."
}
},
"required": [
"signedTransaction"
],
"x-readme-ref-name": "BroadcastTransactionRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"failed"
],
"description": "Transaction status."
},
"blockId": {
"type": "number",
"description": "Unique identifier of the block in which the transaction has been included."
},
"fee": {
"type": "number",
"description": "Total fee in SEI charged for processing the transaction."
},
"gas": {
"description": "Computational effort required to execute the transaction measured in gas units.",
"allOf": [
{
"type": "object",
"properties": {
"used": {
"type": "number",
"description": "Amount of gas spent for the transaction."
},
"wanted": {
"type": "number",
"description": "Maximum gas limit for the transaction."
}
},
"required": [
"used",
"wanted"
],
"x-readme-ref-name": "Gas"
}
]
},
"transactionHash": {
"type": "string",
"pattern": "[A-Z0-9]{64}",
"description": "Hash of the transaction."
}
},
"required": [
"status",
"blockId",
"fee",
"gas",
"transactionHash"
],
"x-readme-ref-name": "TransactionStatusResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 110107,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110109
},
"message": {
"type": "string",
"default": "The transaction could not be broadcasted because the internal server error occurred."
},
"name": {
"type": "string",
"default": "BroadcastTransactionFailedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BroadcastTransactionFailedException"
}
]
}
}
},
"examples": {
"BroadcastTransactionFailedException": {
"value": {
"error": {
"code": 110109,
"message": "The transaction could not be broadcasted because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Sei"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Polygon Staking Undelegate
*Source: [https://docs.p2p.org/reference/polygon-staking-undelegate.md](https://docs.p2p.org/reference/polygon-staking-undelegate.md)*
# Create Undelegate Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polygon/staking/undelegate": {
"post": {
"operationId": "polygon-staking-undelegate",
"summary": "Create Undelegate Request",
"description": "Prepare previously staked tokens for unstaking.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"claimAmount": {
"type": "string",
"description": "Amount of tokens to undelegate, specified in 10^(-18) MATIC.",
"example": "100000000000000000"
},
"stakerAddress": {
"type": "string",
"description": "Staker account address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
}
},
"required": [
"claimAmount",
"stakerAddress"
],
"x-readme-ref-name": "UndelegateRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polygon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Restaking
*Source: [https://docs.p2p.org/docs/withdrawal-restaking.md](https://docs.p2p.org/docs/withdrawal-restaking.md)*
# Withdrawal
For the Restaking API, it is possible to withdraw the node operator's staked Ethereum in one of two ways:
1. Partial withdrawal of the rewards balance staked above 32 ETH.
2. Full withdrawal of all staked assets, followed by liquidating the operator node and exiting the network.
Both flows include a checkpoint proof, which allows checking and comparing the EigenPod and Beacon chain balances. After completing a checkpoint, it is possible to either withdraw accumulated yield or continue with withdrawing the whole stake fully.
> 🚧
>
> Note that only one active checkpoint can be run per an EigenPod, and once started, checkpoints cannot be cancelled (only completed). Since the gas cost of a checkpoint does not depend on the reward amount, it is essential to plan these checkpoints accordingly. In general, starting a new checkpoint more frequently than in 8 days would result in no benefit for the user.
Request examples are provided using [cURL](https://curl.se/).
***
To initiate a withdrawal in the Ethereum network using the Restaking API, follow these steps:
1. Start Checkpoint: construct a serialized transaction to start a checkpoint, proving the expected funds are deposited in the EigenPod and/or validator.
2. Verify Checkpoint Proofs: construct a serialized transaction to verify received proofs.
At this stage, the partial withdrawal scenario is complete.
To fully withdraw a validator and its earnings, continue with the additional steps:
3. Prepare Undelegate Restake Transaction: construct a serialized transaction to undelegate the staked amount of tokens from a node operator.
4. Queue Withdrawals: construct a serialized transaction to queue withdrawals.
5. Create Withdrawal Request: construct a serialized transaction to initiate the validator's exit from the network.
6. Complete Queued Withdrawals: construct a serialized transaction to complete queued withdrawals after the escrow period.
# 1. Start Checkpoint Proof
1\. Create a serialized transaction to start a checkpoint by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/start-checkpoint](ref:eth-eigen-start-checkpoint).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/start-checkpoint \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'authorization: Bearer ' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5"
}
'
```
* `eigenPodOwnerAddress` — owner of the EigenPod address.
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0xaE1ACF4F8bf25D9Aa365E2986BaB1d1B201Bb59c",
"gasLimit": "10000000",
"data": "0x88676cad00000000000000000000000000000000000000000",
"value": "0",
"chainId": "17000",
"type": "2",
"maxFeePerGas": "1000038",
"maxPriorityFeePerGas": "1000000"
},
"error": {}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
2\. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are beginning the process of proving that the amount of validator ETH is active and its withdrawal credentials are pointing to the EigenPod.
# 2. Verify Checkpoint Proofs
1\. Create a serialized transaction to verify received checkpoint proofs by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/verify-checkpoint-proofs](ref:eth-eigen-verify-checkpoint-proofs).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/verify-checkpoint-proofs \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'authorization: Bearer ' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"activateTx": "0x968be713c254134163da7aefef4f27b02b96a393d56306ea471d"
}
'
```
* `eigenPodOwnerAddress` — owner of the EigenPod address.
* `activateTx` — hash of the start checkpoint transaction.
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0xaE1ACF4F8bf25D9Aa365E2986BaB1d1B201Bb59c",
"gasLimit": "10000000",
"data": "0x88676cad00000000000000000000000000000000000000000",
"value": "0",
"chainId": "17000",
"type": "2",
"maxFeePerGas": "1000038",
"maxPriorityFeePerGas": "1000000"
},
"error": {}
}
```
Example response is the same as in the [Start Checkpoint Proof](doc:restaking-eth#1-start-checkpoint-proof) step.
2\. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
> 🚧 Note that the transaction signing is time sensitive
>
> The transaction has to be signed in 8192 slots (approximately 27 hours).
>
> If the time has expired and you have not signed the transaction yet, [contact](doc:contacts) us for support.
By broadcasting this transaction, you are making progress on submitting checkpoint proofs to EigenLayer contracts. After the checkpoint completion, the rewards will be withdrawn to the `eigenPodOwnerAddress`.
This is the last step in the partial withdrawal flow.
# 3. Create Undelegate Request
To continue the flow to fully withdraw the stake and the rewards amount:
1\. Construct a serialized transaction to undelegate the staked amount of tokens from a node operator by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/undelegate](ref:eth-eigen-undelegate).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/undelegate \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'authorization: Bearer ' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5"
}
'
```
* `eigenPodOwnerAddress` — owner of the EigenPod address.
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0xA44151489861Fe9e3055d95adC98FbD462B948e7",
"gasLimit": "10000000",
"data": "0xda8be864000000000000000000000000368f823e4dfe271dc82",
"value": "0",
"chainId": "17000",
"type": "2",
"maxFeePerGas": "1000036",
"maxPriorityFeePerGas": "1000000"
},
"error": {}
}
```
Example response is the same as in the [Start Checkpoint Proof](doc:restaking-eth#1-start-checkpoint-proof) step.
2\. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
# 4. Queue Withdrawals
1\. Construct a serialized transaction to queue withdrawals for all the deposited tokens by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/queue-withdrawals](ref:eth-eigen-queue-withdrawals).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/queue-withdrawals \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'authorization: Bearer ' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"amount": "32"
}
'
```
* `eigenPodOwnerAddress` — owner of the EigenPod address.
* `amount` — amount of ETH that is being unstaked.
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0xA44151489861Fe9e3055d95adC98FbD462B948e7",
"gasLimit": "10000000",
"data": "0x0dd8dd0200000000000000000000000000000000000000000",
"value": "0",
"chainId": "17000",
"type": "2",
"maxFeePerGas": "1000034",
"maxPriorityFeePerGas": "1000000"
},
"error": {}
}
```
Example response is the same as in the [Start Checkpoint Proof](doc:restaking-eth#1-start-checkpoint-proof) step.
2\. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
# 5. Prepare Withdrawal Transaction
1\. Construct a serialized transaction to initiate the network exit for active validators by sending a POST request to [/api/v1/eth/staking/direct/tx/withdrawal](ref:eth-staking-withdrawal).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/withdrawal \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"pubkeys": [
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
]
}
'
```
* `pubkeys` — list of validators public keys.
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0x8C87EFBA90414687A66C8B2E7D21039E81d55456",
"gasLimit": "100000",
"data": "0x0dd8dd0200000000000000000000000000000000000000000",
"value": "0",
"chainId":17000,
"type": 2,
"maxFeePerGas": "1000036",
"maxPriorityFeePerGas" : "1000000"
}
}
```
Example response is the same as in the [Start Checkpoint Proof](doc:restaking-eth#1-start-checkpoint-proof) step.
2\. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network. By broadcasting this transaction, you are submitting the validator's exit from the Ethereum network.
> 🚧 There is a withdrawal delay for EigenLayer contracts
>
> As a security measure, users have to wait for an escrow period before they can withdraw unstaked assets.
>
> For testing environment, it takes 10 blocks, which is roughly 2 minutes, and for the mainnet, it takes up to 7 days.
# 6. Complete Queued Withdrawals
1\. After the withdrawal escrow period has elapsed, construct a serialized transaction to complete queued withdrawals by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/complete-queued-withdrawals](ref:eth-eigen-complete-queued-withdrawals).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/complete-queued-withdrawals \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'authorization: Bearer ' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"queueWithdrawalsTx": "0x5d7baf40071d011f784ced45fa815ea25dfd659837db"
}
'
```
* `eigenPodOwnerAddress` — owner of the EigenPod address.
* `queueWithdrawalsTx` — hash of the queue withdrawals transaction.
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0xA44151489861Fe9e3055d95adC98FbD462B948e7",
"gasLimit": "10000000",
"data": "0x3340439600000000000000000000000000000000000000000",
"value": "0",
"chainId": "17000",
"type": "2",
"maxFeePerGas": "1000028",
"maxPriorityFeePerGas": "1000000"
},
"error": {}
}
```
Example response is the same as in the [Start Checkpoint Proof](doc:restaking-eth#1-start-checkpoint-proof) step.
2\. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
## What's Next?
* [Getting Started](doc:restaking-eth).
* [Restaking API](ref:eth-eigen-create-pod) reference.
---
## Avail Pool Withdraw Unbonded
*Source: [https://docs.p2p.org/reference/avail-pool-withdraw-unbonded.md](https://docs.p2p.org/reference/avail-pool-withdraw-unbonded.md)*
# Withdraw Unbonded Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/staking/pool/withdraw-unbonded": {
"post": {
"operationId": "avail-pool-withdraw-unbonded",
"summary": "Withdraw Unbonded Request",
"description": "Withdrawing tokens within the Avail network that were previously unbonded and the following exiting the nomination pool.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Avail network:
`mainnet` — Avail mainnet.
`testnet` — Avail testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"poolId": {
"type": "number",
"description": "ID of the nomination pool.",
"example": 1
}
},
"required": [
"stashAccountAddress",
"poolId"
],
"x-readme-ref-name": "AvailPoolWithdrawUnbondedRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action."
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format."
}
},
"required": [
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "AvailPoolWithdrawalTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119103
},
"message": {
"type": "string",
"default": "The transaction could not be found. Please specify the correct transaction data."
},
"name": {
"type": "string",
"default": "BondNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119105
},
"message": {
"type": "string",
"default": "The request could not be performed because the controller address does not correspond to the provided one."
},
"name": {
"type": "string",
"default": "WrongControllerException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongControllerException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119139
},
"message": {
"type": "string",
"default": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool."
},
"name": {
"type": "string",
"default": "AvailPoolDoesNotExistsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AvailPoolDoesNotExistsException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 119101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Avail address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"BondNotFoundException": {
"value": {
"error": {
"code": 119103,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"WrongControllerException": {
"value": {
"error": {
"code": 119105,
"message": "The request could not be performed because the controller address does not correspond to the provided one.",
"type": "client"
},
"result": null
}
},
"AvailPoolDoesNotExistsException": {
"value": {
"error": {
"code": 119139,
"message": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119136
},
"message": {
"type": "string",
"default": "The withdrawal request could not be performed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "WithdrawUnbondedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WithdrawUnbondedException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"WithdrawUnbondedException": {
"value": {
"error": {
"code": 119136,
"message": "The withdrawal request could not be performed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Polkadot Pool Bond
*Source: [https://docs.p2p.org/reference/polkadot-pool-bond.md](https://docs.p2p.org/reference/polkadot-pool-bond.md)*
# Create Bond Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/staking/pool/bond": {
"post": {
"operationId": "polkadot-pool-bond",
"summary": "Create Bond Request",
"description": "Creating a bond request on the Polkadot nomination pool where a user has membership in exchange for some other benefit.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"poolId": {
"type": "number",
"description": "ID of the nomination pool.",
"example": 1
},
"amount": {
"type": "number",
"description": "Amount of tokens to bond (in usual DOTs/KSMs/WNDs).",
"example": 3
}
},
"required": [
"stashAccountAddress",
"poolId",
"amount"
],
"x-readme-ref-name": "PoolBondRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xac0406000b0030ef7dba0203ded255321b86f5f975cf04fd0e9d2b1d941469d469dcc93b89441cdfe6c39f7b"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"amount": {
"type": "number",
"description": "Amount of tokens to bond (in usual DOTs/KSMs/WNDs).",
"example": 3
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"unsignedTransaction",
"amount",
"createdAt"
],
"x-readme-ref-name": "PolkadotUnsignedPoolBondTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124109
},
"message": {
"type": "string",
"default": "The request could not be performed because the account does not have enough balance to perform the transaction."
},
"name": {
"type": "string",
"default": "InsufficientBalanceException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientBalanceException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 107139
},
"message": {
"type": "string",
"default": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool."
},
"name": {
"type": "string",
"default": "PolkadotPoolDoesNotExistsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PolkadotPoolDoesNotExistsException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"InsufficientBalanceException": {
"value": {
"error": {
"code": 107102,
"message": "The request could not be performed because the amount of tokens on account is insufficient. Please check that the balance is more than undefined.",
"type": "client"
},
"result": null
}
},
"PolkadotPoolDoesNotExistsException": {
"value": {
"error": {
"code": 107139,
"message": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119132
},
"message": {
"type": "string",
"default": "The bond request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "BondException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"BondException": {
"value": {
"error": {
"code": 107132,
"message": "The bond request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Signing Transaction Tron
*Source: [https://docs.p2p.org/docs/signing-transaction-tron.md](https://docs.p2p.org/docs/signing-transaction-tron.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the SUI network, follow these steps:
## 1. Prepare the Unsigned Transaction
Obtain the `unsignedTransaction` object by following the staking, vote, or undelegate flow via the Staking API.\
The object will have the format returned in previous API responses.
## 2. Sign the Transaction:
Use the [tronweb](https://github.com/TRON-US/tronweb) library to sign the transaction with your private key.
```javascript
// sign-tron-tx.mjs
import { TronWeb } from 'tronweb';
import dotenv from 'dotenv';
dotenv.config();
const tronFullHostUrl = 'https://nile.trongrid.io';
const tronPrivateKey = process.env.TRON_PRIVATE_KEY;
const unsignedTx = {
"visible": false,
"txID": "c07e64f57ebb6ae191404b1c693aa46f80789aceacbfd8cc17a7c85c0c8c5559",
"raw_data_hex": "0a02ee182208eb04b8cce7cc51534090f5d7edfa325a6a080412660a30747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e566f74655769746e657373436f6e747261637412320a1541da53d324a354aa5924c7117caff3ead97910a5e112190a1541351b95e29c2514b7b8183cbc81a8e08c68e8833b100370b0a0d4edfa32",
"raw_data": {
// ... full raw_data from API response ...
}
};
async function main() {
if (!tronPrivateKey) throw new Error('TRON_PRIVATE_KEY is not set');
const tronWeb = new TronWeb({
fullHost: tronFullHostUrl,
headers: {
'TRON-PRO-API-KEY': process.env.TRONGRID_API_KEY,
},
privateKey: tronPrivateKey,
});
const signedTx = await tronWeb.trx.sign(unsignedTx);
// Hex-serialize for sending to API (as required)
const hexSignedTx = Buffer.from(JSON.stringify(signedTx)).toString('hex');
console.log('✅ Signed transaction hex:', `0x${hexSignedTx}`);
}
main().catch((e) => {
console.error('Signing failed:', e.message);
process.exit(1);
});
```
*The output will be a`0x`-prefixed hex string containing your signed transaction, ready for broadcasting.*
## 3. Broadcast the Signed Transaction
Send a `POST` request to [/api/v1/tron/\[network\]/transaction/send](ref:)
Example request:
```
curl --request POST \
--url 'https://api-test.p2p.org/api/v1/tron/testnet-nile/transaction/send' \
--header 'accept: application/json' \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"signedTransaction": "0x7b2276697369626c65223a66616c73652c2274784944223a22..."
}'
```
* `signedTransaction` — your locally signed transaction, hex-encoded.
Example response:
```json
{
"error": null,
"result": {
"transactionHash": "c8e47301ca1d4a56120e6f13f0ce5f8a680e2fda221b3d8bc423cc355f924a70",
"createdAt": "2025-07-04T09:01:10.000Z",
"network": "testnet-nile",
"senderAddress": "41da53d324a354aa5924c7117caff3ead97910a5e1",
"block": null,
"status": "PENDING",
"gas": {
"bandwidthUsed": 0,
"energyUsed": 0
}
}
}
```
* `transactionHash` — hash of the submitted transaction.
* `createdAt` — time transaction was broadcast (ISO 8601).
* `network` — target TRON network.
* `senderAddress` — sender’s address (hex).
* `block` — block number if transaction is confirmed, or null if still pending.
* `status` — transaction status: PENDING or CONFIRMED.
* `gas`
* `bandwidthUsed` — bandwidth consumed.
* `energyUsed` — energy consumed.
Use the `transactionHash` to track the transaction status in explorers like [Tronscan](https://nile.tronscan.org/).
## What's Next?
* [Getting Started](doc:staking-sui).
* [Withdrawal](doc:withdrawal-sui).
* [Staking API](ref:sui) reference.
---
## Signing Transaction Baby
*Source: [https://docs.p2p.org/docs/signing-transaction-baby.md](https://docs.p2p.org/docs/signing-transaction-baby.md)*
# Babylon Transaction Signing
# 1. Prepare the Unsigned Transaction
Obtain the unsigned transaction in the required format (Babylon transaction object). Typically, this is provided by the API endpoint or a transaction builder.\
Example (object form):
```json
{
"messages": [/*...Babylon messages...*/],
"fee": {
"amount": [{"denom": "ubbn", "amount": "1000"}],
"gas": "200000"
},
"memo": ""
}
```
# 2. Sign the Transaction Using the Script Below
```typescript
import { DirectSecp256k1HdWallet, Registry, GeneratedType } from '@cosmjs/proto-signing';
import { SigningCosmWasmClient, defaultRegistryTypes } from '@cosmjs/cosmwasm-stargate';
import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
import axios from 'axios';
// Replace with actual Babylon message types if needed
import {
MsgWrappedDelegate,
MsgWrappedUndelegate,
} from '@babylonlabs-io/babylon-proto-ts/dist/generated/babylon/epoching/v1/tx';
const BABYLON_RPC = ''; // e.g. https://rpc.testnet.babylonchain.io:443
const BABYLON_API_URL = ''; // e.g. https://api.testnet.p2p.org
const BABYLON_API_KEY = '';
const BABYLON_NETWORK = ''; // e.g. testnet, mainnet
const BABYLON_MNEMONIC = '';
const BABYLON_ADDRESS = ''; // e.g. bbn1xyz...
const UNSIGNED_TX = {
// Paste your unsigned transaction object here
messages: [],
fee: {
amount: [{ denom: 'ubbn', amount: '1000' }],
gas: '200000',
},
memo: '',
};
function getBabylonRegistry(): Registry {
const registry = new Registry([...defaultRegistryTypes]);
registry.register(
'/babylon.epoching.v1.MsgWrappedDelegate',
MsgWrappedDelegate as unknown as GeneratedType
);
registry.register(
'/babylon.epoching.v1.MsgWrappedUndelegate',
MsgWrappedUndelegate as unknown as GeneratedType
);
return registry;
}
async function signTransaction(
mnemonic: string,
address: string,
unsignedTx: any
): Promise {
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: 'bbn' });
const registry = getBabylonRegistry();
const client = await SigningCosmWasmClient.connectWithSigner(BABYLON_RPC, wallet, { registry });
const { bodyBytes, authInfoBytes, signatures } = await client.sign(
address,
unsignedTx.messages,
unsignedTx.fee,
unsignedTx.memo
);
const txRaw = TxRaw.fromPartial({
bodyBytes,
authInfoBytes,
signatures,
});
// Return the signed transaction as hex string
return Buffer.from(TxRaw.encode(txRaw).finish()).toString('hex');
}
async function broadcastTransaction(signedTxHex: string): Promise {
const endpoint = `${BABYLON_API_URL}/api/v1/babylon/${BABYLON_NETWORK}/transaction/send`;
const response = await axios.post(
endpoint,
{ signedTransaction: signedTxHex },
{
headers: {
accept: 'application/json',
'content-type': 'application/json',
authorization: `Bearer ${BABYLON_API_KEY}`,
},
}
);
if (!response.data.result?.transactionHash) {
throw new Error(`Broadcast failed: ${JSON.stringify(response.data)}`);
}
return response.data.result.transactionHash;
}
async function main() {
if (!BABYLON_MNEMONIC || !BABYLON_ADDRESS) {
throw new Error('❌ Babylon mnemonic or address is missing.');
}
if (!UNSIGNED_TX.messages || !Array.isArray(UNSIGNED_TX.messages)) {
throw new Error('❌ Invalid unsigned transaction.');
}
const signedTxHex = await signTransaction(BABYLON_MNEMONIC, BABYLON_ADDRESS, UNSIGNED_TX);
console.log('✅ Signed Babylon Tx (hex):');
console.log(signedTxHex);
// Broadcast (optional, can be run separately)
const txHash = await broadcastTransaction(signedTxHex);
console.log('✅ Broadcasted Tx Hash:', txHash);
}
main().catch(console.error);
```
# 3. On Successful Execution
The script prints the signed transaction in hex format, then broadcasts it. Example output:
```
✅ Signed Babylon Tx (hex):
aabbcc...deadbeef
✅ Broadcasted Tx Hash:
BABYLON_TX_HASH_HERE
```
## What's Next?
* [Networks Supported](doc:unified-api-networks)
* [Getting Started](doc:unified-api-getting-started)
* [Unified API Reference](ref:unified-create-stake-transaction)
---
## Staking Avail
*Source: [https://docs.p2p.org/docs/staking-avail.md](https://docs.p2p.org/docs/staking-avail.md)*
# Getting Started
There are two ways to start staking on the Avail network using the Staking API with a public node:
* Stake directly.
* Stake via a nomination pool.
[Get an authentication token](doc:authentication) to start using Staking API.
Request examples are provided using [cURL](https://curl.se/).
# Staking directly
## 1. Create Bond and Nomination Request
1. Send a POST request to [/api/v1/avail/\{network}/staking/direct/stake](ref:avail-staking-stake) to stake the requested amount and nominate a validator in the Avail network. Note that there is a [dynamic minimum threshold to stake](https://blog.availproject.org/stake-avail-earn-rewards/#:~:text=On%20Avail%2C%20you%20currently%20need,behalf%20of%20the%20pool%20members.).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/mainnet/staking/direct/stake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"rewardDestinationType": "account",
"rewardDestination": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount": 1000
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `rewardDestinationType` — rewards destination type:
* `staked` — rewards will be sent to your stash account and added to your current bond (compounding rewards).
* `stash` — rewards will be sent to your stash account as a transferrable balance (not compounding rewards).
* `controller` — rewards will be sent to the controller account.
* `account` — rewards will be sent to any account you specify as a transferrable balance.
* `rewardDestination` — rewards destination account address.
* `amount` — amount of tokens to bond. AVAIL is used for the mainnet network.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"rewardDestinationType": "account",
"rewardDestination": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount": 1000,
"targets": [
"5FUJHYEzKpVJfNbtXmR9HFqmcSEz6ak7ZUhBECz7GpsFkSYR",
"5Ek5JCnrRsyUGYNRaEvkufG1i1EUxEE9cytuWBBjA9oNZVsf",
"5GTD7ZeD823BjpmZBCSzBQp7cvHR1Gunq7oDkurZr9zUev2n",
"5CcHdjf6sPcEkTmXFzF2CfH7MFrVHyY5PZtSm1eZsxgsj1KC"
],
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `rewardDestinationType` — rewards destination type:
* `staked` — rewards will be sent to your stash account and added to your current bond (compounding rewards).
* `stash` — rewards will be sent to your stash account as a transferable balance (not compounding rewards).
* `controller` — rewards will be sent to the controller account.
* `account` — rewards will be sent to any account you specify as a transferable balance.
* `rewardDestination` — rewards destination account address.
* `amount` — amount of tokens to bond. AVAIL is used for the mainnet network.
* `targets` — selected validators in the targets.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
## 2. Add Proxy Account — optional step
You can add a staking proxy to utilize the main stash account less frequently. It allows delegating your staking rights to another account, which can then sign transactions on your behalf. The original account retains all of its rights, and the proxy account can be removed at any time.
1. Send a POST request to [/api/v1/avail/\{network}/account/add](ref:avail-account-add).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/mainnet/account/add \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"proxyAccountAddress": "5Ggpg3JepXM3ZrktNpoc5QA1sKaFVpUPWMRr7jppiMxTuU75"
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding; a proxied address that transfers rights to a proxy account.
* `proxyAccountAddress` — address that receives rights from the proxied account.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xa404160100cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c0200000000",
"createdAt": "2023-09-18T14:49:23.998Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
# Staking via a nomination pool
## 1. Create Bond Request
1. Create a bond request by sending a POST request to [/api/v1/avail/\{network}/staking/pool/bond](ref:avail-pool-bond). The P2P.org pool ID on the Avail mainnet is **23**.
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/mainnet/staking/pool/bond \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"poolId": 23,
"amount": 100
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `poolId` — ID of the nomination pool.
* `amount` — amount of tokens to bond. AVAIL is used for the mainnet network.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"amount": 100,
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `amount` — amount of tokens to bond. AVAIL is used for the mainnet network.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
## 2. Create Set Permission Request
1. Grant permission to the pool to manage rewards on your behalf by sending a POST request to [/api/v1/avail/\{network}/staking/pool/set-claim-permission](ref:avail-pool-set-claim-permission).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/mainnet/staking/pool/set-claim-permission \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"permission": "PermissionlessAll"
}
'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `permission` — state of the permission to grant:
* `Permissioned` — only you can claim, bond or withdraw rewards. If this level of permission is set, an additional [Claiming Payout request](doc:staking-avail#3-create-claim-payout-request) is needed.
* `PermissionlessCompound` — compounding (claim and then bond) of your rewards on your behalf is permitted.
* `PermissionlessWithdraw` — withdrawing (claim and then keep as a free balance) of your rewards on your behalf is permitted.
* `PermissionlessAll` — claiming, bonding and withdrawing rewards on your behalf are permitted.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000",
"createdAt": "2023-08-24T08:23:18.830Z"
},
"error": {}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
## 3. Create Claim Payout Request
Unlike direct staking, after the rewards is distributed to the nomination pool by a validator, each pool member has to claim their part manually. Since that, to bond, compound or withdraw your rewards, you may need to perform an additional claiming payout request.
Whether it is required depends on the claim rewards permissions you [set in the step 2](doc:staking-avail#2-create-set-permission-request):
* For `PermissionlessAll`, the step is optional.
* For `Permissioned`, the step is necessary, as you are the only who can claim the rewards.
* For `PermissionlessCompound` and `PermissionlessWithdraw`, the step is required if you want to withdraw and compound your rewards accordingly.
To create a claim payout request:
1. Send a POST request to [/api/v1/avail/\{network}/staking/pool/claim-payout](ref:avail-pool-claim-payout).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/mainnet/staking/pool/claim-payout \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xa404160100cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c0200000000",
"createdAt": "2023-08-24T08:23:18.830Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
# What's Next?
* [Staking API](ref:avail-transaction-status) reference.
* [Withdrawal](doc:withdrawal-avail).
---
## Polkadot Account Remove
*Source: [https://docs.p2p.org/reference/polkadot-account-remove.md](https://docs.p2p.org/reference/polkadot-account-remove.md)*
# Remove Staking Proxy Account
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/account/remove": {
"post": {
"operationId": "polkadot-account-remove",
"summary": "Remove Staking Proxy Account",
"description": "Removing a proxy account involves discontinuing the delegation of staking responsibilities from one account to another. This action allows users to regain direct control over their staking activities and tokens in the Polkadot network.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Proxied account is an address that transfers rights to a proxy account. The original account retains all of its rights, and the proxy account can be removed at any time.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"proxyAccountAddress": {
"type": "string",
"description": "Proxy account is an address that receives proxied account rights.",
"example": "5Ca1Bqfzc4DdU6zMXLu5UhpRtdX5EzCseDXW9YisVm25ATeJ"
}
},
"required": [
"stashAccountAddress",
"proxyAccountAddress"
],
"x-readme-ref-name": "RemoveRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "TransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119107
},
"message": {
"type": "string",
"default": "The proxy account address provided could not be found. Please specify the correct address."
},
"name": {
"type": "string",
"default": "ProxyNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ProxyNotFoundException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"ProxyNotFoundException": {
"value": {
"error": {
"code": 107107,
"message": "The proxy account address provided could not be found. Please specify the correct address.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119121
},
"message": {
"type": "string",
"default": "The proxy account address could not be removed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "RemoveException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "RemoveException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"RemoveException": {
"value": {
"error": {
"code": 107121,
"message": "The proxy account address could not be removed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Eth Nodes Request Status
*Source: [https://docs.p2p.org/reference/eth-nodes-request-status.md](https://docs.p2p.org/reference/eth-nodes-request-status.md)*
# Get Request Status
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/direct/nodes-request/status/{id}": {
"get": {
"operationId": "eth-nodes-request-status",
"summary": "Get Request Status",
"description": "Check the status of the node set-up operation and retrieve the details of the validator by using the node request operation identifier. For several requests, see the [Get All Requests Status](ref:eth-nodes-request-list) endpoint.",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "UUID of the nodes request.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"example": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"description": "UUID that was specified in the node set-up request."
},
"type": {
"type": "string",
"enum": [
"REGULAR",
"RESTAKING"
],
"description": "Type of the nodes request.",
"example": "REGULAR"
},
"status": {
"type": "string",
"enum": [
"init",
"processing",
"ready",
"cancel"
],
"description": "
Current status of the nodes request:
init — node request was created.
processing — node request is in work.
ready — backend has deposit data for the node request.
cancel — something went wrong and the deposit data did not create.
",
"example": "processing"
},
"validatorsCount": {
"type": "number",
"description": "Number of validators.",
"default": 1,
"minimum": 1,
"maximum": 3125,
"example": 1
},
"amountPerValidator": {
"type": "string",
"description": "Amount of tokens to stake in Gwei per validator.",
"example": "32000000000"
},
"withdrawalCredentialsType": {
"type": "string",
"description": "Withdrawal credentials type.",
"example": "0x02",
"enum": [
"0x01",
"0x02"
]
},
"withdrawalAddress": {
"type": "string",
"description": "Withdrawal address of the validator.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"eigenPodAddress": {
"type": "string",
"description": "EigenPod address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"eigenPodOwnerAddress": {
"type": "string",
"description": "EigenPod owner address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"controllerAddress": {
"type": "string",
"description": "Controller address of the validator.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"feeRecipientAddress": {
"type": "string",
"description": "Fee recipient address of the validator.",
"example": "0x53da3c92fCCEb0CFE1764f65DDfF1564A2b15585",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"depositData": {
"minItems": 1,
"maxItems": 400,
"type": "array",
"items": {
"type": "object",
"properties": {
"pubkey": {
"type": "string",
"description": "Validator public key.",
"example": "0xbe5E9c3Bb9eba1BF4C5eC1c1cbcF85ee2CE2fEC66Ce5460C23eF82332A044FDCabF7011F588CCbD77E73CCe6c4accDF0",
"pattern": "^0x[a-fA-F0-9]{96}$"
},
"signature": {
"type": "string",
"description": "Validator signature.",
"example": "0x15C9D0Bf74BE4ef12b0008Ed53825Da647E0C0FE21c0EfAE2B36E066bf44A5a9b5De0B70cE19F73D8eC5E7237Dde667FE8a99Ad607BddDC4b2aDd4c4Bc57b10ddfe7f0bFb925b48f4d37Cee8f894cEA365CeeA6c4B25a9Ca7DAbDfFdB2EDd6eB",
"pattern": "^0x[a-fA-F0-9]{192}$"
},
"depositDataRoot": {
"type": "string",
"description": "Hash of the deposit data.",
"example": "0xFEDdcB470eAA856c57f466e2f4d4F6971efEA1ED38fdB91bD913EEFFb52C8E24",
"pattern": "^0x[a-fA-F0-9]{64}$"
},
"withdrawalCredentials": {
"type": "string",
"description": "Public key for withdrawing balance."
},
"amount": {
"type": "string",
"description": "Deposit amount."
},
"depositMessageRoot": {
"type": "string",
"description": "Cryptographic hash of the Merkle tree’s root."
},
"forkVersion": {
"type": "string",
"description": "Version of the Ethereum fork that the deposit is for."
},
"eth2NetworkName": {
"type": "string",
"description": "Eth2 network name."
},
"depositCliVersion": {
"type": "string",
"description": "Version of the deposit command-line interface."
}
},
"required": [
"pubkey",
"signature",
"depositDataRoot"
],
"x-readme-ref-name": "DepositDataResponse"
}
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"id",
"type",
"status",
"validatorsCount",
"amountPerValidator",
"withdrawalCredentialsType",
"feeRecipientAddress",
"createdAt"
],
"x-readme-ref-name": "NodesRequestResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103115
},
"message": {
"type": "string",
"default": "The node request ID provided could not be found. Please specify the correct UUID."
},
"name": {
"type": "string",
"default": "NodesRequestNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NodesRequestNotFoundException"
}
]
}
}
},
"examples": {
"NodesRequestNotFoundException": {
"value": {
"error": {
"code": 103115,
"message": "The node request ID provided could not be found. Please specify the correct UUID.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103118
},
"message": {
"type": "string",
"default": "The status of the node request could not be obtained because the internal server error occurred."
},
"name": {
"type": "string",
"default": "NodesRequestGetException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NodesRequestGetException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"NodesRequestGetException": {
"value": {
"error": {
"code": 103118,
"message": "The status of the node request could not be obtained because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Ethereum"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Solana 质押案例 Unified Api
*Source: [https://docs.p2p.org/recipes/solana-质押案例-unified-api.md](https://docs.p2p.org/recipes/solana-质押案例-unified-api.md)*
P2P.ORG
"
},
"amount": {
"type": "string",
"description": "Amount of tokens."
}
},
"required": [
"denom",
"amount"
],
"x-readme-ref-name": "Amount"
}
},
"gas": {
"type": "string",
"description": "Amount of gas spent for the transaction."
}
},
"required": [
"amount",
"gas"
],
"x-readme-ref-name": "TransactionFee"
}
]
},
"memo": {
"type": "string",
"description": "Arbitrary text data to add to the transactions."
},
"encodedBody": {
"type": "string",
"description": "Processable transaction data encoded in the hexadecimal format."
},
"encodedAuthInfo": {
"type": "string",
"description": "Authorization data, including fee, encoded in the hexadecimal format."
}
},
"required": [
"messages",
"fee",
"encodedBody",
"encodedAuthInfo"
],
"x-readme-ref-name": "TransactionData"
}
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the transaction in the ISO 8601 format."
},
"validatorAddress": {
"type": "string",
"description": "Validator address to which tokens are delegated.",
"example": "cosmosvaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^cosmosvaloper[a-zA-Z0-9]{39}$"
}
},
"required": [
"stashAccountAddress",
"transactionData",
"createdAt",
"validatorAddress"
],
"x-readme-ref-name": "ClaimRewardsTransactionStakingCosmosResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110113
},
"message": {
"type": "string",
"default": "The request could not be performed because the simulation transaction failed."
},
"name": {
"type": "string",
"default": "SimulationTransactionOnCosmosException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SimulationTransactionOnCosmosException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"SimulationTransactionOnCosmosException": {
"value": {
"error": {
"code": 110113,
"message": "The request could not be performed because the simulation transaction failed. undefined",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110106
},
"message": {
"type": "string",
"default": "The claiming rewards request transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "CreateClaimRewardsTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CreateClaimRewardsTransactionException"
}
]
}
}
},
"examples": {
"CreateClaimRewardsTransactionException": {
"value": {
"error": {
"code": 110106,
"message": "The claiming rewards request transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Cosmos"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Transaction Exit Validator
*Source: [https://docs.p2p.org/reference/transaction-exit-validator.md](https://docs.p2p.org/reference/transaction-exit-validator.md)*
# Prepare exitValidator Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/tx/exit-validator/{id}": {
"get": {
"operationId": "transaction-exit-validator",
"summary": "Prepare exitValidator Transaction",
"description": "Construct a serialized transaction to initiate the validator exit from the cluster.",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "UUID of the SSV request.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
}
},
"required": [
"list"
],
"x-readme-ref-name": "EthereumUnsignedTransactionListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111104
},
"message": {
"type": "string",
"default": "The SSV ID %s provided could not be found. Please specify the correct UUID."
},
"name": {
"type": "string",
"default": "SsvRequestNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SsvRequestNotFoundException"
}
]
}
}
},
"examples": {
"SsvRequestNotFoundException": {
"value": {
"error": {
"code": 111104,
"message": "The SSV ID undefined provided could not be found. Please specify the correct UUID.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111125
},
"message": {
"type": "string",
"default": "The exit validator transaction could not be created because an internal server error occurred."
},
"name": {
"type": "string",
"default": "ExitValidatorException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ExitValidatorException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111127
},
"message": {
"type": "string",
"default": "The request could not be performed because the number of encrypted shardes is not valid. Please try again."
},
"name": {
"type": "string",
"default": "InvalidEncryptedShardesCountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidEncryptedShardesCountException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"ExitValidatorException": {
"value": {
"error": {
"code": 111125,
"message": "The exit validator transaction could not be created because an internal server error occurred.",
"type": "server"
},
"result": null
}
},
"InvalidEncryptedShardesCountException": {
"value": {
"error": {
"code": 111127,
"message": "The request could not be performed because the number of encrypted shardes is not valid. Please try again.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Unified Api Overview
*Source: [https://docs.p2p.org/docs/unified-api-overview.md](https://docs.p2p.org/docs/unified-api-overview.md)*
# Overview
The Unified API provides a standardized platform to manage staking, transaction broadcasting, and unstaking across multiple blockchain networks. Its modular architecture simplifies integrations, enabling quick support for new networks. Connect once, and you’re ready to interact with all supported networks.
This modular flow ensures that users can seamlessly integrate both existing and future supported networks, as they will maintain a consistent structure.
## Overview of the Integration with the Unified API
## Key features
* **Seamless Cross-Network Compatibility**. Streamline operations with a unified request/response format and consistent staking workflows across all the existing and future supported networks.
* **Fewer Integrations**. By consolidating a number of Staking APIs into a single one, Unified API allows reducing the diversity of integrations to accommodate tech stacks.
* **Coverage**. The Unified API supports the following chains: Babylon, Solana, TON, Avail, and Ethereum (SSV). We are expanding this initial list to meet the clients' growing demands, with up to 30 chains available via one API endpoint.
[Get an authentication token](doc:authentication) to start using Unified API.
## Supported chains and networks
See all [Networks Supported](doc:unified-api-networks).
## What's Next?
* [Getting Started](doc:unified-api-getting-started)
* [Networks Supported](doc:unified-api-networks)
* [Unified API Reference](ref:unified-create-stake-transaction)
---
## Overview Cosmos
*Source: [https://docs.p2p.org/docs/overview-cosmos.md](https://docs.p2p.org/docs/overview-cosmos.md)*
# Overview
Staking in the Cosmos Hub network using the Staking API consists of several main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For Cosmos Hub, there are several networks available:
* `cosmoshub` — the production network.
* `theta-testnet` — a testnet.
## What's Next?
* [Getting Started](doc:staking-cosmos).
* [Withdrawal](doc:withdrawal-cosmos).
* [Staking API](ref:create-cosmos-stake-transaction) reference.
---
## Eth P2P Transaction Deposit List
*Source: [https://docs.p2p.org/reference/eth-p2p-transaction-deposit-list.md](https://docs.p2p.org/reference/eth-p2p-transaction-deposit-list.md)*
# Get List of Deposits With Validators
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/direct/p2p/deposits": {
"get": {
"operationId": "eth-p2p-transaction-deposit-list",
"summary": "Get List of Deposits With Validators",
"description": "Get a list of deposits with validators.",
"parameters": [
{
"name": "limit",
"required": true,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": true,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 100000,
"type": "number"
}
},
{
"name": "type",
"required": true,
"in": "query",
"description": "Type of the request.",
"example": {
"WITHDRAWAL_ADDRESS": "withdrawalAddress",
"TRANSACTION_HASH": "transactionHash",
"DEPOSIT_IDS": "depositIds"
},
"schema": {
"enum": [
"withdrawalAddress",
"transactionHash",
"depositIds"
],
"type": "string"
}
},
{
"name": "withdrawalAddress",
"required": false,
"in": "query",
"description": "Withdrawal address for the validators.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"schema": {
"pattern": "^0x[a-fA-F0-9]{40}$",
"type": "string"
}
},
{
"name": "transactionHash",
"required": false,
"in": "query",
"description": "Hash of the deposit transaction.",
"example": "0x2b1c6bbdeadb0b23ca8260a819fde1c0b0347b0fd42c33a9b2513b36d6521dc6",
"schema": {
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false,
"type": "string"
}
},
{
"name": "depositIds",
"required": false,
"in": "query",
"description": "Deposit ID list.",
"schema": {
"minimum": 1,
"format": "uuid",
"type": "array",
"items": {
"type": "string"
}
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"totalCount": {
"type": "number",
"minimum": 1,
"description": "Total count of resources relevant to the current request, based on filters applied."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"deposit": {
"type": "object",
"properties": {
"depositId": {
"type": "string",
"description": "Deposit ID generated by the P2P.org contract when addEth is called.",
"example": "49851686-9058-491f-a393-9ca477a7063a"
},
"transactionHash": {
"type": "string",
"description": "Transaction with addEth method.",
"example": "0xc6180e03f1ea7e30eba1c0870471516c575e695afa5066b55038ca73df242e33"
},
"senderAddress": {
"type": "string",
"description": "Sender address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"withdrawalAddress": {
"type": "string",
"description": "Withdrawal address of the validator.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"feeRecipientAddress": {
"type": "string",
"description": "Fee recipient address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"totalAmount": {
"type": "string",
"description": "Total amount of the deposit.",
"example": "32000000000"
},
"unprocessedAmount": {
"type": "string",
"description": "Amount of the deposit that was not processed by the contract.",
"example": "0"
}
},
"required": [
"depositId",
"transactionHash",
"senderAddress",
"withdrawalAddress",
"feeRecipientAddress",
"totalAmount",
"unprocessedAmount"
],
"x-readme-ref-name": "DepositDepoResponse"
},
"validator": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"unknown",
"not_found",
"pending_initialized",
"pending_queued",
"active_ongoing",
"active_exiting",
"active_slashed",
"exited_unslashed",
"exited_slashed",
"withdrawal_possible",
"withdrawal_done"
],
"description": "
State of the validator:
`not_found` — specified validator could not be located.
`pending_initialized` — validator is initialized but not yet in the queue for activation.
`pending_queued` — validator entered a queue for activation.
`active_ongoing` — validator was activated and currently participates in attesting and proposing blocks.
`active_exiting` — validator is in process of exiting the network while participating in the validator activities.
`active_slashed` — validator was slashed due to misbehaviors.
`exited_unslashed` — validator has exited the network without being slashed and is no longer acting as a validator.
`exited_slashed` — validator has exited the network after being slashed and is no longer acting as a validator.
`withdrawal_possible` — validator has a non-zero balance.
`withdrawal_done` — validator completed the withdrawal process.
",
"example": "active_ongoing"
},
"amount": {
"type": "string",
"example": "1",
"description": "Total stake amount for the validator at the moment."
},
"pubkey": {
"type": "string",
"description": "Validator public key.",
"example": "0xbe5E9c3Bb9eba1BF4C5eC1c1cbcF85ee2CE2fEC66Ce5460C23eF82332A044FDCabF7011F588CCbD77E73CCe6c4accDF0",
"pattern": "^0x[a-fA-F0-9]{96}$"
}
},
"required": [
"status",
"amount",
"pubkey"
],
"x-readme-ref-name": "DepositValidatorResponse"
}
},
"required": [
"deposit",
"validator"
],
"x-readme-ref-name": "DepositResponse"
}
},
"totalAmount": {
"type": "string",
"description": "Total amount of deposits."
},
"unprocessedAmount": {
"type": "string",
"description": "Total amount of unprocessed deposits."
}
},
"required": [
"limit",
"offset",
"totalCount",
"list",
"totalAmount",
"unprocessedAmount"
],
"x-readme-ref-name": "DepositListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103146
},
"message": {
"type": "string",
"default": "Failed to get list of deposits"
},
"name": {
"type": "string",
"default": "DepositListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "DepositListException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"DepositListException": {
"value": {
"error": {
"code": 103146,
"message": "Failed to get list of deposits",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Ethereum"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Restaking Eth
*Source: [https://docs.p2p.org/docs/restaking-eth.md](https://docs.p2p.org/docs/restaking-eth.md)*
# Getting Started
The EigenLayer restaking flow includes the following steps:
1. Create EigenPod address: construct a serialized transaction to generate an EigenPod address, which your validator can use as a withdrawal address.
2. Create Staking Request: set up nodes for staking using P2P infrastructure.
3. Check Request Status: check the status of the node set-up operation.
4. Prepare Staking Transaction: construct a serialized transaction to deposit the stake amount with a smart contract.
5. Verify Withdrawal Credentials: construct a serialized transaction to verify the validator withdrawal credentials on-chain.
6. Prepare Delegate Restake Transaction: construct a serialized transaction to delegate the restake amount to the EigenLayer node operator.
[Get an authentication token](doc:authentication) to start using Restaking API.
Request examples are provided using [cURL](https://curl.se/).
***
# 1. Create EigenPod Address
1. Retrieve a serialized transaction to generate an EigenPod address by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/create-pod](ref:eth-eigen-create-pod). Use [https://api-test-holesky.p2p.org](https://api-test-holesky.p2p.org) for testing or [https://api.p2p.org](https://api.p2p.org) for production.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/create-pod \
--header 'accept: application/json' \
--header 'authorization: Bearer '
--header 'content-type: application/json'
```
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0x30770d7E3e71112d7A6b7259542D1f680a70e315",
"gasLimit": "10000000",
"data": "0x84d81062",
"value": "0",
"chainId": "17000",
"type": "2",
"maxFeePerGas": "1000040",
"maxPriorityFeePerGas": "1000000"
},
"error": {}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
2. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are generating an EigenPod address. The Ethereum address used to sign this transaction will become the `eigenPodOwnerAddress`.
# 2. Create Stake Request
1. Prepare`id` that is an arbitrary UUID. Generate it in one of the following ways:
* [Online UUID Generator](https://www.uuidgenerator.net/)
* [uuid npm package](https://www.npmjs.com/package/uuid)
2. Set up staking nodes through the P2P infrastructure by sending a POST request with the `RESTAKING` type to [/api/v1/eth/staking/direct/nodes-request/create](ref:eth-nodes-request-create).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/nodes-request/create \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"id":"6df58880-c4c9-484a-8fc4-7f7668fe9522",
"type": "RESTAKING",
"validatorsCount": 1,
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"feeRecipientAddress":"0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"controllerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"nodesOptions":{
"location": "any",
"relaysSet": null
}
}
'
```
* `id` — arbitrary UUID. You can later use that UUID to check the status of the set-up operation.
* `type` — staking operation type:
* `RESTAKING` — value for initiating a restaking operation.
* `REGULAR` — default value used for native staking transactions.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `feeRecipientAddress` — fee recipient address.
* `eigenPodOwnerAddress` — owner of the EigenPod address, created in the [previous step](doc:restaking-eth#1-create-eigenpod-address).
* `controllerAddress` — controller address for the validators.
* `nodesOptions`:
* * `location` — node location. Currently, only `any` is supported.
* `relaysSet` — Miner Extractable Value (MEV) relay selection.
Example response:
```json
{
"result": true
}
```
# 3. Check Request Status
Check the status of the node set-up operation by sending a GET request to [/api/v1/eth/staking/direct/nodes-request/status/\{id}](ref:eth-nodes-request-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/direct/nodes-request/status/6df58880-c4c9-484a-8fc4-7f7668fe9522 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
--header 'content-type: application/json'
```
* `id` — UUID that was specified in the node set-up request.
Example response:
```json
{
"result": {
"id": "6df58880-c4c9-484a-8fc4-7f7668fe9522",
"status": "ready",
"type": "RESTAKING",
"validatorsCount": 1,
"withdrawalAddress": null,
"eigenPodAddress": "0x1433F808a4867aDEeEb3AE0Df58691C252269A2C",
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"controllerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"depositData": [
{
"pubkey": "0xaed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13",
"signature": "0x91b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf5",
"depositDataRoot": "0xd0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89",
"withdrawalCredentials": "0100000000000000000000001433f808a4867adeeeb3ae0df58691c252269a2c",
"amount": 32000000000,
"depositMessageRoot": "04f641c39de982aee68cc7c78bd23bcafffed91fd1c455282b651e0c8d6c4e20",
"forkVersion": "01017000",
"eth2NetworkName": "holesky",
"depositCliVersion": "2.7.0"
}
],
"createdAt": "2025-01-29T15:07:08.399Z"
}
}
```
* `id` — UUID that was specified in the node set-up request.
* `status` — current status of the node request:
* `init` — node request is created.
* `processing` — node request is in progress.
* `ready` — backend has the deposit data for the node request.
* `cancel` — something went wrong and the deposit data was not created.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `withdrawalAddress` — withdrawal address for the validators that is set to `null` by default; corresponds to the EigenPod address.
* `eigenPodAddress` — EigenPod address also used as the validator withdrawal address.
* `eigenPodOwnerAddress` — owner of the EigenPod address.
* `controllerAddress` — controller address for the validators.
* `feeRecipientAddress` — fee recipient address.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `depositDataRoot` — SHA-256 hash of the SSZ-encoded DepositData object; used as a protection against malformed input.
* `withdrawalCredentials`— withdrawal address credentials, passed in the expected format by the Ethereum deposit smart contract.
* `amount` — amount of ETH, denominated in Gwei, that is being deposited.
* `depositMessageRoot` — cryptographic hash of the Merkle tree’s root, ensuring the integrity and authenticity of the deposit data.
* `forkVersion` — version of the network fork that the deposit is intended for. It helps in aligning the deposit with a specific version of the protocol.
* `eth2NetworkName` — name of the Ethereum 2.0 network where the deposit is made.
* `depositCliVersion` — version of the deposit command-line interface (CLI) tool that was used to generate the deposit data.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
# 4. Prepare Staking Transaction
There are two ways to prepare a staking transaction using the Restaking API:
* Interact directly with the Ethereum Deposit Smart Contract.
* Utilize the P2P smart contract.
## Ethereum Deposit Smart Contract
> 📘
>
> This option may be preferrable if you have a lot of engineering resources available and do not want your infrastructure to have an extra dependency.
1. Retrieve all the required data from the previous step within the `depositData` object and prepare the staking transaction.
2. Construct a signature and send the deposit amount to the [Ethereum deposit smart contract](https://etherscan.io/address/0x00000000219ab540356cBB839Cbe05303d7705Fa). Check an example of how to [sign and send](doc:signing-transaction-eth) a transaction to the Ethereum network.
## P2P Smart Contract
1. Create a serialized transaction for depositing the stake amount and send it as a POST request to [/api/v1/eth/staking/direct/tx/deposit](ref:eth-staking-deposit).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/deposit \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"withdrawalAddress": "0x1433F808a4867aDEeEb3AE0Df58691C252269A2C",
"depositData": [
{
"pubkey": "0xaed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13",
"signature": "0x91b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf5",
"depositDataRoot": "0xd0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89"
}
]
}
'
```
* `withdrawalAddress` — withdrawal address for the validators. For the `RESTAKING` operation type, this corresponds to the `eigenPodAddress` in the step 3 [Check Request Status](doc:restaking-eth#3-check-request-status).
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `depositDataRoot` — hash of the deposit data.
* `withdrawalCredentials`— withdrawal address credentials, passed in the expected format by the Ethereum deposit smart contract.
* `amount` — amount of ETH, denominated in Gwei, that is being deposited.
* `depositMessageRoot` — cryptographic hash of the Merkle tree’s root, ensuring the integrity and authenticity of the deposit data.
* `forkVersion` — version of the network fork that the deposit is intended for. It helps in aligning the deposit with a specific version of the protocol.
* `eth2NetworkName` — name of the Ethereum 2.0 network where the deposit is made.
* `depositCliVersion` — version of the deposit command-line interface (CLI) tool that was used to generate the deposit data.
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f902d305808205508205c8830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000001433f808a4867adeeeb3ae0df58691c252269a2c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006091b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf50000000000000000000000000000000000000000000000000000000000000001d0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89c0",
"to": "0xAD91441aB557b5eC5d9f29DB64522Eb918B4f32b",
"gasLimit": "100000",
"data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000001433f808a4867adeeeb3ae0df58691c252269a2c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006091b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf50000000000000000000000000000000000000000000000000000000000000001d0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89",
"value": "32000000000000000000",
"chainId": 17000,
"type": 2,
"maxFeePerGas": "1000030",
"maxPriorityFeePerGas": "1000000"
}
}
```
Example response is the same as in the [Create EigenPod Address](doc:restaking-eth#1-create-eigenpod-address) step.
2. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are depositing the required stake amount in the Ethereum deposit smart contract by using the P2P smart contract as a proxy.
# 5. Verify Withdrawal Credentials
> 📘
>
> The validator activation can take up from 16 to 24 hours. To check whether the validator is active, retrieve its status by sending a POST request to [/api/v1/eth/staking/direct/validator/status](ref:eth-validator-status).
>
> Before proceeding further, wait until the validator gets the `active_ongoing` status and starts performing the validator duties.
1. Initiate verifying the withdrawal credentials to the EigenPod address by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/verify-withdrawal-credentials](ref:eth-eigen-verify-withdrawal-credentials). These credentials will be used to verify that the validator will withdraw its principal to this EigenPod in case it exits the Beacon chain.\
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/verify-withdrawal-credentials \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"pubkey": "0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
}
'
```
* `eigenPodOwnerAddress` — owner of the EigenPod address.
* `pubkey` — validator public keys.
Example response:
```json
{
"error": null,
"result": {
"list": [
{
"serializeTx": "0x02f902d305808205508205c8830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000001433f808a4867adeeeb3ae0df58691c252269a2c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006091b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf50000000000000000000000000000000000000000000000000000000000000001d0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89c0",
"to": "0xAD91441aB557b5eC5d9f29DB64522Eb918B4f32b",
"gasLimit": "10000000",
"data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000001433f808a4867adeeeb3ae0df58691c252269a2c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006091b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf50000000000000000000000000000000000000000000000000000000000000001d0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89",
"value": "0",
"chainId": 17000,
"type": 2,
"maxFeePerGas": "1000032",
"maxPriorityFeePerGas": "1000000"
}
],
}
}
```
Example response is the same as in the [Create EigenPod Address](doc:restaking-eth#1-create-eigenpod-address) step.
2. Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are verifying the validator withdrawal credentials on-chain. You can now delegate your restake amount to an EigenLayer node operator.
> 🚧 Note that the transaction signing is time sensitive
>
> The transaction has to be signed in 8192 slots (approximately 27 hours).
>
> If the time has expired and you have not signed the transaction yet, [contact](doc:contacts) us for support.
# 6. Prepare Delegate Restake Transaction
1. Retrieve a list of all EigenLayer node operators by sending a GET request to [/api/v1/eth/staking/eigenlayer/operator](ref:eth-eigen-operator-list).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/operator \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
Example response:
```json
{
"error": null,
"result": {
"list": [
{
"id": "6df58880-c4c9-484a-8fc4-7f7668fe9522",
"name": "P2P",
"address": "0xdbed88d83176316fc46797b43adee927dc2ff2f5",
}
],
"limit": 10,
"offset": 0,
"totalCount": 1
}
}
```
* `list`:
* `id` — UUID that was specified in the node set-up request.
* `name` — validator name.
* `address` — EigenLayer node operator address.
* `limit` — number of resources that a single response page contains.
* `offset` — number of resources to exclude from a response.
* `totalCount` — total number of validators relevant to the current request, based on filters applied.
2. Create a serialized transaction for delegating the restake amount to the node operator by sending a POST request to [/api/v1/eth/staking/eigenlayer/tx/delegate-to](ref:eth-eigen-delegate-to).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/eigenlayer/tx/delegate-to \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"operatorAddress": "0xdbed88d83176316fc46797b43adee927dc2ff2f5"
}
'
```
* `operatorAddress` — address of the EigenLayer node operator to delegate the restaked assets.
> The EigenLayer node operator address for P2P.org is `0xdbed88d83176316fc46797b43adee927dc2ff2f5`.
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f8ef8242688084030825768486442318830186a094a44151489861fe9e3055d95adc98fbd462b948e780b8c4eea9064b00000000000000000000000037d5077434723d0ec21d894a52567cbe6fb2c3d800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0",
"to": "0xA44151489861Fe9e3055d95adC98FbD462B948e7",
"gasLimit": "0.0000000000001",
"data": "0xeea9064b00000000000000000000000037d5077434723d0ec21d894a52567cbe6fb2c3d800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"value": "0.0",
"chainId": 17000,
"type": 2,
"maxFeePerGas": "0.0000000000034557",
"maxPriorityFeePerGas": "1000000"
}
}
```
Example response is the same as in the [Create EigenPod Address](doc:restaking-eth#1-create-eigenpod-address) step.
3. Use `serializeTx` from the previous step to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are delegating your restake to the EigenLayer node operator.
# What's Next?
* [Withdrawal](doc:withdrawal-restaking).
* [Restaking API reference](ref:eth-eigen-create-pod).
---
## Withdrawal Eth
*Source: [https://docs.p2p.org/docs/withdrawal-eth.md](https://docs.p2p.org/docs/withdrawal-eth.md)*
# Withdrawal
To initiate a withdrawal on the Ethereum network using the Staking API, follow these steps:
1. Prepare Withdrawal Transaction: construct a serialized transaction to initiate the withdrawal process for active validators, utilizing the functionalities of P2P smart contract.
2. Sign and broadcast the transaction.
Request examples are provided using [cURL](https://curl.se/).
Before initiating the withdrawal flow, please note that only the address set as the controller address or withdrawal address can initiate a validator exit via our smart contract. If the transaction sender doesn't match the eligible address, the validator exit will not be initiated.
> 🚧 Please note
>
> On May 7, 2025, the major Ethereum network upgrade was carried out that brought many benefits for clients who use ETH or SSV validators. In particular, for clients with `0x02` withdrawal credentials, **partial withdrawals** are available.
>
> For more details, see [Pectra Upgrade overview](doc:pectra-upgrade-overview).
# 1. Prepare Withdrawal Transaction
Create a serialized transaction to initiate the withdrawal process for active validators and send it as a POST request to [/api/v1/eth/staking/direct/tx/withdrawal](ref:eth-staking-withdrawal). Use [https://api-test-holesky.p2p.org](https://api-test-holesky.p2p.org) for testing or [https://api.p2p.org](https://api.p2p.org) for production.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/withdrawal \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"pubkeys": [
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
]
}
'
```
* `pubkeys` — list of validators public keys.
Example response:
```json
{
"result": {
"serializeTx": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"to": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"gasLimit": "",
"data": "",
"value": "",
"chainId": "",
"type": "",
"maxFeePerGas": "",
"maxPriorityFeePerGas" : ""
}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
# 2. Sign and Broadcast Transaction
Use the following example of the code to sign and broadcast the withdrawal transaction.
```javascript
require("dotenv").config();
const ethers = require("ethers");
async function signAndBroadcast() {
console.log("Started");
// Enter the serialized transaction
const rawTransaction = process.env.RAW_TRANSACTION;
// Enter the private key of the address used to transfer the stake amount
const privateKey = process.env.PRIVATE_KEY;
// Enter the selected RPC URL
const rpcURL = process.env.RPC_URL;
// Initialize the provider using the RPC URL
const provider = new ethers.providers.JsonRpcProvider(rpcURL);
// Initialize a new Wallet instance
const wallet = new ethers.Wallet(privateKey, provider);
// Parse the raw transaction
const tx = ethers.utils.parseTransaction(rawTransaction);
tx.nonce = await provider.getTransactionCount(wallet.address);
// Enter the max fee per gas and prirorty fee
tx.maxFeePerGas = ethers.utils.parseUnits(
process.env.MAX_FEE_PER_GAS_IN_GWEI,
"gwei"
);
tx.maxPriorityFeePerGas = ethers.utils.parseUnits(
process.env.MAX_PRIORITY_FEE_IN_GWEI,
"gwei"
);
// Sign the transaction
const signedTransaction = await wallet.signTransaction(tx);
// Send the signed transaction
const transactionResponse = await provider.sendTransaction(signedTransaction);
return transactionResponse;
}
signAndBroadcast()
.then((transactionResponse) => {
console.log(
"Transaction broadcasted, transaction hash:",
transactionResponse.hash
);
})
.catch((error) => {
console.error("Error:", error);
})
.finally(() => {
console.log("Finished");
});
```
# What's Next?
* [Withdrawal using VEM](doc:withdrawal-vem).
* [Getting Started](doc:staking-eth).
* [Staking API](ref:eth-nodes-request-create) reference.
---
## Transaction Withdraw
*Source: [https://docs.p2p.org/reference/transaction-withdraw.md](https://docs.p2p.org/reference/transaction-withdraw.md)*
# Prepare Withdraw Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/tx/withdraw/{id}": {
"get": {
"operationId": "transaction-withdraw",
"summary": "Prepare Withdraw Transaction",
"description": "Construct a serialized transaction to withdraw a specified amount.",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "UUID of the SSV request.",
"schema": {
"type": "string"
}
},
{
"name": "amount",
"required": true,
"in": "query",
"example": "1000",
"description": "SSV Amount to be withdrawn. The amount must be divisible by 10000000.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
}
},
"required": [
"list"
],
"x-readme-ref-name": "EthereumUnsignedTransactionListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111150
},
"message": {
"type": "string",
"default": "The transaction could not be created because insufficient amount of SSV tokens"
},
"name": {
"type": "string",
"default": "InsufficientSsvException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientSsvException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InsufficientSsvException": {
"value": {
"error": {
"code": 111150,
"message": "The transaction could not be created because insufficient amount of SSV tokens",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111104
},
"message": {
"type": "string",
"default": "The SSV ID %s provided could not be found. Please specify the correct UUID."
},
"name": {
"type": "string",
"default": "SsvRequestNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SsvRequestNotFoundException"
}
]
}
}
},
"examples": {
"SsvRequestNotFoundException": {
"value": {
"error": {
"code": 111104,
"message": "The SSV ID undefined provided could not be found. Please specify the correct UUID.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111122
},
"message": {
"type": "string",
"default": "The withdrawal transaction could not be created because an internal server error occurred."
},
"name": {
"type": "string",
"default": "WithdrawException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WithdrawException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"WithdrawException": {
"value": {
"error": {
"code": 111122,
"message": "The withdrawal transaction could not be created because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Unified Api Tezos
*Source: [https://docs.p2p.org/docs/unified-api-tezos.md](https://docs.p2p.org/docs/unified-api-tezos.md)*
# Tezos
In the following guide, the integration process for the `xtz` chain is covered. The Tezos integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Tezos-specific details
>
> * `chain` — always set to `xtz` for Tezos-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` only.
> * `stakerAddress` — Tezos account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in XTZ.
# Staking Flow
## 1. Create Reveal Request
If you have not performed any operations on this account before, create a reveal request by sending a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "xtz",
"network": "mainnet",
"stakerAddress": "tz1Nfu7TmHj7GWARYHrxdVZ75BgcHwUnr3PM",
"amount": "5",
"extra": {
"operationType": "reveal",
"additionalAddresses": {
"tezosPubKey": "edpkvUh57bdTwgaHBE9bYVPLRv3myqzoD8RLsiRNnQs5TxvhdLswQ9"
}
}
}'
```
* `chain` — blockchain network, always set to `xtz` for Tezos-related requests.
* `network` — environment in which the transaction is processed: `mainnet` only.
* `stakerAddress` — Tezos account address initiating the reveal transaction.
* `amount` — amount of tokens to reveal in XTZ.
* `extra` — additional request parameters.
* `operationType` — type of operation; set to `reveal` for new accounts.
* `additionalAddresses.tezosPubKey` — staker public key.
Example response:
```json
{
"error": null,
"result": {
"amount": 5,
"stakerAddress": "tz1Nfu7TmHj7GWARYHrxdVZ75BgcHwUnr3PM",
"unsignedTransactionData": "5d601c0133d2cba0c9345fb5...",
"createdAt": "2025-06-03T23:36:22.450Z",
"extraData": {
"transactionId": "c23982ec-07aa-426b-a867-013cdacbd281",
"stakeId": "7ba5b6c6-e0e3-481c-8388-57ea3d15cacc",
"gasEstimate": {
"amount": "0.000279000000000000",
"gasLimit": ""
}
}
}
}
```
* `amount` — amount of tokens to reveal in XTZ.
* `stakerAddress` — Tezos account address initiating the transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. The object contains the list of data fields to be used to construct the reveal transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the reveal transaction.
* `stakeId` — unique identifier of the staking request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated fee in XTZ for processing the transaction.
* `gasLimit` — maximum gas limit for the transaction; option can be left empty or ignored, since it is not used in Tezos and reserved for compatibility only.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction.
To broadcast the signed transaction to the Tezos network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "xtz",
"network": "mainnet",
"signedTransaction": "{\"bytes\":\"024c70799bc16c1c95db0091ef51441bd6b8d2bf105a4a17793c776d530f82a16e002142e1ae4c4456b6f3742dd6510ea6dc7d2c11f48c029bf5ad4fa8010000\",\"sig\":\"sigWhmkraxYHSmd1SQS156Y1MvuBBzZ9sK9qFjiGoRDufGpEL6kXRyjmDx4rbGcUzzNatCUWipLvs7cQATocmqDFdVxjJ4n8\",\"prefixSig\":\"edsigtgXEsuorpDdogCRha2vHVJeSg1GvXnjuXX1UScoQEFgE84GhFRM4ppTs7TD4hxBLp8MpQ2WBBYptMCCfTm7oQJhbqPj5AJ\",\"sbytes\":\"024c70799bc16c1c95db0091ef51441bd6b8d2bf105a4a17793c776d530f82a16e002142e1ae4c4456b6f3742dd6510ea6dc7d2c11f48c029bf5ad4fa8010000429d6cadd75dcbc026097e94d90e6145bf477e9bd8a1ffa2948b81509f522ff1f30148bf227c6d83b1c3d98e9cd8f8e71177152b6dca938fe82da73bfaac8603\"}",
"stakerAddress": "tz1Nfu7TmHj7GWARYHrxdVZ75BgcHwUnr3PM",
"extra": {
"transactionId": "7977e904-e9bb-43d8-9c09-83812a15e8a8"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `signedTransaction` — signed transaction as a JSON string, including `bytes`, `sig`, `prefixSig`, and `sbytes` fields, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `stakerAddress` — Tezos account address initiating the transaction.
* `extra` — additional request parameters:
* `transactionId` — unique identifier of the reveal transaction.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"transactionHash": "oo3mw16oJqrBair2s31dvDhKjTXjKNcRPjJthKKN1qMnvjE7eCz"
}
}
}
```
* `extraData` — additional transaction details:
* `transactionHash` — transaction hash on the Tezos network, which can be tracked in [tzkt.io](tzkt.io) explorer.
## 3. Create Delegate Request
> Note that Tezos accounts can have only 1 delegation at a time.
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "xtz",
"network": "mainnet",
"stakerAddress": "tz1Nfu7TmHj7GWARYHrxdVZ75BgcHwUnr3PM",
"amount": "5",
"extra": {
"additionalAddresses": {
"tezosPubKey": "edpkvUh57bdTwgaHBE9bYVPLRv3myqzoD8RLsiRNnQs5TxvhdLswQ9"
}
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — Tezos account address initiating the transaction.
* `amount` — amount of tokens to delegate in XTZ. Minimum amount is 5 XTZ.
* `extra` — additional request parameters.
* `additionalAddresses.tezosPubKey` — staker public key; required for non-revealed accounts.
Example response:
```json
{
"error": null,
"result": {
"amount": 5,
"stakerAddress": "tz1Nfu7TmHj7GWARYHrxdVZ75BgcHwUnr3PM",
"unsignedTransactionData": "74aec234a40c4adfe6d68c5dbd104d04f0804e0e...",
"createdAt": "2025-06-03T23:36:36.439Z",
"extraData": {
"transactionId": "0a471c05-0714-4249-a4a0-e83d4a648fc0",
"stakeId": "d7ac3d47-d2ee-4704-8c5c-ea174ef7bc0b",
"gasEstimate": {
"amount": "0.000279000000000000",
"gasLimit": ""
}
}
}
}
```
* `amount` — amount of tokens to stake in XTZ.
* `stakerAddress` — Tezos account address initiating the staking transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this staking session.
* `stakeId` — unique identifier of the staking request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated fee in XTZ for processing the transaction.
* `gasLimit` — maximum gas limit for the transaction; can be left empty or ignored, since it is not used in Tezos and reserved for compatibility only.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Tezos-specific signing logic.
# Unstaking Flow
## 1. Create Undelegate Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "xtz",
"network": "mainnet",
"stakerAddress": "tz1Nfu7TmHj7GWARYHrxdVZ75BgcHwUnr3PM",
"extra": {
"amount": 5
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — Tezos account address initiating the transaction.
* `extra.amount` — amount of tokens to unstake in XTZ.
Example response:
```json
{
"error": null,
"result": {
"amount": 5,
"stakerAddress": "tz1Nfu7TmHj7GWARYHrxdVZ75BgcHwUnr3PM",
"unsignedTransactionData": "024c70799bc16c1c95db0091ef51441bd6b8d2bf105a4a17793c776d530f82a1...",
"createdAt": "2025-06-05T12:09:40.751Z",
"extraData": {
"transactionId": "b2757302-8e89-4227-a841-461936ccd971",
"stakeId": "a78b76b6-e866-4dd3-9a7d-3a89f5937ec7",
"gasEstimate": {
"amount": "0.000248000000000000",
"gasLimit": ""
}
}
}
}
```
* `amount` — amount of XTZ to be unstaked.
* `stakerAddress` — Tezos account address initiating the transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this unstaking session.
* `stakeId` — unique identifier of the unstaking request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated fee in XTZ for processing the transaction.
* `gasLimit` — maximum gas limit for the transaction; can be left empty or ignored, since it is not used in Tezos and reserved for compatibility only.
## 2. Sign and Send Transaction
> Note that the withdrawal is available only after the unstaking period of 4 days ends.
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Tezos-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Data Validator Fee
*Source: [https://docs.p2p.org/reference/data-validator-fee.md](https://docs.p2p.org/reference/data-validator-fee.md)*
# Get Validator Fee
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/validator/fee": {
"get": {
"operationId": "data-validator-fee",
"summary": "Get Validator Fee",
"description": "Get a list of validator fee.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum-agg",
"ethereum",
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"sui",
"polygon",
"avail",
"ton",
"near",
"cardano"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Validator address in the required network. For the Ethereum network, it is a public validator key.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stakingPeriod": {
"type": "number",
"description": "Number of the staking period."
},
"stakingPeriodStart": {
"type": "string",
"description": "Timestamp of the staking period start in the ISO 8601 format."
},
"stakingPeriodEnd": {
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format."
},
"fee": {
"type": "number",
"description": "Validator fee."
}
},
"required": [
"stakingPeriod",
"stakingPeriodStart",
"stakingPeriodEnd",
"fee"
],
"x-readme-ref-name": "ValidatorFee"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetValidatorFeeResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115100
},
"message": {
"type": "string",
"default": "The request could not be performed because the validator address provided is not valid on the specified network. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "InvalidValidatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidValidatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidValidatorAddressException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the validator address provided is not valid on the specified network. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115302
},
"message": {
"type": "string",
"default": "The list of validator fee could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetValidatorFeeException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetValidatorFeeException"
}
]
}
}
},
"examples": {
"GetValidatorFeeException": {
"value": {
"error": {
"code": 115303,
"message": "The list of validator fee could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Validator"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Avail Pool Claim Payout
*Source: [https://docs.p2p.org/reference/avail-pool-claim-payout.md](https://docs.p2p.org/reference/avail-pool-claim-payout.md)*
# Create Claim Payout Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/staking/pool/claim-payout": {
"post": {
"operationId": "avail-pool-claim-payout",
"summary": "Create Claim Payout Request",
"description": "Creating a claim payout request refers to the process of issuing a payout from the validator to the nomination pool members for further rewards claiming.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Avail network:
`mainnet` — Avail mainnet.
`testnet` — Avail testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
}
},
"required": [
"stashAccountAddress"
],
"x-readme-ref-name": "AvailPoolClaimPayoutRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000"
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "AvailTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119103
},
"message": {
"type": "string",
"default": "The transaction could not be found. Please specify the correct transaction data."
},
"name": {
"type": "string",
"default": "BondNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119105
},
"message": {
"type": "string",
"default": "The request could not be performed because the controller address does not correspond to the provided one."
},
"name": {
"type": "string",
"default": "WrongControllerException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongControllerException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 119101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Avail address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"BondNotFoundException": {
"value": {
"error": {
"code": 119103,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"WrongControllerException": {
"value": {
"error": {
"code": 119105,
"message": "The request could not be performed because the controller address does not correspond to the provided one.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119137
},
"message": {
"type": "string",
"default": "The claim payout request could not be performed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "ClaimPayoutException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ClaimPayoutException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"ClaimPayoutException": {
"value": {
"error": {
"code": 119137,
"message": "The claim payout request could not be performed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Aptos Staking Delegated Unlock
*Source: [https://docs.p2p.org/reference/aptos-staking-delegated-unlock.md](https://docs.p2p.org/reference/aptos-staking-delegated-unlock.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/aptos/{network}/staking/delegated/unlock": {
"post": {
"operationId": "aptos-staking-delegated-unlock",
"summary": "Create Unstake Request",
"description": "Construct a serialized transaction to undelegate tokens from the delegator's active stake in the delegation pool.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Aptos network:
`mainnet` — Aptos mainnet.
`testnet` — Aptos devnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"amount": {
"format": "datetime",
"type": "string",
"description": "Amount of tokens to unlock in Octas (1 APT = 10⁸ Octas).",
"example": 1100000000,
"nullable": false
},
"delegatorAddress": {
"type": "string",
"description": "Delegator account address.",
"nullable": false,
"example": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a"
},
"gas": {
"description": "Computational effort required to execute the transaction, measured in gas units.",
"nullable": false,
"allOf": [
{
"type": "object",
"properties": {
"unitPrice": {
"type": "number",
"description": "Price per unit of gas in Octas for processing the Aptos transaction.",
"example": 100,
"minimum": 0
},
"maxGasLimit": {
"type": "number",
"description": "Maximum gas limit for the transaction.",
"example": 100,
"minimum": 0
},
"used": {
"type": "number",
"description": "Amount of gas spent for the transaction.",
"example": 100,
"minimum": 0
}
},
"required": [
"unitPrice",
"maxGasLimit"
],
"x-readme-ref-name": "GasDataDto"
}
]
}
},
"required": [
"amount",
"delegatorAddress",
"gas"
],
"x-readme-ref-name": "CreateUnlockTransactionRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"amount": {
"format": "datetime",
"type": "string",
"description": "Amount of tokens to unlock in Octas (1 APT = 10⁸ Octas).",
"example": 1100000000,
"nullable": false
},
"delegatorAddress": {
"type": "string",
"description": "Delegator account address.",
"nullable": false,
"example": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a"
},
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa571a5bc9b1bfd5fe58e6e09a5be251a3299985494d022959ce206f1f23f752e21000000000000000200000000000000000000000000000000000000000000000000000000000000010f64656c65676174696f6e5f706f6f6c096164645f7374616b650002207a2ddb6af66beb0d9987c6c9010cb9053454f067e16775a8ecf19961195c3d28080100000000000000400d0300000000006400000000000000e5742068000000000200",
"nullable": false
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z",
"nullable": false
}
},
"required": [
"amount",
"delegatorAddress",
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "CreateUnlockTransactionResponseDto"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124106
},
"message": {
"type": "string",
"default": "The request could not be performed because the gas unit price provided is too low."
},
"name": {
"type": "string",
"default": "GasUnitPriceTooLowException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GasUnitPriceTooLowException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124109
},
"message": {
"type": "string",
"default": "The request could not be performed because the account does not have enough balance to perform the transaction."
},
"name": {
"type": "string",
"default": "InsufficientBalanceException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientBalanceException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124108
},
"message": {
"type": "string",
"default": "The request could not be performed because the delegator address provided is not valid."
},
"name": {
"type": "string",
"default": "InvalidDelegatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidDelegatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124107
},
"message": {
"type": "string",
"default": "The request could not be performed because the max gas amount provided is too low."
},
"name": {
"type": "string",
"default": "MaxGasAmountTooLowException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "MaxGasAmountTooLowException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124110
},
"message": {
"type": "string",
"default": "The request could not be performed because the simulation of the transaction failed. Reason: %s."
},
"name": {
"type": "string",
"default": "SimulateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SimulateTransactionException"
}
]
}
}
},
"examples": {
"GasUnitPriceTooLowException": {
"value": {
"error": {
"code": 124106,
"message": "The request could not be performed because the gas unit price provided is too low.",
"type": "client"
},
"result": null
}
},
"InsufficientBalanceException": {
"value": {
"error": {
"code": 124109,
"message": "The request could not be performed because the account does not have enough balance to perform the transaction.",
"type": "client"
},
"result": null
}
},
"InvalidDelegatorAddressException": {
"value": {
"error": {
"code": 124108,
"message": "The request could not be performed because the delegator address provided is not valid.",
"type": "client"
},
"result": null
}
},
"MaxGasAmountTooLowException": {
"value": {
"error": {
"code": 124107,
"message": "The request could not be performed because the max gas amount provided is too low.",
"type": "client"
},
"result": null
}
},
"SimulateTransactionException": {
"value": {
"error": {
"code": 124110,
"message": "The request could not be performed because the simulation of the transaction failed. Reason: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Aptos"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Polygon
*Source: [https://docs.p2p.org/docs/withdrawal-polygon.md](https://docs.p2p.org/docs/withdrawal-polygon.md)*
# Withdrawal
The withdrawal process in the Polygon network using the Staking API can be done following these steps:
1. Undelegate staked tokens.
> It takes up to 3-4 days to prepare your tokens for unstaking as Polygon uses a system of checkpoints. The average undelegate period on Polygon is 80 checkpoints.
2. Unstake tokens — available after the undelegate period.
3. Withdraw unstaked tokens.
After all operations, you need to [sign and send the transaction](doc:signing-transaction-solana) to the Polygon network.
# 1. Undelegate Staked Tokens
Prepare previously staked tokens to unstake by sending a POST request to [/api/v1/polygon/staking/undelegate](ref:StakingController_undelegate).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polygon/staking/undelegate \
--head 'accept: application/json' \
--head 'Authorization: Bearer ' \
--head 'Content-Type: application/json' \
--data '
{
"amount": "100000000000000000",
"stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
}
'
```
* `amount` — amount of tokens in Wei (1 MATIC = 10^18 Wei) to undelegate.
* `stakerAddress` — staker account address.
Example response:
```json
{
"result": {
"serializeTx": "0x02f86505800214830186a094499d11e0b6eac7c0593d8fb292dcbbf815fb29ae80b844095ea7b300000000000000000000000000200ea4ee292e253e6ca07dba5edc07c8aa37a3000000000000000000000000000000000000000000000000016345785d8a0000c0",
"to": "0x499d11E0b6eAC7c0593d8Fb292DCBbF815Fb29Ae",
"gasLimit": "0.0000000000001",
"data": "0x095ea7b300000000000000000000000000200ea4ee292e253e6ca07dba5edc07c8aa37a3000000000000000000000000000000000000000000000000016345785d8a0000",
"value": "0.0",
"chainId": 1,
"type": 2,
"maxFeePerGas": "0.00000000000000002",
"maxPriorityFeePerGas": "2"
}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
# 2. Unstake Tokens
After the undelegate period on Polygon is complete, unstake your tokens by sending a POST request to [/api/v1/polygon/staking/unstake](ref:StakingController_unstake).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polygon/staking/unstake \
--head 'accept: application/json' \
--head 'Authorization: Bearer ' \
--head 'Content-Type: application/json' \
--data '
{
"unbondNonce": "100",
"stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
}
'
```
* `unbondNonce` — unique identifier (nonce) of the undelegate request.
* `stakerAddress` — staker account address.
Example response is the same as in the first Undelegate Staked Tokens step.
# 3. Withdraw Unstaked Tokens
To withdraw unstaked tokens:
1. Send a POST request to [/api/v1/polygon/staking/withdraw](ref:StakingController_withdraw).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polygon/staking/withdraw \
--head 'accept: application/json' \
--head 'Authorization: Bearer ' \
--head 'Content-Type: application/json' \
--data '
{
"stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
}
'
```
* `stakerAddress` — staker account address.
Example response is the same as for the two previous steps.
2. [Sign and send the transaction](doc:signing-transaction-solana) to the Polygon network.
## What's Next?
* [Getting Started](doc:staking-polygon).
* [Staking API](ref:polygon-staking-stake) reference.
---
## Data Delegator Apy
*Source: [https://docs.p2p.org/reference/data-delegator-apy.md](https://docs.p2p.org/reference/data-delegator-apy.md)*
# Get Delegator APY
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/delegator/apy": {
"get": {
"operationId": "data-delegator-apy",
"summary": "Get Delegator APY",
"description": "Get a list of delegator annual percentage yield (APY).",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum-agg",
"ethereum",
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"sui",
"polygon",
"avail",
"ton",
"near",
"cardano"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Delegator address in the required network.",
"schema": {
"type": "string"
}
},
{
"name": "addressType",
"required": false,
"in": "query",
"description": "
Delegator address type in the required network:
`deposit` — available for the Ethereum network (used by default)
`withdrawal` — available for the Ethereum network
`delegator` — available for the Polygon, Solana, Cosmos, Near, and Sui networks (used by default)
`stake_account` — available for the Solana
`nominator` — available for the TON and Polkadot networks (used by default)
`nominator_reward_account` — available for the Polkadot networks
`all` — aggregate the results over the entire period
.",
"schema": {
"enum": [
"stakingPeriod",
"day",
"all"
],
"type": "string"
}
},
{
"name": "skip",
"required": false,
"in": "query",
"description": "Exclude breakdown by `validator` from the data report.",
"schema": {
"enum": [
"validator"
],
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"validator": {
"type": "string",
"description": "Validator address."
},
"stakingPeriod": {
"type": "number",
"description": "Number of the staking period."
},
"stakingPeriodStart": {
"type": "string",
"description": "Timestamp of the staking period start in the ISO 8601 format."
},
"stakingPeriodEnd": {
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format."
},
"grossApy": {
"type": "number",
"description": "Delegator gross annual percentage yield (APY)."
},
"netApy": {
"type": "number",
"description": "Delegator net annual percentage yield (APY)."
}
},
"required": [
"stakingPeriod",
"stakingPeriodStart",
"stakingPeriodEnd",
"grossApy",
"netApy"
],
"x-readme-ref-name": "DelegatorAPY"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetDelegatorAPYResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124108
},
"message": {
"type": "string",
"default": "The request could not be performed because the delegator address provided is not valid."
},
"name": {
"type": "string",
"default": "InvalidDelegatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidDelegatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidDelegatorAddressException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the delegator address provided is not valid on the specified network. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115404
},
"message": {
"type": "string",
"default": "The delegator annual percentage yield could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetDelegatorApyException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetDelegatorApyException"
}
]
}
}
},
"examples": {
"GetDelegatorApyException": {
"value": {
"error": {
"code": 115404,
"message": "The delegator annual percentage yield could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Delegator"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Polkadot Staking Unbond
*Source: [https://docs.p2p.org/reference/polkadot-staking-unbond.md](https://docs.p2p.org/reference/polkadot-staking-unbond.md)*
# Create Unbond Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/staking/unbond": {
"post": {
"operationId": "polkadot-staking-unbond",
"summary": "Create Unbond Request",
"description": "Unbonding tokens within the Polkadot network refers to the process of withdrawing or releasing tokens that were previously staked or bonded.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"amount": {
"type": "number",
"description": "Amount of tokens to unbond (in usual DOTs/KSMs/WNDs).",
"example": 3
}
},
"required": [
"stashAccountAddress",
"amount"
],
"x-readme-ref-name": "UnbondRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xac0406000b0030ef7dba0203ded255321b86f5f975cf04fd0e9d2b1d941469d469dcc93b89441cdfe6c39f7b"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"amount": {
"type": "number",
"description": "Amount of tokens for bond operations (in usual DOTs/KSMs/WNDs).",
"example": 3
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"unsignedTransaction",
"stashAccountAddress",
"amount",
"createdAt"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119110
},
"message": {
"type": "string",
"default": "The request could not be performed because the requested amount of tokens to unbond exceeds the bonded amount. Please specify the correct amount."
},
"name": {
"type": "string",
"default": "NotEnoughBonedAmountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NotEnoughBonedAmountException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"NotEnoughBonedAmountException": {
"value": {
"error": {
"code": 107110,
"message": "The request could not be performed because the requested amount of tokens to unbond exceeds the bonded amount. Please specify the correct amount.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119135
},
"message": {
"type": "string",
"default": "The unbond request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "UnbondException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "UnbondException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"UnbondException": {
"value": {
"error": {
"code": 107130,
"message": "The unbond request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Polkadot Transaction List
*Source: [https://docs.p2p.org/reference/polkadot-transaction-list.md](https://docs.p2p.org/reference/polkadot-transaction-list.md)*
# List Broadcasted Transactions
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/tx": {
"get": {
"operationId": "polkadot-transaction-list",
"summary": "List Broadcasted Transactions",
"description": "Return a list of all broadcasted transactions.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
},
{
"name": "limit",
"required": true,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": true,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 100000,
"type": "number"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"totalCount": {
"type": "number",
"minimum": 1,
"description": "Total count of resources relevant to the current request, based on filters applied."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"network": {
"type": "string",
"enum": [
"mainnet",
"kusama",
"westend"
],
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
"
},
"signedTransaction": {
"type": "string",
"description": "Signed transaction in Base64 encrypted format which needs to be broadcast to the network.",
"example": "0xbd018400cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c011a6fc75a4d779e13a789ce9fe03d5cbb090b1e9833ae38c2c873571b73e2d7393f30bf097d93ca1692d426196f263d609e4d421cef3e017ad8bd388604e47e839502a80006010700e40b5402",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"status": {
"type": "string",
"enum": [
"success",
"failed"
],
"description": "Transaction status.",
"example": "success"
},
"blockHash": {
"type": "string",
"description": "Block hash in which the transaction was included.",
"example": "0x0628743b05ffb4c9d5ea2144b359af38910f0ae439a685f57d85b50b9481ba3f"
},
"blockId": {
"type": "number",
"description": "Unique block identifier.",
"example": "17168395"
},
"extrinsicId": {
"type": "number",
"description": "Unique extrinsic identifier.",
"example": "17177570-2"
},
"transactionHash": {
"type": "string",
"description": "Signed extrinsic transaction in hex format.",
"example": "0xbd018400cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c011a6fc75a4d779e13a789ce9fe03d5cbb090b1e9833ae38c2c873571b73e2d7393f30bf097d93ca1692d426196f263d609e4d421cef3e017ad8bd388604e47e839502a80006010700e40b5402"
},
"signerAccount": {
"type": "string",
"description": "Account that signed the transaction.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"data": {
"type": "string",
"description": "Method data."
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"network",
"signedTransaction",
"status",
"blockHash",
"blockId",
"extrinsicId",
"transactionHash",
"signerAccount",
"data",
"createdAt"
],
"x-readme-ref-name": "PolkadotTransactionResponse"
}
}
},
"required": [
"limit",
"offset",
"totalCount",
"list"
],
"x-readme-ref-name": "GetListTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119124
},
"message": {
"type": "string",
"default": "The list of broadcasted transactions could not be obtained because the internal server error occurred."
},
"name": {
"type": "string",
"default": "TransactionGetListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionGetListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TransactionGetListException": {
"value": {
"error": {
"code": 107124,
"message": "The list of broadcasted transactions could not be obtained because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Ton Staking Broadcast
*Source: [https://docs.p2p.org/reference/ton-staking-broadcast.md](https://docs.p2p.org/reference/ton-staking-broadcast.md)*
# Broadcast Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/ton/{network}/transactions/broadcast": {
"post": {
"operationId": "ton-staking-broadcast",
"summary": "Broadcast Transaction",
"description": "Broadcast a signed transaction to the TON network.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
TON network:
`mainnet` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Signed transaction in the hexadecimal format which needs to be broadcasted to the network.",
"example": "te6ccgEBAQEABgAACCiAmCM="
},
"signature": {
"type": "string",
"description": "External message signature which needs to be signed with the private key.",
"example": "te6ccgEBAQEABgAACCiAmCM="
},
"publicKey": {
"type": "string",
"description": "Public key of the nominator for the TON network.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"walletVersion": {
"type": "string",
"description": "Version of the smart contract used by the wallet in the TON blockchain.",
"example": "V4",
"default": "V4"
}
},
"required": [
"unsignedTransaction",
"signature",
"publicKey"
],
"x-readme-ref-name": "BroadcastRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {},
"x-readme-ref-name": "BroadcastResponse"
}
]
}
}
}
}
}
}
},
"tags": [
"TON"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Staking Ton
*Source: [https://docs.p2p.org/docs/staking-ton.md](https://docs.p2p.org/docs/staking-ton.md)*
# Getting Started
There are two ways to start staking on the TON network using the Staking API:
* Stake individually with a validator via a single nominator pool.
* Stake along with multiple nominators via [Ton Whales pools](https://tonwhales.com/staking).
> 🚧 About single nominator pools
>
> This is an alternative type of the TON smart contract designed for validators that have enough self stake to validate by themselves without relying on third-party nominators stakes.
>
> Staking via this flow is possible only through the specific nominator address. Since the P2P team has to prepare a separate pool for your address, [contact](doc:contacts) us and provide your address before you start working with the API.
For both flows, to start using the Staking API:
1. Create a stake transaction.
2. Sign and broadcast it to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
Request examples are provided using [cURL](https://curl.se/).
# 1. Create Stake Transaction
Depending on the type of your staking pool, send a POST request either to [/api/v1/ton/\{network}/staking/single-nominator/stake](ref:ton-staking-single-nominator-stake) or to [/api/v1/ton/\{network}/staking/ton-whales/stake](ref:).
Example request (in the `testnet` network for a single nominator pool):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/ton/testnet/staking/single-nominator/stake \
--header 'accept: application/json' \\
--header 'authorization: Bearer ' \\
--header 'content-type: application/json' \\
--data '
{
"publicKey": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6",
"amount": 20000000000,
"walletVersion": "V4"
}'
```
* `publicKey` — public key of the nominator for the TON network.
* `amount` — amount of tokens to stake in nanoTONs (1 TON = 10⁹ nanoTONs). Note that the minimum staking amount is not limited, but there is a maximum cap of 2 000 000 TON for each pool.
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain:
* `V3R1` and `V3R2` — wallet V3.
* `V4` — wallet V4; used by default.
* `V5R1` — wallet V5.
Example response:
```json
{
"error": null,
"result": {
"unsignedTransaction": "b5ee9c7241010101003800006b000010000000000000000001000000039fedeab7a2b56b38f19f60b5b9f70b2f1ba2d89b9c5a756036c7cfad73571fb281887735940193456f7e",
"walletVersion": "V4",
"stakerAddress": "0QDZncytCDTPJylG1POFhqzeCLDFZNKhJ2v73lcsBNjQHMZx",
"publicKey": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6",
"amount": 2
}
}
```
* `unsignedTransaction` — unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to create a staking request.
* `poolAddress` — nominator pool address (for Ton Whales pools).
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain.
* `stakerAddress` — main account address of the bounceable type which keeps tokens.
* `publicKey` — public key of the nominator for the TON network.
* `amount` — amount of tokens to stake in TON.
# 2. Sign and Broadcast Transaction
[Sign and broadcast](doc:signing-transaction-ton) the `unsignedTransaction` to the TON network.
To check the transaction status, send a GET request to [/api/v1/ton/\{network}/transactions/status/\{address}/\{transactionHash}](ref:ton-staking-transaction-status).
Example request (in the `testnet` network for a single nominator pool):
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/ton/testnet/transactions/status/0QDZncytCDTPJylG1POFhqzeCLDFZNKhJ2v73lcsBNjQHMZx/2829e4bb8a7b8084040c731a07523d680ce30fecef12f8eec1e409f3c6077a5e \
--header 'accept: application/json'
```
* `address` — staker account address.
* `transactionHash` — hash of the transaction.
Example response:
```json
{
"error": null,
"result": {
"address": "0QC1f6DghlW6w31D7GWiYt0dZvX1SR3sGAsto_AhdQRFBobh",
"lt": "27726830000001",
"prevTransactionHash": "6210303f3cfb630c349b3859d9e367a65a6772938c681774e2a315aa95c80224",
"prevTransactionLt": "1234567890abcdef",
"now": 1730905768,
"outMessagesCount": 1,
"oldStatus": "active",
"endStatus": "active",
"transactionHash": "2829e4bb8a7b8084040c731a07523d680ce30fecef12f8eec1e409f3c6077a5e"
},
}
```
* `address` — staker account address.
* `lt` — logical time of the last transaction created by this staker account.
* `prevTransactionHash` — hash of the previous transaction.
* `prevTransactionLt` — logical time of the previous transaction.
* `now` — current time on the TON blockchain node.
* `outMessagesCount` — count of output messages sent by the smart contract in the result of this transaction.
* `oldStatus` — staker account status before transaction execution.
* `endStatus` — staker account status after transaction execution.
* `transactionHash` — hash of the transaction.
# What's Next?
* [Staking API](ref:ton-staking-single-nominator-stake) reference.
* [Withdrawal](doc:withdrawal-ton).
---
## Unified Create Unstake Transaction
*Source: [https://docs.p2p.org/reference/unified-create-unstake-transaction.md](https://docs.p2p.org/reference/unified-create-unstake-transaction.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/unified/staking/unstake": {
"post": {
"operationId": "unified-create-unstake-transaction",
"summary": "Create Unstake Request",
"description": "Create an unstake request transaction to unstake the locked assets within the network.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"chain": {
"type": "string",
"enum": [
"aptos",
"avail",
"babylon-btc",
"babylon",
"cardano",
"celestia",
"cosmos",
"polkadot",
"polygon",
"sei",
"solana",
"eth_ssv",
"ton_whales",
"near",
"dydx",
"sui",
"grt",
"xtz"
],
"description": "Target blockchain network in which the transaction is processed (aptos,avail,babylon-btc,babylon,cardano,celestia,cosmos,polkadot,polygon,sei,solana,eth_ssv,ton_whales,near,dydx,sui,grt,xtz).",
"example": "aptos"
},
"network": {
"type": "string",
"enum": [
"mainnet",
"testnet",
"babylon-testnet",
"babylon-mainnet",
"celestia-mainnet-beta",
"celestia-mocha-testnet",
"cosmoshub-4",
"kusama",
"westend",
"pacific-1",
"atlantic-2",
"mainnet-beta"
],
"description": "Network environment in which the transaction is processed (mainnet,testnet,babylon-testnet,babylon-mainnet,celestia-mainnet-beta,celestia-mocha-testnet,cosmoshub-4,kusama,westend,pacific-1,atlantic-2,mainnet-beta).",
"example": "mainnet"
},
"stakerAddress": {
"type": "string",
"description": "Account address initiating the unstaking transaction.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"extra": {
"type": "object",
"description": "Additional chain-specific request parameters.",
"example": {
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
}
}
},
"required": [
"chain",
"network",
"stakerAddress"
],
"x-readme-ref-name": "UnifiedUnstakeRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"amount": {
"type": "number",
"description": "Amount of tokens to stake in native currency.",
"example": 1002282880,
"minimum": 0
},
"stakerAddress": {
"description": "Account address initiated the staking, unstaking or withdrawal operation.",
"example": "6ZuLUCwVTvuQJrN1HrpoHJheQUw9Zk8CtiD3CEpHiA9E",
"allOf": [
{
"type": "object",
"properties": {},
"x-readme-ref-name": "String"
}
]
},
"unsignedTransactionData": {
"description": "Unsigned transaction data in Base64 encrypted format or as an object. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAA...",
"allOf": [
{
"type": "object",
"properties": {},
"x-readme-ref-name": "String"
}
]
},
"extraData": {
"type": "object",
"description": "Additional chain-specific transaction details."
},
"createdAt": {
"format": "datetime",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z",
"allOf": [
{
"type": "object",
"properties": {},
"x-readme-ref-name": "CodecDate"
}
]
}
},
"required": [
"amount",
"stakerAddress",
"unsignedTransactionData",
"createdAt"
],
"x-readme-ref-name": "UnifiedStakeResponse"
}
]
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Unified"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Ssv Request Status
*Source: [https://docs.p2p.org/reference/ssv-request-status.md](https://docs.p2p.org/reference/ssv-request-status.md)*
# Check Status Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/request/status/{id}": {
"get": {
"operationId": "ssv-request-status",
"summary": "Check Status Request",
"description": "Check the status of the set-up operation.",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "UUID of the SSV request.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"example": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"description": "UUID that was specified in the SSV set-up request."
},
"status": {
"type": "string",
"enum": [
"init",
"processing",
"ready",
"validator-ready",
"validator-error",
"cancel"
],
"description": "
Current status of the SSV request:
init — request is stored.
processing — request in progress, please wait.
ready — request is ready.
validator-ready — validator is registered on the SSV network.
validator-error — validator data is not valid.
cancel — request canceled due to an error or timeout.
",
"example": "processing"
},
"validatorsCount": {
"type": "number",
"description": "Number of validators.",
"default": 1,
"minimum": 1,
"maximum": 1,
"example": 1
},
"amountPerValidator": {
"type": "string",
"description": "Amount of tokens to stake in Gwei per validator.",
"example": "32000000000"
},
"withdrawalCredentialsType": {
"type": "string",
"description": "Withdrawal credentials type.",
"example": "0x02",
"enum": [
"0x01",
"0x02"
]
},
"withdrawalAddress": {
"type": "string",
"description": "Withdrawal address of the cluster owner.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"feeRecipientAddress": {
"type": "string",
"description": "Eth1 address that receives fee recipient rewards.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"ssvOwnerAddress": {
"type": "string",
"description": "An ETH1 address from which registerValidator method of SSV contract will be called.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"type": {
"type": "string",
"enum": [
"with-encrypt-key",
"without-encrypt-key"
],
"example": "without-encrypt-key",
"default": "without-encrypt-key",
"description": "Request type: with or without an encrypted key. If `with-encrypt-key` is selected, fill the `ecdhPublicKey` field."
},
"operationPeriodInDays": {
"type": "number",
"example": 31556952,
"description": "Operation period in days."
},
"liquidationPeriodInDays": {
"type": "number",
"example": 2629746,
"description": "Liquidation threshold period in days."
},
"ecdhPublicKey": {
"type": "string",
"example": null,
"description": "Your ECDH public key for getting the encrypted validator private key."
},
"validatorRegistrationTxs": {
"example": null,
"description": "Array of transactions related to validator registration.",
"type": "array",
"items": {
"type": "string"
}
},
"feeRecipientTx": {
"example": null,
"description": "Array of transaction for setting the fee recipient address.",
"type": "array",
"items": {
"type": "string"
}
},
"approveTx": {
"example": null,
"description": "Array of transaction to approve SSV transfer.",
"type": "array",
"items": {
"type": "string"
}
},
"encryptedShares": {
"type": "array",
"items": {
"type": "object",
"properties": {
"publicKey": {
"type": "string",
"description": "Validator public key."
},
"nonce": {
"type": "string",
"description": "Nonce used for signature in `sharesData`."
},
"sharesData": {
"type": "string",
"description": "Data used in the `registerValidator` Ethereum transaction from the SSV contract to create a validator."
},
"ecdhEncryptedPrivateKey": {
"type": "string",
"description": "Encrypted validator private key."
}
},
"required": [
"publicKey",
"nonce",
"sharesData"
],
"x-readme-ref-name": "EncryptedShareResponse"
}
},
"clusters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"operators": {
"description": "Number of operators in the cluster.",
"type": "array",
"items": {
"type": "number"
}
}
},
"required": [
"operators"
],
"x-readme-ref-name": "ClusterResponse"
}
}
},
"required": [
"id",
"status",
"validatorsCount",
"amountPerValidator",
"withdrawalCredentialsType",
"withdrawalAddress",
"feeRecipientAddress",
"ssvOwnerAddress",
"type",
"operationPeriodInDays",
"liquidationPeriodInDays",
"encryptedShares",
"clusters"
],
"x-readme-ref-name": "SsvRequestResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111104
},
"message": {
"type": "string",
"default": "The SSV ID %s provided could not be found. Please specify the correct UUID."
},
"name": {
"type": "string",
"default": "SsvRequestNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SsvRequestNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111123
},
"message": {
"type": "string",
"default": "The request could not be performed because the SSV cluster was liquidated. Please register a new cluster and then try again."
},
"name": {
"type": "string",
"default": "ClusterIsLiquidatedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ClusterIsLiquidatedException"
}
]
}
}
},
"examples": {
"SsvRequestNotFoundException": {
"value": {
"error": {
"code": 111104,
"message": "The SSV ID undefined provided could not be found. Please specify the correct UUID.",
"type": "not_found"
},
"result": null
}
},
"ClusterIsLiquidatedException": {
"value": {
"error": {
"code": 111123,
"message": "The request could not be performed because the SSV cluster was liquidated. Please register a new cluster and then try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111127
},
"message": {
"type": "string",
"default": "The request could not be performed because the number of encrypted shardes is not valid. Please try again."
},
"name": {
"type": "string",
"default": "InvalidEncryptedShardesCountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidEncryptedShardesCountException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111102
},
"message": {
"type": "string",
"default": "The status of the SSV request could not be obtained because the internal server error occurred."
},
"name": {
"type": "string",
"default": "SsvRequestGetException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SsvRequestGetException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"InvalidEncryptedShardesCountException": {
"value": {
"error": {
"code": 111127,
"message": "The request could not be performed because the number of encrypted shardes is not valid. Please try again.",
"type": "server"
},
"result": null
}
},
"SsvRequestGetException": {
"value": {
"error": {
"code": 111102,
"message": "The status of the SSV request could not be obtained because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Getting Started Aptos
*Source: [https://docs.p2p.org/docs/getting-started-aptos.md](https://docs.p2p.org/docs/getting-started-aptos.md)*
# Getting Started
Staking in the Aptos network using the Staking API consists of several main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
A request example is provided using [cURL](https://curl.se/).
## 1. Create Stake Transaction
Send a POST request to `/api/v1/aptos/{network}/staking/delegated/add` [endpoint](ref:aptos-staking-delegated-add).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/aptos/mainnet/staking/delegated/add \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"amount": 1100000000,
"delegatorAddress": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a",
"gas": {
"unitPrice": 100,
"maxGasLimit": 100,
"used": 100
}
}
'
```
* `amount` — amount of tokens to stake in Octas. Minimum stake amount is 11 APT (1 APT = 10⁸ Octas).
* `delegatorAddress` — delegator stash account address which keeps tokens.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `unitPrice` — price per unit of gas in Octas for processing the Aptos transaction.
* `maxGasLimit` — maximum gas limit for the transaction.
* `used` — amount of gas spent for the transaction.
Example response:
```json
{
"result": {
"amount": 1100000000,
"delegatorAddress": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a",
"unsignedTransaction": "0xa571a5bc9b1bfd5fe58e6e09a5be251a3299985494d022959ce206f1f23f752e21000000000000000200000000000000000000000000000000000000000000000000000000000000010f64656c65676174696f6e5f706f6f6c096164645f7374616b650002207a2ddb6af66beb0d9987c6c9010cb9053454f067e16775a8ecf19961195c3d28080100000000000000400d0300000000006400000000000000e5742068000000000200",
"createdAt": "2023-08-24T08:14:50.455Z"
},
"error": {}
}
```
* `amount` — amount of tokens to stake in Octas.
* `delegatorAddress` — delegator stash account address which keeps tokens.
* `unsignedTransaction` — unsigned transaction in hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
## 2. Sign and Send Transaction
Use `unsignedTransaction` to [sign and send](doc:signing-transaction-aptos) the signed transaction to the Aptos network. By broadcasting this transaction, you're adding the tokens to P2P.ORG delegation pool.
To check the transaction status, send a GET request to `/api/v1/aptos/{network}/transaction/status/{transactionHash}]` [endpoint](ref:aptos-transaction-status).
Example request (for `mainnet` network):
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/aptos/mainnet/transaction/status/0x8d80b8ed85b578eeb873731101a926221701ee48218f6c9b83895f7ac1535641 \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json'
```
* `transactionHash` — hash of the transaction.
Example response:
```json
{
"result": {
"createdAt": "2025-06-24T08:14:50.455Z",
"gas": {
"unitPrice": 100,
"maxGasLimit": 100,
"used": 100
},
"senderAddress": "0xd890b1115b39c8d182aeac6cae313cc713cd93922135f8a5893c34fce4e0f32a",
"sequenceNumber": 42,
"status": "success",
"transactionHash": "0x8d80b8ed85b578eeb873731101a926221701ee48218f6c9b83895f7ac1535641"
},
"error": {}
}
```
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `unitPrice` — price per unit of gas in Octas for processing the Aptos transaction.
* `maxGasLimit` — maximum gas limit for the transaction.
* `used` — amount of gas spent for the transaction.
* `senderAddress` — transaction sender address.
* `sequenceNumber` — number of transactions that have been submitted and committed on chain from the sender account.
* `status` — transaction status: `success`, `failed`.
* `transactionHash` — hash of the transaction.
## What's Next?
* [Sign and Broadcast Transaction](doc:signing-transaction-aptos)
* [Withdrawal](doc:withdrawal-aptos)
* [Staking API](ref:aptos-transaction-status) reference
---
## Unified Api Cosmos
*Source: [https://docs.p2p.org/docs/unified-api-cosmos.md](https://docs.p2p.org/docs/unified-api-cosmos.md)*
# Cosmos
In the following guide, the integration process for the `cosmos` chain is covered. The Cosmos integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Cosmos-specific details
>
> * `chain` — always set to `cosmos` for Cosmos-related requests.
> * `network` — environment in which the transaction is processed: `cosmoshub-4` only.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in ATOM (in uATOM internally).
# Staking Flow
## 1. Create Stake Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "cosmos",
"network": "cosmoshub-4",
"stakerAddress": "cosmos1tmpp633vf37d67lqnyuxw5a8lvvdaqksa0x0aq",
"amount": "0.0042"
}'
```
* `chain` — blockchain network, always set to `cosmos` for Cosmos-related requests.
* `network` — environment in which the transaction is processed: `cosmoshub-4` only.
* `stakerAddress` — account address initiating the staking transaction.
* `amount` — amount of tokens to stake in ATOM.
Example response:
```json
{
"error": null,
"result": {
"amount": 0.0042,
"stakerAddress": "cosmos1tmpp633vf37d67lqnyuxw5a8lvvdaqksa0x0aq",
"unsignedTransactionData": {
"messages": [
{
"typeUrl": "/cosmos.staking.v1beta1.MsgUndelegate",
"value": {
"delegatorAddress": "cosmos1tmpp633vf37d67lqnyuxw5a8lvvdaqksa0x0aq",
"validatorAddress": "cosmosvaloper132juzk0gdmwuxvx4phug7m3ymyatxlh9734g4w",
"amount": {
"denom": "uatom",
"amount": "4000"
}
}
}
],
"fee": {
"amount": [
{
"amount": "14672",
"denom": "uatom"
}
],
"gas": "586847"
},
"memo": "",
"encodedBody": "0a9d010a252f636f736d6f732e7374616b696e672e763162657461312e4d7367556e64656c656761746512740a2d636f736d6f7331746d7070363333766633376436376c716e797578773561386c76766461716b736130783061711234636f736d6f7376616c6f7065723133326a757a6b3067646d77757876783470687567376d33796d796174786c68393733346734771a0d0a057561746f6d120434303030",
"encodedAuthInfo": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21030b155e1a5773bfae8759223f986febc4094328de05f79924363cc6887ffd9aed12040a020801180212140a0e0a057561746f6d1205313436373210dfe823",
"messageHash": "cd63647dbc65aaae6a6fd925df121ffde799eadb665784a3a465993207024ec5"
},
"createdAt": "2025-03-31T08:02:36.633Z",
"extraData": {
"currency": "atom",
"validatorAddress": "cosmosvaloper132juzk0gdmwuxvx4phug7m3ymyatxlh9734g4w",
"rewardDestinationAddress": "cosmos1k664uhuyzpwss3y45fc0zzamcr3ujpeww33ruu"
}
}
}
```
* `amount` — amount of tokens to stake in ATOM.
* `stakerAddress` — account address initiating the staking transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. The object contains the list of data fields to be used to construct the staking transaction.
* `messages` — transaction messages for each staking operation.
* `typeUrl` — Cosmos network operation type.
* `value` — message payload, encoded in the hexadecimal format.
* `delegatorAddress` — account address initiating the delegation.
* `validatorAddress` — validator address receiving the delegation.
* `amount.amount` — amount of tokens to stake.
* `amount.denom` — currency of tokens, always set to `uatom` (1 ATOM = 10⁻⁶ uATOM).
* `fee` — fee charged for processing the transaction.
* `amount` — amount of tokens.
* `denom` — currency of tokens: `atom`, `uatom`, or `matom`.
* `gas` — amount of gas spent for the transaction.
* `memo` — arbitrary text data to add to the transactions.
* `encodedBody` — processable transaction data encoded in the hexadecimal format.
* `encodedAuthInfo` — authorization data, including fee, encoded in the hexadecimal format.
* `messageHash` — hash of the transaction message.
* `createdAt` — timestamp of the transaction in ISO 8601 format.
* `extraData` — additional transaction details:
* `currency` — ATOM, Cosmos native staking token.
* `validatorAddress` — validator address to which tokens are delegated.
* `rewardDestinationAddress` — account address receiving the staking rewards.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction using the Cosmos-specific signing logic.
To broadcast the signed transaction to the Cosmos network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "cosmos",
"network": "cosmoshub-4",
"stakerAddress": "cosmos1tmpp633vf37d67lqnyuxw5a8lvvdaqksa0x0aq",
"signedTransaction": "0aa6010aa3010a252f636f736d6f732e7374616b696e672e763162657461312e4d7367556e64656c6567617465127a0a2f63656c657374696131746d7070363333766633376436376c716e797578773561386c76766461716b737639686c3864123663656c657374696176616c6f70657231616d6d30756d7871787877386a32713630783738787333327330383936303673646d767839321a0f0a047574696112073130303030303012660a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21030b155e1a5773bfae8759223f986febc4094328de05f79924363cc6887ffd9aed12040a020801180112120a0c0a047574696112043439363010f08d0c1a40b704538dadc6a1de4d7c881a1454ca75245f2651b35347062b9246543d2f7eb016bc897eeeeac37702ddaf6697d92b75cd659b4be46103a6da0cf3407dc0d73b"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — Cosmos account address initiating the staking transaction.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
Example response:
```json
{
"error": null,
"result": {
"status": "success",
"blockId": 18575267,
"fee": 0.005952,
"gas": {
"used": 202947,
"wanted": 238047
},
"transactionHash": "ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47"
}
}
```
* `status` — transaction status: `pending`, `success`, or `failed`.
* `extraData` — additional transaction details:
* `blockId` — unique identifier of the block in which the transaction has been included.
* `fee` — total fee in ATOM charged for processing the transaction.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `used` — amount of gas spent for the transaction.
* `wanted` — maximum gas limit available to consume for the transaction.
* `transactionHash` — hash of the transaction.
# Unstaking Flow
## 1. Create Unstaking Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "cosmos",
"network": "cosmoshub-4",
"stakerAddress": "cosmos1tmpp633vf37d67lqnyuxw5a8lvvdaqksa0x0aq",
"extra": {
"amount": 0.0042
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiated the staking transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to unstake in ATOM.
Example response:
```json
{
"error": null,
"result": {
"amount": 0.0042,
"stakerAddress": "cosmos1tmpp633vf37d67lqnyuxw5a8lvvdaqksa0x0aq",
"unsignedTransactionData": {
"messages": [
{
"typeUrl": "/cosmos.staking.v1beta1.MsgUndelegate",
"value": {
"delegatorAddress": "cosmos1tmpp633vf37d67lqnyuxw5a8lvvdaqksa0x0aq",
"validatorAddress": "cosmosvaloper132juzk0gdmwuxvx4phug7m3ymyatxlh9734g4w",
"amount": {
"denom": "uatom",
"amount": "4000"
}
}
}
],
"fee": {
"amount": [
{
"amount": "14672",
"denom": "uatom"
}
],
"gas": "586847"
},
"memo": "",
"encodedBody": "0a9d010a252f636f736d6f732e7374616b696e672e763162657461312e4d7367556e64656c656761746512740a2d636f736d6f7331746d7070363333766633376436376c716e797578773561386c76766461716b736130783061711234636f736d6f7376616c6f7065723133326a757a6b3067646d77757876783470687567376d33796d796174786c68393733346734771a0d0a057561746f6d120434303030",
"encodedAuthInfo": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21030b155e1a5773bfae8759223f986febc4094328de05f79924363cc6887ffd9aed12040a020801180212140a0e0a057561746f6d1205313436373210dfe823",
"messageHash": "cd63647dbc65aaae6a6fd925df121ffde799eadb665784a3a465993207024ec5"
},
"createdAt": "2025-03-27T07:16:58.337Z",
"extraData": {
"currency": "atom",
"validatorAddress": "cosmosvaloper132juzk0gdmwuxvx4phug7m3ymyatxlh9734g4w",
"rewardDestinationAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r"
}
}
}
```
* `amount` — amount of tokens to unstake in ATOM.
* `stakerAddress` — staking account address keeping the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. The object contains the list of data fields to be used to construct the unstaking transaction.
* `messages` — transaction messages for each staking operation.
* `typeUrl` — Cosmos network operation type.
* `delegatorAddress` — delegator address.
* `validatorAddress` — validator address.
* `amount` — amount of tokens to unstake.
* `denom` — currency of tokens, always set to `uatom` (1 ATOM = 10⁻⁶ uATOM).
* `fee` — fee charged for processing the transaction.
* `amount` — amount of tokens.
* `denom` — currency of tokens: `atom`, `uatom`, or `matom`.
* `gas` — amount of gas spent for the transaction.
* `memo` — arbitrary text data to add to the transactions.
* `encodedBody` — processable transaction data encoded in the hexadecimal format.
* `encodedAuthInfo` — authorization data, including fee, encoded in the hexadecimal format.
* `messageHash` — hash of the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `amount` — amount of tokens to unstake in ATOM.
* `currency` — currency of tokens: `atom`, `uatom`, or `matom`.
* `validatorAddress` — validator address from which tokens are delegated.
* `rewardDestinationAddress` — rewards destination account address.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Cosmos-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Withdrawal Ssv
*Source: [https://docs.p2p.org/docs/withdrawal-ssv.md](https://docs.p2p.org/docs/withdrawal-ssv.md)*
# Withdrawal
> 🚧 Warning
>
> Attempting to first remove the validator from the cluster will cause an inability to initiate the validator exit via SSV protocol. Please, **follow the steps as indicated in this guide**.
The withdrawal process on the Ethereum network using the DVT Staking API can be done following these steps:
1. Create a request to initiate the validator's exit.
2. Create a request to remove the validator from the cluster.
After each of these operations, you need to [sign and send](doc:signing-transaction-eth) the transaction to the Ethereum network.
Request examples are provided using [cURL](https://curl.se/).
To start the withdrawal process:
1. Create a serialized transaction initiating the validator exit by sending a GET request to [/api/v1/eth/staking/\{network}/ssv/tx/exit-validator/\{id}](ref:transaction-exit-validator).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/goerli/ssv/tx/exit-validator/3fa85f64-5717-4562-b3fc-2c963f66afa5 \
--header 'accept: application/json'
--header 'Authorization: Bearer '
```
* `id` — UUID of the SSV request.
Example response:
```curl
{
"result": {
"list": [
{
"serializeTx": "0x02f9078605010210830f424094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80b9076406e8fb9c00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb2700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000520971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.000000000001",
"data": "0x06e8fb9c00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb2700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000520971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200",
"value": "0.0",
"chainId": "5",
"type": "2",
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
}
]
},
"error": {}
}
```
* `list` includes a list of data fields that contain the following data:
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
2. Use `serializeTx` to [sign and send](https://docs.p2p.org/docs/signing-transaction-eth) the signed transaction to the Ethereum network.
3. Create the serialized transaction initiating the process of removing validator from the cluster by sending a GET request to [/api/v1/eth/staking/\{network}/ssv/tx/remove-validator/\{id}](ref:transaction-remove-validator).
> ❗️ Important
>
> Send a request only after the validator has completed its exit on the Ethereum Beacon chain. If called before, the validator would stop performing its duties and will be getting penalties for that.
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/goerli/ssv/tx/remove-validator/3fa85f64-5717-4562-b3fc-2c963f66afa5 \
--header 'accept: application/json'
--header 'Authorization: Bearer '
```
* `id` — UUID of the SSV request.
Example response is the same as for step 2.
4. Use `serializeTx` to [sign and send](https://docs.p2p.org/docs/signing-transaction-eth) the signed transaction to the Ethereum network.
## What's Next?
* [Getting Started](doc:getting-started-ssv).
* [DVT Staking API](ref:introduction-dvt) reference.
---
## Create Celestia Unstake Transaction
*Source: [https://docs.p2p.org/reference/create-celestia-unstake-transaction.md](https://docs.p2p.org/reference/create-celestia-unstake-transaction.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/celestia/{network}/staking/unstake": {
"post": {
"operationId": "create-celestia-unstake-transaction",
"summary": "Create Unstake Request",
"description": "Create unstake request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "celestia-mainnet-beta",
"description": "
"
},
"amount": {
"type": "string",
"description": "Amount of tokens."
}
},
"required": [
"denom",
"amount"
],
"x-readme-ref-name": "Amount"
}
},
"gas": {
"type": "string",
"description": "Amount of gas spent for the transaction."
}
},
"required": [
"amount",
"gas"
],
"x-readme-ref-name": "TransactionFee"
}
]
},
"memo": {
"type": "string",
"description": "Arbitrary text data to add to the transactions."
},
"encodedBody": {
"type": "string",
"description": "Processable transaction data encoded in the hexadecimal format."
},
"encodedAuthInfo": {
"type": "string",
"description": "Authorization data, including fee, encoded in the hexadecimal format."
}
},
"required": [
"messages",
"fee",
"encodedBody",
"encodedAuthInfo"
],
"x-readme-ref-name": "TransactionData"
}
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the transaction in the ISO 8601 format."
},
"amount": {
"type": "number",
"format": "decimal",
"description": "Amount of tokens."
},
"currency": {
"type": "string",
"enum": [
"tia",
"utia",
"mtia"
],
"description": "Currency of the tokens:
`tia` — Celestia native staking token.
`utia` — 1 TIA = 10^-6 UTIA.
`mtia` — 1 TIA = 10^-3 MTIA.
"
},
"validatorAddress": {
"type": "string",
"description": "Validator address to which tokens are delegated.",
"example": "celestiavaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^celestiavaloper[a-zA-Z0-9]{39}$"
},
"rewardDestinationAddress": {
"type": "string",
"description": "Reward destination account address.",
"pattern": "^celestia[a-zA-Z0-9]{39}$"
}
},
"required": [
"stashAccountAddress",
"transactionData",
"createdAt",
"amount",
"currency",
"validatorAddress",
"rewardDestinationAddress"
],
"x-readme-ref-name": "StakeOrUnstakeTransactionStakingCelestiaResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110102
},
"message": {
"type": "string",
"default": "The request could not be performed because the amount of tokens staked in the Validator account is insufficient. Please check the balance and specify the correct request parameters."
},
"name": {
"type": "string",
"default": "InsufficientFundsOnCosmosValidatorException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientFundsOnCosmosValidatorException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InsufficientFundsOnCosmosValidatorException": {
"value": {
"error": {
"code": 110102,
"message": "The request could not be performed because the amount of tokens staked in the Validator account is insufficient. Please check the balance and specify the correct request parameters.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110104
},
"message": {
"type": "string",
"default": "The unstake request transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "CreateUnstakeTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CreateUnstakeTransactionException"
}
]
}
}
},
"examples": {
"CreateUnstakeTransactionException": {
"value": {
"error": {
"code": 110104,
"message": "The staking request transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Celestia"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Getting Started Ssv Trezor
*Source: [https://docs.p2p.org/docs/getting-started-ssv-trezor.md](https://docs.p2p.org/docs/getting-started-ssv-trezor.md)*
# Getting Started with Trezor
To start staking on the SSV network using our DVT Staking API, there are a few essential **prerequisites** to ensure a smooth and efficient setup:
* **Minimum Stake Requirement**: You will need a minimum of 32 ETH for each staking validator you wish to run.
* **SSV Tokens**: To operate validators on the SSV network, it's recommended to hold at least 15 SSV tokens per validator to cover yearly operational costs. [Get SSV test tokens here](https://faucet.ssv.network/).
* **API Key Request**: [Get an authentication token](doc:authentication) to start using DVT Staking API.
We also provide convenient request examples using [cURL](https://curl.se/) to guide you through the process.
## Stake with the P2P Smart Contract
1. Prepare`id` that is an arbitrary UUID. Generate it in one of the following ways:
* [Online UUID Generator](https://www.uuidgenerator.net/)
* [uuid npm package](https://www.npmjs.com/package/uuid)
2. Set up staking SSV nodes through P2P infrastructure by sending a POST request to [/api/v1/eth/staking/ssv/request/create](ref:ssv-request-create). Use [https://api-test-holesky.p2p.org](https://api-test-holesky.p2p.org) for testing\
or [https://api.p2p.org](https://api.p2p.org) for production.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/create \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa5",
"validatorsCount": "1",
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"ssvOwnerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"type": "without-encrypt-key",
"operationPeriodInDays": 30,
"ecdhPublicKey": null
}
'
```
* `id` — arbitrary UUID. You can later use that UUID to check the status of the set-up operation.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `withdrawalAddress` — withdrawal address for the client. This address is also used as the validator owner's address and must be used to sign the transaction to register the SSV validator at step 6.
* `feeRecipientAddress` — Eth1 address that receives the fee recipient rewards.
* `ssvOwnerAddress` — address that acts as the owner of the SSV cluster. The cluster owner can register the validator, update the fee recipient address, top-up the cluster balance, and claim SSV incentives rewards.
* `type`— type of operation:
* `without-encrypt-key` (available) — validator's private key is returned encrypted to the client.
* `with-encrypt-key` (not available) — validator private key is instead maintained by P2P to initiate withdrawals when requested by the client. If selected, fill the `ecdhPublicKey` field.
* `operationPeriodInDays`— operation period in days.
* `ecdhPublicKey`— your ECDH public key to obtain an encrypted validator private key.
Example response:
```json
{
"error": null,
"result": true
}
```
3. Check the node set-up operation status by sending a GET request to [/api/v1/eth/staking/ssv/request/status/\{id}](ref:ssv-request-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/status/3fa85f64-5717-4562-b3fc-2c963f66afa5 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `id` — UUID that was specified in the SSV set-up request.
Example response:
```json
{
"error": null,
"result": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa5",
"status": "ready",
"type": "without-encrypt-key",
"operationPeriodInDays": 30,
"liquidationPeriodInDays": 30,
"ecdhPublicKey": null,
"encryptedShares": [
{
"publicKey": "0xb4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27",
"nonce": 1,
"sharesData": "0x971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200",
"ecdhEncryptedPrivateKey": null
}
],
"validatorsCount": 1,
"withdrawalAddress": "0x9c7d4b4595402ed44167C74f9F7c7720AB5528E0",
"ssvOwnerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x9c7d4b4595402ed44167C74f9F7c7720AB5528E0",
"depositData": [
{
"pubkey": "0xb632ad4ebec8594ec8f2fbacc6df53dec180f8bae6561d70bf74c19520a35beff99cd92513058da6a22a75b9570ab31d",
"signature": "0x836e9eebeb29ed1d4b232fa38649e9902ea7d6f9d19e571c4e76cde4da2bcdbca822c8f29d21379325201735fa93925d1597f0c021a147910c165e60bf3308bc827d5fcd545f1c901e7b3102e28b8ea09d6c162c3ffd57e7398f73e5968e05db",
"depositDataRoot": "0x16678e6d91a8c3a8f1cdabc037fa32f1d296e629d1665a57f493eda1e6a6964a",
"withdrawalCredentials": "0100000000000000000000005cef11327af4104ba0f8a82fbb8628caee7cb1e3",
"amount": "32000000000",
"depositMessageRoot": "6a572503239cd1f11998af7901c0947fe36eb8efec080f22598d607d3938c1a8",
"forkVersion": "00001020",
"eth2NetworkName": "goerli",
"depositCliVersion": "2.3.0"
}
],
"validatorRegistrationTxs": [
{
"serializeTx": "0x02f9078605010210830f424094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80b9076406e8fb9c00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb2700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000520971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.000000000001",
"data": "0x06e8fb9c00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb2700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000520971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
}
],
"ssvFeeTxs": [
{
"serializeTx": "0x02f901c605800210830186a094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80b901a4bc26e7e50000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c00000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.0000000000001",
"data": "0xbc26e7e50000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c00000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
}
],
"feeRecipientTx": {
"serializeTx": "0x02f84405800210830186a094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80a4dbcdc2cc0000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.0000000000001",
"data": "0xdbcdc2cc0000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
},
"approveTx": {
"serializeTx": "0x02f86505800210830186a0943a9f01091c446bde031e39ea8354647afef091e780b844095ea7b3000000000000000000000000c3cd9a0ae89fff83b71b58b6512d43f8a41f363dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0",
"to": "0x3a9f01091C446bdE031E39ea8354647AFef091E7",
"gasLimit": "0.0000000000001",
"data": "0x095ea7b3000000000000000000000000c3cd9a0ae89fff83b71b58b6512d43f8a41f363dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
}
}
}
```
* `id` — UUID that was specified in the SSV set-up request.
* `status` — current status of the SSV request:
* `init` — request is stored.
* `processing` — request in progress, please wait.
* `ready` — request is ready.
* `cancel` — request canceled due to an error or timeout.\
When `ready`, the validator data is ready to be used in the validator registration step.
* `type`— type of operation:
* `without-encrypt-key` (available) — validator's private key is returned encrypted to the client.
* `with-encrypt-key` (not available) — validator private key is instead maintained by P2P to initiate withdrawals when requested by the client.
* `operationPeriodInDays`— operation period in days.
* `liquidationPeriodInDays`— liquidation threshold period in days.
* `ecdhPublicKey` — your ECDH public key for getting the encrypted validator private key.
* `encryptedShares`:
* `publicKey` — validator public key.
* `nonce` — validator key owner's nonce used for signature in `sharesData`.
* `sharesData` — the shares (i.e. validator key into a predefined threshold of shares) and the signature, used to prove the validator owner address. Used in the `registerValidator` Ethereum transaction from the SSV smart contract to create a validator.
* `ecdhEncryptedPrivateKey` — encrypted validator private key.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `withdrawalAddress` — withdrawal address of the cluster owner.
* `ssvOwnerAddress` — address that acts as the owner of the SSV cluster. The cluster owner can register the validator, update the fee recipient address, top-up the cluster balance, and claim SSV incentives rewards.
* `feeRecipientAddress` — Eth1 address that receives the fee recipient rewards.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `depositDataRoot` — SHA-256 hash of the SSZ-encoded DepositData object. They are used as a protection against malformed input.
* `withdrawalCredentials`— withdrawal address credentials, passed in the expected format by the Ethereum deposit smart contract.
* `amount` — amount of ETH, denominated in gwei, that is being deposited.
* `depositMessageRoot` — cryptographic hash of the Merkle tree’s root, ensuring the integrity and authenticity of the deposit data.
* `forkVersion` — version of the network fork that the deposit is intended for. It helps in aligning the deposit with a specific version of the protocol.
* `eth2NetworkName` — name of the Ethereum 2.0 network where the deposit is made.
* `depositCliVersion` — version of the deposit command-line interface (CLI) tool that was used to generate the deposit data.
* `validatorRegistrationTxs` — transaction data presented in both a serialized and unserialized way to register the validator on the SSV network.
* `ssvFeeTxs` — transaction data presented in both a serialized and unserialized way to deposit SSV fees into the cluster balance.
* `feeRecipientTx` — transaction data presented in both a serialized and unserialized way to set the fee recipient address.
* `approveTx` — transaction data presented in both a serialized and unserialized way to approve the transfer of SSV tokens from the SSV.network smart contract on behalf of the users.
`validatorRegistrationTxs`, `ssvFeeTxs`, `feeRecipientTx`, and `approveTx` includes a list of data fields that contain the following data:
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per gas unit in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
4. Sign the transaction `approveTx` with trezorctl by using the unserialized transaction data in the `approveTx` object.
You will find the unserialized transaction data within the `approveTx` JSON object. Here is an example of the data structure you'll work with:
```Text JSON
"approveTx": {
"serializeTx": "",
"to": "0x3a9f01091C446bdE031E39ea8354647AFef091E7",
"gasLimit": "",
"data": "",
"value": "",
"chainId": "",
"type": 2,
"maxFeePerGas": "",
"maxPriorityFeePerGas": ""
}
```
Use the retrieved data to fill in the respective fields in the command line instruction for signing the transaction with trezorctl. Replace the placeholders with actual values from the `approveTx` object:
```powershell
trezorctl ethereum sign-tx --address {SENDER_ADDRESS_BIP_32} --data {TX_DATA} --chain-id {CHAIN_ID} --max-gas-fee {MAX_FEE_PER_GAS} --max-priority-fee {MAX_PRIORITY_FEE_PER_GAS} --gas-limit {GAS_LIMIT} --eip2718-type {TYPE} {TO_ADDRESS} {VALUE}
```
* `{SENDER_ADDRESS_BIP_32}`: This is your Ethereum wallet address in BIP 32 format
* `{TX_DATA}`: Use the value from `data` in the `approveTx` object
* `{CHAIN_ID}`: Use the value from `chainId` in the `approveTx` object
* `{MAX_FEE_PER_GAS}` and `{MAX_PRIORITY_FEE_PER_GAS}`: These fields correspond to `maxFeePerGas` and `maxPriorityFeePerGas` in the `approveTx` object, respectively. These values must be passed in the Wei unit of measure.
* `{GAS_LIMIT}`: Use the value from `gasLimit` in the `approveTx` object. This value must be passed in the Wei unit of measure.
* `{TYPE}`: Use the value from `type` in the `approveTx` object
* `{TO_ADDRESS}`: Use the value from `to` in the `approveTx` object
* `{VALUE}`: Use the value from `value` in the `approveTx` object
5. After replacing the placeholders with actual data from the `approveTx` object, run the command in your terminal or command prompt. This will initiate the signing process with your Trezor device.
6. After signing is completed with your Trezor device, the command line will return the signed transaction hash.
[Send](doc:broadcast-transaction-eth-trezor) the signed transaction to the Ethereum network.
**This step is required only once per account.** It enables the SSV smart contract to transfer SSV tokens on your behalf to fund the cluster balance.
7. Sign the transaction `feeRecipientTx` with trezorctl by using the unserialized transaction data in the `feeRecipientTx` object.
You will find the unserialized transaction data within the `feeRecipientTx` JSON object. Here is an example of the data structure you'll work with:
```Text JSON
"feeRecipientTx": {
"serializeTx": "",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "",
"data": "",
"value": "",
"chainId": "",
"type": 2,
"maxFeePerGas": "",
"maxPriorityFeePerGas": ""
}
```
Use the retrieved data to fill in the respective fields in the command line instruction for signing the transaction with trezorctl. Replace the placeholders with actual values from the `feeRecipientTx` object:
```powershell
trezorctl ethereum sign-tx --address {SENDER_ADDRESS_BIP_32} --data {TX_DATA} --chain-id {CHAIN_ID} --max-gas-fee {MAX_FEE_PER_GAS} --max-priority-fee {MAX_PRIORITY_FEE_PER_GAS} --gas-limit {GAS_LIMIT} --eip2718-type {TYPE} {TO_ADDRESS} {VALUE}
```
* `{SENDER_ADDRESS_BIP_32}`: This is your Ethereum wallet address in BIP 32 format
* `{TX_DATA}`: Use the value from `data` in the `feeRecipientTx` object
* `{CHAIN_ID}`: Use the value from `chainId` in the `feeRecipientTx` object
* `{MAX_FEE_PER_GAS}` and `{MAX_PRIORITY_FEE_PER_GAS}`: These fields correspond to `maxFeePerGas` and `maxPriorityFeePerGas` in the `feeRecipientTx` object, respectively. These values must be passed in the Wei unit of measure.
* `{GAS_LIMIT}`: Use the value from `gasLimit` in the `feeRecipientTx` object. This value must be passed in the Wei unit of measure.
* `{TYPE}`: Use the value from `type` in the `feeRecipientTx` object
* `{TO_ADDRESS}`: Use the value from `to` in the `feeRecipientTx` object
* `{VALUE}`: Use the value from `value` in the `feeRecipientTx` object
8. After replacing the placeholders with actual data from the `feeRecipientTx` object, run the command in your terminal or command prompt. This will initiate the signing process with your Trezor device.
9. After signing is completed with your Trezor device, the command line will return the signed transaction hash.
[Send](doc:broadcast-transaction-eth-trezor) the signed transaction to the Ethereum network.
**This step is required only once per account.** It enables the SSV smart contract to transfer SSV tokens on your behalf to fund the cluster balance.
10. Sign the transaction `validatorRegistrationTxs` with trezorctl by using the unserialized transaction data in the `validatorRegistrationTxs` object.
You will find the unserialized transaction data within the `feeRecipientTx` JSON object. Here is an example of the data structure you'll work with:
```Text JSON
"validatorRegistrationTxs": {
"serializeTx": "",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "",
"data": "",
"value": "",
"chainId": "",
"type": 2,
"maxFeePerGas": "",
"maxPriorityFeePerGas": ""
}
```
Use the retrieved data to fill in the respective fields in the command line instruction for signing the transaction with trezorctl. Replace the placeholders with actual values from the `validatorRegistrationTxs` object:
```powershell
trezorctl ethereum sign-tx --address {SENDER_ADDRESS_BIP_32} --data {TX_DATA} --chain-id {CHAIN_ID} --max-gas-fee {MAX_FEE_PER_GAS} --max-priority-fee {MAX_PRIORITY_FEE_PER_GAS} --gas-limit {GAS_LIMIT} --eip2718-type {TYPE} {TO_ADDRESS} {VALUE}
```
* `{SENDER_ADDRESS_BIP_32}`: This is your Ethereum wallet address in BIP 32 format
* `{TX_DATA}`: Use the value from `data` in the `validatorRegistrationTxs` object
* `{CHAIN_ID}`: Use the value from `chainId` in the `validatorRegistrationTxs` object
* `{MAX_FEE_PER_GAS}` and `{MAX_PRIORITY_FEE_PER_GAS}`: These fields correspond to `maxFeePerGas` and `maxPriorityFeePerGas` in the `validatorRegistrationTxs` object, respectively. These values must be passed in the Wei unit of measure.
* `{GAS_LIMIT}`: Use the value from `gasLimit` in the `validatorRegistrationTxs` object. This value must be passed in the Wei unit of measure.
* `{TYPE}`: Use the value from `type` in the `validatorRegistrationTxs` object
* `{TO_ADDRESS}`: Use the value from `to` in the `validatorRegistrationTxs` object
* `{VALUE}`: Use the value from `value` in the `validatorRegistrationTxs` object
11. After replacing the placeholders with actual data from the `validatorRegistrationTxs` object, run the command in your terminal or command prompt. This will initiate the signing process with your Trezor device.
12. After signing is completed with your Trezor device, the command line will return the signed transaction hash.
[Send](doc:broadcast-transaction-eth-trezor) the signed transaction to the Ethereum network.
By broadcasting this transaction, your validator will be registered on the SSV network and simultaneously managed by a pool (i. e., cluster) of four top-performance node operators: Allnodes, Huobi, P2P.org, and Stakeley. Check an [example on Goerli](https://goerli.etherscan.io/tx/0xc492e5ec2c6b230e5e88cc68e4b0d0f923b0871c4b0d2c8fa1dc18899dff6c84) of a successfully broadcasted transaction using the `validatorRegistrationTxs` data.
13. Create a serialized transaction for depositing the stake amount and send it as a POST request to [/api/v1/eth/staking/direct/tx/deposit](ref:eth-staking-deposit).
Example request:
```Text c
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/deposit \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"depositData": [
{
"pubkey": "0xac1e9969d7b87f3102549ab41558136674a7306b85b9f73cfbd7d9fdb7db85724569da3ebd4d7de9689f6ac058d7e2a3",
"signature": "0xb656f9c771166c82a7891b930e6a920878d9736eb3f9f241753a15ea69d8e2f20a3740dfaf546c70e31bd323e14b341205d04e3227dd4cf2923644a375f6792875ac02c5f256f7a17c96b09bafcbce7e4443e1862356b1e90d78875d78e9a742",
"depositDataRoot": "0xba013b4950b9aff0c3c19017ec5b6e0ed5b957b36f6ff03a545e5cc5605baff8"
}
]
}
'
```
* `withdrawalAddress` — withdrawal address for the validators.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `depositDataRoot` — SHA-256 hash of the SSZ-encoded DepositData object. Used as a protection against malformed input.
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f902cf0580021e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060a307b2e1661bcc38d482a69603713baf332ad36adf837392e9f20a96b77a03ca415a46261fc62b8f5d4aa69a0d70e2cf0d23e3396bd387cfde18d392a2c7ba822d3f8a60d075366625dcb3c88cd59ebc8f7ab1fc312c6b8b625a57bf7e1b6e6f000000000000000000000000000000000000000000000000000000000000000178ae581ccc8bdf1fde00cff35b2278e1c10a9ed2fc18632373dac118a03cfacdc0",
"to": "0x681a1b3441c6BFb12f91651EFD9F02c83c070293",
"gasLimit": "0.0000000000001",
"data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060a307b2e1661bcc38d482a69603713baf332ad36adf837392e9f20a96b77a03ca415a46261fc62b8f5d4aa69a0d70e2cf0d23e3396bd387cfde18d392a2c7ba822d3f8a60d075366625dcb3c88cd59ebc8f7ab1fc312c6b8b625a57bf7e1b6e6f000000000000000000000000000000000000000000000000000000000000000178ae581ccc8bdf1fde00cff35b2278e1c10a9ed2fc18632373dac118a03cfacd",
"value": "32.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.00000000000000003",
"maxPriorityFeePerGas": "2"
}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
14. Sign the transaction `result` with trezorctl by using the unserialized transaction data in the `result` object.\
Use the retrieved data to fill in the respective fields in the command line instruction for signing the transaction with trezorctl. Replace the placeholders with actual values from the `validatorRegistrationTxs` object:
```powershell
trezorctl ethereum sign-tx --address {SENDER_ADDRESS_BIP_32} --data {TX_DATA} --chain-id {CHAIN_ID} --max-gas-fee {MAX_FEE_PER_GAS} --max-priority-fee {MAX_PRIORITY_FEE_PER_GAS} --gas-limit {GAS_LIMIT} --eip2718-type {TYPE} {TO_ADDRESS} {VALUE}
```
* `{SENDER_ADDRESS_BIP_32}`: This is your Ethereum wallet address in BIP 32 format
* `{TX_DATA}`: Use the value from `data` in the `result` object
* `{CHAIN_ID}`: Use the value from `chainId` in the `result` object
* `{MAX_FEE_PER_GAS}` and `{MAX_PRIORITY_FEE_PER_GAS}`: These fields correspond to `maxFeePerGas` and `maxPriorityFeePerGas` in the `result` object, respectively. These values must be passed in the Wei unit of measure.
* `{GAS_LIMIT}`: Use the value from `gasLimit` in the `result` object. This value must be passed in the Wei unit of measure.
* `{TYPE}`: Use the value from `type` in the `result` object
* `{TO_ADDRESS}`: Use the value from `to` in the `result` object
* `{VALUE}`: Use the value from `value` in the `result` object
15. After replacing the placeholders with actual data from the `result` object, run the command in your terminal or command prompt. This will initiate the signing process with your Trezor device.
16. After signing is completed with your Trezor device, the command line will return the signed transaction hash.\
[Send](doc:broadcast-transaction-eth-trezor) the signed transaction to the Ethereum network.\
By broadcasting this transaction, you are depositing the required stake amount in the Ethereum deposit smart contract by using the P2P smart contract as a proxy.
17. After your deposit is successful, your validator will enter the activation queue and soon start performing the validator tasks. You can check the status of your validator on the [SSV network explorer](https://goerli.explorer.ssv.network/validators).
## What's Next?
* [DVT Staking API](ref:ssv-request-create) reference.
---
## Eth Eigen Complete Queued Withdrawals
*Source: [https://docs.p2p.org/reference/eth-eigen-complete-queued-withdrawals.md](https://docs.p2p.org/reference/eth-eigen-complete-queued-withdrawals.md)*
# Complete Queued Withdrawals
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/eigenlayer/tx/complete-queued-withdrawals": {
"post": {
"operationId": "eth-eigen-complete-queued-withdrawals",
"summary": "Complete Queued Withdrawals",
"description": "Construct a serialized transaction to complete queued withdrawals.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"eigenPodOwnerAddress": {
"type": "string",
"description": "Owner of the EigenPod address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"queueWithdrawalsTx": {
"type": "string",
"description": "Hash of the queue withdrawal transaction."
}
},
"required": [
"eigenPodOwnerAddress",
"queueWithdrawalsTx"
],
"x-readme-ref-name": "CompleteQueuedWithdrawalsRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103104
},
"message": {
"type": "string",
"default": "The Web3 transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "Web3CreateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "Web3CreateTransactionException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"Web3CreateTransactionException": {
"value": {
"error": {
"code": 103104,
"message": "The Web3 transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"EigenLayer"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Solana Staking Stake
*Source: [https://docs.p2p.org/reference/solana-staking-stake.md](https://docs.p2p.org/reference/solana-staking-stake.md)*
# Create Staking Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/solana/{network}/staking/stake": {
"post": {
"operationId": "solana-staking-stake",
"summary": "Create Staking Request",
"description": "Create staking request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
Solana network:
`mainnet-beta` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet-beta",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"feePayer": {
"type": "string",
"description": "Account address that will pay the fee for the transaction.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"fromPublicKey": {
"type": "string",
"description": "Account address from which the staking account will be created.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"nonceAccount": {
"type": "string",
"description": "Account address that keeps the value of the nonce.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"computeUnitLimit": {
"type": "number",
"description": "Maximum computational effort limit for the transaction measured in compute units.",
"minimum": 1,
"example": 300
},
"computeUnitPrice": {
"type": "number",
"description": "Price of a compute unit for the transaction in micro-lamports (1 microLamport = 10⁻⁶ lamports).",
"minimum": 1,
"example": 20000
},
"stakeAuthority": {
"type": "string",
"description": "Account address that can perform staking operations with staking account. If not specified, rights will be taken from the `fromPublicKey` parameter.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"withdrawAuthority": {
"type": "string",
"description": "Account address that can perform withdrawal operation with staking account. If not specified, rights will be taken from the `fromPublicKey` parameter.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"amount": {
"type": "number",
"description": "Amount of tokens to stake in lamports (1 SOl = 10^9 lamports). Min amount is `1002282880`.",
"minimum": 1,
"example": 1
}
},
"required": [
"feePayer",
"fromPublicKey",
"amount"
],
"x-readme-ref-name": "StakeRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"feePayer": {
"type": "string",
"description": "Account address that will pay the fee for the transaction.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"fromPublicKey": {
"type": "string",
"description": "Account address from which the staking account will be created.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"stakeAccount": {
"type": "string",
"description": "Account address that stores tokens for staking.",
"example": "6ZuLUCwVTvuQJrN1HrpoHJheQUw9Zk8CtiD3CEpHiA9E"
},
"stakeAuthority": {
"type": "string",
"description": "Account address that can perform staking operations with staking account.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"withdrawAuthority": {
"type": "string",
"description": "Account address that can perform withdrawal operation with staking account.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"amount": {
"type": "number",
"description": "Amount of tokens to stake in lamports (1 SOl = 10^9 lamports). Min amount is `1002282880`.",
"minimum": 1,
"example": 1
},
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcJjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+jagnMHpK8BDHt0PpssHwXGD2fBxS6MWBoxptD2u9TvrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NjSeWM5+GSJdoQd43Al9SVVXC9FfWGwbe7icpomwAUGodgXkTdUKpg0N73+KnqyVX9TXIp4citopJ3AAAAAAAah2BelAgULaAeR5s5tuI4eW3FQ9h/GeQpOtNEAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAan1RcZNYTQ/u2bs0MdEyBr5UQoG1e4VmzFN1/0AAAAijW940iwWddz25ZC37fI0ue5fa+eTbC2ynBM3b0t4pcDAgMAAQBgAwAAAI5ELeF3F+N1ZPBWe0G1FV0heaKPY7e8dg5tBPbrf8voBAAAAAAAAABzZWVkgJaYAAAAAADIAAAAAAAAAAah2BeRN1QqmDQ3vf4qerJVf1NcinhyK2ikncAAAAAABAIBB3QAAAAAjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+iORC3hdxfjdWTwVntBtRVdIXmij2O3vHYObQT263/L6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGAQMGCAUABAIAAAA="
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"feePayer",
"fromPublicKey",
"stakeAccount",
"stakeAuthority",
"withdrawAuthority",
"amount",
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "StakeResult"
}
]
}
}
}
}
}
}
},
"tags": [
"Solana"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Solana Staking Withdraw
*Source: [https://docs.p2p.org/reference/solana-staking-withdraw.md](https://docs.p2p.org/reference/solana-staking-withdraw.md)*
# Create Withdrawal Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/solana/{network}/staking/withdraw": {
"post": {
"operationId": "solana-staking-withdraw",
"summary": "Create Withdrawal Request",
"description": "Create withdrawal request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
Solana network:
`mainnet-beta` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet-beta",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"feePayer": {
"type": "string",
"description": "Account address that will pay the fee for the transaction.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"stakeAccount": {
"type": "string",
"description": "Account address that stores tokens for staking.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"withdrawAuthority": {
"type": "string",
"description": "Account address that can perform withdrawal operations with staking account.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"recipient": {
"type": "string",
"description": "Account address to which tokens will be sent.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"amount": {
"type": "number",
"description": "Amount of tokens to withdraw in lamports (1 SOl = 10^9 lamports).",
"minimum": 1,
"example": 1
},
"nonceAccount": {
"type": "string",
"description": "Account address that keeps the value of the nonce.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"computeUnitLimit": {
"type": "number",
"description": "Maximum computational effort limit for the transaction measured in compute units.",
"minimum": 1,
"example": 300
},
"computeUnitPrice": {
"type": "number",
"description": "Price of a compute unit for the transaction in micro-lamports (1 microLamport = 10⁻⁶ lamports).",
"minimum": 1,
"example": 20000
}
},
"required": [
"feePayer",
"amount"
],
"x-readme-ref-name": "WithdrawRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"feePayer": {
"type": "string",
"description": "Account address that will pay the fee for the transaction.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"stakeAccount": {
"type": "string",
"description": "Account address that stores tokens for staking.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"withdrawAuthority": {
"type": "string",
"description": "Account address that can perform withdrawal operation with staking account.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"recipient": {
"type": "string",
"description": "Account address to which tokens will be sent.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"amount": {
"type": "number",
"description": "Amount of tokens to withdraw in lamports (1 SOl = 10^9 lamports).",
"minimum": 1,
"example": 1
},
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcJjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+jagnMHpK8BDHt0PpssHwXGD2fBxS6MWBoxptD2u9TvrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NjSeWM5+GSJdoQd43Al9SVVXC9FfWGwbe7icpomwAUGodgXkTdUKpg0N73+KnqyVX9TXIp4citopJ3AAAAAAAah2BelAgULaAeR5s5tuI4eW3FQ9h/GeQpOtNEAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAan1RcZNYTQ/u2bs0MdEyBr5UQoG1e4VmzFN1/0AAAAijW940iwWddz25ZC37fI0ue5fa+eTbC2ynBM3b0t4pcDAgMAAQBgAwAAAI5ELeF3F+N1ZPBWe0G1FV0heaKPY7e8dg5tBPbrf8voBAAAAAAAAABzZWVkgJaYAAAAAADIAAAAAAAAAAah2BeRN1QqmDQ3vf4qerJVf1NcinhyK2ikncAAAAAABAIBB3QAAAAAjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+iORC3hdxfjdWTwVntBtRVdIXmij2O3vHYObQT263/L6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGAQMGCAUABAIAAAA="
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"feePayer",
"amount",
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "WithdrawResult"
}
]
}
}
}
}
}
}
},
"tags": [
"Solana"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Create Sei Redelegate To Transaction
*Source: [https://docs.p2p.org/reference/create-sei-redelegate-to-transaction.md](https://docs.p2p.org/reference/create-sei-redelegate-to-transaction.md)*
# Create Redelegate To Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/sei/{network}/staking/redelegate/to": {
"post": {
"operationId": "create-sei-redelegate-to-transaction",
"summary": "Create Redelegate To Request",
"description": "Create a redelegate to the default validator request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "pacific-1",
"description": "
"
},
"amount": {
"type": "string",
"description": "Amount of tokens."
}
},
"required": [
"denom",
"amount"
],
"x-readme-ref-name": "Amount"
}
},
"gas": {
"type": "string",
"description": "Amount of gas spent for the transaction."
}
},
"required": [
"amount",
"gas"
],
"x-readme-ref-name": "TransactionFee"
}
]
},
"memo": {
"type": "string",
"description": "Arbitrary text data to add to the transactions."
},
"encodedBody": {
"type": "string",
"description": "Processable transaction data encoded in the hexadecimal format."
},
"encodedAuthInfo": {
"type": "string",
"description": "Authorization data, including fee, encoded in the hexadecimal format."
}
},
"required": [
"messages",
"fee",
"encodedBody",
"encodedAuthInfo"
],
"x-readme-ref-name": "TransactionData"
}
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the transaction in the ISO 8601 format."
},
"amount": {
"type": "number",
"format": "decimal",
"description": "Amount of tokens to stake."
},
"currency": {
"type": "string",
"enum": [
"sei",
"usei",
"msei"
],
"description": "Currency of the tokens:
`sei` — Sei native staking token.
`usei` — 1 SEI = 10⁻⁶ uSEI.
`msei` — 1 SEI = 10⁻³ mSEI.
"
},
"sourceValidatorAddress": {
"type": "string",
"description": "Redelegate source validator address.",
"example": "seivaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^seivaloper[a-zA-Z0-9]{39}$"
},
"destinationValidatorAddress": {
"type": "string",
"description": "Redelegate destination validator address.",
"example": "seivaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^seivaloper[a-zA-Z0-9]{39}$"
}
},
"required": [
"stashAccountAddress",
"transactionData",
"createdAt",
"amount",
"currency",
"sourceValidatorAddress",
"destinationValidatorAddress"
],
"x-readme-ref-name": "RedelegateTransactionStakingSeiResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110113
},
"message": {
"type": "string",
"default": "The request could not be performed because the simulation transaction failed."
},
"name": {
"type": "string",
"default": "SimulationTransactionOnCosmosException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SimulationTransactionOnCosmosException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110114
},
"message": {
"type": "string",
"default": "The request could not be performed because the redelegation to this validator is already in progress. Please try again after the redelegation process will be completed."
},
"name": {
"type": "string",
"default": "RedelegationTransactionInProcessException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "RedelegationTransactionInProcessException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"SimulationTransactionOnCosmosException": {
"value": {
"error": {
"code": 110113,
"message": "The request could not be performed because the simulation transaction failed. undefined",
"type": "client"
},
"result": null
}
},
"RedelegationTransactionInProcessException": {
"value": {
"error": {
"code": 110114,
"message": "The request could not be performed because the redelegation to this validator is already in progress. Please try again after the redelegation process will be completed.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110105
},
"message": {
"type": "string",
"default": "The redelegate request transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "CreateRedelegateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CreateRedelegateTransactionException"
}
]
}
}
},
"examples": {
"CreateRedelegateTransactionException": {
"value": {
"error": {
"code": 110105,
"message": "The redelegate request transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Sei"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Faq
*Source: [https://docs.p2p.org/docs/faq.md](https://docs.p2p.org/docs/faq.md)*
# FAQ
The main staking details from the P2P Validator can be found [here](https://p2p.org/faq/en).
## What is Staking
Cryptocurrency staking is the process of holding coins/tokens (stake) to earn rights to participate in the validation of transaction blocks, and in doing so, Validators are rewarded.
## What is DVT Staking API
DVT Staking API is an innovative product designed specifically for institutions and intermediaries, enabling them to leverage the advantages of Distributed Validator Technology (DVT). Our API simplifies the process of integrating with the SSV protocol, automating the staking process for enhanced efficiency and ease.
## What is DVT
Distributed Validator Technology (DVT), in the majority of PoS (proof-of-stake) systems, assigns each validator a single staking node. However, Distributed Validator Technology allows for the splitting of responsibilities and risks associated with a single validator node across multiple participants. The primary goals of DVT are to increase the security, decentralization, and resilience of the network by ensuring that no single point of failure exists.
## What are the advantages of using DVT
**Enhanced Security and Fault Tolerance:** DVT's distributed nature means that your staking operations are not dependent on a single node operator. This significantly reduces the risk of system failures, security breaches, and the impact of potential attacks, as responsibilities and tasks are shared across multiple providers.
**Diversification and Reduced Risk:** By spreading your staking across various operators and geographical locations, DVT minimizes the risks associated with relying on a single validator or location. This diversification ensures more stable and reliable staking outcomes.
**Cost Efficiency:** DVT allows for more efficient management of staking operations. By distributing tasks across various nodes, operational costs can be optimized, translating into better cost-efficiency for the clients.
**High Performance and Reliability:** With nodes distributed globally and managed by top-performing operators, DVT systems typically exhibit higher uptime and performance consistency, contributing to potentially greater staking rewards.
## What are the risks of using DVT
**Technology Risks:** As with any technology reliant on software and online connectivity, there is always the risk of software bugs, vulnerabilities, or unforeseen technical issues that could affect the system's stability.
**Market Risks:** A key consideration is the volatility of the SSV token price. Since users top-up the cluster balance with SSV tokens, a price decrease can lead to operators increasing their fee in SSV tokens to maintain their margins. This necessitates users to pay more and constantly monitor their balance to avoid liquidation risks.
## What is SSV
Secret Shared Validator (SSV) is a technology that allows for the secure and decentralized operation of validator nodes in proof-of-stake (PoS) blockchain networks.
## What is EigenLayer
EigenLayer is a protocol built on top of Ethereum designed to enhance the economic utility of staked ETH by allowing users to leverage their existing Ethereum stakes to secure additional protocols and applications without requiring additional collateral.
## What is AVS
Actively Validated Services (AVS) refer to any system that necessitates its own distributed validation semantics for verification. This includes sidechains, data availability layers, new virtual machines, keeper networks, oracle networks, bridges, threshold cryptography schemes, and trusted execution environments. AVS is integrated into EigenLayer, essentially serving as node operators.
---
## Withrawal Babylon
*Source: [https://docs.p2p.org/docs/withrawal-babylon.md](https://docs.p2p.org/docs/withrawal-babylon.md)*
# Withrawal
Since the Bitcoin staking flow is currently limited to only locking bitcoins according to the [Babylon launching phases](https://babylonlabs.io/blog/babylon-bitcoin-staking-mainnet-launch-phase-1), for the moment there are two ways to initiate the withdrawal process using the Staking API:
* Wait until the time lock expires and withdraw the staked assets.
* Unbond the stake before time-lock expiration and withdraw it.
In the [first flow](doc:withrawal-babylon#withdrawal-after-time-lock-expiration), it is considered that a stake will automatically expire after the time-lock period, so that it will be enough to submit the withdrawal transaction to the Bitcoin ledger to withdraw bitcoins.
[Unbonding the stake before its expiration](doc:withrawal-babylon#early-unbonding-and-withdrawal) involves more steps. First, an additional unstaking request is required to be followed then by a call to a separate API method to broadcast the partially signed unbonding transaction. Only after that, a withdrawal request can be created.
> ❗️ Please note
>
> **In the case of early withdrawal, a fee for unlocking the staked bitcoins is charged**. The exact amount to be paid depends on the current chain load.
Request examples are provided using [cURL](https://curl.se/).
# Withdrawal after time-lock expiration
1. Wait until the time lock period set in the `stakingDuration` parameter expires so that the stake becomes available for withdrawal.
2. To withdraw an expired stake, generate a withdrawal transaction by sending a POST request to [/api/v1/babylon-btc/\{network}/staking/withdrawal](ref:babylon-withdrawal).
Example request (for `sigNet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/babylon-btc/signet/transaction/withdrawal \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHash": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028",
"withdrawalAddress": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9"
}'
```
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
* `withdrawalAddress` — staker withdrawal address.
Example response:
```json
{
"error": null,
"result": {
"withdrawalAddress": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9",
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHash": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028",
"withdrawalTransactionHex": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000",
"fee": 1000
}
}
```
* `withdrawalAddress` — staker withdrawal address.
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
* `withdrawalTransactionHex` — unsigned transaction for withdrawal request in the hexadecimal format. Sign the transaction and submit it to the Bitcoin blockchain to perform the called action.
* `fee` — total fee in SATOSHI charged for processing the transaction.
3. Use `unstakeTransactionHex` from the previous step to [sign and send](doc:signing-transaction-eth) the signed transaction to the Bitcoin chain.
# Early unbonding and withdrawal
The unbonding process for early withdrawal in the Bitcoin network using the Staking API can be done in a few steps:
1. Create an unstaking transaction.
2. Broadcast partially signed transaction to unbond the stake.
3. Create a withdrawal transaction.
## 1. Create Unstaking Transaction
1. Set up the unstake request by sending a POST request to [/api/v1/babylon-btc/\{network}/staking/unstake](ref:babylon-unstake).
Example request (for `sigNet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/babylon-btc/signet/staking/unstake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHash": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028"
}'
```
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
Example response:
```json
{
"error": null,
"result": {
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHash": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028",
"unstakeTransactionHex": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000",
"unstakeFee": 1000
}
}
```
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
* `unstakeTransactionHex` — unsigned transaction for the unstake request in the hexadecimal format. Sign the transaction to consequently send it to the Bitcoin blockchain.
* `unstakeFee` — total fee in SATOSHI charged for unlocking the staked assets and processing the transaction.
2. Use `unstakeTransactionHex` from the previous step to [sign](doc:signing-transaction-eth) the transaction. Note that this transaction will only be partially signed, since it must be signed by validators too.
## 2. Broadcast Unstaking Transaction
To broadcast the partially signed unstaking transaction to the Bitcoin network and unbond your stake before its expiration, send a POST request to [/api/v1/babylon-btc/\{network}/transaction/unbonding](ref:babylon-transaction-unbonding).
Example request (for `sigNet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/babylon-btc/signet/transaction/unbonding \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stakingTxHash": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028",
"unbondingTxHex": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000"
}'
```
* `stakingTxHash` — hash of the initial staking transaction.
* `unbondingTxHex` — unsigned transaction for the unbonding request in the hexadecimal format.
Example response:
```json
{
"error": null,
"result": {
"stakingTxHash": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"unbondingTxHex": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000",
"unbondingTxHash": "02000000000101e64994aad9ebe5f9bbe8344a743aa6dbbc9d5ecab0cc135b2697bbeef7834bfd0000000000ffffffff017869000000000000225120abc575829d73ef108ceba4f1686f657e6e2f70852208eabaa0cd74e248f203a7034031226d5e6be2988bc81b4ede2e507e8795992e2f8dbf73c3c7887ca611ef74d46e4ddcf41734478e088a2c9f110be6bb29f4d8fc9a6c0aca6b2ba648bdb850208a20be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4ad2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ac2049766ccd9e3cd94343e2040474a77fb37cdfd30530d05f9f1e96ae1e2102c86eba2076d1ae01f8fb6bf30108731c884cddcf57ef6eef2d9d9559e130894e0e40c62cba529c61c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac073c168cce70e3d66240fcd3ef216f083436f448372fe7cccb668449cbcb15b26639fa5fb4094c2f7ea65e9c176ccd983b1cda874de942d6fb8cd3b4f2e2aa14b00000000",
"stakerSignature": "304402203f7c0f6c1f7a8f7"
}
}
```
* `stakingTxHash` — hash of the initial staking transaction.
* `unbondingTxHex` — unsigned transaction for the unbonding request in the hexadecimal format.
* `unbondingTxHash` — hash of the partially signed unbonding transaction.
* `stakerSignature` — staker signature of the unbonding transaction.
## 3. Create Withdrawal Transaction
1. Generate a withdrawal transaction by sending a POST request to [/api/v1/babylon-btc/\{network}/staking/withdrawal](ref:babylon-withdrawal).
Example request (for `sigNet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/babylon-btc/signet/transaction/withdrawal \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHash": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028",
"withdrawalAddress": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9"
}'
```
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
* `withdrawalAddress` — staker withdrawal address.
Example response:
```json
{
"error": null,
"result": {
"withdrawalAddress": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9",
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHash": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028",
"withdrawalTransactionHex": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000",
"fee": 1000
}
}
```
* `withdrawalAddress` — staker withdrawal address.
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
* `withdrawalTransactionHex` — unsigned transaction for withdrawal request in the hexadecimal format. Sign the transaction and submit it to the Bitcoin blockchain to perform the called action.
* `fee` — total fee in SATOSHI charged for processing the transaction.
2. Use `unstakeTransactionHex` from the previous step to [sign and send](doc:signing-transaction-eth) the signed transaction to the Bitcoin chain.
# What's Next?
* [Staking API](ref:babylon-stake) reference.
* [Sign and Broadcast Transaction](doc:signing-transaction-babylon)
---
## Dydx Transaction Signing
*Source: [https://docs.p2p.org/docs/dydx-transaction-signing.md](https://docs.p2p.org/docs/dydx-transaction-signing.md)*
# dYdX Transaction Signing
To sign and broadcast the transaction to the dYdX network, follow these steps:
1. Prepare unsigned transaction in Base64 encrypted format.
2. Sign the transaction using the following code:
```typescript
import { ImportableWallets, getSigningWallet } from '@stakekit/signers';
import { Networks } from '@stakekit/common';
async function main() {
const walletoptions = {
mnemonic:
'***',
walletType: ImportableWallets.Keplr,
index: 0,
};
const signingWallet = await getSigningWallet(Networks.Dydx, walletoptions);
const address = await signingWallet.getAddress();
const additionalAddresses = await signingWallet.getAdditionalAddresses();
console.log('My wallet additionalAddresses: ', additionalAddresses);
console.log('My wallet address: ', address);
const unsignedTransaction = '';
const signedTx = await signingWallet.signTransaction(unsignedTransaction);
console.log('Signed transaction Tx (hex): ', signedTx);
}
(async () => {
await main();
})();
```
Upon successful execution, the script prints the signed transaction in the hexadecimal format, ready to be broadcasted:
```Text Bash
✅ Signed transaction Tx (hex): ...
```
3. Broadcast the transaction to the dYdX network by sending a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
## What's Next?
* [Networks Supported](doc:unified-api-networks)
* [Getting Started](doc:unified-api-getting-started)
* [Unified API Reference](ref:unified-create-stake-transaction)
---
## Restaking Api Fixed Beacon Chain Proof Generation
*Source: [https://docs.p2p.org/changelog/restaking-api-fixed-beacon-chain-proof-generation.md](https://docs.p2p.org/changelog/restaking-api-fixed-beacon-chain-proof-generation.md)*
# Restaking API: Fixed Withdrawal Credentials Ownership Proof
### Fixed
* Fixed beacon chain proof generation for validators with EigenPod withdrawal credentials
* Resolved proof generation issues preventing successful verification requests using the [/api/v1/eth/staking/eigenlayer/tx/verify-withdrawal-credentials](https://docs.p2p.org/reference/eth-eigen-verify-withdrawal-credentials#/) endpoint
* Endpoint now returns valid transaction data for all eligible validators
***
**Note**: Validators that previously encountered "activate restake request not found" errors can now retry successfully.
---
## Avail Pool Bond
*Source: [https://docs.p2p.org/reference/avail-pool-bond.md](https://docs.p2p.org/reference/avail-pool-bond.md)*
# Create Bond Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/staking/pool/bond": {
"post": {
"operationId": "avail-pool-bond",
"summary": "Create Bond Request",
"description": "Creating a bond request on the Avail nomination pool where a user has membership in exchange for some other benefit.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Avail network:
`mainnet` — Avail mainnet.
`testnet` — Avail testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"poolId": {
"type": "number",
"description": "ID of the nomination pool.",
"example": 1
},
"amount": {
"type": "number",
"description": "Amount of tokens to bond. AVAIL is used for the mainnet network.",
"example": 3
}
},
"required": [
"stashAccountAddress",
"poolId",
"amount"
],
"x-readme-ref-name": "AvailPoolBondRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xac0406000b0030ef7dba0203ded255321b86f5f975cf04fd0e9d2b1d941469d469dcc93b89441cdfe6c39f7b"
},
"amount": {
"type": "number",
"description": "Amount of tokens to bond. AVAIL is used for the mainnet network.",
"example": 3
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"unsignedTransaction",
"amount",
"createdAt"
],
"x-readme-ref-name": "AvailUnsignedPoolBondTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124109
},
"message": {
"type": "string",
"default": "The request could not be performed because the account does not have enough balance to perform the transaction."
},
"name": {
"type": "string",
"default": "InsufficientBalanceException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientBalanceException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119139
},
"message": {
"type": "string",
"default": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool."
},
"name": {
"type": "string",
"default": "AvailPoolDoesNotExistsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AvailPoolDoesNotExistsException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119106
},
"message": {
"type": "string",
"default": "The request could not be performed because the bond amount is too small. Please check that the bond amount is more than %s and try again."
},
"name": {
"type": "string",
"default": "StakeAmountTooSmallException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "StakeAmountTooSmallException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 119101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Avail address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"InsufficientBalanceException": {
"value": {
"error": {
"code": 119102,
"message": "The request could not be performed because the amount of tokens on account is insufficient. Please check that the balance is more than undefined.",
"type": "client"
},
"result": null
}
},
"AvailPoolDoesNotExistsException": {
"value": {
"error": {
"code": 119139,
"message": "The request could not be performed because the ID provided is not found. Please specify the correct ID of the nomination pool.",
"type": "client"
},
"result": null
}
},
"StakeAmountTooSmallException": {
"value": {
"error": {
"code": 119106,
"message": "The request could not be performed because the bond amount is too small. Please check that the bond amount is more than undefined and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119132
},
"message": {
"type": "string",
"default": "The bond request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "BondException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"BondException": {
"value": {
"error": {
"code": 119132,
"message": "The bond request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Sei
*Source: [https://docs.p2p.org/docs/withdrawal-sei.md](https://docs.p2p.org/docs/withdrawal-sei.md)*
# Withdrawal
The withdrawal process in the Sei network using the Staking API can be done in a few steps:
1. Create an unstake transaction.
2. Sign and send the transaction to the network.
## 1. Create Unstake Transaction
1. Send a POST request to [/api/v1/sei/\{network}/staking/unstake](ref:create-sei-unstake-transaction).
Example request (for `atlantic-2` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/sei/atlantic-2/staking/unstake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"delegatorAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r",
"memo": "This is your memo message",
"amount": 0.0001
}'
```
* `stashAccountAddress` — delegator account address which keeps tokens.
* `memo` — arbitrary text data to add to the transactions.
* `amount` — amount of tokens to unstake in SEI.
Example response:
```json
{
"error": null,
"result": {
"amount": 0.0001,
"currency": "sei",
"validatorAddress": "cosmosvaloper132juzk0gdmwuxvx4phug7m3ymyatxlh9734g4w",
"delegatorAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r",
"transactionData": {
"messages": [
{
"typeUrl": "/cosmos.staking.v1beta1.MsgUndelegate",
"value": {
"delegatorAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r",
"validatorAddress": "cosmosvaloper132juzk0gdmwuxvx4phug7m3ymyatxlh9734g4w",
"amount": {
"denom": "usei",
"amount": "100"
}
}
}
],
"fee": {
"amount": [
{
"amount": "16384",
"denom": "usei"
}
],
"gas": "655324"
},
"memo": "This is your memo message",
"encodedBody": "0a9c010a252f636f736d6f732e7374616b696e672e763162657461312e4d7367556e64656c656761746512730a2d636f736d6f733179397765666d6c706d30646a6b74387373656576656b653068747466756b67326136306730721234636f736d6f7376616c6f7065723133326a757a6b3067646d77757876783470687567376d33796d796174786c68393733346734771a0c0a057561746f6d1203313030120b546865206d657373616765",
"encodedAuthInfo": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103b0c7ac278e1941ac0b65d6bd45d541cae58aa584058fbbd822311b8718708c0e12040a020801180212140a0e0a057561746f6d1205313633383410dcff27"
},
"createdAt": "2023-11-03T10:10:05.407Z"
}
}
```
* `amount` — amount of tokens to stake.
* `currency` — currency of tokens:
* `sei` — Sei native staking token.
* `usei` — 1 SEI = 10⁻⁶ uSEI.
* `msei` — 1 SEI = 10⁻³ mSEI.
* `validatorAddress` — validator address to which tokens are delegated.
* `stashAccountAddress` — delegator stash account address which keeps tokens.
* `rewardDestinationAddress` — reward destination account address.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
`transactionData` is the list of data fields to be used to construct the staking transactions:
* `messages`:
* `typeUrl` — Sei network operation type.
* `delegatorAddress` — delegator address.
* `validatorAddress` — validator address.
* `amount` — amount of tokens to unstake.
* `denom` — currency of tokens.
* `fee` — fee charged for the transaction.
* `amount` — amount of tokens.
* `denom` — currency of tokens: `sei`, `usei`, or `msei`.
* `gas` — amount of gas spent for the transaction.
* `memo` — arbitrary text data to add to the transactions.
* `encodedBody` — processable transaction data encoded in the hexadecimal format.
* `encodedAuthInfo` — authorization data, including fee, encoded in the hexadecimal format.
## 2. Sign and Send Transaction
Use `transactionData` to [sign and send](doc:signing-transaction-cosmos) the signed transaction to the Sei network.
To check the transaction status, send a GET request to [/api/v1/sei/\{network}/transaction/status/\{transactionHash}](ref:get-sei-transaction-status).
Example request (for `atlantic-2` network):
```curl
curl --request GET \
--url https://api-test.p2p.org/api/v1/sei/atlantic-2/transaction/status/ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47 \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json'
```
* `transactionHash` — hash of the transaction.
Example response:
```json
{
"error": null,
"result": {
"status": "success",
"blockId": 18575267,
"fee": 0.005952,
"gas": {
"used": 202947,
"wanted": 238047
},
"transactionHash": "ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47"
}
}
```
* `status` — transaction status: `success`, `failed`.
* `blockId` — unique identifier of the block in which the transaction has been included.
* `fee` — total fee in ATOM charged for processing the transaction.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `used` — amount of gas spent for the transaction.
* `wanted` — maximum gas limit that the transaction initiator was willing to consume for the transaction.
* `transactionHash` — hash of the transaction.
## What's Next?
* [Sign and Broadcast Transaction](doc:signing-transaction-sei)
* [Staking API](ref:create-sei-stake-transaction) reference.
---
## Data Validator Statuses Detailed
*Source: [https://docs.p2p.org/reference/data-validator-statuses-detailed.md](https://docs.p2p.org/reference/data-validator-statuses-detailed.md)*
# Get Validator Statuses Detailed
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/validator/statuses/detailed": {
"get": {
"operationId": "data-validator-statuses-detailed",
"summary": "Get Validator Statuses Detailed",
"description": "Get a detailed status information for each individual validator along with their total count.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum"
],
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"total": {
"type": "number",
"description": "Total count of validators."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"validator": {
"type": "string",
"description": "Validator address in the required network. For the Ethereum network, it is a public validator key."
},
"status": {
"type": "string",
"description": "Validator status."
}
},
"x-readme-ref-name": "ValidatorStatusesDetailed"
}
}
},
"required": [
"total",
"list"
],
"x-readme-ref-name": "GetValidatorStatusesDetailedResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115308
},
"message": {
"type": "string",
"default": "The list of validator statuses could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetValidatorStatusesException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetValidatorStatusesException"
}
]
}
}
},
"examples": {
"GetValidatorStatusesException": {
"value": {
"error": {
"code": 115308,
"message": "The list of validator statuses could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Validator"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Broadcast Babylon Transaction
*Source: [https://docs.p2p.org/reference/broadcast-babylon-transaction.md](https://docs.p2p.org/reference/broadcast-babylon-transaction.md)*
# Broadcast Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon/{network}/transaction/send": {
"post": {
"operationId": "broadcast-babylon-transaction",
"summary": "Broadcast Transaction",
"description": "Broadcast transaction to the Babylon network.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "babylon-mainnet",
"description": "
Babylon network:
`mainnet` — Babylon mainnet.
`babylon-testnet` — Babylon testnet.
",
"schema": {
"enum": [
"babylon-testnet",
"babylon-mainnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"signedTransaction": {
"type": "string",
"description": "Signed transaction in Base64 encrypted format which needs to be broadcast to the network."
}
},
"required": [
"signedTransaction"
],
"x-readme-ref-name": "BroadcastTransactionRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"failed"
],
"description": "Transaction status."
},
"blockId": {
"type": "number",
"description": "Unique identifier of the block in which the transaction has been included."
},
"fee": {
"type": "number",
"description": "Total fee in SEI charged for processing the transaction."
},
"gas": {
"description": "Computational effort required to execute the transaction measured in gas units.",
"allOf": [
{
"type": "object",
"properties": {
"used": {
"type": "number",
"description": "Amount of gas spent for the transaction."
},
"wanted": {
"type": "number",
"description": "Maximum gas limit for the transaction."
}
},
"required": [
"used",
"wanted"
],
"x-readme-ref-name": "Gas"
}
]
},
"transactionHash": {
"type": "string",
"pattern": "[A-Z0-9]{64}",
"description": "Hash of the transaction."
}
},
"required": [
"status",
"blockId",
"fee",
"gas",
"transactionHash"
],
"x-readme-ref-name": "TransactionStatusResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 110107,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110109
},
"message": {
"type": "string",
"default": "The transaction could not be broadcasted because the internal server error occurred."
},
"name": {
"type": "string",
"default": "BroadcastTransactionFailedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BroadcastTransactionFailedException"
}
]
}
}
},
"examples": {
"BroadcastTransactionFailedException": {
"value": {
"error": {
"code": 110109,
"message": "The transaction could not be broadcasted because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Babylon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Overview Sei
*Source: [https://docs.p2p.org/docs/overview-sei.md](https://docs.p2p.org/docs/overview-sei.md)*
# Overview
Staking on Sei using the Staking API can be done in several steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For Sei blockchain, there are several networks available:
* `pacific-1` — the production network
* `atlantic-2` — a testnet for development and testing purposes.
## What's Next?
* [Getting Started](doc:staking-sei).
* [Withdrawal](doc:withdrawal-sei).
* [Staking API](ref:create-sei-stake-transaction) reference.
---
## Eth Nodes Request Create
*Source: [https://docs.p2p.org/reference/eth-nodes-request-create.md](https://docs.p2p.org/reference/eth-nodes-request-create.md)*
# Create Staking Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/direct/nodes-request/create": {
"post": {
"operationId": "eth-nodes-request-create",
"summary": "Create Staking Request",
"description": "Set up nodes for staking using P2P infrastructure.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"example": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"description": "Arbitrary UUID. You can later use that UUID to check the status of the set-up operation."
},
"type": {
"type": "string",
"enum": [
"REGULAR",
"RESTAKING"
],
"description": "Type of the nodes request.",
"example": "REGULAR"
},
"validatorsCount": {
"type": "number",
"description": "Number of validators: each validator stakes from 32 to 2048 ETH.",
"default": 1,
"minimum": 1,
"maximum": 3125,
"example": 1
},
"amountPerValidator": {
"type": "string",
"description": "Amount of tokens to stake in Gwei per validator.",
"example": "32000000000"
},
"withdrawalCredentialsType": {
"type": "string",
"description": "Withdrawal credentials type.",
"example": "0x02",
"enum": [
"0x01",
"0x02"
]
},
"withdrawalAddress": {
"type": "string",
"description": "Withdrawal address for the validators.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"eigenPodOwnerAddress": {
"type": "string",
"description": "EigenPod owner address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"controllerAddress": {
"type": "string",
"description": "Controller address for the validators.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"feeRecipientAddress": {
"type": "string",
"description": "Fee recipient address.",
"example": "0x53da3c92fCCEb0CFE1764f65DDfF1564A2b15585",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"nodesOptions": {
"type": "object",
"properties": {
"location": {
"type": "string",
"enum": [
"any"
],
"example": "any",
"description": "Nodes location. Currently, only `any` is supported.",
"default": "any"
},
"relaysSet": {
"type": "string",
"description": "MEV Relay selection.",
"example": null
}
},
"required": [
"location"
],
"x-readme-ref-name": "NodesOptionsRequest"
}
},
"required": [
"id",
"validatorsCount",
"nodesOptions"
],
"x-readme-ref-name": "CreateNodesRequestRequest"
}
}
}
},
"responses": {
"201": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"type": "boolean",
"example": true
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103122
},
"message": {
"type": "string",
"default": "The nodes set-up request could not be performed because the node ID specified already exists."
},
"name": {
"type": "string",
"default": "NodesRequestIdAlreadyExistException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NodesRequestIdAlreadyExistException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103129
},
"message": {
"type": "string",
"default": "The transaction could not be created because the withdrawal address '%s' provided is invalid. For the restaking flow, the withdrawal address corresponds to the EigenPod address set by default or explicitly. Please check the request parameters."
},
"name": {
"type": "string",
"default": "CannotGetPodAddressException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CannotGetPodAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103143
},
"message": {
"type": "string",
"default": "The size of validators provided is invalid. Please check the request parameters."
},
"name": {
"type": "string",
"default": "WrongValidatorSizeException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongValidatorSizeException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103142
},
"message": {
"type": "string",
"default": "The size of validators provided has to be equal to 32 ETH. Please check the request parameters."
},
"name": {
"type": "string",
"default": "ValidatorSizeHasToBeDefaultException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorSizeHasToBeDefaultException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NodesRequestIdAlreadyExistException": {
"value": {
"error": {
"code": 103122,
"message": "The nodes set-up request could not be performed because the node ID specified already exists.",
"type": "client"
},
"result": null
}
},
"CannotGetPodAddressException": {
"value": {
"error": {
"code": 103129,
"message": "The transaction could not be created because the withdrawal address 'undefined' provided is invalid. For the restaking flow, the withdrawal address corresponds to the EigenPod address set by default or explicitly. Please check the request parameters.",
"type": "client"
},
"result": null
}
},
"WrongValidatorSizeException": {
"value": {
"error": {
"code": 103143,
"message": "The size of validators provided is invalid. Please check the request parameters.",
"type": "client"
},
"result": null
}
},
"ValidatorSizeHasToBeDefaultException": {
"value": {
"error": {
"code": 103142,
"message": "The size of validators provided has to be equal to 32 ETH. Please check the request parameters.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103117
},
"message": {
"type": "string",
"default": "The nodes set-up request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "NodesRequestCreateException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NodesRequestCreateException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"NodesRequestCreateException": {
"value": {
"error": {
"code": 103117,
"message": "The nodes set-up request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Ethereum"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Ton
*Source: [https://docs.p2p.org/docs/withdrawal-ton.md](https://docs.p2p.org/docs/withdrawal-ton.md)*
# Withdrawal
The withdrawal process in the TON network using the Staking API can be done following these steps:
1. Create an unstake transaction.
2. Sign and broadcast the transaction to withdraw staked tokens from the pool.
> 🚧 Please note
>
> For single nominator pools, the unstake transaction could only be performed by the pool owner. It is also crucial to use the wallet version of the pool owner for the unstake request.
# 1. Create Unstake Transaction
Depending on the type of your staking pool, send a POST request either to [/api/v1/ton/\{network}/staking/single-nominator/unstake](ref:ton-staking-single-nominator-unstake) or to [/api/v1/ton/\{network}/staking/ton-whales/unstake](). A special memo message for withdrawal will be created.
Example request (for the single nominator pool in the `testnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/ton/testnet/staking/single-nominator/unstake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"publicKey": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6",
"amount": 200,
"walletVersion": "V4"
}
```
* `publicKey` — public key of the nominator for the TON network.
* `amount` — amount of tokens to unstake in TON.
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain. `V4` is used by default.
> Since only an owner of the single nominator pool can perform the transaction, mind specifying the current wallet version of the active pool owner.
Example response:
```json
{
"error": null,
"result": {
"unsignedTransaction": "b5ee9c7241010101003800006b000010000000000000000001000000039fedeab7a2b56b38f19f60b5b9f70b2f1ba2d89b9c5a756036c7cfad73571fb281887735940193456f7e",
"publicKey": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6",
"amount": "2"
}
}
```
* `unsignedTransaction` — unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to create an unstake request.
* `publicKey` — public key of the nominator for the TON network.
* `amount` — amount of tokens to unstake in TON.
# 2. Sign and Broadcast Transaction
[Sign and broadcast](doc:signing-transaction-ton) the `unsignedTransaction` to the TON network.
## What's Next?
* [Getting Started](doc:staking-ton).
* [Staking API](ref:ton-staking-single-nominator-stake) reference.
---
## Transaction Deposit
*Source: [https://docs.p2p.org/reference/transaction-deposit.md](https://docs.p2p.org/reference/transaction-deposit.md)*
# Prepare Top-Up Cluster Balance Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/tx/deposit/{id}": {
"get": {
"operationId": "transaction-deposit",
"summary": "Prepare Top-Up Cluster Balance Transaction",
"description": "Construct a serialized transaction to deposit SSV tokens in the cluster balance.",
"parameters": [
{
"name": "operationPeriodInDays",
"required": true,
"in": "query",
"example": 365,
"description": "Operation period in days.",
"schema": {
"minimum": 1,
"maximum": 3650,
"default": 365,
"type": "number"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "UUID of the SSV request.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
}
},
"required": [
"list"
],
"x-readme-ref-name": "EthereumUnsignedTransactionListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111104
},
"message": {
"type": "string",
"default": "The SSV ID %s provided could not be found. Please specify the correct UUID."
},
"name": {
"type": "string",
"default": "SsvRequestNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SsvRequestNotFoundException"
}
]
}
}
},
"examples": {
"SsvRequestNotFoundException": {
"value": {
"error": {
"code": 111104,
"message": "The SSV ID undefined provided could not be found. Please specify the correct UUID.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111120
},
"message": {
"type": "string",
"default": "The deposit transaction could not be created because an internal server error occurred."
},
"name": {
"type": "string",
"default": "DepositException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "DepositException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"DepositException": {
"value": {
"error": {
"code": 111120,
"message": "The deposit transaction could not be created because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Sui
*Source: [https://docs.p2p.org/docs/withdrawal-sui.md](https://docs.p2p.org/docs/withdrawal-sui.md)*
# Withdrawal
The withdrawal process in the SUI network using the Staking API can be done following these steps:
1. Get the list of stakes for your wallet.
2. Use the `stakeId` from the active or pending stake to initiate withdrawal.
3. Sign and send the transaction to the SUI network.
4. Confirm completion via explorer.
After each operation, you need to [sign and send the transaction](doc:signing-transaction-sui) to the SUI network.
> You can withdraw at any time while the stake status is either `Pending` or `Active`.\
> The withdrawal is **immediate** and processed within seconds.
## 1. Get Stake ID
Before withdrawing, identify which stake you want to withdraw.
See: [Getting Started → Get Stake Status](doc:staking-sui#3-optionally-track-the-stake-status-to-confirm-activation)
The response will include one or more objects like:
```json
{
"stakeId": "0x5d920b8fca6a6043d898ab1a9a8ab167d8aa323fe2b9e76a27312f7f16e20a67",
"amount": 1000000000,
"status": "Pending"
}
```
Copy the `stakeId` to use in the next step.
## 2. Create Withdrawal Transaction
Send a `POST` request to [/api/v1/sui/\/staking/withdraw](ref:sui-staking-withdraw)
Example response:
```curl
curl --request
--url 'https://api-test.p2p.org/api/v1/sui/testnet/staking/withdraw' \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"sender": "0x696f4402d7151fb49e52b629de3ce3098f3dda7721a7425c000b4f26653709e3",
"gasPrice": 1000,
"gasBudget": 10000000,
"stakeId": "0x5d920b8fca6a6043d898ab1a9a8ab167d8aa323fe2b9e76a27312f7f16e20a67"
}'
```
* `sender` — your SUI wallet address.
* `gasPrice` — gas price in MIST.
* `gasBudget` — maximum gas budget.
* `stakeId` — identifier of the stake to withdraw (retrieved from stake-list).
Example response:
```json
{
"error": null,
"result": {
"unsignedTransaction": "0x00000201010000000000000000000000000000..."
}
}
```
You will receive a serialized unsigned transaction in the `unsignedTransaction` field. This must be signed and sent to the SUI network.
## 3. Sign and Send Transaction
Sign and broadcast the transaction using your local signer or SDK.
See: [Sign and Send Transaction](doc:signing-transaction-sui)
Example broadcasted transaction:\
[https://suiscan.xyz/testnet/tx/DiXajfAeTLVhiQZuW8aH2UD1XsCEoZVH4twRC5PjeK5](https://suiscan.xyz/testnet/tx/DiXajfAeTLVhiQZuW8aH2UD1XsCEoZVH4twRC5PjeK5)
## What's Next?
* [Staking API](ref:sui) reference.
---
## Polkadot Transaction Status
*Source: [https://docs.p2p.org/reference/polkadot-transaction-status.md](https://docs.p2p.org/reference/polkadot-transaction-status.md)*
# Get Transaction Status
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/tx/status/{blockHash}/{transactionHash}": {
"get": {
"operationId": "polkadot-transaction-status",
"summary": "Get Transaction Status",
"description": "Check the status of the transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
`freeBalance` — portion of a balance that is not reserved for any operations.
`rewards` — claimed rewards tokens.
",
"example": "freeBalance",
"default": "freeBalance"
}
},
"required": [
"stashAccountAddress",
"amount",
"amountType"
],
"x-readme-ref-name": "AvailPoolBondExtraRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xac0406000b0030ef7dba0203ded255321b86f5f975cf04fd0e9d2b1d941469d469dcc93b89441cdfe6c39f7b"
},
"amount": {
"type": "number",
"description": "Amount of tokens for bond operations (in usual DOTs/KSMs/WNDs).",
"example": 3
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"unsignedTransaction",
"amount",
"createdAt"
],
"x-readme-ref-name": "AvailUnsignedPoolTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124109
},
"message": {
"type": "string",
"default": "The request could not be performed because the account does not have enough balance to perform the transaction."
},
"name": {
"type": "string",
"default": "InsufficientBalanceException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientBalanceException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 119101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Avail address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"InsufficientBalanceException": {
"value": {
"error": {
"code": 119102,
"message": "The request could not be performed because the amount of tokens on account is insufficient. Please check that the balance is more than undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119133
},
"message": {
"type": "string",
"default": "The extra bond request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "BondExtraException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondExtraException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"BondExtraException": {
"value": {
"error": {
"code": 119133,
"message": "The extra bond request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Ton Staking Ton Whales Unstake
*Source: [https://docs.p2p.org/reference/ton-staking-ton-whales-unstake.md](https://docs.p2p.org/reference/ton-staking-ton-whales-unstake.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/ton/{network}/staking/ton-whales/unstake": {
"post": {
"operationId": "ton-staking-ton-whales-unstake",
"summary": "Create Unstake Request",
"description": "Create the unstake request transaction in the TON Whales pool.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
TON network:
`mainnet` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"publicKey": {
"type": "string",
"description": "Public key of the nominator for the TON network.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"amount": {
"format": "int64",
"type": "integer",
"description": "Amount of tokens to unstake in nanoTONs (1 TON = 10⁹ nanoTONs).",
"example": "200"
},
"walletVersion": {
"type": "string",
"description": "Version of the smart contract used by the wallet in the TON blockchain.",
"example": "V4",
"default": "V4"
}
},
"required": [
"publicKey",
"amount"
],
"x-readme-ref-name": "TonWhalesUnstakeRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"publicKey": {
"type": "string",
"description": "Public key of the nominator for the TON network.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"amount": {
"format": "int64",
"type": "integer",
"description": "Amount of tokens to unstake in nanoTONs (1 TON = 10⁹ nanoTONs).",
"example": "200"
},
"walletVersion": {
"type": "string",
"description": "Version of the smart contract used by the wallet in the TON blockchain.",
"example": "V4",
"default": "V4"
}
},
"required": [
"publicKey",
"amount"
],
"x-readme-ref-name": "TonWhalesUnstakeRequest"
}
]
}
}
}
}
}
}
},
"tags": [
"TON"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Celestia
*Source: [https://docs.p2p.org/docs/withdrawal-celestia.md](https://docs.p2p.org/docs/withdrawal-celestia.md)*
# Withdrawal
The withdrawal process in the Celestia network using the Staking API can be done in a few steps:
1. Create an unstake transaction.
2. Sign and send the transaction to the network.
## 1. Create Unstake Transaction
1. Send a POST request to [/api/v1/celestia/\{network}/staking/unstake](ref:create-celestia-unstake-transaction).
Example request (for `celestia-mainnet-beta` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/celestia/celestia-mainnet-beta/staking/unstake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"delegatorAddress": "celestia1yknsyf9ws4ugtv3r9g43kwqkne4zmrupae4xb2",
"memo": "This is your memo message",
"amount": 0.0001
}'
```
* `stashAccountAddress` — delegator account address which keeps tokens.
* `memo` — arbitrary text data to add to the transactions.
* `amount` — amount of tokens to unstake in TIA.
Example response:
```json
{
"error": null,
"result": {
"amount": 0.0001,
"currency": "tia",
"validatorAddress": "celestiavaloper1r4kqtye4dzacmrwnh6f057p50pdjm8g59tlhhg",
"delegatorAddress": "celestia1yknsyf9ws4ugtv3r9g43kwqkne4zmrupae4xb2",
"transactionData": {
"messages": [
{
"typeUrl": "/cosmos.staking.v1beta1.MsgUndelegate",
"value": {
"delegatorAddress": "celestia1yknsyf9ws4ugtv3r9g43kwqkne4zmrupae4xb2",
"validatorAddress": "celestiavaloper1r4kqtye4dzacmrwnh6f057p50pdjm8g59tlhhg",
"amount": {
"denom": "utia",
"amount": "100"
}
}
}
],
"fee": {
"amount": [
{
"amount": "16384",
"denom": "utia"
}
],
"gas": "655324"
},
"memo": "This is your memo message",
"encodedBody": "0a9c010a252f636f736d6f732e7374616b696e672e763162657461312e4d7367556e64656c656761746512730a2d636f736d6f733179397765666d6c706d30646a6b74387373656576656b653068747466756b67326136306730721234636f736d6f7376616c6f7065723133326a757a6b3067646d77757876783470687567376d33796d796174786c68393733346734771a0c0a057561746f6d1203313030120b546865206d657373616765",
"encodedAuthInfo": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103b0c7ac278e1941ac0b65d6bd45d541cae58aa584058fbbd822311b8718708c0e12040a020801180212140a0e0a057561746f6d1205313633383410dcff27"
},
"createdAt": "2023-11-03T10:10:05.407Z"
}
}
```
* `amount` — amount of tokens to stake.
* `currency` — currency of tokens:
* `tia` — TIA, Celestia native staking token.
* `utia` — 1 TIA = 10^-6 uTIA,
* `mtia` — 1 TIA = 10^-3 mTIA.
* `validatorAddress` — validator address to which tokens are delegated.
* `stashAccountAddress` — delegator stash account address which keeps tokens.
* `rewardDestinationAddress` — reward destination account address.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
`transactionData` is the list of data fields to be used to construct the staking transactions:
* `messages`:
* `typeUrl` — Celestia network operation type.
* `delegatorAddress` — delegator address.
* `validatorAddress` — validator address.
* `amount` — amount of tokens to unstake.
* `denom` — currency of tokens.
* `fee` — fee charged for the transaction.
* `amount` — amount of tokens.
* `denom` — currency of tokens: `tia`, `utia`, or `mtia`.
* `gas` — amount of gas spent for the transaction.
* `memo` — arbitrary text data to add to the transactions.
* `encodedBody` — processable transaction data encoded in the hexadecimal format.
* `encodedAuthInfo` — authorization data, including fee, encoded in the hexadecimal format.
## 2. Sign and Send Transaction
Use `transactionData` to [sign and send](doc:signing-transaction-cosmos) the signed transaction to the Celestia network.
To check the transaction status, send a GET request to [/api/v1/celestia/\{network}/transaction/status/\{transactionHash}](ref:get-celestia-transaction-status).
Example request (for `celestia-mainnet-beta` network):
```curl
curl --request GET \
--url https://api-test.p2p.org/api/v1/celestia/celestia-mainnet-beta/transaction/status/ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47 \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json'
```
* `transactionHash` — hash of the transaction.
Example response:
```json
{
"error": null,
"result": {
"status": "success",
"blockId": 18575267,
"fee": 0.005952,
"gas": {
"used": 202947,
"wanted": 238047
},
"transactionHash": "ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47"
}
}
```
* `status` — transaction status: `success`, `failed`.
* `blockId` — unique identifier of the block in which the transaction has been included.
* `fee` — total fee in TIA charged for processing the transaction.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `used` — amount of gas spent for the transaction.
* `wanted` — maximum gas limit that the transaction initiator was willing to consume for the transaction.
* `transactionHash` — hash of the transaction.
## What's Next?
* [Staking API](ref:create-celestia-stake-transaction) reference.
---
## Validator Consolidation
*Source: [https://docs.p2p.org/docs/validator-consolidation.md](https://docs.p2p.org/docs/validator-consolidation.md)*
# Validator Consolidation
The Pectra upgrade introduces major improvements to how validators are created and managed across both Ethereum and SSV staking APIs. These enhancements improve scalability, enable larger validator sizes (up to 2048 ETH), and streamline flows using `0x02` withdrawal credentials.
## Objective
Streamline validator management by merging multiple existing validators into a single `0x02`-enabled validator. This enables autocompounding and simplifies future staking operations.
## Applicable Scenarios
* Reducing the number of active validators tied to the same withdrawal address
* Migrating from `0x01` to `0x02` withdrawal credentials
* Preparing for advanced staking operations such as top-ups and partial withdrawals
## API Endpoint
`POST` [/api/v1/eth/staking/direct/tx/consolidation-validators](ref:eth-staking-consolidation-validators).
## Flow
1. Submit a list of `sourcePubkeys` and a `targetPubkey` — all validators must share the same withdrawal address.
2. The API returns a serialized transaction payload.
3. Sign the transaction using the withdrawal address.
4. Broadcast the transaction to complete the consolidation. The resulting validator will use `0x02` withdrawal credentials.
> This method is supported for both Ethereum and SSV validators via the same endpoint.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/consolidation-validators \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"withdrawalAddress": "0x0FCb73Fbf9d4...E21c1EcE5aE1Ccb63",
"sourcePubkeys": [
"0xad9049587a26e8db61f...9f334caaf5e9"
],
"targetPubkey": "0xad9049587a26e8...aaf5e9"
}'
```
Example response
```json
{
"error": null,
"result": {
"list": [
{
"serializeTx": "0x02f87883088bb080840422bd...334caaf5e9c0",
"gasLimit": "1000000",
"data": "0xad9049587a26e8db61f6...1549f334caaf5e9",
"value": "1",
"chainId": 560048,
"type": 2,
"maxFeePerGas": "2211533588",
"maxPriorityFeePerGas": "69385672"
}
]
}
}
```
---
## Avail Pool Set Claim Permission
*Source: [https://docs.p2p.org/reference/avail-pool-set-claim-permission.md](https://docs.p2p.org/reference/avail-pool-set-claim-permission.md)*
# Create Claim Permission Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/staking/pool/set-claim-permission": {
"post": {
"operationId": "avail-pool-set-claim-permission",
"summary": "Create Claim Permission Request",
"description": "Creating a claim permission request allows users having membership in the Avail nomination pool to grant permission to any other pool member account for claiming, bonding or withdrawing rewards on behalf of the user.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
---
## Overview Solana
*Source: [https://docs.p2p.org/docs/overview-solana.md](https://docs.p2p.org/docs/overview-solana.md)*
# Overview
Staking in the Solana network using the Staking API consists of several main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For Solana, there are several networks available:
* `mainnet-beta` — production environment.
* `testnet` — Solana testing environment called Testnet. Note that we don't support Devnet environment yet.
## What's Next?
* [Getting Started](doc:staking-solana).
* [Sign and Send Transaction](doc:signing-transaction-solana).
* [Withdrawal](doc:withdrawal-solana).
* [Staking API](ref:solana-2) reference.
---
## Polkadot Staking Withdrawunbonded
*Source: [https://docs.p2p.org/reference/polkadot-staking-withdrawunbonded.md](https://docs.p2p.org/reference/polkadot-staking-withdrawunbonded.md)*
# Withdraw Unbonded Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/staking/withdraw-unbonded": {
"post": {
"operationId": "polkadot-staking-withdrawUnbonded",
"summary": "Withdraw Unbonded Request",
"description": "Withdrawing tokens within the Polkadot network that were previously unbonded.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
}
},
"required": [
"stashAccountAddress"
],
"x-readme-ref-name": "WithdrawUnbondedRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action."
},
"unsignedTransactionSerialized": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Payload of the unsigned transaction in hex format",
"example": "0x27000700e40b5402ee000000c500100000e1510f001a00000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3898b77c3a2359f56733c56804a1f1539df9dd90e38167bc1ee4090e4ed92ce2100"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding."
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format."
}
},
"required": [
"unsignedTransaction",
"stashAccountAddress",
"createdAt"
],
"x-readme-ref-name": "WithdrawalTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119103
},
"message": {
"type": "string",
"default": "The transaction could not be found. Please specify the correct transaction data."
},
"name": {
"type": "string",
"default": "BondNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119105
},
"message": {
"type": "string",
"default": "The request could not be performed because the controller address does not correspond to the provided one."
},
"name": {
"type": "string",
"default": "WrongControllerException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongControllerException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"BondNotFoundException": {
"value": {
"error": {
"code": 107103,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"WrongControllerException": {
"value": {
"error": {
"code": 107105,
"message": "The request could not be performed because the controller address does not correspond to the provided one.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119136
},
"message": {
"type": "string",
"default": "The withdrawal request could not be performed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "WithdrawUnbondedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WithdrawUnbondedException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"WithdrawUnbondedException": {
"value": {
"error": {
"code": 107131,
"message": "The withdrawal request could not be performed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Unified Api Networks
*Source: [https://docs.p2p.org/docs/unified-api-networks.md](https://docs.p2p.org/docs/unified-api-networks.md)*
# Networks Supported (Unified API)
The table below summarizes all networks supported in the Unified API and the parameters to be used in the staking endpoints.
| Protocol | Chain ID | Network for mainnet | Network for testnet |
| :------------------------------------------------- | :------------ | :---------------------- | :----------------------- |
| [Aptos](doc:unified-api-aptos) | `aptos` | `mainnet` | `testnet` |
| [Avail](doc:unified-api-avail) | `avail` | `mainnet` | `testnet` (Turing) |
| [Babylon](doc:unified-api-babylon) | `babylon-btc` | `mainnet` | `testnet` |
| [Babylon PoS](doc:unified-api-babylon-pos) | `babylon` | `babylon-mainnet` | `babylon-testnet` |
| [Cardano](doc:unified-api-cardano) | `cardano` | `mainnet` | – |
| [Celestia](doc:unified-api-celestia) | `celestia` | `celestia-mainnet-beta` | `celestia-mocha-testnet` |
| [Cosmos ATOM](doc:unified-api-cosmos) | `cosmos` | `cosmoshub-4` | – |
| [dYdX](doc:unified-api-dydx) | `dydx` | `mainnet` | – |
| [Ethereum](doc:unified-api-ethereum) | `eth_ssv` | `mainnet` | `testnet` (Hoodi) |
| [Kusama](doc:unified-api-polkadot) | `polkadot` | | `kusama` |
| [Near](doc:unified-api-near) | `near` | `mainnet` | – |
| [Polkadot](doc:unified-api-polkadot) | `polkadot` | `mainnet` | `westend` (Westend) |
| [Polygon](doc:unified-api-polygon) | `polygon` | `mainnet` | `testnet` |
| [Sei](doc:unified-api-sei) | `sei` | `pacific-1` | `atlantic-2` |
| [Sui](doc:unified-api-sui) | `sui` | `mainnet` | `testnet` |
| [Solana](doc:unified-api-solana) | `solana` | `mainnet-beta` | `testnet` (Testnet) |
| [Story Protocol](doc:unified-api-story-protocol)\* | | | |
| [Tezos](doc:unified-api-tezos) | `xtz` | `mainnet` | – |
| [The Graph](doc:unified-api-the-graph) | `grt` | `mainnet` | – |
| [TON](doc:unified-api-ton) | `ton_whales` | `mainnet` (TON Whales) | `testnet` (TON Whales) |
| [TRON](doc:unified-api-tron)\* | | | |
\*These networks are available with exclusive access, public rollout coming soon. Please [contact us](doc:contacts) to integrate with any of these networks.
## Testing and production environments
We provide two distinct endpoints for testing and production environments:
* Production: \<[https://api.p2p.org](https://api.p2p.org)>
* Testing: \<[https://api-test.p2p.org](https://api-test.p2p.org)>
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
---
## Create Babylon Claim Rewards Transaction
*Source: [https://docs.p2p.org/reference/create-babylon-claim-rewards-transaction.md](https://docs.p2p.org/reference/create-babylon-claim-rewards-transaction.md)*
# Create Claim Rewards Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon/{network}/staking/claim-rewards": {
"post": {
"operationId": "create-babylon-claim-rewards-transaction",
"summary": "Create Claim Rewards Request",
"description": "Create claim rewards request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "babylon-mainnet",
"description": "
"
},
"amount": {
"type": "string",
"description": "Amount of tokens."
}
},
"required": [
"denom",
"amount"
],
"x-readme-ref-name": "Amount"
}
},
"gas": {
"type": "string",
"description": "Amount of gas spent for the transaction."
}
},
"required": [
"amount",
"gas"
],
"x-readme-ref-name": "TransactionFee"
}
]
},
"memo": {
"type": "string",
"description": "Arbitrary text data to add to the transactions."
},
"encodedBody": {
"type": "string",
"description": "Processable transaction data encoded in the hexadecimal format."
},
"encodedAuthInfo": {
"type": "string",
"description": "Authorization data, including fee, encoded in the hexadecimal format."
}
},
"required": [
"messages",
"fee",
"encodedBody",
"encodedAuthInfo"
],
"x-readme-ref-name": "TransactionData"
}
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the transaction in the ISO 8601 format."
},
"amount": {
"type": "number",
"format": "decimal",
"description": "Amount of tokens."
},
"currency": {
"type": "string",
"enum": [
"bbn",
"ubbn",
"mbbn"
],
"description": "Currency of the tokens:
`BBN` — Babylon native staking token.
`uBBN` — 1 BBN = 10⁻⁶ uBBN.
`mBBN` — 1 BBN = 10⁻³ mBBN.
"
},
"validatorAddress": {
"type": "string",
"description": "Validator address to which tokens are delegated.",
"example": "babylonvaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^bbnvaloper[a-zA-Z0-9]{39}$"
},
"rewardDestinationAddress": {
"type": "string",
"description": "Reward destination account address.",
"pattern": "^bbn[a-zA-Z0-9]{39}$"
}
},
"required": [
"stashAccountAddress",
"transactionData",
"createdAt",
"amount",
"currency",
"validatorAddress",
"rewardDestinationAddress"
],
"x-readme-ref-name": "StakeOrUnstakeTransactionStakingBabylonResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110113
},
"message": {
"type": "string",
"default": "The request could not be performed because the simulation transaction failed."
},
"name": {
"type": "string",
"default": "SimulationTransactionOnCosmosException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SimulationTransactionOnCosmosException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110101
},
"message": {
"type": "string",
"default": "The request could not be performed because the amount of tokens in the stash account is insufficient. Please check the balance and specify the correct request parameters."
},
"name": {
"type": "string",
"default": "InsufficientFundsOnCosmosAccountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientFundsOnCosmosAccountException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"SimulationTransactionOnCosmosException": {
"value": {
"error": {
"code": 110113,
"message": "The request could not be performed because the simulation transaction failed. undefined",
"type": "client"
},
"result": null
}
},
"InsufficientFundsOnCosmosAccountException": {
"value": {
"error": {
"code": 110101,
"message": "The request could not be performed because the amount of tokens in the stash account is insufficient. Please check the balance and specify the correct request parameters.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110103
},
"message": {
"type": "string",
"default": "The staking request transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "CreateStakeTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CreateStakeTransactionException"
}
]
}
}
},
"examples": {
"CreateStakeTransactionException": {
"value": {
"error": {
"code": 110103,
"message": "The staking request transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Babylon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Signing Transaction Avail
*Source: [https://docs.p2p.org/docs/signing-transaction-avail.md](https://docs.p2p.org/docs/signing-transaction-avail.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the Avail network, follow these steps:
1. Prepare unsigned transaction in Base64 encrypted format.
2. Sign the transaction using the following code:
```javascript
import { readFileSync } from "fs";
import { ApiPromise, WsProvider, Keyring } from "@polkadot/api";
import '@polkadot/api-augment';
async function sign () {
// Avail websocket url
const provider = process.env.PROVIDER;
// sr25519 secret key filename
const secretFileName = process.env.SECRET_FILE_NAME;
// password of secret key
const password = process.env.PASSWORD;
// transaction in base64
const rawTransaction = process.env.RAW_TRANSACTION;
// connect to Avail node
const wsProvider = new WsProvider(provider);
const api = await ApiPromise.create({ provider: wsProvider });
await api.isReady;
// load keyring file
const keyring = new Keyring({ type: "sr25519" });
const fileContent = readFileSync(
secretFileName,
"utf8"
);
const keyInfo = JSON.parse(fileContent);
const sender = keyring.addFromJson(keyInfo);
// decode secret key
sender.decodePkcs8(password);
const unsigned = api.tx(rawTransaction);
// sing transaction
const signedExtrinsic = await unsigned.signAsync(sender);
console.log('signedExtrinsic', signedExtrinsic.toHuman());
// print signed transaction
const hexEx = signedExtrinsic.toHex()
console.log('signedExtrinsic toHex', hexEx);
await api.disconnect()
}
// run sing function
sign().catch((error) => {
console.error(error);
process.exit(1);
});
```
3. Broadcast the transaction to the Avail network by sending a POST request to [/api/v1/avail/\{network}/transaction/send](ref:avail-transaction-send).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/testnet/tx/send \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"signedTransaction": "0x450284002c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f01befdb7fa39c5a995a8d58676a0513d082be"
}'
```
* `signedTransaction` — signed transaction in hex format.
Example response:
```curl JSON
{
"result": {
"status": "success",
"blockHash": "0x0628743b05ffb4c9d5ea2144b359af38910f0ae439a685f57d85b50b9481ba3f",
"blockId": "17168395",
"extrinsicId": "0xb838911d5a5f965f33b8ee134e1115b5b9902abfc567f0c3050073faf9d3c3e0",
"transactionHash": "0x450284002c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f01befdb7fa39c5a995a8d58676a0513d082be",
"signerAccount": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `staus` — transaction status.
* `blockHash` — block hash in which the transaction was included.
* `blockId` — unique block identifier.
* `extrinsicId` — unique extrinsic identifier.
* `transactionHash` — signed transaction in hex format.
* `signerAccount` — account that signed the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
## What's Next?
* [Getting Started](doc:staking-avail).
* [Withdrawal](doc:withdrawal-avail).
* [Staking API](ref:avail-transaction-status) reference.
---
## Polygon Staking Approve
*Source: [https://docs.p2p.org/reference/polygon-staking-approve.md](https://docs.p2p.org/reference/polygon-staking-approve.md)*
# Create Approve Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polygon/staking/approve": {
"post": {
"operationId": "polygon-staking-approve",
"summary": "Create Approve Request",
"description": "Allow the Polygon smart contract to manage tokens.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"description": "Amount of tokens to delegate, specified in 10^(-18) MATIC.",
"example": "100000000000000000"
},
"stakerAddress": {
"type": "string",
"description": "Staker account address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
}
},
"required": [
"amount",
"stakerAddress"
],
"x-readme-ref-name": "ApproveRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polygon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Data Network Staking Queue
*Source: [https://docs.p2p.org/reference/data-network-staking-queue.md](https://docs.p2p.org/reference/data-network-staking-queue.md)*
# Get Staking Queue
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/network/staking-queue": {
"get": {
"operationId": "data-network-staking-queue",
"summary": "Get Staking Queue",
"description": "Method to retrieve network staking queue.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum"
],
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"length": {
"type": "number",
"description": "Length of the queue.",
"example": 0.1750427
},
"updatedAt": {
"format": "date-time",
"type": "string",
"description": "Timestamp of the last update to the queue.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"length",
"updatedAt"
],
"x-readme-ref-name": "GetNetworkQueueResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115200
},
"message": {
"type": "string",
"default": "The data for the parameters provided could not be found."
},
"name": {
"type": "string",
"default": "GetNetworkStatsNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetNetworkStatsNotFoundException"
}
]
}
}
},
"examples": {
"GetNetworkStatsNotFoundException": {
"value": {
"error": {
"code": 115200,
"message": "The data for the parameters provided could not be found.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115202
},
"message": {
"type": "string",
"default": "The network staking queue could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetNetworkStakingQueueException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetNetworkStakingQueueException"
}
]
}
}
},
"examples": {
"GetNetworkStakingQueueException": {
"value": {
"error": {
"code": 115202,
"message": "The network staking queue could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Network"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Eth Staking Withdrawal
*Source: [https://docs.p2p.org/reference/eth-staking-withdrawal.md](https://docs.p2p.org/reference/eth-staking-withdrawal.md)*
# Prepare Withdrawal Transaction for EOA Validators
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/direct/tx/withdrawal": {
"post": {
"operationId": "eth-staking-withdrawal",
"summary": "Prepare Withdrawal Transaction for EOA Validators",
"description": "Construct a serialized transaction to initiate the withdrawal process for EOA validators validators, utilizing the functionalities of P2P smart contract.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"pubkeys": {
"description": "List of validators public keys.",
"example": [
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
],
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"pubkeys"
],
"x-readme-ref-name": "UnstakeEthereumRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103114
},
"message": {
"type": "string",
"default": "The withdrawal transaction could not be created because the signature of the deposit data is invalid. Please re-sign the serialized transaction by following https://docs.p2p.org/docs/signing-transaction-eth."
},
"name": {
"type": "string",
"default": "InvalidDepositDataSignException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidDepositDataSignException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103105
},
"message": {
"type": "string",
"default": "The transaction could not be created because the validator public keys provided are invalid or do not exist."
},
"name": {
"type": "string",
"default": "PubkeyDoNotExistsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PubkeyDoNotExistsException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103106
},
"message": {
"type": "string",
"default": "The transaction could not be created because one or more validators are not participating currently in the validator activities."
},
"name": {
"type": "string",
"default": "ValidatorNotActiveException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorNotActiveException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103152
},
"message": {
"type": "string",
"default": "Error while pubkeys has duplicates"
},
"name": {
"type": "string",
"default": "PubkeysDuplicatesException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PubkeysDuplicatesException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidDepositDataSignException": {
"value": {
"error": {
"code": 103114,
"message": "The withdrawal transaction could not be created because the signature of the deposit data is invalid. Please re-sign the serialized transaction by following https://docs.p2p.org/docs/signing-transaction-eth.",
"type": "client"
},
"result": null
}
},
"PubkeyDoNotExistsException": {
"value": {
"error": {
"code": 103105,
"message": "The transaction could not be created because the validator public keys provided are invalid or do not exist.",
"type": "client"
},
"result": null
}
},
"ValidatorNotActiveException": {
"value": {
"error": {
"code": 103106,
"message": "The transaction could not be created because one or more validators are not participating currently in the validator activities.",
"type": "client"
},
"result": null
}
},
"PubkeysDuplicatesException": {
"value": {
"error": {
"code": 103152,
"message": "Error while pubkeys has duplicates",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103104
},
"message": {
"type": "string",
"default": "The Web3 transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "Web3CreateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "Web3CreateTransactionException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103107
},
"message": {
"type": "string",
"default": "The withdrawal transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "WithdrawalTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WithdrawalTransactionException"
}
]
}
}
},
"examples": {
"Web3CreateTransactionException": {
"value": {
"error": {
"code": 103104,
"message": "The Web3 transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"WithdrawalTransactionException": {
"value": {
"error": {
"code": 103107,
"message": "The withdrawal transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Ethereum"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Data Delegator Pool Rewards
*Source: [https://docs.p2p.org/reference/data-delegator-pool-rewards.md](https://docs.p2p.org/reference/data-delegator-pool-rewards.md)*
# Get Delegator Pool Rewards
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/delegator/pool/rewards": {
"get": {
"operationId": "data-delegator-pool-rewards",
"summary": "Get Delegator Pool Rewards",
"description": "Get a list of delegator pool's rewards.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"polkadot",
"kusama"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Pool address in the required network.",
"schema": {
"type": "string"
}
},
{
"name": "delegatorAddress",
"required": false,
"in": "query",
"description": "Delegator address in the required network.",
"schema": {
"type": "string"
}
},
{
"name": "groupBy",
"required": false,
"in": "query",
"description": "
Group the report data:
`stakingPeriod` — aggregate the results by epoch
`day` — aggregate the results by days
`all` — aggregate the results over the entire period
.",
"schema": {
"enum": [
"stakingPeriod",
"day",
"all"
],
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"activeBalance": {
"type": "string",
"description": "Amount of tokens in the stake."
},
"activeBalanceUsd": {
"type": "number",
"description": "Amount of tokens in the stake in USD."
},
"stakingPeriod": {
"type": "number",
"description": "Timestamp of the staking period start in the ISO 8601 format."
},
"stakingPeriodEnd": {
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format."
},
"netRewards": {
"type": "string",
"description": "Reward amount after the pool's commission is charged."
},
"netRewardsUsd": {
"type": "number",
"description": "Reward amount in USD after the pool's commission is charged."
},
"grossRewards": {
"type": "string",
"description": "Reward amount before the pool's commission is charged."
},
"grossRewardsUsd": {
"type": "number",
"description": "Reward amount in USD before the pool's commission is charged."
},
"netApy": {
"type": "number",
"description": "Delegator pool net annual percentage yield (APY)."
},
"grossApy": {
"type": "number",
"description": "Delegator pool gross annual percentage yield (APY)."
},
"tokenPrice": {
"type": "number",
"description": "Token price in USD."
},
"currency": {
"type": "string",
"enum": [
"ETH",
"SOL",
"DOT",
"KSM",
"GLMR",
"VARA",
"ATOM",
"MATIC",
"SUI",
"AVAIL",
"TON",
"NEAR",
"ADA"
],
"description": "Currency of the tokens."
}
},
"required": [
"activeBalance",
"activeBalanceUsd",
"stakingPeriod",
"stakingPeriodEnd",
"netRewards",
"netRewardsUsd",
"grossRewards",
"grossRewardsUsd",
"netApy",
"grossApy",
"tokenPrice",
"currency"
],
"x-readme-ref-name": "DelegatorPoolsRewards"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetDelegatorPoolsRewardsResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115400
},
"message": {
"type": "string",
"default": "The request could not be performed because the delegator address provided is not valid on the specified network. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "InvalidDelegatorPoolsAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidDelegatorPoolsAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidDelegatorPoolsAddressException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the delegator address provided is not valid on the specified network. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115408
},
"message": {
"type": "string",
"default": "The delegator pool summary could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetDelegatorPoolsSummaryException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetDelegatorPoolsSummaryException"
}
]
}
}
},
"examples": {
"GetDelegatorPoolsSummaryException": {
"value": {
"error": {
"code": 115408,
"message": "The delegator pool summary could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Delegator Pool"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Staking Sei
*Source: [https://docs.p2p.org/docs/staking-sei.md](https://docs.p2p.org/docs/staking-sei.md)*
# Getting Started
Staking in the Sei network using the Staking API consists of the following main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
Request examples are provided using [cURL](https://curl.se/).
## 1. Create Stake Transaction
Send a POST request to [/api/v1/sei/\{network}/staking/stake](ref:create-sei-stake-transaction).
Example request (for `atlantic-2` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/sei/atlantic-2/staking/stake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r",
"memo": "This is your memo message",
"amount": 0.00420
}'
```
* `stashAccountAddress` — delegator stash account address which keeps tokens.
* `memo` — arbitrary text data to add to the transactions.
* `amount` — amount of tokens to stake in SEI.
Example response:
```json
{
"error": null,
"result": {
"amount": 0.0042,
"currency": "sei",
"validatorAddress": "cosmosvaloper17lgg03ze9x6xka02fs0hhw4ad4wwg05heqr2y8",
"stashAccountAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r",
"rewardDestinationAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r",
"transactionData": {
"messages": [
{
"typeUrl": "/cosmos.staking.v1beta1.MsgDelegate",
"value": {
"delegatorAddress": "cosmos1y9wefmlpm0djkt8sseeveke0httfukg2a60g0r",
"validatorAddress": "cosmosvaloper17lgg03ze9x6xka02fs0hhw4ad4wwg05heqr2y8",
"amount": {
"denom": "usei",
"amount": "4200"
}
}
}
],
"fee": {
"amount": [
{
"amount": "5953",
"denom": "usei"
}
],
"gas": "238098"
},
"memo": "The message",
"encodedBody": "0a9b010a232f636f736d6f732e7374616b696e672e763162657461312e4d736744656c656761746512740a2d636f736d6f733179397765666d6c706d30646a6b74387373656576656b653068747466756b67326136306730721234636f736d6f7376616c6f70657231376c676730337a65397836786b613032667330686877346164347777673035686571723279381a0d0a057561746f6d120434323030120b546865206d657373616765",
"encodedAuthInfo": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103b0c7ac278e1941ac0b65d6bd45d541cae58aa584058fbbd822311b8718708c0e12040a020801182312130a0d0a057561746f6d1204353935331092c40e"
},
"createdAt": "2023-11-02T11:21:40.810Z"
}
}
```
* `amount` — amount of tokens to stake.
* `currency` — currency of tokens:
* `sei` — Sei native staking token.
* `usei` — 1 SEI = 10⁻⁶ uSEI.
* `msei` — 1 SEI = 10⁻³ mSEI.
* `validatorAddress` — validator address to which tokens are delegated.
* `stashAccountAddress` — delegator stash account address which keeps tokens.
* `rewardDestinationAddress` — reward destination account address.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
`transactionData` is the list of data fields to be used to construct the staking transactions:
* `messages`:
* `typeUrl` — Sei network operation type.
* `delegatorAddress` — delegator address.
* `validatorAddress` — validator address.
* `amount` — amount of tokens to stake.
* `currency` — currency of tokens.
* `fee` — fee charged for the transaction.
* `amount` — amount of tokens.
* `denom` — currency of tokens: `sei`, `usei`, or `msei`.
* `gas` — amount of gas spent for the transaction.
* `memo` — arbitrary text data to add to the transactions.
* `encodedBody` — processable transaction data encoded in the hexadecimal format.
* `encodedAuthInfo` — authorization data, including fee, encoded in the hexadecimal format.
## 2. Sign and Send Transaction
Use `transactionData` to [sign and send](doc:signing-transaction-cosmos) the signed transaction to the Sei network.
To check the transaction status, send a GET request to [/api/v1/sei/\{network}/transaction/status/\{transactionHash}](ref:get-sei-transaction-status).
Example request (for `atlantic-2` network):
```curl
curl --request GET \
--url https://api-test.p2p.org/api/v1/sei/atlantic-2/transaction/status/ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47 \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json'
```
* `transactionHash` — hash of the transaction.
Example response:
```json
{
"error": null,
"result": {
"status": "success",
"blockId": 18575267,
"fee": 0.005952,
"gas": {
"used": 202947,
"wanted": 238047
},
"transactionHash": "ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47"
}
}
```
* `status` — transaction status: `success`, `failed`.
* `blockId` — unique identifier of the block in which the transaction has been included.
* `fee` — total fee in SEI charged for processing the transaction.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `used` — amount of gas spent for the transaction.
* `wanted` — maximum gas limit that the transaction initiator was willing to consume for the transaction.
* `transactionHash` — hash of the transaction.
## What's Next?
* [Sign and Send Transaction](doc:signing-transaction-sei).
* [Withdrawal](doc:withdrawal-sei).
* [Staking API](ref:create-sei-stake-transaction) reference.
---
## Unified Api Sei
*Source: [https://docs.p2p.org/docs/unified-api-sei.md](https://docs.p2p.org/docs/unified-api-sei.md)*
# Sei
In the following guide, the integration process for the `sei` chain is covered. The Sei integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Sei-specific details
>
> * `chain` — always set to `sei` for Sei-related requests.
> * `network` — environment in which the transaction is processed: `pacific-1` or `atlantic-2`.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in SEI.
# Staking Flow
## 1. Create Staking Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `pacific-1` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "sei",
"network": "pacific-1",
"stakerAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp",
"amount": 0.1
}'
```
* `chain` — blockchain network, always set to `sei` for Sei-related requests.
* `network` — environment in which the transaction is processed: `pacific-1` or `atlantic-2`.
* `stakerAddress` — account address initiating the staking transaction.
* `amount` — amount of tokens to stake in SEI, minimum amount is 0.1.
Example response:
```json
{
"error": null,
"result": {
"amount": 0.1,
"stakerAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp",
"unsignedTransactionData": {
"messages": [
{
"typeUrl": "/sei.staking.v1beta1.MsgDelegate",
"value": {
"delegatorAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp",
"validatorAddress": "seivaloper1qmpxlswwk42wya67t7zsaawf3vur03cuevss0h",
"amount": {
"denom": "usei",
"amount": "100000"
}
}
}
],
"fee": {
"amount": [
{
"amount": "4851",
"denom": "usei"
}
],
"gas": "194020"
},
"memo": "abc",
"encodedBody": "0a96010a232f636f736d6f732e7374616b696e672e763162657461312e4d736744656c6567617465126f0a2a7365693138667a67767a79336830713634367771326e777a34327a72743578737279757366386a6d6d70123173656976616c6f70657231716d70786c7377776b3432777961363774377a736161776633767572303363756576737330681a0e0a047573656912063130303030301203616263",
"encodedAuthInfo": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103c0caf89df9997994f61207d69c755060aeadf9cbf1ba3ea3fa9117bdb304414e12040a020801180612120a0c0a047573656912043438353110e4eb0b",
"messageHash": "ef6f9484c2aaf4d27b9b1354e2a52491869f5250746976fcaba3c30f8437ac03"
},
"createdAt": "2025-03-06T12:53:02.657Z",
"extraData": {
"currency": "sei",
"validatorAddress": "seivaloper1qmpxlswwk42wya67t7zsaawf3vur03cuevss0h",
"rewardDestinationAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp"
}
}
}
```
* `amount` — amount of tokens to stake in SEI.
* `stakerAddress` — staking account address receiving the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. It contains the list of data fields to be used to construct the staking transactions:
* `messages`:
* `typeUrl` — Sei network operation type.
* `delegatorAddress` — delegator address.
* `validatorAddress` — validator address.
* `amount` — amount of tokens to stake.
* `denom` — currency of tokens:
* `sei` — SEI native staking token.
* `usei` — 1 SEI = 10⁻⁶ uSEI.
* `msei` — 1 SEI = 10⁻³ mSEI.
* `fee` — fee charged for processing the transaction.
* `amount` — amount of tokens.
* `denom` — currency of tokens: `sei`, `usei`, or `msei`.
* `gas` — amount of gas spent for the transaction.
* `memo` — arbitrary text data to add to the transactions.
* `encodedBody` — processable transaction data encoded in the hexadecimal format.
* `encodedAuthInfo` — authorization data, including fee, encoded in the hexadecimal format.
* `messageHash` — hash of the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `currency` — currency of tokens: `sei`, `usei`, or `msei`.
* `validatorAddress` — validator address to which tokens are delegated.
* `rewardDestinationAddress` — reward destination account address.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction.
To broadcast the signed transaction to the Sei network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request (for `pacific-1` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "sei",
"network": "pacific-1",
"stakerAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp",
"amount": 0.1,
"signedTransaction": "0a9e010a96010a232f636f736d6f732e7374616b696e672e763162657461312e4d736744656c6567617465126f0a2a7365693138667a67767a79336830713634367771326e777a34327a72743578737279757366386a6d6d70123173656976616c6f70657231716d70786c7377776b3432777961363774377a736161776633767572303363756576737330681a0e0a04757365691206313030303030120361626312660a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103c0caf89df9997994f61207d69c755060aeadf9cbf1ba3ea3fa9117bdb304414e12040a020801180612120a0c0a047573656912043438353110e4eb0b1a4012ce8717390c205ea7fc800c1d0aeacc260d558906f2825756cdef24a13daaae57256b6a8b1085ae8af77f8c9a59a83933b9f5a456e5d563f9048ab1bb691036"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — staking account address receiving the staked tokens.
* `amount` — amount of tokens to stake in SEI.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
Example response:
```json
{
"error": null,
"result": {
"status": "success",
"extraData": {
"blockId": 135190135,
"fee": 0.004850999999999999,
"gas": {
"used": 160707,
"wanted": 194020
},
"transactionHash": "76EDCE98041DFA42615DEA1BF483AD4752D2C389B8B312DFEB4F5171F7F57BBD"
}
}
}
```
* `status` — transaction status: `pending`, `success` or `failed`.
* `extraData` — additional transaction details:
* `blockId` — unique identifier of the block in which the transaction has been included.
* `fee` — total fee in SEI charged for processing the transaction.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `used` — amount of gas spent for the transaction.
* `wanted` — maximum gas limit available to consume for the transaction.
* `transactionHash` — hash of the transaction.
# Unstaking Flow
## 1. Create Unstaking Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request (for `pacific-1` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "sei",
"network": "pacific-1",
"stakerAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp"
"extra": {
"amount": 0.1
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiated the staking transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to unstake in SEI, minimum amount is 0.1 SEI.
Example response:
```json
{
"error": null,
"result": {
"unsignedTransactionData": {
"messages": [
{
"typeUrl": "/sei.staking.v1beta1.MsgUndelegate",
"value": {
"delegatorAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp",
"validatorAddress": "seivaloper1qmpxlswwk42wya67t7zsaawf3vur03cuevss0h",
"amount": {
"denom": "usei",
"amount": "100000"
}
}
}
],
"fee": {
"amount": [
{
"amount": "5222",
"denom": "usei"
}
],
"gas": "208859"
},
"memo": "",
"encodedBody": "0a98010a252f636f736d6f732e7374616b696e672e763162657461312e4d7367556e64656c6567617465126f0a2a7365693138667a67767a79336830713634367771326e777a34327a72743578737279757366386a6d6d70123173656976616c6f70657231716d70786c7377776b3432777961363774377a736161776633767572303363756576737330681a0e0a04757365691206313030303030",
"encodedAuthInfo": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103c0caf89df9997994f61207d69c755060aeadf9cbf1ba3ea3fa9117bdb304414e12040a020801180712120a0c0a047573656912043532323210dbdf0c",
"messageHash": "eb685b1e4f0c8fe5fb9c44ec83bc58ca5351756b28a78ec32efa8df7c736f77b"
},
"createdAt": "2025-03-06T12:55:03.838Z",
"extraData": {
"amount": 0.1,
"currency": "sei",
"validatorAddress": "seivaloper1qmpxlswwk42wya67t7zsaawf3vur03cuevss0h",
"stashAccountAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp",
"rewardDestinationAddress": "sei18fzgvzy3h0q646wq2nwz42zrt5xsryusf8jmmp"
}
}
}
```
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. It is the list of data fields to be used to construct the staking transactions.
* `messages`:
* `typeUrl` — Sei network operation type.
* `delegatorAddress` — delegator address.
* `validatorAddress` — validator address.
* `amount` — amount of tokens to unstake.
* `denom` — currency of tokens:
* `sei` — SEI native staking token.
* `usei` — 1 SEI = 10⁻⁶ uSEI.
* `msei` — 1 SEI = 10⁻³ mSEI.
* `fee` — fee charged for processing the transaction.
* `amount` — amount of tokens.
* `denom` — currency of tokens: `sei`, `usei`, or `msei`.
* `gas` — amount of gas spent for the transaction.
* `memo` — arbitrary text data to add to the transactions.
* `encodedBody` — processable transaction data encoded in the hexadecimal format.
* `encodedAuthInfo` — authorization data, including fee, encoded in the hexadecimal format.
* `messageHash` — hash of the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `amount` — amount of tokens to unstake in SEI.
* `currency` — currency of tokens: `sei`, `usei`, or `msei`.
* `validatorAddress` — validator address from which tokens are delegated.
* `stashAccountAddress` — staking account address keeping the staked tokens.
* `rewardDestinationAddress` — rewards destination account address.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Sei-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Transaction Set Feerecipientaddress
*Source: [https://docs.p2p.org/reference/transaction-set-feerecipientaddress.md](https://docs.p2p.org/reference/transaction-set-feerecipientaddress.md)*
# Prepare Change feeRecipientAddress Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/tx/fee-recipient-address": {
"get": {
"operationId": "transaction-set-feeRecipientAddress",
"summary": "Prepare Change feeRecipientAddress Transaction",
"description": "Construct a serialized transaction to set the `feeRecipientAddress` on the SSV cluster.",
"parameters": [
{
"name": "feeRecipientAddress",
"required": true,
"in": "query",
"description": "Eth1 address that receives fee recipient rewards.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"schema": {
"pattern": "^0x[a-fA-F0-9]{40}$",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111108
},
"message": {
"type": "string",
"default": "The set fee recipient address transaction could not be created because an internal server error occurred."
},
"name": {
"type": "string",
"default": "SetFeeRecipientAddressException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SetFeeRecipientAddressException"
}
]
}
}
},
"examples": {
"SetFeeRecipientAddressException": {
"value": {
"error": {
"code": 111108,
"message": "The set fee recipient address transaction could not be created because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Ton Staking Single Nominator Unstake
*Source: [https://docs.p2p.org/reference/ton-staking-single-nominator-unstake.md](https://docs.p2p.org/reference/ton-staking-single-nominator-unstake.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/ton/{network}/staking/single-nominator/unstake": {
"post": {
"operationId": "ton-staking-single-nominator-unstake",
"summary": "Create Unstake Request",
"description": "Create the unstake request transaction in the single nominator pool.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
TON network:
`mainnet` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"publicKey": {
"type": "string",
"description": "Public key of the nominator for the TON network.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"amount": {
"format": "int64",
"type": "integer",
"description": "Amount of tokens to unstake in nanoTONs (1 TON = 10⁹ nanoTONs).",
"example": "200"
},
"walletVersion": {
"type": "string",
"description": "Version of the smart contract used by the wallet in the TON blockchain.",
"example": "V4",
"default": "V4"
}
},
"required": [
"publicKey",
"amount"
],
"x-readme-ref-name": "SingleNominatorUnstakeRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction for the unstake request in the hexadecimal format.",
"example": "b5ee9c7241010101003800006b000010000000000000000001000000039fedeab7a2b56b38f19f60b5b9f70b2f1ba2d89b9c5a756036c7cfad73571fb281887735940193456f7e"
},
"publicKey": {
"type": "string",
"description": "Public key of the nominator for the TON network.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"amount": {
"type": "string",
"description": "Amount of tokens to unstake in TON.",
"example": "2"
}
},
"required": [
"unsignedTransaction",
"publicKey",
"amount"
],
"x-readme-ref-name": "SingleNominatorUnstakeResponse"
}
]
}
}
}
}
}
}
},
"tags": [
"TON"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Getting Started Ssv On Chain
*Source: [https://docs.p2p.org/docs/getting-started-ssv-on-chain.md](https://docs.p2p.org/docs/getting-started-ssv-on-chain.md)*
# Getting started
To start staking on the SSV network using our SSV On-Chain, there are a few essential **prerequisites** to ensure a smooth and efficient setup:
* **Minimum Stake Requirement**: You will need a minimum of 32 ETH for each staking validator you wish to run.
* **API Key Request**: [Get an authentication token](doc:authentication) to start using DVT Staking API.
We created an API endpoint to return the transaction data required to interact with our proxy smart contract. We also provide convenient request examples using [cURL](https://curl.se/) to guide you through the process. While the use of the API method is not mandatory for the smart contract interaction, we recommend it for a faster integration.
> 🚧 Please note
>
> On May 7, 2025, the major Ethereum network upgrade was carried out that brought many benefits for clients who use ETH or SSV validators. **P2P.ORG recommends** upgrading to the `0x02` withdrawal credentials to enhance your functionality. It can be done in two ways:
>
> * By [consolidating multiple existing validators](doc:validator-consolidation) into a single one
> * By [creating a new `0x02`-enabled validator](doc:new-validator-creation) via simplified 3.1 smart contract flow
>
> For more details, see [Pectra Upgrade overview](doc:pectra-upgrade-overview).
>
> However, upgrading to the new address format is not necessary, all existing endpoints remain supported. You can follow the `0x01` creation flow below, if you need fine-grained control over validator count, effective balance per validator, or you intend to manually broadcast deposit transactions.
## Staking via SSV Proxy Smart Contract and API
1. Create a serialized transaction for depositing the stake amount to the SSV proxy smart contract by sending a GET request to [/api/v1/eth/staking/ssv/p2p/deposit](ref:p2p-transaction-deposit).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/ssv/p2p/deposit \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"amount": 32,
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x01",
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
}
'
```
* `amount` — amount of ETH to deposit. The value must be in multiples of 32 ETH.
* `amountPerValidator` — amount of tokens to stake in Gwei per validator. Note that if the amount is more than 32 ETH (1 ETH = 10⁹ Gwei), the `withdrawalCredentialsType` parameter defaults to `0x02`.
* `withdrawalCredentialsType` — withdrawal credentials preferred format: `0x01` or `0x02`.
* `withdrawalAddress` — withdrawal address for the validators.
* `feeRecipientAddress` — Eth1 address that receives the fee recipient rewards.
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f902cf0580021e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060a307b2e1661bcc38d482a69603713baf332ad36adf837392e9f20a96b77a03ca415a46261fc62b8f5d4aa69a0d70e2cf0d23e3396bd387cfde18d392a2c7ba822d3f8a60d075366625dcb3c88cd59ebc8f7ab1fc312c6b8b625a57bf7e1b6e6f000000000000000000000000000000000000000000000000000000000000000178ae581ccc8bdf1fde00cff35b2278e1c10a9ed2fc18632373dac118a03cfacdc0",
"to": "0x681a1b3441c6BFb12f91651EFD9F02c83c070293",
"gasLimit": "0.0000000000001",
"data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060a307b2e1661bcc38d482a69603713baf332ad36adf837392e9f20a96b77a03ca415a46261fc62b8f5d4aa69a0d70e2cf0d23e3396bd387cfde18d392a2c7ba822d3f8a60d075366625dcb3c88cd59ebc8f7ab1fc312c6b8b625a57bf7e1b6e6f000000000000000000000000000000000000000000000000000000000000000178ae581ccc8bdf1fde00cff35b2278e1c10a9ed2fc18632373dac118a03cfacd",
"value": "32.0",
"chainId": 1,
"type": 2,
"maxFeePerGas": "0.00000000000000003",
"maxPriorityFeePerGas": "2"
}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
2. Use `serializeTx` from the previous step to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are depositing the requested stake amount in the Ethereum deposit smart contract by using the SSV proxy smart contract. Also, the smart contract will register the newly created validators on the SSV protocol.
After your deposit is successful, your validator will enter the activation queue and soon start performing the validator tasks. You can check the status of your validator on the [SSV network explorer](https://goerli.explorer.ssv.network/validators).
3. Check the list of validators created via your authentication token and their status by sending a GET request to [/api/v1/eth/staking/ssv/p2p/deposits](ref:p2p-transaction-deposit).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/ssv/p2p/deposits?limit=50&offset=0&type=withdrawalAddress&withdrawalAddress=0xe3bb3cc1fd44fced699e5eae6fbbc643a0fbcca0 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `limit` — number of resources that a single response page contains.
* `offset` — number of resources to exclude from a response.
* `type` — type of filter:
* `withdrawalAddress`
* `withdrawalAddress` — withdrawal address for the validators.
Example response:
```json
{
"error": null,
"result": {
"list": [
{
"deposit": {
"depositId": "",
"transactionHash": "",
"senderAddress": "",
"withdrawalAddress": "0xe3bb3cc1fd44fced699e5eae6fbbc643a0fbcca0",
"feeRecipientAddress": "",
"totalAmount": "",
"unprocessedAmount": "18273"
},
"validator": {
"pubkey": "0xad9049587a26e8db61f6b2443798519a7220bb3dde4b6ec8f4d3ab9c06f48952377ae6869b67e4b9d1549f334caaf5e9",
"status": "unknown",
"amount": "1991"
}
},
{
"deposit": {
"depositId": "",
"transactionHash": "",
"senderAddress": "",
"withdrawalAddress": "0xe3bb3cc1fd44fced699e5eae6fbbc643a0fbcca0",
"feeRecipientAddress": "",
"totalAmount": "",
"unprocessedAmount": "18273"
},
"validator": {
"pubkey": "0xcd5ff4fbeafeb6bcdc5dde3ba41d88638eb7b14e52ee3beaf0d32ae3abb303ff8814258ecaa49c5ed0bd7dd48bb0ca502ac89c0bcd36dc7b01a00b8db1e4adec",
"status": "unknown",
"amount": "2073"
}
}
],
"limit": 50,
"offset": 0,
"totalCount": 17,
"totalAmount": "18273",
"unprocessedAmount": "18273"
}
}
```
* `deposit`:
* `depositId` — unique identifier for the deposit initiated by the user.
* `transactionHash` — hash of the transaction associated with the user's validator deposit.
* `senderAddress` — address used to interact with the SSV proxy smart contract and transfer the requested stake amount.
* `withdrawalAddress` — withdrawal address for the validators.
* `feeRecipientAddress` — the address that receives the fee recipient rewards.
* `totalAmount` — total amount currently staked for the specified deposit ID.
* `unprocessedAmount` — amount associated with validators that are not yet activated for the specified deposit ID
* `validator`:
* `pubkey` — validator public key.
* `status` — current status of the validator
* `amount` — amount of ETH, denominated in gwei, that is being deposited.
* `limit` — number of resources that a single response page contains.
* `offset` — number of resources to exclude from a response.
* `totalCount` — total number of validators relevant to the current request, based on applied filters.
* `totalAmount` — total staked amount for the current request.
* `unprocessedAmount` — cumulative staked amount across all validators that are not yet activated for the current request.
## What's Next?
* [SSV On-Chain](ref:p2p-transaction-deposit) API reference.
---
## Transaction Remove Validator
*Source: [https://docs.p2p.org/reference/transaction-remove-validator.md](https://docs.p2p.org/reference/transaction-remove-validator.md)*
# Prepare removeValidator Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/tx/remove-validator/{id}": {
"get": {
"operationId": "transaction-remove-validator",
"summary": "Prepare removeValidator Transaction",
"description": "Construct a serialized transaction to remove a validator from the cluster.",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "UUID of the SSV request.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
}
},
"required": [
"list"
],
"x-readme-ref-name": "EthereumUnsignedTransactionListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111104
},
"message": {
"type": "string",
"default": "The SSV ID %s provided could not be found. Please specify the correct UUID."
},
"name": {
"type": "string",
"default": "SsvRequestNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SsvRequestNotFoundException"
}
]
}
}
},
"examples": {
"SsvRequestNotFoundException": {
"value": {
"error": {
"code": 111104,
"message": "The SSV ID undefined provided could not be found. Please specify the correct UUID.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111121
},
"message": {
"type": "string",
"default": "The remove validator transaction could not be created because an internal server error occurred."
},
"name": {
"type": "string",
"default": "RemoveValidatorException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "RemoveValidatorException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111127
},
"message": {
"type": "string",
"default": "The request could not be performed because the number of encrypted shardes is not valid. Please try again."
},
"name": {
"type": "string",
"default": "InvalidEncryptedShardesCountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidEncryptedShardesCountException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"RemoveValidatorException": {
"value": {
"error": {
"code": 111121,
"message": "The remove validator transaction could not be created because an internal server error occurred.",
"type": "server"
},
"result": null
}
},
"InvalidEncryptedShardesCountException": {
"value": {
"error": {
"code": 111127,
"message": "The request could not be performed because the number of encrypted shardes is not valid. Please try again.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Ssv On Chain
*Source: [https://docs.p2p.org/docs/withdrawal-ssv-on-chain.md](https://docs.p2p.org/docs/withdrawal-ssv-on-chain.md)*
# Withdrawal
The withdrawal process on the Ethereum network using the SSV On-chain flow can be done by simply:
1. Creating a request to initiate the validator's exit.
After this step, you need to [sign and send](doc:signing-transaction-eth) the transaction to the Ethereum network. Request examples are provided using [cURL](https://curl.se/).
To start the withdrawal process:
1. Create a serialized transaction initiating the validator exit by sending a GET request to [/api/v1/eth/staking/ssv/p2p/withdraw](ref:p2p-transaction-withdraw).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/ssv/p2p/withdraw?withdrawalAddress=0x368F823e4dfe271dc820f4Ea14689917bf8e4a21&pubkeys[]=0x95458df5f24a5354e0fe11fbd36fcf4665e205ecf37264f75b96c04c28f7e8eee732f8b204ead89326277ca693460bfe' \
--header 'accept: application/json'
--header 'Authorization: Bearer '
```
* `withdrawalAddress` — UUID of the SSV request.
* `pubkeys` — list of validators public keys.
Example response:
```curl
{
"error": null,
"result": {
"list": [
{
"serializeTx": "0x02f9021982426880840622063d84062206518398968094e9dfc1850110dadf68402ec6ad2b9bdfb79807338903782dace9d9000000b901e4746bd1000100000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000000000000000251c0000000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000c3b22ead56c5ebdedefa48bd3b494c6af1e97f4f760bcfccf74afd103fa7aeb9da44088fd6ffe5f4bbc085315675c25419b8c85eea02b53d9c48845eb74c0619e4a4f1e606a0229ddf61c40b7931cfdeca72c335632667534489f9076c880d0dd0125db16567e84d0b1dfaa1219c991c4316ddd30ab049b0f9bb9d6a5ff55b370e64b3f607ca826cb804c6378659b3fd9094eafe29eb2527c9d4abe7e717e7c8f2c2fbf57bba3cc35c09f1fa0d33f35e3d3d74f304f93407350089733aed910660e2a9ad0000000000000000000000000000000000000000000000000000000000c0",
"to": "0xE9DfC1850110DadF68402Ec6AD2B9bDfB7980733",
"gasLimit": "10000000",
"data": "0x746bd1000100000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000000000000000251c0000000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000c3b22ead56c5ebdedefa48bd3b494c6af1e97f4f760bcfccf74afd103fa7aeb9da44088fd6ffe5f4bbc085315675c25419b8c85eea02b53d9c48845eb74c0619e4a4f1e606a0229ddf61c40b7931cfdeca72c335632667534489f9076c880d0dd0125db16567e84d0b1dfaa1219c991c4316ddd30ab049b0f9bb9d6a5ff55b370e64b3f607ca826cb804c6378659b3fd9094eafe29eb2527c9d4abe7e717e7c8f2c2fbf57bba3cc35c09f1fa0d33f35e3d3d74f304f93407350089733aed910660e2a9ad0000000000000000000000000000000000000000000000000000000000",
"value": "64000000000000000000",
"chainId": 17000,
"type": 2,
"maxFeePerGas": "102893137",
"maxPriorityFeePerGas": "102893117"
}
]
}
}
```
* `list` includes a list of data fields that contain the following data:
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
2. Use `serializeTx` to [sign and send](https://docs.p2p.org/docs/signing-transaction-eth) the signed transaction to the Ethereum network.
## What's Next?
* [Getting Started](doc:getting-started-ssv).
* [DVT Staking API](ref:introduction-dvt) reference.
---
## Unified Api Aptos
*Source: [https://docs.p2p.org/docs/unified-api-aptos.md](https://docs.p2p.org/docs/unified-api-aptos.md)*
# Aptos
In the following guide, the integration process for the `aptos` chain is covered. The Aptos integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Aptos-specific details
>
> * `chain` — always set to `aptos` for Aptos-related requests.
> * `network` — environment in which the transaction is processed: `testnet` or `mainnet`.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal operations.
> * `amount`— amount of tokens in Octas (1 APT = 10⁸ Octas).
> * `extra.gas` — optional settings for gas management.
> * `signature` — delegator account signature, required for broadcasting transactions.
# Staking Flow
## 1. Create Stake Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "aptos",
"network": "testnet",
"stakerAddress": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad88",
"amount": 11,
"extra":{
"gas": {
"unitPrice": 102,
"maxGasLimit": 1234
}
}
}'
```
* `chain` — blockchain network, always set to `aptos` for Aptos-related requests.
* `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
* `stakerAddress` — `0x`-prefixed Aptos account address, initiating the staking transaction.
* `amount` — amount of tokens to stake in Octas (1 APT = 10⁸ Octas). Note that minimum staking amount for testing is 11 APT, and on `mainnet`, no less than 1 000 000 APT delegation to the validator is required.
* `extra.gas` — optional settings for gas management:
* `unitPrice` — price per unit of gas in Octas for processing the Aptos transaction.
* `maxGasLimit` — maximum gas limit for the transaction.
Example response:
```json
{
"error": null,
"result": {
"amount": 1100000000,
"stakerAddress": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad88",
"unsignedTransactionData": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad8800000000000000000200000000000000000000000000000000000000000000000000000000000000010f64656c65676174696f6e5f706f6f6c096164645f7374616b650002207a2ddb6af66beb0d9987c6c9010cb9053454f067e16775a8ecf19961195c3d280800ab904100000000400d0300000000006400000000000000bd192087970100000200",
"createdAt": "2025-06-19T06:38:37.373Z"
}
}
```
* `amount` — amount of tokens to stake in Octas (1 APT = 10⁸ Octas).
* `stakerAddress` — staking account address receiving the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 or hex-encoded format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in ISO 8601 format.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction using the Aptos-specific signing logic.
To broadcast the signed transaction to the Aptos network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "aptos",
"network": "testnet",
"signedTransaction": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad8800000000000000000200000000000000000000000000000000000000000000000000000000000000010f64656c65676174696f6e5f706f6f6c096164645f7374616b650002207a2ddb6af66beb0d9987c6c9010cb9053454f067e16775a8ecf19961195c3d280800ab904100000000400d0300000000006400000000000000bd192087970100000200",
"stakerAddress": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad88",
"extra": {
"signature": "0x00204a7d68bc540b902995941b77373cd378f39b0e0ebff42566e03774b0ad2285e940cb030ea54fa24986712ffb5c941f3950a2bf1087b2e588c6c3daa08689b5668fbe469a76351101275f694f1ec45cc7d433e103825e55d20ded63cbbcbe344d01"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the staking transaction.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `extra.signature` — delegator signature of the transaction externally produced via the signing code.
Example response:
```json
{
"error": null,
"result": {
"status": "pending",
"extraData": {
"gas": {
"maxGasLimit": 200000,
"unitPrice": 100,
"used": null
},
"createdAt": "2025-06-19T06:56:50.979Z",
"transactionHash": "0x3051a37fdb7a3e6aa8fc0429d2896dff53c36d6da8144e438aa3ba9d9cb60810",
"senderAddress": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad88"
}
}
}
```
* `status` — transaction status: `pending`, `success`, or `failed`.
* `extraData` — additional transaction details:
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `maxGasLimit` — maximum gas limit for the transaction.
* `unitPrice` — price per unit of gas in Octas for processing the Aptos transaction.
* `used` — amount of gas spent for the transaction.
* `createdAt` — timestamp of the transaction in ISO 8601 format.
* `transactionHash` — hash of the transaction.
* `senderAddress` — transaction sender address.
# Unstaking Flow
## 1. Create Unlock Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction)
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "aptos",
"network": "testnet",
"stakerAddress": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad88",
"extra":{
"amount": 1000000000,
"gas": {
"unitPrice": 100,
"maxGasLimit": 1000
}
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the unstaking transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to unlock in Octas (1 APT = 10⁸ Octas).
* `gas` — optional settings for gas management:
* `unitPrice` — price per unit of gas in Octas for processing the Aptos transaction.
* `maxGasLimit` — maximum gas limit for the transaction.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad88",
"unsignedTransactionData": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad8801000000000000000200000000000000000000000000000000000000000000000000000000000000010f64656c65676174696f6e5f706f6f6c06756e6c6f636b0002207a2ddb6af66beb0d9987c6c9010cb9053454f067e16775a8ecf19961195c3d280800ca9a3b00000000e803000000000000640000000000000018e5bf87970100000200",
"createdAt": "2025-06-19T09:33:09.655Z",
"extraData": {
"amount": 1000000000
}
}
}
```
* `stakerAddress` — account address initiating the unstaking transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 or hex-encoded format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in ISO 8601 format.
* `extraData` — additional transaction details:
* `amount` — amount of tokens to unlock in Octas.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Aptos-specific signing logic.
## 3. Create Withdrawal Request
> 📘
>
> Note that it takes up to 30 days to unlock tokens on Aptos network. During this waiting period, unlocked tokens continue earning rewards. Withdrawal is only available after the unlocking period ends.
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "aptos",
"network": "testnet",
"stakerAddress": "0x2588942932015ae61b7e9b77d41f8ed053dde2b341ccaca57bf6a6ecb4fa511a",
"extra":{
"amount": 99,
"gas": {
"unitPrice": 100,
"maxGasLimit": 1000
}
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the withdrawal transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to withdraw in Octas.
* `gas` — optional settings for gas management:
* `unitPrice` — price per unit of gas in Octas for processing the Aptos transaction.
* `maxGasLimit` — maximum gas limit for the transaction.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad88",
"unsignedTransactionData": "0x717b869e7c8d0d29a5065073df84513d373df54ae7ff85775979c9c9f4d2ad8802000000000000000200000000000000000000000000000000000000000000000000000000000000010f64656c65676174696f6e5f706f6f6c0877697468647261770002207a2ddb6af66beb0d9987c6c9010cb9053454f067e16775a8ecf19961195c3d28086300000000000000e80300000000000064000000000000007f06f587970100000200",
"createdAt": "2025-06-19T10:31:11.615Z",
"extraData": {
"amount": 99
}
}
}
```
* `stakerAddress` — account address initiating the withdrawal transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 or hex-encoded format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in ISO 8601 format.
* `extraData` — additional transaction details:
* `amount` — amount of tokens to withdraw in Octas.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Aptos-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Ton Staking Transaction Status
*Source: [https://docs.p2p.org/reference/ton-staking-transaction-status.md](https://docs.p2p.org/reference/ton-staking-transaction-status.md)*
# Get Transaction Status
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/ton/{network}/transactions/status/{transactionHash}": {
"get": {
"operationId": "ton-staking-transaction-status",
"summary": "Get Transaction Status",
"description": "Retrieve a specific transaction from the TON network by its hash.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
TON network:
`mainnet` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
},
{
"name": "transactionHash",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"address": {
"type": "string",
"description": "Staker account address.",
"example": "0QC1f6DghlW6w31D7GWiYt0dZvX1SR3sGAsto_AhdQRFBobh"
},
"lt": {
"type": "string",
"description": "Logical time of the last transaction created by this staker account.",
"example": "27726830000001"
},
"prevTransactionHash": {
"type": "string",
"description": "Hash of the previous transaction.",
"example": "6210303f3cfb630c349b3859d9e367a65a6772938c681774e2a315aa95c80224"
},
"prevTransactionLt": {
"type": "string",
"description": "Logical time of the previous transaction.",
"example": "1234567890abcdef"
},
"now": {
"type": "number",
"description": "Current time on the TON blockchain node.",
"example": 1730905768
},
"outMessagesCount": {
"type": "number",
"description": "Count of output messages sent by the smart contract in the result of this transaction.",
"example": 1
},
"oldStatus": {
"type": "string",
"description": "Staker account status before the transaction execution.",
"example": "active"
},
"endStatus": {
"type": "string",
"description": "Staker account status after the transaction execution.",
"example": "active"
},
"transactionHash": {
"type": "string",
"description": "Transaction hash.",
"example": "2829e4bb8a7b8084040c731a07523d680ce30fecef12f8eec1e409f3c6077a5e"
}
},
"required": [
"address",
"lt",
"prevTransactionHash",
"prevTransactionLt",
"now",
"outMessagesCount",
"oldStatus",
"endStatus",
"transactionHash"
],
"x-readme-ref-name": "StatusResponse"
}
]
}
}
}
}
}
}
},
"tags": [
"TON"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Docgraph Transaction Signing
*Source: [https://docs.p2p.org/docs/docgraph-transaction-signing.md](https://docs.p2p.org/docs/docgraph-transaction-signing.md)*
# Graph Transaction Signing
To sign and broadcast the transaction to the Gprah network, follow these steps:
1. Prepare unsigned transaction in JSON format. Obtain the `unsignedTransactionData` field from the Unified API (staking, approval, unstake, or withdrawal).\
This field contains the full **EIP-1559** transaction as a JSON string.
2. Sign the transaction using the following code:
```typescript
import { ethers } from 'ethers';
// Replace with your wallet mnemonic and Arbitrum RPC URL
const MNEMONIC = '';
const RPC_URL = ''; // e.g., https://arb1.arbitrum.io/rpc
const UNSIGNED_TX_JSON = ``; // Stringified JSON from API
async function main() {
if (!UNSIGNED_TX_JSON || UNSIGNED_TX_JSON.length < 10) {
throw new Error("❌ UNSIGNED_TX_JSON is missing or invalid.");
}
// Parse the unsigned transaction data
const txData = JSON.parse(UNSIGNED_TX_JSON);
// Set up provider and wallet
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const wallet = ethers.Wallet.fromMnemonic(MNEMONIC).connect(provider);
// Prepare the EIP-1559 transaction
const tx: ethers.providers.TransactionRequest = {
from: txData.from,
to: txData.to,
data: txData.data,
nonce: txData.nonce,
gasLimit: ethers.BigNumber.from(txData.gasLimit),
maxFeePerGas: ethers.BigNumber.from(txData.maxFeePerGas),
maxPriorityFeePerGas: ethers.BigNumber.from(txData.maxPriorityFeePerGas),
chainId: txData.chainId,
type: txData.type, // 2 for EIP-1559
};
// Sign the transaction (returns raw transaction hex)
const signedTx = await wallet.signTransaction(tx);
console.log("✅ Signed The Graph (Arbitrum) Tx (hex):");
console.log(signedTx);
}
main().catch(console.error);
```
Upon successful execution, the script prints the signed transaction in hexadecimal format, ready to be broadcasted:
```Text Bash
✅ Signed The Graph (Arbitrum) Tx (hex): 0x...
```
3. Broadcast the transaction to the Graph network by sending a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
## What's Next?
* [Networks Supported](doc:unified-api-networks)
* [Getting Started](doc:unified-api-getting-started)
* [Unified API Reference](ref:unified-create-stake-transaction)
*
---
## Getting Started Data Api
*Source: [https://docs.p2p.org/docs/getting-started-data-api.md](https://docs.p2p.org/docs/getting-started-data-api.md)*
# Getting Started
Staking Data API provides methods to retrieve essential information about network, about validators and delegators within the network.
To start using Staking Data API, [get an authentication token](https://docs.p2p.org/docs/authentication).
> The section provides the examples of how to interact with the API for Ethereum data.
# Using curl commands
Request examples are provided using [cURL](https://curl.se/).
To demonstrate the API usage scenarios, the examples cover:
* retrieving the last staking period,
* fetching active stakes for validators,
* checking validator states,
* obtaining rewards by type.
## Get Last Staking Period
To retrieve the last staking period, send a GET request to [/api/v1/\{network}/data/network/last-staking-period](ref:data-network-last-staking-period).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/ethereum/data/network/last-staking-period \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
Example response:
```json JSON
{
"result": {
"period": 244333,
"updatedAt": "2023-08-24T08:23:18.830Z"
},
"error": {}
}
```
* `period` — last staking period.
* `updatedAt` — timestamp of the last update to the queue.
## Get Delegator Stake
To fetch an active stake for each validator, send a GET request to [/api/v1/\{network}/data/delegator/stakes](ref:data-delegator-stakes). Note that there is a list of additional query params.
Example request:
```curl
curl --request GET \
--url 'https://api.p2p.org/api/v1/ethereum/data/delegator/stakes?startNumber=298991&finishNumber=298991&limit=1000&address=0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb&addressType=deposit' \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `startNumber` — start number of the staking period.
* `finishNumber` — finish number of the staking period.
* `limit` — number of resources that a single response page contains.
* `address` — delegator address in the required network.
* `addressType` — delegator address type in the required network:
* `deposit` — available for the Ethereum network (used by default).
* `withdrawal` — available for the Ethereum network.
* `delegator` — available for the Polygon, Solana, Cosmos, and Sui networks (used by default).
* `stake_account` — available for the Solana.
* `nominator` — available for the Polkadot network (used by default).
* `nominator_reward_account` — available for the Polkadot network.
Example response:
```json JSON
{
"result": {
"limit": 50,
"offset": 0,
"list": [
{
"stakingPeriod": 298991,
"stakingPeriodStart": "2023-11-01T06:43:17.000Z",
"stakingPeriodEnd": "2020-11-01T07:12:27.000Z",
"stake": 1.82282,
"validator": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
}
]
},
"error": {}
}
```
* `limit` — number of resources that a single response page contains, the default value is 50.
* `offset` — number of resources to exclude from the beginning of a response.
* `list`:
* `stakingPeriod` — number of the staking period.
* `stakingPeriodStart` — timestamp of the staking period start in the ISO 8601 format.
* `stakingPeriodEnd` — timestamp of the staking period finish in the ISO 8601 format.
* `stake` — total stake balance of the delegator.
* `validator` — validator address.
## Get Validator State and Statuses
To retrieve validator state, send a GET request to [/api/v1/\{network}/data/validator/state](ref:data-validator-state).
Example request:
```curl
curl --request GET \
--url 'https://api.p2p.org/api/v1/ethereum/data/validator/state?address=0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17' \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `address` — validator address in the required network. For the Ethereum network, it is a public validator key.
Example response:
```json
{
"result": {
"state": "string",
"activatedAt": "string",
"activatedStakingPeriodNum": 0
},
"error": {}
}
```
* `state` — validator state.
* `activatedAt` — timestamp of the validator activated date in the ISO 8601 format.
* `activatedStakingPeriodNum` — timestamp of the validator activated staking period.
You can also retrieve the information about validator statuses by sending a GET request to [/api/v1/\{network}/data/validator/statuses](ref:data-validator-statuses) .
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/ethereum/data/validator/statuses \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
Example response:
```json
{
"result": {
"total": 3,
"by_status": [
{
"pending_initialized": 0,
"pending_queued": 0,
"active_ongoing": 2,
"active_slashed": 0,
"exited_unslashed": 0,
"exited_slashed": 0,
"withdrawal_possible": 1,
"withdrawal_done": 0
}
]
},
"error": {}
}
```
* `total` — total count of validators.
* `by_status`:
* `pending_initialized` — number of validators which are initialized but not yet in the queue for activation.
* `pending_queued` — number of validators that entered a queue for activation.
* `active_ongoing` — number of validators that were activated and currently participate in attesting and proposing blocks.
* `active_slashed` — number of validators that were slashed due to misbehaviors.
* `exited_unslashed` — number of validators that have exited the network without being slashed and are no longer acting as validators.
* `exited_slashed` — number of validators that have exited the network after being slashed and are no longer acting as validators.
* `withdrawal_possible` — number of validators having a non-zero balance.
* `withdrawal_done` — number of validators completed the withdrawal process.
## Get Delegator Rewards
To fetch a list of delegators rewards by type, send a GET request to [/api/v1/\{network}/data/delegator/rewards](ref:data-delegator-rewards). Note that there is a list of additional query params, e.g., grouping the data by date.
Example request:
```bash
curl --request GET \
--url 'https://api.p2p.org/api/v1/ethereum/data/delegator/rewards?startAt=2024-07-01T00%3A00%3A00&finishAt=2024-07-23T00%3A00%3A00&limit=100&address=0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb&addressType=deposit&groupBy=day' \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `startAt` — timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.
* `finishAt` — timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.
* `limit` — number of resources that a single response page contains; from 1 to 1000.
* `address` — delegator address in the required network.
* `addressType` — delegator address type in the required network:
* `deposit` — available for the Ethereum network (used by default).
* `withdrawal` — available for the Ethereum network.
* `delegator` — available for the Polygon, Solana, Cosmos, and Sui networks (used by default).
* `stake_account` — available for the Solana.
* `nominator` — available for the Polkadot network (used by default).
* `nominator_reward_account` — available for the Polkadot network.
* `validatorAddress` — validator address in the required network for this delegator.
* `groupBy` — group the output data:
* `stakingPeriod` — aggregate the results by epoch.
* `day` — aggregate the results by days.
* `all` — aggregate the results over the entire period.
Example response:
```json
{
"result": {
"limit": 50,
"offset": 0,
"list": [
{
"stakingPeriod": 298991,
"stakingPeriodStart": "2023-11-01T06:43:17.000Z",
"stakingPeriodEnd": "2020-11-01T07:12:27.000Z",
"rewards": [
{
"type": "consensus",
"amount": 0.63722,
"currency": "ETH",
"recipient": "string"
}
]
}
]
},
"error": {}
}
"validator": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
```
* `limit` — number of resources that a single response page contains.
* `offset` — number of resources to exclude from the beginning of a response.
* `list`:
* `stakingPeriod` — number of the staking period.
* `stakingPeriodStart` — timestamp of the staking period start in the ISO 8601 format.
* `stakingPeriodEnd` — timestamp of the staking period finish in the ISO 8601 format.
* `rewards`:
* `type` — rewards type: `consensus` or `execution`.
* `amount` — amount of tokens in the stake.
* `currency` — currency of the tokens.
* `recipient` — rewards recipient address.
# Using Python code
This section demonstrates how to use Python with the Staking Data API. The examples for Ethereum data cover:
* fetching the delegator daily rewards,
* retrieving the summary for a delegator and validator.
## Get Delegator Rewards
To fetch the daily rewards for a delegator, use the following code with the API endpoint [/api/v1/\{network}/data/delegator/rewards](ref:data-delegator-rewards):
```python
import requests
import datetime
import pickle
# API endpoint.
API_URL = 'https://api.p2p.org/api/v1/ethereum/data/delegator/rewards'
# Include your Bearer token for authentication and specify the delegator address.
ACCESS_TOKEN = 'YOUR_ACCESS_TOKEN'
DELEGATOR_ADDRESS = 'DELEGATOR_ADDRESS'
def fetch_rewards_for_date(session, date, address):
"""Fetch rewards for a specific date."""
params = {
'startAt': date.strftime('%Y-%m-%dT00:00:00') ,# Start time in the ISO 8601 format for each day.
'finishAt': (date + datetime.timedelta(days=1)).strftime('%Y-%m-%dT00:00:00'), # Finish time in the ISO 8601 format for the next day.
'limit': 1000, # Number of resources per page; the default value is 1000.
'offset': 0, # Number of resources to exclude from the beginning; the default value is 0.
'address': address, # Delegator address in the Ethereum network.
'addressType': 'deposit', # Delegator address type in the required network. For Ethereum it can be `deposit` or `withdrawal`.
'skip': 'validator', # Excludes breakdown by validator from the data report. To include validator, specify the empty value.
'groupBy': 'stakingPeriod' # Group the results by `stakingPeriod`, `day` or `all` (the entire period).
}
rewards = []
while True:
try:
response = session.get(API_URL, params=params)
response.raise_for_status()
result = response.json()
new_rows = result.get('result', {}).get('list', [])
if new_rows:
rewards.extend(new_rows)
params['offset'] += 1000
else:
break
except requests.RequestException as e:
print(f"An error occurred: {e}")
break
return rewards
def main():
# Setup session
session = requests.Session()
session.headers.update({'Authorization': f'Bearer {ACCESS_TOKEN}'})
# Define date range
start_date = datetime.date(year=2024, month=1, day=1)
end_date = datetime.date.today()
date_range = (start_date + datetime.timedelta(days=d) for d in range((end_date - start_date).days + 1))
all_rewards = []
# Fetch rewards for each date
for date in date_range:
print(f"Fetching rewards for {date}")
daily_rewards = fetch_rewards_for_date(session, date, DELEGATOR_ADDRESS)
all_rewards.extend(daily_rewards)
# Save rewards to file
with open('dump.pkl', 'wb') as file:
pickle.dump(all_rewards, file)
# Calculate total amount
total_amount = sum(reward['amount'] for epoch in all_rewards for reward in epoch.get('rewards', []))
print(f"Total Amount: {total_amount}")
if __name__ == '__main__':
main()
```
This script gathers daily rewards data from a start date to the current date, saves the data to a file, and calculates the total rewards amount.
## Get Delegator Summary
To fetch the lifetime stake, rewards, and APY for a delegator, use the following code with the API endpoint [/api/v1/\{network}/data/delegator/summary](ref:data-delegator-summary):
```python
import requests
# API endpoint.
url = "https://api.p2p.org/api/v1/{network}/data/delegator/summary"
# Include your Bearer token for authentication.
headers = {
"Authorization": "Bearer ",
"Content-Type": "application/json"
}
# Specify the following parameters:
params = {
"address": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb", # Delegator address.
"addressType": "deposit", # Delegator address type in the required network. For Ethereum it can be `deposit` or `withdrawal`.
"network": "ethereum", # Network name.
"startAt": "2024-04-17T15:00:00.000Z", # Report data start time in the ISO 8601 format.
"finishAt": "2024-04-19T15:00:00.000Z", # Report data finish time in the ISO 8601 format.
"groupBy": "all", # Aggregate the results by `stakingPeriod` or `day`. To aggregate the results for the entire period, set `all`.
"skip": "validator" # Exclude breakdown by validator from the report. To include validators in the output, remove the parameter or pass an empty value.
}
try:
# Make the request.
response = requests.get(url.format(network=params["network"]), headers=headers, params=params)
# Check the response status.
response.raise_for_status()
# Parse the JSON response.
data = response.json()
# Check if the response contains data.
if data and "result" in data:
print("Delegator Summary:")
print("APY:", data["result"]["list"][0]["apy"])
print("Stake:", data["result"]["list"][0]["stake"], data["result"]["list"][0]["currency"])
print("Rewards:")
for reward in data["result"]["list"][0]["rewards"]:
print("Type:", reward["type"])
print("Amount:", reward["amount"], reward["currency"])
print("---")
else:
print("Empty response received.")
except requests.exceptions.HTTPError as http_err:
print(f"HTTP error occurred: {http_err}")
except requests.exceptions.RequestException as req_err:
print(f"Request exception occurred: {req_err}")
except ValueError as val_err:
print(f"Value error occurred: {val_err}")
except Exception as err:
print(f"Other error occurred: {err}")
```
Example output (with breaking down the result by validators):
```json
APY: 1638378.514999824
Stake: 1411 ETH
Rewards:
Type: consensus
Amount: 5.195236601009028 ETH
---
Type: execution
Amount: 1.188704036616951 ETH
---
```
* `APY` — delegator annual percentage yield (APY).
* `Stake` — total stake balance of the delegator.
* `Rewards`:
* `Type` — rewards type: `consensus` or `execution`.
* `Amount` — amount of tokens in the stake.
## Get Validator Summary
To retrieve the validator summary, use the following code with the API endpoint [/api/v1/\{network}/data/validator/summary](ref:data-validator-summary):
```python
import requests
# API endpoint.
url = "https://api.p2p.org/api/v1/{network}/data/validator/summary"
# Include your Bearer token for authentication.
headers = {
"Authorization": "Bearer ",
"Content-Type": "application/json"
}
# Specify the following parameters:
params = {
"address": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17", # Validator address in the required network. For the Ethereum network, it is a public validator key.
"network": "ethereum", # Network name.
"startAt": "2024-04-17T15:00:00.000Z", # Report data start time in the ISO 8601 format.
"finishAt": "2024-04-19T15:00:00.000Z", # Report data finish time in the ISO 8601 format.
"limit": 50, # Number of resources that a single response page contains; the default value is 50.
"offset": 0 # Number of resources to exclude from the beginning of a response; the default value is 0.
}
try:
# Make the request.
response = requests.get(url.format(network=params["network"]), headers=headers, params=params)
# Check the response status.
response.raise_for_status()
# Parse the JSON response.
data = response.json()
# Check if the response contains data.
if data and "result" in data:
validator_summary = data["result"]
# Print the validator summary information.
print("Validator Summary:")
print("---")
# Iterate over each item in the list.
for item in validator_summary["list"]:
print("Staking Period:", item["stakingPeriod"])
print("Start:", item["stakingPeriodStart"])
print("End:", item["stakingPeriodEnd"])
print("APY:", item["apy"])
print("Stake:", item["stake"], "ETH")
# Print the rewards information.
print("Rewards:")
for reward in item["rewards"]:
print("Amount:", reward["amount"], reward["currency"])
print("---")
else:
print("Empty response received.")
except requests.exceptions.HTTPError as http_err:
print(f"HTTP error occurred: {http_err}")
except requests.exceptions.RequestException as req_err:
print(f"Request exception occurred: {req_err}")
except ValueError as val_err:
print(f"Value error occurred: {val_err}")
except Exception as err:
print(f"Other error occurred: {err}")
```
Example output (without breaking down the results by validators):
```json
Validator Summary:
---
Staking Period: 277903
Start: 2024-04-19 14:59:35
End: 2024-04-19 15:05:59
APY: 0.024850512
Stake: 32.01709 ETH
Rewards:
Amount: 9.683e-06 ETH
---
Staking Period: 277902
Start: 2024-04-19 14:53:11
End: 2024-04-19 14:59:35
APY: 0.024770953
Stake: 32.01708 ETH
Rewards:
Amount: 9.652e-06 ETH
---
```
* `Staking Period` — number of the staking period.
* `Start` and `End` — timestamp of the staking period start and finish in the ISO 8601 format.
* `APY` — validator annual percentage yield (APY).
* `Stake` — total stake balance of the validator.
* `Rewards`:
* `Amount` — amount of tokens in the stake.
# What's Next?
* [Network Data API](doc:network).
* [Validator Data API](doc:validator).
* [Delegator Data API](doc:data-delegator).
---
## Withdrawal Solana
*Source: [https://docs.p2p.org/docs/withdrawal-solana.md](https://docs.p2p.org/docs/withdrawal-solana.md)*
# Withdrawal
The withdrawal process in the Solana network using the Staking API can be done following these steps:
1. Deactivate the Stake Transaction.
2. Withdrawal.
After each operation, you need to [sign and send the transaction](doc:signing-transaction-solana) to the Solana network.
It normally takes up to three days to unstake your Solana. This is because Solana uses a system of epochs, each of which lasts around 2.5 days. In order to ensure fairness and network security when you deactivate your stake, it will remain active for the remainder of the current epoch.
## 1. Deactivate Stake Transaction
1. Send a POST request to [/api/v1/solana/\{network}/staking/deactivate](ref:solana-staking-deactivate).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/solana/testnet/staking/deactivate \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"feePayer": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"stakeAccount": "6ZuLUCwVTvuQJrN1HrpoHJheQUw9Zk8CtiD3CEpHiA9E",
"stakeAuthority": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC"
}'
```
* `feePayer` — account address that will pay the fee for the transaction.
* `stakeAccount` — account address that stores tokens for staking.
* `stakeAuthority` — account address that can perform staking operations with staking account.
Example response:
```json
{
"result": {
"feePayer": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"stakeAccount": "6ZuLUCwVTvuQJrN1HrpoHJheQUw9Zk8CtiD3CEpHiA9E",
"stakeAuthority": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `feePayer` — account address that will pay the fee for the transaction.
* `stakeAccount` — account address that stores tokens for staking.
* `stakeAuthority` — account address that can perform staking operations with the staking account.
* `unsignedTransaction` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
> The transaction exists for one minute.
2. Use `unsignedTransaction` to [sign and send](doc:signing-transaction-solana) the signed transaction to the Solana network.
## 2. Withdrawal
1. Send a POST request to [/api/v1/solana/\{network}/staking/withdraw](ref:solana-staking-withdraw).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/solana/testnet/staking/withdraw \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"feePayer": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"stakeAccount": "6ZuLUCwVTvuQJrN1HrpoHJheQUw9Zk8CtiD3CEpHiA9E",
"withdrawAuthority": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"recipient": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"amount": 1002282880
}'
```
* `feePayer` — account address that will pay the fee for the transaction.
* `stakeAccount` — account address that stores tokens for staking.
* `withdrawAuthority` — account address that can perform withdrawal operations with the staking account.
* `recipient` — account address to which tokens will be sent.
* `amount` — amount of tokens to withdraw in lamports (1 SOl = 10^9 lamports).
Example response:
```json
{
"result": {
"feePayer": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"stakeAccount": "6ZuLUCwVTvuQJrN1HrpoHJheQUw9Zk8CtiD3CEpHiA9E",
"stakeAuthority": "C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC",
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `feePayer` — account address that will pay the fee for the transaction.
* `stakeAccount` — account address that stores tokens for staking.
* `stakeAuthority` — account address that can perform staking operations with the staking account.
* `unsignedTransaction` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
> The transaction exists for one minute.
2. Use `unsignedTransaction` to [sign and send](doc:signing-transaction-solana) the signed transaction to the Solana network.
## What's Next?
* [Staking API](ref:solana-2) reference.
---
## Platform Overview
*Source: [https://docs.p2p.org/docs/platform-overview.md](https://docs.p2p.org/docs/platform-overview.md)*
# Overview
P2P.org provides enterprise-grade APIs that enable businesses to integrate staking operations and analytics across multiple blockchain networks. Our unified platform combines comprehensive staking capabilities with real-time data insights, all through a single, secure interface.
The staking ecosystem is growing rapidly. The staking process can be complex and challenging to navigate for many users. The complexity arises even further when we look at large organizations.
The P2P Staking APIs serve as an integration point for enterprises to access the entire staking ecosystem. The platform provides clients with access to direct staking on multiple blockchains. The product caters to institutional clients, crypto exchanges, crypto wallets, and anyone else who wants to participate in staking.
## Our Products
* **Unified API**: Go multi-chain with one API for your staking needs
* **Staking API**: Direct staking operations across multiple networks
* **Restaking API**: Maximize yield through restaking capabilities
* **DVT Staking**: Distributed validator technology for enhanced rewards with security and reliability
* **Data API**: Analytics and historical staking data
## Use Cases
* Launch staking services on your platform without infrastructure overhead
* Monitor validator performance and network statistics
* Automate staking operations across multiple networks
* Access historical staking data for analytics and reporting
* Implement distributed validation for enhanced security
## Introduction and Showcase of the Unified API
Need help? Contact our [team](https://docs.p2p.org/docs/contacts#/) for dedicated assistance.
---
## Authentication
*Source: [https://docs.p2p.org/docs/authentication.md](https://docs.p2p.org/docs/authentication.md)*
# Authentication
Staking Platform APIs use bearer JSON Web Token (JWT). Each client is assigned a unique authentication token for secure access to the service.
Contact [andre.zommerfelds@p2p.org](mailto:andre.zommerfelds@p2p.org) with your request, and you'll receive your authentication token directly via email or direct message.
Specify the received authentication token when interacting with our APIs. Pass the token in the Authorization header in the following format:
```curl
authorization: Bearer
```
---
## Near Staking Unified Api
*Source: [https://docs.p2p.org/recipes/near-staking-unified-api.md](https://docs.p2p.org/recipes/near-staking-unified-api.md)*
P2P.ORG
---
## Polygon Staking Unstake
*Source: [https://docs.p2p.org/reference/polygon-staking-unstake.md](https://docs.p2p.org/reference/polygon-staking-unstake.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polygon/staking/unstake": {
"post": {
"operationId": "polygon-staking-unstake",
"summary": "Create Unstake Request",
"description": "Unstake tokens.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stakerPublicKey": {
"type": "string",
"description": "Staker public key.",
"example": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
},
"stakeTransactionHash": {
"type": "string",
"description": "Hash of the initial staking transaction.",
"example": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028"
}
},
"required": [
"stakerPublicKey",
"stakeTransactionHash"
],
"x-readme-ref-name": "UnstakeRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polygon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Avail Staking Rebond
*Source: [https://docs.p2p.org/reference/avail-staking-rebond.md](https://docs.p2p.org/reference/avail-staking-rebond.md)*
# Create Rebond Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/staking/direct/rebond": {
"post": {
"operationId": "avail-staking-rebond",
"summary": "Create Rebond Request",
"description": "Rebonding tokens within the Avail network involves the process of re-staking or redelegating tokens that were previously withdrawn from the staking mechanism.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Avail network:
`mainnet` — Avail mainnet.
`testnet` — Avail testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"amount": {
"type": "number",
"description": "Amount of tokens to bond. AVAIL is used for the mainnet network.",
"example": 3
}
},
"required": [
"stashAccountAddress",
"amount"
],
"x-readme-ref-name": "AvailRebondRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xac0406000b0030ef7dba0203ded255321b86f5f975cf04fd0e9d2b1d941469d469dcc93b89441cdfe6c39f7b"
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"amount": {
"type": "number",
"description": "Amount of tokens for bond operations (in usual DOTs/KSMs/WNDs).",
"example": 3
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"unsignedTransaction",
"stashAccountAddress",
"amount",
"createdAt"
],
"x-readme-ref-name": "AvailUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119104
},
"message": {
"type": "string",
"default": "The request could not be performed because the ledger address could not be found."
},
"name": {
"type": "string",
"default": "LedgerNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "LedgerNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119109
},
"message": {
"type": "string",
"default": "The request could not be performed because the requested amount exceeds the unbonded amount."
},
"name": {
"type": "string",
"default": "NotEnoughPendingAmountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NotEnoughPendingAmountException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119105
},
"message": {
"type": "string",
"default": "The request could not be performed because the controller address does not correspond to the provided one."
},
"name": {
"type": "string",
"default": "WrongControllerException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongControllerException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 119101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Avail address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"LedgerNotFoundException": {
"value": {
"error": {
"code": 119104,
"message": "The request could not be performed because the ledger address could not be found.",
"type": "client"
},
"result": null
}
},
"NotEnoughPendingAmountException": {
"value": {
"error": {
"code": 119109,
"message": "The request could not be performed because the requested amount exceeds the unbonded amount.",
"type": "client"
},
"result": null
}
},
"WrongControllerException": {
"value": {
"error": {
"code": 119105,
"message": "The request could not be performed because the controller address does not correspond to the provided one.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119129
},
"message": {
"type": "string",
"default": "The rebond request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "RebondException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "RebondException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"RebondException": {
"value": {
"error": {
"code": 119129,
"message": "The rebond request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Data Delegator Total Rewards
*Source: [https://docs.p2p.org/reference/data-delegator-total-rewards.md](https://docs.p2p.org/reference/data-delegator-total-rewards.md)*
# Get Total Delegator Rewards
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/delegator/total-rewards": {
"get": {
"operationId": "data-delegator-total-rewards",
"summary": "Get Total Delegator Rewards",
"description": "Get total delegator rewards.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Delegator address in the required network.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stakingPeriod": {
"type": "number",
"description": "Number of the staking period."
},
"stakingPeriodStart": {
"type": "string",
"description": "Timestamp of the staking period start in the ISO 8601 format."
},
"stakingPeriodEnd": {
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format."
},
"rewards": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Reward type.",
"enum": [
"consensus",
"execution"
]
},
"amount": {
"type": "number",
"format": "float",
"description": "Amount of tokens in the stake."
},
"amountUsd": {
"type": "number",
"format": "float",
"description": "Amount of tokens in the stake in USD."
},
"currency": {
"type": "string",
"enum": [
"ETH",
"SOL",
"DOT",
"KSM",
"GLMR",
"VARA",
"ATOM",
"MATIC",
"SUI",
"AVAIL",
"TON",
"NEAR",
"ADA"
],
"description": "Currency of the tokens."
},
"recipient": {
"type": "string",
"description": "Rewards recipient address."
}
},
"required": [
"type",
"amount",
"amountUsd",
"currency",
"recipient"
],
"x-readme-ref-name": "Reward"
}
},
"validator": {
"type": "string",
"description": "Validator address."
},
"notFinalized": {
"type": "boolean",
"description": "Boolean flag indicating whether the rewards for the specified epoch have been finalized."
}
},
"required": [
"stakingPeriod",
"stakingPeriodStart",
"stakingPeriodEnd",
"rewards"
],
"x-readme-ref-name": "DelegatorRewards"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetDelegatorRewardsResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124108
},
"message": {
"type": "string",
"default": "The request could not be performed because the delegator address provided is not valid."
},
"name": {
"type": "string",
"default": "InvalidDelegatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidDelegatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidDelegatorAddressException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the delegator address provided is not valid on the specified network. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115406
},
"message": {
"type": "string",
"default": "The request could not be performed because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetDelegatorAutostakingDataException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetDelegatorAutostakingDataException"
}
]
}
}
},
"examples": {
"GetDelegatorAutostakingDataException": {
"value": {
"error": {
"code": 115406,
"message": "The request could not be performed because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Delegator"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Ton Staking Ton Whales Stake
*Source: [https://docs.p2p.org/reference/ton-staking-ton-whales-stake.md](https://docs.p2p.org/reference/ton-staking-ton-whales-stake.md)*
# Create Staking Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/ton/{network}/staking/ton-whales/stake": {
"post": {
"operationId": "ton-staking-ton-whales-stake",
"summary": "Create Staking Request",
"description": "Create the staking request transaction in the TON Whales pool.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
TON network:
`mainnet` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"publicKey": {
"type": "string",
"description": "Public key of the nominator for the TON network.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"amount": {
"format": "int64",
"type": "integer",
"description": "Amount of tokens to stake in nanoTONs (1 TON = 10⁹ nanoTONs).",
"example": "20000000000"
},
"walletVersion": {
"type": "string",
"description": "Version of the smart contract used by the wallet in the TON blockchain.",
"example": "V4",
"default": "V4"
}
},
"required": [
"publicKey",
"amount"
],
"x-readme-ref-name": "TonWhalesStakeRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction for the staking request in the hexadecimal format.",
"example": "b5ee9c7241010101003000005c00000000000000039fedeab7a2b56b38f19f60b5b9f70b2f1ba2d89b9c5a756036c7cfad73571fb28188ee6b2800b10cbe42"
},
"poolAddress": {
"type": "string",
"description": "Nominator pool address in the TON network.",
"example": "kQDr9Sq482A6ikIUh5mUUjJaBUUJBrye13CJiDB-R31_l7mg"
},
"walletVersion": {
"type": "string",
"description": "Version of the smart contract used by the wallet in the TON blockchain.",
"example": "V4"
},
"stakerAddress": {
"type": "string",
"description": "Main account address of the bounceable type which keeps tokens.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"publicKey": {
"type": "string",
"description": "Public key of the nominator for the TON network.",
"example": "7031f1dcbe0f670daf4094d04ff9a7947bc4ac9174a7d470255d1a664e20b7c6"
},
"amount": {
"type": "string",
"description": "Amount of tokens to stake in TON.",
"example": 2
}
},
"required": [
"unsignedTransaction",
"poolAddress",
"walletVersion",
"stakerAddress",
"publicKey",
"amount"
],
"x-readme-ref-name": "TonWhalesStakeResponse"
}
]
}
}
}
}
}
}
},
"tags": [
"TON"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## P2P Transaction Deposit
*Source: [https://docs.p2p.org/reference/p2p-transaction-deposit.md](https://docs.p2p.org/reference/p2p-transaction-deposit.md)*
# Prepare SSV Proxy Staking Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/p2p/deposit": {
"get": {
"operationId": "p2p-transaction-deposit",
"summary": "Prepare SSV Proxy Staking Transaction",
"description": "Construct a serialized transaction to deposit ETH to the SSV proxy smart contract.",
"parameters": [
{
"name": "amount",
"required": true,
"in": "query",
"description": "Amount of ETH to deposit.",
"example": 32,
"schema": {
"type": "number"
}
},
{
"name": "amountPerValidator",
"required": false,
"in": "query",
"description": "Amount of tokens to stake in Gwei per validator.",
"example": "32000000000",
"schema": {
"type": "string"
}
},
{
"name": "withdrawalCredentialsType",
"required": false,
"in": "query",
"description": "Withdrawal credentials type.",
"example": "0x02",
"schema": {
"enum": [
"0x01",
"0x02"
],
"type": "string"
}
},
{
"name": "withdrawalAddress",
"required": true,
"in": "query",
"description": "Withdrawal address for the validators.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"schema": {
"pattern": "^0x[a-fA-F0-9]{40}$",
"type": "string"
}
},
{
"name": "controllerAddress",
"required": false,
"in": "query",
"description": "Controller address for the validators.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"schema": {
"pattern": "^0x[a-fA-F0-9]{40}$",
"type": "string"
}
},
{
"name": "feeRecipientAddress",
"required": false,
"in": "query",
"description": "Fee recipient address.",
"example": "0x53da3c92fCCEb0CFE1764f65DDfF1564A2b15585",
"schema": {
"pattern": "^0x[a-fA-F0-9]{40}$",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111120
},
"message": {
"type": "string",
"default": "The deposit transaction could not be created because an internal server error occurred."
},
"name": {
"type": "string",
"default": "DepositException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "DepositException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"DepositException": {
"value": {
"error": {
"code": 111140,
"message": "Failed to create P2P SSV deposit transaction",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"P2P SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Avail
*Source: [https://docs.p2p.org/docs/withdrawal-avail.md](https://docs.p2p.org/docs/withdrawal-avail.md)*
# Withdrawal
The withdrawal process in the Avail network using the Staking API can be done following these steps:
1. Create Unbond Request: unbond tokens within the Avail network that were previously staked or bonded.
> It takes 28 days to unbond on Avail mainnet.
2. Withdraw Unbonded Request: withdraw tokens within the Avail network that were previously unbonded. Note that this request is available after the unbond period.
# Staking directly
## 1. Create Unbond Request
1. Send a POST request to [/api/v1/avail/\{network}/staking/direct/unbond](ref:avail-staking-unbond).
Example request (for `testnet`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/testnet/staking/unbond \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount": 1000
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `amount` — amount of tokens to unbond. AVAIL is used for the mainnet network.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount":1000,
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `amount` — amount of tokens for bond operations. AVAIL is used for the mainnet network.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
## 2. Withdraw Unbonded Request
1. Send a POST request to [/api/v1/avail/\{network}/staking/direct/withdraw-unbonded](ref:avail-staking-withdrawunbonded).
Example request (for `testnet`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/testnet/staking/withdrawal-unbonded \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
# Staking via a nomination pool
## 1\. Create Unbond Request
1. Send a POST request to [/api/v1/avail/\{network}/staking/pool/unbond](avail-pool-unbond).
Example request (for `testnet`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/testnet/staking/pool/unbond \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount": 3
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `amount` — amount of tokens to unbond. AVAIL is used for the mainnet network.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"amount": 3,
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `amount` — amount of tokens for bond operations. AVAIL is used for the mainnet network.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
## 2\. Withdraw Unbonded Request
1. Send a POST request to [/api/v1/avail/\{network}/staking/pool/withdraw-unbonded](avail-pool-withdraw-unbonded).
Example request (for `testnet`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/avail/testnet/staking/withdrawal-unbonded \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"poolId": "45"
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `poolId` — ID of the nomination pool in which you participate in.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-avail) the `unsignedTransaction` to the Avail network.
## What's Next?
* [Getting Started](doc:staking-avail).
* [Staking API](ref:avail-transaction-status) reference.
---
## Unified Api The Graph
*Source: [https://docs.p2p.org/docs/unified-api-the-graph.md](https://docs.p2p.org/docs/unified-api-the-graph.md)*
# The Graph
In the following guide, the integration process for the `grt` chain is covered. The Graph integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Graph-specific details
>
> * `chain` — always set to `grt` for Graph-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` only.
> * `stakerAddress` — Ethereum-compatible account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in GRT.
# Staking Flow
## 1. Create Approval Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "grt",
"network": "mainnet",
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"amount": "1",
"extra": {
"operationType": "approve"
}
}'
```
* `chain` — blockchain network, always set to `grt` for The Graph-related requests.
* `network` — environment in which the transaction is processed: `mainnet` only.
* `stakerAddress` — Ethereum-compatible account address initiating the approval transaction.
* `amount` — amount of tokens to approve in GRT. Minimum amount is 1 GRT.
* `extra` — additional request parameters:
* `operationType` — type of operation; set to `approve` to approve token transferring.
Example response:
```json
{
"error": null,
"result": {
"amount": 1,
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"unsignedTransactionData": "{\"from\":\"0x368F823e4dfe271dc820f4Ea14689917bf8e4a21\",\"gasLimit\":\"0x012bee\",\"to\":\"0x9623063377AD1B27544C965cCd7342f7EA7e88C7\",\"data\":\"0x095ea7b3...\",\"nonce\":13,\"type\":2,\"maxFeePerGas\":\"0x01312d00\",\"maxPriorityFeePerGas\":\"0x00\",\"chainId\":42161}",
"createdAt": "2025-05-29T00:19:57.734Z",
"extraData": {
"transactionId": "d3e006d5-3652-4265-b54b-dcff52753622",
"stakeId": "5eacf5b6-a366-4376-beab-84e50c426a31",
"gasEstimate": {
"amount": "0.000001535640000000",
"gasLimit": "76782"
}
}
}
}
```
* `amount` — amount of tokens to approve in GRT.
* `stakerAddress` — Ethereum-compatible account address initiating the approval transaction.
* `unsignedTransactionData` — unsigned transaction in JSON format ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this session.
* `stakeId` — unique identifier of the approval request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated fee in ETH for processing the transaction.
* `gasLimit` — maximum gas limit for the transaction.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction.
To broadcast the signed transaction to the Graph network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "grt",
"network": "mainnet",
"signedTransaction": "",
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"extra": {
"transactionId": "d3e006d5-3652-4265-b54b-dcff52753622"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `stakerAddress` — Ethereum-compatible account address initiating the transaction.
* `extra` — additional request parameters:
* `transactionId` — unique identifier of the approval transaction.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"transactionHash": "0x8592d8d4657b735b3662132c0f7b271f49796a8a716ae81bc448513bcefc880f"
}
}
}
```
* `extraData` — additional transaction details:
* `transactionHash` — transaction hash.
## 3. Create Delegate Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "grt",
"network": "mainnet",
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"amount": "1"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — Ethereum-compatible account address initiating the staking transaction.
* `amount` — amount of tokens to delegate in GRT. Minimum amount is 1 GRT.
Example response:
```json
{
"error": null,
"result": {
"amount": 1,
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"unsignedTransactionData": "{\"from\":\"0x368F823e4dfe271dc820f4Ea14689917bf8e4a21\",\"gasLimit\":\"0x01f998\",\"to\":\"0x00669A4CF01450B64E8A2A20E9b1FCB71E61eF03\",\"data\":\"0x026e402b...\",\"nonce\":15,\"type\":2,\"maxFeePerGas\":\"0x014f4420\",\"maxPriorityFeePerGas\":\"0x00\",\"chainId\":42161}",
"createdAt": "2025-05-29T00:28:32.621Z",
"extraData": {
"transactionId": "1a605e71-ecae-4b50-b202-092b163a1b0f",
"stakeId": "2a0269a7-6aeb-42e5-8f46-2f8fb69d48ac",
"gasEstimate": {
"amount": "0.000002843879904000",
"gasLimit": "129432"
}
}
}
}
```
* `amount` — amount of tokens to delegate in GRT.
* `stakerAddress` — Ethereum-compatible account address initiating the staking transaction.
* `unsignedTransactionData` — unsigned transaction in JSON format ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this staking session.
* `stakeId` — unique identifier of the staking request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated fee in ETH for processing the transaction.
* `gasLimit` — maximum gas limit for the transaction.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Graph-specific signing logic.
# Unstaking Flow
## 1. Create Undelegate Request
> 🚧
>
> Note that currently only full unstake is supported, partial withdrawals are unavailable. Regardless of the amount specified, the entire stake is removed.
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "grt",
"network": "mainnet",
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"extra": {
"amount": 1
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — Ethereum-compatible account address initiating the unstaking transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to unstake in GRT; to be ignored since only full unstake is available.
Example response:
```json
{
"error": null,
"result": {
"amount": 1,
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"unsignedTransactionData": "{\"from\":\"0x368F823e4dfe271dc820f4Ea14689917bf8e4a21\",\"gasLimit\":\"0x01b174\",\"to\":\"0x00669A4CF01450B64E8A2A20E9b1FCB71E61eF03\",\"data\":\"0x4d99dd16...\",\"nonce\":16,\"type\":2,\"maxFeePerGas\":\"0x01de5520\",\"maxPriorityFeePerGas\":\"0x00\",\"chainId\":42161}",
"createdAt": "2025-05-29T00:30:26.502Z",
"extraData": {
"transactionId": "57481121-14fa-4c31-ab29-13b80cf26242",
"stakeId": "7763655a-6e2b-466c-8c9f-997e848a5787",
"gasEstimate": {
"amount": "0.000003478499472000",
"gasLimit": "110964"
}
}
}
}
```
* `amount` — amount of tokens to unstake in GRT; to be ignored since only full unstake is available.
* `stakerAddress` — Ethereum-compatible account address initiating the unstaking transaction.
* `unsignedTransactionData` — unsigned transaction in JSON format ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this unstaking session.
* `stakeId` — unique identifier of the unstaking request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated fee in ETH for processing the transaction.
* `gasLimit` — maximum gas limit for the transaction.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Graph-specific signing logic.
## 3. Create Withdrawal Request
> 📘
>
> Note that the withdrawal is available only after the unbonding period of 28 days ends.
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "grt",
"network": "mainnet",
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"extra": {}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — Ethereum-compatible account address initiating the withdrawal transaction.
Example response:
```json
{
"error": null,
"result": {
"amount": 1,
"stakerAddress": "0x368f823e4dfe271dc820f4ea14689917bf8e4a21",
"unsignedTransactionData": "{\"from\":\"0x368F823e4dfe271dc820f4Ea14689917bf8e4a21\",\"gasLimit\":\"0x01b174\",\"to\":\"0x00669A4CF01450B64E8A2A20E9b1FCB71E61eF03\",\"data\":\"0x4d99dd16...\",\"nonce\":16,\"type\":2,\"maxFeePerGas\":\"0x01de5520\",\"maxPriorityFeePerGas\":\"0x00\",\"chainId\":42161}",
"createdAt": "2025-05-29T00:30:26.502Z",
"extraData": {
"transactionId": "57481121-14fa-4c31-ab29-13b80cf26242",
"stakeId": "7763655a-6e2b-466c-8c9f-997e848a5787",
"gasEstimate": {
"amount": "0.000003478499472000",
"gasLimit": "110964"
}
}
}
}
```
* `amount` — amount of tokens to withdraw in GRT.
* `stakerAddress` — Ethereum-compatible account address initiating the withdrawal transaction.
* `unsignedTransactionData` — unsigned transaction in JSON format ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this withdrawal session.
* `stakeId` — unique identifier of the withdrawal request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated fee in ETH for processing the transaction.
* `gasLimit` — maximum gas limit for the transaction.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Graph-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Planning Considerations
*Source: [https://docs.p2p.org/docs/planning-considerations.md](https://docs.p2p.org/docs/planning-considerations.md)*
# Integration Planning Guide
Before starting your integration with P2P.org's APIs, it's important to understand the different approaches available and their implications. This guide will help you choose the right integration path and plan your development effectively.
## Integration Approach
| | Unified API (recommended) | Staking API |
| :------------------------- | :------------------------------- | :---------------------------------------- |
| Estimated Integration Time | \<1 week for 10+ networks | \<1 week for a single network |
| Network Support | Single endpoint for all networks | Network-specific endpoints |
| Customization | Standard options | More control over the staking flow |
| Development Complexity | Low - standardized requests | Medium - network-specific implementations |
| Best For | Quick multi-chain integration | Single blockchain implementation |
## Integration Timeline
### Phase 1: Planning (estimation: \<1 week)
* Choose between [Unified API](https://docs.p2p.org/docs/unified-api-overview) or [Staking API](https://docs.p2p.org/docs/staking-overview), or other APIs (Restaking API, DVT API)
* Define required networks and features (see [Networks Supported](https://docs.p2p.org/docs/networks-supported))
* Check existing code [Recipes](https://docs.p2p.org/recipes)
### Phase 2: Development
#### Option 1: Unified API (estimation: \<1 week for 10+ networks)
* Implement [authentication](https://docs.p2p.org/docs/authentication)
* Integrate single endpoint for all networks
* Test with multiple networks
#### Option 2: Staking API (estimation: \<1 week for a single network)
* Implement [authentication](https://docs.p2p.org/docs/authentication)
* Set up network-specific integrations
* Implement advanced features for each network individually
### Phase 3: Testing & Production Launch (estimation: \~1 week)
* Production credentials setup
* End-to-end testing
* Monitoring implementation
Need help planning your integration? Contact our [team](https://docs.p2p.org/docs/contacts) for guidance.
---
## Eth Eigen Start Checkpoint
*Source: [https://docs.p2p.org/reference/eth-eigen-start-checkpoint.md](https://docs.p2p.org/reference/eth-eigen-start-checkpoint.md)*
# Start Checkpoint
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/eigenlayer/tx/start-checkpoint": {
"post": {
"operationId": "eth-eigen-start-checkpoint",
"summary": "Start Checkpoint",
"description": "Construct a serialized transaction to start a checkpoint, initiating the process of proving the validator with verified withdrawal credentials is still active.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"eigenPodOwnerAddress": {
"type": "string",
"description": "Owner of the EigenPod address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
}
},
"required": [
"eigenPodOwnerAddress"
],
"x-readme-ref-name": "EigenPodOwnerAddressRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103104
},
"message": {
"type": "string",
"default": "The Web3 transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "Web3CreateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "Web3CreateTransactionException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"Web3CreateTransactionException": {
"value": {
"error": {
"code": 103104,
"message": "The Web3 transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"EigenLayer"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Sui Transactio Get Stake List
*Source: [https://docs.p2p.org/reference/sui-transactio-get-stake-list.md](https://docs.p2p.org/reference/sui-transactio-get-stake-list.md)*
# Get Stake List
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/sui/{network}/transaction/stake-list/{address}": {
"get": {
"operationId": "sui-transactio-get-stake-list",
"summary": "Get Stake List",
"description": "Retrieve a list of stakes for account address specified.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Sui network:
`mainnet` — Sui mainnet.
`testnet` — Sui testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
},
{
"name": "address",
"required": true,
"in": "path",
"description": "Staker account address.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {},
"x-readme-ref-name": "GetStakeListResponseDto"
}
]
}
}
}
}
}
}
},
"tags": [
"Sui"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Staking Ethereum
*Source: [https://docs.p2p.org/docs/staking-ethereum.md](https://docs.p2p.org/docs/staking-ethereum.md)*
# Getting Started
To start staking on the Ethereum network using the Staking API:
1. Create Staking Request: set up nodes for staking using P2P infrastructure.
2. Check Request Status: check the status of the node set-up operation.
3. Prepare Staking Transaction: construct a serialized transaction to deposit the stake amount with a smart contract.
[Get an authentication token](doc:authentication) to start using Staking API.
Request examples are provided using [cURL](https://curl.se/).
> 🚧 Please note
>
> On May 7, 2025, the major Ethereum network upgrade was carried out that brought many benefits for clients who use ETH or SSV validators. **P2P.ORG recommends** upgrading to the `0x02` withdrawal credentials to enhance your functionality. It can be done in two ways:
>
> * By [consolidating multiple existing validators](doc:validator-consolidation) into a single one
> * By [creating a new `0x02`-enabled validator](doc:new-validator-creation) via simplified 3.1 smart contract flow
>
> For more details, see [Pectra Upgrade overview](doc:pectra-upgrade-overview).
>
> However, upgrading to the new address format is not necessary, all existing endpoints remain supported. You can follow the `0x01` creation flow below, if you need fine-grained control over validator count, effective balance per validator, or you intend to manually broadcast deposit transactions.
# 1. Create Staking Request
1. Prepare`id` that is an arbitrary UUID. Generate it in one of the following ways:
* [Online UUID Generator](https://www.uuidgenerator.net/)
* [uuid npm package](https://www.npmjs.com/package/uuid)
2. Set up staking nodes through the P2P infrastructure by sending a POST request to [/api/v1/eth/staking/direct/nodes-request/create](ref:eth-nodes-request-create). Use [https://api-test.p2p.org](https://api-test.p2p.org) for testing or [https://api.p2p.org](https://api.p2p.org) for production.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/nodes-request/create \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"id": "3611b95c-e1b3-40c0-9086-3de0a4379943",
"type": "REGULAR",
"validatorsCount": 2,
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x01",
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"eigenPodOwnerAddress": "",
"controllerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x53da3c92fCCEb0CFE1764f65DDfF1564A2b15585",
"nodesOptions": {
"location": "any",
"relaysSet": ""
}
}
'
```
* `id` — arbitrary UUID. You can later use that UUID to check the status of the set-up operation.
* `type` — staking operation type:
* `REGULAR` — default value for native staking transactions. Set the `REGULAR` operation type for this flow.
* `RESTAKING` — value that is used to initiate a [restaking operation](doc:restaking-overview) with the EigenPod address.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `amountPerValidator` — amount of tokens to stake in Gwei per validator. Note that if the amount is more than 32 ETH (1 ETH = 10⁹ Gwei), the `withdrawalCredentialsType` parameter defaults to `0x02`.
* `withdrawalCredentialsType` — withdrawal credentials preferred format: `0x01` or `0x02`.
* `withdrawalAddress` — withdrawal address for the validators.
* `eigenPodOwnerAddress` — owner of the EigenPod address. Used in the [restaking flow](doc:restaking-eth).
* `feeRecipientAddress` — fee recipient address.
* `controllerAddress` — controller address for the validators.
* `nodesOptions`:
* `location` — node location. Currently, only `any` is supported.
* `relaysSet` — Miner Extractable Value (MEV) relay selection.
Example response:
```json
{
"error": null,
"result": true
}
```
# 2) Check Request Status
Check the status of the node set-up operation by sending a GET request to [/api/v1/eth/staking/direct/nodes-request/status/\{id}](ref:eth-nodes-request-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/direct/nodes-request/status/3611b95c-e1b3-40c0-9086-3de0a4379943 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `id` — UUID that was specified in the node set-up request.
Example response:
```json
"error": null,
"result": {
"status": "ready",
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x01",
"depositData": [
{
"pubkey": "0xac1e9969d7b87f3102549ab41558136674a7306b85b9f73cfbd7d9fdb7db85724569da3ebd4d7de9689f6ac058d7e2a3",
"signature": "0xb656f9c771166c82a7891b930e6a920878d9736eb3f9f241753a15ea69d8e2f20a3740dfaf546c70e31bd323e14b341205d04e3227dd4cf2923644a375f6792875ac02c5f256f7a17c96b09bafcbce7e4443e1862356b1e90d78875d78e9a742",
"withdrawalCredentials": "0100000000000000000000005cef11327af4104ba0f8a82fbb8628caee7cb1e3",
"amount": 32000000000,
"depositDataRoot": "0xba013b4950b9aff0c3c19017ec5b6e0ed5b957b36f6ff03a545e5cc5605baff8",
"depositMessageRoot": "6a572503239cd1f11998af7901c0947fe36eb8efec080f22598d607d3938c1a8",
"forkVersion": "10000910",
"eth2NetworkName": "hoodi",
"depositCliVersion": "2.7.0"
},
{
"pubkey": "0xbe5E9c3Bb9eba1BF4C5eC1c1cbcF85ee2CE2fEC66Ce5460C23eF82332A044FDCabF7011F588CCbD77E73CCe6c4accDF0",
"signature": "0x83D2E925AEAEdcB18db983Bd447db0BFc1Ee9a6Ead118E5BEfeBcb24BA8C0efd3BD19Cb1cE8e807Fc980a67bBbf8b11e039efe2DB71fcdF096fccac5B04dF80f6a1804cd8d492455D30abE27FcDbDA78AFE61856cad65ffF5cA48Ed4776edd88",
"withdrawalCredentials": "010000000000000000000000515ea819fde1c0d36eb8e78e9a69dbf8e4a21",
"amount": 32000000000,
"depositDataRoot": "0x53da3c92fCCEb0CFE1764f65DDfF1564A2b15585",
"depositMessageRoot": "0x2b1c6bbdeadb0b23ca8260a819fde1c0b0347b0fd42c33a9b2513b36d6521dc6",
"forkVersion": "10000910",
"eth2NetworkName": "hoodi",
"depositCliVersion": "2.7.0"
}
]
}
}
```
* `status` — current status of the nodes request:
* `init` — node request was created.
* `processing` — node request is in progress.
* `ready` — backend has the deposit data for the node request.
* `cancel` — something went wrong, and the deposit data was not created.
* `amountPerValidator` — amount of tokens to stake in Gwei per validator.
* `withdrawalCredentialsType` — withdrawal credentials preferred format: `0x01` or `0x02`.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `withdrawalCredentials`— withdrawal address credentials, passed in the expected format by the Ethereum deposit smart contract.
* `amount` — amount of ETH, denominated in Gwei, that is being deposited.
* `depositDataRoot` — SHA-256 hash of the SSZ-encoded `depositData` object. Used as a protection against malformed input.
* `depositMessageRoot` — cryptographic hash of the Merkle tree’s root, ensuring the integrity and authenticity of the deposit data.
* `forkVersion` — version of the network fork that the deposit is intended for. It helps in aligning the deposit with a specific version of the protocol.
* `eth2NetworkName` — name of the Ethereum 2.0 network where the deposit is made.
* `depositCliVersion` — version of the deposit command-line interface (CLI) tool that was used to generate the deposit data.
# 3. Prepare Staking Transaction
> The step is only applicable for validators with `0x01` withdrawal credentials.
There are two ways to prepare a staking transaction using the Staking API:
* Interact directly with the Ethereum Deposit Smart Contract.
* Utilize the P2P smart contract.
## Ethereum Deposit Smart Contract
This option can be preferable for clients, who have a lot of engineering resources available and don't want their infrastructure to have an extra dependency. In this case:
1. Retrieve all the required data from the step 2 within the `depositData` object and prepare the staking transaction yourselves.
2. Construct a signature and send the deposit amount to the [Ethereum deposit smart contract](https://etherscan.io/address/0x00000000219ab540356cBB839Cbe05303d7705Fa). Check an example of how to [sign and send](doc:signing-transaction-eth) a transaction to the Ethereum network.
## P2P Smart Contract
1. Create a serialized transaction for depositing the stake amount and send it as a POST request to [/api/v1/eth/staking/direct/tx/deposit](ref:eth-staking-deposit).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/deposit \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
--data '{
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"depositData": [
{
"pubkey": "0xac1e9969d7b87f3102549ab41558136674a7306b85b9f73cfbd7d9fdb7db85724569da3ebd4d7de9689f6ac058d7e2a3",
"signature": "0xb656f9c771166c82a7891b930e6a920878d9736eb3f9f241753a15ea69d8e2f20a3740dfaf546c70e31bd323e14b341205d04e3227dd4cf2923644a375f6792875ac02c5f256f7a17c96b09bafcbce7e4443e1862356b1e90d78875d78e9a742",
"withdrawalCredentials": "0100000000000000000000005cef11327af4104ba0f8a82fbb8628caee7cb1e3",
"depositDataRoot": "0xba013b4950b9aff0c3c19017ec5b6e0ed5b957b36f6ff03a545e5cc5605baff8"
},
{
"pubkey": "0xbe5E9c3Bb9eba1BF4C5eC1c1cbcF85ee2CE2fEC66Ce5460C23eF82332A044FDCabF7011F588CCbD77E73CCe6c4accDF0",
"signature": "0x83D2E925AEAEdcB18db983Bd447db0BFc1Ee9a6Ead118E5BEfeBcb24BA8C0efd3BD19Cb1cE8e807Fc980a67bBbf8b11e039efe2DB71fcdF096fccac5B04dF80f6a1804cd8d492455D30abE27FcDbDA78AFE61856cad65ffF5cA48Ed4776edd88",
"withdrawalCredentials": "010000000000000000000000515ea819fde1c0d36eb8e78e9a69dbf8e4a21",
"depositDataRoot": "0x53da3c92fCCEb0CFE1764f65DDfF1564A2b15585"
}
]
}'
```
* `withdrawalAddress` — withdrawal address for the validators.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `withdrawalCredentials`— withdrawal address credentials, passed in the expected format by the Ethereum deposit smart contract.
* `depositDataRoot` — hash of the deposit data.
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f902d9824268808402718e18847c8ca34c830186a09494edf7e950fa01baa44a8690cac64264cdb7ca7c8901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000308c0bbe942f40bf50895da668c95fb1feede465ab175d5f93e00a8c33d146584f7f4ee4f963d317844be5d552135b595a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020010000000000000000000000338ef19fa2ec0fc4d1277b1307a613fa1fbbc0cb000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060ac5b5e49f647d6107d71a08e255bfead1c5c42375f50e5301ffa4f5e36a8ccf159e3a594069375aef5dd2a23718634950f99947f24e67cc7a84c9f805849a7b0ac5ca732e63cca1f876dbac7e0efc8000a0f19e04bf5df80c7131d30cf45e8f3000000000000000000000000000000000000000000000000000000000000000101a591baee083825d59d36f06b4d0fbd55688ed81b337819a2bf145cb8a2a022c0",
"to": "0x94EDf7e950fA01bAa44a8690cAC64264cdB7cA7c",
"gasLimit": "100000",
"data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000308c0bbe942f40bf50895da668c95fb1feede465ab175d5f93e00a8c33d146584f7f4ee4f963d317844be5d552135b595a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020010000000000000000000000338ef19fa2ec0fc4d1277b1307a613fa1fbbc0cb000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060ac5b5e49f647d6107d71a08e255bfead1c5c42375f50e5301ffa4f5e36a8ccf159e3a594069375aef5dd2a23718634950f99947f24e67cc7a84c9f805849a7b0ac5ca732e63cca1f876dbac7e0efc8000a0f19e04bf5df80c7131d30cf45e8f3000000000000000000000000000000000000000000000000000000000000000101a591baee083825d59d36f06b4d0fbd55688ed81b337819a2bf145cb8a2a022",
"value": "64000000000000000000",
"chainId": 560048,
"type": 2,
"maxFeePerGas": "2221240288",
"maxPriorityFeePerGas": "79693564"
}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
2. Use `serializeTx` from the previous step to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are depositing the required stake amount in the Ethereum deposit smart contract by using the P2P smart contract as a proxy.
# What's Next?
* [Withdrawal](doc:withdrawal-eth).
* [Staking API](ref:eth-nodes-request-create) reference.
---
## Eth Eigen Create Pod
*Source: [https://docs.p2p.org/reference/eth-eigen-create-pod.md](https://docs.p2p.org/reference/eth-eigen-create-pod.md)*
# Create EigenPod
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/eigenlayer/tx/create-pod": {
"post": {
"operationId": "eth-eigen-create-pod",
"summary": "Create EigenPod",
"description": "Construct a serialized transaction to initiate the process of creating the EigenPod address.",
"parameters": [],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103104
},
"message": {
"type": "string",
"default": "The Web3 transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "Web3CreateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "Web3CreateTransactionException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"Web3CreateTransactionException": {
"value": {
"error": {
"code": 103104,
"message": "The Web3 transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"EigenLayer"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Signing Transaction Aptos
*Source: [https://docs.p2p.org/docs/signing-transaction-aptos.md](https://docs.p2p.org/docs/signing-transaction-aptos.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the Aptos network, follow these steps:
1. Retrieve an unsigned serialized transaction in Base64 encrypted format.
2. Sign the transaction using the following code:
```typescript
import {
Aptos,
Hex,
Deserializer,
RawTransaction,
AptosConfig,
Network,
Ed25519PrivateKey,
Account,
SimpleTransaction,
AccountAuthenticator,
} from "@aptos-labs/ts-sdk";
export function signTransaction(rawTx: string, privateKeyHex: string, aptosEnv: "mainnet" | "testnet"): string {
if (!rawTx || !privateKeyHex) throw new Error("Missing raw transaction or private key");
const config = new AptosConfig({
network: aptosEnv === "mainnet" ? Network.MAINNET : Network.TESTNET,
fullnode: aptosEnv === "mainnet" ? "https://api.mainnet.aptoslabs.com/v1" : "https://api.testnet.aptoslabs.com/v1",
});
const aptos = new Aptos(config);
const signer = Account.fromPrivateKey({ privateKey: new Ed25519PrivateKey(privateKeyHex) });
const transaction = new SimpleTransaction(
RawTransaction.deserialize(new Deserializer(Hex.hexInputToUint8Array(rawTx)))
);
const signedTx: AccountAuthenticator = aptos.transaction.sign({ signer, transaction });
return signedTx.toString();
}
const [, , rawTx, privKey, network] = process.argv;
if (!["mainnet", "testnet"].includes(network)) {
throw new Error("Network must be 'mainnet' or 'testnet'");
}
console.log(signTransaction(rawTx, privKey, network as "mainnet" | "testnet"));
/**
* How to run this script:
* npx --yes -p @aptos-labs/ts-sdk@2.0.0 tsx signTransaction.ts
**/
/**
* To run with env variables:
*
* $ export RAW_TX= 'rawtxhere'
* $ export PRIVATE_KEY= 'privatekeyhere'
* $ export NETWORK= 'testnet'
* $ npx --yes -p @aptos-labs/ts-sdk@2.0.0 tsx signTransaction.ts $RAW_TX $PRIVATE_KEY $NETWORK
**/
```
3. Send the signed transaction to the Aptos network by making a POST request to `/api/v1/aptos/{network}/transaction/send` [endpoint](ref:aptos-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/aptos/mainnet/transaction/send \
--header 'accept: application/json' \
--head 'Authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"transaction": "0x0020b92f133c8e4768d990f39853f1931eb0481ea289a985687f0b7e59e83456333140d386bb294c9a3ce9c8e6b49c4d6dba1bbf4d99b7803f9947bcec59855414d064bf138d29c14e884fb0e7f18c35fd39ffcae96fe767a3ddcbdc6603e407673006",
"signature": "0x0020b92f133c8e4768d990f39853f1931eb0481ea289a985687f0b7e59e83456333140960e71dc383c5e0660940bbe476499ed8b64bc37efff47db1c20274f20b39d5858737269d6c7bcb1b9fc88dce0f0f7cc12b5e86516cf9f8d787827eaedf9f906"
}
'
```
* `transaction` — signed transaction in the hexadecimal format which needs to be broadcasted to the network.
* `signature` — delegator signature of the transaction.
Example response:
```json
{
"result": {
"network": "mainnet",
"senderAddress": "0xa571a5bc9b1bfd5fe58e6e09a5be251a3299985494d022959ce206f1f23f752e",
"transaction": "0x0020b92f133c8e4768d990f39853f1931eb0481ea289a985687f0b7e59e83456333140d386bb294c9a3ce9c8e6b49c4d6dba1bbf4d99b7803f9947bcec59855414d064bf138d29c14e884fb0e7f18c35fd39ffcae96fe767a3ddcbdc6603e407673006",
"status": "success",
"transactionHash": "0x8d80b8ed85b578eeb873731101a926221701ee48318f6c9b83895f7ac1535640",
"gas": {
"unitPrice": 100,
"maxGasLimit": 100,
"used": 100
},
"createdAt": "2023-08-24T08:14:50.455Z"
},
"error": {}
}
```
* `network` — Aptos network: `mainnet` or `testnet`.
* `senderAddress` — transaction sender address.
* `transaction` — signed transaction in hexadecimal format.
* `status` — transaction status: `pending`, `success`, or `failed`.
* `transactionHash` — hash of the transaction.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `unitPrice` — price per unit of gas in Octas for processing the Aptos transaction.
* `maxGasLimit` — maximum gas limit for the transaction.
* `used` — amount of gas spent for the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
## What's Next?
* [Getting Started](doc:getting-started-aptos)
* [Withdrawal](doc:withdrawal-aptos)
* [Staking API](ref:aptos-transaction-status) reference
---
## Unified Api Ethereum
*Source: [https://docs.p2p.org/docs/unified-api-ethereum.md](https://docs.p2p.org/docs/unified-api-ethereum.md)*
# Ethereum
In the following guide, the integration process for the `eth-ssv` chain is covered. The Ethereum SSV On-Chain integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Ethereum-specific details
>
> * `chain`— always set to `eth_ssv` for Ethereum-related requests.
> * `network` — environment in which the transaction is processed: `testnet` or `mainnet`.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
# Staking Flow
## 1. Create Staking Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "eth_ssv",
"network": "testnet",
"stakerAddress": "0x136C861fC99d1624155f5FC8A06Bac79ED8547B1",
"amount": 32
}'
```
* `chain`— blockchain network, always set to `eth_ssv` for Ethereum-related requests.
* `network` — environment in which the transaction is processed: `testnet` or `mainnet`.
* `stakerAddress` — account address initiating the staking transaction.
* `amount` — amount of tokens to stake in ETH.
Example response:
```json
{
"error": null,
"result": {
"amount": "32000000000000000000",
"stakerAddress": "0x136C861fC99d1624155f5FC8A06Bac79ED8547B1",
"unsignedTransactionData": "0x02f9023882426880830f42408463aeabb88398968094e9dfc1850110dadf68402ec6ad2b9bdfb79807338901bc16d674ec800000b90204746bd1000100000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000251c0000000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000e8ffb2afa84510d1814e8d74478b71041c42db7fe128144fdd7a268bf448ba856345ad5b70b23bae824295c393fa1df1d3dcc203112022ca0cfe23b069877d20ea1e5dd64fffec475f7b0d0200182525b28bf76e1e6110ba0db5edd87b39799b7d01bceefe4af93f0a94fac12291a9f0b5b093fb11c220581de0ff2e20f126105918e2b27ed42c9bccda8e949d0bc0ff8be8c4a57741db21c30ff2fefdce7ecf8722ea53db9800d6612c4f0a81a54334b6ab08f52dd6c28f5f363dd5a59a1bab46e2a2fc30bf2c83ae388fa15e0faf4a3d2da85b1b8a180b77906286eaf4443d9e4825a7df8a7cf940000000000000000000000000000000000000000000000000c0",
"extraData": {
"to": "0xE9DfC1850110DadF68402Ec6AD2B9bDfB7980733",
"gasLimit": "10000000",
"data": "0x746bd1000100000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000251c0000000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000e8ffb2afa84510d1814e8d74478b71041c42db7fe128144fdd7a268bf448ba856345ad5b70b23bae824295c393fa1df1d3dcc203112022ca0cfe23b069877d20ea1e5dd64fffec475f7b0d0200182525b28bf76e1e6110ba0db5edd87b39799b7d01bceefe4af93f0a94fac12291a9f0b5b093fb11c220581de0ff2e20f126105918e2b27ed42c9bccda8e949d0bc0ff8be8c4a57741db21c30ff2fefdce7ecf8722ea53db9800d6612c4f0a81a54334b6ab08f52dd6c28f5f363dd5a59a1bab46e2a2fc30bf2c83ae388fa15e0faf4a3d2da85b1b8a180b77906286eaf4443d9e4825a7df8a7cf940000000000000000000000000000000000000000000000000",
"chainId": 17000,
"type": 2,
"maxFeePerGas": "1672391608",
"maxPriorityFeePerGas": "1000000"
}
}
}
```
* `amount` — amount of tokens to stake denominated in Gwei (1 ETH = 10⁻⁹ Gwei)
* `stakerAddress` — staking account address receiving the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction, following the Ethereum-specific signing logic.
To broadcast the signed transaction to the Ethereum network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
# Unstaking Flow
## 1. Create Withdrawal Request
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "eth_ssv",
"network": "testnet",
"stakerAddress": "0x136C861fC99d1624155f5FC8A06Bac79ED8547B1",
"extra":{
"publicKeys": [
"0x88D461F02A8CBD2B81E39A98318E11724C6CDAA05A7AE8AD318AD29989AB693034209B37B7150BCE00D268163F58360D"
]
}
}'
```
* `chain`— blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiated the staking transaction.
* `extra` — additional request parameters:
* `publicKeys` — list of validators public keys.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"list": [
{
"serializeTx": "0x02f901ae82426880830f4240830f432c83989680947d5a8de7e3721f6692d88a8d30b9c927fffcdbb480b9018432afd02f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003083340b237f8f07cc3569b94d66e1c1616c5d96ec1f57c75bb81d824eead70f1aa4ffae2dbb32b7aebe8e6bc9dc40eb9c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000050d000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000005130000000000000000000000000000000000000000000000000000000000000516c0",
"to": "0x7D5a8De7E3721F6692d88A8D30B9C927fffcDBb4",
"gasLimit": "10000000",
"data": "0x32afd02f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003083340b237f8f07cc3569b94d66e1c1616c5d96ec1f57c75bb81d824eead70f1aa4ffae2dbb32b7aebe8e6bc9dc40eb9c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000050d000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000005130000000000000000000000000000000000000000000000000000000000000516",
"value": "0",
"chainId": 17000,
"type": 2,
"maxFeePerGas": "1000236",
"maxPriorityFeePerGas": "1000000"
}
]
}
}
}
```
* `serializeTx` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — transaction value.
* `chainId` — chain ID this transaction is authorized on, as specified by EIP-155.
* `type` — EIP-2718 type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Ethereum-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction).
* [Integration Workflow Example](doc:implementation-example)
* [Networks](doc:unified-api-networks)
---
## Ssv Api Overview
*Source: [https://docs.p2p.org/docs/ssv-api-overview.md](https://docs.p2p.org/docs/ssv-api-overview.md)*
# Overview
SSV Staking API provides seamless integration for initiating DVT staking requests using the SSV protocol. By integrating with our API, your platform can bypass the complexity of manual forms and instantly connect your customers to a world-class staking service.
## Key Benefits
* **Premium Validator Network**: Access our premier P2P validator network bolstered by three of the industry's finest institutional operators. Their exemplary performance and stringent security standards are your assurance of a resilient and secure staking operation.
* **Risk Mitigation**: Our strategically designed cluster minimizes risks by distributing validators across diverse locations and client software, ensuring your operations are safeguarded against single points of failure and regionalized threats.
* **Operational Efficiency**: Embrace the ease of automated integration with our API, designed to align with the SSV protocol, reducing your operational overhead and simplifying the staking process for your clients.
By seamlessly integrating SSV Staking API into your systems, you can enhance your offering and simplify the staking process for your customers.
We provide two distinct endpoints for testing and production environments. The test environment is linked to the Holesky network (Ethereum).
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING ON HOLESKY: [https://api-test-holesky.p2p.org](https://api-test-holesky.p2p.org)
## What's Next?
* [Getting Started](doc:getting-started-ssv).
* [SSV Staking API](ref:introduction-dvt) reference.
---
## Signing Transaction Polkadot
*Source: [https://docs.p2p.org/docs/signing-transaction-polkadot.md](https://docs.p2p.org/docs/signing-transaction-polkadot.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the Polkadot network, follow these steps:
1. Prepare the unsigned transaction in Base64 encrypted format.
2. Sign the transaction using the following code:
```javascript
import { readFileSync } from "fs";
import { ApiPromise, WsProvider, Keyring } from "@polkadot/api";
import '@polkadot/api-augment';
async function sign () {
// Polkadot websocket url
const provider = process.env.PROVIDER;
// sr25519 secret key filename
const secretFileName = process.env.SECRET_FILE_NAME;
// password of secret key
const password = process.env.PASSWORD;
// transaction in base64
const rawTransaction = process.env.RAW_TRANSACTION;
// connect to polkadot node
const wsProvider = new WsProvider(provider);
const api = await ApiPromise.create({ provider: wsProvider });
await api.isReady;
// load keyring file
const keyring = new Keyring({ type: "sr25519" });
const fileContent = readFileSync(
secretFileName,
"utf8"
);
const keyInfo = JSON.parse(fileContent);
const sender = keyring.addFromJson(keyInfo);
// decode secret key
sender.decodePkcs8(password);
const unsigned = api.tx(rawTransaction);
// sing transaction
const signedExtrinsic = await unsigned.signAsync(sender);
console.log('signedExtrinsic', signedExtrinsic.toHuman());
// print signed transaction
const hexEx = signedExtrinsic.toHex()
console.log('signedExtrinsic toHex', hexEx);
await api.disconnect()
}
// run sing function
sign().catch((error) => {
console.error(error);
process.exit(1);
});
```
3. Broadcast the transaction to the Polkadot network by sending a POST request to [/api/v1/polkadot/\{network}/tx/send](ref:polkadot-transaction-send).
Example request (for `westend` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/tx/send \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"signedTransaction": "0x450284002c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f01befdb7fa39c5a995a8d58676a0513d082be"
}'
```
* `signedTransaction` — signed transaction in hex format.
Example response:
```curl JSON
{
"result": {
"status": "success",
"blockHash": "0x0628743b05ffb4c9d5ea2144b359af38910f0ae439a685f57d85b50b9481ba3f",
"blockId": "17168395",
"extrinsicId": "0xb838911d5a5f965f33b8ee134e1115b5b9902abfc567f0c3050073faf9d3c3e0",
"transactionHash": "0x450284002c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f01befdb7fa39c5a995a8d58676a0513d082be",
"signerAccount": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `staus` — transaction status.
* `blockHash` — block hash in which the transaction was included.
* `blockId` — unique block identifier.
* `extrinsicId` — unique extrinsic identifier.
* `transactionHash` — signed transaction in hex format.
* `signerAccount` — account that signed the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
## What's Next?
* [Getting Started](doc:staking-polkadot).
* [Withdrawal](doc:withdrawal-polkadot).
* [Staking API](ref:polkadot-transaction-status) reference.
---
## Staking Solana
*Source: [https://docs.p2p.org/docs/staking-solana.md](https://docs.p2p.org/docs/staking-solana.md)*
# Getting Started
Staking in the Solana network using the Staking API consists of several main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
A request example is provided using [cURL](https://curl.se/).
## 1. Create Stake Transaction
Send a POST request to [/api/v1/solana/\{network}/staking/stake](ref:solana-staking-stake).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/solana/testnet/staking/stake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"feePayer": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"fromPublicKey": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"amount": "1002282880",
"stakeAuthority": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"withdrawAuthority": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf"
}'
```
* `feePayer` — account address that will pay the fee for the transaction.
* `fromPublicKey` — account address from which the staking account will be created.
* `amount` — amount of tokens to stake in lamports (1 SOl = 10^9 lamports). Min amount is `1002282880`.
* `stakeAuthority` — account address that can perform staking operations with the staking account. If not specified, rights will be taken from the `fromPublicKey` parameter.
* `withdrawAuthority` — account address that can perform withdrawal operations with the staking account. If not specified, rights will be taken from the `fromPublicKey` parameter.
Example response:
```json
{
"result": {
"feePayer": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"fromPublicKey": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"stakeAccount": "6ZuLUCwVTvuQJrN1HrpoHJheQUw9Zk8CtiD3CEpHiA9E",
"stakeAuthority": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"withdrawAuthority": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"amount": "1002282880",
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `feePayer` — account address that will pay the fee for the transaction.
* `fromPublicKey` — account address from which the staking account will be created.
* `stakeAccount` — account address that stores tokens for staking.
* `stakeAuthority` — account address that can perform staking operations with the staking account.
* `withdrawAuthority` — account address that can perform withdrawal operations with the staking account.
* `amount` — amount of tokens to stake in lamports (1 SOL = 10^9 lamports). Min amount is `1002282880`.
* `unsignedTransaction` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
> The transaction exists for one minute.
## 2. Sign and Send Transaction
Use `unsignedTransaction` to [sign and send](doc:signing-transaction-solana) the signed transaction to the Solana network.
To check the transaction status, send a GET request to [/api/v1/solana/\{network}/account/staking](ref:solana-staking-get-staking-account).
Example request (for `testnet` network):
```curl
curl --request GET \
--url https://api-test.p2p.org/api/v1/solana/testnet/account/staking?stakeAuthorities=7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf&withdrawAuthorities=7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json'
```
* `stakeAuthorities` — list of account addresses that can perform staking operations with staking accounts.
* `stakeAccounts` — list of staking account addresses.
* `withdrawAuthorities` — list of account addresses that can perform withdrawal operations with the staking accounts.
* `status` — staking account status: `active`, `inactive`, `activating`, `deactivating`.
Example response:
```json
{
"result": {
"accounts": [
"amount": 2282881,
"stakeAccount": "1298uXQBW2azVA33UonLu2RoouDWkNqsV1rMUrQAy1SN",
"withdrawAuthority": "7E5LgJx7w7AfoeA5YgLPZFdBptz18nhdT7hxZuDA9aQf",
"stakeAuthority": "AaMC5y1RofbY3unyrahRzyCzsesp7rfGuaGegbAg1Hxb",
"voteAccount": "FKsC411dik9ktS6xPADxs4Fk2SCENvAiuccQHLAPndvk",
"status": "active"
]
}
}
```
* `accounts` — list of stake accounts.
* `amount` — amount of tokens to stake in lamports (1 SOl = 10^9 lamports).
* `stakeAccount` — account address that stores tokens for staking.
* `stakeAuthority` — account address that can perform staking operations with the staking account.
* `withdrawAuthority` — account address that can perform withdrawal operations with the staking account.
* `voteAccount` — vote account address.
* `status` — stake account status: `active`, `inactive`, `activating`, `deactivating`.
## What's Next?
* [Sign and Send Transaction](doc:signing-transaction-solana).
* [Withdrawal](doc:withdrawal-solana).
* [Staking API](ref:solana-2) reference.
---
## Broadcast Cosmos Transaction
*Source: [https://docs.p2p.org/reference/broadcast-cosmos-transaction.md](https://docs.p2p.org/reference/broadcast-cosmos-transaction.md)*
# Broadcast Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/cosmos/{network}/transaction/send": {
"post": {
"operationId": "broadcast-cosmos-transaction",
"summary": "Broadcast Transaction",
"description": "Broadcast transaction to the Cosmos network.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "cosmoshub-4",
"description": "
Cosmos network:
`cosmoshub-4` — Cosmos mainnet.
",
"schema": {
"enum": [
"cosmoshub-4"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"signedTransaction": {
"type": "string",
"description": "Signed transaction in Base64 encrypted format which needs to be broadcast to the network."
}
},
"required": [
"signedTransaction"
],
"x-readme-ref-name": "BroadcastTransactionRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"failed"
],
"description": "Transaction status."
},
"blockId": {
"type": "number",
"description": "Unique identifier of the block in which the transaction has been included."
},
"fee": {
"type": "number",
"description": "Total fee in SEI charged for processing the transaction."
},
"gas": {
"description": "Computational effort required to execute the transaction measured in gas units.",
"allOf": [
{
"type": "object",
"properties": {
"used": {
"type": "number",
"description": "Amount of gas spent for the transaction."
},
"wanted": {
"type": "number",
"description": "Maximum gas limit for the transaction."
}
},
"required": [
"used",
"wanted"
],
"x-readme-ref-name": "Gas"
}
]
},
"transactionHash": {
"type": "string",
"pattern": "[A-Z0-9]{64}",
"description": "Hash of the transaction."
}
},
"required": [
"status",
"blockId",
"fee",
"gas",
"transactionHash"
],
"x-readme-ref-name": "TransactionStatusResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 110107,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110109
},
"message": {
"type": "string",
"default": "The transaction could not be broadcasted because the internal server error occurred."
},
"name": {
"type": "string",
"default": "BroadcastTransactionFailedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BroadcastTransactionFailedException"
}
]
}
}
},
"examples": {
"BroadcastTransactionFailedException": {
"value": {
"error": {
"code": 110109,
"message": "The transaction could not be broadcasted because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Cosmos"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Data Validator Rewards
*Source: [https://docs.p2p.org/reference/data-validator-rewards.md](https://docs.p2p.org/reference/data-validator-rewards.md)*
# Get Validator Rewards
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/validator/rewards": {
"get": {
"operationId": "data-validator-rewards",
"summary": "Get Validator Rewards",
"description": "Get a list of validator rewards.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum-agg",
"ethereum",
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"sui",
"polygon",
"avail",
"ton",
"near",
"cardano"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Validator address in the required network. For the Ethereum network, it is a public validator key.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stakingPeriod": {
"type": "number",
"description": "Number of the staking period."
},
"stakingPeriodStart": {
"type": "string",
"description": "Timestamp of the staking period start in the ISO 8601 format."
},
"stakingPeriodEnd": {
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format."
},
"rewards": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Reward type.",
"enum": [
"consensus",
"execution"
]
},
"amount": {
"type": "number",
"format": "float",
"description": "Amount of tokens in the stake."
},
"amountUsd": {
"type": "number",
"format": "float",
"description": "Amount of tokens in the stake in USD."
},
"currency": {
"type": "string",
"enum": [
"ETH",
"SOL",
"DOT",
"KSM",
"GLMR",
"VARA",
"ATOM",
"MATIC",
"SUI",
"AVAIL",
"TON",
"NEAR",
"ADA"
],
"description": "Currency of the tokens."
},
"recipient": {
"type": "string",
"description": "Rewards recipient address."
}
},
"required": [
"type",
"amount",
"amountUsd",
"currency",
"recipient"
],
"x-readme-ref-name": "Reward"
}
},
"tokenPrice": {
"type": "number",
"description": "Token price in USD."
}
},
"required": [
"stakingPeriod",
"stakingPeriodStart",
"stakingPeriodEnd",
"rewards",
"tokenPrice"
],
"x-readme-ref-name": "ValidatorRewards"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetValidatorRewardsResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115100
},
"message": {
"type": "string",
"default": "The request could not be performed because the validator address provided is not valid on the specified network. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "InvalidValidatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidValidatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidValidatorAddressException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the validator address provided is not valid on the specified network. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115301
},
"message": {
"type": "string",
"default": "The list of validator rewards could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetValidatorRewardsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetValidatorRewardsException"
}
]
}
}
},
"examples": {
"GetValidatorRewardsException": {
"value": {
"error": {
"code": 115301,
"message": "The list of validator rewards could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Validator"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## P2P Ssv Transaction Validator
*Source: [https://docs.p2p.org/reference/p2p-ssv-transaction-validator.md](https://docs.p2p.org/reference/p2p-ssv-transaction-validator.md)*
# Get List of Validators
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/p2p/validators": {
"get": {
"operationId": "p2p-ssv-transaction-validator",
"summary": "Get List of Validators",
"description": "Get a list of validators by address.",
"parameters": [
{
"name": "limit",
"required": true,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": true,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 100000,
"type": "number"
}
},
{
"name": "withdrawalAddress",
"required": true,
"in": "query",
"description": "Withdrawal address for the validators.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"schema": {
"pattern": "^0x[a-fA-F0-9]{40}$",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"totalCount": {
"type": "number",
"minimum": 1,
"description": "Total count of resources relevant to the current request, based on filters applied."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"pubkey": {
"type": "string",
"description": "Validator public key.",
"example": "0xbe5E9c3Bb9eba1BF4C5eC1c1cbcF85ee2CE2fEC66Ce5460C23eF82332A044FDCabF7011F588CCbD77E73CCe6c4accDF0",
"pattern": "^0x[a-fA-F0-9]{96}$"
}
},
"required": [
"pubkey"
],
"x-readme-ref-name": "SsvValidatorResponse"
}
}
},
"required": [
"limit",
"offset",
"totalCount",
"list"
],
"x-readme-ref-name": "SsvValidatorListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103144
},
"message": {
"type": "string",
"default": "Failed to get list of validators"
},
"name": {
"type": "string",
"default": "ValidatorsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorsException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"ValidatorsException": {
"value": {
"error": {
"code": 111143,
"message": "Failed to get list of validators",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"P2P SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Create Sei Claim Rewards Transaction
*Source: [https://docs.p2p.org/reference/create-sei-claim-rewards-transaction.md](https://docs.p2p.org/reference/create-sei-claim-rewards-transaction.md)*
# Create Claim Rewards Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/sei/{network}/staking/claim-rewards": {
"post": {
"operationId": "create-sei-claim-rewards-transaction",
"summary": "Create Claim Rewards Request",
"description": "Create a claim rewards request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "pacific-1",
"description": "
`staked` — rewards will be sent to your Stash account and added to your current bond (compounding rewards).
`stash` — rewards will be sent to your Stash account as transferrable balance (not compounding rewards).
`controller` — rewards will be sent to the controller account.
`account` — rewards will be sent to any account you specify as transferrable balance.
"
},
"rewardDestination": {
"type": "string",
"description": "Rewards destination account address.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"amount": {
"type": "number",
"description": "Amount of tokens to bond (in usual DOTs/KSMs/WNDs).",
"example": 3
}
},
"required": [
"stashAccountAddress",
"rewardDestinationType",
"amount"
],
"x-readme-ref-name": "BondRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xac0406000b0030ef7dba0203ded255321b86f5f975cf04fd0e9d2b1d941469d469dcc93b89441cdfe6c39f7b"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"rewardDestinationType": {
"type": "string",
"enum": [
"staked",
"stash",
"controller",
"account"
],
"description": "
Rewards destination type:
`staked` — rewards will be sent to your Stash account and added to your current bond (compounding rewards).
`stash` — rewards will be sent to your Stash account as transferrable balance (not compounding rewards).
`controller` — rewards will be sent to the controller account.
`account` — rewards will be sent to any account you specify as transferrable balance.
"
},
"rewardDestination": {
"type": "string",
"description": "Rewards destination account address.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"amount": {
"type": "number",
"description": "Amount of tokens to bond (in usual DOTs/KSMs/WNDs).",
"example": 3
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"unsignedTransaction",
"stashAccountAddress",
"rewardDestinationType",
"rewardDestination",
"amount",
"createdAt"
],
"x-readme-ref-name": "PolkadotUnsignedBondTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119106
},
"message": {
"type": "string",
"default": "The request could not be performed because the bond amount is too small. Please check that the bond amount is more than %s and try again."
},
"name": {
"type": "string",
"default": "StakeAmountTooSmallException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "StakeAmountTooSmallException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124109
},
"message": {
"type": "string",
"default": "The request could not be performed because the account does not have enough balance to perform the transaction."
},
"name": {
"type": "string",
"default": "InsufficientBalanceException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientBalanceException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"StakeAmountTooSmallException": {
"value": {
"error": {
"code": 107106,
"message": "The request could not be performed because the bond amount is too small. Please check that the bond amount is more than undefined and try again.",
"type": "client"
},
"result": null
}
},
"InsufficientBalanceException": {
"value": {
"error": {
"code": 107102,
"message": "The request could not be performed because the amount of tokens on account is insufficient. Please check that the balance is more than undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119132
},
"message": {
"type": "string",
"default": "The bond request could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "BondException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"BondException": {
"value": {
"error": {
"code": 107126,
"message": "The bond request could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Unified Api Polygon
*Source: [https://docs.p2p.org/docs/unified-api-polygon.md](https://docs.p2p.org/docs/unified-api-polygon.md)*
# Polygon
In the following guide, the integration process for the `polygon` chain is covered. The Polygon integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Polygon-specific details
>
> * `chain` — always set to `polygon` for Polygon-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
> * `stakerAddress` — Ethereum-compatible account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in MATIC.
# Staking Flow
## 1. Approve Token Management
> Note that the flow uses transactions of type 2 (EIP-1559). Staking, unstaking, and withdrawal operations require interaction with smart contracts via prepared transactions.
Approve transferring your MATIC tokens to the staking contract by sending a POST request to [/api/v1/polygon/staking/approve](ref:polygon-staking-approve).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/polygon/staking/approve \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"amount": "1",
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21"
}'
```
* `amount` — amount of tokens in MATIC to approve staking operations.
* `stakerAddress` — staker account address providing approval.
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f86c0180830e57e084b6687a7c830f424094455e53cbb86018ac2b8092fdcd39d8444affc3f680b844095ea7b3000000000000000000000000455e53cbb86018ac2b8092fdcd39d8444affc3f60000000000000000000000000000000000000000000000000de0b6b3a7640000c0",
"to": "0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6",
"gasLimit": "1000000",
"data": "0x095ea7b3...",
"value": "0",
"chainId": 137,
"type": 2,
"maxFeePerGas": "3060300412",
"maxPriorityFeePerGas": "940000"
}
}
```
* `serializeTx` — serialized unsigned transaction ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) format).
* `to` — recipient contract address for approval.
* `gasLimit` — maximum gas limit for the transaction.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155). Polygon chain ID for `mainnet` is 137.
* `type` — [EIP-1559](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
## 2. Sign and Send Transaction
Use `serializeTx` to [sign](doc:unified-api-signing-transaction) the transaction using the Polygon-specific signing logic.
To broadcast the signed transaction to the Polygon network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "polygon",
"network": "mainnet",
"signedTransaction": "",
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21",
"extra": {}
}'
```
* `chain` — blockchain network, always set to `polygon` for Polygon-related requests.
* `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `stakerAddress` — staker account address initiating the staking transaction.
* `extra` — additional request parameters.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"transactionHash": "0x2423921ace5d44e1df4f61a966917b738ae1dd3eaad085efc6eef4275e454088",
"signedTransaction": "",
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21",
"sentAt": "2025-04-23T17:21:11.991Z"
}
}
}
```
* `extraData` — additional transaction details:
* `transactionHash` — hash of the broadcasted approval transaction.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `stakerAddress` — staking account address initiating the delegate transaction.
* `sentAt` — timestamp of the transaction in the ISO 8601 format.
## 3. Create Delegate Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "polygon",
"network": "mainnet",
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21",
"amount": "1"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — staker account address initiating the staking transaction.
* `amount` — amount of tokens to delegate in MATIC.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21",
"unsignedTransactionData": "0x02f86c0180830e57e084a51c350e830f42409415c2b3adca66e26b6f230b4023f52a285b7f999580b8446ab150710000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000c0",
"extraData": {
"to": "0x15C2b3AdcA66E26B6F230b4023f52a285b7f9995",
"gasLimit": "1000000",
"data": "0x6ab15071...",
"value": "0",
"chainId": 137,
"type": 2,
"maxFeePerGas": "2770089230",
"maxPriorityFeePerGas": "940000"
}
}
}
```
* `stakerAddress` — staker account address initiated the delegate transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `to` — recipient contract address for approval.
* `gasLimit` — maximum gas limit for the transaction.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155). Polygon chain ID for `mainnet` is 137.
* `type` — [EIP-1559](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Polygon-specific signing logic.
# Unstaking Flow
## 1. Create Undelegate Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "polygon",
"network": "mainnet",
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21",
"extra": {
"amount": "1"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — staker account address initiating the undelegate transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to undelegate in MATIC.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21",
"unsignedTransactionData": "0x02f86c0180830e57e084a8c1ba86830f42409415c2b3adca66e26b6f230b4023f52a285b7f999580b844c83ec04d...",
"extraData": {
"to": "0x15C2b3AdcA66E26B6F230b4023f52a285b7f9995",
"gasLimit": "1000000",
"data": "0xc83ec04d...",
"value": "0",
"chainId": 137,
"type": 2,
"maxFeePerGas": "2831268486",
"maxPriorityFeePerGas": "940000"
}
}
}
```
* `stakerAddress` — staker account address initiated the undelegate transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `to` — recipient contract address for approval.
* `gasLimit` — maximum gas limit for the transaction.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155). Polygon chain ID for `mainnet` is 137.
* `type` — [EIP-1559](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Polygon-specific signing logic.
## 3. Create Withdrawal Request
> 📘
>
> Note that it takes up to 3-4 days to prepare your tokens for unstaking as Polygon uses a system of checkpoints. The average undelegate period on Polygon is 80 checkpoints. Withdrawal is only available after the undelegate period ends.
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "polygon",
"network": "mainnet",
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — staker account address initiating the withdrawal transaction.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "0x368F823e4dfe271dc820f4Ea14689917bf8e4a21",
"unsignedTransactionData": "0x02f86c0180830e57e084a51c350e830f42409415c2b3adca66e26b6f230b4023f52a285b7f999580b8444e71d92d...",
"extraData": {
"to": "0x15C2b3AdcA66E26B6F230b4023f52a285b7f9995",
"gasLimit": "1000000",
"data": "0x4e71d92d...",
"value": "0",
"chainId": 137,
"type": 2,
"maxFeePerGas": "2770089230",
"maxPriorityFeePerGas": "940000"
}
}
}
```
* `stakerAddress` — staker account address initiated the withdrawal transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `to` — recipient contract address for approval.
* `gasLimit` — maximum gas limit for the transaction.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155). Polygon chain ID for `mainnet` is 137.
* `type` — [EIP-1559](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Polygon-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Avail Staking Withdrawunbonded
*Source: [https://docs.p2p.org/reference/avail-staking-withdrawunbonded.md](https://docs.p2p.org/reference/avail-staking-withdrawunbonded.md)*
# Withdraw Unbonded Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/staking/direct/withdraw-unbonded": {
"post": {
"operationId": "avail-staking-withdrawUnbonded",
"summary": "Withdraw Unbonded Request",
"description": "Withdrawing tokens within the Avail network that were previously unbonded.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Avail network:
`mainnet` — Avail mainnet.
`testnet` — Avail testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
}
},
"required": [
"stashAccountAddress"
],
"x-readme-ref-name": "AvailWithdrawUnbondedRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action."
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding."
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format."
}
},
"required": [
"unsignedTransaction",
"stashAccountAddress",
"createdAt"
],
"x-readme-ref-name": "AvailWithdrawalTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119103
},
"message": {
"type": "string",
"default": "The transaction could not be found. Please specify the correct transaction data."
},
"name": {
"type": "string",
"default": "BondNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119105
},
"message": {
"type": "string",
"default": "The request could not be performed because the controller address does not correspond to the provided one."
},
"name": {
"type": "string",
"default": "WrongControllerException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongControllerException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 119101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Avail address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"BondNotFoundException": {
"value": {
"error": {
"code": 119103,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"WrongControllerException": {
"value": {
"error": {
"code": 119105,
"message": "The request could not be performed because the controller address does not correspond to the provided one.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119136
},
"message": {
"type": "string",
"default": "The withdrawal request could not be performed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "WithdrawUnbondedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WithdrawUnbondedException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"WithdrawUnbondedException": {
"value": {
"error": {
"code": 119131,
"message": "The withdrawal request could not be performed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Transaction Get Operator Fee
*Source: [https://docs.p2p.org/reference/transaction-get-operator-fee.md](https://docs.p2p.org/reference/transaction-get-operator-fee.md)*
# Get Operator Fee
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/ssv/tx/operator-fee": {
"get": {
"operationId": "transaction-get-operator-fee",
"summary": "Get Operator Fee",
"description": "Check the operator on the SSV cluster.",
"parameters": [
{
"name": "operatorId",
"required": true,
"in": "query",
"example": 1,
"description": "ID of the SSV operator.",
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"fee": {
"type": "string",
"example": "1000",
"description": "Fee charged by the operator, denominated in SSV tokens."
},
"balance": {
"type": "string",
"example": "1000",
"description": "Operator outstanding earnings, denominated in SSV tokens."
}
},
"required": [
"fee",
"balance"
],
"x-readme-ref-name": "GetOperatorFeeResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 111109
},
"message": {
"type": "string",
"default": "The amount of fee charged by the operator could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetOperatorFeeException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetOperatorFeeException"
}
]
}
}
},
"examples": {
"GetOperatorFeeException": {
"value": {
"error": {
"code": 111109,
"message": "The amount of fee charged by the operator could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"SSV"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Sui Staking Withdraw
*Source: [https://docs.p2p.org/reference/sui-staking-withdraw.md](https://docs.p2p.org/reference/sui-staking-withdraw.md)*
# Create Withdrawal Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/sui/{network}/staking/withdraw": {
"post": {
"operationId": "sui-staking-withdraw",
"summary": "Create Withdrawal Request",
"description": "Create a request to withdraw unstaked tokens.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
"
},
"amount": {
"type": "string",
"description": "Amount of tokens."
}
},
"required": [
"denom",
"amount"
],
"x-readme-ref-name": "Amount"
}
},
"gas": {
"type": "string",
"description": "Amount of gas spent for the transaction."
}
},
"required": [
"amount",
"gas"
],
"x-readme-ref-name": "TransactionFee"
}
]
},
"memo": {
"type": "string",
"description": "Arbitrary text data to add to the transactions."
},
"encodedBody": {
"type": "string",
"description": "Processable transaction data encoded in the hexadecimal format."
},
"encodedAuthInfo": {
"type": "string",
"description": "Authorization data, including fee, encoded in the hexadecimal format."
}
},
"required": [
"messages",
"fee",
"encodedBody",
"encodedAuthInfo"
],
"x-readme-ref-name": "TransactionData"
}
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the transaction in the ISO 8601 format."
},
"validatorAddress": {
"type": "string",
"description": "Validator address to which tokens are delegated.",
"example": "celestiavaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^celestiavaloper[a-zA-Z0-9]{39}$"
}
},
"required": [
"stashAccountAddress",
"transactionData",
"createdAt",
"validatorAddress"
],
"x-readme-ref-name": "ClaimRewardsTransactionStakingCelestiaResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110113
},
"message": {
"type": "string",
"default": "The request could not be performed because the simulation transaction failed."
},
"name": {
"type": "string",
"default": "SimulationTransactionOnCosmosException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SimulationTransactionOnCosmosException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"SimulationTransactionOnCosmosException": {
"value": {
"error": {
"code": 110113,
"message": "The request could not be performed because the simulation transaction failed. undefined",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110106
},
"message": {
"type": "string",
"default": "The claiming rewards request transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "CreateClaimRewardsTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CreateClaimRewardsTransactionException"
}
]
}
}
},
"examples": {
"CreateClaimRewardsTransactionException": {
"value": {
"error": {
"code": 110106,
"message": "The claiming rewards request transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Celestia"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Cardano Transaction Signing
*Source: [https://docs.p2p.org/docs/cardano-transaction-signing.md](https://docs.p2p.org/docs/cardano-transaction-signing.md)*
# Cardano Transaction Signing
To sign and broadcast the transaction to the Cardano network, follow these steps:
1. Prepare unsigned transaction in Base64 encrypted format.
2. Sign the transaction using the following code:
```typescript
import {
Bip32PrivateKey,
Transaction,
TransactionHash,
TransactionWitnessSet,
Vkey,
Vkeywitness,
Vkeywitnesses,
} from "@emurgo/cardano-serialization-lib-nodejs";
import { mnemonicToEntropy } from "bip39";
import { blake2b } from "blakejs";
const MNEMONIC = "";
const RAW_TX_HEX = "";
function deriveKey(mnemonic: string, role: number, index = 0): Bip32PrivateKey {
const entropy = Buffer.from(mnemonicToEntropy(mnemonic), "hex");
const rootKey = Bip32PrivateKey.from_bip39_entropy(entropy, Buffer.from(""));
return rootKey
.derive(1852 | 0x80000000) // purpose
.derive(1815 | 0x80000000) // coin type
.derive(0 | 0x80000000) // account 0
.derive(role) // role: 0=payment, 2=stake
.derive(index); // index
}
function signTransactionHex(
unsignedHex: string,
paymentKey: Bip32PrivateKey,
stakeKey: Bip32PrivateKey
): string {
const tx = Transaction.from_bytes(Buffer.from(unsignedHex, "hex"));
const txHashBytes = blake2b(tx.body().to_bytes(), undefined, 32);
const txHash = TransactionHash.from_bytes(txHashBytes);
const witnesses = Vkeywitnesses.new();
// Payment key witness
const rawPaymentKey = paymentKey.to_raw_key();
witnesses.add(
Vkeywitness.new(
Vkey.new(rawPaymentKey.to_public()),
rawPaymentKey.sign(txHash.to_bytes())
)
);
// Stake key witness
const rawStakeKey = stakeKey.to_raw_key();
witnesses.add(
Vkeywitness.new(
Vkey.new(rawStakeKey.to_public()),
rawStakeKey.sign(txHash.to_bytes())
)
);
const witnessSet = TransactionWitnessSet.new();
witnessSet.set_vkeys(witnesses);
const signedTx = Transaction.new(tx.body(), witnessSet, tx.auxiliary_data());
return Buffer.from(signedTx.to_bytes()).toString("hex");
}
async function main() {
if (!RAW_TX_HEX || RAW_TX_HEX.length < 10) {
throw new Error("❌ RAW_TX_HEX is missing or invalid.");
}
const paymentKey = deriveKey(MNEMONIC, 0); // m/1852'/1815'/0'/0/0
const stakeKey = deriveKey(MNEMONIC, 2); // m/1852'/1815'/0'/2/0
const signedHex = signTransactionHex(RAW_TX_HEX, paymentKey, stakeKey);
console.log("✅ Signed Cardano Tx (hex):");
console.log(signedHex);
}
main().catch(console.error);
```
Upon successful execution, the script prints the signed transaction in hexadecimal format, ready to be broadcasted:
```Text Bash
✅ Signed Cardano Tx (hex): ...
```
3. Broadcast the transaction to the Cardano network by sending a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
## What's Next?
* [Networks Supported](doc:unified-api-networks)
* [Getting Started](doc:unified-api-getting-started)
* [Unified API Reference](ref:unified-create-stake-transaction)
---
## Eth Eigen Undelegate
*Source: [https://docs.p2p.org/reference/eth-eigen-undelegate.md](https://docs.p2p.org/reference/eth-eigen-undelegate.md)*
# Prepare Undelegate Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/eigenlayer/tx/undelegate": {
"post": {
"operationId": "eth-eigen-undelegate",
"summary": "Prepare Undelegate Transaction",
"description": "Construct a serialized transaction to undelegate the restaked amount of tokens from a node operator.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"eigenPodOwnerAddress": {
"type": "string",
"description": "Owner of the EigenPod address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
}
},
"required": [
"eigenPodOwnerAddress"
],
"x-readme-ref-name": "EigenPodOwnerAddressRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103104
},
"message": {
"type": "string",
"default": "The Web3 transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "Web3CreateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "Web3CreateTransactionException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"Web3CreateTransactionException": {
"value": {
"error": {
"code": 103104,
"message": "The Web3 transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"EigenLayer"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Getting Started Ssv
*Source: [https://docs.p2p.org/docs/getting-started-ssv.md](https://docs.p2p.org/docs/getting-started-ssv.md)*
# Getting Started
To start staking on the SSV network using our DVT Staking API, there are a few essential **prerequisites** to ensure a smooth and efficient setup:
* **Minimum Stake Requirement**: You will need a minimum of 32 ETH for each staking validator you wish to run.
* **SSV Tokens**: To register validators on the SSV network, you must top-up enough SSV tokens in your cluster balance to cover validator and network costs. We recommend contacting our product team to understand the most effective strategies to maintain your cluster balance. [Get SSV test tokens here](https://faucet.ssv.network/).
* **API Key Request**: [Get an authentication token](doc:authentication) to start using DVT Staking API.
There are several pathways to engage in DVT staking:
* Utilize the P2P smart contract for a simplified operation.
* Directly interact with the Ethereum Deposit Smart Contract.
We also provide convenient request examples using [cURL](https://curl.se/) to guide you through the process.
> 🚧 Please note
>
> On May 7, 2025, the major Ethereum network upgrade was carried out that brought many benefits for clients who use ETH or SSV validators. **P2P.ORG recommends** upgrading to the `0x02` withdrawal credentials to enhance your functionality. It can be done in two ways:
>
> * By [consolidating multiple existing validators](doc:validator-consolidation-copy) into a single one
> * By [creating a new `0x02`-enabled validator](doc:new-validator-creation-copy) via simplified 3.1 smart contract flow
>
> For more details, see [Pectra Upgrade overview](doc:pectra-upgrade-overview).
>
> However, upgrading to the new address format is not necessary, all existing endpoints remain supported. You can follow the `0x01` creation flow below, if you need fine-grained control over validator count, effective balance per validator, or you intend to manually broadcast deposit transactions.
## Using the P2P Smart Contract
1. Prepare`id` that is an arbitrary UUID. Generate it in one of the following ways:
* [Online UUID Generator](https://www.uuidgenerator.net/)
* [uuid npm package](https://www.npmjs.com/package/uuid)
2. Set up staking SSV nodes through P2P infrastructure by sending a POST request to [/api/v1/eth/staking/ssv/request/create](ref:ssv-request-create). Use [https://api-test.p2p.org](https://api-test.p2p.org) for testing\
or [https://api.p2p.org](https://api.p2p.org) for production.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/create \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa5",
"validatorsCount": "1",
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x01",
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"ssvOwnerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"type": "without-encrypt-key",
"operationPeriodInDays": 30,
"ecdhPublicKey": null
}
'
```
* `id` — arbitrary UUID. You can later use that UUID to check the status of the set-up operation.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `amountPerValidator` — amount of tokens to stake in Gwei per validator. Note that if the amount is more than 32 ETH (1 ETH = 10⁹ Gwei), the `withdrawalCredentialsType` parameter defaults to `0x02`.
* `withdrawalCredentialsType` — withdrawal credentials preferred format: `0x01` or `0x02`.
* `withdrawalAddress` — 0x01 prefixed withdrawal address for the client. This address is also used as the validator owner's address and must be used to sign the transaction to register the SSV validator at step 6.
* `feeRecipientAddress` — Eth1 address that receives priority fees and MEV rewards that are not related to Beacon chain partial withdrawal sweeps.
* `ssvOwnerAddress` — address that acts as the owner of the SSV cluster. The cluster owner can register the validator, update the fee recipient address, top-up the cluster balance, and claim SSV incentives rewards.
* `type`— type of operation:
* `without-encrypt-key` (available) — validator's private key is returned encrypted to the client.
* `with-encrypt-key` (not available) — validator private key is instead maintained by P2P to initiate withdrawals when requested by the client. If selected, fill the `ecdhPublicKey` field.
* `operationPeriodInDays`— operation period in days.
* `ecdhPublicKey`— your ECDH public key to obtain an encrypted validator private key.
Example response:
```json
{
"error": null,
"result": true
}
```
3. Check the node set-up operation status and retrieve the required transaction data to interact with the SSV smart contract by sending a GET request to [/api/v1/eth/staking/ssv/request/status/\{id}](ref:ssv-request-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/status/3fa85f64-5717-4562-b3fc-2c963f66afa5 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `id` — UUID that was specified in the SSV set-up request.
Example response:
```json
{
"result": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "processing",
"validatorsCount": 1,
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x01",
"withdrawalAddress": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"feeRecipientAddress": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"ssvOwnerAddress": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"type": "without-encrypt-key",
"operationPeriodInDays": 31556952,
"liquidationPeriodInDays": 2629746,
"ecdhPublicKey": null,
"validatorRegistrationTxs": null,
"feeRecipientTx": {
"serializeTx": "0x02f84405800210830186a094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80a4dbcdc2cc0000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.0000000000001",
"data": "0xdbcdc2cc0000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
},
"approveTx": {
"serializeTx": "0x02f86505800210830186a0943a9f01091c446bde031e39ea8354647afef091e780b844095ea7b3000000000000000000000000c3cd9a0ae89fff83b71b58b6512d43f8a41f363dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0",
"to": "0x3a9f01091C446bdE031E39ea8354647AFef091E7",
"gasLimit": "0.0000000000001",
"data": "0x095ea7b3000000000000000000000000c3cd9a0ae89fff83b71b58b6512d43f8a41f363dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
},
"encryptedShares": [
{
"publicKey": "string",
"nonce": "string",
"sharesData": "string",
"ecdhEncryptedPrivateKey": "string"
}
],
"clusters": [
{
"operators": [
0
]
}
]
},
"error": {}
}
```
* `id` — UUID that was specified in the SSV set-up request.
* `status` — current status of the SSV request:
* `init` — request is stored.
* `processing` — request in progress, please wait.
* `ready` — request is ready.
* `validator-ready` — validator is registered on the SSV network and contains the deposit data.
* `validator-error` — validator data is not valid.
* `cancel` — request canceled due to an error or timeout.\
When `ready`, the validator data is ready to be used in the validator registration step.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `amountPerValidator` — amount of tokens to stake in Gwei per validator.
* `withdrawalCredentialsType` — withdrawal credentials preferred format: `0x01` or `0x02`.
* `withdrawalAddress` — withdrawal address of the cluster owner.
* `feeRecipientAddress` — Eth1 address that receives the fee recipient rewards.
* `ssvOwnerAddress` — address that acts as the owner of the SSV cluster. The cluster owner can register the validator, update the fee recipient address, top-up the cluster balance, and claim SSV incentives rewards.
* `type`— type of operation:
* `without-encrypt-key` (available) — validator's private key is returned encrypted to the client.
* `with-encrypt-key` (not available) — validator private key is instead maintained by P2P to initiate withdrawals when requested by the client.
* `operationPeriodInDays`— operation period in days.
* `liquidationPeriodInDays`— liquidation threshold period in days.
* `ecdhPublicKey` — your ECDH public key for getting the encrypted validator private key.
* `validatorRegistrationTxs` — transaction data presented in both a serialized and unserialized way to register the validator on the SSV network.
* `feeRecipientTx` — transaction data presented in both a serialized and unserialized way to set the fee recipient address.
* `approveTx` — transaction data presented in both a serialized and unserialized way to approve the transfer of SSV tokens from the SSV.network smart contract on behalf of the users.
* `ssvFeeTxs` — transaction data presented in both a serialized and unserialized way to deposit SSV fees into the cluster balance.
* `encryptedShares`:
* `publicKey` — validator public key.
* `nonce` — validator key owner's nonce used for signature in `sharesData`.
* `sharesData` — the shares (i.e. validator key into a predefined threshold of shares) and the signature, used to prove the validator owner address. Used in the `registerValidator` Ethereum transaction from the SSV smart contract to create a validator.
* `ecdhEncryptedPrivateKey` — encrypted validator private key.
* `clusters`:
* `operators` — number of operators in the cluster.
`validatorRegistrationTxs`, `ssvFeeTxs`, `feeRecipientTx`, and `approveTx` includes a list of data fields that contain the following data:
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
4. Sign and broadcast the transaction `approveTx` either by using the serialized signature in `serializeTx` or by constructing the signature using the unserialized data inside `approveTx`.
Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
**This step is required only once per account.** It enables the SSV smart contract to transfer SSV tokens on your behalf to fund the cluster balance.
> The step is only applicable for validators with `0x01` withdrawal credentials.
1. Sign and broadcast the transaction `feeRecipientTx` either by using the serialized signature in `serializeTx` or by constructing the signature using the unserialized data inside `feeRecipientTx`.
Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
**This step is required only once per account.** It sets the fee recipient address for the validator on the SSV network. This address will be the recipient of the execution layer rewards accrued.
2. Sign and broadcast the transaction `validatorRegistrationTxs` either by using the serialized signature in `serializeTx` or by constructing the signature using the unserialized data inside `validatorRegistrationTxs`.
Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, your validator will be registered on the SSV network and simultaneously managed by a pool (i. e., cluster) of four top-performance node operators: Allnodes, Huobi, P2P.org, and Stakeley.
Check an [example on Goerli](https://goerli.etherscan.io/tx/0xc492e5ec2c6b230e5e88cc68e4b0d0f923b0871c4b0d2c8fa1dc18899dff6c84) of a successfully broadcasted transaction using the `validatorRegistrationTxs` data.
3. After the transaction `validatorRegistrationTxs` is correctly broadcasted to the Ethereum network, retrieve the validators' request deposit data by sending a GET request to [/api/v1/eth/staking/ssv/request/deposit-data/\{id}](ref:ssv-request-deposit-data).
Note that there is a **mandatory 6-minutes delay** before the deposit data becomes available. This delay is implemented for security reasons, ensuring that the validator can be correctly verified.
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/deposit-data/3fa85f64-5717-4562-b3fc-2c963f66afa5 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `id` — UUID that was specified in the SSV set-up request.
Example response:
```json
{
"error": null,
"result": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa5",
"status": "ready",
"depositData": [
{
"pubkey": "0xb632ad4ebec8594ec8f2fbacc6df53dec180f8bae6561d70bf74c19520a35beff99cd92513058da6a22a75b9570ab31d",
"signature": "0x836e9eebeb29ed1d4b232fa38649e9902ea7d6f9d19e571c4e76cde4da2bcdbca822c8f29d21379325201735fa93925d1597f0c021a147910c165e60bf3308bc827d5fcd545f1c901e7b3102e28b8ea09d6c162c3ffd57e7398f73e5968e05db",
"depositDataRoot": "0x16678e6d91a8c3a8f1cdabc037fa32f1d296e629d1665a57f493eda1e6a6964a",
"withdrawalCredentials": "0100000000000000000000005cef11327af4104ba0f8a82fbb8628caee7cb1e3",
"amount": "32000000000",
"depositMessageRoot": "6a572503239cd1f11998af7901c0947fe36eb8efec080f22598d607d3938c1a8",
"forkVersion": "00001020",
"eth2NetworkName": "goerli",
"depositCliVersion": "2.3.0"
}
]
}
}
```
* `id` — UUID that was specified in the SSV set-up request.
* `status` — current status of the SSV request:
* `init` — request is stored.
* `processing` — request in progress, please wait.
* `ready` — request is ready.
* `validator-ready` — validator is registered on the SSV network.
* `validator-error` — validator data is not valid.
* `cancel` — request canceled due to an error or timeout.\
When `ready`, the validator data is ready to be used in the validator registration step.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `depositDataRoot` — SHA-256 hash of the SSZ-encoded DepositData object. They are used as a protection against malformed input.
* `withdrawalCredentials`— withdrawal address credentials, passed in the expected format by the Ethereum deposit smart contract.
* `amount` — amount of ETH, denominated in gwei, that is being deposited.
* `depositMessageRoot` — cryptographic hash of the Merkle tree’s root, ensuring the integrity and authenticity of the deposit data.
* `forkVersion` — version of the network fork that the deposit is intended for. It helps in aligning the deposit with a specific version of the protocol.
* `eth2NetworkName` — name of the Ethereum 2.0 network where the deposit is made.
* `depositCliVersion` — version of the deposit command-line interface (CLI) tool that was used to generate the deposit data.
4. Create a serialized transaction for depositing the stake amount and send it as a POST request to [/api/v1/eth/staking/direct/tx/deposit](ref:eth-staking-deposit).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/deposit \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"depositData": [
{
"pubkey": "0xac1e9969d7b87f3102549ab41558136674a7306b85b9f73cfbd7d9fdb7db85724569da3ebd4d7de9689f6ac058d7e2a3",
"signature": "0xb656f9c771166c82a7891b930e6a920878d9736eb3f9f241753a15ea69d8e2f20a3740dfaf546c70e31bd323e14b341205d04e3227dd4cf2923644a375f6792875ac02c5f256f7a17c96b09bafcbce7e4443e1862356b1e90d78875d78e9a742",
"depositDataRoot": "0xba013b4950b9aff0c3c19017ec5b6e0ed5b957b36f6ff03a545e5cc5605baff8"
}
]
}
'
```
* `withdrawalAddress` — withdrawal address for the validators.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `depositDataRoot` — SHA-256 hash of the SSZ-encoded DepositData object. Used as a protection against malformed input.
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f902cf0580021e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060a307b2e1661bcc38d482a69603713baf332ad36adf837392e9f20a96b77a03ca415a46261fc62b8f5d4aa69a0d70e2cf0d23e3396bd387cfde18d392a2c7ba822d3f8a60d075366625dcb3c88cd59ebc8f7ab1fc312c6b8b625a57bf7e1b6e6f000000000000000000000000000000000000000000000000000000000000000178ae581ccc8bdf1fde00cff35b2278e1c10a9ed2fc18632373dac118a03cfacdc0",
"to": "0x681a1b3441c6BFb12f91651EFD9F02c83c070293",
"gasLimit": "0.0000000000001",
"data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060a307b2e1661bcc38d482a69603713baf332ad36adf837392e9f20a96b77a03ca415a46261fc62b8f5d4aa69a0d70e2cf0d23e3396bd387cfde18d392a2c7ba822d3f8a60d075366625dcb3c88cd59ebc8f7ab1fc312c6b8b625a57bf7e1b6e6f000000000000000000000000000000000000000000000000000000000000000178ae581ccc8bdf1fde00cff35b2278e1c10a9ed2fc18632373dac118a03cfacd",
"value": "32.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.00000000000000003",
"maxPriorityFeePerGas": "2"
}
}
```
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
5. Use `serializeTx` from the previous step to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, you are depositing the required stake amount in the Ethereum deposit smart contract by using the P2P smart contract as a proxy.
After your deposit is successful, your validator will enter the activation queue and soon start performing the validator tasks. You can check the status of your validator on the [SSV network explorer](https://goerli.explorer.ssv.network/validators).
## Interacting directly with the Ethereum Deposit Smart Contract
1. Prepare`id` that is an arbitrary UUID. Generate it in one of the following ways:
* [Online UUID Generator](https://www.uuidgenerator.net/)
* [uuid npm package](https://www.npmjs.com/package/uuid)
2. Set up staking SSV nodes through P2P infrastructure by sending a POST request to [/api/v1/eth/staking/ssv/request/create](ref:ssv-request-create). Use [https://api-test.p2p.org](https://api-test.p2p.org) for testing\
or [https://api.p2p.org](https://api.p2p.org) for production.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/create \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa5",
"validatorsCount": "1",
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x01",
"withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"ssvOwnerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"type": "without-encrypt-key",
"operationPeriodInDays": 30,
"ecdhPublicKey": null
}
'
```
* `id` — arbitrary UUID. You can later use that UUID to check the status of the set-up operation.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `amountPerValidator` — amount of tokens to stake in Gwei per validator. Note that if the amount is more than 32 ETH (1 ETH = 10⁹ Gwei), the `withdrawalCredentialsType` parameter defaults to `0x02`.
* `withdrawalCredentialsType` — withdrawal credentials preferred format: `0x01` or `0x02`.
* `withdrawalAddress` — withdrawal address for the client. This address is also used as the validator owner's address and must be used to sign the transaction to register the SSV validator at step 6.
* `feeRecipientAddress` — Eth1 address that receives the fee recipient rewards.
* `ssvOwnerAddress` — address that acts as the owner of the SSV cluster. The cluster owner can register the validator, update the fee recipient address, top-up the cluster balance, and claim SSV incentives rewards.
* `type`— type of operation:
* `without-encrypt-key` (available) — validator's private key is returned encrypted to the client.
* `with-encrypt-key` (not available) — validator private key is instead maintained by P2P to initiate withdrawals when requested by the client. If selected, fill the `ecdhPublicKey`field.
* `operationPeriodInDays`— operation period in days.
* `ecdhPublicKey`— your ECDH public key to obtain an encrypted validator private key.
Example response:
```json
{
"error": null,
"result": true
}
```
3. Check the node set-up operation status by sending a GET request to [/api/v1/eth/staking/ssv/request/status/\{id}](ref:ssv-request-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/status/3fa85f64-5717-4562-b3fc-2c963f66afa5 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `id` — UUID that was specified in the SSV set-up request.
Example response:
```json
{
"error": null,
"result": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa5",
"status": "ready",
"type": "without-encrypt-key",
"operationPeriodInDays": 30,
"liquidationPeriodInDays": 30,
"ecdhPublicKey": null,
"encryptedShares": [
{
"publicKey": "0xb4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb27",
"nonce": 1,
"sharesData": "0x971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200",
"ecdhEncryptedPrivateKey": null
}
],
"validatorsCount": 1,
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x0",
"withdrawalAddress": "0x9c7d4b4595402ed44167C74f9F7c7720AB5528E0",
"ssvOwnerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
"feeRecipientAddress": "0x9c7d4b4595402ed44167C74f9F7c7720AB5528E0",
"validatorRegistrationTxs": [
{
"serializeTx": "0x02f9078605010210830f424094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80b9076406e8fb9c00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb2700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000520971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.000000000001",
"data": "0x06e8fb9c00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000030b4b5f251eac53f34eb1da2b6659d35db303e408c4c830156cf090441564474f356abd023a0e679aa97cefeed850abb2700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000520971aade51840b84fc5b88fee2ef1ed80ce57c2ea9a8fb610d2fdb3a287589a87c421b845e3f1cb4ef5a84eaba6c31d4c159ead3c818758d6fc988a207ea467ff35fb90ab502805569f8ff94042d870ebedc327ea0778476559c95076a99c7cd1b78b94bb2a5098c10b50000c7419476f295e0d1e94b17c1f985c76adfad8b7897bdf34b58388b6b201104616e179e93888016e92ab60b4bf5d844b1a8fd9fdd97e3dba2cfadbe65f1bc3b66aeed8b1be8407a150ae6a028fe72e50d70121e7eab424e02922422ce66fb45c5878eb0d307fae5b5b0637cee897a119563d18082c33fe5ac017d3cfd3a42e2f5f7d8bece98e679000fb7cfd339fbc1470177963d5cd73b6b4001e77f3dcb348cb07797b25fd3b6811e4dfbafe78a4a9d70861fd27001d88253500347ba8ff907bd647b83aa6b5bf727929ee35ce5360a0b7810b355f8e524426e8a6db75e240af29527b398c2d5a926e4867f04483ec61338d7f413cd419d17bc572a0b3ecd98e04426964a8350d1545493e2fe039828f8e74fb48da7f4ee26166b4c2b2b05fa94bf4721a0b6888a8065062ed45bd23f9d3fcbb80ecf3febfb8c90522b20ae724a94f12fb9de80c95dd7b1762d6b15312c3bbde291224fb7b809384404bde5d78bd36801a67154addc466d20c6e6146eda1e263167a96a9d21a1b4fef6d532957cfca20d3311ac2f5bfd6c4601df0eebec49b5a74adce8c1b7fbf82c5333d25c499f72928d3bfe47fa9c54ec9f55c63586758af8a256683952376b4feef745bbc2280e66bb475e48edc4a90eb128bfb3322b30065f3fedf6dcd3180798375eee05abc20433f79e3d6e73948a84057ca7b72b6ba756f257ca1a11f2fa3b130bcf28d9ef80cb946bf11e6008815ee6c100ab1527f13c064bac2b67a8f832ab70c98d39d77940f975c35c8dea26f2e25a5e706da368fa0dd08958ea11904b1b51ca40aab37e581e58a5c60ea1caa08063461b3319e6c8ff21b75f2ff9358ddccf27abea55e7dbad4f474741ff14fe9e63d9c001eec990531a5bc6b2196269cfa0050beced2e2ce55f9dfea48c0c81f3d1a1f4f6548e29de76b085f83f9399c29b89880a15b80e049de2fa9eef3eab7a1a15cd1d6ae2bc8fdc9837f59baf56c11ed7405bda5d2cd2de6fd80c7b7461abfb757c742b3216ef79d8268501cb3531a5fcf9d46b58e828e6aaea4bef8484cc8945912ac611827463d4a3dabe56f608181dfba8ffc7cb1cfdef5a09a9f107652b44d290fc42b0d5e3e16634342af07f205153b0c7d095e0d418f1d0aef8a7e00d41e5af183ceed36d5832169bdd91810b4ad686b85130ec07aeaccfbc26d440684ac34c8005c12b38caa41d18ecd51167afaba0aae2b605cb0cefcae1b4f64ff220167d1f93b73abd75368dd67c3a6ad48448021c66086daf62419d6de350ee3f25aef4784340c0932362da25cff3f1ed7316afce3034d264f1206322c6510aacddb9315f8b532516a52f2483d0a191caa38a10cb40d00494c43ddcc49b54349fd809409a8d6131746ef7adc57a9f7feea9bb3a4142d418e5b1f89ccde686a1627c9a9d5ac9bc6a06685017b15eb549e9bc2e7cf98720b616d8bea14b5b9194280bb1386154be5fd31dc6f64cfe5bbf80fff95e2a82a2a803e579e302c0db931470b78fb32fb1774840002417b86c4ad621e43ec36d2496a7f6b63d470fae3edb863f909ee0e4ce43ca293770a229cbcbd542c9bd123889298c3a6e32c2e5c5f4861afa640a16d5c5089373d3e6ddfdebc223a2d966c3e37d135f3f8805eb3432ff46befac6c41aff89739b1bab6ccee383fb524ff985b5054091fed2d351bff38ec78800200",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
}
],
"ssvFeeTxs": [
{
"serializeTx": "0x02f901c605800210830186a094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80b901a4bc26e7e50000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c00000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.0000000000001",
"data": "0xbc26e7e50000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000016c7ded605b5c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f3111b30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000016c7ded605b5c00000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
}
],
"feeRecipientTx": {
"serializeTx": "0x02f84405800210830186a094c3cd9a0ae89fff83b71b58b6512d43f8a41f363d80a4dbcdc2cc0000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0c0",
"to": "0xC3CD9A0aE89Fff83b71b58b6512D43F8a41f363D",
"gasLimit": "0.0000000000001",
"data": "0xdbcdc2cc0000000000000000000000009c7d4b4595402ed44167c74f9f7c7720ab5528e0",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
},
"approveTx": {
"serializeTx": "0x02f86505800210830186a0943a9f01091c446bde031e39ea8354647afef091e780b844095ea7b3000000000000000000000000c3cd9a0ae89fff83b71b58b6512d43f8a41f363dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0",
"to": "0x3a9f01091C446bdE031E39ea8354647AFef091E7",
"gasLimit": "0.0000000000001",
"data": "0x095ea7b3000000000000000000000000c3cd9a0ae89fff83b71b58b6512d43f8a41f363dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"value": "0.0",
"chainId": 5,
"type": 2,
"maxFeePerGas": "0.000000000000000016",
"maxPriorityFeePerGas": "2"
}
}
}
```
* `id` — UUID that was specified in the SSV set-up request.
* `status` — current status of the SSV request:
* `init` — request is stored.
* `processing` — request in progress, please wait.
* `ready` — request is ready.
* `validator-ready` — validator is registered on the SSV network.
* `validator-error` — validator data is not valid.
* `cancel` — request canceled due to an error or timeout.\
When `ready`, the validator data is ready to be used in the validator registration step.
* `type`— type of operation:
* `without-encrypt-key` (available) — validator's private key is returned encrypted to the client.
* `with-encrypt-key` (not available) — validator private key is instead maintained by P2P to initiate withdrawals when requested by the client.
* `operationPeriodInDays`— operation period in days.
* `liquidationPeriodInDays`— liquidation threshold period in days.
* `ecdhPublicKey` — your ECDH public key for getting the encrypted validator private key.
* `encryptedShares`:
* `publicKey` — validator public key.
* `nonce` — validator key owner's nonce used for signature in `sharesData`.
* `sharesData` — the shares (i. e., validator key into a predefined threshold of shares) and the signature, used to prove the validator owner address. Used in the `registerValidator` Ethereum transaction from the SSV smart contract to create a validator.
* `ecdhEncryptedPrivateKey` — encrypted validator private key.
* `validatorsCount` — number of validators. One validator is equal to 32 ETH.
* `amountPerValidator` — amount of tokens to stake in Gwei per validator.
* `withdrawalCredentialsType` — withdrawal credentials preferred format: `0x01` or `0x02`.
* `withdrawalAddress` — withdrawal address of the cluster owner.
* `ssvOwnerAddress` — address that acts as the owner of the SSV cluster. The cluster owner can register the validator, update the fee recipient address, top-up the cluster balance, and claim SSV incentives rewards.
* `feeRecipientAddress` — Eth1 address that receives the fee recipient rewards.
* `validatorRegistrationTxs` — transaction data presented in both a serialized and unserialized way to register the validator on SSV network.
* `ssvFeeTxs` — transaction data presented in both a serialized and unserialized way to deposit SSV fees into the cluster balance.
* `feeRecipientTx` — transaction data presented in both a serialized and unserialized way to set the fee recipient address.
* `approveTx` — transaction data presented in both a serialized and unserialized way to approve the transfer of SSV tokens from the SSV.network smart contract on behalf of the users.
`validatorRegistrationTxs`, `ssvFeeTxs`, `feeRecipientTx`, and `approveTx` includes a list of data fields that contain the following data:
* `serializeTx` — serialized unsigned transaction.
* `to` — recipient address for this transaction.
* `gasLimit` — maximum gas limit for this block.
* `data` — transaction data.
* `value` — amount this transaction is sending in Wei.
* `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
* `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
* `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
* `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
4. Sign and broadcast the transaction `approveTx` either by using the serialized signature in `serializeTx` or by constructing the signature using the unserialized data inside `approveTx`.
Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
**This step is required only once per account.** It enables the SSV smart contract to transfer SSV tokens on your behalf to fund the cluster balance.
5. Sign and broadcast the transaction `feeRecipientTx` either by using the serialized signature in `serializeTx` or by constructing the signature using the unserialized data inside `feeRecipientTx`.
Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
**This step is required only once per account.** It sets the fee recipient address for the validator on the SSV network. This address will be the recipient of the execution layer rewards accrued.
6. Sign and broadcast the transaction `validatorRegistrationTxs` either by using the serialized signature in `serializeTx` or by constructing the signature using the unserialized data inside `validatorRegistrationTxs`.
Use `serializeTx` to [sign and send](doc:signing-transaction-eth) the signed transaction to the Ethereum network.
By broadcasting this transaction, your validator will be registered on the SSV network and simultaneously managed by a pool (i. e., cluster) of four top-performance node operators: Allnodes, Huobi, P2P.org, and Stakeley.
Check an [example on Goerli](https://goerli.etherscan.io/tx/0xc492e5ec2c6b230e5e88cc68e4b0d0f923b0871c4b0d2c8fa1dc18899dff6c84) of a successful broadcasted transaction using the `validatorRegistrationTxs` data.
7. After the transaction `validatorRegistrationTxs` is correctly broadcasted to the Ethereum network, retrieve the validators' request deposit data by sending a GET request to [/api/v1/eth/staking/ssv/request//deposit-data/\{id}](ref:ssv-request-deposit-data).
Note that there is a **mandatory 6-minutes delay** before the deposit data becomes available. This delay is implemented for security reasons, ensuring that the validator can be correctly verified.
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/ssv/request/deposit-data/3fa85f64-5717-4562-b3fc-2c963f66afa5 \
--header 'accept: application/json' \
--header 'authorization: Bearer '
```
* `id` — UUID that was specified in the SSV set-up request.
Example response:
```json
{
"error": null,
"result": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa5",
"status": "ready",
"depositData": [
{
"pubkey": "0xb632ad4ebec8594ec8f2fbacc6df53dec180f8bae6561d70bf74c19520a35beff99cd92513058da6a22a75b9570ab31d",
"signature": "0x836e9eebeb29ed1d4b232fa38649e9902ea7d6f9d19e571c4e76cde4da2bcdbca822c8f29d21379325201735fa93925d1597f0c021a147910c165e60bf3308bc827d5fcd545f1c901e7b3102e28b8ea09d6c162c3ffd57e7398f73e5968e05db",
"depositDataRoot": "0x16678e6d91a8c3a8f1cdabc037fa32f1d296e629d1665a57f493eda1e6a6964a",
"withdrawalCredentials": "0100000000000000000000005cef11327af4104ba0f8a82fbb8628caee7cb1e3",
"amount": "32000000000",
"depositMessageRoot": "6a572503239cd1f11998af7901c0947fe36eb8efec080f22598d607d3938c1a8",
"forkVersion": "00001020",
"eth2NetworkName": "goerli",
"depositCliVersion": "2.3.0"
}
]
}
}
```
* `id` — UUID that was specified in the SSV set-up request.
* `status` — current status of the SSV request:
* `init` — request is stored.
* `processing` — request in progress, please wait.
* `ready` — request is ready.
* `validator-ready` — validator is registered on the SSV network.
* `validator-error` — validator data is not valid.
* `cancel` — request canceled due to an error or timeout.\
When `ready`, the validator data is ready to be used in the validator registration step.
* `depositData`:
* `pubkey` — validator public key.
* `signature` — validator signature.
* `depositDataRoot` — SHA-256 hash of the SSZ-encoded DepositData object. They are used as a protection against malformed input.
* `withdrawalCredentials`— withdrawal address credentials, passed in the expected format by the Ethereum deposit smart contract.
* `amount` — amount of ETH, denominated in gwei, that is being deposited.
* `depositMessageRoot` — cryptographic hash of the Merkle tree’s root, ensuring the integrity and authenticity of the deposit data.
* `forkVersion` — version of the network fork that the deposit is intended for. It helps in aligning the deposit with a specific version of the protocol.
* `eth2NetworkName` — name of the Ethereum 2.0 network where the deposit is made.
* `depositCliVersion` — version of the deposit command-line interface (CLI) tool that was used to generate the deposit data.
> 📘 Construct a signature yourself
>
> If you prefer to construct a signature yourself to send the deposit amount to the [Ethereum deposit smart contract](https://etherscan.io/address/0x00000000219ab540356cBB839Cbe05303d7705Fa), you can retrieve all the required data from step 3 within the `depositData` object.
>
> Check an example of how to [sign and send](doc:signing-transaction-eth) a transaction to the Ethereum network.
After your deposit is successful, your validator will enter the activation queue and soon start performing the validator tasks. You can check the status of your validator on the [SSV network explorer](https://goerli.explorer.ssv.network/validators).
## What's Next?
* [DVT Staking API](ref:ssv-request-create) reference.
---
## Babylon Transaction Get By Tx Hash
*Source: [https://docs.p2p.org/reference/babylon-transaction-get-by-tx-hash.md](https://docs.p2p.org/reference/babylon-transaction-get-by-tx-hash.md)*
# Check Transaction Status
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon-btc/{network}/transaction/get-by-tx-hash/{txHash}": {
"get": {
"operationId": "babylon-transaction-get-by-tx-hash",
"summary": "Check Transaction Status",
"description": "Retrieve a specific transaction from the Bitcoin network by its hash to check the status.",
"parameters": [
{
"name": "txHash",
"description": "Transaction hash.",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Babylon network:
`mainnet` — Babylon main production environment and Bitcoin mainnet (only locking BTC is currently available).
`testnet` — Babylon testing environment and Bitcoin testnet called sigNet.
",
"schema": {
"enum": [
"testnet",
"mainnet"
],
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"transaction": {
"description": "List of Babylon transactions.",
"allOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Transaction type.",
"example": "Stake"
},
"txHash": {
"type": "string",
"description": "Transaction hash.",
"example": "0x"
},
"stakerPublicKey": {
"type": "string",
"description": "Staker public key.",
"example": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
},
"stakerAddress": {
"type": "string",
"description": "Staker address.",
"example": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9"
},
"stakeAmount": {
"type": "number",
"description": "Stake amount in SATOSHI (1 BTC = 10⁸ SATOSHI).",
"example": 1000000
},
"stakeTime": {
"type": "number",
"description": "Time-lock period for staking in Bitcoin blocks.",
"example": 100
},
"finallyProviderPublicKey": {
"type": "string",
"description": "Finality provider public key produced by the Schnorr signature algorithm.",
"example": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
}
},
"required": [
"type",
"txHash",
"stakerPublicKey",
"stakerAddress",
"stakeAmount",
"stakeTime",
"finallyProviderPublicKey"
],
"x-readme-ref-name": "Transaction"
}
]
}
},
"required": [
"transaction"
],
"x-readme-ref-name": "GetByHashResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 120104
},
"message": {
"type": "string",
"default": "The provided address [ 'testnet', 'mainnet' ] is invalid."
},
"name": {
"type": "string",
"default": "InvalidAddressException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 120102
},
"message": {
"type": "string",
"default": "The requested transaction is not a stake transaction"
},
"name": {
"type": "string",
"default": "TransactionIsNotStake"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionIsNotStake"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 120100,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"InvalidAddressException": {
"value": {
"error": {
"code": 120104,
"message": "The provided address undefined is invalid.",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 120100,
"message": "The requested transaction was not found.",
"type": "client"
},
"result": null
}
},
"TransactionIsNotStake": {
"value": {
"error": {
"code": 120102,
"message": "The requested transaction is not a stake transaction",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Babylon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Babylon Transaction Unbonding
*Source: [https://docs.p2p.org/reference/babylon-transaction-unbonding.md](https://docs.p2p.org/reference/babylon-transaction-unbonding.md)*
# Broadcast Unbonding Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon-btc/{network}/transaction/unbonding": {
"post": {
"operationId": "babylon-transaction-unbonding",
"summary": "Broadcast Unbonding Transaction",
"description": "Broadcast the unstaking transaction to the Bitcoin network to release the unbonded assets for early withdrawal.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Babylon network:
`mainnet` — Babylon main production environment and Bitcoin mainnet (only locking BTC is currently available).
`testnet` — Babylon testing environment and Bitcoin testnet called sigNet.
",
"schema": {
"enum": [
"testnet",
"mainnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stakingTxHash": {
"type": "string",
"description": "Hash of the initial staking transaction.",
"example": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028"
},
"unbondingTxHex": {
"type": "string",
"description": "Unsigned transaction for the unbonding request in the hexadecimal format.",
"example": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000"
}
},
"required": [
"stakingTxHash",
"unbondingTxHex"
],
"x-readme-ref-name": "UnbondingRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"stakingTxHash": {
"type": "string",
"description": "Hash of the initial staking transaction.",
"example": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028"
},
"unbondingTxHex": {
"type": "string",
"description": "Unsigned transaction for the unbonding request in the hexadecimal format.",
"example": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000"
},
"unbondingTxHash": {
"type": "string",
"description": "Hash of the partially signed unbonding transaction.",
"example": "02000000000101e64994aad9ebe5f9bbe8344a743aa6dbbc9d5ecab0cc135b2697bbeef7834bfd0000000000ffffffff017869000000000000225120abc575829d73ef108ceba4f1686f657e6e2f70852208eabaa0cd74e248f203a7034031226d5e6be2988bc81b4ede2e507e8795992e2f8dbf73c3c7887ca611ef74d46e4ddcf41734478e088a2c9f110be6bb29f4d8fc9a6c0aca6b2ba648bdb850208a20be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4ad2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ac2049766ccd9e3cd94343e2040474a77fb37cdfd30530d05f9f1e96ae1e2102c86eba2076d1ae01f8fb6bf30108731c884cddcf57ef6eef2d9d9559e130894e0e40c62cba529c61c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac073c168cce70e3d66240fcd3ef216f083436f448372fe7cccb668449cbcb15b26639fa5fb4094c2f7ea65e9c176ccd983b1cda874de942d6fb8cd3b4f2e2aa14b00000000"
},
"stakerSignature": {
"type": "string",
"description": "Staker signature of the unbonding transaction.",
"example": "304402203f7c0f6c1f7a8f7"
}
},
"required": [
"stakingTxHash",
"unbondingTxHex",
"unbondingTxHash",
"stakerSignature"
],
"x-readme-ref-name": "UnbondingResponseDto"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 120100,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Babylon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Signing Transaction Sui
*Source: [https://docs.p2p.org/docs/signing-transaction-sui.md](https://docs.p2p.org/docs/signing-transaction-sui.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the SUI network, follow these steps:
### 1. Prepare unsigned transactions in Base64 encrypted format.
### 2. Sign the transaction using the following code:
```javascript
import { Ed25519Keypair, RawSigner } from '@mysten/sui.js';
const keypair = Ed25519Keypair.fromSecretKey(
Uint8Array.from(Buffer.from(process.env.PRIVATE_KEY!, 'hex'))
);
const signer = new RawSigner(keypair, provider);
// Convert unsigned hex string to bytes
const txBytes = Uint8Array.from(Buffer.from(process.env.UNSIGNED_TX!, 'hex'));
const { signature } = await signer.signTransactionBlock(txBytes);
console.log('Signed TX:', signature);
```
### 3. Broadcast via API
Example request:
```
curl --location 'https://api-test.p2p.org/api/v1/sui/testnet/transaction/send' \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"signedTransaction": "",
"sender": "0x696f4402d7151fb49e52b629de3ce3098f3dda7721a7425c000b4f26653709e3"
}'
```
* `signedTransaction` — your locally signed transaction, hex-encoded.
* `sender` — wallet address used for the original unsigned transaction.
Example response:
```json
{
"error": null,
"result": {
"transactionDigest": "DiXajfAeTLVhiQZuW8aH2UD1XsCEoZVH4twRC5PjeK5"
}
}
```
* `txHash` — hash of the submitted transaction.
* `status` — expected to be `"Success"` on successful submission.\
May also return `"Pending"` or an error depending on network state.
> Use the `txHash` to track the transaction status in explorers like [SuiScan](https://suiscan.xyz/).
## What's Next?
* [Getting Started](doc:staking-sui).
* [Withdrawal](doc:withdrawal-sui).
* [Staking API](ref:sui) reference.
---
## Unified Api Tron
*Source: [https://docs.p2p.org/docs/unified-api-tron.md](https://docs.p2p.org/docs/unified-api-tron.md)*
# TRON
In the following guide, the integration process for the `tron` chain is covered. TRON integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key TRON-specific details
>
> * `chain` — always set to `tron` for TRON-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` or`testnet-nile`.
> * `stakerAddress` — TRON account address initiating staking, voting or withdrawal transactions.
> * `amount` — amount of tokens in SUN (1 TRX = 10⁶ SUN). Note that only TRX (SUN) can be staked, since USDT (TRC-20) is not natively stakeable.
# Staking Flow
## 1. Create Freeze Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `testnet-nile` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "tron",
"network": "testnet-nile",
"stakerAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
"amount": 1000000,
"extra": {
"resource": "BANDWIDTH"
}
}'
```
* `chain` — blockchain network, always set to `tron` for TRON-related requests.
* `network` — environment in which the transaction is processed: `mainnet` or`testnet-nile`.
* `stakerAddress` — TRON account address initiating the freeze transaction.
* `amount` — amount of tokens to freeze in SUN (1 TRX = 10⁶ SUN). Note that only TRX (SUN) can be staked, since USDT (TRC-20) is not natively stakeable.
* `extra` — additional request parameters:
* `resource` — type of resources to be used for processing the TRON transaction`BANDWIDTH` or `ENERGY`.
Example response:
```json
{
"error": null,
"result": {
"amount": 1000000,
"stakerAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
"createdAt": "2025-06-26T19:18:33.983Z",
"extraData": {
"unsignedTransactionData": {
"visible": false,
"txID": "5fa8e694866ba0ecfcbf4d4932552ad7f9a198fccc30b5d0b4a1564a986cec8a",
"raw_data_hex": "0a02ed712208bed86bc0563959f54088abb9edfa325a57083612530a34747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e467265657a6542616c616e63655632436f6e7472616374121b0a1541da53d324a354aa5924c7117caff3ead97910a5e110c0843d70a8d6b5edfa32",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"owner_address": "41da53d324a354aa5924c7117caff3ead97910a5e1",
"frozen_balance": 1000000
},
"type_url": "type.googleapis.com/protocol.FreezeBalanceV2Contract"
},
"type": "FreezeBalanceV2Contract"
}
],
"ref_block_bytes": "ed71",
"ref_block_hash": "bed86bc0563959f5",
"expiration": 1750965573000,
"timestamp": 1750965513000
}
}
}
}
}
```
* `amount` — amount of tokens to freeze in SUN (1 TRX = 10⁶ SUN). Note that only TRX (SUN) can be staked, since USDT (TRC-20) is not natively stakeable.
* `stakeAddress` — TRON account address initiating the freeze transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. The object contains the list of data fields to be used to construct the staking transaction.
* `visible` — internal SDK parameter; always set to `false`.
* `txID` — hash of the freeze transaction.
* `raw_data_hex` — raw payload of the unsigned transaction in the hexadecimal format.
* `raw_data` — full decoded transaction structure with all the fields and metadata:
* `contract` — list of TRON contracts:
* `parameter.type_url` — TRON network operation type, e.g., `type.googleapis.com/protocol.FreezeBalanceV2Contract`.
* `parameter.value.owner_address ` — TRON account address initiated the transaction in the hexadecimal format.
* `parameter.value.frozen_balance` — amount of tokens to freeze in SUN (1 TRX = 10⁶ SUN).
* `ref_block_bytes`, `ref_block_hash` — hash and references of the block in which the transaction has been included.
* `expiration` — timestamp of the transaction expiration in ms since last epoch.
* `timestamp` — timestamp of the transaction in ms since last epoch.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction using the TRON-specific signing logic.
To broadcast the signed transaction to the TRON network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request (for `testnet-nile` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "tron",
"network": "testnet-nile",
"stakerAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
"signedTransaction": "0x410284007427a7dee592c47c6875266357ee7afd763ddfdf6bd1634e410b7335fc38331e01f214ddb36378b5f5927b06028eccfe284d9cb736f8552e301cc09c2006998b098f84bf6386a201aa952fe298dd5f0c5fb6f03fc7b9f7efafd87b6ee321500b8e450340000600070010a5d4e8037427a7dee592c47c6875266357ee7afd763ddfdf6bd1634e410b7335fc38331e"
}'
```
* `chain` — blockchain network, always set to `tron`.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — TRON account address initiated the transaction.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
Example response:
```json
{
"error": null,
"result": {
"status": "PENDING",
"extraData": {
"transactionHash": "71e64f4fca71012b4ee5a40c90eed269875e4a796011e42f46358da68f758a34",
"createdAt": "2025-06-26T19:25:13.712Z",
"network": "testnet-nile",
"senderAddress": "41da53d324a354aa5924c7117caff3ead97910a5e1",
"block": null,
"gas": {
"bandwidthUsed": 0,
"energyUsed": 0
}
}
}
}
```
* `status` — transaction status: `pending`, `success` or `failed`.
* `extraData` — additional transaction details:
* `transactionHash` — hash of the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `network` — environment in which the transaction is processed.
* `senderAddress` — TRON account address in the hexadecimal format.
* `block` — block number in which the transaction has been included; `null` if the transaction has not been confirmed yet.
* `gas` — gas usage details:
* `bandwidthUsed` — number of bandwidth points consumed for processing the TRON transaction.
* `energyUsed` — amount of energy in ms representing the time spent during an execution of a smart contract.
## 3. Create Vote Request
To vote for a Super Representative after freezing TRX tokens, send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `testnet-nile` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "tron",
"network": "testnet-nile",
"stakerAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
"amount": 1000000,
"extra": {
"voteAddress": "TH7Fe1W8CcLeqN4LGfqX1R9EpsnrJBQJji",
"voteCount": 1
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — TRON account address initiating the voting transaction.
* `amount` — amount of frozen tokens to use for voting in SUN (1 TRX = 10⁶ SUN).
* `extra` — additional request parameters:
* `voteAddress` — address of the Super Representative to vote for.
* `voteCount` — number of votes.
Example response:
```json
{
"error": null,
"result": {
"amount": 1000000,
"stakerAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
"createdAt": "2025-06-26T19:26:54.816Z",
"extraData": {
"unsignedTransactionData": {
"visible": false,
"txID": "c07e64f57ebb6ae191404b1c693aa46f80789aceacbfd8cc17a7c85c0c8c5559",
"raw_data_hex": "0a02ee182208eb04b8cce7cc51534090f5d7edfa325a6a080412660a30747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e566f74655769746e657373436f6e747261637412320a1541da53d324a354aa5924c7117caff3ead97910a5e112190a1541351b95e29c2514b7b8183cbc81a8e08c68e8833b100370b0a0d4edfa32",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"owner_address": "41da53d324a354aa5924c7117caff3ead97910a5e1",
"votes": [
{
"vote_address": "41351b95e29c2514b7b8183cbc81a8e08c68e8833b",
"vote_count": 3
}
]
},
"type_url": "type.googleapis.com/protocol.VoteWitnessContract"
},
"type": "VoteWitnessContract"
}
],
"ref_block_bytes": "ee18",
"ref_block_hash": "eb04b8cce7cc5153",
"expiration": 1750966074000,
"timestamp": 1750966014000
}
}
}
}
}
```
* `amount` — amount of frozen tokens used for voting in SUN (1 TRX = 10⁶ SUN).
* `stakerAddress` — TRON account address initiated the voting transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. The object contains the list of data fields to be used to construct the staking transaction.
* `visible` — internal SDK parameter; always set to `false`.
* `txID` — hash of the voting transaction.
* `raw_data_hex` — raw payload of the unsigned transaction in the hexadecimal format.
* `raw_data` — full decoded transaction structure with all the fields and metadata:
* `contract` — list of TRON contracts:
* `parameter.type_url` — TRON network operation type, e.g., `type.googleapis.com/protocol.FreezeBalanceV2Contract`.
* `parameter.value.owner_address ` — TRON account address in the hexadecimal format.
* `parameter.value.frozen_balance` — amount of tokens used for voting in SUN (1 TRX = 10⁶ SUN).
* `ref_block_bytes`, `ref_block_hash` — hash and references of the block in which the transaction has been included.
* `expiration` — timestamp of the transaction expiration in ms since last epoch.
* `timestamp` — timestamp of the transaction in ms since last epoch.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the TRON-specific signing logic.
# Unstaking Flow
## 1. Create Unfreeze Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request (for `testnet-nile` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "tron",
"network": "testnet-nile",
"stakerAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
"extra": {
"amount": 1000000,
"resource": "BANDWIDTH"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — TRON account address initiating the unfreeze transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to unfreeze in SUN (1 TRX = 10⁶ SUN).
* `resource` — type of resources used for processing the freeze transaction:`BANDWIDTH` or `ENERGY`.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
"createdAt": "2025-06-26T19:28:54.816Z",
"extraData": {
"unsignedTransactionData": {
... // (same transaction structure as above)
}
}
}
}
```
* `amount` — amount of tokens to unfreeze in SUN (1 TRX = 10⁶ SUN).
* `stakerAddress` — TRON account address initiated the unfreeze transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. The object contains the list of data fields to be used to construct the staking transaction.
* `visible` — internal SDK parameter; always set to `false`.
* `txID` — hash of the unfreeze transaction.
* `raw_data_hex` — raw payload of the unsigned transaction in the hexadecimal format.
* `raw_data` — full decoded transaction structure with all the fields and metadata:
* `contract` — list of TRON contracts:
* `parameter.type_url` — TRON network operation type, e.g., `type.googleapis.com/protocol.FreezeBalanceV2Contract`.
* `parameter.value.owner_address ` — TRON account address in the hexadecimal format.
* `parameter.value.frozen_balance` — amount of tokens to unfreeze in SUN (1 TRX = 10⁶ SUN).
* `ref_block_bytes`, `ref_block_hash` — hash and references of the block in which the transaction has been included.
* `expiration` — timestamp of the transaction expiration in ms since last epoch.
* `timestamp` — timestamp of the transaction in ms since last epoch.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the TRON-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Unified Api Ton
*Source: [https://docs.p2p.org/docs/unified-api-ton.md](https://docs.p2p.org/docs/unified-api-ton.md)*
# TON
In the following guide, the integration process for the `ton_whales` chain is covered. The TON integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key TON-specific details
>
> * `chain` — always set to `ton_whales` for TON-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in nanoTONs (1 TON = 10⁹ nanoTONs).
> * `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet for staking operations.
> * `publicKey` — public key of the nominator for the TON network.
# Staking Flow
## 1. Create Staking Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "ton_whales",
"network": "mainnet",
"stakerAddress": "0QDLFn0rX92mwLFL5bMAkamPxvjM_2k4SHDi4VEQG4Jk8rCE",
"extra": {
"publicKey": "dbc17009994431c741d22396f71ebb220951c2d2a643e0c17e63125d9acae32d",
"amount": "5000000000",
"walletVersion": "V3R1"
}
}'
```
* `chain` — blockchain network, always set to `ton_whales` for TON-related requests.
* `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
* `stakerAddress` — staking account address receiving the staked tokens.
* `extra` — additional request parameters:
* `publicKey` — public key of the nominator for the TON network.
* `amount` — amount of tokens to stake in nanoTONs (1 TON = 10⁹ nanoTONs).
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain.
Example response:
```json
{
"error": null,
"result": {
"amount": "5000000000",
"stakerAddress": "0QDLFn0rX92mwLFL5bMAkamPxvjM_2k4SHDi4VEQG4Jk8rCE",
"unsignedTransactionData": "b5ee9c7241010201005c00011a29a9a3176761922b0000000f0301009462001b0eecbed3c3c21725606281a98dfb0152db86a09eb434df3d75fd862d8466e723b9aca00000000000000000000000000000da803efd00000193d519d3184773594005012a05f200a7846cb2",
"extraData": {
"seqno": 15,
"walletVersion": "V3R1",
"publicKey": "dbc17009994431c741d22396f71ebb220951c2d2a643e0c17e63125d9acae32d",
"poolAddress": "kQA2Hdl9p4eELkrAxQNTG_YCpbcNQT1oab566_sMWwjNztst"
}
}
}
```
* `amount` — amount of tokens to stake in nanoTONs (1 TON = 10⁹ nanoTONs).
* `stakerAddress` — staking account address receiving the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `seqno` — [sequence number](https://docs.ton.org/v3/guidelines/smart-contracts/howto/wallet#replay-protection---seqno) of the message.
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain.
* `publicKey` — public key of the nominator for the TON network.
* `poolAddress` — TON Whales pool address.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction.
To broadcast the signed transaction to the TON network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "ton_whales",
"network": "mainnet",
"signedTransaction": "710f0456d675c0715bcdcbce5ab4fc5ad8e00cccaa3bd40fe59329cfe33c7089901bffa9c412bcd502c9f751f15de93abb297599c0dadb4f247eaeea72a2a003",
"stakerAddress": "0QDLFn0rX92mwLFL5bMAkamPxvjM_2k4SHDi4VEQG4Jk8rCE",
"extra": {
"unsignedTransaction": "b5ee9c7241010201005a00011c29a9a317ffffffff00000000000301008d62001b0eecbed3c3c21725606281a98dfb0152db86a09eb434df3d75fd862d8466e7280d09dc3000000000000000000000000000007bcd1fef00000193e11e3d975012a05f2008b7558aef",
"publicKey": "dbc17009994431c741d22396f71ebb220951c2d2a643e0c17e63125d9acae32d",
"walletVersion": "V3R1"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `stakerAddress` — staking account address receiving the staked tokens.
* `extra` — additional request parameters:
* `unsignedTransaction` — unsigned transaction in Base64 encrypted format.
* `publicKey` — public key of the nominator for the TON network.
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain.
Example response:
```json
{
"error": null,
"result": {
"extraData": {}
}
}
```
# Unstaking Flow
## 1. Create Withdrawal Request
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request (for `mainnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "ton_whales",
"network": "mainnet",
"stakerAddress": "0QDLFn0rX92mwLFL5bMAkamPxvjM_2k4SHDi4VEQG4Jk8rCE",
"extra": {
"publicKey": "dbc17009994431c741d22396f71ebb220951c2d2a643e0c17e63125d9acae32d",
"amount": "5000000000",
"walletVersion": "V3R1"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — staking account address initiating the withdrawal transaction.
* `extra` — additional request parameters:
* `publicKey` — public key of the nominator for the TON network.
* `amount` — amount of tokens to withdraw in nanoTONs (1 TON = 10⁹ nanoTONs).
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain.
Example response:
```json
{
"error": null,
"result": {
"amount": "5000000000",
"stakerAddress": "0QDLFn0rX92mwLFL5bMAkamPxvjM_2k4SHDi4VEQG4Jk8rCE",
"unsignedTransactionData": "b5ee9c7241010201005c00011a29a9a3176761922b0000000f0301009462001b0eecbed3c3c21725606281a98dfb0152db86a09eb434df3d75fd862d8466e723b9aca00000000000000000000000000000da803efd00000193d519d3184773594005012a05f200a7846cb2",
"extraData": {
"seqno": 15,
"walletVersion": "V3R1",
"publicKey": "dbc17009994431c741d22396f71ebb220951c2d2a643e0c17e63125d9acae32d",
"poolAddress": "kQA2Hdl9p4eELkrAxQNTG_YCpbcNQT1oab566_sMWwjNztst"
}
}
}
```
* `amount` — amount of tokens to withdraw in nanoTONs (1 TON = 10⁹ nanoTONs).
* `stakerAddress` — account address initiating the withdrawal transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `seqno` — [sequence number](https://docs.ton.org/v3/guidelines/smart-contracts/howto/wallet#replay-protection---seqno) of the message.
* `walletVersion` — [version of the smart contract](https://docs.ton.org/participate/wallets/contracts) used by the wallet in the TON blockchain.
* `publicKey` — public key of the nominator for the TON network.
* `poolAddress` — TON Whales pool address.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the TON-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Pooled Staking Overview
*Source: [https://docs.p2p.org/docs/pooled-staking-overview.md](https://docs.p2p.org/docs/pooled-staking-overview.md)*
# Overview
P2P.org’s Pooled Staking API empowers enterprise partners — including wallets, exchanges, and custodians — to offer Ethereum staking to their users without the traditional 32 ETH minimum. User deposits are aggregated into dedicated vaults, with validator operations and staking workflows fully managed by P2P.org’s infrastructure.
The API provides the interface for initiating stakes, processing withdrawals, and accessing real-time status and reporting.
All staking operations are fully non-custodial: the API constructs only unsigned transactions, while transaction signing and key management remain entirely within the partner’s or user’s control. Private keys are never transmitted to or stored by P2P.org at any point.
**Key Features**
* **No 32 ETH Minimum**: Stake any amount of ETH.
* **API-Driven**: Full staking and withdrawal lifecycle managed via API endpoints.
* **Non-Custodial**: Only unsigned transactions are generated; signing stays on the client side.
* **White-Label Vaults**: The partner may have a dedicated vault with their own branding and configuration.
* **Transparent Reward Tracking**: Query endpoints for current balance, earnings, and withdrawal status.
* **Enterprise Grade**: Designed for integration with high-volume, regulated platforms.
We provide distinct endpoints for testing and production environments. The test environment is linked to the Hoodi network (Ethereum).
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING ON HOODI: [https://api-test.p2p.org](https://api-test.p2p.org)
[Get an authentication token](doc:authentication) to start using Pooled Staking API.
## What's Next?
* [Getting Started](doc:pooled-staking).
* [Withdrawal](doc:pooled-staking-withdrawal).
* [Pooled Staking API](ref:eth-eigen-create-pod) reference.
---
## Signing Transaction Solana
*Source: [https://docs.p2p.org/docs/signing-transaction-solana.md](https://docs.p2p.org/docs/signing-transaction-solana.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the Solana network, follow these steps:
1. Prepare unsigned transactions in Base64 encrypted format.
2. Sign the transaction using the following code:
```javascript
const web3 = require('@solana/web3.js');
const bs58 = require('bs58');
const { Transaction } = web3
(async () => {
// base58 signer private keys devided by comma `,`
const privateKeys = process.env.PRIVATE_KEYS;
// base64 unsigned transaction
const transaction = process.env.TX
let tx = Transaction.from(Buffer.from(transaction, 'base64'));
// sign transaction for each signer
for (const pk of privateKeys) {
const signer = web3.Keypair.fromSecretKey(new Uint8Array(bs58.decode(pk)));
tx.sign(signer)
}
// print signed transaction
console.log(tx.serialize().toString('base64'))
})();
```
3. Send the signed transaction to the Solana network by making a POST request to [/api/v1/solana/\{network}/tx/send](ref:solana-staking-send).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/solana/testnet/tx/send \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"signedTransaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcJjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+jagnMHpK8BDHt0PpssHwXGD2fBxS6MWBoxptD2u9TvrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NjSeWM5+GSJdoQd43Al9SVVXC9FfWGwbe7icpomwAUGodgXkTdUKpg0N73+KnqyVX9TXIp4citopJ3AAAAAAAah2BelAgULaAeR5s5tuI4eW3FQ9h/GeQpOtNEAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAan1RcZNYTQ/u2bs0MdEyBr5UQoG1e4VmzFN1/0AAAAijW940iwWddz25ZC37fI0ue5fa+eTbC2ynBM3b0t4pcDAgMAAQBgAwAAAI5ELeF3F+N1ZPBWe0G1FV0heaKPY7e8dg5tBPbrf8voBAAAAAAAAABzZWVkgJaYAAAAAADIAAAAAAAAAAah2BeRN1QqmDQ3vf4qerJVf1NcinhyK2ikncAAAAAABAIBB3QAAAAAjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+iORC3hdxfjdWTwVntBtRVdIXmij2O3vHYObQT263/L6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGAQMGCAUABAIAAAA="
}'
```
* `signedTransaction` — signed transaction in Base64 encrypted format.
Example response:
```json
{
"result": {
"transactionId": "0x0628743b05ffb4c9d5ea2144b359af38910f0ae439a685f57d85b50b9481ba3f",
"slot": 17168395,
"signerAccounts": [
"C83GxcNFTC2tK22rLCCrLKYRkckbNVGsjethN5iswgfC"
],
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `transactionId` — block hash in which the transaction was included.
* `slot` — period of time during which each leader collects transactions and creates a block in the Solana network.
* `signerAccounts` — account addresses that signed the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
## What's Next?
* [Getting Started](doc:staking-solana).
* [Withdrawal](doc:withdrawal-solana).
* [Staking API](ref:solana-2) reference.
---
## Solana Staking Deactivate
*Source: [https://docs.p2p.org/reference/solana-staking-deactivate.md](https://docs.p2p.org/reference/solana-staking-deactivate.md)*
# Create Deactivate Stake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/solana/{network}/staking/deactivate": {
"post": {
"operationId": "solana-staking-deactivate",
"summary": "Create Deactivate Stake Request",
"description": "Create deactivate stake request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "
Solana network:
`mainnet-beta` — production network.
`testnet` — testnet.
",
"schema": {
"enum": [
"mainnet-beta",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"feePayer": {
"type": "string",
"description": "Account address that will pay the fee for the transaction.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"nonceAccount": {
"type": "string",
"description": "Account address that keeps the value of the nonce.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"computeUnitLimit": {
"type": "number",
"description": "Maximum computational effort limit for the transaction measured in compute units.",
"minimum": 1,
"example": 300
},
"computeUnitPrice": {
"type": "number",
"description": "Price of compute unit for transaction.",
"minimum": 1,
"example": 20000
},
"stakeAccount": {
"type": "string",
"description": "Account address that stores tokens for staking.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"stakeAuthority": {
"type": "string",
"description": "Account address that can perform staking operations with staking account.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
}
},
"required": [
"feePayer",
"stakeAccount",
"stakeAuthority"
],
"x-readme-ref-name": "DeactivateRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"feePayer": {
"type": "string",
"description": "Account address that will pay the fee for the transaction.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"stakeAccount": {
"type": "string",
"description": "Account address that stores tokens for staking.",
"example": "Fw82VhehY4yazX6tcZfNQWTsqHDSXaGmwVkbJYegDMbG"
},
"stakeAuthority": {
"type": "string",
"description": "Account address that can perform staking operations with staking account.",
"example": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
},
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcJjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+jagnMHpK8BDHt0PpssHwXGD2fBxS6MWBoxptD2u9TvrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NjSeWM5+GSJdoQd43Al9SVVXC9FfWGwbe7icpomwAUGodgXkTdUKpg0N73+KnqyVX9TXIp4citopJ3AAAAAAAah2BelAgULaAeR5s5tuI4eW3FQ9h/GeQpOtNEAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAan1RcZNYTQ/u2bs0MdEyBr5UQoG1e4VmzFN1/0AAAAijW940iwWddz25ZC37fI0ue5fa+eTbC2ynBM3b0t4pcDAgMAAQBgAwAAAI5ELeF3F+N1ZPBWe0G1FV0heaKPY7e8dg5tBPbrf8voBAAAAAAAAABzZWVkgJaYAAAAAADIAAAAAAAAAAah2BeRN1QqmDQ3vf4qerJVf1NcinhyK2ikncAAAAAABAIBB3QAAAAAjkQt4XcX43Vk8FZ7QbUVXSF5oo9jt7x2Dm0E9ut/y+iORC3hdxfjdWTwVntBtRVdIXmij2O3vHYObQT263/L6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGAQMGCAUABAIAAAA="
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"feePayer",
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "DeactivateResult"
}
]
}
}
}
}
}
}
},
"tags": [
"Solana"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Signing Transaction Babylon
*Source: [https://docs.p2p.org/docs/signing-transaction-babylon.md](https://docs.p2p.org/docs/signing-transaction-babylon.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the Bitcoin network, follow these steps from the *README* of [this repository](https://github.com/p2p-org/babylon-btc-sign):
1. Initialize the service by installing dependencies.
2. In the *config.js* file, set your private key and specify the network.
3. Sign the transaction using the code.
4. Finally, send the signed transaction to the Bitcoin network by making a POST request to [/api/v1/babylon-btc/\{network}/transaction/send](ref:babylon-transaction-send).
Example request (for `sigNet` network):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/babylon-btc/signet/transaction/send \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"tranasctionHex": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000",
"maxFee": 1000000
}`
```
* `transactionHex` — signed transaction in the hexadecimal format which needs to be broadcasted to the network.
* `maxFee` — maximum fee in SATOSHI that can be charged for processing the transaction (1 BTC = 10⁸ SATOSHI).
Example response:
```json
{
"error": null,
"result": {
"transactionHash": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000"
}
}
```
* `transactionHash` — hash of the transaction.
# What's Next?
* [Getting Started](doc:staking-babylon).
* [Withdrawal](doc:withdrawal-babylon).
* [Staking API](ref:babylon-stake) reference.
---
## Signing Transaction Cosmos
*Source: [https://docs.p2p.org/docs/signing-transaction-cosmos.md](https://docs.p2p.org/docs/signing-transaction-cosmos.md)*
# Sign and Broadcast Transaction
To sign and broadcast a transaction to the Cosmos network, follow these steps:
1. Prepare unsigned transactions in Base64 encrypted format.
2. Sign the transaction using your preferred Cosmos signing method.
3. Broadcast the signed transaction to the Cosmos network by making a POST request to [/api/v1/cosmos/\{network}/transaction/send](ref:broadcast-cosmos-transaction).
Example request (for `cosmoshub-4` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/cosmos/cosmoshub-4/transaction/send \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"signedTransaction": "0aab010a9b010a232f636f736d6f732e7374616b696e672e763162657461312e4d736744656c656761746512740a2d636f736d6f733179397765666d6c706d30646a6b74387373656576656b653068747466756b67326136306730721234636f736d6f7376616c6f70657231376c676730337a65397836786b613032667330686877346164347777673035686571723279381a0d0a057561746f6d120434323030120b546865206d65737361676512670a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103b0c7ac278e1941ac0b65d6bd45d541cae58aa584058fbbd822311b8718708c0e12040a020801181312130a0d0a057561746f6d12043539353210dfc30e1a4026d73408f2f516a2a26604cb5a63f3d57262a4462d10931c21d36c1ce9d73d8f7d051f1c4aabc2e3142c7f01a4935b85c5c7d3854e8a3c41f0c218daf2a7b5ef"
}'
```
* `signedTransaction` — signed transaction in Base64 encrypted format which needs to be broadcast to the network.
Example response:
```json
{
"error": null,
"result": {
"status": "success",
"blockId": 18575267,
"fee": 0.005952,
"gas": {
"used": 202947,
"wanted": 238047
},
"transactionHash": "ADD7B2791E1959075D1836D4BCC71ED256CCD724459F9BD8862D85E205075D47"
}
}
```
* `status` — transaction status: `success`, `failed`.
* `blockId` — unique identifier of the block in which the transaction has been included.
* `fee` — total fee in ATOM charged for processing the transaction.
* `gas` — computational effort required to execute the transaction, measured in gas units.
* `used` — amount of gas spent for the transaction.
* `wanted` — maximum gas limit that the transaction initiator was willing to consume for the transaction.
* `transactionHash` — hash of the transaction.
## What's Next?
* [Getting Started](doc:staking-cosmos).
* [Withdrawal](doc:withdrawal-cosmos).
* [Staking API](ref:create-cosmos-stake-transaction) reference.
---
## Avail Transaction Status
*Source: [https://docs.p2p.org/reference/avail-transaction-status.md](https://docs.p2p.org/reference/avail-transaction-status.md)*
# Get Transaction Status
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/transaction/status/{blockHash}/{transactionHash}": {
"get": {
"operationId": "avail-transaction-status",
"summary": "Get Transaction Status",
"description": "Check the status of the transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
"
},
"signedTransaction": {
"type": "string",
"description": "Signed transaction in Base64 encrypted format which needs to be broadcast to the network.",
"example": "0xbd018400cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c011a6fc75a4d779e13a789ce9fe03d5cbb090b1e9833ae38c2c873571b73e2d7393f30bf097d93ca1692d426196f263d609e4d421cef3e017ad8bd388604e47e839502a80006010700e40b5402",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"status": {
"type": "string",
"enum": [
"success",
"failed"
],
"description": "Transaction status.",
"example": "success"
},
"blockHash": {
"type": "string",
"description": "Block hash in which the transaction was included.",
"example": "0x0628743b05ffb4c9d5ea2144b359af38910f0ae439a685f57d85b50b9481ba3f"
},
"blockId": {
"type": "number",
"description": "Unique block identifier.",
"example": "17168395"
},
"extrinsicId": {
"type": "number",
"description": "Unique extrinsic identifier.",
"example": "17177570-2"
},
"transactionHash": {
"type": "string",
"description": "Signed extrinsic transaction in hex format.",
"example": "0xbd018400cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c011a6fc75a4d779e13a789ce9fe03d5cbb090b1e9833ae38c2c873571b73e2d7393f30bf097d93ca1692d426196f263d609e4d421cef3e017ad8bd388604e47e839502a80006010700e40b5402"
},
"signerAccount": {
"type": "string",
"description": "Account that signed the transaction.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"network",
"signedTransaction",
"status",
"blockHash",
"blockId",
"extrinsicId",
"transactionHash",
"signerAccount",
"createdAt"
],
"x-readme-ref-name": "AvailSignTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 119119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
}
]
}
}
},
"examples": {
"TransactionNotFoundException": {
"value": {
"error": {
"code": 119108,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119122
},
"message": {
"type": "string",
"default": "The transaction status could not be obtained because the internal server error occurred."
},
"name": {
"type": "string",
"default": "StatusException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "StatusException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"StatusException": {
"value": {
"error": {
"code": 119122,
"message": "The transaction status could not be obtained because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Unified Api Avail
*Source: [https://docs.p2p.org/docs/unified-api-avail.md](https://docs.p2p.org/docs/unified-api-avail.md)*
# Avail
In the following guide, the integration process for the `avail` chain is covered. The Avail integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Avail-specific details
>
> * `chain` — always set to `avail` for Avail-related requests.
> * `network` — environment in which the transaction is processed: `testnet` or `mainnet`.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
> * `rewardDestinationType` — way of receiving the rewards; the default value is `account`.
> * `rewardDestination` — account address receiving the staking rewards.
> * `targets` — validator accounts selected for staking operations.
# Staking Flow
## 1. Create Bond Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "avail",
"network": "testnet",
"stakerAddress": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"amount": "1000"
}'
```
* `chain` — blockchain network, always set to `avail` for Avail-related requests.
* `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
* `stakerAddress` — account address initiating the bonding transaction.
* `amount` — amount of tokens to bond. AVAIL is used for the `mainnet` network.
Example response:
```json
{
"error": null,
"result": {
"amount": 1000,
"stakerAddress": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"unsignedTransactionData": "0x550104010208...",
"extraData": {
"targets": ["5G6Zhgm59oujA5UW8wMu4XHFP59uenjC2xp1zshyrWVa638J"],
"rewardDestinationType": "account",
"rewardDestination": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"createdAt": "2024-12-19T11:51:03.477Z"
}
}
}
```
* `amount` — amount of tokens to bond. AVAIL is used for the `mainnet` network.
* `stakerAddress` — staking account address receiving the bonded tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `targets` — validators selected in the [targets](https://explorer.availproject.org/#/staking/targets).
* `rewardDestinationType` — type of receiving the rewards:
* `staked` — rewards will be sent to the stash account and added to the current bond (compounding rewards).
* `stash` — rewards will be sent to the stash account as a transferable balance (not compounding rewards).
* `controller` — rewards will be sent to the controller account.
* `account` — default; rewards will be sent to any account specified as a transferrable balance.
* `rewardDestination` — rewards destination account address.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction using the Avail-specific signing logic.
To broadcast the signed transaction to the Avail network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "avail",
"network": "testnet",
"stakerAddress": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"signedTransaction": "0xf1028400365b17c9f769d13458469cf2c0eb89e65bef71e3d86cbc75d07ee7b076ca706f01566c41fdc460e5a2f91003a874f2a8698d83984681b58e58d79c773dd58a80158c58eac3e9589f504d81ed1e82333957c7a06dcc30a12745186b37788e19f388b4000800000102080a00170000a0dec5adc9353603365b17c9f769d13458469cf2c0eb89e65bef71e3d86cbc75d07ee7b076ca706f0a050400b25bf90ee3ce10bce071ef48539e7f2aae424038bffb4a50e1e0d6bf961e982f"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the bonding transaction.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
Example response:
```json
{
"error": null,
"result": {
"status": "success",
"extraData": {
"network": "testnet",
"signedTransaction": "0xf1028400365b17c9f769d13458469cf2c0eb89e65bef71e3d86cbc75d07ee7b076ca706f01566c41fdc460e5a2f91003a874f2a8698d83984681b58e58d79c773dd58a80158c58eac3e9589f504d81ed1e82333957c7a06dcc30a12745186b37788e19f388b4000800000102080a00170000a0dec5adc9353603365b17c9f769d13458469cf2c0eb89e65bef71e3d86cbc75d07ee7b076ca706f0a050400b25bf90ee3ce10bce071ef48539e7f2aae424038bffb4a50e1e0d6bf961e982f",
"blockHash": "0xd46b0f2ea6daa7f1012f7feefc1d2475405654700ea4082e376a4f173ae3b85d",
"blockId": 1145872,
"extrinsicId": 1,
"transactionHash": "0x0ad1243d382fd9782b5c51248905a388ccd992df47397feefb7d1f643e72e8dc",
"signerAccount": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"createdAt": "2024-12-19T11:57:38.626Z"
}
}
}
```
* `status` — transaction status: `pending`, `success` or `failed`.
* `extraData` — additional transaction details:
* `network` — environment in which the transaction is processed.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `blockHash` — block hash in which the transaction has been included.
* `blockId` — unique block identifier.
* `extrinsicId` — unique extrinsic identifier.
* `transactionHash` — signed transaction in the hexadecimal format.
* `signerAccount` — account that signed the transaction.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
# Unstaking Flow
## 1. Create Unstaking Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "avail",
"network": "testnet",
"stakerAddress": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"extra": {
"amount": 500
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiated the bonding transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to unbond. AVAIL is used for the `mainnet` network.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"unsignedTransactionData": "0x34040a0217000050efe2d6e41a1b",
"createdAt": "2024-12-19T13:25:51.320Z",
"extraData": {
"amount": 500
}
}
}
```
* `stakerAddress` — account address initiating the unbonding transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `amount` — amount of tokens to unbond. AVAIL is used for the `mainnet` network.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Avail-specific signing logic.
## 3. Create Withdrawal Request
> 📘
>
> Note that the withdrawal is available only after the unbonding period of \~28 days.
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "avail",
"network": "testnet",
"stakerAddress": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the withdrawal transaction.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "5DHyW8yCpJEAzFm1jyk5qbNXicd3Dg1tyNAEcPVLjTBCQEgG",
"unsignedTransactionData": "0x1c040a0300000000",
"createdAt": "2024-12-19T13:36:13.979Z",
"extraData": {}
}
}
```
* `stakerAddress` — account address initiating the withdrawal transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Avail-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Unified Api Near
*Source: [https://docs.p2p.org/docs/unified-api-near.md](https://docs.p2p.org/docs/unified-api-near.md)*
# Near
In the following guide, the integration process for the `near` chain is covered. The Near integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Near-specific details
>
> * `chain` — always set to `near` for Near-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` only.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in NEAR.
# Staking Flow
## 1. Create Staking Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "near",
"network": "mainnet",
"stakerAddress": "c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc040",
"amount": "1"
}'
```
* `chain` — blockchain network, always set to `near` for Near-related requests.
* `network` — environment in which the transaction is processed: `mainnet` only.
* `stakerAddress` — Near implicit account address initiating the staking transaction.
* `amount` — amount of tokens to stake in NEAR. Minimum amount is 1 NEAR.
Example response:
```json
{
"error": null,
"result": {
"amount": 1,
"stakerAddress": "c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc040",
"unsignedTransactionData": "400000006339636434396461346662336361646535343264363235666139303961633434336537376131636231306530323837646636633562386466376534636330343000c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc0400f146f9cac7e0000130000007032702d6f72672e706f6f6c76312e6e6561723bf366edf6cf4e3890d95360b8fbc35cb7a2290076a0aa1224c256efbeb4caf30100000002110000006465706f7369745f616e645f7374616b65260000007b22616d6f756e74223a2231303030303030303030303030303030303030303030303030227d00203d88792d0000000000a1edccce1bc2d3000000000000",
"createdAt": "2025-02-19T21:48:10.228Z",
"extraData": {
"transactionId": "548f7bce-6e03-411d-9118-2d59a021f177",
"stakeId": "e0081662-8a9c-47b5-9c26-45320b8ce951",
"gasEstimate": {
"amount": "0.025000000000000000",
"gasLimit": "50000000000000"
}
}
}
}
```
* `amount` — amount of tokens to stake in NEAR.
* `stakerAddress` — staking account address receiving the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this staking session.
* `stakeId` — unique identifier for the staking request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated transaction fee in NEAR.
* `gasLimit` — maximum gas limit for processing the transaction in yoctoNEAR (1 NEAR = 10¹⁸ yoctoNEAR).
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction.
To broadcast the signed transaction to the Near network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "near",
"network": "mainnet",
"signedTransaction": "400000006339636434396461346662336361646535343264363235666139303961633434336537376131636231306530323837646636633562386466376534636330343000c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc04012146f9cac7e0000130000007032702d6f72672e706f6f6c76312e6e6561728c7d5ee5f77c298039c9ccd944ebb6218a7a036737c12356e75ef912662509870100000002110000006465706f7369745f616e645f7374616b65260000007b22616d6f756e74223a2231303030303030303030303030303030303030303030303030227d00203d88792d0000000000a1edccce1bc2d300000000000000ebc276fccd41088080c127999bd78cc5ecfbb8ce6282638b5cd19e3f465bd402c8cf30f8e5b4aa4fccae9f81d8340862d4748b102e4e2621533e9f788a793705",
"stakerAddress": "c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc040",
"extra": {
"transactionId": "548f7bce-6e03-411d-9118-2d59a021f177"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `stakerAddress` — staking account address receiving the staked tokens.
* `extra` — additional request parameters:
* `transactionId` — unique identifier of the staking transaction, obtained from the previous step.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"transactionHash": "HvnL1nyej4cCJnUbeghqWdxeVFkXdDjroA4yN6zcHv9f"
}
}
}
```
* `extraData` — additional transaction details:
* `transactionHash` — hash of the block in which the transaction has been included.
# Unstaking Flow
## 1. Create Unstaking Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "near",
"network": "mainnet",
"stakerAddress": "c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc040",
"extra": {
"amount": "1"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiated the staking transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to withdraw in NEAR.
Example response:
```json
{
"error": null,
"result": {
"amount": "1",
"stakerAddress": "c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc040",
"unsignedTransactionData": "400000006339636434396461346662336361646535343264363235666139303961633434336537376131636231306530323837646636633562386466376534636330343000c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc0400b146f9cac7e0000130000007032702d6f72672e706f6f6c76312e6e656172afa6fb301707310d7c898f7c9f83fc8bc91be960e3a286145afe416f8c418942010000000207000000756e7374616b65260000007b22616d6f756e74223a2231303030303030303030303030303030303030303030303030227d00203d88792d000000000000000000000000000000000000",
"createdAt": "2025-02-10T22:36:14.547Z",
"extraData": {
"transactionId": "69f8b6f1-8b36-4429-843c-90107cfb5bfb",
"stakeId": "6f102d59-b479-4a87-905b-7572b904bb01",
"gasEstimate": {
"amount": "0.025000000000000000",
"gasLimit": "50000000000000"
}
}
}
}
```
* `amount` — amount of tokens to withdraw in NEAR.
* `stakerAddress` — account address initiated the staking transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this withdrawal session.
* `stakeId` — unique identifier of the withdrawal request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated transaction fee in NEAR.
* `gasLimit` — maximum gas limit for processing the transaction in yoctoNEAR (1 NEAR = 10¹⁸ yoctoNEAR).
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Near-specific signing logic.
## 3. Create Withdrawal Request
> 📘
>
> Note that the withdrawal is available only after the unstaking period, which lasts for 4 epochs (\~72 hours).
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "near",
"network": "mainnet",
"stakerAddress": "c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc040"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the withdrawal transaction.
Example response:
```json
{
"error": null,
"result": {
"amount": "1",
"stakerAddress": "c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc040",
"unsignedTransactionData": "400000006339636434396461346662336361646535343264363235666139303961633434336537376131636231306530323837646636633562386466376534636330343000c9cd49da4fb3cade542d625fa909ac443e77a1cb10e0287df6c5b8df7e4cc0400b146f9cac7e0000130000007032702d6f72672e706f6f6c76312e6e656172afa6fb301707310d7c898f7c9f83fc8bc91be960e3a286145afe416f8c418942010000000207000000756e7374616b65260000007b22616d6f756e74223a2231303030303030303030303030303030303030303030303030227d00203d88792d000000000000000000000000000000000000",
"createdAt": "2025-02-10T22:36:14.547Z",
"extraData": {
"transactionId": "69f8b6f1-8b36-4429-843c-90107cfb5bfb",
"stakeId": "6f102d59-b479-4a87-905b-7572b904bb01",
"gasEstimate": {
"amount": "0.025000000000000000",
"gasLimit": "50000000000000"
}
}
}
}
```
* `amount` — amount of tokens to withdraw in NEAR.
* `stakerAddress` — account address initiated the withdrawal transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this withdrawal session.
* `stakeId` — unique identifier of the withdrawal request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated transaction fee in NEAR.
* `gasLimit` — maximum gas limit for processing the transaction in yoctoNEAR (1 NEAR = 10¹⁸ yoctoNEAR).
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Near-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Unified Api Babylon
*Source: [https://docs.p2p.org/docs/unified-api-babylon.md](https://docs.p2p.org/docs/unified-api-babylon.md)*
# Babylon
In the following guide, the integration process for the `babylon-btc` chain is covered. The Babylon integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key Babylon-specific details
>
> * `chain` — always set to `babylon-btc` for Babylon-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in SATOSHI.
# Staking Flow
## 1. Create Staking Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "babylon-btc",
"network": "testnet",
"stakerAddress": "tb1paty3ht42hj74lfq7608v6uhmlry6yn4hpxefa32ucqyzldzaqrks3juxrs",
"amount": "1",
"extra": {
"stakerPublicKey": "0384b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98"
}
}'
```
* `chain` — blockchain network, always set to `babylon-btc` for Babylon-related requests.
* `network` — environment in which the transaction is processed: `mainnet` or `testnet`.
* `stakerAddress` — account address initiating the staking transaction.
* `amount` — amount of tokens to stake in SATOSHI (1 BTC = 10⁸ SATOSHI). Minimum amount is 1 SATs.
* `extra` — additional request parameters:
* `stakerPublicKey` — staker public key address.
Example response:
```json
{
"error": null,
"result": {
"stakerAddress": "tb1paty3ht42hj74lfq7608v6uhmlry6yn4hpxefa32ucqyzldzaqrks3juxrs",
"unsignedTransactionData": "70736274ff0100db0200000001d234d43d0f49b02eeb06dce44a2bf0ebfada6915d8d933f9d73514d87c6c278a0200000000fdffffff0340420f000000000022512080626985aa1791ea5c368e9c595904d7a5669084172a3be41932716bf9e086df0000000000000000496a47626264340084b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c984bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000969cfc1d0000000000225120eac91baeaabcbd5fa41ed3cecd72fbf8c9a24eb709b29ec55cc0082fb45d00ed000000000001012be73f2d0000000000225120eac91baeaabcbd5fa41ed3cecd72fbf8c9a24eb709b29ec55cc0082fb45d00ed01172084b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c9800000000",
"extraData": {
"stakerPublicKey": "84b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98",
"stakeAmount": 1000000,
"stakingDuration": 150,
"fee": 267,
"finallyProviderPublicKey": "4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c0"
}
}
}
```
* `stakerAddress` — staking account address receiving the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `extraData` — additional transaction details:
* `stakerPublicKey` — staker public key address.
* `stakeAmount` — amount to stake in SATOSHI (1 BTC = 10⁸ SATOSHI).
* `stakingDuration` — time-lock period for staking in Bitcoin blocks. The maximum is 64 000 Bitcoin blocks, which is approximately 15 months. The time lock occurs after the Bitcoin transaction has been included in a mined block.
* `fee` — total fee in SATOSHI charged for processing the transaction.
* `finallyProviderPublicKey` — finality provider public key produced by the Schnorr signature algorithm.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction.
To broadcast the signed transaction to the Babylon network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "babylon-btc",
"network": "testnet",
"stakerAddress": "tb1paty3ht42hj74lfq7608v6uhmlry6yn4hpxefa32ucqyzldzaqrks3juxrs",
"signedTransaction": "02000000000101c3898f041f0984eec6191f1aa8e34630dba7693e0cac897b7a636cdd897939470200000000fdffffff037176000000000000225120c999af7219b587edcbd0495446c75cdf61abc4a8415a3b2e4b1270e8e40ae3d00000000000000000496a47626264340084b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c984bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c0009f9d03e10500000000225120eac91baeaabcbd5fa41ed3cecd72fbf8c9a24eb709b29ec55cc0082fb45d00ed01404534873265173f212b4d74e8aa038cd7d08b7f8d836e450a8ddb0698fdd7436686cdbaf826ddbe6d6c21be14e65bf7a87b12aa0efb24e38846ec2d02602dcb8c00000000"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — staking account address receiving the staked tokens.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"transactionHash": "5bc762103a40f102899b4f06af266fe9047ce824024ef25a5b048b854ddec858"
}
}
}
```
* `extraData` — additional transaction details specific to the network:
* `transactionHash` — hash of the block in which the transaction has been included.
# Unstaking Flow
## 1. Create Unstaking Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "babylon-btc",
"network": "testnet",
"stakerAddress": "tb1paty3ht42hj74lfq7608v6uhmlry6yn4hpxefa32ucqyzldzaqrks3juxrs"
"extra": {
"stakerPublicKey": "0384b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98",
"stakeTransactionHash": "f1b05868cf4f6a43c5d3f89dab36b2f9556b24bd55f66436c8594fb5d693c4e6"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the unstake transaction.
* `extra` — additional request parameters:
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"stakerPublicKey": "84b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98",
"stakeTransactionHash": "5bc762103a40f102899b4f06af266fe9047ce824024ef25a5b048b854ddec858",
"unstakeTransactionHex": "70736274ff01005e020000000158c8de4d858b045b5af24e0224e87c04e96f26af064f9b8902f1403a1062c75b0000000000ffffffff0188360f000000000022512013edabd9b2c7d91d967bcf2bcd8289b821d4cc894738eefeb08ac49af9400ff7000000000001012b40420f000000000022512080626985aa1791ea5c368e9c595904d7a5669084172a3be41932716bf9e086df6215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0a975832ad515ff03b76ce8bb0d40d077cba912fa1da48dce220061f060bea4ee7ef97a6d24c34584e32c874bd3fe429c1319758201d6989b8e1b6de6411fea468b2084b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98ad2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ac2049766ccd9e3cd94343e2040474a77fb37cdfd30530d05f9f1e96ae1e2102c86eba2076d1ae01f8fb6bf30108731c884cddcf57ef6eef2d9d9559e130894e0e40c62cba529cc001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000",
"unstakeFee": 3000
}
}
}
```
* `extraData` — additional transaction details:
* `stakerPublicKey` — staker public key address.
* `stakeTransactionHash` — hash of the initial staking transaction.
* `unstakeTransactionHex` — unsigned transaction for the unstake request in the hexadecimal format. Sign the transaction and submit it to the Bitcoin blockchain to perform the called action.
* `ustakeFee` — total fee in SATOSHI charged for processing the transaction.
## 2. Sign and Send Transaction
Use `unstakeTransactionHex` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Babylon-specific signing logic.
## 3. Create Withdrawal Request
> 📘
>
> Note that the withdrawal is available only after the unstaking period of \~28 days.
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request (for `testnet` network):
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "babylon-btc",
"network": "testnet",
"stakerAddress": "tb1paty3ht42hj74lfq7608v6uhmlry6yn4hpxefa32ucqyzldzaqrks3juxrs",
"amount": "1002282880",
"extra": {
"stakerPublicKey": "0384b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98",
"stakeTransactionHash": "f1b05868cf4f6a43c5d3f89dab36b2f9556b24bd55f66436c8594fb5d693c4e6"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the withdrawal transaction.
* `amount` — amount of tokens to withdraw in SATOSHI (1 BTC = 10⁸ SATOSHI).
* `extra` — additional request parameters:
* `stakerPublicKey` — staker public key.
* `stakeTransactionHash` — hash of the initial staking transaction.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"withdrawalAddress": "tb1paty3ht42hj74lfq7608v6uhmlry6yn4hpxefa32ucqyzldzaqrks3juxrs",
"stakerPublicKey": "84b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98",
"stakeTransactionHash": "df5c7c052e953ea7697f0df6452b40f4d79e5a47eb062f483db7f9aff13cc11c",
"withdrawalTransactionHex": "70736274ff01005e02000000016a10981a428a4c21ff41cd531305497abd4dfc4101e669687aa082714080f16d00000000000500000001e9350f0000000000225120eac91baeaabcbd5fa41ed3cecd72fbf8c9a24eb709b29ec55cc0082fb45d00ed000000000001012b88360f000000000022512013edabd9b2c7d91d967bcf2bcd8289b821d4cc894738eefeb08ac49af9400ff74215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac07ef97a6d24c34584e32c874bd3fe429c1319758201d6989b8e1b6de6411fea46252084b203765094496a32cf8817fba045d0bc8a4dab3256551c41f05a8536141c98ad55b2c001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000",
"fee": 159
}
}
}
```
* `extraData` — additional transaction details:
* `withdrawalAddress` — staker withdrawal address.
* `stakerPublicKey` — staker public key address.
* `stakeTransactionHash` — hash of the initial staking transaction.
* `withdrawalTransactionHex` — unsigned transaction for the withdrawal request in the hexadecimal format. Sign the transaction and submit it to the Bitcoin blockchain to perform the called action.
* `fee` — total fee in SATOSHI charged for processing the transaction.
## 4. Sign and Send Transaction
Use `withdrawalTransactionHex` to [sign and send](doc:unified-api-signing-transaction) the transaction following the Babylon-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Near Signing Transaction
*Source: [https://docs.p2p.org/docs/near-signing-transaction.md](https://docs.p2p.org/docs/near-signing-transaction.md)*
# Near Transaction Signing
To sign and broadcast the transaction to the Near network, follow these steps:
1. Prepare unsigned transaction in Base64 encrypted format.
2. Sign the transaction using the following code:
```typescript
import { KeyPair, Signer } from "near-api-js";
import { signTransaction, Transaction } from "near-api-js/lib/transaction";
import * as sha256 from "js-sha256";
import { KeyPairString, PublicKey } from "near-api-js/lib/utils";
// Private key (ensure this is securely stored)
const PRIVATE_KEY = "ed25519:YOUR_PRIVATE_KEY_HERE";
// Unsigned transaction in hexadecimal format
const RAW_TX_HEX = "YOUR_UNSIGNED_TRANSACTION_HEX";
// Create a signer instance using the private key
function createSigner(privateKey: string): Signer {
const keyPair = KeyPair.fromString(privateKey as KeyPairString);
return {
async getPublicKey() {
return keyPair.getPublicKey();
},
async signMessage(message: Uint8Array) {
const hash = new Uint8Array(sha256.sha256.array(message));
const signature = keyPair.sign(hash);
return {
signature: signature.signature,
publicKey: keyPair.getPublicKey(),
};
},
createKey(accountId: string, networkId?: string): Promise {},
};
}
// Function to sign the transaction
async function signTransactionWithSigner(
tx: Transaction,
signer: Signer
): Promise {
const [, signedTx] = await signTransaction(tx, signer);
const signedTxSerialized = signedTx.encode();
return Buffer.from(signedTxSerialized).toString("hex");
}
// Process the transaction signing
async function processTransaction() {
if (!RAW_TX_HEX) {
throw new Error("❌ Error: RAW_TX_HEX is empty. Insert your transaction!");
}
// Create signer with private key
const signer = createSigner(PRIVATE_KEY);
// Decode transaction from hex format
const tx = Transaction.decode(Buffer.from(RAW_TX_HEX, "hex"));
// Sign the transaction
const signedTxHex = await signTransactionWithSigner(tx, signer);
console.log("✅ Signed Transaction (Hex):", signedTxHex);
}
// Execute signing process
processTransaction().catch(console.error);
```
Upon successful execution, the script prints the signed transaction in the hexadecimal format, ready to be broadcasted:
```Text Bash
✅ Signed Transaction (Hex): 0x...
```
3. Broadcast the transaction to the Near network by sending a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
## What's Next?
* [Networks Supported](doc:unified-api-networks)
* [Getting Started](doc:unified-api-getting-started)
* [Unified API Reference](ref:unified-create-stake-transaction)
---
## Create Celestia Redelegate From Transaction
*Source: [https://docs.p2p.org/reference/create-celestia-redelegate-from-transaction.md](https://docs.p2p.org/reference/create-celestia-redelegate-from-transaction.md)*
# Create Redelegate From Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/celestia/{network}/staking/redelegate/from": {
"post": {
"operationId": "create-celestia-redelegate-from-transaction",
"summary": "Create Redelegate From Request",
"description": "Create redelegate from default validator request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "celestia-mainnet-beta",
"description": "
"
},
"amount": {
"type": "string",
"description": "Amount of tokens."
}
},
"required": [
"denom",
"amount"
],
"x-readme-ref-name": "Amount"
}
},
"gas": {
"type": "string",
"description": "Amount of gas spent for the transaction."
}
},
"required": [
"amount",
"gas"
],
"x-readme-ref-name": "TransactionFee"
}
]
},
"memo": {
"type": "string",
"description": "Arbitrary text data to add to the transactions."
},
"encodedBody": {
"type": "string",
"description": "Processable transaction data encoded in the hexadecimal format."
},
"encodedAuthInfo": {
"type": "string",
"description": "Authorization data, including fee, encoded in the hexadecimal format."
}
},
"required": [
"messages",
"fee",
"encodedBody",
"encodedAuthInfo"
],
"x-readme-ref-name": "TransactionData"
}
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the transaction in the ISO 8601 format."
},
"amount": {
"type": "number",
"format": "decimal",
"description": "Amount of tokens to stake."
},
"currency": {
"type": "string",
"enum": [
"tia",
"utia",
"mtia"
],
"description": "
Currency of the tokens:
`tia` — Celestia native staking token.
`utia` — 1 TIA = 10^-6 UTIA.
`mtia` — 1 TIA = 10^-3 MTIA.
"
},
"sourceValidatorAddress": {
"type": "string",
"description": "Redelegate source validator address.",
"example": "celestiavaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^celestiavaloper[a-zA-Z0-9]{39}$"
},
"destinationValidatorAddress": {
"type": "string",
"description": "Redelegate destination validator address.",
"example": "celestiavaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^celestiavaloper[a-zA-Z0-9]{39}$"
}
},
"required": [
"stashAccountAddress",
"transactionData",
"createdAt",
"amount",
"currency",
"sourceValidatorAddress",
"destinationValidatorAddress"
],
"x-readme-ref-name": "RedelegateTransactionStakingCelestiaResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110113
},
"message": {
"type": "string",
"default": "The request could not be performed because the simulation transaction failed."
},
"name": {
"type": "string",
"default": "SimulationTransactionOnCosmosException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SimulationTransactionOnCosmosException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110114
},
"message": {
"type": "string",
"default": "The request could not be performed because the redelegation to this validator is already in progress. Please try again after the redelegation process will be completed."
},
"name": {
"type": "string",
"default": "RedelegationTransactionInProcessException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "RedelegationTransactionInProcessException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"SimulationTransactionOnCosmosException": {
"value": {
"error": {
"code": 110113,
"message": "The request could not be performed because the simulation transaction failed. undefined",
"type": "client"
},
"result": null
}
},
"RedelegationTransactionInProcessException": {
"value": {
"error": {
"code": 110114,
"message": "The request could not be performed because the redelegation to this validator is already in progress. Please try again after the redelegation process will be completed.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110105
},
"message": {
"type": "string",
"default": "The redelegate request transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "CreateRedelegateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CreateRedelegateTransactionException"
}
]
}
}
},
"examples": {
"CreateRedelegateTransactionException": {
"value": {
"error": {
"code": 110105,
"message": "The redelegate request transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Celestia"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## New Validator Creation
*Source: [https://docs.p2p.org/docs/new-validator-creation.md](https://docs.p2p.org/docs/new-validator-creation.md)*
# New Validator Creation
## Objective
Enable creation of new validators with flexible sizing — from **32 ETH** up to **1920 ETH** — using `0x01` withdrawal credentials via the **standard flow**, or `0x02` credentials via the **simplified smart contract flow**.
> Top-ups support amounts starting from **1 gwei**, but new validator creation requires at least **32 ETH**.
>
> Top-ups require `0x02` withdrawal credentials.
## Standard Flow (Multi-step)
### Applicable scenarios
* You need fine-grained control over validator count, size per validator, and withdrawal credential type
* You intend to manually broadcast deposit transactions
### Endpoints (Ethereum)
* `POST` [/eth/staking/direct/nodes-request/create](ref:eth-nodes-request-create).
* `GET` [/eth/staking/direct/nodes-request/status/\{id}](ref:eth-nodes-request-status)
* `POST` [/eth/staking/direct/tx/deposit](ref:eth-staking-deposit)
### Endpoints (SSV)
* `POST` [/eth/staking/ssv/request/create](ref:ssv-request-create)
* `GET` [/eth/staking/ssv/request/status/\{id}](ref:ssv-request-status)
### Flow
1. Create a validator request by specifying the number of validators and optional parameters like `amountPerValidator` and `withdrawalCredentialsType`.
2. Retrieve deposit data by polling the request status.
3. Broadcast deposit transaction manually.
### Behavior
* If `amountPerValidator > 32 ETH`, the system defaults to `0x02` withdrawal credentials
* You can explicitly set withdrawalCredentialsType to `0x01` or `0x02`. For `0x02` withdrawal credentials, the standard flow ends after deposit data retrieval. Deposit broadcasting and validator activation are not supported for `0x02` in this flow (both in Ethereum and SSV).
* The status response includes validator size, credential type, and `depositData[]`
* SSV flow supports both `0x01` and `0x02` credentials, but for `0x02`, it only supports data generation — not broadcasting or activation.
### Flow Example
#### 1. Create Validator Request
Send a `POST` request to [/api/v1/eth/staking/direct/nodes-request/create](ref:eth-nodes-request-create).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/nodes-request/create \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"id": "f79ad9fe-6cfc-4480-ba80-683c26914971",
"type": "REGULAR",
"validatorsCount": 2,
"withdrawalAddress": "0x368F823e4df...bf8e4a21",
"controllerAddress": "0x368F823e4df...bf8e4a21",
"feeRecipientAddress": "0x368F823e4df...bf8e4a21",
"nodesOptions": {
"location": "any"
}
}'
```
Example response:
```json
{
"error": null,
"result": true
}
```
#### 2. Poll Status to Get Deposit Data
Send a `GET` request to [/api/v1/eth/staking/direct/nodes-request/status/\{id}](ref:eth-nodes-request-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/direct/nodes-request/status/f79ad9fe-6cfc-4480-ba80-683c26914971 \
--header 'Authorization: Bearer '
```
Example response:
```json
{
"error": null,
"result": {
"status": "ready",
"amountPerValidator": "32000000000",
"withdrawalCredentialsType": "0x01",
"depositData": [
{
"pubkey": "0xa6ecac19d...",
"signature": "0xb2a...",
"withdrawalCredentials": "0100000000...bf8e4a21",
"amount": 32000000000,
"depositDataRoot": "0x75348c59...",
"depositMessageRoot": "0x3179df...",
"forkVersion": "10000910",
"eth2NetworkName": "hoodi",
"depositCliVersion": "2.7.0"
},
{
"pubkey": "0xb63e7e5c32f...",
"signature": "0xa0b4...",
"withdrawalCredentials": "0100000000...bf8e4a21",
"amount": 32000000000,
"depositDataRoot": "0x5177528...",
"depositMessageRoot": "0x25c35250...",
"forkVersion": "10000910",
"eth2NetworkName": "hoodi",
"depositCliVersion": "2.7.0"
}
]
}
}
```
* `amountPerValidator` — amount in GWEI. (32 ETH = 32\_000\_000\_000 GWEI)
#### 3. Broadcast Deposit Transaction
> The following broadcast example is only applicable for validators with `0x01` withdrawal credentials.
Send a `POST` request to [/api/v1/eth/staking/direct/tx/deposit](ref:eth-staking-deposit).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/deposit \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"withdrawalAddress": "0x368F823e4df...689917bf8e4a21",
"depositData": [
{
"pubkey": "0xa6ecac19d...",
"signature": "0xb2a...",
"withdrawalCredentials": "0100000000...bf8e4a21",
"amount": 32000000000,
"depositMessageRoot": "0x3179df...",
"depositDataRoot": "0x75348c59...",
"forkVersion": "10000910",
"eth2NetworkName": "hoodi",
"depositCliVersion": "2.7.0"
},
{
"pubkey": "0xb63e7e5c32f...",
"signature": "0xa0b4...",
"withdrawalCredentials": "0100000000...bf8e4a21",
"amount": 32000000000,
"depositMessageRoot": "0x25c35250...",
"depositDataRoot": "0x5177528...",
"forkVersion": "10000910",
"eth2NetworkName": "hoodi",
"depositCliVersion": "2.7.0"
}
]
}'
```
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f904...",
"value": "64000000000000000000",
"chainId": 560048,
"type": 2,
"maxFeePerGas": "2221240288",
"maxPriorityFeePerGas": "79693564"
}
}
```
**Legacy SSV Note**
> Deposit broadcasting is **not supported** for `0x02` credentials via legacy SSV flow.
>
> Only deposit data generation is available at this time.
## Simplified Flow (via Smart Contract 3.1)
> This flow applies only to **Ethereum Direct staking via smart contract 3.1**.
>
> The example below describes a legacy SSV flow and will be updated once SSV 3.1 integration is available.
### Applicable scenarios
* You want to minimize steps and create a validator using a prebuilt transaction
* You intend to use `0x02` withdrawal credentials and avoid manual deposit data handling
### Endpoints
* Ethereum: `GET` [/eth/staking/direct/p2p/deposit](ef:p2p-transaction-direct-deposit)
### Flow
1. Call the endpoint with query parameters: `amount`, `withdrawalAddress`, `controllerAddress`, `feeRecipientAddress`
2. Receive a fully constructed transaction ready for signing and broadcasting.
> This flow is supported for Ethereum Direct staking only and applies exclusively to validators using `0x02` withdrawal credentials.
### Flow Example
#### 1. Get Prebuilt Transaction (Ethereum Direct 3.1)
Example request:
```curl
curl --request GET \
--url "https://api.p2p.org/api/v1/eth/staking/direct/p2p/deposit?amount=32&withdrawalAddress=0x8eB2277e54A2A7db9b7c0D9FA9B78dcB35f74866&controllerAddress=0x8eB2277e54A2A7db9b7c0D9FA9B78dcB35f74866&feeRecipientAddress=0x3202B5B0602274197CcB22B8c02CEC9539990c7c" \
--header 'Authorization: Bearer '
```
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f9025701808312c36c850727b59762839896809423be839a14cec3d6d716d904f09368bbf9c750eb8903782dace9d9000000b90224a49b131b0200000000000000000000008eb2277e54a2a7db9b7c0d9fa9b78dcb35f74866000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000003fcd8d9acac042095dfba53f4c40c74d19e2e9d9000000000000000000000000000000000000000000000000000000000000251c0000000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000e86b78000ed3b7b820ac6a39b46602356daee0602180fefa69a94774c3209a9f5ad1df42aa2c426b1494a39afc4ee79a528dca95807f5a1b518c8fb0a4df1be92b8a8b6e5f4fccf35f3975f9cf64aa92f4896f2553a5ba9fb0b13cabb25f21a2881f027d9703bfa57f45a514fff7bcc1b8020c2a3ab0581cfbb748dfe612a14acef40bc61de068cf3117e8227ab1315e0302f97e17d5b8948aa8071645b27ad74f669783d363fbc7e9dd58c01e535aff418b2fdbff56a55212e25efbc6b963bb048d98ecc1d03020f890bbf7518fd2463afb82ffdf452863268bdae4eae18d6108dce9ef803669f466000000000000000000000000000000000000000000000000c0",
"to": "0x23BE839a14cEc3D6D716D904f09368Bbf9c750eb",
"gasLimit": "10000000",
"data": "0xa49b131b0200000000000000000000008eb2277e54a2a7db9b7c0d9fa9b78dcb35f74866000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000003fcd8d9acac042095dfba53f4c40c74d19e2e9d9000000000000000000000000000000000000000000000000000000000000251c0000000000000000000000003202b5b0602274197ccb22b8c02cec9539990c7c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000e86b78000ed3b7b820ac6a39b46602356daee0602180fefa69a94774c3209a9f5ad1df42aa2c426b1494a39afc4ee79a528dca95807f5a1b518c8fb0a4df1be92b8a8b6e5f4fccf35f3975f9cf64aa92f4896f2553a5ba9fb0b13cabb25f21a2881f027d9703bfa57f45a514fff7bcc1b8020c2a3ab0581cfbb748dfe612a14acef40bc61de068cf3117e8227ab1315e0302f97e17d5b8948aa8071645b27ad74f669783d363fbc7e9dd58c01e535aff418b2fdbff56a55212e25efbc6b963bb048d98ecc1d03020f890bbf7518fd2463afb82ffdf452863268bdae4eae18d6108dce9ef803669f466000000000000000000000000000000000000000000000000",
"value": "64000000000000000000",
"chainId": 1,
"type": 2,
"maxFeePerGas": "30730983266",
"maxPriorityFeePerGas": "1229676"
}
}
```
> amount is in ETH (e.g., "32")
#### 2. Sign and Broadcast transaction
Use the following example of the code to sign and broadcast the withdrawal transaction.
```javascript
require("dotenv").config();
const ethers = require("ethers");
async function signAndBroadcast() {
console.log("Started");
// Enter the serialized transaction
const rawTransaction = process.env.RAW_TRANSACTION;
// Enter the private key of the address used to transfer the stake amount
const privateKey = process.env.PRIVATE_KEY;
// Enter the selected RPC URL
const rpcURL = process.env.RPC_URL;
// Initialize the provider using the RPC URL
const provider = new ethers.providers.JsonRpcProvider(rpcURL);
// Initialize a new Wallet instance
const wallet = new ethers.Wallet(privateKey, provider);
// Parse the raw transaction
const tx = ethers.utils.parseTransaction(rawTransaction);
tx.nonce = await provider.getTransactionCount(wallet.address);
// Enter the max fee per gas and prirorty fee
tx.maxFeePerGas = ethers.utils.parseUnits(
process.env.MAX_FEE_PER_GAS_IN_GWEI,
"gwei"
);
tx.maxPriorityFeePerGas = ethers.utils.parseUnits(
process.env.MAX_PRIORITY_FEE_IN_GWEI,
"gwei"
);
// Sign the transaction
const signedTransaction = await wallet.signTransaction(tx);
// Send the signed transaction
const transactionResponse = await provider.sendTransaction(signedTransaction);
return transactionResponse;
}
signAndBroadcast()
.then((transactionResponse) => {
console.log(
"Transaction broadcasted, transaction hash:",
transactionResponse.hash
);
})
.catch((error) => {
console.error("Error:", error);
})
.finally(() => {
console.log("Finished");
});
```
---
## Get Started
*Source: [https://docs.p2p.org/docs/get-started.md](https://docs.p2p.org/docs/get-started.md)*
# Get Started
Start integrating P2P.org's staking capabilities into your platform in minutes. This guide will help you set up your environment and make your first API call.
## Quick Setup
1. **Get API Access**
To get started with our APIs, you'll need to obtain authentication credentials. Visit our [Authentication Guide](https://docs.p2p.org/docs/authentication) for detailed instructions.
2. **Choose Your Environment**
Production API endpoint:
```
https://api.p2p.org
```
Test environment endpoint:
```
https://api-test.p2p.org
```
3. **Make Your First API Call**
Try creating your first stake transaction using the Unified API (no funds required):
```bash
curl --request POST \
--url https://api-test.p2p.org/api/v1/unified/staking/stake \
--header 'accept: application/json' \
--header 'authorization: Bearer 8aAEXXJsogPZzpAKk1uedM7TYxPvGrBi' \
--header 'content-type: application/json' \
--data '
{
"chain": "polkadot",
"network": "westend",
"stakerAddress": "5FU44bZkd8iza8Sw8xS9QeRamsj9MpcBiwvLBReVDLBmd25q",
"amount": 1
}
'
```
This will return an unsigned transaction that you can review without committing any funds.
## Integration Steps
### 1. Authentication Setup
* Follow our [Authentication Guide](https://docs.p2p.org/docs/authentication) to get your API token
* Use JWT authentication for all API calls
* Include token in Authorization header
### 2. Choose Your Product
* [**Unified API**](https://docs.p2p.org/docs/unified-api-overview): Start here for multi-chain integration
* [**Staking API**](https://docs.p2p.org/docs/staking-overview): Direct staking operations
* [**Restaking API**](https://docs.p2p.org/docs/restaking-overview): Enhanced yield opportunities
* [**DVT Staking API**](https://docs.p2p.org/docs/overview-dvt-solutions): Distributed validation
* [**Data API**](https://docs.p2p.org/docs/overview): Analytics and monitoring
### 3. Test Your Integration
* Use test networks for initial development
* Validate responses and error handling
* Monitor rate limits and usage
### 4. Go Live
* Switch to production endpoints
* Configure network-specific parameters
* Set up monitoring and alerts
## Code Examples
Looking for implementation examples? Check out our [Code Recipes](https://docs.p2p.org/recipes) for ready-to-use code samples and common integration patterns.
Need help? Our [team](https://docs.p2p.org/docs/contacts) is available to assist with your integration.
---
## Polkadot Pool Claim Payout
*Source: [https://docs.p2p.org/reference/polkadot-pool-claim-payout.md](https://docs.p2p.org/reference/polkadot-pool-claim-payout.md)*
# Create Claim Payout Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/staking/pool/claim-payout": {
"post": {
"operationId": "polkadot-pool-claim-payout",
"summary": "Create Claim Payout Request",
"description": "Creating a claim payout request refers to the process of issuing a payout from the validator to the nomination pool members for further rewards claiming.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
Polkadot network:
`mainnet` — Polkadot mainnet.
`kusama` — Kusama mainnet.
`westend` — Polkadot testnet.
",
"schema": {
"enum": [
"mainnet",
"kusama",
"westend"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"extended": {
"type": "string",
"description": "Optional boolean parameter indicating whether to include additional metadata in the response.",
"example": false
},
"stashAccountAddress": {
"type": "string",
"description": "Main stash account address which keeps tokens for bonding.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
}
},
"required": [
"stashAccountAddress"
],
"x-readme-ref-name": "ClaimPayoutRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000"
},
"unsignedTransactionPayload": {
"type": "string",
"description": "Unsigned transaction in serialized format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "7b226164647265...737326164647265732"
},
"unsignedTransactionObject": {
"description": "Unsigned transaction object.",
"allOf": [
{
"type": "object",
"properties": {
"blockHash": {
"type": "string",
"description": "Hash of the checkpoint block in which the transaction was included."
},
"eraPeriod": {
"type": "number",
"description": "Validity period of the transaction, representing the number of blocks after the checkpoint for which the transaction is valid."
},
"currentEra": {
"type": "number",
"description": "Current staking era of the transaction."
},
"genesisHash": {
"type": "number",
"description": "Hash of the genesis block."
},
"metadataRpc": {
"type": "string",
"description": "Serialized metadata used for offline decoding and transaction signing."
},
"method": {
"type": "object",
"description": "List of data fields containing information on the method called to construct a transaction."
},
"nonce": {
"type": "number",
"description": "Nonce of the transaction."
},
"specVersion": {
"type": "number",
"description": "Current version of the chain specification for the runtime."
},
"transactionVersion": {
"type": "number",
"description": "Current version of the transaction format."
},
"tip": {
"type": "number",
"description": "Optional fee used to increase the transaction priority."
}
},
"required": [
"blockHash",
"eraPeriod",
"currentEra",
"genesisHash",
"metadataRpc",
"method",
"nonce",
"specVersion",
"transactionVersion",
"tip"
],
"x-readme-ref-name": "PolkadotUnsignedTransactionObjectResponse"
}
]
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"unsignedTransaction",
"createdAt"
],
"x-readme-ref-name": "TransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119101
},
"message": {
"type": "string",
"default": "The request could not be performed because the address %s provided is invalid. Please specify the correct Avail address."
},
"name": {
"type": "string",
"default": "AddressIsInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "AddressIsInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119103
},
"message": {
"type": "string",
"default": "The transaction could not be found. Please specify the correct transaction data."
},
"name": {
"type": "string",
"default": "BondNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "BondNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119105
},
"message": {
"type": "string",
"default": "The request could not be performed because the controller address does not correspond to the provided one."
},
"name": {
"type": "string",
"default": "WrongControllerException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongControllerException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"AddressIsInvalidException": {
"value": {
"error": {
"code": 107101,
"message": "The request could not be performed because the address undefined provided is invalid. Please specify the correct Polkadot address.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"BondNotFoundException": {
"value": {
"error": {
"code": 107103,
"message": "The transaction could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"WrongControllerException": {
"value": {
"error": {
"code": 107105,
"message": "The request could not be performed because the controller address does not correspond to the provided one.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119137
},
"message": {
"type": "string",
"default": "The claim payout request could not be performed because the internal server error occurred."
},
"name": {
"type": "string",
"default": "ClaimPayoutException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ClaimPayoutException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"ClaimPayoutException": {
"value": {
"error": {
"code": 107137,
"message": "The claim payout request could not be performed because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Polygon Staking Withdraw
*Source: [https://docs.p2p.org/reference/polygon-staking-withdraw.md](https://docs.p2p.org/reference/polygon-staking-withdraw.md)*
# Create Withdraw Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polygon/staking/withdraw": {
"post": {
"operationId": "polygon-staking-withdraw",
"summary": "Create Withdraw Request",
"description": "Withdraw unstaked tokens.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stakerAddress": {
"type": "string",
"description": "Staker account address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
}
},
"required": [
"stakerAddress"
],
"x-readme-ref-name": "WithdrawRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polygon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Data Network Validator Count
*Source: [https://docs.p2p.org/reference/data-network-validator-count.md](https://docs.p2p.org/reference/data-network-validator-count.md)*
# Get Validators Count
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/network/validators-count": {
"get": {
"operationId": "data-network-validator-count",
"summary": "Get Validators Count",
"description": "Method to retrieve network validators count by staking period.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"polygon",
"sui",
"avail",
"ethereum"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stakingPeriodNumber": {
"type": "number",
"description": "Unique identifier for the current staking period.",
"example": 1227
},
"stakingPeriodStart": {
"format": "date-time",
"type": "string",
"description": "Timestamp of the staking period start in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
},
"stakingPeriodEnd": {
"format": "date-time",
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format.",
"example": "2023-08-24T08:23:18.830Z"
},
"validatorsCount": {
"type": "number",
"description": "Validators count for the current staking period.",
"example": 297
},
"updatedAt": {
"format": "date-time",
"type": "string",
"description": "Timestamp of the last update to this data.",
"example": "2023-08-24T08:23:18.830Z"
}
},
"required": [
"stakingPeriodNumber",
"stakingPeriodStart",
"stakingPeriodEnd",
"validatorsCount",
"updatedAt"
],
"x-readme-ref-name": "GetNetworkValidatorsCountResponse"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetNetworkValidatorsCountListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115207
},
"message": {
"type": "string",
"default": "The data for the parameters provided could not be found."
},
"name": {
"type": "string",
"default": "GetNetworkStatsHistoryNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetNetworkStatsHistoryNotFoundException"
}
]
}
}
},
"examples": {
"GetNetworkStatsHistoryNotFoundException": {
"value": {
"error": {
"code": 115200,
"message": "The data for the parameters provided could not be found.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115206
},
"message": {
"type": "string",
"default": "The request could not be performed because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetNetworkStatsHistoryException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetNetworkStatsHistoryException"
}
]
}
}
},
"examples": {
"GetNetworkStatsHistoryException": {
"value": {
"error": {
"code": 115206,
"message": "The request could not be performed because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Network"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Overview
*Source: [https://docs.p2p.org/docs/overview.md](https://docs.p2p.org/docs/overview.md)*
# Overview
Our Staking Data API service is specifically designed to provide comprehensive data information regarding your staking activities, allowing you to stay up-to-date with the status of your assets.
## Features
* **Coverage:** Currently, we support six networks in the Staking Data API — Ethereum, Polkadot, Solana, Sui, Avail, Cosmos Hub, TON, and Polygon. Additionally, we operate in more than 37 networks, continually adding data for all networks we support. Moreover, we have universal EVM and Cosmos SDK indexers and can promptly integrate any new networks.
* **Cross-Network Integration:** Our architecture is built with flexibility in mind. Our API allows you to streamline all your networks through a unified single data integration, saving considerable resource time.
* **Data Latency:** Our data latency ranges from 30 minutes to 1 day depending on the network. We continuously boost our data latency and focus on achieving near real-time data by using streaming infrastructure.
* **Speed and Volume:** We can provide a millisecond response for any data in the Staking Data API with a 200 RPS load.
* **Quality:** As we internally use all the data for accounting and analytical purposes, we conduct thousands of data quality tests. Additionally, we have a disaster recovery architecture for the Staking Data API and most of the data pipelines.
* **Customization:** We can promptly implement new API methods and customize existing ones to meet your specific requests.
## What's Next?
* [Network Supported](doc:networks-supported-data-api)
* [Getting Started](doc:getting-started-data-api)
* [Network Data API](doc:network).
* [Validator Data API](doc:validator).
* [Delegator Data API](doc:data-delegator).
---
## Eth Staking Withdrawal Partial
*Source: [https://docs.p2p.org/reference/eth-staking-withdrawal-partial.md](https://docs.p2p.org/reference/eth-staking-withdrawal-partial.md)*
# Prepare Partial or Full Withdrawal Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/direct/tx/withdrawal/partial": {
"post": {
"operationId": "eth-staking-withdrawal-partial",
"summary": "Prepare Partial or Full Withdrawal Transaction",
"description": "Construct a serialized transaction to initiate the partial or full withdrawal process for active validators.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"pubkey": {
"description": "Validator public key.",
"example": [
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
],
"items": {
"type": "string"
},
"type": "array"
},
"amount": {
"description": "Amount of tokens to withdraw in ETH. Can be a single number, an array of numbers, or null. If specified as 0, the validator will be fully withdrawn.",
"example": "1",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"pubkey"
],
"x-readme-ref-name": "PartialWithdrawalEthereumRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
}
},
"required": [
"list"
],
"x-readme-ref-name": "EthereumUnsignedTransactionListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103114
},
"message": {
"type": "string",
"default": "The withdrawal transaction could not be created because the signature of the deposit data is invalid. Please re-sign the serialized transaction by following https://docs.p2p.org/docs/signing-transaction-eth."
},
"name": {
"type": "string",
"default": "InvalidDepositDataSignException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidDepositDataSignException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103105
},
"message": {
"type": "string",
"default": "The transaction could not be created because the validator public keys provided are invalid or do not exist."
},
"name": {
"type": "string",
"default": "PubkeyDoNotExistsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PubkeyDoNotExistsException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103106
},
"message": {
"type": "string",
"default": "The transaction could not be created because one or more validators are not participating currently in the validator activities."
},
"name": {
"type": "string",
"default": "ValidatorNotActiveException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorNotActiveException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103147
},
"message": {
"type": "string",
"default": "The transaction could not be created because the validator is not consolidated."
},
"name": {
"type": "string",
"default": "ValidatorNotConsolidatedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorNotConsolidatedException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103148
},
"message": {
"type": "string",
"default": "The transaction could not be created because the amount of Gwei provided is invalid."
},
"name": {
"type": "string",
"default": "WrongAmountLenghtException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongAmountLenghtException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103150
},
"message": {
"type": "string",
"default": "The transaction could not be created because the validator is not old enough."
},
"name": {
"type": "string",
"default": "ValidatorNotOldEnoughException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorNotOldEnoughException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103152
},
"message": {
"type": "string",
"default": "Error while pubkeys has duplicates"
},
"name": {
"type": "string",
"default": "PubkeysDuplicatesException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PubkeysDuplicatesException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103153
},
"message": {
"type": "string",
"default": "The transaction could not be created due to wrong amount"
},
"name": {
"type": "string",
"default": "PartialWithdrawalWrongAmountException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PartialWithdrawalWrongAmountException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidDepositDataSignException": {
"value": {
"error": {
"code": 103114,
"message": "The withdrawal transaction could not be created because the signature of the deposit data is invalid. Please re-sign the serialized transaction by following https://docs.p2p.org/docs/signing-transaction-eth.",
"type": "client"
},
"result": null
}
},
"PubkeyDoNotExistsException": {
"value": {
"error": {
"code": 103105,
"message": "The transaction could not be created because the validator public keys provided are invalid or do not exist.",
"type": "client"
},
"result": null
}
},
"ValidatorNotActiveException": {
"value": {
"error": {
"code": 103106,
"message": "The transaction could not be created because one or more validators are not participating currently in the validator activities.",
"type": "client"
},
"result": null
}
},
"ValidatorNotConsolidatedException": {
"value": {
"error": {
"code": 103147,
"message": "The transaction could not be created because the validator is not consolidated.",
"type": "client"
},
"result": null
}
},
"WrongAmountLenghtException": {
"value": {
"error": {
"code": 103148,
"message": "The transaction could not be created because the amount of Gwei provided is invalid.",
"type": "client"
},
"result": null
}
},
"ValidatorNotOldEnoughException": {
"value": {
"error": {
"code": 103150,
"message": "The transaction could not be created because the validator is not old enough.",
"type": "client"
},
"result": null
}
},
"PubkeysDuplicatesException": {
"value": {
"error": {
"code": 103152,
"message": "Error while pubkeys has duplicates",
"type": "client"
},
"result": null
}
},
"PartialWithdrawalWrongAmountException": {
"value": {
"error": {
"code": 103153,
"message": "The transaction could not be created due to wrong amount",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103104
},
"message": {
"type": "string",
"default": "The Web3 transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "Web3CreateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "Web3CreateTransactionException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"Web3CreateTransactionException": {
"value": {
"error": {
"code": 103104,
"message": "The Web3 transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Ethereum"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Staking Sui
*Source: [https://docs.p2p.org/docs/staking-sui.md](https://docs.p2p.org/docs/staking-sui.md)*
# Getting Started
Staking in the Sei network using the Staking API consists of the following main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
3. Optionally, track the stake status to confirm activation.
> Amounts must be specified in MIST (1 SUI = 1,000,000,000 MIST).
[Get an authentication token](doc:authentication) to start using Staking API.
Request examples are provided using [cURL](https://curl.se/).
## 1. Create Stake Transaction
Send a `POST` request to [/api/v1/sei/\{network}/staking/stake](ref:create-sei-stake-transaction).
Example request (for `testnet` network):
```curl
curl --request POST
--url 'https://api-test.p2p.org/api/v1/sui/testnet/staking/stake' \
--header 'accept: application/json' \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"sender": "0x696f4402d7151fb49e52b629de3ce3098f3dda7721a7425c000b4f26653709e3",
"gasPrice": 1000,
"gasBudget": 500000000,
"amount": 1000000000
}'
```
* `sender` — your SUI wallet address.
* `gasPrice` — gas price in MIST.
* `gasBudget` — maximum gas budget for the transaction.
* `amount` — amount to stake, in MIST.
Example response:
```json
{
"error": null,
"result": {
"unsignedTransaction": "0x000003000800ca9a3b00000000010100000000000000000000000000000000000000000000000000000000000000050100000000000000010020ab4fb3eeaa7b0ab4f91eedab33adf140c6750e60ca5e44b3df82491937d7bab4020200010100000000000000000000000000000000000000000000000000000000000000000000030a7375695f73797374656d11726571756573745f6164645f7374616b650003010100020000010200696f4402d7151fb49e52b629de3ce3098f3dda7721a7425c000b4f26653709e3024af02b603f7d65cced30be6ed44300d7d9d66522940e501e1a2083cfc25429e5a60bd0140000000020abca58a9797ecf7cc82596d71b4a154f8dd14b18e3190beee205b905611fbfa29c6ca3ef6b075ab6294342fe06c323768659879813e0544d3fd25a7db7875cca440000180000000020405515b0e64b00c04ebdb0517c2a1f07f3e32cba49adf4ea87d4daadc265c1f0696f4402d7151fb49e52b629de3ce3098f3dda7721a7425c000b4f26653709e3e8030000000000000065cd1d0000000000"
}
}
```
* `unsignedTransaction` — serialized, unsigned transaction in Base64 format.
## 2. Sign and Send Transaction
Use `transactionData` to [sign and send](doc:signing-transaction-sui) the signed transaction to the Sei network.
## 3. Optionally, track the stake status to confirm activation.
To view your staking position and status, use the following endpoint:
Send a `GET` request to [/api/v1/sei/\{network}/transaction/stake-list/\{address}](ref:sui-transactio-get-stake-list).
Example request (for `testnet` network):
```curl
curl --request GET
--url 'https://api-test.p2p.org/api/v1/sui/testnet/transaction/stake-list/0x696f4402d7151fb49e52b629de3ce3098f3dda7721a7425c000b4f26653709e3' \
--header 'Authorization: Bearer '
```
Example response:
```json
{
"error": null,
"result": {
"validatorAddress": "0xab4fb3eeaa7b0ab4f91eedab33adf140c6750e60ca5e44b3df82491937d7bab4",
"stakerAddress": "0x696f4402d7151fb49e52b629de3ce3098f3dda7721a7425c000b4f26653709e3",
"stakes": [
{
"stakeId": "0x5d920b8fca6a6043d898ab1a9a8ab167d8aa323fe2b9e76a27312f7f16e20a67",
"amount": 1000000000,
"status": "Pending"
}
]
}
}
```
Stake status values:
* `Pending` — The stake has been submitted and is awaiting activation.
* `Active` — The stake is active and earning rewards. Activation may take up to 12 hours depending on validator configuration.
* `Unstaked` — The stake has been withdrawn.
> Note: You will need the stakeId to perform a withdrawal later.
## What's Next?
* [Sign and Send Transaction](doc:signing-transaction-sui).
* [Withdrawal](doc:withdrawal-sui).
* [Staking API](ref:sui) reference.
---
## Polygon Staking Redelegate
*Source: [https://docs.p2p.org/reference/polygon-staking-redelegate.md](https://docs.p2p.org/reference/polygon-staking-redelegate.md)*
# Create Redelegate Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polygon/staking/redelegate": {
"post": {
"operationId": "polygon-staking-redelegate",
"summary": "Create Redelegate Request",
"description": "Redelegate tokens from another validator.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"fromValidatorId": {
"type": "string",
"description": "From validator ID.",
"example": "12"
},
"toValidatorId": {
"type": "string",
"description": "To validator ID.",
"example": "18"
},
"amount": {
"type": "string",
"description": "Amount of tokens to delegate, specified in 10^(-18) MATIC",
"example": "100000000000000000"
},
"stakerAddress": {
"type": "string",
"description": "Staker account address.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
}
},
"required": [
"fromValidatorId",
"toValidatorId",
"amount",
"stakerAddress"
],
"x-readme-ref-name": "RedelegateRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polygon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Ethereum Staking A Comprehensive Guide
*Source: [https://docs.p2p.org/docs/ethereum-staking-a-comprehensive-guide.md](https://docs.p2p.org/docs/ethereum-staking-a-comprehensive-guide.md)*
# Ethereum Staking 101
Ethereum staking represents the process of participating in the validation of transactions on the Ethereum blockchain, which has transitioned to a Proof-of-Stake (PoS) consensus mechanism following [The Merge](https://ethereum.org/en/roadmap/merge/) update. This is a crucial element of the Ethereum ecosystem as it not only contributes to the security of the network but also allows participants to earn rewards for their contribution. Here’s what you need to know to start staking Ethereum.
## Understanding Ethereum Staking
Ethereum's transition to PoS invited participants, dubbed validators, to stake ETH as a security deposit to validate transactions and create new blocks. This mechanism enhances network security and energy efficiency compared to the former Proof-of-Work (PoW) system.
### What is Staking?
Staking involves locking up a certain amount of cryptocurrency (in this case, Ether) to participate in the functioning of a blockchain network. This participation includes validating transactions and maintaining network security. Stakers, in return, receive rewards for their contributions.
[Ethereum Launchpad](https://launchpad.ethereum.org/) serves as the official starting point for individuals aiming to become validators on the Ethereum network. It's a user-friendly platform designed to guide users through the staking process, ensuring they meet the necessary requirements and understand the commitments involved. Launchpad educates prospective validators on the risks and responsibilities of staking, providing a streamlined path from initial interest to active participation. This includes detailed instructions on setting up validator software, contributing to making the Ethereum network more decentralized and secure.
### What is a Deposit?
A deposit in the context of Ethereum staking refers to the act of locking up 32 ETH as a commitment to become a network validator. This deposit is a prerequisite for participating in transaction validation and block proposal processes in Ethereum 2.0's PoS consensus mechanism.
### What is a Validator?
A validator in the Ethereum network is a participant who stakes 32 ETH to validate transactions, propose new blocks, and maintain the network's security within its Proof-of-Stake (PoS) mechanism. Validators are crucial for the integrity and continuity of the blockchain, being rewarded for their contributions and penalized for any actions that jeopardize the network's operation. They run node software, enabling them to take part in the consensus process, ensuring Ethereum remains decentralized and secure. The balance of rewards and penalties incentivizes validators to act in the network's best interest.
Validators are at the core of Ethereum's PoS consensus mechanism. They are selected to propose new blocks and validate transactions. For their service, validators earn rewards, but they also face penalties and slashing for downtime or malicious actions.
## Creating a Deposit
Creating a deposit for staking in Ethereum 2.0 is a critical step towards becoming a validator. This process involves several key actions and requires attention to detail to avoid any errors that could potentially lead to financial loss or other issues. Here's a more detailed breakdown:
* **Amount of ETH to Stake**: A minimum of 32 ETH is required for staking as a single validator. This is a fixed threshold set by the Ethereum 2.0 protocol to ensure validators have a vested interest in the network's security.
* **Validator's Public Key**: The public key is part of the validator's cryptographic key pair (public and private keys) used for signing and verifying transactions and messages within the network. It identifies the validator on the network and is crucial for the operation and security of your validator node.
* **Withdrawal Credentials**: These credentials are necessary for withdrawing staked ETH and rewards after the validator exits or is no longer active. Withdrawal credentials protect your funds by ensuring that only the entity in possession of the corresponding private key can access them.
* **Signature from the Validator's Private Key**: The deposit must be signed with the validator's private key. This signature is a cryptographic proof that the validator is indeed the one making the deposit. It secures the transaction against unauthorized actions.
**Timing Considerations**
* **Deposit Transmission Time**: After being submitted, the deposit typically appears on the Ethereum blockchain within a few minutes, depending on the current network congestion. However, the Beacon Chain's recognition of the deposit and the transition from "Pending" to "Processed" status may take several hours or more during periods of high demand.
* **Activation Queue**: After the deposit has been processed, validators enter a queue for activation. The waiting time in this queue can vary significantly, from a few days to several weeks, depending on the number of validators awaiting activation. The Ethereum protocol dynamically manages the number of validators that can be activated in each epoch (approximately 6.4 minutes long) to ensure gradual and controlled growth of the validator set.
**Important Considerations**
Double-Check All Inputted Data: Before confirming the deposit, it is essential to verify all information meticulously. Errors in the deposit transaction, such as incorrect public keys or withdrawal credentials, cannot be reversed and might result in the permanent loss of ETH or affect your ability to withdraw funds in the future.
**Initiating the Staking Transaction**:
* To begin staking, the deposit, along with the necessary data points, must be sent to the Ethereum 2.0 deposit contract. This contract is responsible for registering validators and managing their deposits.
* Ensure you have enough ETH not only for the deposit but also to cover transaction fees. These fees vary based on network congestion and can be significant during periods of high demand.
## Deposit Statuses
Deposits can have various statuses, reflecting the stage of the staking process:
* **Pending**: This status indicates that your deposit has been made to the Ethereum 2.0 contract, but it hasn't been processed yet. Your ETH is waiting to be recognized by the network and included in the Beacon Chain.
* **Processed**: At this point, your deposit has been acknowledged by the Beacon Chain and is included in its registry. The deposit is now waiting for the validator to be activated.
* **Active**: Congratulations, your deposit is now linked to an active validator on the Ethereum network. This means you are participating in the consensus process, proposing and attesting to blocks.
* **Exited**: This status indicates that your validator has ceased its active duties. This can happen voluntarily if you decide to stop staking or involuntarily if your validator is slashed for malicious activities or severe downtime.
To track the status of your deposit and validator, the following tools are invaluable:
* [Etherescan](https://etherscan.io/): Use this for initial deposit tracking to confirm your ETH has been successfully sent to the staking contract. Etherscan provides transaction receipts, including success or failure status, gas used, and more.
* [Beaconcha.in](https://beaconcha.in/): A specialized Beacon Chain explorer that allows you to monitor the status of your deposit and validator in real-time. Beaconcha.in offers insights into validator queues, activation, performance metrics, and potential penalties.
## Validator
The process of validator activation in Ethereum 2.0 is a critical step for those who wish to participate in the network's PoS consensus mechanism. Let’s expand on the key phases and responsibilities involved in this process to provide a more detailed view.
### Becoming a Validator
1. **Preparation**: Accumulate at least 32 ETH and familiarize yourself with Ethereum's staking mechanisms.
2. **Technical Setup**: Visit [Ethereum Launchpad](https://launchpad.ethereum.org/), follow the setup guide for execution and consensus clients, and understand the responsibilities and risks involved.
3. **Staking**: Commit your ETH through the Launchpad, completing the necessary steps to activate your validator status.
Becoming a validator is a commitment that contributes to the security and functionality of the Ethereum network, offering rewards but also entailing risks and responsibilities. Potential validators should thoroughly research and prepare to ensure they contribute positively to the network's health.
### Validator Activation Process
**Initial Stage: Deposit and Pending Status**
* **Making the Deposit**: To initiate the journey of becoming a validator, a stake of 32 ETH must be deposited into the official Ethereum 2.0 staking contract. This step is generally swift, with the deposit appearing on the Ethereum blockchain within a few minutes under normal conditions. However, this timing can be affected by the current state of network congestion, potentially leading to delays.
* **Pending Status**: Following the deposit, the transaction is processed by the Ethereum network. During this phase, the deposited ETH is locked, awaiting further action. The validator's status is set to "pending" until the Ethereum network acknowledges and includes the deposit in the Beacon Chain. The amount of time your deposit remains in this status can significantly vary, largely depending on the network's current workload and the queue of pending deposits awaiting recognition by the Beacon Chain.
### During Activation
**Queued for Activation**:
* **Entering the Queue**: After the deposit is recognized, the validator enters a queue. This is due to the protocol's design to limit the number of validators activated in each epoch, which helps manage the network’s growth and maintain its security.
* **Preparation and Monitoring**: Validators in the queue should ensure their node is correctly set up, secure, and fully synchronized with the Ethereum 2.0 blockchain. Continuous monitoring is essential during this stage to avoid any issues that might delay activation or cause the node to miss its activation turn.
### After Activation
**Active Participation**:
* **Beginning of Duties**: Upon activation, validators start their roles in the network's consensus mechanism. This includes proposing new blocks and attesting to blocks they believe should be added to the blockchain.
* **Security and Performance**: An active validator contributes to the overall security and efficiency of the network. It's crucial for validators to maintain a high online uptime and participate honestly in consensus activities to avoid penalties, known as slashing, which can result from actions like double voting or being offline for extended periods.
**Earning Rewards**:
* **Rewards for Participation**: Validators receive rewards for their active participation, specifically for proposing and attesting to blocks. The amount of rewards earned can vary based on several factors, including the total number of active validators and the validator's own performance.
* **Penalties and Slashing**: To incentivize continuous participation and honesty, the Ethereum 2.0 network implements penalty mechanisms. Minor penalties are applied for being offline (inactivity leak), while more severe penalties (slashing) are enforced for malicious activities against the network.
**Maintaining Validator Status**:
* **Continuous Operation**: Validators are expected to run their nodes continuously. Regular software updates, secure key management, and adherence to best security practices are necessary to maintain validator health and optimize reward earning potential.
* **Monitoring Tools**: Utilizing tools like beaconcha.in or other Ethereum 2.0 staking dashboards can help validators monitor their performance, projected rewards, and network status. These tools provide valuable insights that can help in maintaining optimal validator operation.
Becoming and serving as a validator on the Ethereum 2.0 network is a significant commitment that entails responsibility, technical know-how, and ongoing management. However, it also offers the opportunity to contribute to the network’s security and earn rewards for playing a crucial role in the Ethereum ecosystem's evolution.
## Rewards
The rewards mechanism in Ethereum 2.0 is designed to incentivize validators to act in the best interest of the network. By actively participating in the consensus mechanism, validators help secure the network and, in return, receive rewards for their contributions. Here's a deeper dive into the types of activities rewarded and how they are calculated:
### Types of Validator Rewards
* **Block Proposals**: Validators are randomly selected to propose new blocks to the Beacon Chain. When a proposed block is successfully validated by other validators and added to the blockchain, the proposer receives a reward. This process is critical for the continuation of the blockchain and ensures validators are motivated to propose blocks accurately and efficiently.
* **Attestations**: Attestation is the process by which validators vote on the validity and correctness of a block. By attesting to a block, validators confirm that they have seen and verified the block as being correct. Validators are rewarded for these attestations, especially when they quickly attest to blocks that are successfully included in the chain. This mechanism helps the network reach consensus more swiftly and securely.
* **Sync Committees**: Validators may be selected to serve in sync committees, which are responsible for helping light clients stay up-to-date with the state of the blockchain. Sync committees provide signatures that light clients can use to verify the blockchain's state without needing to process every block. Participation in these committees is rewarded, as it plays a vital role in maintaining the network's accessibility and efficiency.
### Reward Calculation and Distribution
* **Epoch-Based Calculation**: Rewards are calculated at the end of each epoch, which is a fixed period of time in the Ethereum 2.0 network. An epoch consists of multiple slots, with each slot representing an opportunity for a block to be proposed.
* **Automatic Addition to Validator’s Balance**: Once rewards are calculated, they are automatically added to the validator's balance within the Beacon Chain. This process is seamless and does not require any action from the validator.
### Compounding of Rewards
* **Stake Increase**: As rewards are added to the validator's balance, their total stake in the network increases. This increased stake can lead to higher rewards over time, as the validator's proportionate share of the total staked ETH grows.
* **Long-Term Earning Potential**: The compounding effect of rewards means that validators who continuously perform their duties well can see significant growth in their staked ETH over time. This serves as an additional incentive for validators to maintain operational excellence and contribute positively to the network's health.
### Considerations for Maximizing Rewards
* **Uptime and Performance**: Validators must ensure their node remains online and operates efficiently to maximize their rewards. Downtime or poor performance can lead to missed opportunities for block proposals and attestations, directly impacting reward potential.
* **Security and Compliance**: Adhering to best security practices and following protocol rules is essential. Slashing penalties for malicious actions or protocol violations can severely reduce a validator’s stake and rewards.
## Penalties
While rewards incentivize validators to act in the best interest of the network, penalties are designed to discourage and penalize undesirable actions. There are primarily two types of penalties:
**1. Inactivity Leaks**
* **Mechanism**: Inactivity leaks are designed to gradually reduce the stakes of validators who fail to participate in consensus activities, effectively decreasing their influence over the network. This penalty applies network-wide during extended periods of non-finality, affecting all validators but impacting inactive ones the most.
* **Purpose**: The primary goal is to prevent inactive validators from causing long-term harm to the network's health. By slowly reducing their stakes, the network encourages validators to maintain a high level of uptime and participation.
* **Recovery**: Validators affected by inactivity leaks can halt the penalty by returning to active participation in consensus activities, demonstrating the system's design to be forgiving and encouraging validators to rectify their status.
**2. Slashing**
* **Severe Misbehavior**: Slashing penalties are reserved for actions deemed explicitly harmful to the network's security, such as double signing or similar slashable offenses. These penalties are more severe than inactivity leaks, reflecting the seriousness of the actions.
* **Proposer Slashing**: This type of slashing targets validators who propose two or more conflicting blocks for the same slot, an action that can lead to network instability or forks.
* **Attester Slashing**: Validators who attest to contradictory block versions for the same epoch are subject to attester slashing. This behavior disrupts the consensus process and threatens network finality.
* **Consequences**: Slashed validators suffer immediate and substantial stake reductions, part of which is burned and part distributed as rewards to whistleblowers who detected and reported the offense. Additionally, slashed validators are removed from the validator set, losing their ability to participate in consensus and earn rewards.
## Conclusion
Ethereum staking is not only a way to earn rewards but also a method to contribute to the security and efficiency of the network. By becoming a validator, you play a direct role in the future of Ethereum.
## References
* Ethereum Launchpad: [https://launchpad.ethereum.org/](https://launchpad.ethereum.org/)
* Official FAQ: [https://launchpad.ethereum.org/en/faq](https://launchpad.ethereum.org/en/faq)
* Validator Specification: [https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/validator.md#becoming-a-validator](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/validator.md#becoming-a-validator)
---
## Pooled Staking Signing Transaction
*Source: [https://docs.p2p.org/docs/pooled-staking-signing-transaction.md](https://docs.p2p.org/docs/pooled-staking-signing-transaction.md)*
# Sign and Broadcast Transaction
To complete any staking, withdrawal, or claim operation on Ethereum, you must sign and broadcast the unsigned transaction provided by the Pooled Staking API.
# 1. Retrieve an Unsigned Transaction
Use the relevant API endpoint (e.g., `/staking/deposit`, `/staking/withdraw`, `/staking/claim`) to obtain an unsigned transaction object:
```json
{
"result": {
"unsignedTransaction": {
"to": "0xba447498dc4c169f2b4f427b2c4d532320457e89",
"data": "0xf9609f08...",
"value": "10000000000000000"
}
}
}
```
* `to` — Recipient (contract) address.
* `data` — Transaction data payload (hexadecimal).
* `value` — Amount of ETH to send (in Wei, as a string).
# 2. Sign the Transaction
Sign the unsigned transaction using your Ethereum private key.\
You can use a variety of libraries and environments; here’s a reference implementation using [ethers.js](https://docs.ethers.org/v5/):
```typescript
import { Wallet, providers, TransactionRequest } from "ethers";
// Example input values (replace with your data)
const PRIVATE_KEY = "";
const RPC_URL = "";
const unsignedTx: TransactionRequest = {
to: "0xba447498dc4c169f2b4f427b2c4d532320457e89",
data: "0xf9609f08...",
value: "10000000000000000" // as string, convert if needed
};
async function signTransaction() {
const provider = new providers.JsonRpcProvider(RPC_URL);
const wallet = new Wallet(PRIVATE_KEY, provider);
const tx = await wallet.populateTransaction(unsignedTx);
// Optionally set gas/gasPrice here
const signedTx = await wallet.signTransaction(tx);
console.log(signedTx);
}
signTransaction();
```
How to run:
```shell
npm install ethers@5.7.2
node signTransaction.js
```
* This script prints a raw signed transaction ready to broadcast.
# 3. Broadcast the Signed Transaction
Send the signed transaction to the Ethereum network using the Pooled Staking API by making a POST request to `/api/v1/eth-pool/[network]/transaction/send` [endpoint](ref:).
Example request:
```curl
curl --request POST \
--url https://api-test.p2p.org/api/v1/eth-pool/hoodi/transaction/send \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"signedTransaction": "0xf86b80...29a0eab2..."
}'
```
* `signedTransaction` — Raw signed Ethereum transaction (hexadecimal).
Example response:
```json
{
"result": {
"network": "mainnet",
"senderAddress": "0x092Af80778ff3c3D27Fd2744C39f6e9326d9AaEe",
"transactionHash": "0x4fbe6e8a6e9ea1d0efc9ea9d4ef6b93714664b7b8a81d81080b24f8894ebc991",
"status": "pending",
"gas": {
"gasLimit": "21000",
"gasPrice": "32000000000",
"used": "21000"
},
"createdAt": "2025-07-11T12:00:00.000Z"
},
"error": null
}
```
* `network` — Ethereum network: mainnet or testnet.
* `senderAddress` — Sender address for the transaction.
* `transactionHash` — Hash of the transaction on Ethereum.
* `status` — Transaction status: pending, success, or failed.
* `gas` — Gas usage details for the transaction.
* `gasLimit` — Maximum gas provided for the transaction.
* `gasPrice` — Price per gas unit (in Wei).
* `used` — Gas actually used.
* `createdAt` — ISO 8601 timestamp when the transaction was accepted for broadcast.
## What's Next?
* [Getting Started](doc:pooled-staking-getting-started)
* [Withdrawal](doc:pooled-staking-withdrawal)
* [Pooled Staking API](ref:) reference
---
## Validator
*Source: [https://docs.p2p.org/docs/validator.md](https://docs.p2p.org/docs/validator.md)*
# Validator
Staking Data API provides methods to retrieve essential information about validators within the network. These endpoints offer insights into a validator's current stake, rewards received, Annual Percentage Yield (APY), and associated fees.
## Methods
### Get Validator Summary
**Endpoint:** [GET /api/v1/\{network}/data/validator/summary](ref:data-validator-summary)
**Description:** Utilize this endpoint to obtain the general basic information about a validator for the period, such as the different types of rewards earned by the validator, the current stake and APY associated with the validator.
### Get Validator Stake
**Endpoint:** [GET /api/v1/\{network}/data/validator/stakes](ref:data-validator-stakes)
**Description:** Utilize this endpoint to monitor the current stake of a validator. Regularly check the stake data to assess the validator's commitment and participation in the network.
### Get Validator Rewards
**Endpoint:** [GET /api/v1/\{network}/data/validator/rewards](ref:data-validator-rewards)
**Description:** Utilize this endpoint to track the different types of rewards earned by the validator. Monitor reward data to assess the validator's performance and profitability.
### Get Validator APY
**Endpoint:** [GET /api/v1/\{network}/data/validator/apy](ref:data-validator-apy)
**Description:** Utilize this endpoint to understand the APY associated with the validator. Regularly check APY data for insights into the validator's long-term performance.
### Get Validator Fee
**Endpoint:** [GET /api/v1/\{network}/data/validator/fee](ref:data-validator-fee)
**Description:** Utilize this endpoint to assess the fees charged by the validator. Monitor fee data to understand the financial implications of choosing a particular validator.
### Get Validator Name
**Endpoint:** [GET /api/v1/\{network}/data/validator/name](ref:data-validator-name)
**Description:** Utilize this endpoint to know the name of the validator.
### Get Validator State
**Endpoint:** [GET /api/v1/\{network}/data/validator/state](ref:data-validator-state)
**Description:** Utilize this endpoint to know the state of the validator.
### Get Validator Delegators Count
**Endpoint:** [GET /api/v1/\{network}/data/validator/delegators-count](ref:data-validator-delegators-count)
**Description:** Utilize this method to automate the monitoring of changes in the number of delegates associated with a specific validator. This allows for timely responses to dynamic delegation changes and ensures proactive management of validator-related data.
### Get Validator Statuses
**Endpoint:** [GET /api/v1/\{network}/data/validator/statuses](ref:data-validator-statuses)
**Description:** Utilize this method to obtain a list of validator statuses. This allows identifying any changes, such as transitions from waiting to active or instances of slashing, and staying informed that you are supporting a reliable and actively participating validator.
## What's Next?
* [Network Data API](doc:network).
* [Delegator Data API](doc:data-delegator).
---
## Dydx
*Source: [https://docs.p2p.org/docs/dydx.md](https://docs.p2p.org/docs/dydx.md)*
# dYdX
In the following guide, the integration process for the `dydx` chain is covered. The dYdX integration aligns with the general [Unified API process](doc:unified-api-getting-started) but with network-specific parameters.
[Get an authentication token](doc:authentication) to start using the Unified API.
Request examples are provided using [cURL](https://curl.se/).
> To check the integration guides for other chains, refer to the [Networks Supported](doc:unified-api-networks) section.
> 📘 Key dYdX-specific details
>
> * `chain` — always set to `dydx` for dYdX-related requests.
> * `network` — environment in which the transaction is processed: `mainnet` only.
> * `stakerAddress` — account address initiating staking, unstaking or withdrawal transactions.
> * `amount` — amount of tokens in dYdX.
> * `extra.additionalAddresses.cosmosPubKey`— staker public key; required only for new accounts that have not performed any transactions before.
# Staking Flow
## 1. Create Staking Request
Send a POST request to [/api/v1/unified/staking/stake](ref:unified-create-stake-transaction).
Example request (for already existing account):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "dydx",
"network": "mainnet",
"stakerAddress": "dydx1tmpp633vf37d67lqnyuxw5a8lvvdaqks5kgtah",
"amount": 0.8
}'
```
* `chain` — blockchain network, always set to `dydx` for dYdX-related requests.
* `network` — environment in which the transaction is processed: `mainnet` only.
* `stakerAddress` — dYdX implicit account address initiating the staking transaction.
* `amount` — amount of tokens to stake in dYdX.
Example request (for a new account):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/stake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "dydx",
"network": "mainnet",
"stakerAddress": "dydx1pq0w7wedwvgttv4zjr99kx6n6e8ennu9c7nh5x",
"amount": 0.8,
"extra": {
"additionalAddresses": {
"cosmosPubKey": "ApmGOJAE6bgmNgawUZa8HA3mGNFehOl69Dst89kHqU5V"
}
}
}'
```
* `chain` — blockchain network, always set to `dydx` for dYdX-related requests.
* `network` — environment in which the transaction is processed: `mainnet` only.
* `stakerAddress` — dYdX implicit account address initiated the staking transaction.
* `amount` — amount of tokens to stake in dYdX.
* `extra` — additional request parameters:
* `extra.additionalAddresses.cosmosPubKey` — staker public key; required for new accounts only.
Example response:
```json
{
"error": null,
"result": {
"amount": 2,
"stakerAddress": "dydx1tmpp633vf37d67lqnyuxw5a8lvvdaqks5kgtah",
"unsignedTransactionData": "",
"createdAt": "2025-04-14T11:13:32.812Z",
"extraData": {
"transactionId": "dea742b5-bd89-4ddf-aa69-dbbf65edb2f0",
"stakeId": "6c058ca1-75af-448c-8db4-bae6c4ea9636",
"gasEstimate": {
"amount": "0.001992075000000000",
"gasLimit": "159366"
}
}
}
}
```
* `amount` — amount of tokens to stake in dYdX.
* `stakerAddress` — staking account address receiving the staked tokens.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this staking session.
* `stakeId` — unique identifier for the staking request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated transaction fee in dYdX.
* `gasLimit` — maximum gas limit estimated for the transaction.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign](doc:unified-api-signing-transaction) the transaction.
To broadcast the signed transaction to the dYdX network, send a POST request to [/api/v1/unified/transaction/broadcast](ref:unified-transaction-send).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/transaction/broadcast \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "dydx",
"network": "mainnet",
"signedTransaction": "",
"stakerAddress": "dydx1tmpp633vf37d67lqnyuxw5a8lvvdaqks5kgtah",
"extra": {
"transactionId": "dea742b5-bd89-4ddf-aa69-dbbf65edb2f0"
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `signedTransaction` — signed transaction in Base64 encrypted format, which contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the network.
* `stakerAddress` — staking account address receiving the staked tokens.
* `extra` — additional request parameters:
* `transactionId` — unique identifier of the staking transaction.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"transactionHash": "834059BE0B72D95F2702DBB082D90F9858A5D71694B772D968390604E518A919"
}
}
}
```
* `extraData` — additional transaction details:
* `transactionHash` — hash of the block in which the transaction has been included.
# Unstaking Flow
## 1. Create Unstaking Request
Send a POST request to [/api/v1/unified/staking/unstake](ref:unified-create-unstake-transaction).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/unstake \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "dydx",
"network": "mainnet",
"stakerAddress": "dydx1pq0w7wedwvgttv4zjr99kx6n6e8ennu9c7nh5x",
"extra": {
"amount": 0.8
}
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiated the staking transaction.
* `extra` — additional request parameters:
* `amount` — amount of tokens to withdraw in dYdX.
Example response:
```json
{
"error": null,
"result": {
"amount": 0.8,
"stakerAddress": "dydx1pq0w7wedwvgttv4zjr99kx6n6e8ennu9c7nh5x",
"unsignedTransactionData": "",
"createdAt": "2025-04-14T12:54:33.472Z",
"extraData": {
"transactionId": "2b185ae0-a97d-4088-9ed0-38b533943fe2",
"stakeId": "9b7114f4-40c1-4c78-984f-1fdffdbe98ac",
"gasEstimate": {
"amount": "0.0024585",
"gasLimit": "196680"
}
}
}
}
```
* `amount` — amount of tokens to withdraw in dYdX.
* `stakerAddress` — account address initiated the staking transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this withdrawal session.
* `stakeId` — unique identifier of the withdrawal request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated transaction fee in dYdX.
* `gasLimit` — maximum gas limit estimated for the transaction.
## 2. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the dYdX-specific signing logic.
## 3. Create Withdrawal Request
> 📘
>
> Note that the withdrawal is available only after the 30-day unbonding period.
Send a POST request to [/api/v1/unified/staking/withdraw](ref:unified-create-withdraw-transaction).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/unified/staking/withdraw \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"chain": "dydx",
"network": "mainnet",
"stakerAddress": "dydx1pq0w7wedwvgttv4zjr99kx6n6e8ennu9c7nh5x"
}'
```
* `chain` — blockchain network.
* `network` — environment in which the transaction is processed.
* `stakerAddress` — account address initiating the withdrawal transaction.
Example response:
```json
{
"error": null,
"result": {
"extraData": {
"transactionHash": "834059BE0B72D95F2702DBB082D90F9858A5D71694B772D968390604E518A919"
}
}
}
```
* `amount` — amount of tokens to withdraw in dYdX.
* `stakerAddress` — account address initiated the withdrawal transaction.
* `unsignedTransactionData` — unsigned transaction in Base64 encrypted format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
* `extraData` — additional transaction details:
* `transactionId` — unique identifier of the transaction within this withdrawal session.
* `stakeId` — unique identifier of the withdrawal request.
* `gasEstimate` — estimated gas usage details:
* `amount` — estimated transaction fee in dYdX.
* `gasLimit` — maximum gas limit estimated for the transaction.
## 4. Sign and Send Transaction
Use `unsignedTransactionData` to [sign and send](doc:unified-api-signing-transaction) the transaction following the dYdX-specific signing logic.
## What's Next?
* [Unified API Reference](ref:unified-create-stake-transaction)
* [Integration Workflow Example](doc:implementation-example)
* [Networks Supported](doc:unified-api-networks)
---
## Networks Supported Staking Api
*Source: [https://docs.p2p.org/docs/networks-supported-staking-api.md](https://docs.p2p.org/docs/networks-supported-staking-api.md)*
# Networks Supported
The table below summarizes all networks supported in the Staking API and the `network` parameter that may be required for the staking endpoints:
| Protocol | `network` - mainnet | `network` - testnet |
| :--------------------------------------------------------------------------- | :------------------------- | :-------------------------------------- |
| [Aptos](https://docs.p2p.org/docs/overview-aptos) | `mainnet` | `testnet` |
| [Avail](https://docs.p2p.org/docs/overview-avail) | `mainnet` | `testnet` (Turing) |
| [Babylon](https://docs.p2p.org/docs/overview-babylon) | `mainnet` | `testnet` |
| Babylon PoS\* | | |
| [Celestia](https://docs.p2p.org/docs/overview-celestia) | `celestia-mainnet-beta` | `celestia-mocha-testnet` |
| [Cosmos ATOM](https://docs.p2p.org/docs/overview-cosmos) | `cosmoshub-4` | |
| [Ethereum](https://docs.p2p.org/docs/ethereum-staking-a-comprehensive-guide) | use `api.p2p.org` base URL | use `api-test.p2p.org` base URL (Hoodi) |
| [Kusama](https://docs.p2p.org/docs/overview-polkadot) | | `kusama` |
| [Polkadot](https://docs.p2p.org/docs/overview-polkadot) | `mainnet` | `westend` (Westend) |
| [Polygon](https://docs.p2p.org/docs/overview-polygon) | use `api.p2p.org` base URL | use `api-test.p2p.org` base URL (Hoodi) |
| [Sei](https://docs.p2p.org/docs/overview-sei) | `pacific-1` | `atlantic-2` |
| [Solana](https://docs.p2p.org/docs/overview-solana) | `mainnet-beta` | `testnet` (Testnet) |
| [Sui](https://docs.p2p.org/docs/overview-sui) | `mainnet` | `testnet` |
| Story Protocol\* | | |
| [TON](https://docs.p2p.org/docs/overview-ton) | `mainnet` (TON Whales) | `testnet` (TON Whales) |
| TRON\* | `mainnet` | |
\*These networks are available with exclusive access - public rollout coming soon. Please [contact us](https://docs.p2p.org/update/docs/contacts) to integrate with any of these networks.
## Testing and production environments
We provide two distinct endpoints for testing and production environments:
* Production: \<[https://api.p2p.org](https://api.p2p.org)>
* Testing: \<[https://api-test.p2p.org](https://api-test.p2p.org)>
---
## Create Sei Unstake Transaction
*Source: [https://docs.p2p.org/reference/create-sei-unstake-transaction.md](https://docs.p2p.org/reference/create-sei-unstake-transaction.md)*
# Create Unstake Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/sei/{network}/staking/unstake": {
"post": {
"operationId": "create-sei-unstake-transaction",
"summary": "Create Unstake Request",
"description": "Create an unstake request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "pacific-1",
"description": "
"
},
"amount": {
"type": "string",
"description": "Amount of tokens."
}
},
"required": [
"denom",
"amount"
],
"x-readme-ref-name": "Amount"
}
},
"gas": {
"type": "string",
"description": "Amount of gas spent for the transaction."
}
},
"required": [
"amount",
"gas"
],
"x-readme-ref-name": "TransactionFee"
}
]
},
"memo": {
"type": "string",
"description": "Arbitrary text data to add to the transactions."
},
"encodedBody": {
"type": "string",
"description": "Processable transaction data encoded in the hexadecimal format."
},
"encodedAuthInfo": {
"type": "string",
"description": "Authorization data, including fee, encoded in the hexadecimal format."
}
},
"required": [
"messages",
"fee",
"encodedBody",
"encodedAuthInfo"
],
"x-readme-ref-name": "TransactionData"
}
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the transaction in the ISO 8601 format."
},
"amount": {
"type": "number",
"format": "decimal",
"description": "Amount of tokens."
},
"currency": {
"type": "string",
"enum": [
"sei",
"usei",
"msei"
],
"description": "Currency of the tokens:
`sei` — Sei native staking token.
`usei` — 1 SEI = 10⁻⁶ uSEI.
`msei` — 1 SEI = 10⁻³ mSEI.
"
},
"validatorAddress": {
"type": "string",
"description": "Validator address to which tokens are delegated.",
"example": "seivaloperjj5m7nku1ZlgyUJJ5kH1Rln3bER6eWHAKwKsgC9",
"pattern": "^seivaloper[a-zA-Z0-9]{39}$"
},
"rewardDestinationAddress": {
"type": "string",
"description": "Reward destination account address.",
"pattern": "^sei[a-zA-Z0-9]{39}$"
}
},
"required": [
"stashAccountAddress",
"transactionData",
"createdAt",
"amount",
"currency",
"validatorAddress",
"rewardDestinationAddress"
],
"x-readme-ref-name": "StakeOrUnstakeTransactionStakingSeiResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110102
},
"message": {
"type": "string",
"default": "The request could not be performed because the amount of tokens staked in the Validator account is insufficient. Please check the balance and specify the correct request parameters."
},
"name": {
"type": "string",
"default": "InsufficientFundsOnCosmosValidatorException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InsufficientFundsOnCosmosValidatorException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InsufficientFundsOnCosmosValidatorException": {
"value": {
"error": {
"code": 110102,
"message": "The request could not be performed because the amount of tokens staked in the Validator account is insufficient. Please check the balance and specify the correct request parameters.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 110104
},
"message": {
"type": "string",
"default": "The unstake request transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "CreateUnstakeTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CreateUnstakeTransactionException"
}
]
}
}
},
"examples": {
"CreateUnstakeTransactionException": {
"value": {
"error": {
"code": 110104,
"message": "The staking request transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Sei"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Staking Babylon
*Source: [https://docs.p2p.org/docs/staking-babylon.md](https://docs.p2p.org/docs/staking-babylon.md)*
# Getting Started
To start staking on the Bitcoin network using the Staking API:
1. Retrieve staker public key address.
2. Create Stake Transaction.
3. Sign and Send the Transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
Request examples are provided using [cURL](https://curl.se/).
> 🚧 Please note
>
> As the Babylon protocol for the mainnet is in the first launching phase, the staking flow is currently limited to only initiating the staking process by submitting time-lock transactions to the Bitcoin blockchain. **No direct rewards is considered until the next launching phase.**
>
> However, early unbonding is possible, see [Withdrawal](doc:waithdrawal-babylon) .
# 1. Retrieve Staker Public Key Address
We request users to specify the staker public key address in the request to ensure it matches the taproot address correctly. To retrieve it, follow these steps from the *README* of [this repository](https://github.com/p2p-org/babylon-btc-sign):
1. Initialize the service by installing dependencies.
2. In the *config.js* file, set your private key and specify the network.
3. Print the public key address using the provided code.
# 2. Create Stake Transaction
Initiate the staking process by sending a POST request to [/api/v1/babylon-btc/\{network}/staking/stake](ref:babylon-stake).
Example request (for `sigNet` network):
```curl curl
curl --request POST \
--url https://api.p2p.org/api/v1/babylon-btc/signet/staking/stake \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json'
--data '
{
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakerAddress": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9",
"stakeAmount": 30000,
"stakingDuration": 150
}'
```
* `stakerPublicKey` — staker public key address.
* `stakerAddress` — staker taproot address.
* `stakeAmount` — amount to stake in SATOSHI (1 BTC = 10⁸ SATOSHI).
* `stakingDuration` — time-lock period for staking in Bitcoin blocks. The maximum is 64 000 Bitcoin blocks, which is approximately 15 months. The time lock occurs after the Bitcoin transaction has been included in a mined block.
Example response:
```json
{
"error": null,
"result": {
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakerAddress": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9",
"stakingAmount": 1000000,
"stakingDuration": 100,
"finallyProviderPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHex": "0,000009998373764507203",
"fee": 1000
}
}
```
* `stakerPublicKey` — staker public key address.
* `stakerAddress` — staker taproot address.
* `stakingAmount` — amount to stake in SATOSHI (1 BTC = 10⁸ SATOSHI).
* `stakingDuration` — time-lock period for staking in Bitcoin blocks.
* `finallyProviderPublicKey` — finality provider public key produced by the Schnorr signature algorithm.
* `stakeTransactionHex` — unsigned transaction in the hexadecimal format. Sign the stake transaction and submit it to the Bitcoin blockchain to perform the called action.
* `fee` — total fee in SATOSHI charged for processing the transaction.
# 3. Sign and Broadcast Transaction
Use `stakeTransactionHex` from the previous step to [sign and send](doc:signing-transaction-eth) the signed transaction to the Bitcoin chain.
To check the transaction status, send a GET request to [/api/v1/babylon-btc/\{network}/transaction/get-by-tx-hash/\{txHash}](ref:babylon-transaction-get-by-tx-hash).
Example request (for `sigNet` network):
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/babylon-btc/signet/transaction/get-by-tx-hash/{txHash} \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json'
```
Example response:
```json
{
"error": null,
"result": {
"stakerPublicKey": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4",
"stakeTransactionHash": "",
"unstakeTransactionHex": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000"
}
}
```
* `stakerPublicKey` — staker public keys.
* `stakeTransactionHash` — hash of the stake transaction.
* `unstakeTrahsactionHex` — unsigned transaction in the hexadecimal format required for unstaking, see [Withdrawal](doc:waithdrawal-babylon).
# What's Next?
* [Sign and Broadcast Transaction](doc:signing-transaction-babylon).
* [Withdrawal](doc:withdrawal-babylon).
* [Staking API](ref:babylon-stake) reference.
---
## Networks Supported Data Api
*Source: [https://docs.p2p.org/docs/networks-supported-data-api.md](https://docs.p2p.org/docs/networks-supported-data-api.md)*
# Networks Supported
| Network | Data scope | Accounts | Time Aggregations | Historical Depth | Latency |
| -------- | :------------------------------------------ | :---------------------------------------------------------- | :---------------- | :--------------- | :-------- |
| Avail | All network | Validator Account, Delegator Account | Era, Daily | No Limit | 2 hours |
| Ethereum | All network | Validator Public Key, Withdrawal Address, Delegator Address | Epoch, Daily | No Limit | 2-4 hours |
| Cardano | All Network Validators, only P2P Delegators | Validator Account, Delegator Account | Daily | No Limit | 1 day |
| Kusama | All network | Validator Account, Delegator Account | Era, Daily | No Limit | 2 hours |
| Moonbeam | All network | Collator Account, Nominator Account | Round, Daily | No Limit | 2 hours |
| Near | All Network Delegators | Delegator Account | Epoch, Daily | Since 2025-03-03 | 2 hours |
| Polkadot | All network | Validator Account, Delegator Account | Era, Daily | No Limit | 2 hours |
| Polygon | All network | Validator Account, Delegator Account | Daily | Up to 2025-02-01 | 1 day |
| Solana | All network | Stake address, Delegator address, Validator vote address | Epoch | Up to epoch #132 | 2 hours |
| Sui | All Network Validators, only P2P Delegators | Validators, Delegators | Epoch | No Limit | 2 hours |
| TON | Only P2P Delegators | Delegator Account | Epoch, Daily | Since 2024-01-01 | 2 hours |
| Vara | All network | Validator Account, Delegator Account | Era, Daily | No Limit | 2 hours |
{`
`}
---
## Withdrawal Polkadot
*Source: [https://docs.p2p.org/docs/withdrawal-polkadot.md](https://docs.p2p.org/docs/withdrawal-polkadot.md)*
# Withdrawal
The withdrawal process in the Polkadot network using the Staking API can be done following these steps:
1. Create Unbond Request: unbond tokens within the Polkadot network that were previously staked or bonded.
> It takes 7 days (28 eras) to unbond on Kusama, 28 days (28 eras) on Polkadot, and 12 hours (2 eras) on Westend.
2. Withdraw Unbonded Request: withdraw tokens within the Polkadot network that were previously unbonded. Note that this request is available after the unbond period.
# Staking directly
## 1. Create Unbond Request
1. Send a POST request to [/api/v1/polkadot/\{network}/staking/unbond](ref:polkadot-staking-unbond).
Example request (for `westend`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/unbond \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount": 3
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `amount` — amount of tokens to unbond. DOT is used for the main network, KSM for Kusama, and WND for Westend.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount": 3,
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `amount` — amount of tokens for bond operations. DOT is used for the main network, KSM for Kusama, and WND for Westend.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
## 2. Withdraw Unbonded Request
1. Send a POST request to [/api/v1/polkadot/\{network}/staking/withdrawal-unbonded](ref:polkadot-staking-withdrawunbonded).
Example request (for `westend`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/withdrawal-unbonded \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
# Staking via a nomination pool
## 1\. Create Unbond Request
1. Send a POST request to [api/v1/polkadot/\{network}/staking/pool/unbond](ref:polkadot-pool-unbond).
Example request (for `westend`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/{network}/staking/pool/unbond \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"amount": 3
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `amount` — amount of tokens to unbond. DOT is used for the main network, KSM for Kusama, and WND for Westend.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"amount": 3,
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `amount` — amount of tokens for bond operations. DOT is used for the main network, KSM for Kusama, and WND for Westend.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
## 2\. Withdraw Unbonded Request
1. Send a POST request to [api/v1/polkadot/\{network}/staking/pool/withdraw-unbonded](ref:polkadot-pool-withdraw-unbonded).
Example request (for `westend`):
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/polkadot/westend/staking/withdrawal-unbonded \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"stashAccountAddress": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5",
"poolId": "1"
}'
```
* `stashAccountAddress` — main stash account address which keeps tokens for bonding.
* `poolId` — ID of the nomination pool in which you participate in.
Example response:
```json
{
"result": {
"unsignedTransaction": "0xac0406000b00487835a302032c6eca5cdaa3e87d7f8e06d10015bf0508b52d301c8991af113d5cf49a53553f",
"createdAt": "2023-08-15T15:07:54.795Z"
}
}
```
* `unsignedTransaction` — unsigned transaction in hex format. Sign the transaction and submit it to the blockchain to perform the called action.
* `createdAt` — timestamp of the transaction in the ISO 8601 format.
2. [Sign and broadcast](doc:signing-transaction-polkadot) the `unsignedTransaction` to the Polkadot network.
## What's Next?
* [Getting Started](doc:staking-polkadot-public).
* [Staking API](ref:polkadot-transaction-status) reference.
---
## Staking Ui Showcase With Unified Api
*Source: [https://docs.p2p.org/docs/staking-ui-showcase-with-unified-api.md](https://docs.p2p.org/docs/staking-ui-showcase-with-unified-api.md)*
# Staking UI Showcase with Unified API
We've provided a [public repository](https://github.com/AndreGZommerfelds/p2p-unified-api-demo-example-1) with a reference implementation demonstrating how crypto intermediaries (exchanges, wallets, and custodians) can integrate P2P.ORG's Unified API to offer staking, unstaking, and withdrawal functionalities to their end-users.
## Overview
The P2P.ORG Unified API Staking Showcase is a functional demonstration of integrating P2P.ORG's Unified API, allowing users to:
* Perform staking operations across multiple blockchain networks
* Execute unstaking transactions
All API interactions are handled through a internal proxy layer that manages authentication and abstracts direct API calls.
## 🚀 Getting Started
### Prerequisites
* Node.js 18.x or later
* npm or yarn
* A P2P.ORG API key
### Installation
1. Clone the repository:
```bash
git clone https://github.com/AndreGZommerfelds/p2p-unified-api-demo-example-1.git
cd p2p-unified-api-demo-example-1
```
2. Install dependencies:
```bash
npm install
# or
yarn install
```
3. Configure environment variables:
```bash
cp .env.example .env
```
4. Edit `.env` with your specific configuration:
5. Run the development server:
```bash
npm run dev
# or
yarn dev
```
6. Open [http://localhost:3000](http://localhost:3000) in your browser.
## 📝 Usage
### Staking Flow
1. Select a blockchain network
2. Select your address and amount to stake
3. Click "Stake" to create a stake request
4. Sign and broadcast the transaction
### Unstaking Flow
1. Select a blockchain network
2. Choose the position to unstake
3. Enter the amount to unstake
4. Click "Unstake"
5. Sign and broadcast the transaction
## 🛠️ Technology Stack
* **Framework**: Next.js (App Router)
* **UI Library**: Shadcn UI
* **Styling**: Tailwind CSS
* **API Proxy**: Next.js API routes
## 💼 Business Advantages of the P2P.ORG Unified API
### Simplified Integration
The P2P.ORG Unified API provides a single integration point for staking operations across 10+ leading networks, including ETH, SOL, BTC (Babylon), TON, DOT, KSM, AVAIL, ATOM, TIA, and MATIC.
### Significant Development Resource Savings
* Integration time can be reduced significantly compared to individual network integrations
* Unified operational flow for staking, unstaking, and withdrawing across all supported networks
### Future-Ready Scalability
* The API is designed to accommodate both existing and future networks
* Adding support for new blockchains requires only updating network parameters
* Long-term flexibility without additional integrations as new networks emerge
## 🔍 Project Structure
The application uses Next.js App Router architecture:
```
/api # API Proxy Routes
/app # Next.js App Router
/components # UI Components
/config # Configuration files
/hooks # Custom React Hooks
/lib # Utilities and API client
/public # Static assets
```
## 📄 API Documentation
For detailed API documentation, please refer to the [P2P.ORG Developer Portal](https://docs.p2p.org/docs/unified-api-overview) or the `/api` directory in this repository for implementation examples.
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## ⚠️ Legal Disclaimer
**DEMONSTRATION PURPOSE ONLY - NOT FOR PRODUCTION USE**
This software is provided strictly as a demonstration and reference implementation of the P2P.ORG Unified API integration. It is not intended, designed, or suitable for production environments or commercial applications.
P2P.ORG PROVIDES THIS SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND.
### Security and Risk Notice
This software has not undergone comprehensive security auditing or penetration testing. Any entity considering adapting this code for their own purposes must:
* Conduct a thorough security assessment and code review
* Implement appropriate security controls and safeguards
* Test extensively in a controlled environment before any production consideration
* Ensure compliance with relevant regulations and industry standards
By using this software, you acknowledge that you have read and understood this disclaimer and agree to these terms.
## 📞 Contact Support
Need assistance with the Unified API implementation? Our product team is ready to help!
If you encounter any issues or have questions about implementation, please reach out to our dedicated support contacts:
* André Zommerfelds: [andre.zommerfelds@p2p.org](mailto:andre.zommerfelds@p2p.org)
When contacting support, please include specific details about your question or issue to help us provide faster and more effective assistance.
***
Built with ❤️ by P2P.ORG
---
## Incremental Staking Top Up
*Source: [https://docs.p2p.org/docs/incremental-staking-top-up.md](https://docs.p2p.org/docs/incremental-staking-top-up.md)*
# Incremental Staking / Top-up
## Objective
Increase the balance of an existing validator by staking additional ETH, up to a total of **2048 ETH**.
## Applicable scenarios
* You want to increase the stake of a validator without creating a new one
* The validator is already active and uses `0x02` withdrawal credentials
## Endpoints
* `POST` [`/api/v1/eth/staking/direct/increment-request/create`](ref:eth-increment-request-create)
* `GET` [`/api/v1/eth/staking/direct/increment-request/status/\{id}`](ref:eth-increment-request-status)
## Flow
1. Submit the `pubkey` of the target validator and the additional `amount` to stake.
2. The system verifies:
* The resulting balance will not exceed **2048 ETH**
* The validator is compatible with top-ups (uses `0x02` credentials)
3. The API returns a transaction payload to be signed and broadcasted.
> This method is currently not supported for SSV validators.
## Flow Example
#### 1. Create Increment Request
Send a POST request to [`/api/v1/eth/staking/direct/increment-request/create`](ref:eth-increment-request-create).
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/increment-request/create \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{
"id": "f293e499-9188-4e01-8e7c-621038967b06",
"pubkeys": [
"0x80001...66ea3e185fc"
],
"amountPerValidator": "10000000000",
"withdrawalAddress": "0x368F...f8e4a21"
}'
```
Example response:
```json
{
"error": null,
"result": true
}
```
#### 2. Check Status & Retrieve Transaction Data
Send a GET request to [`/api/v1/eth/staking/direct/increment-request/status/\{id}`](ref:eth-increment-request-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/direct/increment-request/status/f293e499-9188-4e01-8e7c-621038967b06 \
--header 'Authorization: Bearer '
```
Example response:
```json
{
"error": null,
"result": {
"serializeTx": "0x02f8ab8b0...",
"value": "10000000000",
"to": "0x00000000219ab540356cBB839Cbe05303d7705Fa",
"gasLimit": "100000",
"data": "0x",
"chainId": 560048,
"type": 2,
"maxFeePerGas": "2111533588",
"maxPriorityFeePerGas": "79385672"
}
}
```
---
## Data Delegator Rewards
*Source: [https://docs.p2p.org/reference/data-delegator-rewards.md](https://docs.p2p.org/reference/data-delegator-rewards.md)*
# Get Delegator Rewards
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/delegator/rewards": {
"get": {
"operationId": "data-delegator-rewards",
"summary": "Get Delegator Rewards",
"description": "Get a list of delegator rewards.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum-agg",
"ethereum",
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"sui",
"polygon",
"avail",
"ton",
"near",
"cardano"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Delegator address in the required network.",
"schema": {
"type": "string"
}
},
{
"name": "addressType",
"required": false,
"in": "query",
"description": "
Delegator address type in the required network:
`deposit` — available for the Ethereum network (used by default)
`withdrawal` — available for the Ethereum network
`delegator` — available for the Polygon, Solana, Cosmos, Near, and Sui networks (used by default)
`stake_account` — available for the Solana
`nominator` — available for the TON and Polkadot networks (used by default)
`nominator_reward_account` — available for the Polkadot networks
`all` — aggregate the results over the entire period
.",
"schema": {
"enum": [
"stakingPeriod",
"day",
"all"
],
"type": "string"
}
},
{
"name": "skip",
"required": false,
"in": "query",
"description": "Exclude breakdown by `validator` from the data report.",
"schema": {
"enum": [
"validator"
],
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"limit": {
"type": "number",
"minimum": 1,
"default": 50,
"description": "Number of resources that a single response page contains."
},
"offset": {
"type": "number",
"minimum": 0,
"description": "Number of resources to exclude from a response."
},
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stakingPeriod": {
"type": "number",
"description": "Number of the staking period."
},
"stakingPeriodStart": {
"type": "string",
"description": "Timestamp of the staking period start in the ISO 8601 format."
},
"stakingPeriodEnd": {
"type": "string",
"description": "Timestamp of the staking period finish in the ISO 8601 format."
},
"rewards": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Reward type.",
"enum": [
"consensus",
"execution"
]
},
"amount": {
"type": "number",
"format": "float",
"description": "Amount of tokens in the stake."
},
"amountUsd": {
"type": "number",
"format": "float",
"description": "Amount of tokens in the stake in USD."
},
"currency": {
"type": "string",
"enum": [
"ETH",
"SOL",
"DOT",
"KSM",
"GLMR",
"VARA",
"ATOM",
"MATIC",
"SUI",
"AVAIL",
"TON",
"NEAR",
"ADA"
],
"description": "Currency of the tokens."
},
"recipient": {
"type": "string",
"description": "Rewards recipient address."
}
},
"required": [
"type",
"amount",
"amountUsd",
"currency",
"recipient"
],
"x-readme-ref-name": "Reward"
}
},
"validator": {
"type": "string",
"description": "Validator address."
},
"notFinalized": {
"type": "boolean",
"description": "Boolean flag indicating whether the rewards for the specified epoch have been finalized."
}
},
"required": [
"stakingPeriod",
"stakingPeriodStart",
"stakingPeriodEnd",
"rewards"
],
"x-readme-ref-name": "DelegatorRewards"
}
}
},
"required": [
"limit",
"offset",
"list"
],
"x-readme-ref-name": "GetDelegatorRewardsResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124108
},
"message": {
"type": "string",
"default": "The request could not be performed because the delegator address provided is not valid."
},
"name": {
"type": "string",
"default": "InvalidDelegatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidDelegatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidDelegatorAddressException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the delegator address provided is not valid on the specified network. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115403
},
"message": {
"type": "string",
"default": "The list of delegator rewards could not be obtained because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetDelegatorRewardsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetDelegatorRewardsException"
}
]
}
}
},
"examples": {
"GetDelegatorRewardsException": {
"value": {
"error": {
"code": 115403,
"message": "The list of delegator rewards could not be obtained because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Delegator"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Pectra Upgrade Overview
*Source: [https://docs.p2p.org/docs/pectra-upgrade-overview.md](https://docs.p2p.org/docs/pectra-upgrade-overview.md)*
# Overview
The Ethereum Pectra upgrade brings many **benefits for clients** using ETH or SSV validators.
* Enhanced efficiency & security with validators that can hold more than 32 ETH (up to 2048 ETH). Validators can now be consolidated into one.
* Autocompounded rewards
* You can top up your validators, or withdraw a partial amount
P2P.ORG has introduced a series of improvements to its staking APIs, enabling clients to take full advantage of the new validator capabilities. These changes include support for validator consolidation, incremental staking (top-ups), partial withdrawals, and streamlined validator setup — both for Ethereum and SSV-based validators.
All changes are backward compatible with the current `0x01` validator flow and allow seamless migration to `0x02` withdrawal credentials for enhanced functionality.
## What's New
Feature
Description
API Availability
Validator Consolidation
Merge multiple validators into one with a single withdrawal address
Ethereum & SSV APIs
Partial Withdrawals
Withdraw ETH in excess of 32 ETH
without exiting the validator
Ethereum & SSV APIs
Top-ups (Incremental Staking)
Increase stake on an existing validator up to 2048 ETH
Ethereum & SSV APIs
Simplified Setup
Create 0x02 validators with a single transaction
(via 3.1 contract)
Ethereum & SSV APIs
Backward Compatibility
All existing 0x01 flows remain unchanged and supported
Yes
## Backward Compatibility
The Pectra upgrade introduces new capabilities while maintaining compatibility with all existing validator flows:
* Clients currently using the **0x01 validator setup** can continue without changes.
* All existing methods remain supported.
* New functionality (e.g. validator consolidation, partial withdrawals, top-ups)\
is exposed via **new API methods** or **optional parameters** in existing methods.
This ensures a seamless upgrade path without breaking changes.
## SSV Validator Support under Pectra
P2P.ORG has extended its SSV staking API to fully support the capabilities introduced with the Ethereum Pectra upgrade. This ensures that clients using the SSV Network can benefit from the same validator enhancements as native Ethereum staking users.
**Key Updates:**
* **Unified flow:**\
Most operations (validator consolidation, top-ups, partial withdrawals) use the same API methods for both Ethereum and SSV validators.
* **Validator setup enhancements:**\
The only divergence lies in the validator setup process:
* We've **updated our existing SSV validator creation method** to support **0x02 withdrawal credentials.**
* This enhancement is **fully backward compatible** — clients can still create 0x01 validators as before.
* Support for simplified setup via the **3.1 Smart Contract** is also available.
All SSV staking methods now align with the Ethereum staking API to offer consistent workflows, regardless of your validator backend.
## Next Steps
To get started with the new Pectra-enabled features, we recommend the following workflow:
1. **Review the API overview table** below to understand which methods support new features.
2. **Select the relevant flows** based on your validator type (Ethereum or SSV) and your use case (consolidation, top-up, partial withdrawal, etc.).
3. **Test in the Hoodi testnet** environment (available from May 5).
4. **Refer to the examples section** for complete cURL samples and expected responses.
5. **Reach out to our team** if you need help integrating or have specific questions:\
📧 [andre.zommerfelds@p2p.org](mailto:andre.zommerfelds@p2p.org)
### Overview of Pectra API Enhancements
| Use Case | API Type | SSV Support | Compatibility |
| :------------------------------ | :---------------------- | :----------------------- | :----------------------------- |
| Validator Consolidation | New | Same method | Compatible |
| Set up New Validator | Updated | Updated for 0x02 support | Fully compatible |
| Simplified Setup (3.1 Contract) | New | Available via SSV method | Compatible |
| Upgrade 0x01 to 0x02 | New (via Consolidation) | Supported | Compatible |
| Top-up / Incremental Staking | New | Same method | Compatible |
| Partial Withdrawal | New | Same method | Requires 0x02 withdrawal creds |
| Full Withdrawal | Unchanged | Unchanged | Compatible |
---
## Polkadot Transaction Send
*Source: [https://docs.p2p.org/reference/polkadot-transaction-send.md](https://docs.p2p.org/reference/polkadot-transaction-send.md)*
# Broadcast Transaction
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/polkadot/{network}/tx/send": {
"post": {
"operationId": "polkadot-transaction-send",
"summary": "Broadcast Transaction",
"description": "Broadcast transaction to the Polkadot network.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "westend",
"description": "
"
},
"signedTransaction": {
"type": "string",
"description": "Signed transaction in Base64 encrypted format which needs to be broadcast to the network.",
"example": "0xbd018400cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c011a6fc75a4d779e13a789ce9fe03d5cbb090b1e9833ae38c2c873571b73e2d7393f30bf097d93ca1692d426196f263d609e4d421cef3e017ad8bd388604e47e839502a80006010700e40b5402",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"status": {
"type": "string",
"enum": [
"success",
"failed"
],
"description": "Transaction status.",
"example": "success"
},
"blockHash": {
"type": "string",
"description": "Block hash in which the transaction was included.",
"example": "0x0628743b05ffb4c9d5ea2144b359af38910f0ae439a685f57d85b50b9481ba3f"
},
"blockId": {
"type": "number",
"description": "Unique block identifier.",
"example": "17168395"
},
"extrinsicId": {
"type": "number",
"description": "Unique extrinsic identifier.",
"example": "17177570-2"
},
"transactionHash": {
"type": "string",
"description": "Signed extrinsic transaction in hex format.",
"example": "0xbd018400cc7cb7325ad1208212e2d8ee41a7572e816d53ac1bcac1be5df433486819213c011a6fc75a4d779e13a789ce9fe03d5cbb090b1e9833ae38c2c873571b73e2d7393f30bf097d93ca1692d426196f263d609e4d421cef3e017ad8bd388604e47e839502a80006010700e40b5402"
},
"signerAccount": {
"type": "string",
"description": "Account that signed the transaction.",
"example": "5H6ryBWChC5w7eaQ4GZjo329sEnhvjetSr6MBEt42mZ5tPw5"
},
"data": {
"type": "string",
"description": "Method data."
},
"createdAt": {
"format": "datetime",
"type": "string",
"description": "Timestamp of the transaction in the ISO 8601 format.",
"example": "2023-08-24T08:14:50.455Z"
}
},
"required": [
"network",
"signedTransaction",
"status",
"blockHash",
"blockId",
"extrinsicId",
"transactionHash",
"signerAccount",
"data",
"createdAt"
],
"x-readme-ref-name": "SignTransactionResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119116
},
"message": {
"type": "string",
"default": "The extrinsic could not be found. Please specify the correct transaction data."
},
"name": {
"type": "string",
"default": "ExtrinsicCouldNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ExtrinsicCouldNotFoundException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119125
},
"message": {
"type": "string",
"default": "The transaction has not been run in dry mode"
},
"name": {
"type": "string",
"default": "ExtrinsicCouldNotDryRunException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ExtrinsicCouldNotDryRunException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 107119,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"ExtrinsicCouldNotFoundException": {
"value": {
"error": {
"code": 107116,
"message": "The extrinsic could not be found. Please specify the correct transaction data.",
"type": "client"
},
"result": null
}
},
"ExtrinsicCouldNotDryRunException": {
"value": {
"error": {
"code": 107125,
"message": "The transaction has not been run in dry mode.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119123
},
"message": {
"type": "string",
"default": "The transaction could not be broadcasted because the internal server error occurred."
},
"name": {
"type": "string",
"default": "SendException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "SendException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119113
},
"message": {
"type": "string",
"default": "The transaction has not been broadcasted because it was rejected by the network as usurped."
},
"name": {
"type": "string",
"default": "TransactionUsurpedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionUsurpedException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119117
},
"message": {
"type": "string",
"default": "The transaction has not been broadcasted because the status of the extrinsic could not be obtained."
},
"name": {
"type": "string",
"default": "CouldNotGetStateException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "CouldNotGetStateException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119118
},
"message": {
"type": "string",
"default": "The transaction has not been broadcasted because it was rejected by the server."
},
"name": {
"type": "string",
"default": "ExtrinsicCouldNotSendException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ExtrinsicCouldNotSendException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119112
},
"message": {
"type": "string",
"default": "The transaction has not been broadcasted because it was rejected by the network as invalid."
},
"name": {
"type": "string",
"default": "TransactionInvalidException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionInvalidException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119114
},
"message": {
"type": "string",
"default": "The transaction has not been broadcasted because it was rejected by the network due to timeout."
},
"name": {
"type": "string",
"default": "TransactionFinalityTimeoutException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionFinalityTimeoutException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 119115
},
"message": {
"type": "string",
"default": "The transaction has not been broadcasted because it was rejected by the network as dropped."
},
"name": {
"type": "string",
"default": "TransactionDroppedException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionDroppedException"
}
]
}
}
},
"examples": {
"SendException": {
"value": {
"error": {
"code": 107123,
"message": "The transaction could not be broadcasted because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
},
"TransactionUsurpedException": {
"value": {
"error": {
"code": 107113,
"message": "The transaction has not been broadcasted because it was rejected by the network as usurped.",
"type": "server"
},
"result": null
}
},
"CouldNotGetStateException": {
"value": {
"error": {
"code": 107117,
"message": "The transaction has not been broadcasted because the status of the extrinsic could not be obtained.",
"type": "server"
},
"result": null
}
},
"ExtrinsicCouldNotSendException": {
"value": {
"error": {
"code": 107118,
"message": "The transaction has not been broadcasted because it was rejected by the server.",
"type": "server"
},
"result": null
}
},
"TransactionInvalidException": {
"value": {
"error": {
"code": 107112,
"message": "The transaction has not been broadcasted because it was rejected by the network as invalid.",
"type": "server"
},
"result": null
}
},
"TransactionFinalityTimeoutException": {
"value": {
"error": {
"code": 107114,
"message": "The transaction has not been broadcasted because it was rejected by the network due to timeout.",
"type": "server"
},
"result": null
}
},
"TransactionDroppedException": {
"value": {
"error": {
"code": 107115,
"message": "The transaction has not been broadcasted because it was rejected by the network as dropped.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Polkadot"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Avail Staking Nominate List
*Source: [https://docs.p2p.org/reference/avail-staking-nominate-list.md](https://docs.p2p.org/reference/avail-staking-nominate-list.md)*
# Get List Validators
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/avail/{network}/staking/direct/validators": {
"get": {
"operationId": "avail-staking-nominate-list",
"summary": "Get List Validators",
"description": "Return a list of P2P.org public validators to nominate.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Avail network:
`mainnet` — Avail mainnet.
`testnet` — Avail testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"nominate": {
"type": "string",
"description": "Validator address."
}
},
"required": [
"nominate"
],
"x-readme-ref-name": "AvailNominateResponse"
}
}
},
"required": [
"list"
],
"x-readme-ref-name": "GetListNominateResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Avail"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Staking Overview
*Source: [https://docs.p2p.org/docs/staking-overview.md](https://docs.p2p.org/docs/staking-overview.md)*
# Overview
Staking API provides seamless integration for initiating staking requests and accessing staking data. By integrating your systems with our validators' infrastructure, you can eliminate the need for dedicated web page forms, making it easier to offer staking services to your customers.
## Key Benefits
* **Reliable Infrastructure**: Gain access to our P2P validator infrastructure, consistently ranked among the top-performing validators, ensuring the reliability and security of your staking operations.
* **Dedicated Support**: Our experienced developers provide customer-oriented support through a dedicated channel, assisting you with any questions or issues during the integration process.
* **Customizable Configuration**: Tailor your staking node by selecting the desired location, MEV relay, and regulatory entity (currently in development). This flexibility allows you to align the staking setup with your specific requirements.
* **Slashing Insurance**: We offer extensive insurance protection against slashing events, with customizable plans to mitigate the risks associated with staking.
The illustration below shows the interaction with Staking API and relationships in the project infrastructure.
By seamlessly integrating Staking API into your systems, you can enhance your offering and simplify the staking process for your customers.
Staking API is gradually expanding to support close to 50 Proof-of-Stake protocols, allowing you to stake in all of them. For the list of currently supported networks, visit [Networks Supported](doc:networks-supported-staking-api).
## API Limitations
To ensure optimal usage of Staking API, please be aware of the following limitations:
* **Request Rate Limit**: The API enforces a maximum of 60 requests per minute. Ensure that your application adheres to this limit to avoid disruptions in service.
* **Response Times**: While the P2P infrastructure aims for an average response time of 200 milliseconds (ms), please note that response times may vary depending on the specific nature of the request. P2P guarantees a 95th percentile response time of 10 seconds and a 99th percentile response time of 60 seconds to provide transparency.
* **Node Request Limit**: The API supports the ability to request a maximum of 3125 validators in a single API call. This is to prevent the risk of users mistakenly requesting an excessive number of validators. If more validators are needed, you can send additional requests, each supporting up to 3125 validators.
* **Validator Keys Limit**: The node request creation is subject to a limit based on the available validator keys in our clusters. Ensure that our team knows the amount and frequency of your validator key requests to prevent service disruptions.
* **Withdrawal and Validator Status Endpoint Limits**: For specific endpoints like Withdrawal and Validator Status, the rate limit is 10 requests per minute, with 10,000 requests per day and a total of 30,000 requests per month.
By keeping these limitations in mind, you can optimize your usage of Staking API and ensure a smooth and reliable integration process.
If you have any questions or need further assistance, please [contact](doc:contacts) us. We are committed to helping you make the most of Staking API and providing a seamless staking experience for your customers.
## What's Next?
* Learn more about [Authentication](doc:authentication).
* Refer to [Staking API](ref:ethereum) reference.
---
## Babylon Withdrawal
*Source: [https://docs.p2p.org/reference/babylon-withdrawal.md](https://docs.p2p.org/reference/babylon-withdrawal.md)*
# Create Withdrawal Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon-btc/{network}/staking/withdrawal": {
"post": {
"operationId": "babylon-withdrawal",
"summary": "Create Withdrawal Request",
"description": "Withdraw staked assets within the Bitcoin network, the time-lock period for those has expired or those that were previously unbonded for early withdrawal.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Babylon network:
`mainnet` — Babylon main production environment and Bitcoin mainnet (only locking BTC is currently available).
`testnet` — Babylon testing environment and Bitcoin testnet called sigNet.
",
"schema": {
"enum": [
"testnet",
"mainnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stakerPublicKey": {
"type": "string",
"description": "Staker public key.",
"example": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
},
"stakeTransactionHash": {
"type": "string",
"description": "Hash of the initial staking transaction.",
"example": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028"
},
"withdrawalAddress": {
"type": "string",
"description": "Staker withdrawal address.",
"example": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9"
}
},
"required": [
"stakerPublicKey",
"stakeTransactionHash",
"withdrawalAddress"
],
"x-readme-ref-name": "WithdrawalRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"withdrawalAddress": {
"type": "string",
"description": "Staker withdrawal address.",
"example": "tb1p3e5dfkaxxqgq4vgv4peujcg8dwqe7ry9ky9702hx7jfmvrk5a3yq4q5ua9"
},
"stakerPublicKey": {
"type": "string",
"description": "Staker public key.",
"example": "02be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4"
},
"stakeTransactionHash": {
"type": "string",
"description": "Hash of the initial staking transaction.",
"example": "80410b51dabc9d31edab7fbdff26ac3bda70d3131830239ac0e3e9c8c1fc4028"
},
"withdrawalTransactionHex": {
"type": "string",
"description": "Unsigned transaction for withdrawal request in the hexadecimal format. Sign the transaction and submit it to the Bitcoin blockchain to perform the called action.",
"example": "70736274ff0100e402000000014f0d8e70d376cda7200bc900803d35dab2658fad9ce15454326b642523660ae90200000000fdffffff04b80b000000000000225120df0ec02350705a695b526f5c7662f33d8f8256cbd80cf8cda6d7c46d7d1578d00000000000000000496a4762626434002be65fdd561fee421c4f4564b02e4de31f74836b9b8cd1bbbf9d9c544733614e4bf609ba8977d3fbf4dee7f9d993c41f2fa584ccd27b3e4bf04a5376267e13c000c8025d0000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec48102700000000000000000000000001012bc5690000000000002251208e68d4dba630100ab10ca873c961076b819f0c85b10be7aae6f493b60ed4ec480000000000"
},
"fee": {
"type": "number",
"description": "Total fee in SATOSHI charged for processing the transaction (1 BTC = 10⁸ SATOSHI).",
"example": 1000
}
},
"required": [
"withdrawalAddress",
"stakerPublicKey",
"stakeTransactionHash",
"withdrawalTransactionHex",
"fee"
],
"x-readme-ref-name": "WithdrawalResponseDto"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124103
},
"message": {
"type": "string",
"default": "The request could not be performed because the transaction hash provided does not exist."
},
"name": {
"type": "string",
"default": "TransactionNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TransactionNotFoundException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 120100,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
},
"TransactionNotFoundException": {
"value": {
"error": {
"code": 120100,
"message": "The requested transaction was not found.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Babylon"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Babylon Transaction Get By Address
*Source: [https://docs.p2p.org/reference/babylon-transaction-get-by-address.md](https://docs.p2p.org/reference/babylon-transaction-get-by-address.md)*
# Get List Transactions
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/babylon-btc/{network}/transaction/get-by-address/{address}": {
"get": {
"operationId": "babylon-transaction-get-by-address",
"summary": "Get List Transactions",
"description": "Retrieve a list of all Babylon transactions on the Bitcoin network for a specific staker address.",
"parameters": [
{
"name": "address",
"description": "Staker address.",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Babylon network:
`mainnet` — Babylon main production environment and Bitcoin mainnet (only locking BTC is currently available).
`testnet` — Babylon testing environment and Bitcoin testnet called sigNet.
---
## Eth Staking Consolidation Validators
*Source: [https://docs.p2p.org/reference/eth-staking-consolidation-validators.md](https://docs.p2p.org/reference/eth-staking-consolidation-validators.md)*
# Consolidate Multiple Validators
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/eth/staking/direct/tx/consolidation-validators": {
"post": {
"operationId": "eth-staking-consolidation-validators",
"summary": "Consolidate Multiple Validators",
"description": "Construct a serialized transaction to consolidate multiple validators into a single entity.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"withdrawalAddress": {
"type": "string",
"description": "Withdrawal address for the target validator.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"sourcePubkeys": {
"description": "List of the source validators' public keys.",
"example": [
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39",
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
],
"items": {
"type": "string"
},
"type": "array"
},
"targetPubkey": {
"type": "string",
"description": "Public key of the target validator.",
"example": "0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39",
"pattern": "^0x[a-fA-F0-9]{96}$"
}
},
"required": [
"withdrawalAddress",
"sourcePubkeys",
"targetPubkey"
],
"x-readme-ref-name": "ConsolidationValidatorsRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"type": "object",
"properties": {
"serializeTx": {
"type": "string",
"description": "Serialized unsigned transaction.",
"example": "0x02f902d705808301674e8508530af16e830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aa5f27070a21d79455c4a9b73c0aa4a8b1a65a1fb530d7fd8e6cd23aa16660679ac43ee4861098f6d9166aed3a4d8abb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002001000000000000000000000028c84612d37de9209018ad96167f12169b653e9a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060978c565cd915f4e885b4201093d1501697610eb9ee99b9b60b70434dc330e98d5b42927725304ded48483a8b8f39506d09bcb22ee18d4f6b50257946ac5ee360385308d95c0e2bc963902d42e985c29ee489aa3c989ac1561c952a6424f107a800000000000000000000000000000000000000000000000000000000000000014cb452f6e3f10ba2175c86a0284f53fcb61404b458393391abc3d5622e3e55cdc0",
"pattern": "^0x([A-Fa-f0-9])+$",
"nullable": false
},
"to": {
"type": "string",
"description": "Recipient address for this transaction.",
"example": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb",
"pattern": "^0x[a-fA-F0-9]{40}$"
},
"gasLimit": {
"type": "string",
"example": "0",
"description": "Maximum gas limit for this block."
},
"data": {
"type": "string",
"example": "",
"description": "Transaction data."
},
"value": {
"type": "string",
"example": "0",
"description": "Amount of tokens to send in Wei."
},
"chainId": {
"type": "string",
"example": "0",
"description": "Chain ID this transaction is authorized on, as specified by EIP-155."
},
"type": {
"type": "string",
"example": "0",
"description": "EIP-2718 type of this transaction envelope."
},
"maxFeePerGas": {
"type": "string",
"example": "0",
"description": "Maximum price per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee in Wei."
},
"maxPriorityFeePerGas": {
"type": "string",
"example": "0",
"description": "Price per unit of gas in Wei, which is added to the EIP-1559 block's base fee. This added fee is used to incentivize miners to prioritize this transaction."
}
},
"required": [
"serializeTx",
"to",
"gasLimit",
"data",
"value",
"chainId",
"type",
"maxFeePerGas",
"maxPriorityFeePerGas"
],
"x-readme-ref-name": "EthereumUnsignedTransactionResponse"
}
}
},
"required": [
"list"
],
"x-readme-ref-name": "EthereumUnsignedTransactionListResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103114
},
"message": {
"type": "string",
"default": "The withdrawal transaction could not be created because the signature of the deposit data is invalid. Please re-sign the serialized transaction by following https://docs.p2p.org/docs/signing-transaction-eth."
},
"name": {
"type": "string",
"default": "InvalidDepositDataSignException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "InvalidDepositDataSignException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103105
},
"message": {
"type": "string",
"default": "The transaction could not be created because the validator public keys provided are invalid or do not exist."
},
"name": {
"type": "string",
"default": "PubkeyDoNotExistsException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PubkeyDoNotExistsException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103106
},
"message": {
"type": "string",
"default": "The transaction could not be created because one or more validators are not participating currently in the validator activities."
},
"name": {
"type": "string",
"default": "ValidatorNotActiveException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "ValidatorNotActiveException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103108
},
"message": {
"type": "string",
"default": "The transaction could not be created because the validator withdrawal address doesn't match with the withdrawalAddress."
},
"name": {
"type": "string",
"default": "WrongValidatorWithdrawalAddressException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongValidatorWithdrawalAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103152
},
"message": {
"type": "string",
"default": "Error while pubkeys has duplicates"
},
"name": {
"type": "string",
"default": "PubkeysDuplicatesException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "PubkeysDuplicatesException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidDepositDataSignException": {
"value": {
"error": {
"code": 103114,
"message": "The withdrawal transaction could not be created because the signature of the deposit data is invalid. Please re-sign the serialized transaction by following https://docs.p2p.org/docs/signing-transaction-eth.",
"type": "client"
},
"result": null
}
},
"PubkeyDoNotExistsException": {
"value": {
"error": {
"code": 103105,
"message": "The transaction could not be created because the validator public keys provided are invalid or do not exist.",
"type": "client"
},
"result": null
}
},
"ValidatorNotActiveException": {
"value": {
"error": {
"code": 103106,
"message": "The transaction could not be created because one or more validators are not participating currently in the validator activities.",
"type": "client"
},
"result": null
}
},
"WrongValidatorWithdrawalAddressException": {
"value": {
"error": {
"code": 103108,
"message": "The transaction could not be created because the validator withdrawal address doesn't match with the withdrawalAddress.",
"type": "client"
},
"result": null
}
},
"PubkeysDuplicatesException": {
"value": {
"error": {
"code": 103152,
"message": "Error while pubkeys has duplicates",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 103104
},
"message": {
"type": "string",
"default": "The Web3 transaction could not be created because the internal server error occurred."
},
"name": {
"type": "string",
"default": "Web3CreateTransactionException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "Web3CreateTransactionException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101110
},
"message": {
"type": "string",
"default": "The request could not be performed because the server authorization error occurred."
},
"name": {
"type": "string",
"default": "TokenGuardException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "TokenGuardException"
}
]
}
}
},
"examples": {
"Web3CreateTransactionException": {
"value": {
"error": {
"code": 103104,
"message": "The Web3 transaction could not be created because the internal server error occurred.",
"type": "server"
},
"result": null
}
},
"TokenGuardException": {
"value": {
"error": {
"code": 101110,
"message": "The request could not be performed because the server authorization error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Ethereum"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Data Validator State
*Source: [https://docs.p2p.org/reference/data-validator-state.md](https://docs.p2p.org/reference/data-validator-state.md)*
# Get Validator State
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/validator/state": {
"get": {
"operationId": "data-validator-state",
"summary": "Get Validator State",
"description": "Get a validator state.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum-agg",
"ethereum",
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"sui",
"polygon",
"avail",
"ton",
"near",
"cardano"
],
"type": "string"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Validator address in the required network. For the Ethereum network, it is a public validator key",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"state": {
"type": "string",
"description": "Validator state."
},
"activatedAt": {
"type": "string",
"description": "Timestamp of the validator activated date in the ISO 8601 format."
},
"activatedStakingPeriodNum": {
"type": "number",
"description": "Timestamp of the validator activated staking period."
}
},
"required": [
"activatedAt",
"activatedStakingPeriodNum"
],
"x-readme-ref-name": "GetValidatorStateResponse"
}
]
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 100101
},
"message": {
"type": "string",
"default": "The data provided is not valid. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "ValidationException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "ValidationException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115100
},
"message": {
"type": "string",
"default": "The request could not be performed because the validator address provided is not valid on the specified network. Please check the request parameters and try again."
},
"name": {
"type": "string",
"default": "InvalidValidatorAddressException"
},
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string"
},
"constraints": {
"additionalProperties": {
"type": "string"
},
"type": "array",
"items": {
"type": "object"
}
}
},
"required": [
"property",
"constraints"
],
"x-readme-ref-name": "ValidationErrorResponse"
}
}
},
"required": [
"code",
"message",
"name",
"errors"
],
"x-readme-ref-name": "InvalidValidatorAddressException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 124100
},
"message": {
"type": "string",
"default": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: [ 'mainnet', 'testnet' ]."
},
"name": {
"type": "string",
"default": "NetworkIsNotIncludedInListException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NetworkIsNotIncludedInListException"
}
]
}
}
},
"examples": {
"ValidationException": {
"value": {
"error": {
"code": 100101,
"message": "The data provided is not valid. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"InvalidValidatorAddressException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the validator address provided is not valid on the specified network. Please check the request parameters and try again.",
"type": "client"
},
"result": null
}
},
"NetworkIsNotIncludedInListException": {
"value": {
"error": {
"code": 100101,
"message": "The request could not be performed because the network provided is not supported. Please specify the network from the list of available ones: undefined.",
"type": "client"
},
"result": null
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101111
},
"message": {
"type": "string",
"default": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication."
},
"name": {
"type": "string",
"default": "NoTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "NoTokenException"
},
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 101109
},
"message": {
"type": "string",
"default": "An invalid Bearer token has been provided. Please specify the correct authentication token."
},
"name": {
"type": "string",
"default": "WrongTokenException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "WrongTokenException"
}
]
}
}
},
"examples": {
"NoTokenException": {
"value": {
"error": {
"code": 101111,
"message": "No Bearer token has been provided. To obtain an authentication token, follow the instructions at https://docs.p2p.org/docs/authentication.",
"type": "authentication"
},
"result": null
}
},
"WrongTokenException": {
"value": {
"error": {
"code": 101109,
"message": "An invalid Bearer token has been provided. Please specify the correct authentication token.",
"type": "authentication"
},
"result": null
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115305
},
"message": {
"type": "string",
"default": "The validator could not be found. Please specify the correct validator address and the network."
},
"name": {
"type": "string",
"default": "GetValidatorInfoNotFoundException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetValidatorInfoNotFoundException"
}
]
}
}
},
"examples": {
"GetValidatorInfoNotFoundException": {
"value": {
"error": {
"code": 115305,
"message": "The validator could not be found. Please specify the correct validator address and the network.",
"type": "not_found"
},
"result": null
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object"
},
"result": {
"type": "object",
"nullable": true,
"default": null
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "ExceptionResponse"
}
],
"properties": {
"error": {
"allOf": [
{
"type": "object",
"properties": {
"code": {
"type": "number",
"default": 115304
},
"message": {
"type": "string",
"default": "The request could not be performed because an internal server error occurred."
},
"name": {
"type": "string",
"default": "GetValidatorInfoException"
}
},
"required": [
"code",
"message",
"name"
],
"x-readme-ref-name": "GetValidatorInfoException"
}
]
}
}
},
"examples": {
"GetValidatorInfoException": {
"value": {
"error": {
"code": 115304,
"message": "The request could not be performed because an internal server error occurred.",
"type": "server"
},
"result": null
}
}
}
}
}
}
},
"tags": [
"Validator"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Overview Aptos
*Source: [https://docs.p2p.org/docs/overview-aptos.md](https://docs.p2p.org/docs/overview-aptos.md)*
# Overview
Staking in the Aptos network using the Staking API consists of several main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For Aptos, there are two networks available:
* `mainnet` — the production network.
* `testnet` — Aptos devnet.
## What's Next?
* [Getting Started](doc:getting-started-aptos)
* [Withdrawal](doc:withdrawal-aptos)
* [Staking API](ref:aptos-transaction-status) reference
---
## Sui Staking Stake
*Source: [https://docs.p2p.org/reference/sui-staking-stake.md](https://docs.p2p.org/reference/sui-staking-stake.md)*
# Create Staking Request
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/sui/{network}/staking/stake": {
"post": {
"operationId": "sui-staking-stake",
"summary": "Create Staking Request",
"description": "Create staking request transaction.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"example": "testnet",
"description": "
Sui network:
`mainnet` — Sui mainnet.
`testnet` — Sui testnet.
",
"schema": {
"enum": [
"mainnet",
"testnet"
],
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"sender": {
"type": "string",
"description": "Address of the account.",
"example": "0x2c0def86e107ae6ca6a610b4188bb3c2802c30350ac01817be6a02d2a247faf5"
},
"gasPrice": {
"type": "number",
"description": "Number of native tokens in MIST per gas unit this transaction will pay..",
"example": 1000,
"default": 1000
},
"gasBudget": {
"type": "number",
"example": 1000000,
"default": 1000000
},
"amount": {
"type": "number",
"description": "",
"minimum": 1,
"example": 1
}
},
"required": [
"sender",
"amount"
],
"x-readme-ref-name": "SuiStakeRequestDto"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"type": "object",
"properties": {
"error": {
"type": "object",
"nullable": true,
"default": null
},
"result": {
"type": "object"
}
},
"required": [
"error",
"result"
],
"x-readme-ref-name": "SuccessResponse"
}
],
"properties": {
"result": {
"oneOf": [
{
"type": "object",
"properties": {
"unsignedTransaction": {
"type": "string",
"description": "Unsigned transaction in the hexadecimal format. Sign the transaction and submit it to the blockchain to perform the called action.",
"example": "0xa404160200165874de804160c3cd013d9b6f4bba864657c4c2168a542f78ff14a0253873190200000000"
}
},
"required": [
"unsignedTransaction"
],
"x-readme-ref-name": "SuiStakeResponseDto"
}
]
}
}
}
}
}
}
},
"tags": [
"Sui"
],
"security": [
{
"bearer": []
}
]
}
}
},
"info": {
"title": "Staking API",
"description": "API used for staking",
"version": "1.0.0",
"contact": {}
},
"servers": [
{
"url": "https://api.p2p.org",
"description": "Staking API"
},
{
"url": "https://api-test.p2p.org",
"description": "Testnet Staking API"
}
],
"components": {
"securitySchemes": {
"bearer": {
"scheme": "bearer",
"bearerFormat": "JWT",
"type": "http"
}
}
}
}
```
---
## Withdrawal Vem
*Source: [https://docs.p2p.org/docs/withdrawal-vem.md](https://docs.p2p.org/docs/withdrawal-vem.md)*
# Withdrawal using VEM
It is possible to initiate withdrawals on the Ethereum network using the Staking API by retrieving the Validator Exit Message (VEM). The process consists of the following steps:
1. Prepare ECDH keys to decrypt the VEM.
2. Create a VEM request.
3. Sign the VEM request.
4. Retrieve the signed VEM for your staked Ethereum.
Request examples are provided using [cURL](https://curl.se/).
Before initiating the withdrawal flow, please check the below conditions:
* A voluntary exit can be initiated only if the validator is currently active, has not been slashed and has been active for at least 256 epochs (\~27 hours) since it has been activated.
* Only the address set as the controller address or withdrawal address can initiate a validator exit via our smart contract. If the transaction sender doesn't match the eligible address, the validator exit will not be initiated.
# 1. Prepare ECDH keys
Generate an Elliptic Curve Diffie-Hellman (ECDH) key pair. Retain the private key securely for future steps, as it is needed to decrypt the VEM.
P2P.org uses keys on the`NIST P-256` curve (aka `secp256r11` aka `prime256v1`) for the key pair ECDH algorithm inside the ECIES encryption scheme. Keep your private key secret and discard it when it is not needed any more. You will also need it for creating the initial VEM request.
The public keys have to be a base64-encoded string of a PEM block with the `x509 SPKI` (aka `PKIX`) formatted public key on the `P-256` curve.
Example of such a key:
```json
1. "ecdhPublicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFNWgwcmRaSEZaZWNSbWIxR2RqQis3T0dUMnovegozMG1TRnZhWTdQaTltek5HT3J6SjZVbS9GbUMwb2lXMVFBT1FhOVFldGFpZm1EMU0zc09iU0JwV3N3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
```
Example of its base64-decoded version:
```text
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5h0rdZHFZecRmb1GdjB+7OGT2z/z
30mSFvaY7Pi9mzNGOrzJ6Um/FmC0oiW1QAOQa9QetaifmD1M3sObSBpWsw==
-----END PUBLIC KEY-----
```
The ECDH public key will be used to produce a ECDH shared secret inside the ECIES scheme by the P2P server. The server’s ECDH public key is encoded in the first N bytes (65 in case of the `P-256` curve) as it is required in [SEC 1 v2](https://www.secg.org/).
# 2. Create VEM Request
1. Prepare `id` that is an arbitrary UUID. Generate it in one of the following ways:
* [Online UUID Generator](https://www.uuidgenerator.net/)
* [uuid npm package](https://www.npmjs.com/package/uuid)
2. Prepare the JSON `vem_request` structure by embedding the validators' `pubkeys` for withdrawal and `ecdh_client_pubkey`.
Example of `vem_request` structure:
```json
{
"action": "vem_request",
"pubkeys": [
"0x867a9f95287decd74e076b8fefca3022fcb2c3c37de246e950ade0cc3609c74d4badda62657a64c2c4009f1b6625c647",
"0x93e298f6ac5fb8f262a23450d1638aec1c45f77fd1ac86beb19b696b3b84fef3694e9b2166b337783911a3d7df13fbf1"
],
"ecdh_client_pubkey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFNWgwcmRaSEZaZWNSbWIxR2RqQis3T0dUMnovegozMG1TRnZhWTdQaTltek5HT3J6SjZVbS9GbUMwb2lXMVFBT1FhOVFldGFpZm1EMU0zc09iU0JwV3N3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
}
```
* `action` — action type to be requested, here specified as a VEM request.
* `pubkeys` — array of public keys identifying the validators you are withdrawing from.
* `ecdh_client_pubkey` — your ECDH public key for secure communication.
3. Submit the VEM request by sending a POST request to [/api/v1/eth/staking/direct/vem/create](ref:eth-vem-create). Use [https://api-test-holesky.p2p.org](https://api-test-holesky.p2p.org) for testing or [https://api.p2p.org](https://api.p2p.org) for production.
Example request:
```curl
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/vem/create \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "off_chain",
"vemRequest": "{\"action\": \"vem_request\",\"pubkeys\": [\"0x867a9f95287decd74e076b8fefca3022fcb2c3c37de246e950ade0cc3609c74d4badda62657a64c2c4009f1b6625c647\", \"0x93e298f6ac5fb8f262a23450d1638aec1c45f77fd1ac86beb19b696b3b84fef3694e9b2166b337783911a3d7df13fbf1\"],\"ecdh_client_pubkey\": \"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFNWgwcmRaSEZaZWNSbWIxR2RqQis3T0dUMnovegozMG1TRnZhWTdQaTltek5HT3J6SjZVbS9GbUMwb2lXMVFBT1FhOVFldGFpZm1EMU0zc09iU0JwV3N3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==\"}",
"vemRequestSignature": "0x.....",
"vemRequestSignedBy": "0x.....",
"vemRequestTxId": "",
"vemRequestProof": ""
}
'
```
* `id` — UUID to identify the VEM set-up request.
* `type` — VEM request type used. Two types are supported: `off_chain` and `on_chain`.
* `vemRequest` — JSON formatted string that represents the VEM request.
* `vemRequestSignature` — signature of the `vem_request` by either `withdrawalAddress` or `controllerAddress`. Required if the type is `off_chain`.
* `vemRequestSignedBy` — Ethereum address (`withdrawalAddress` or `controllerAddress`) that signed the request. Required if the type is `off_chain`.
* `vemRequestTxId` — hash of the successful `vem_request` transaction. Required if the type is `on_chain`.
* `vemRequestProof` — hash of the signed `vemRequestTxId` transaction. Required if the type is `on_chain`.
Example response:
```json
{
"result": true
}
```
# 3. Sign VEM request
To authorize the withdrawal process, digitally sign the `vem_request` using the Ethereum private key associated with your `withdrawalAddress` or `controllerAddress`.
`vem_request_signature` is a 0x prefixed hex encoded signature of the `Keccak256` hash of the `vem_request` field, done using the private key of either the `withdrawalAddress` or `controllerAddress`. This private key should be a standard Ethereum key on the `secp256k1` curve and use the standard Ethereum extended ECDSA signature algorithm.
The signature verifies that the requestor has the authority to perform the transaction and is an essential security measure to prevent unauthorized withdrawals.
# 4. Retrieve signed VEM
Check the request status and retrieve the signed VEM by sending a GET request to [/api/v1/eth/staking/direct/vem/status/\{id}](ref:eth-vem-status).
Example request:
```curl
curl --request GET \
--url https://api.p2p.org/api/v1/eth/staking/direct/vem/status/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
--header 'accept: application/json' \
--header 'authorization: Bearer ' \
```
* `id` — UUID that was specified in the VEM set-up request.
Example response:
```json
{
"error": null,
"result": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "processing",
"type": "off_chain",
"vemRequest": "{\"action\": \"vem_request\",\"pubkeys\": [\"0x867a9f95287decd74e076b8fefca3022fcb2c3c37de246e950ade0cc3609c74d4badda62657a64c2c4009f1b6625c647\", \"0x93e298f6ac5fb8f262a23450d1638aec1c45f77fd1ac86beb19b696b3b84fef3694e9b2166b337783911a3d7df13fbf1\"],\"ecdh_client_pubkey\": \"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFNWgwcmRaSEZaZWNSbWIxR2RqQis3T0dUMnovegozMG1TRnZhWTdQaTltek5HT3J6SjZVbS9GbUMwb2lXMVFBT1FhOVFldGFpZm1EMU0zc09iU0JwV3N3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==\"}",
"vemRequestSignature": "0x5d64827430e3d2fc1f4C9293709B13fc2af45c8eed295f96a4195d2c9224b5e344a969279ff437139868fc7e534191217ef3fe4d9c9b71d1bfeeDASbfb26d118243",
"vemRequestSignedBy": "0x78ADAeE48151b2E42de20f42b1a1980871314Ef5",
"vemRequestTxId": null,
"vemRequestProof": null,
"error": "",
"vemResult": "",
"forkVersion": ""
}
}
```
* `id` — UUID that was specified in the VEM set-up request.
* `status` — current status of the VEM request:
* `processing` — request is in progress.
* `success` — request is ready.
* `error` — there is an issue with the data, unable to create VEM.
* `fault` — internal error occurred on the server side.
* `type` — VEM request type used. Two types are supported: `off_chain` and `on_chain`.
* `vemRequest` — base64-encoded VEM request.
* `vemRequestSignature` — digital signature of the request.
* `vemRequestSignedBy` — Ethereum address that signed the request, providing a linkage to the withdrawal or controller account.
* `vemRequestTxId` — hash of the successful `vem_request` transaction.
* `vemRequestProof` — hash of the signed `vemRequestTxId` transaction.
* `error` — error message (if exists).
* `vemResult` — encrypted VEM results.
* `forkVersion` — version of the Ethereum fork.
Upon receipt of the `vemResult`, use your private ECDH key to decrypt the message using the ECIES scheme and retrieve the signed VEM for your staked Ethereum.
## What's Next?
* [Getting Started](doc:staking-eth).
* [Staking API](ref:eth-nodes-request-create) reference.
---
## Overview Celestia
*Source: [https://docs.p2p.org/docs/overview-celestia.md](https://docs.p2p.org/docs/overview-celestia.md)*
# Overview
Staking in Celestia using the Staking API consists of several main steps:
1. Create a stake transaction.
2. Sign and send the transaction to the network.
[Get an authentication token](doc:authentication) to start using Staking API.
We provide two distinct endpoints for testing and production environments.
* PRODUCTION: [https://api.p2p.org](https://api.p2p.org)
* TESTING: [https://api-test.p2p.org](https://api-test.p2p.org)
For Celestia, there are several networks available:
* `mainnet-beta` — the production network.
* `mocha-testnet` — a testnet.
## What's Next?
* [Getting Started](doc:staking-celestia).
* [Withdrawal](doc:withdrawal-celestia).
* [Staking API](ref:create-celestia-stake-transaction) reference.
---
## Data Delegator Stakes
*Source: [https://docs.p2p.org/reference/data-delegator-stakes.md](https://docs.p2p.org/reference/data-delegator-stakes.md)*
# Get Delegator Stake
# OpenAPI definition
```json
{
"openapi": "3.0.0",
"paths": {
"/api/v1/{network}/data/delegator/stakes": {
"get": {
"operationId": "data-delegator-stakes",
"summary": "Get Delegator Stake",
"description": "Get a current delegator stake.",
"parameters": [
{
"name": "network",
"required": true,
"in": "path",
"description": "Network name.",
"schema": {
"enum": [
"ethereum-agg",
"ethereum",
"solana",
"cosmoshub",
"polkadot",
"kusama",
"moonbeam",
"vara",
"sui",
"polygon",
"avail",
"ton",
"near",
"cardano"
],
"type": "string"
}
},
{
"name": "startAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "finishAt",
"required": false,
"in": "query",
"example": "2024-01-01T00:00:00.000Z",
"description": "Timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "startNumber",
"required": false,
"in": "query",
"description": "Start number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "finishNumber",
"required": false,
"in": "query",
"description": "Finish number of the staking period.",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"example": 50,
"description": "Number of resources that a single response page contains.",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"example": 0,
"description": "Number of resources to exclude from a response.",
"schema": {
"minimum": 0,
"maximum": 10000000,
"type": "number"
}
},
{
"name": "address",
"required": true,
"in": "query",
"description": "Delegator address in the required network.",
"schema": {
"type": "string"
}
},
{
"name": "addressType",
"required": false,
"in": "query",
"description": "
Delegator address type in the required network:
`deposit` — available for the Ethereum network (used by default)
`withdrawal` — available for the Ethereum network
`delegator` — available for the Polygon, Solana, Cosmos, Near, and Sui networks (used by default)
`stake_account` — available for the Solana
`nominator` — available for the TON and Polkadot networks (used by default)
`nominator_reward_account` — available for the Polkadot networks