Skip to main content

Ethereum / Aggregated Unstaking

The Aggregated Unstaking flow allows you to unstake ETH from multiple validators at once. There are two ways:

Option 1: On Demand Exits

This is the way to unstake ETH across multiple validators with a single request.

There are no transactions to be signed by the customer in this flow Figment will review and manually approve on-demand exits within 24-72 business hours from the time the flow is processed.

A maximum of 100 validators sharing the same withdrawal address can be exited per request.


Option 2: Using VoluntaryExits

This is the way to unstake ETH if you have pre-signed exit transactions for the validators you want to exit. View our guide for pre-signed exit transactions here.

There are no transactions to be signed by the customer in this flow The VoluntaryExit data will be immediately broadcast without a manual approval by Figment.


Create New Aggregated Unstaking Flow

To initiate the aggregated staking process, create a new flow with a POST request to /api/v1/flows.

URL

https://eth-slate.datahub.figment.io/api/v1/flows

Request

  • flow : object
    • network_code* : string Network this flow operates on (ex. ethereum).
    • chain_code* : string Chain this flow operates on (ex. goerli).
    • operation* : string The operation to perform (ex. aggregated_staking).

Response

  • id : string ID of the newly created flow.
  • operation : string The Staking API operation being performed by this flow.
  • state : string The current state of the flow.
  • actions : array
    • perform_aggregated_unstake : Use this action to unstake your ETH from a maximum of 100 validators with a single request.

The perform_aggregated_unstake action indicates three fields for data collection.

  • To go with Option 1: On Demand Exits, you only need to specify the withdrawal_address and amount.
  • To go with Option 2: Using VoluntaryExits, you'll need to supply an array of VoluntaryExit data.
Request
Example Response
{
"id": "404cfb10-cc3b-4c89-8b40-dff22643aec0",
"operation": "aggregated_unstaking",
"state": "initialized",
"actions": [
{
"name": "perform_aggregated_unstake",
"inputs": [
{
"name": "exits",
"display": "Exits",
"description": "",
"type": "array_of_validator_exit_data",
"validations": [
{
"type": "array",
"options": {
"allow_empty": true,
"allow_duplicates": false
}
},
{
"type": "length",
"options": {
"maximum": 100,
"message": "translation missing: en.workflows.v1.ethereum.aggregated_unstaking.create_aggregated_unstake_input.exceeded_max_validators"
}
},
{
"type": "array_of_objects",
"options": {
"merge_array_errors": true
}
}
],
"array": true,
"default_value": null,
"element_type": "validator_exit_data",
"inputs": [
{
"name": "validator_index",
"display": "Validator Index",
"description": "",
"type": "integer",
"validations": [],
"array": false,
"default_value": null
},
{
"name": "epoch",
"display": "Epoch",
"description": "",
"type": "integer",
"validations": [],
"array": false,
"default_value": null
},
{
"name": "signature",
"display": "Signature",
"description": "",
"type": "hex",
"validations": [],
"array": false,
"default_value": null
}
]
},
{
"name": "amount",
"display": "Amount",
"description": "",
"type": "decimal",
"validations": [],
"array": false,
"default_value": null
},
{
"name": "withdrawal_address",
"display": "Withdrawal Address",
"description": "",
"type": "string",
"validations": [],
"array": false,
"default_value": null
}
]
}
],
"data": {
"exits": [],
"estimated_principal_return_at": null,
"withdrawal_address": null,
"amount": null,
"transactions": []
},
"network_code": "ethereum",
"chain_code": "goerli",
"created_at": "2023-04-21T19:38:14.421Z",
"updated_at": "2023-04-21T19:38:14.421Z"
}


Submit Aggregated Unstaking Data (Option 1: On Demand Exits)

After collecting the required inputs, PUT /api/v1/flows/[:flow_id]/next to move on to the next step.

URL

https://eth-slate.datahub.figment.io/api/v1/flows/[:flow_id]/next

Request

  • name* : string Name of the action to execute (required).
  • inputs* : object.
    • withdrawal_address* : string The wallet to which the ETH will be deposited.
    • amount* : A multiple of 32 ETH.

Response

The aggregated unstaking flow will exit enough validators to unstake your full amount, provided that the validators have a common withdrawal address. The flow state will become broadcasting until Figment manually approves the validator exits (within 24-72 business hours). The flow state will move to exiting when the validators have joined the exit queue, withdrawing when the validators have left the exit queue and unstaked when all validators have been withdrawn. Refer to the guide Ethereum Validator Lifecycle for details. The timestamp estimated_principal_return_at indicates the (estimated) latest time for all validators to be withdrawn.

Request
Example Response
{
"id": "535807ff-2ff7-4b1c-a887-bfc4fcc15ed2",
"operation": "aggregated_unstaking",
"state": "broadcasting",
"actions": [
{
"name": "wait",
"estimated_state_change_at": "2023-04-21T17:51:39.341Z",
"inputs": []
}
],
"data": {
"exits": [
{
"validator_index": null,
"validator_pubkey": "aa4e2aa5322c4b5f2b2f735daa68a2b9b9e0bf1ede924abaef7f66f9d2aa6463b048a4da10bede2a1a5c3ec885044056",
"epoch": null,
"signature": null,
"status": "broadcast_scheduled",
"source": "internal"
}
],
"estimated_principal_return_at": null,
"withdrawal_address": "0x3B41D9736eD9bfC15A87d8FBB69C616190AeD6C6",
"amount": "32.0",
"transactions": []
},
"network_code": "ethereum",
"chain_code": "goerli",
"created_at": "2023-04-21T16:10:42.673Z",
"updated_at": "2023-04-21T16:12:10.281Z"
}


Submit Aggregated Unstaking Data (Option 2: Using VoluntaryExits)

After collecting the required inputs, PUT /api/v1/flows/[:flow_id]/next to move on to the next step.

URL

https://eth-slate.datahub.figment.io/api/v1/flows/[:flow_id]/next

Request

  • name* :string Name of the action to execute.
  • inputs* : object.
    • exits* : array of VoluntaryExit data.
      • validator_index* : number The validator's index number on the beacon chain. Pass either the index number or the public key.
      • validator_pubkey : string The public key of the validator to exit.
      • epoch* : number Epoch when the pre-signed exit transaction was generated by Figment.
      • signature* : string A BLS proof of possession i.e., a proof that the private key corresponding to the validator_pubkey or validator_index is known by the signer.

Response

The aggregated unstaking flow will exit the validators for which you provide VoluntaryExit data. The exit transactions are immediately broadcast, without manual approval by Figment. The flow state will move from broadcasting to exiting while the validator is in the exit queue. Once the validator has been withdrawn, the flow state will move to unstaked. The validator status(es) will update as the validator(s) join the exit queue, leave the exit queue, and are withdrawn.

  • in_queue when a validator is found in the exit queue and is still in the active set.
  • exited_queue when a validator has left the active set and is no longer receiving rewards.
  • withdrawal_done when a validator has exited the active set and the staked ETH has been sent to the withdrawal address.
Request
Example Response
{
"id": "46318ed0-05b9-4027-896a-cbd35e43983e",
"operation": "aggregated_unstaking",
"state": "broadcasting",
"actions": [
{
"name": "wait",
"estimated_state_change_at": "2023-04-24T16:23:48.419Z",
"inputs": []
}
],
"data": {
"exits": [
{
"validator_index": 470821,
"validator_pubkey": null,
"epoch": 171379,
"signature": "0xb4ab419f310e3485e7ac03f40a31839b595c006227cc93900421ee5f4df768ca97c99a8dd447c543b5e789b4f37bb3490fd2d8c5259c08516d888c88c2534cb15c94493bab321d11ff30c34e3a31f97785bf09f9a15a6e564fb98676215d5c93",
"status": "broadcasting",
"source": "external"
}
],
"estimated_principal_return_at": null,
"withdrawal_address": null,
"amount": "32.0",
"transactions": []
},
"network_code": "ethereum",
"chain_code": "goerli",
"created_at": "2023-04-24T16:15:07.485Z",
"updated_at": "2023-04-24T16:15:48.175Z"
}


Get Aggregated Unstaking Flow Status

To get the current state of the existing flow, send a GET request to /api/v1/flows/[:flow_id] using the flow ID from the previous step.

URL

https://eth-slate.datahub.figment.io/api/v1/flows/[:flow_id]

Request

  • None

Response

  • id : string ID of the flow.
  • operation : string The Staking API operation being performed by this flow.
  • state : string The current state of the flow.
    • broadcasting : Transaction is broadcasting and not confirmed yet.
    • exiting : The validator has joined the exit queue, and is still in the active set.
    • withdrawing : The validator has left the exit queue and the staked ETH is being sent to the withdrawal address.
    • unstaked : Withdrawal has been confirmed and unstaked ETH sent to the withdrawal address.
    • Refer to the Ethereum Validator Lifecycle guide for more information.
  • actions : array It includes the name & inputs of all next possible actions.
  • data : object Flow & transaction data.
    • exits : array One object per validator being exited.
      • validator_index : The validator index number.
      • validator_pubkey : The validator's beacon chain public key.
      • epoch : The epoch in which the validator exit was requested.
      • status : Will be one of broadcast_scheduled, in_queue, exited_queue, withdrawal_done depending on the current status of the validator being exited.
      • source : "internal"
    • estimated_principal_return_at : This timestamp indicates the (estimated) latest time that all unstaked ETH will be sent to the withdrawal address. This is subject to change depending on the exit queue, and withdrawals can complete before this time.
    • withdrawal_address : The withdrawal address specified for the validator when it was provisioned.
    • amount : A multiple of 32 ETH.
    • transactions : Since there are no transactions signed in this flow, this array will always be empty.
Request
Example Response
{
"id": "4b4dbd07-27ed-45d9-940f-e74e94bf5664",
"operation": "aggregated_unstaking",
"state": "unstaked",
"actions": [],
"data": {
"exits": [
{
"validator_index": null,
"validator_pubkey": "a58c71cf8fdf116114afd9622a9087609a314766f25b9afea6a511522b50091ace55424143a19d41a73b39f9f07b2b58",
"epoch": null,
"signature": null,
"status": "withdrawal_done",
"source": "internal"
}
],
"estimated_principal_return_at": "2023-04-14T22:20:49.882Z",
"withdrawal_address": "0x3b41d9736ed9bfc15a87d8fbb69c616190aed6c6",
"amount": "32.0",
"transactions": []
},
"network_code": "ethereum",
"chain_code": "goerli",
"created_at": "2023-04-12T20:30:14.556Z",
"updated_at": "2023-04-15T00:21:05.517Z"
}