Withdrawal
For the Restaking API, it is possible to withdraw the node operator's staked Ethereum in one of two ways:
- Partial withdrawal of the rewards balance staked above 32 ETH.
- 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.
To initiate a withdrawal in the Ethereum network using the Restaking API, follow these steps:
- Start Checkpoint: construct a serialized transaction to start a checkpoint, proving the expected funds are deposited in the EigenPod and/or validator.
- 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:
- Prepare Undelegate Restake Transaction: construct a serialized transaction to undelegate the staked amount of tokens from a node operator.
- Queue Withdrawals: construct a serialized transaction to queue withdrawals.
- Create Withdrawal Request: construct a serialized transaction to initiate the validator's exit from the network.
- 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.
Example request:
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 <token>' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5"
}
'
eigenPodOwnerAddress
— owner of the EigenPod address.
Example response:
{
"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.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. Use serializeTx
to sign and send 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.
Example request:
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 <token>' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"activateTx": "0x968be713c254134163da7aefef4f27b02b96a393d56306ea471d"
}
'
eigenPodOwnerAddress
— owner of the EigenPod address.activateTx
— hash of the start checkpoint transaction.
Example response:
{
"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 step.
2. Use serializeTx
to sign and send 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 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.
Example request:
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 <token>' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5"
}
'
eigenPodOwnerAddress
— owner of the EigenPod address.
Example response:
{
"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 step.
2. Use serializeTx
to sign and send 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.
Example request:
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 <token>' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"amount": "32"
}
'
eigenPodOwnerAddress
— owner of the EigenPod address.amount
— amount of ETH that is being unstaked.
Example response:
{
"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 step.
2. Use serializeTx
to sign and send 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.
Example request:
curl --request POST \
--url https://api.p2p.org/api/v1/eth/staking/direct/tx/withdrawal \
--header 'accept: application/json' \
--header 'authorization: Bearer <token>' \
--header 'content-type: application/json' \
--data '
{
"pubkeys": [
"0xffC08FcD7cFeF5c70fB2b0e1f2A8EaA690AaE2bDFfa5dBEc4dEef31DcC0B19eB1f9Cebe3E2fe9eefBD9a1BDF6FD89b39"
]
}
'
pubkeys
— list of validators public keys.
Example response:
{
"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 step.
2. Use serializeTx
to sign and send 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.
Example request:
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 <token>' \
--data '
{
"eigenPodOwnerAddress": "0x27AABeE07E0dbC8b0de20f42b1a1980871314Ef5",
"queueWithdrawalsTx": "0x5d7baf40071d011f784ced45fa815ea25dfd659837db"
}
'
eigenPodOwnerAddress
— owner of the EigenPod address.queueWithdrawalsTx
— hash of the queue withdrawals transaction.
Example response:
{
"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 step.
2. Use serializeTx
to sign and send the signed transaction to the Ethereum network.
What's Next?
- Getting Started.
- Restaking API reference.
Updated 2 days ago