> ## Documentation Index
> Fetch the complete documentation index at: https://docs.p2p.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Getting Started

> Stake on Ethereum programmatically with the P2P.org Staking API.

To start staking on the Ethereum network using the Staking API:

1. Set up nodes for staking using P2P infrastructure.
2. Check the status of the node set-up operation.
3. Construct a serialized transaction to deposit the stake amount with a smart contract.

[Get an authentication token](/docs/authentication) to start using Staking API.

Request examples are provided using [cURL](https://curl.se/).

<Warning>
  **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](/docs/validator-consolidation) into a single one
  * By [creating a new `0x02`-enabled validator](/docs/initial-staking) via simplified 3.1 integrators with smart contract flow
    allowlists

  For more details, see [Pectra Upgrade overview](/docs/pectra-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.
</Warning>

<Steps>
  <Step title="Create setting-up node 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](/reference/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:

       ```bash theme={null}
       curl --request POST \
         --url https://api.p2p.org/api/v1/eth/staking/direct/nodes-request/create \
         --header 'accept: application/json' \
         --header 'authorization: Bearer <token>' \
         --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](/docs/restaking-overview) with the EigenPod address.
         * `MANAGED_SSV`— value that is used to initiate a managed SSV cluster.
       * `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](/docs/restaking-eth).
       * `feeRecipientAddress` — fee recipient address.
       * `controllerAddress` — <Tooltip tip="On Ethereum, we introduced the controller address entity to provide greater flexibility and maintain high-level security during the withdrawal flow. When the user requests the validator withdrawal, only authorized addresses can initiate this request by calling our withdrawal smart contract. The authorized addresses are the withdrawal address and the controller address. Since many users prefer not to use the withdrawal address to interact with smart contracts, a second authorized address can be specified as controller address in the new staking request.">controller address</Tooltip> for the validators.
       * `nodesOptions`:
         * `location` — node location. Currently, only `any` is supported.
         * `relaysSet` — Miner Extractable Value (<Tooltip tip="Miner Extractable Value Relay Selection is a process of selecting a validator to participate in the next Ethereum block based on the value that they can extract from transactions in that block.">MEV</Tooltip>) relay selection.

       Example response:

       ```json theme={null}
       {
         "error": null,
         "result": true
       }
       ```
  </Step>

  <Step title="Check request status">
    After setting up the node, check the status of the node set-up operation by sending a GET request to [/api/v1/eth/staking/direct/nodes-request/status/\{id}](/reference/eth-nodes-request-status) . You must poll this until status is `ready`.

    Example request:

    ```bash theme={null}
    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 <token>'
    ```

    * `id` — UUID that was specified in the node set-up request.

    Example response:

    ```json theme={null}
    {
      "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.
  </Step>

  <Step title="Prepare staking transaction">
    After setting up the nodes and successfully generating the `depositData`, retrieve it and proceed with make the deposit.

    There are two flows to make a deposit:

    | Workflow                  | Best For    | Logic                                                                             |
    | ------------------------- | ----------- | --------------------------------------------------------------------------------- |
    | Simplified Smart Contract | Most Users  | Uses P2P proxy contract to handle registration and deposit in one flow.           |
    | Direct Interaction        | Power Users | Manually interacting with the Ethereum Deposit Contract for fine-grained control. |

    ### [P2P Proxy deposit](/docs/direct-staking#p2p-direct-staking-v1-eth2-depositor--message-sender-flow)

    Create a serialized transaction for depositing the stake amount and send it as a POST request to [/api/v1/eth/staking/direct/tx/deposit](/reference/eth-staking-deposit).

    ```bash theme={null}
    curl --request POST \
      --url https://api.p2p.org/api/v1/eth/staking/direct/tx/deposit \
      --header 'accept: application/json' \
      --header 'authorization: Bearer <token>' \
      --header 'content-type: application/json' \
      --data '{
      "withdrawalAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
      "depositData": [
        {
          "pubkey": "0xac1e9969d7b87f3102549ab41558136674a7306b85b9f73cfbd7d9fdb7db85724569da3ebd4d7de9689f6ac058d7e2a3",
          "signature": "0xb656f9c771166c82a7891b930e6a920878d9736eb3f9f241753a15ea69d8e2f20a3740dfaf546c70e31bd323e14b341205d04e3227dd4cf2923644a375f6792875ac02c5f256f7a17c96b09bafcbce7e4443e1862356b1e90d78875d78e9a742",
          "withdrawalCredentials": "0100000000000000000000005cef11327af4104ba0f8a82fbb8628caee7cb1e3",
          "depositDataRoot": "0xba013b4950b9aff0c3c19017ec5b6e0ed5b957b36f6ff03a545e5cc5605baff8",
          "amount": 32000000000
        },
        {
          "pubkey": "0xbe5E9c3Bb9eba1BF4C5eC1c1cbcF85ee2CE2fEC66Ce5460C23eF82332A044FDCabF7011F588CCbD77E73CCe6c4accDF0",
          "signature": "0x83D2E925AEAEdcB18db983Bd447db0BFc1Ee9a6Ead118E5BEfeBcb24BA8C0efd3BD19Cb1cE8e807Fc980a67bBbf8b11e039efe2DB71fcdF096fccac5B04dF80f6a1804cd8d492455D30abE27FcDbDA78AFE61856cad65ffF5cA48Ed4776edd88",
          "withdrawalCredentials": "010000000000000000000000515ea819fde1c0d36eb8e78e9a69dbf8e4a21",
          "depositDataRoot": "0x53da3c92fCCEb0CFE1764f65DDfF1564A2b15585",
          "amount": 32000000000
        }
      ]
    }'
    ```

    * `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 theme={null}
    {
      "error": null,
      "result": {
        "serializeTx": "0x02f902d9824268808402718e18847c8ca34c830186a09494edf7e950fa01baa44a8690cac64264cdb7ca7c8901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000308c0bbe942f40bf50895da668c95fb1feede465ab175d5f93e00a8c33d146584f7f4ee4f963d317844be5d552135b595a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020010000000000000000000000338ef19fa2ec0fc4d1277b1307a613fa1fbbc0cb000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060ac5b5e49f647d6107d71a08e255bfead1c5c42375f50e5301ffa4f5e36a8ccf159e3a594069375aef5dd2a23718634950f99947f24e67cc7a84c9f805849a7b0ac5ca732e63cca1f876dbac7e0efc8000a0f19e04bf5df80c7131d30cf45e8f3000000000000000000000000000000000000000000000000000000000000000101a591baee083825d59d36f06b4d0fbd55688ed81b337819a2bf145cb8a2a022c0",
        "to": "0x94EDf7e950fA01bAa44a8690cAC64264cdB7cA7c",
        "gasLimit": "100000",
        "data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000308c0bbe942f40bf50895da668c95fb1feede465ab175d5f93e00a8c33d146584f7f4ee4f963d317844be5d552135b595a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020010000000000000000000000338ef19fa2ec0fc4d1277b1307a613fa000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000060ac5b5e49f647d6107d71a08e255bfead1c5c42375f50e5301ffa4f5e36a8ccf159e3a594069375aef5dd2a23718634950f99947f24e67cc7a84c9f805849a7b0ac5ca732e63cca1f876dbac7e0efc8000a0f19e04bf5df80c7131d30cf45e8f3000000000000000000000000000000000000000000000000000000000000000101a591baee083825d59d36f06b4d0fbd55688ed81b337819a2bf145cb8a2a022",
        "value": "64000000000000000000",
        "chainId": 560048,
        "type": 2,
        "maxFeePerGas": "2221240288",
        "maxPriorityFeePerGas": "79693564"
      }
    }
    ```

    * `serializeTx` — serialized unsigned transaction.
    * `to` — recipient address for this transaction.
    * `gasLimit` — maximum <Tooltip tip="A measure of computational effort required to execute a transaction or smart contract on a blockchain. Users must pay a gas fee, usually in the native token, to have their transactions processed by the network.">gas</Tooltip> 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.

    Use `serializeTx` from the previous step to [sign and send](/docs/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.

    ### Ethereum direct deposit

    Use this if you prefer to interact with the official Ethereum contract without a proxy.

    1. Take the pubkey, signature, and depositDataRoot from the deposit-data response.
    2. Go to the [Official Ethereum Deposit Contract](https://etherscan.io/address/0x00000000219ab540356cBB839Cbe05303d7705Fa)
    3. Manually execute the `deposit` function with your 32 ETH and the provided data.

    After your deposit is successful, your validator will enter the activation queue and soon start performing the validator tasks.
  </Step>
</Steps>

## Smart contracts

### Current addresses

> Returned by the API endpoint; forwards to Beacon DepositContract.

* [Mainnet](https://etherscan.io/address/0xa6cf239220a8a9939d3207dfd8f26cd5e4f36ae6) `0xa6cf239220a8a9939d3207dfd8f26cd5e4f36ae6`
* [Hoodi](https://hoodi.etherscan.io/address/0xda2934020efd473fac5cd73bdde440a719bf4c59) `0xda2934020efd473fac5cd73bdde440a719bf4c59`

### Previous addresses

> Direct on-chain deposits (v1), still accepted.

* [Mainnet](https://etherscan.io/address/0x4ca21e4d3a86e7399698f88686f5596dbe74adeb) `0x4ca21e4d3a86e7399698f88686f5596dbe74adeb`
* [Hoodi](https://hoodi.etherscan.io/address/0x375e183efA05fb2bb66Cd0e7C3a05D9942046612) `0x375e183efA05fb2bb66Cd0e7C3a05D9942046612`

[Github](https://github.com/p2p-org/p2p-eth2-depositor/blob/main/src/P2pEth2Depositor.sol)

[Audit](https://github.com/mixbytes/audits_public/tree/master/P2P.org/ETH2%20Depositor%20%26%20ETH%20Staking%20Fee%20Distributor%20\(v.1\))


## Related topics

- [Withdrawal](/docs/withdrawal-eth.md)
- [Staking API reference](/reference/eth-nodes-request-create.md)
