Getting Started

There are two ways to start restaking on the Ethereum network using the Restaking API:

The restaking process consists of the following steps:

  1. Create EigenPod address: construct a serialized transaction to generate an EigenPod address for your validator to use as a withdrawal address.
  2. Sign and broadcast the transaction.
  3. Create Staking Request: set up nodes for staking using P2P infrastructure.
  4. Check Request Status: check the status of the node set-up operation.
  5. Prepare Staking Transaction: construct a serialized transaction to deposit the stake amount with a P2P smart contract.
  6. Sign and broadcast the transaction.

Get an authentication token to start using Restaking API.

A request example is provided using cURL.

P2P Smart Contract

1. Create EigenPod Address

Retrieve a serialized transaction to generate an EigenPod address by sending a POST request to /api/v1/eth/staking/direct/tx/create-pod. Use https://api-test.p2p.org for testing or https://api.p2p.org for production.

Example response:

{
  "error": null,
  "result": {
    "serializeTx": "0x02e80580820556820578830186a094a286b84c96af280a49fe1f40b9627c2a2827df41808484d81062c0",
    "to": "0xa286b84C96aF280a49Fe1F40B9627C2A2827df41",
    "gasLimit": "0.0000000000001",
    "data": "0x84d81062",
    "value": "0.0",
    "chainId": 5,
    "type": 2,
    "maxFeePerGas": "0.0000000000000014",
    "maxPriorityFeePerGas": "1366"
  }
}
  • 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.
  • typeEIP-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 Broadcast Transaction

Use serializeTx from the previous step to sign and send the signed transaction to the Ethereum network.
By broadcasting this transaction, you are generating an EigenPod address. The eigenPodOwnerAddress will be the Ethereum address used to sign this transaction.

3. Create Staking Request

Let's now start the node request creation.

  1. Prepareid that is an arbitrary UUID. Generate it in one of the following ways:

  2. Set up staking nodes through P2P infrastructure by sending a POST request to /api/v1/eth/staking/direct/nodes-request/create.

    Example request:

    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":"6df58880-c4c9-484a-8fc4-7f7668fe9522",
        "type": "RESTAKING",
        "validatorsCount": 1,
        "feeRecipientAddress":"0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
        "eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
        "controllerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
        "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. You need to specifically set the type to RESTAKING to initiate a restaking operation. The default value is RESTAKING, that is 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. You can retrieve this value in the previous EigenPod creation step.
    • controllerAddress — controller address for the validators.
    • nodesOptions:
      • location — node location. Currently, only any is supported.
      • relaysSet — Miner Extractable Value (MEV) relay selection.

    Example response:

    {
      "result": true
    }
    

4. Check Request Status

Check the node set-up operation status by sending a GET request to /api/v1/eth/staking/direct/nodes-request/status/{id}.

Example request:

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:

{
  "result": {
    "id": "e467729e-0a7d-442a-9d5a-ba93a0d39d80",
    "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": "00001020",
        "eth2NetworkName": "goerli",
        "depositCliVersion": "2.3.0"
      }
    ],
    "createdAt": "2024-01-30T15:40:55.453Z"
  }
}
  • id — UUID that was specified in the node set-up request.

  • status — current status of the nodes request.

  • validatorsCount — number of validators. One validator is equal to 32 ETH.

  • withdrawalAddress — withdrawal address for the validators by default set to null. This corresponds to the EigenPod address.

  • eigenPodAddress — EigenPod address. This address is 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.

5. Prepare Staking Transaction

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

Example request:

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": "0x1433F808a4867aDEeEb3AE0Df58691C252269A2C",
  "depositData": [
    {
      "pubkey": "0xaed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13",
      "signature": "0x91b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf5",
      "depositDataRoot": "0xd0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89"
    }
  ]
}
'
  • withdrawalAddress — withdrawal address for the validators. For the RESTAKING type, this will correspond to the eigenPodAddress in the previous step.

  • 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:

{
  "error": null,
  "result": {
    "serializeTx": "0x02f902d305808205508205c8830186a094681a1b3441c6bfb12f91651efd9f02c83c0702938901bc16d674ec800000b902a44f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000001433f808a4867adeeeb3ae0df58691c252269a2c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006091b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf50000000000000000000000000000000000000000000000000000000000000001d0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89c0",
    "to": "0x681a1b3441c6BFb12f91651EFD9F02c83c070293",
    "gasLimit": "0.0000000000001",
    "data": "0x4f498c730000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030aed7226d86d884dd44bc45c2b57f7634e72abf247713163388b1c34d89a1322d7228ca023dbaf2465b822e35ba00da13000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000001433f808a4867adeeeb3ae0df58691c252269a2c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006091b710f0e3affe704e76ada81b095afbedf4b760f3160760e8fa0298cc4858e0f325c2652dc698ec63c59db65562551114ab7fcafe1d675eaaf186fa7758800f0157bd0b51cd3a131fac562d6933658ddbf182aab8d20a9483b1392085e54cf50000000000000000000000000000000000000000000000000000000000000001d0d00dce54b4ec8a7803783fc786a859459ead1d35b856c525cb289aba4b0f89",
    "value": "32.0",
    "chainId": 5,
    "type": 2,
    "maxFeePerGas": "0.00000000000000148",
    "maxPriorityFeePerGas": "1360"
  }
}
  • 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.
  • typeEIP-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.

6. Sign and Broadcast Transaction

Use serializeTx from the previous step to sign and send 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 Deposit Smart Contract

1. Create EigenPod Address

Retrieve a serialized transaction to generate an EigenPod address by sending a POST request to /api/v1/eth/staking/direct/tx/create-pod. Use https://api-test.p2p.org for testing or https://api.p2p.org for production.

Example response:

{
  "error": null,
  "result": {
    "serializeTx": "0x02e80580820556820578830186a094a286b84c96af280a49fe1f40b9627c2a2827df41808484d81062c0",
    "to": "0xa286b84C96aF280a49Fe1F40B9627C2A2827df41",
    "gasLimit": "0.0000000000001",
    "data": "0x84d81062",
    "value": "0.0",
    "chainId": 5,
    "type": 2,
    "maxFeePerGas": "0.0000000000000014",
    "maxPriorityFeePerGas": "1366"
  }
}
  • 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.
  • typeEIP-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 Broadcast Transaction

Use serializeTx from the previous step to sign and send the signed transaction to the Ethereum network.
By broadcasting this transaction, you are generating an EigenPod address. The eigenPodOwnerAddress will be the Ethereum address used to sign this transaction.

3. Create Staking Request

Let's now start the node request creation.

  1. Prepareid that is an arbitrary UUID. Generate it in one of the following ways:

  2. Set up staking nodes through P2P infrastructure by sending a POST request to /api/v1/eth/staking/direct/nodes-request/create.

    Example request:

    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":"6df58880-c4c9-484a-8fc4-7f7668fe9522",
        "type": "RESTAKING",
        "validatorsCount": 1,
        "feeRecipientAddress":"0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
        "eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
        "controllerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
        "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. You need to specifically set the type to RESTAKING to initiate a restaking operation. The default value is RESTAKING, that is 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. You can retrieve this value in the previous EigenPod creation step.
    • controllerAddress — controller address for the validators.
    • nodesOptions:
      • location — node location. Currently, only any is supported.
      • relaysSet — Miner Extractable Value (MEV) relay selection.

    Example response:

    {
      "result": true
    }
    

4. Check Request Status

Check the node set-up operation status by sending a GET request to /api/v1/eth/staking/direct/nodes-request/status/{id}.

Example request:

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:

{
  "result": {
    "id": "e467729e-0a7d-442a-9d5a-ba93a0d39d80",
    "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": "00001020",
        "eth2NetworkName": "goerli",
        "depositCliVersion": "2.3.0"
      }
    ],
    "createdAt": "2024-01-30T15:40:55.453Z"
  }
}
  • id — UUID that was specified in the node set-up request.

  • status — current status of the nodes request.

  • validatorsCount — number of validators. One validator is equal to 32 ETH.

  • withdrawalAddress — withdrawal address for the validators by default set to null. This corresponds to the EigenPod address.

  • eigenPodAddress — EigenPod address. This address is 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.

5. Sign and Broadcast Transaction

Clients, who prefer to construct a signature themselves to send the deposit amount to the Ethereum deposit smart contract, can retrieve all the required data from step 3 within the depositData object.

Check an example of how to sign and send a transaction to the Ethereum network.

What's Next?