# Staking

* [API URL](#api-url)
* [Authentication](#authentication)
* [API Endpoints](#api-endpoints)
  * [`POST /api/v2/staking/transactions`](#post-api-v2-staking-transactions)
    * [Accepted parameters](#accepted-parameters)
    * [Response Format](#response-format)
    * [Examples](#examples)
  * [`POST /api/v2/staking/eth/validators/:validator_pubkey/exits`](#post-api-v2-staking-eth-validators-validator_pubkey-exits)
    * [Accepted parameters](#accepted-parameters)
    * [Response Format](#response-format)
    * [Examples](#examples)
  * [`POST /api/v2/staking/eth/validators/:validator_pubkey/withdrawals`](#post-api-v2-staking-eth-validators-validator_pubkey-withdrawals)
    * [Accepted parameters](#accepted-parameters-2)
    * [Response Format](#response-format-2)
    * [Examples](#examples-2)
  * [`POST /api/v2/staking/eth/validators/:validator_pubkey/top-ups`](#post-api-v2-staking-eth-validators-validator_pubkey-top-ups)
    * [Accepted parameters](#accepted-parameters-3)
    * [Response Format](#response-format-3)
    * [Examples](#examples-3)

## API URL

You will receive your warm wallet integration URL from your point of contact at Balance, and will look like:

```
YOUR_CUSTOM_SUBDOMAIN.balancecustody.ca
```

***

## Authentication

Due to the nature of the information exposed, every endpoint in this API requires authentication.

For more information on authentication go to [Authentication ](/balance-custody-api/authentication.md)doc.

***

## API Endpoints

For brevity, the `curl` examples below do not include headers. See the Authentication Docs for required headers.

Response data is for example purposes only and does not represent real accounts.

### `POST /api/v2/staking/transactions`

Creates a staking transaction for a given asset.

Note that this API is only supported if your account is configured for staking to a provider with established API credentials and configuration such as Attestant.

#### Accepted parameters:

Accepts the following parameters as JSON-encoded POST request body. Must specify the `Content-Type: application/json` header with the request.

**`asset`**

Required. String. Lowercase asset to be transferred.

Currently only the following assets are supported for this API call:

* `eth` - Ethereum

**`amount`**

Required. String. Specifies the amount to be staked, in base unit (e.g. `wei`). Note that specifying more than 32 ETH (i.e. `"32000000000000000000"` ) will result in a compounding validator.

**`compounding`**

Optional. Boolean. Creates a compounding validator when enabled. If the amount is > 32 ETH, this value is automatically set to `true`. If you explicitly set `compounding: false`, the amount must be 32 ETH (i.e. `"32000000000000000000"` ).

**`source_wallet_id`**

Required. Integer. ID of the wallet from which the funds are to be withdrawn.

**`destination_id`**

Required. Integer. This must be the ID of the Ethereum (ETH) staking contract external account that is configured for your instance by Balance. Note that the default beneficiary entity needs to be set on this external account.

**`withdrawal_wallet_id`**

Required. Integer. ID of the wallet where staking rewards are to be sent. Can be a warm or offline wallet ID or an external account ID.

**`fee`**

Optional. String or integer. Specifies the fee rate or preset. Valid values are:

* `slow` - we recommend specifying this if you're ok with waiting for hours / days for your transaction to be included in a block, or potentially be dropped out of the mempool during periods of high congestion.
* `medium` - recommended preset, your transaction should be included in the next block in most cases
* `fast` - we recommend using this if you want to ensure your transaction is included in the next block during periods of high congestion.

You can also specify a fee rate, in the fee rate unit. In the case of Ethereum (ETH) that unit is `gwei`. Our backend will perform additional validation on this value to ensure it is within reasonable bounds.

**`group_id`**

Optional. String (max 256 characters). Specifies the Group ID with which an Attestant validator is to be configured.

**`notes`**

Optional. String. Any notes for your own records. These have no effect on the on-chain transactions.

**`beneficiary_entities`**

Required if travel rule is applicable. An object of type Originator Entity.

**`idempotency_key`**

Optional. String (32 to 255 characters). Specifies a globally unique identifier for the request. If a request\
if received with an idempotency key that has already been used, the API will return the existing transaction, and no new transaction will be created. Useful for avoiding duplicate transactions when retries are required. It is recommended to use a UUID or similar robust key generator for this value to avoid collisions.

#### Response Format:

The response format is the standard Transaction struct, which can be found in [`GET /api/v1/transactions/:id`](https://gitlab.com/paradiso-ventures/api-docs/-/tree/master/transactions/README.md#get-apiv1transactionsid).

Once the transaction has been generated and broadcast (after all applicable approvals and checks are done), you will receive the following fields from the [`GET /api/v1/transactions/:id`](https://gitlab.com/paradiso-ventures/api-docs/-/tree/master/transactions/README.md#get-apiv1transactionsid) API call, that are specific to the staking transactions:

**`withdrawal_wallet`**

A wallet struct (definition can be found in the [`GET /api/v1/wallets/:id`](https://gitlab.com/paradiso-ventures/api-docs/-/tree/master/wallets/README.md#get-apiv1walletsid) API call) specifying the wallet where ETH staking rewards will be deposited.

**`validator_pubkey`**

The public key of the validator once it has been allocated. Note that this field will not be immediately available until the transaction has been approved, validator has been allocated and transaction has been generated. We suggest polling the [`GET /api/v1/transactions/:id`](https://gitlab.com/paradiso-ventures/api-docs/-/tree/master/transactions/README.md#get-apiv1transactionsid) API call to look for this field.

#### Examples:

Example request body:

```json
{
  "asset": "eth",
  "amount": "32000000000000000000",
  "source_wallet_id": 1,
  "destination_id": 2,
  "withdrawal_wallet_id": 3
}
```

Example request body with group ID:

```json
{
  "asset": "eth",
  "amount": "32000000000000000000",
  "source_wallet_id": 1,
  "destination_id": 2,
  "withdrawal_wallet_id": 3,
  "group_id": "foobar"
}
```

Example request body with custom fee preset:

```json
{
  "asset": "eth",
  "amount": "32000000000000000000",
  "source_wallet_id": 1,
  "destination_id": 2,
  "withdrawal_wallet_id": 3,
  "fee": "fast"
}
```

Example request body with custom fee rate of 15 Gwei and notes:

```json
{
  "asset": "eth",
  "amount": "32000000000000000000",
  "source_wallet_id": 1,
  "destination_id": 2,
  "withdrawal_wallet_id": 3,
  "fee": 15,
  "notes": "foo bar"
}
```

Example response body:

```json
{
    "amounts": { "eth": 32.0 },
    "beneficiary_entities": [],
    "beneficiary_entity": {},
    "block": { "eth": 8014743 },
    "cad_rates": { "eth": 1594.09107 },
    "completed_at": "2022-11-25T01:57:27.000Z",
    "created_at": "2022-11-25T01:57:20.000Z",
    "destination": {
        "addresses": { "eth": "0xff50ed3d0ec03ac01d4c79aad74928bff48a7b2b" },
        "custom_id": "eth2-deposit-contract",
        "description": "An executed Staking Service Agreement with the provider as well as the appointment of Balance as an Authorized Person under the agreement are needed as prerequisites.",
        "id": 193,
        "name": "ETH Staking Service Provider",
        "type": "external_account"
    },
    "fee_units": { "eth": "gwei" },
    "fees": { "eth": 0.00000124812567414 },
    "id": 6299,
    "is_batched": false,
    "notes": "32 ETH to be staked with ETH Staking Service Provider with the withdrawal account set to Test Withdrawal Wallet at 0x58aCD2a994C8F20095b53b682d6dba0907E6Ec0B",
    "originator_entity": {},
    "regulatory_status": "completed",
    "requested_by": "Satoshi Nakamoto",
    "source": {
        "balance": { "eth": 38.1919651569535 },
        "custom_id": "Operating Wallet ID",
        "description": "",
        "funding_addresses": { "eth": "0x0CDE25dB916Bf4fef6BeFE384c69294515f2819E" },
        "id": 3,
        "kind": "warm",
        "name": "Operations Wallet",
        "type": "wallet"
    },
    "status": "completed",
    "transaction_ids": [{
        "currency": "eth",
        "transaction_id": "0xd5d67ced79b816bd7a8418df1603c5b74c0177a1ab5584a87767bd943a6c4695"
    }],
    "type": "transaction",
    "validator_pubkey": "0xaae1e03655adef16d1d685050f329c920f08d9acc62a26d86be5384c2e2dd91d46b84eee7f12e721e93bfdcb3571ecb8",
    "withdrawal_wallet": {
        "balance": { "eth": 0.418593319 },
        "custom_id": "test-withdrawal-wallet",
        "description": "",
        "funding_addresses": { "eth": "0x58aCD2a994C8F20095b53b682d6dba0907E6Ec0B" },
        "id": 1259,
        "kind": "warm",
        "name": "Test Withdrawal Wallet",
        "type": "wallet"
    }
}
```

Example `curl` command:

```bash
curl -XPOST \
     -d '{"asset":"eth","amount":"32000000000000000000","source_wallet_id":1,"destination_id":2,"withdrawal_wallet_id":3}' \
     https://your_custom_subdomain.balancecustody.ca/api/v2/staking/transactions
```

### `POST /api/v2/staking/eth/validators/:validator_pubkey/exits`

Performs a voluntary exit for an ETH validator with a given public key.

Note that this API is only supported if your account is configured for staking with a provider with established API credentials and configuration, which supports voluntary exits.&#x20;

Currently, voluntary exits are supported if you're using the following staking service providers: Attestant.

#### Accepted parameters:

None

#### Response Format:

Upon success you will receive a 200 response code, with no body.

#### Examples:

Example `curl` command:

```bash
curl -XPOST \
     https://your_custom_subdomain.balancecustody.ca/api/v2/staking/eth/validators/0xad8c768353f336e660e0162c93bdb8091f4fe8ddb4c810f2df46e0ecd46c786334f3f807f3fecb32c11f3a80db467bc1/exits
```

### `POST /api/v2/staking/eth/validators/:validator_pubkey/withdrawals`

Initiates a withdrawal transaction using the withdrawal credentials of a validator with the given public key.

#### Accepted parameters:

**`amount`**&#x20;

Required. String. Specifies the amount to be withdrawn, in base unit (e.g. `wei`). Specifying `0` will perform a full withdrawal. Note that partial withdrawals (i.e. non-zero amounts) are only supported for compounding validators.

#### Response Format:

Upon success you will receive a 200 response code, with the transaction in the response body.

#### Examples:

Example `curl` command:

```bash
curl -XPOST \
     https://your_custom_subdomain.balancecustody.ca/api/v2/staking/eth/validators/0xad8c768353f336e660e0162c93bdb8091f4fe8ddb4c810f2df46e0ecd46c786334f3f807f3fecb32c11f3a80db467bc1/withdrawals \
     -d '{"amount": "0"}' \
     -H "Content-Type: application/json"
```

### `POST /api/v2/staking/eth/validators/:validator_pubkey/top-ups`

Initiates a top-up transaction to a validator with the given public key. These transactions can be initiated from any wallet.

#### Accepted parameters:

**`amount`**&#x20;

Required. String. Specifies the amount to be sent to the validator, in base unit (e.g. `wei`). The amount must be divisible by `1 gwei`. Note that top-ups need to be a minimum of 1 ETH.

**`source_wallet_id`**&#x20;

Required. Integer. Specifies the ID of the wallet from which the top-up amount is to be sent.

#### Response Format:

Upon success you will receive a 200 response code, with the transaction in the response body.

#### Examples:

Example `curl` command:

```bash
curl -XPOST \
     https://your_custom_subdomain.balancecustody.ca/api/v2/staking/eth/validators/0xad8c768353f336e660e0162c93bdb8091f4fe8ddb4c810f2df46e0ecd46c786334f3f807f3fecb32c11f3a80db467bc1/top-ups \
     -d '{"amount": "1000000000000000000", "source_wallet_id": 1}' \
     -H "Content-Type: application/json"
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://balance-1.gitbook.io/balance-custody-api/v2/staking.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
