> ## 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.

# Withdrawal using VEM

> Withdraw staked ETH with a Validator Exit Message using the P2P.org Staking API.

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/).

<Note>
  **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 <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> 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.
</Note>

<Steps>
  <Step title="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 theme={null}
    1. "ecdhPublicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFNWgwcmRaSEZaZWNSbWIxR2RqQis3T0dUMnovegozMG1TRnZhWTdQaTltek5HT3J6SjZVbS9GbUMwb2lXMVFBT1FhOVFldGFpZm1EMU0zc09iU0JwV3N3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
    ```

    Example of its base64-decoded version:

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

  <Step title="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 theme={null}
       {
         "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](/reference/eth-vem-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/vem/create \
            --header 'accept: application/json' \
            --header 'authorization: Bearer <token>' \
            --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 theme={null}
       {
         "result": true
       }
       ```
  </Step>

  <Step title="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.
  </Step>

  <Step title="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}](/reference/eth-vem-status).

    Example request:

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

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

    Example response:

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


## Related topics

- [Getting Started](/docs/staking-ethereum.md)
- [Staking API reference](/reference/eth-nodes-request-create.md)
