# What is Bloq?

[**Bloq**](https://www.bloq.com) consists of multiple managed blockchain cloud services to help accelerate blockchain development and deployment. Bloq caters to individual developers and startups and scales to enterprise requirements.

Bloq currently consists of three services:

* [**Nodes**](/bloq-services/bloqnodes): Private, fully managed cluster of nodes to access popular public blockchain networks.
* [**Stake**](/bloq-services/bloqstake): Infrastructure and API endpoints to allow users to create validators and start staking, simpler than ever. Currently, the Bloq API supports staking on the following networks:
  * Ethereum
  * Avalanche


# Introduction

Currently, access to Bloq services is through the Bloq Command Line Interface (CLI) or REST API. A web GUI will be provided at a future point in time.

In the following sections, you will find tutorials which guide you along the main features of Bloq services:

* [Create an account](/readme/bloq-account-setup)
* [Manage client keys and tokens](/readme/create-client-keys)
* [Create your first BloqNode](/bloq-services/bloqnodes)
* [Stake with BloqStake](/bloq-services/bloqstake)


# Bloq Account Setup

This tutorial will guide you through all the required steps to set up a Bloq account and start using our services.

Users require a Bloq Account in order to acccess Bloq services. A Bloq account is associated with an individual user. Organizational support will be provided in a future release.

### Install Bloq CLI

To set up your Bloq account, install our [CLI](https://www.npmjs.com/package/@bloq/cloud-cli). Open a terminal window and run the following command:

```shell
npm i -g @bloq/cloud-cli
```

{% hint style="warning" %}
**`WARNING`**

* CLI requires that you have installed [Node.js](https://nodejs.org/en/download/)>= 8.x.x
* If you run into permissioning issues installing npm packages globally, please refer to this [article](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally).
  {% endhint %}

### Check CLI Version

Once you install the CLI, you will have access to the global command `bcl`. You can run CLI with `--version` flag to check that everything is working.

```console
$ bcl --version
@bloq/cloud-cli/2.3.2 darwin-x64 node-v8.12.0
```

### Signup

Once you confirm the CLI is functioning, please see the [Bloq Console Signup](https://console.bloq.cloud/signup) page to create your Bloq account.

Through the Bloq Console website, users can perform a variety Bloq Accounts operations, such as:

* Access and update account information and preferences.
* Manage payments and billing information.
* Manage Bloq Nodes and node clusters.

{% hint style="success" %}
**`TIP`**

Some of the steps outlined in later on, such as \`Verify Account , may alternatively be carried out through the Bloq Console.
{% endhint %}

### Verify Account

In order to verfy your account, check your email and have the confirmation email at hand. Run the CLI `verify`command, which will prompt you for your **Email Address**and **Verfication Token** contained in the email.

```shell
bcl verify
```

```console
? Enter your email address or account id your@email.com
? Enter your verification token xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
✔ The account your@email.com has been validated
ℹ You can now start a new session running the command: bcl login -u your@email.com
```

### Login & Start Using Bloq

When your account is successfully created, you can start using Bloq services, manage your user information and generate client keys using the CLI. To start using Bloq services, start a new session using the `login` command:

```shell
bcl login -u your@email.com
```

```console
ℹ Account saved. Next time you only need -p flag (--password) to login.
ℹ Login with user your@email.com
? Enter your password xxxxxxxx
✔ Login success. Your session expires in 12h.
```

#### Password creation important note

When you choose your password, keep in mind that there are some special characters that are handled as **command line modifiers**, depending on your operating system. For example, if your password includes hyphens (-) or exclamation marks (!) and you are under a Linux-ish environment, the `--password` value must be surrounded by quotation marks (') in order to avoid the default shell behavior for these symbols. On Windows environments, such behavior could be present on other symbols, or not be present at all. Please refer to your operating system documentation to check which characters are used as command line modifiers, and how to escape them correctly if you want to use them on your password at the command line.

{% hint style="success" %}
**`TIP`**

* Each CLI session expires in 12h. After that, you will need to re-login to continue using services.
* You can run the `login` command using your **Email Address** or **Bloq Account ID**.
* Most commands allow you to add arguments using flags. If you miss a required flag, you will be prompted to enter the argument manually.
* Run `bcl help` to list available commands and their associated options.
  {% endhint %}


# Create Client Keys

Client keys are pairs (Client ID + Client Secret) composed of random hexadecimal numbers which enables your code/program to authenticate with our servers and grant you access to various Bloq services.

{% hint style="danger" %}
**WARNING**

* Client keys are sensitive information. You should avoid sharing or exposing them and always keep them safe.
* Keep in mind that once you generate a client key, you will not be able to see the Client Secret \*\*\*\* again.
* Bloq is unable to help recover / retrieve generated client keys.
  {% endhint %}

### Using the CLI

The CLI has the `'bcl client-keys'` command with a set of arguments that lets you create, list, and revoke client keys.

To create a new pair of client keys, run `bcl client-keys create` on a terminal. Remember that you first need to be authenticated (with the `bcl login` command) into Bloq to perform this operation.

```shell
bcl client-keys create
```

```console
ℹ Creating new pair of client keys for user jon@doe.com.
? Do you want bcl to store your tokens locally for future usage? Yes
✔ Generated new client keys:
   * Client ID:  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   * Client Secret:  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

ℹ Client secret was copied to clipboard.
WARN  You will be not able to see your client secret again. Remember to copy it and keep it safe.
```

Copy the **Client ID** and **Client Secret** and keep them safe. You now have everything to start using Bloq Services.

{% hint style="success" %}
**TIP**

* The CLI will ask you to store those keys locally. We recommend for you to store the keys locally as you will need them in order to use Bloq services through the CLI.
* You can have multiple pairs of client keys. Use `bcl client-keys` to list all available keys.
  {% endhint %}


# Accounts Overview

The Bloq Accounts service is central to all Bloq services. The Bloq Accounts service is used to manage access and authenticate users. Through the Bloq Accounts service, users can:

* Manage their Bloq account and profile
* Manage their tokens (e.g., access tokens, refresh tokens) and client-keys
* Manage list of events associated with their Bloq account
* Manage their PGP public keys

Bloq Accounts service can be accessed through the Command Line Interface, SDKs, Bloq Console website, or REST APIs. The [Technical Reference](/advanced-documentation/technical-reference) provides information on how to access the Accounts service through the REST API.

### API URL

Account-related operations interact with the URL endpoint found at [accounts.bloq.cloud](https://accounts.bloq.cloud/).

In other words, the above actions (managing your Bloq account, tokens, events, etc.) can only take place once your client hits the Bloq Accounts endpoint URL. The REST API provides a nice insight as to what this activity looks like:

```shell
curl -X GET https://accounts.bloq.cloud/users/me \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```

The user can interact with the Bloq Accounts service through the above command by accessing the `https://accounts.bloq.cloud/` API URL. More specifically, the above command requests the URL to access the `users/me` endpoint, which returns account-related information such as the account display name, email and Client ID. If a token is not sent, the request to GET the information will be denied.

For Bloq Accounts API calls, an `<AUTH_TOKEN>` is required. You can retrieve your `<AUTH_TOKEN>` via the CLI with the following command:

```shell
bcl conf accessToken
```

When logging in to your Bloq account through the REST API, your `<AUTH_TOKEN>` will be automatically returned alongside a successful login. The [Technical Reference](/advanced-documentation/technical-reference/accounts-api) provides a lower level and more thorough walk-through for interacting with the Accounts API URL through the REST API.

{% hint style="success" %}
TIP

The URL is used for back-end communication. If you try to access via web browser, you will reach an unintuitive destination!
{% endhint %}

The following section includes steps to generate a `Client Access Token`. The `Client Access Token` is used to communicate with the BloqNodes service. However, only the `<AUTH_TOKEN>` is accepted for Accounts service operations.


# BloqNodes

#### Description

The BloqNodes service enables users to create a new dedicated, managed blockchain node.

Currently, the Nodes service supports mainnet and testnet for the following chains:

* Bitcoin (BTC)
* Bitcoin Cash (BCH)
* Litecoin (LTC) (mainnet only)
* Ethereum (ETH)
* Avalanche (AVAX)

#### Why BloqNodes?

In just a few steps, you can spin up your own dedicated cluster of nodes to access the most important blockchain networks. With BloqNodes, you can leave the infrastructure concerns to us.

Please refer to the [command line interface](/bloq-services/bloqnodes/cli) or [Bloq Console](https://console.bloq.cloud/) for the latest available blockchain software versions available.


# CLI

The `bcl nodes` command is used to access the Nodes service.

The following operations are supported within `bcl nodes <OPERATION>`

| Operation      | Description                       |
| -------------- | --------------------------------- |
| chains         | Get list of supported blockchains |
| info           | Get information on a node         |
| list (default) | Get list of nodes                 |
| remove         | Remove a node                     |
| services       | Get list of Bloq Node services    |

#### Creating a New Node

Creation of a node must be done through the [Bloq Console](https://console.bloq.cloud/nodes/single/new). For the moment you are not allowed to use the CLI to spin a new node.

> TIP: Once initialization of a node is complete, a node will require some time to catch-up to the latest blocks on the blockchain. A node is created using a recent snapshot of the blockchain and generally needs to catch-up for the last few hours of data.\
> The duration to sync to the latest blockchain data will vary across blockchains. Upon completion of the sync, the node is ready for usage.

#### Listing supported chains

Viewing all blockchains supported by BloqNodes is accessed through the command: `bcl nodes chains`. The user will be able to view the list of all chains that are offered by Bloq Nodes.

#### Getting node information

To retrieve information on a node, use the command: `bcl nodes info`. The user will receive a prompt for the *Node ID*. Upon providing the *Node ID*, the CLI will provide detailed information on the node.

#### Listing nodes

Viewing the list of active nodes is accessed through the command: `bcl nodes list`.\
The user will be able to view the list of nodes including the *Node ID* and the time the node was initialized.

#### Removing a node <a href="#removing-a-node" id="removing-a-node"></a>

To remove a node, use the command: `bcl nodes remove`. The user will receive a prompt for the *Node ID*. Upon providing the *Node ID*, and confirmation for the removal of the node, the node will be removed.

#### Listing Bloq services <a href="#listing-bloq-services" id="listing-bloq-services"></a>

Viewing all services offered by Bloq Nodes is accessed through the command: `bcl nodes services`. The user will be able to view a comprehensive list of all types of nodes that can be accessed by the Bloq Nodes service. Specifications include the chain, region, performance tier, software version, and service id.


# Nodes Usage

To access a node, you will need to use the IP address which you can obtain via `bcl nodes list` or `bcl nodes info`.

From there you may access the REST or RPC interfaces (described in the [Technical Reference](/advanced-documentation/technical-reference/nodes-api)) using `curl` or any other HTTP client.

### REST <a href="#rest" id="rest"></a>

*Use REST for connecting to Bitcoin, Bitcoin Cash, and Litecoin nodes.*

```shell
curl -k -X GET \
  --user <nodeUser>:<nodePass> \
  https://<ip-address>:8332/rest/chaininfo.json
```

### JSON RPC <a href="#json-rpc" id="json-rpc"></a>

*Use JSON RPC for connecting to Ethereum and Avalanche nodes.*

```shell
curl -k -X POST \
  --user <nodeUser>:<nodePass> \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": [] }' \
  https://<ip-address>:8332/
```

#### Client-token

To generate a client token, run the following command:

`bcl client-token`


# BloqStake

BloqStake is a non-custodial staking solution that provides stakers with the ability to stake their tokens to validate on various blockchain networks.

BloqStake provides the following services for staking (dependent on the protocol):

1. Dedicated / white-labelled validator nodes
2. Public delegated nodes

The following services are currently supported (broken out by protocol):

| Protocol      | Dedicated/ White-labelled Node                            | Delegation                                         |
| ------------- | --------------------------------------------------------- | -------------------------------------------------- |
| **Ethereum**  | [Yes](/bloq-services/bloqstake/ethereum/getting-started)  | N/A                                                |
| **Algorand**  | Yes                                                       | No                                                 |
| **Avalanche** | [Yes](/bloq-services/bloqstake/avalanche/getting-started) | [Yes](https://stake.bloq.com/protocols/avalanche/) |
| **BNB Chain** | Yes                                                       | No                                                 |
| **Cardano**   | Yes                                                       | Coming Soon                                        |
| **Kusama**    | Yes                                                       | Coming Soon                                        |
| **Orchid**    | Yes                                                       | No                                                 |
| **Polkadot**  | Yes                                                       | Coming Soon                                        |
| **Polygon**   | Yes                                                       | No                                                 |
| **Solana**    | Yes                                                       | Coming Soon                                        |
| **Tezos**     | Yes                                                       | No                                                 |
| **V Systems** | Yes                                                       | [Yes](https://stake.bloq.com/protocols/vsystems/)  |

To start your own dedicated/white-label node, please contact us at **<support@bloq.com>** and we can help you get started.


# Authenticate to Bloq API

To get started with BloqStake services using an Ethereum PoW account, you must authenticate to the Bloq API. Please contact [**support@bloq.com**](mailto:support@bloq.com) to have your address whitelisted before authenticating.\
\
After whitelisting your address, visit [authentication.md](https://github.com/bloqpriv/bloq-services-monorepo/blob/gitbook/docs/bloq-services/bloqstake/auth/authentication.md) to authenticate your account and begin staking.


# Authentication

> **Note:** To get started with BloqStake services using an Ethereum PoW account, you must authenticate to the Bloq API. Please contact **<support@bloq.com>** to have your address whitelisted before authenticating.

This is a multi-step process:

1. obtain a nonce,
2. create a message,
3. sign it, and
4. send it back to receive an authentication token.

Note that the account must be enabled by the Bloq administrators as this is a permissioned service. Also note that the account is used to identify the user. It is not related to the validators and must be derived from a different mnemonic than the one used to create the validator keys.

### 1. Obtain a nonce

Obtain the alphanumeric random nonce required to authenticate using the address of the account mentioned above:

```shell
curl -X POST https://api.bloq.com/auth/users/<PUBLIC_ADDRESS>/nonce
```

> **Note**: The `PUBLIC_ADDRESS` must be lowercase or in EIP-55 checksum format.

The response will be a JSON with the user nonce.

```json
// Sample response
{
  "nonce": "<NONCE>"
}
```

### 2. Create the authentication message

Using the copy icon, copy the authentication message below into your preferred text editor and insert your public address, nonce, and ISO time string.

```
api.bloq.com wants you to sign in with your Ethereum account:
<PUBLIC_ADDRESS>

Signing In With Ethereum on Bloq

URI: https://api.bloq.com
Version: 1
Chain ID: 1
Nonce: <NONCE>
Issued At: <ISO_STRING_DATETIME_OF_SIGNING>
```

> **Note:** The signature time ISO string can be obtained by executing `new Date().toISOString()`. To obtain the signature time ISO string, you may use a JS browser to run the command.

### 3. Sign the authentication message

Visit <https://pure.finance/sign-message> and submit the authentication message to receive your signature. The signature will be used to authenticate to the Bloq API.

### 4. Send the signature to authenticate

Using the copy icon, copy the message below into your preferred text editor and insert your public address, signature, and identical ISO time string. Send the message and obtain your authentication token. Note your authentication token will expire after 12 hours.

```shell
curl -X POST https://api.bloq.com/auth \
  -H 'Content-Type: application/json' \
  -d '{
    "address": "<PUBLIC_ADDRESS>",
    "service": "stake",
    "signature": "<SIGNATURE>",
    "signedAt": "<ISO_STRING_DATETIME_OF_SIGNING>"
  }'
```

> **TIP:** If you are experiencing difficulties receiving a successful response, check your quotation marks to ensure they are in appropriate format.


# API Routes

Jump to:

* [POST /auth](#post-auth)
* [POST /users/{publicAddress}/nonce](#post-userspublicaddressnonce)

## POST /users/{publicAddress}/nonce

Get the Bloq API authentication nonce for the given user.

This nonce has to be signed with the private key corresponding to the Ethereum 1.0 address representing the user and sent in the request.

The signature must be then sent by calling `POST /auth` to get the authentication token and complete the authentication flow.

### Parameters

| Name          | In   | Type   | Required | Description                                                              |
| ------------- | ---- | ------ | -------- | ------------------------------------------------------------------------ |
| publicAddress | path | string | yes      | The Ethereum address of the user in lowercase or EIP-55 checksum format. |

#### Sample request

```shell
curl -X POST https://api.bloq.com/users/0x0000000000000000000000000000000000000000/nonce
```

### Response

| Status | Description                     |
| ------ | ------------------------------- |
| 200    | The user's nonce was retrieved. |
| 404    | The user was not found.         |

| Property | Type   | Description                      |
| -------- | ------ | -------------------------------- |
| nonce    | string | The user's authentication nonce. |

#### Sample response

```json
{
  "nonce": "Qd4b6cs9OUOEoXiSx"
}
```

## POST /auth

Authenticate to the Bloq API and obtain the token required to call the rest of the API routes.

After obtaining the nonce by calling `GET /users/{publicAddress}/nonce`, that nonce has to be signed with the private key corresponding to the user's Ethereum 1.0 address and sent back to the API to complete the authentication flow.

Once validated, the API will issue a short-lived JWT to be used as proof of authentication with the rest of the API routes.

### Parameters

| Name       | In   | Type   | Required | Description                                   |
| ---------- | ---- | ------ | -------- | --------------------------------------------- |
| .address   | body | string | yes      | The Ethereum 1.0 address of the signing user. |
| .service   | body | string | yes      | It must be 'stake'.                           |
| .signature | body | string | yes      | The signature of the message                  |
| .signedAt  | body | string | yes      | The ISO date of the moment of signing.        |

#### Sample request

```shell
curl -X POST https://api.bloq.com/auth \
  -H 'Content-Type: application/json' \
  -d '{
    "address": "0x0000000000000000000000000000000000000000"
    "service": "stake",
    "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "signedAt: "2022-07-11T18:23:22.513Z"
  }'
```

### Response

| Status | Description                             |
| ------ | --------------------------------------- |
| 200    | The authentication token was generated. |
| 401    | The user was not found.                 |
| 403    | The signature is invalid.               |

| Property | Type   | Description               |
| -------- | ------ | ------------------------- |
| (root)   | object | The response.             |
| .token   | string | The authentication token. |

#### Sample response

```json
{
  "token": "xxxxxx.xxxxxxxxxx.xxxxxx"
}
```


# Ethereum

Ethereum is a decentralized blockchain, secured by ETH, that establishes a peer-to-peer network to verify smart contracts and allow participants to transact with each other without a single point of authority. Ethereum shifting to proof-of-stake will provide opportunities for you to secure the network and earn rewards.

As with most PoS networks, each validator will get rewarded with the transaction fees involved in the block they verify. Validators are required to stake exactly 32 ETH on the network to be eligible for selection.

### Rewards

Validator rewards serve as an intrinsic motivation system to encourage validators who propose blocks to maintain appropriate conduct. When a validator successfully presents a valid block that subsequently gains unanimous attestation from all other validators, they are granted a block reward.

The value of a block reward is composed of three sources:

* Attestation / block proposal,
* Transaction fees, and
* MEV

### Penalties

Ethereum validators that make incorrect or missing attestations will receive penalties. In these cases, the penalties are commensurate with the rewards that would have been earned if the attestations had been submitted correctly.\
\
"Slashing" is a measure in the Ethereum network aimed at maintaining the integrity of the system by discouraging malicious or negligent behavior. It involves the removal, or slashing, of a portion of a validator's staked ETH when they act against the network's rules or fail to perform their duties correctly.\
\
A validator can be slashed by:

* Proposing and signing two different blocks for the same slot,
* Attesting to a block that "surrounds" another one, or
* Attesting to two candidates for the same block (double voting).

Bloq covers instances of slashing to safeguard your stake, ensuring that you receive maximum rewards. Visit [Stake ETH](/bloq-services/bloqstake/ethereum/getting-started) To start staking with BloqStake services.


# Stake ETH

In order to stake ETH with Bloq, follow the steps in this guide.

Staking in Ethereum requires infrastructure, Ether, and carefully following some steps to become a validator and start earning Ether.

While ethereum.org provides a step by step guide on how to [become a validator](https://launchpad.ethereum.org/en/), the Bloq platform makes it simpler by providing the infrastructure needed and an API to allow the users easily create validators and start staking.

**Requirements**

* A minimum balance of 32 ETH in the PoS Ethereum chain per validator to create.
* [Authentication to the Bloq API](/bloq-services/bloqstake/authenticate-to-bloq-api)

### 1. Prepare to create a validator

Before starting, ensure you have control on 3 Ethereum 1.0 addresses:

1. A funding address with at least 32 ETH plus an extra amount to pay for transaction fees.
2. A withdrawal address to receive the 32 ETH back.
3. A fee address to collect the transaction fees.

{% hint style="danger" %}
Be very careful when selecting and inputting the withdrawal address. The withdrawal address **can not** be changed later and losing access to the withdrawal keys will result in loss of access to tokens.
{% endhint %}

### 2. Create a validator

To create a validator using the addresses previously defined, call the BloqStake API with the authentication token (created using the steps outlined in [authentication.md](https://github.com/bloqpriv/bloq-services-monorepo/blob/gitbook/docs/bloq-services/bloqstake/auth/authentication.md)), the withdrawal address, and the fee address.

```shell
curl -X POST https://api.bloq.com/staking/ethereum/mainnet/validators \
  -H 'Authorization: Bearer <AUTH_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "withdrawalAddress": "<WITHDRAW_ADDRESS>",
    "feeAddress": "<FEE_ADDRESS>"
  }'
```

The response to the call will include the data required to create the 32 ETH deposit transaction:

```json
{
  "balance": "0",
  "chain": "mainnet",
  "pubkey": "91adb75d3347747a2d143d204adaaa3eb6edaf136c3429ff796c6f825c956916f4494d433ec94615184ddc3abe8697b2",
  "status": "pending",
  "depositData": "0x22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012066c8e8eecc24c7c2fd0d1eabf608207069492414be53d3c8bc4c23c7e7d2459b000000000000000000000000000000000000000000000000000000000000003091adb75d3347747a2d143d204adaaa3eb6edaf136c3429ff796c6f825c956916f4494d433ec94615184ddc3abe8697b200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000f12bf2780ee9e15dff6ddedd3e0216e754a3d52f25bd9532fd71f78787d80e00000000000000000000000000000000000000000000000000000000000000608816e587d36f04837113260fcb8a71509e4db3b1459b1dff6d3bd9c91169458a6f34b2763d2b53071709eb01924bcf92061bd85fe022b698875f760e2573500816beb173d98c0dc27f133a60c423a5317c88183db5bcd3e04ea50add2dcf9888"
}
```

The response includes the `pubkey` of the validator and other status information. That key can be used to check the status in the [beaconcha.in](https://beaconcha.in/) website.

### 3. Initiate the deposit

With the `depositData` provided, create, sign and transmit the transaction to the Ethereum PoW network. Using `web3.js`, doing so will look like this:

```javascript
web3.eth.sendTransaction({
  from: '<FUNDING_ADDRESS>',
  to: '0x00000000219ab540356cbb839cbe05303d7705fa', // Ethereum Foundation Eth 2.0 deposit contract
  data: '<DEPOSIT_DATA>',
  value: '32000000000000000000'
})
```

Once the transaction is confirmed, the Beacon Chain will process it and issue the 32 ETH in the PoS chain. Then, the validator will start attesting new blocks.


# Withdraw ETH

In order to withdraw your staked ETH with Bloq, follow the steps in this guide.

Initiating an exit operation is not a "formal transaction" on the Ethereum network. The exit request is sent via Bloq API (using your Bloq authentication keys) and the exit operation starts immediately. It is not stored and can not be reversed.

*As a non-custodial solution, Bloq never touches your ETH.*

## Withdrawal process

Make a call to the BloqStake API to initiate the withdrawal operation:

```sh
curl -w "\n%{http_code}" -X POST https://api.bloq.com/staking/ethereum/mainnet/validators/<VALIDATOR_PUBLIC_KEY>/validatorExit \
  -H 'Authorization: Bearer <AUTH_TOKEN>' \
  -H 'Content-Type: application/json'
```

On success, the API will return a 204 status code. From that point forward, the validator and Ethereum network will take over the process, stop validating blocks, and eventually transfer the staked ETH to the withdrawal account.

{% hint style="warning" %}
**NOTE: Once initiated, this operation can not be undone.**
{% endhint %}

#### Failure modes

The following conditions will invalidate the above mentioned request:

* The validator does not have any balance.
* The validator is not in the "active"/"active\_online" state.
* The validator has no withdrawal credentials set, or these are not valid.
* The validator was already requested to initiate a full withdrawal and exit.

### Further reading

[Staking withdrawals documentation at `ethereum.org`](https://ethereum.org/en/staking/withdrawals/)


# API Routes

Jump to:

* [DELETE /staking/ethereum/{chain}/validators/{pubkey}](#delete-staking-ethereum-chain-validators-pubkey)
* [GET /staking/ethereum/chains](#get-stakingethereumchains)
* [GET /staking/ethereum/{chain}/stats](#get-staking-ethereum-chain-stats)
* [GET /staking/ethereum/{chain}/validators](#get-staking-ethereum-chain-validators)
* [GET /staking/ethereum/{chain}/validators/{pubkey}](#get-staking-ethereum-chain-validators-pubkey)
* [GET /staking/ethereum/{chain}/validators/{pubkey}/performance](#get-staking-ethereum-chain-validators-pubkey-performance)
* [GET /staking/ethereum/billing/report](#get-staking-ethereum-billing-report)
* [GET /staking/ethereum/regions](#get-staking-ethereum-regions)
* [GET /staking/ethereum/validators/report](#get-staking-ethereum-validators-report)
* [POST /staking/ethereum/{chain}/validators](#post-staking-ethereum-chain-validators)
* [POST /staking/ethereum/{chain}/validators/{pubkey}/validatorExit](#post-staking-ethereum-chain-validators-pubkey-validatorexit)
* [PUT /staking/ethereum/{chain}/validators/{pubkey}](#put-staking-ethereum-chain-validators-pubkey)
* [Error responses](#error-responses)

## DELETE /staking/ethereum/{chain}/validators/{pubkey}

Deletes a validator

### Parameters

| Name          | In     | Type   | Required | Description                 |
| ------------- | ------ | ------ | -------- | --------------------------- |
| chain         | path   | string | yes      | The validator's chain.      |
| pubkey        | path   | string | yes      | The validator's public key. |
| Authorization | header | string | yes      | The authentication token.   |

#### Sample request

```shell
curl -X DELETE https://api.bloq.com/staking/ethereum/mainnet/validators/000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                                                                           |
| ------ | ------------------------------------------------------------------------------------- |
| 204    | The validator was deleted.                                                            |
| 403    | The authorization token is invalid, or the user is not allowed to perform the delete. |
| 404    | The validator was not found.                                                          |
| 409    | The validator has balance or is staking.                                              |

#### Sample response

Successful response: HTTP 204 No content

## GET /staking/ethereum/chains

Retrieves all the chains that are enabled for the protocol

### Parameters

| Name          | In     | Type   | Required | Description               |
| ------------- | ------ | ------ | -------- | ------------------------- |
| Authorization | header | string | yes      | The authentication token. |

```shell
curl -X GET https://api.bloq.com/staking/ethereum/chains \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The list was retrieved.             |
| 401    | No authentication header found.     |
| 403    | The authorization token is invalid. |

| Property | Type   | Description            |
| -------- | ------ | ---------------------- |
| (root)   | array  | The response.          |
| \[]      | string | The name of the chain. |

#### Sample response

```json
["mainnet"]
```

## GET /staking/ethereum/regions

Retrieves all the regions where validators can be created by the user.

### Parameters

| Name          | In     | Type   | Required | Description               |
| ------------- | ------ | ------ | -------- | ------------------------- |
| Authorization | header | string | yes      | The authentication token. |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/ethereum/regions \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The list was retrieved.             |
| 401    | No authentication header found.     |
| 403    | The authorization token is invalid. |

| Property | Type   | Description             |
| -------- | ------ | ----------------------- |
| (root)   | array  | The response.           |
| \[]      | string | The name of the region. |

#### Sample response

```json
["us-east-2"]
```

## GET /staking/ethereum/{chain}/validators

List all user's Ethereum validators.

### Parameters

| Name          | In     | Type   | Required | Description               |
| ------------- | ------ | ------ | -------- | ------------------------- |
| chain         | path   | string | yes      | The validators chain.     |
| Authorization | header | string | yes      | The authentication token. |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/ethereum/mainnet/validators \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The list was retrieved.             |
| 403    | The authorization token is invalid. |

| Property              | Type                   | Description                                                                                           |
| --------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------- |
| (root)                | array                  | The response.                                                                                         |
| \[].balance           | string \| null         | The ETH balance, expressed in Wei. Returns `null` if there is a failure while retrieving the balance. |
| \[].chain             | string                 | The validator chain.                                                                                  |
| \[].depositData       | object\[] \| undefined | The deposit transaction data.                                                                         |
| \[].feeAddress        | string \| undefined    | The fee address of the validator.                                                                     |
| \[].id                | string                 | The validator's id.                                                                                   |
| \[].pubkey            | string                 | The public address of the validator.                                                                  |
| \[].region            | string                 | The region where the validator was created.                                                           |
| \[].startedAt         | string                 | The date the validator was created.                                                                   |
| \[].status            | string                 | The status: `active_online`, `pending` or `unknown` (when there is a failure getting the status).     |
| \[].user              | string                 | The user id.                                                                                          |
| \[].withdrawalAddress | string \| undefined    | The withdrawal address of the validator.                                                              |

#### Sample response

```json
[
  {
    "balance": "32000000000000000000",
    "chain": "mainnet",
    "feeAddress": "0x000000000000000000000000000000000000000",
    "id": "mainnet:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "pubkey": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "region": "us-east-2",
    "startedAt": "2022-11-01T03:56:43.000Z",
    "status": "active",
    "user": "user-00000000-0000-0000-0000-000000000000"
  }
]
```

## GET /staking/ethereum/{chain}/validators/{pubkey}

Returns one validator

### Parameters

| Name          | In     | Type   | Required | Description                 |
| ------------- | ------ | ------ | -------- | --------------------------- |
| chain         | path   | string | yes      | The validator's chain.      |
| pubkey        | path   | string | yes      | The validator's public key. |
| Authorization | header | string | yes      | The authentication token.   |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/ethereum/mainnet/validators/000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The validator was retrieved.        |
| 403    | The authorization token is invalid. |
| 404    | The validator was not found.        |

| Property           | Type                   | Description                                                                                           |
| ------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------- |
| (root)             | object                 | The response.                                                                                         |
| .balance           | string \| null         | The ETH balance, expressed in Wei. Returns `null` if there is a failure while retrieving the balance. |
| .chain             | string                 | The validator chain.                                                                                  |
| .depositData       | object\[] \| undefined | The deposit transaction data.                                                                         |
| .feeAddress        | string \| undefined    | The fee address of the validator.                                                                     |
| .id                | string                 | The validator's id.                                                                                   |
| .pubkey            | string                 | The public address of the validator.                                                                  |
| .region            | string                 | The region where the validator was created.                                                           |
| .startedAt         | string                 | The date the validator was created.                                                                   |
| .status            | string                 | The status: `active_online`, `pending` or `unknown` (when there is a failure getting the status).     |
| .user              | string                 | The user id.                                                                                          |
| .withdrawalAddress | string \| undefined    | The withdrawal address of the validator.                                                              |

#### Sample response

```json
{
  "balance": "32000000000000000000",
  "chain": "mainnet",
  "feeAddress": "0x000000000000000000000000000000000000000",
  "id": "mainnet:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "pubkey": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "region": "us-east-2",
  "startedAt": "2022-11-01T03:56:43.000Z",
  "status": "active",
  "user": "user-00000000-0000-0000-0000-000000000000"
}
```

## PUT /staking/ethereum/{chain}/validators/{pubkey}

Updates the fee address of the validator

### Parameters

| Name          | In     | Type   | Required | Description                 |
| ------------- | ------ | ------ | -------- | --------------------------- |
| feeAddress    | body   | string | yes      | The new fee address.        |
| chain         | path   | string | yes      | The validator's chain.      |
| pubkey        | path   | string | yes      | The validator's public key. |
| Authorization | header | string | yes      | The authentication token.   |

#### Sample request

```shell
curl -X PUT https://api.bloq.com/staking/ethereum/mainnet/validators/000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \
  -H 'Authorization: Bearer <auth-token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "feeAddress": "0x000000000000000000000000000000000000000"
  }'
```

### Response

| Status | Description                             |
| ------ | --------------------------------------- |
| 204    | The update was successful.              |
| 400    | The validator id or chain is incorrect. |
| 403    | The authorization token is invalid.     |
| 404    | The validator does not exist.           |

#### Sample response

Successful response: HTTP 204 No content

## POST /staking/ethereum/{chain}/validators

Create a new Ethereum validator.

To create a mainnet validator using the Ethereum 1.0 withdrawal address, that address shall be supplied. The response will include the data required to create the transaction to deposit the 32 ETH in the Ethereum 2.0 deposit contract.

### Request

| Name               | In     | Type   | Required | Description                              |
| ------------------ | ------ | ------ | -------- | ---------------------------------------- |
| chain              | path   | path   | yes      | The validator chain.                     |
| Authorization      | header | string | yes      | The authentication token.                |
| .feeAddress        | body   | string | no       | The fee address of the validator.        |
| .region            | body   | string | no       | The AWS region. Defaults to us-east-2.   |
| .withdrawalAddress | body   | string | yes (#1) | The withdrawal address of the validator. |

#### Sample request

To use the the Ethereum 1.0 withdrawal address (#1) method:

```shell
curl -X POST https://api.bloq.com/staking/ethereum/mainnet/validators \
  -H 'Authorization: Bearer <auth-token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "withdrawalAddress": "0x000000000000000000000000000000000000000"
  }'
```

### Response

| Status | Description                                             |
| ------ | ------------------------------------------------------- |
| 201    | The validator was created.                              |
| 400    | The validator type, chain or call payload is incorrect. |
| 403    | The authorization token is invalid.                     |
| 409    | Another validator with the same pubkey already exists.  |

| Property           | Type                   | Description                                        |
| ------------------ | ---------------------- | -------------------------------------------------- |
| (root)             | object                 | The validator data.                                |
| .balance           | string \| null         | The ETH balance.                                   |
| .chain             | string                 | The validator chain.                               |
| .depositData       | object\[] \| undefined | The deposit transaction data when using method #1. |
| .feeAddress        | string \| undefined    | The fee address of the validator.                  |
| .pubkey            | string                 | The public address of the validator.               |
| .region            | string                 | The validator region.                              |
| .status            | string                 | The status: deposited, pending, active, exited.    |
| .withdrawalAddress | string \| undefined    | The withdrawal address of the validator.           |

#### Sample response

Successful response:

```json
{
  "balance": "32000000000000000000",
  "chain": "mainnet",
  "pubkey": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "region": "us-east-2",
  "status": "pending",
  "depositData": "0x22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000008000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000008000000000"
}
```

## GET /staking/ethereum/{chain}/validators/{pubkey}/performance

List performance metrics of the validator.

### Parameters

| Name              | In           | Type   | Required | Description                                                         |
| ----------------- | ------------ | ------ | -------- | ------------------------------------------------------------------- |
| chain             | path         | string | yes      | The validators chain.                                               |
| pubkey            | path         | string | yes      | The public address of the validator.                                |
| Authorization     | header       | string | yes      | The authentication token.                                           |
| includeServiceFee | query string | bool   | no       | Whether to include the service fee or not to calculate the metrics. |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/ethereum/mainnet/validators/000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/performance \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The list was retrieved.             |
| 403    | The authorization token is invalid. |
| 404    | The validator was not found.        |

| Property          | Type           | Description                                                                                                                                       |
| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| (root)            | object         | The response.                                                                                                                                     |
| .apr              | number         | The APR of the validator, real or annualized if the validator is less than one year. Formatted in 2 decimals.                                     |
| .balance          | string \| null | The ETH balance, expressed in Wei. Returns `null` if there is a failure while retrieving the balance.                                             |
| .chain            | string         | The validator chain.                                                                                                                              |
| .consensusApr     | number         | The APR of the validator, real or annualized if the validator is less than one year, considering only consensus rewards. Formatted in 2 decimals. |
| .effectiveBalance | string \| null | The APR of the validator, real or annualized if the validator is less than one year, considering only execution rewards. Formatted in 2 decimals  |
| .executionApr     | number         | The APR of the validator, real or annualized if the validator is less than one year. Formatted in 2 decimals.                                     |
| .pubkey           | string         | The public address of the validator.                                                                                                              |

#### Sample response

```json
{
  "apr": 3.42,
  "balance": "32277007585000000000",
  "chain": "mainnet",
  "consensusApr": 3.3,
  "effectiveBalance": "32000000000000000000",
  "executionApr": 0.12,
  "pubkey": "9426757d7db19ce59bd7936bde95a97607199dbb412a5708fdf2f1da029c59d7d72ca1d3c01f05c96f9270df59083bff"
}
```

## POST /staking/ethereum/{chain}/validators/{pubkey}/validatorExit

Initiates the validator exit process to withdraw the staked balance of the validator.\
\
Initiating an exit operation is not a "formal transaction" on the Ethereum network. The exit request is sent via Bloq API (using your Bloq authentication keys), and the exit operation starts immediately.

{% hint style="warning" %}
**NOTE: The API call is not stored and cannot be reversed.**
{% endhint %}

### Parameters

| Name                  | In     | Type   | Required | Description                      |
| --------------------- | ------ | ------ | -------- | -------------------------------- |
| Authorization         | header | string | yes      | The authentication token.        |
| confirmationDate      | body   | string | yes      | The date the message was signed. |
| confirmationSignature | body   | string | yes      | The signature from the user.     |

```shell
curl -X POST https://api.bloq.com/staking/ethereum/mainnet/validators/000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/validatorExit \
  -H "Authorization: Bearer <AUTH_TOKEN>" \
  -H 'Content-Type: application/json' \
  -d '{
        "confirmationDate": "2023-02-01T09:08:07.060Z",
        "confirmationSignature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
      }'
```

### Response

| Status | Description                                                                           |
| ------ | ------------------------------------------------------------------------------------- |
| 204    | The validator exit process was initiated successfully.                                |
| 400    | Failed validator (due to signature, missing balance, process already initiated, etc). |
| 403    | The authorization token is invalid.                                                   |
| 404    | The validator does not exist.                                                         |

#### Sample response

Successful response: HTTP 204 No content

## GET /staking/ethereum/{chain}/stats

Return stats for a specific chain.

### Parameters

| Name              | In           | Type   | Required | Description                                                         |
| ----------------- | ------------ | ------ | -------- | ------------------------------------------------------------------- |
| chain             | path         | string | yes      | The validators chain.                                               |
| Authorization     | header       | string | yes      | The authentication token.                                           |
| includeServiceFee | query string | bool   | no       | Whether to include the service fee or not to calculate the metrics. |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/ethereum/mainnet/stats \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The stats were retrieved.           |
| 403    | The authorization token is invalid. |

| Property      | Type   | Description                                                                      |
| ------------- | ------ | -------------------------------------------------------------------------------- |
| (root)        | object | The response.                                                                    |
| .apr          | string | The APR of the chain. Formatted in 2 decimals                                    |
| .chain        | number | The chain.                                                                       |
| .consensusApr | number | APR of the validator considering only consensus rewards. Formatted in 2 decimals |
| .executionApr | number | APR of the validator considering only execution rewards. Formatted in 2 decimals |

#### Sample response

```json
{
  "apr": 3.42,
  "chain": "mainnet",
  "consensusApr": 3.4,
  "executionApr": 0.02
}
```

## GET staking/ethereum/validators/report

Returns a csv report with all the validators associated to the account.

### Parameters

| Name          | In     | Type   | Required | Description               |
| ------------- | ------ | ------ | -------- | ------------------------- |
| Authorization | header | string | yes      | The authentication token. |

```shell
curl -X GET "https://api.bloq.com/staking/ethereum/validators/report" \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The stats were retrieved.           |
| 403    | The authorization token is invalid. |

The content type of the response is `text/csv`. The headers are:

| Property         | Type   | Description                                                                                                   |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------- |
| account          | string | The address of the user                                                                                       |
| apr              | number | APR of the validator                                                                                          |
| balance          | string | The ETH balance, expressed in Wei.                                                                            |
| chain            | string | The validators chain                                                                                          |
| consensusApr     | number | APR of the validator considering only consensus rewards                                                       |
| effectiveBalance | string | The ETH balance, expressed in Wei, that is used to calculate rewards.                                         |
| executionApr     | number | APR of the validator considering only execution rewards                                                       |
| feeAddress       | string | The fee address of the validator.                                                                             |
| pubkey           | string | The public address of the validator.                                                                          |
| region           | string | The AWS region of the validator                                                                               |
| status           | string | The status: `active_online`, `inactive`, `pending` or `unknown` (when there is a failure getting the status). |

## GET /staking/ethereum/billing/report

Returns billing data for all the validators of the organization, grouped per user, in a date range. Requires the role `auditor` or `billing`.

### Parameters

| Name         | In           | Type   | Required | Description                                                                    |
| ------------ | ------------ | ------ | -------- | ------------------------------------------------------------------------------ |
| accept       | header       | string | no       | The format of the report. Accepts "application/json" (default), "text/csv"     |
| fromDate     | query string | string | yes      | The initial date of the report. This date is included. Format is `yyyy-mm-dd`. |
| organization | query string | string | no       | Organization to filter the validators. Only valid for `billing` users          |
| toDate       | query string | string | yes      | The end date of the report. This date is included. Format is `yyyy-mm-dd`.     |

#### Sample request

```sh
curl -X GET "https://api.bloq.com/staking/ethereum/billing/report?fromDate=0000-00-00&toDate=0000-00-00" \
  -H 'Authorization: Bearer <auth_token>'
```

### Response

| Status | Description                                             |
| ------ | ------------------------------------------------------- |
| 200    | The list was retrieved.                                 |
| 401    | No authentication header found.                         |
| 403    | The authorization token is invalid/Caller is not admin. |

#### If the `accept` header is `application/json`

| Property                                                         | Type      | Description                                                                                               |
| ---------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------- |
| (root)                                                           | array     | The response.                                                                                             |
| \[].organization                                                 | string    | The organization Id where the user belongs to.                                                            |
| \[].organizationName                                             | string    | The organization name.                                                                                    |
| \[].reportFrom                                                   | string    | The initial date of the report .                                                                          |
| \[].reportTo                                                     | string    | The end date of the report.                                                                               |
| \[].user                                                         | string    | The owner the validator.                                                                                  |
| \[].userEmail                                                    | string    | The owner's email.                                                                                        |
| \[].userName                                                     | string    | The owner's display name.                                                                                 |
| \[].validatorsPerChain                                           | object\[] | Validators grouped by chain.                                                                              |
| \[].validatorsPerChain\[].chain                                  | string    | The chain, i.e. "mainnet".                                                                                |
| \[].validatorsPerChain\[].consensusPenalties                     | string    | The consensus penalties of the period in wei.                                                             |
| \[].validatorsPerChain\[].consensusRewards                       | string    | The consensus rewards of the period in wei.                                                               |
| \[].validatorsPerChain\[].executionPenalties                     | string    | The execution penalties of the period in wei.                                                             |
| \[].validatorsPerChain\[].executionRewards                       | string    | The execution rewards of the period in wei.                                                               |
| \[].validatorsPerChain\[].fees                                   | string    | The sum of the fees for the specified period in wei.                                                      |
| \[].validatorsPerChain\[].penalties                              | string    | The sum of all penalties for the specified period in wei.                                                 |
| \[].validatorsPerChain\[].rewards                                | string    | The sum of all rewards for the specified period in wei.                                                   |
| \[].validatorsPerChain\[].rewardsAfterFees                       | string    | The sum of all rewards minus penalties and the fees for the specified period in wei.                      |
| \[].validatorsPerChain\[].totalActiveValidators                  | number    | The count of validators that were staking during the period.                                              |
| \[].validatorsPerChain\[].totalCurrentValidators                 | number    | The count of validators that are currently staking.                                                       |
| \[].validatorsPerChain\[].totalInactiveValidators                | number    | The count of validators that were spun up but not staking during the period.                              |
| \[].validatorsPerChain\[].totalWeightedValidators                | number    | The sum of every day that the validators were staking divided by the number of days in the report period. |
| \[].validatorsPerChain\[].validatorsActive\[]                    | array     | The list of validators that were staking as reported by the Beacon chain.                                 |
| \[].validatorsPerChain\[].validatorsActive\[].activeDays         | number    | Number of days the validator has been staking during the period.                                          |
| \[].validatorsPerChain\[].validatorsActive\[].balance            | string    | The staked balance plus the earned rewards in wei.                                                        |
| \[].validatorsPerChain\[].validatorsActive\[].consensusPenalties | string    | The consensus penalties in wei.                                                                           |
| \[].validatorsPerChain\[].validatorsActive\[].consensusRewards   | string    | The consensus rewards in wei.                                                                             |
| \[].validatorsPerChain\[].validatorsActive\[].createdAt          | string    | The creation date.                                                                                        |
| \[].validatorsPerChain\[].validatorsActive\[].effectiveBalance   | string    | The staked balance in wei.                                                                                |
| \[].validatorsPerChain\[].validatorsActive\[].executionPenalties | string    | The execution penalties in wei.                                                                           |
| \[].validatorsPerChain\[].validatorsActive\[].executionRewards   | string    | The execution rewards in wei.                                                                             |
| \[].validatorsPerChain\[].validatorsActive\[].fees               | string    | The fees in wei.                                                                                          |
| \[].validatorsPerChain\[].validatorsActive\[].penalties          | string    | The penalties in wei.                                                                                     |
| \[].validatorsPerChain\[].validatorsActive\[].pubkey             | string    | The public key.                                                                                           |
| \[].validatorsPerChain\[].validatorsActive\[].rewards            | string    | The rewards in wei.                                                                                       |
| \[].validatorsPerChain\[].validatorsActive\[].rewardsAfterFees   | string    | The rewards subtracted penalties and fees in wei.                                                         |
| \[].validatorsPerChain\[].validatorsActive\[].runningDays        | number    | The number of days that the validator was running to the present day or deletion date.                    |
| \[].validatorsPerChain\[].validatorsActive\[].slashed            | boolean   | The slashing status.                                                                                      |
| \[].validatorsPerChain\[].validatorsInactive\[]                  | array     | The list of validators that were spun up, but not staking as reported by the Beacon chain.                |
| \[].validatorsPerChain\[].validatorsInactive\[].balance          | string    | The staked balance plus the earned rewards in wei.                                                        |
| \[].validatorsPerChain\[].validatorsInactive\[].createdAt        | string    | The creation date.                                                                                        |
| \[].validatorsPerChain\[].validatorsInactive\[].pubkey           | string    | The public key.                                                                                           |
| \[].validatorsPerChain\[].validatorsInactive\[].runningDays      | number    | The number of days that the validator was running to the present day or deletion date.                    |
| \[].validatorsPerChain\[].validatorsInactive\[].slashed          | boolean   | The slashing status.                                                                                      |

#### Sample response

```json
[
  {
    "organization": "org-0000000-0000-0000-0000-000000000000",
    "organizationName": "My organization",
    "reportFrom": "2023-01-17",
    "reportTo": "2023-02-16",
    "user": "user-00000000-0000-0000-0000-000000000000",
    "userEmail": "user@bloq.com",
    "userName": "user name",
    "validatorsPerChain": [
      {
        "chain": "mainnet",
        "consensusPenalties": "0",
        "consensusRewards": "2114557999950000",
        "executionPenalties": "5000",
        "executionRewards": "55000",
        "fees": "169164640000000",
        "penalties": "5000",
        "rewards": "2114558000000000",
        "rewardsAfterFees": "1945393360000000",
        "totalActiveValidators": 1,
        "totalCurrentValidators": 1,
        "totalInactiveValidators": 1,
        "totalWeightedValidators": 1,
        "validatorsActive": [
          {
            "activeDays": 30,
            "balance": "32119059422000000000",
            "consensusPenalties": "0",
            "consensusRewards": "2114557999950000",
            "createdAt": "2022-09-02T00:00:00.000Z",
            "effectiveBalance": "32000000000000000000",
            "executionPenalties": "5000",
            "executionRewards": "55000",
            "fees": "169164640000000",
            "penalties": "5000",
            "pubkey": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
            "rewards": "2114558000000000",
            "rewardsAfterFees": "1945393360000000",
            "runningDays": 125,
            "slashed": false
          }
        ],
        "validatorsInactive": [
          {
            "balance": "1",
            "createdAt": "2022-10-10T00:00:00.000Z",
            "pubkey": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
            "runningDays": 87,
            "slashed": false
          }
        ]
      }
    ]
  }
]
```

#### If the `accept` header is `text/csv`

| Property           | Type    | Description                                                                            |
| ------------------ | ------- | -------------------------------------------------------------------------------------- |
| activeDays         | number  | Number of days the validator has been staking during the period.                       |
| balance            | string  | The staked balance plus the earned rewards in wei.                                     |
| chain              | string  | The chain, i.e. "mainnet".                                                             |
| consensusPenalties | string  | The consensus penalties in wei.                                                        |
| consensusRewards   | string  | The consensus rewards in wei.                                                          |
| createdAt          | string  | The creation date.                                                                     |
| effectiveBalance   | string  | The staked balance in wei.                                                             |
| executionPenalties | string  | The execution penalties in wei.                                                        |
| executionRewards   | string  | The execution rewards in wei.                                                          |
| fees               | string  | The fees in wei.                                                                       |
| organization       | string  | The organization Id where the user belongs to.                                         |
| organizationName   | string  | The organization name.                                                                 |
| penalties          | string  | The penalties in wei.                                                                  |
| pubkey             | string  | The public key.                                                                        |
| reportFrom         | string  | The initial date of the report .                                                       |
| reportTo           | string  | The end date of the report.                                                            |
| rewards            | string  | The rewards in wei.                                                                    |
| rewardsAfterFees   | string  | The rewards subtracted penalties and fees in wei.                                      |
| runningDays        | number  | The number of days that the validator was running to the present day or deletion date. |
| slashed            | boolean | The slashing status.                                                                   |
| user               | string  | The owner the validator.                                                               |
| userEmail          | string  | The owner's email.                                                                     |
| userName           | string  | The owner's display name.                                                              |

#### Sample response

```
activeDays,balance,chain,consensusPenalties,consensusRewards,createdAt,effectiveBalance,executionPenalties,executionRewards,fees,organization,organizationName,penalties,pubkey,reportFrom,reportTo,rewards,rewardsAfterFees,runningDays,slashed,user,userEmail,userName
30,32119059422000000000,mainnet,0,2114557999950000,2022-09-02T00:00:00.000Z,32000000000000000000,5000,55000,169164640000000,org-0000000-0000-0000-0000-000000000000,My organization,5000,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,2023-01-17,2023-02-16,2114558000000000,1945393360000000,125,false,user-00000000-0000-0000-0000-000000000000,user@bloq.com,user name
,1,mainnet,,,2022-10-10T00:00:00.000Z,,,,,org-0000000-0000-0000-0000-000000000000,My organization,,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,2023-01-17,2023-02-16,,,87,false,user-00000000-0000-0000-0000-000000000000,user@bloq.com,user name
```

## Error responses

All error responses are JSON objects that loosely follow the [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) specification.

```json
{
  "status": 403,
  "title": "Forbidden",
  "detail": "The authorization token is expired."
}
```


# Avalanche

Avalanche is an open, programmable smart contracts platform used to launch both private and public blockchains (subnets) for the development of decentralized applications.

While avax.network provides documentation and guides to [add validators](https://docs.avax.network/nodes/validate/what-is-staking), the Bloq platform makes it easy by providing the infrastructure needed and an API to allow users to easily create validators and start staking.

> The minimum amount that a validator must stake is 2,000 AVAX


# Stake AVAX

To become a validator and to start staking on Avalanche requires infrastructure, AVAX, and carefully following some steps

**Requirements**

## 1. Requirements

* **Mainnet:** A minimum of 2,000 AVAX per validator.
  * The minimum amount of time one can stake funds for validation is 2 weeks.
  * The maximum amount of time one can stake funds for validation is 1 year.
  * The maximum weight of a validator (their own stake + stake delegated to them) is the minimum of 3 million AVAX and 5 times the amount the validator staked. For example, if you staked 2,000 AVAX to become a validator, only 8,000 AVAX can be delegated to your node total (not per delegator).
* **Fuji Testnet:** A minimum of 1 AVAX per validator
  * The minimum amount of time one can stake funds for validation is 24 hours

More on the [Avalanche Staking docs](https://docs.avax.network/nodes/validate/staking).

### 1. Authenticate to the Bloq API

To use the Bloq API, visit [authentication.md](https://github.com/bloqpriv/bloq-services-monorepo/blob/gitbook/docs/bloq-services/bloqstake/auth/authentication.md).

### 2. Create a new validator node

Create a validator node by calling the BloqStake API with the authentication token.

```shell
curl -X POST https://api.bloq.com/staking/avalanche/fuji/validators \
  -H 'Authorization: Bearer <auth-token>' \
  -H 'Content-Type: application/json'
```

This `post` call will return a `nodeId` value. Save it and wait a couple of minutes after creating the validator, then run the following command as follows:

```shell
curl -X GET https://api.bloq.com/staking/avalanche/fuji/validators/node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -H 'Authorization: Bearer <auth-token>' \
  -H 'Content-Type: application/json'
```

The response will include the `avalancheNodeId` property of the validator and other status information.\
Take note of this `avalancheNodeId` value, as you'll need it for the next step.

### 3. Register and fund the validator on Avalanche Network

{% hint style="danger" %}
**WARNING:** Note that once you register the validator, there is no way to change the parameters. You can’t remove your stake early or change the stake amount, node ID, or reward address.
{% endhint %}

To register the validator, with the `avalancheNodeId` value taken from the previous step, follow one of these guides:

* [Add a validator with Avalanche Wallet](https://docs.avax.network/nodes/validate/add-a-validator#add-a-validator-with-avalanche-wallet)

As the validator created needs to catch up with the Avalanche chain, after the deposit transaction is confirmed, it may take some time for the Validator to detect the new staking period.


# API Routes

Jump to:

* [DELETE /staking/avalanche/{chain}/validators/{id}](#delete-staking-avalanche-chain-validators-id)
* [GET /staking/avalanche/{chain}/validators](#get-staking-avalanche-chain-validators)
* [GET /staking/avalanche/{chain}/validators/{id}](#get-staking-avalanche-chain-validators-id)
* [GET /staking/avalanche/billing/report](#get-staking-avalanche-billing-report)
* [GET /staking/avalanche/chains](#get-staking-avalanche-chains)
* [POST /staking/avalanche/{chain}/validators](#post-staking-avalanche-chain-validators)
* [Error responses](#error-responses)

## GET /staking/avalanche/chains

Retrieves all the chains that are enabled for the protocol

### Parameters

| Name          | In     | Type   | Required | Description               |
| ------------- | ------ | ------ | -------- | ------------------------- |
| Authorization | header | string | yes      | The authentication token. |

```shell
curl -X GET https://api.bloq.com/staking/avalanche/chains \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The list was retrieved.             |
| 401    | No authentication header found.     |
| 403    | The authorization token is invalid. |

| Property | Type   | Description            |
| -------- | ------ | ---------------------- |
| (root)   | array  | The response.          |
| \[]      | string | The name of the chain. |

#### Sample response

```json
["fuji", "mainnet"]
```

## GET /staking/avalanche/{chain}/validators

List all of the user's Avalanche validators.

### Parameters

| Name          | In     | Type   | Required | Description                                 |
| ------------- | ------ | ------ | -------- | ------------------------------------------- |
| chain         | path   | string | yes      | The validator's chain: "mainnet" or "fuji". |
| Authorization | header | string | yes      | The authentication token.                   |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/avalanche/fuji/validators \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The list was retrieved.             |
| 403    | The authorization token is invalid. |

| Property                              | Type      | Description                                                                   |
| ------------------------------------- | --------- | ----------------------------------------------------------------------------- |
| (root)                                | array     | The validator data.                                                           |
| \[].avalancheNodeId                   | string    | The Avalanche Node ID.                                                        |
| \[].chain                             | string    | The validator chain                                                           |
| \[].createdAt                         | string    | The validator creation date.                                                  |
| \[].id                                | string    | The BloqStake id of the validator.                                            |
| \[].region                            | string    | The validator region.                                                         |
| \[].rewardingStakePercentage          | string    | Percent of stake which thinks this validator is above the uptime requirement. |
| \[].stake                             | string    | The current amount staked during this period.                                 |
| \[].stakingPeriods                    | array     | Array of staking periods of the validator                                     |
| \[].stakingPeriods\[].depositTxId     | string    | Transaction Id of the deposit operation for staking.                          |
| \[].stakingPeriods\[].end             | string    | End date of the staking.                                                      |
| \[].stakingPeriods\[].rewardAddresses | string\[] | Array of reward addresses.                                                    |
| \[].stakingPeriods\[].rewards         | string    | (Optional). Rewards in nAvax.                                                 |
| \[].stakingPeriods\[].stake           | string    | The amount staked in nAvax during this period.                                |
| \[].stakingPeriods\[].start           | string    | Start date of the staking.                                                    |
| \[].updatedAt                         | string    | The validator update date.                                                    |
| \[].user                              | string    | The user Id.                                                                  |
| \[].weightedAveragePercentage         | string    | Stake-weighted average of all observed uptimes for this validator.            |

#### Sample response

```json
[
  {
    "avalancheNodeId": "NodeID-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "chain": "mainnet",
    "createdAt": "2022-08-23T20:21:17.725Z",
    "id": "node-0000000-0000-0000-0000-000000000000",
    "region": "us-east-2",
    "rewardingStakePercentage": "45.1234",
    "stake": "0",
    "stakingPeriods": [
      {
        "depositTxId": "aMQx5eMng21SxwXozxikRcMymmts3cRACJhrAEJeruLJpRzgZ",
        "end": "2022-09-30T20:29:13.000Z",
        "rewardAddresses": ["P-fuji1vy5ttya00gkq5h7hlvt6lkpsee8vur0qkjmgkc"],
        "rewards": "10000000",
        "stake": "3000000000",
        "start": "2022-09-05T20:19:44.000Z"
      }
    ],
    "updatedAt": "2022-08-24T10:04:16.142Z",
    "user": "user-00000000-0000-0000-0000-000000000000",
    "weightedAveragePercentage": "45.1234"
  }
]
```

## POST /staking/avalanche/{chain}/validators

Create a new Avalanche validator.

### Request

| Name          | In     | Type   | Required | Description                                                                                                |
| ------------- | ------ | ------ | -------- | ---------------------------------------------------------------------------------------------------------- |
| Authorization | header | string | yes      | The authentication token.                                                                                  |
| chain         | path   | path   | yes      | The validator chain: "mainnet" or "fuji".                                                                  |
| region        | body   | string | no       | The region where it will be created. "us-east-2" for EC2, or "k8s" for Kubernetes. Defaults to "us-east-2" |

#### Sample request

```shell
curl -X POST https://api.bloq.com/staking/avalanche/mainnet/validators \
  -H 'Authorization: Bearer <auth-token>'
  --data { "region": "us-east-2" }
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The validator was created.          |
| 403    | The authorization token is invalid. |

| Property   | Type   | Description                        |
| ---------- | ------ | ---------------------------------- |
| (root)     | object | The validator data.                |
| .chain     | string | The validator chain                |
| .createdAt | string | The validator creation date.       |
| .id        | string | The BloqStake Id of the validator. |
| .user      | string | The user Id.                       |
| .region    | string | The validator region.              |

#### Sample responses

Successful response:

```json
{
  "chain": "mainnet",
  "createdAt": "2022-08-23T20:21:17.725Z",
  "id": "node-00000000-0000-0000-0000-000000000000",
  "user": "user-00000000-0000-0000-0000-000000000000",
  "region": "us-east-2"
}
```

## GET /staking/avalanche/{chain}/validators/{id}

Returns one Avalanche validator by its BloqStake Id.

### Parameters

| Name          | In     | Type   | Required | Description                                 |
| ------------- | ------ | ------ | -------- | ------------------------------------------- |
| chain         | path   | string | yes      | The validator's chain: "mainnet" or "fuji". |
| id            | path   | string | yes      | The validator's Id.                         |
| Authorization | header | string | yes      | The authentication token.                   |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/avalanche/fuji/validators/node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                         |
| ------ | ----------------------------------- |
| 200    | The validator was retrieved.        |
| 403    | The authorization token is invalid. |
| 404    | The validator was not found.        |

| Property                           | Type      | Description                                                                   |
| ---------------------------------- | --------- | ----------------------------------------------------------------------------- |
| (root)                             | object    | The validator data.                                                           |
| .avalancheNodeId                   | string    | The Avalanche Node ID.                                                        |
| .chain                             | string    | The validator chain                                                           |
| .createdAt                         | string    | The validator creation date.                                                  |
| .id                                | string    | The BloqStake Id of the validator.                                            |
| .region                            | string    | The validator region.                                                         |
| .rewardingStakePercentage          | string    | Percent of stake which thinks this validator is above the uptime requirement. |
| .stake                             | string    | The current amount staked during this period.                                 |
| .stakingPeriods                    | array     | Array of staking periods of the validator                                     |
| .stakingPeriods\[].depositTxId     | string    | Transaction Id of the deposit operation for staking.                          |
| .stakingPeriods\[].end             | string    | End date of the staking.                                                      |
| .stakingPeriods\[].rewardAddresses | string\[] | Array of reward addresses.                                                    |
| .stakingPeriods\[].rewards         | string    | (Optional). Rewards in nAvax.                                                 |
| .stakingPeriods\[].stake           | string    | The amount staked during this period in nAvax.                                |
| .stakingPeriods\[].start           | string    | Start date of the staking.                                                    |
| .updatedAt                         | string    | The validator update date.                                                    |
| .user                              | string    | The user Id.                                                                  |
| .weightedAveragePercentage         | string    | Stake-weighted average of all observed uptimes for this validator.            |

#### Sample response

```json
{
  "avalancheNodeId": "NodeID-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "chain": "mainnet",
  "createdAt": "2022-08-23T20:21:17.725Z",
  "id": "node-0000000-0000-0000-0000-000000000000",
  "region": "us-east-2",
  "rewardingStakePercentage": "45.1234",
  "stake": "0",
  "stakingPeriods": [
    {
      "depositTxId": "aMQx5eMng21SxwXozxikRcMymmts3cRACJhrAEJeruLJpRzgZ",
      "end": "2022-09-30T20:29:13.000Z",
      "rewardAddresses": ["P-fuji1vy5ttya00gkq5h7hlvt6lkpsee8vur0qkjmgkc"],
      "rewards": "10000000",
      "stake": "3000000000",
      "start": "2022-09-05T20:19:44.000Z"
    }
  ],
  "updatedAt": "2022-08-24T10:04:16.142Z",
  "user": "user-00000000-0000-0000-0000-000000000000",
  "weightedAveragePercentage": "45.1234"
}
```

## GET /staking/avalanche/billing/report

Returns a billing report of the organization's validators for the period specified, grouped by user. Requires the role `auditor` or `billing`.

### Parameters

| Name         | In           | Type   | Required | Description                                                                |
| ------------ | ------------ | ------ | -------- | -------------------------------------------------------------------------- |
| accept       | header       | string | no       | The format of the report. Accepts "application/json" (default), "text/csv" |
| fromDate     | query string | string | no       | Report's starting date                                                     |
| organization | query string | string | no       | Organization to filter the validators. Only valid for `billing` users      |
| toDate       | query string | string | no       | Report's end date                                                          |

#### Sample request

```shell
curl -X GET https://api.bloq.com/staking/avalanche/billing/report/user?fromDate=2023-01-15&toDate=2023-02-25 \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                                                         |
| ------ | ------------------------------------------------------------------- |
| 200    | The report was retrieved.                                           |
| 403    | The authorization token is invalid or the user has no auditor role. |

#### If the `accept` header is `application/json`

| Property                                                        | Type           | Description                                                                                                    |
| --------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------- |
| (root)                                                          | object         | The report data.                                                                                               |
| \[].organization                                                | string         | The organization Id where the user belongs to.                                                                 |
| \[].organizationName                                            | string         | The organization name the validator belongs to.                                                                |
| \[].reportFrom                                                  | string         | Report's starting date.                                                                                        |
| \[].reportTo                                                    | string         | Report's end date.                                                                                             |
| \[].user                                                        | string         | User Id.                                                                                                       |
| \[].userEmail                                                   | string         | The user email.                                                                                                |
| \[].userName                                                    | string         | The user name.                                                                                                 |
| \[].validatorsPerChain                                          | object\[]      | Validators grouped by chain.                                                                                   |
| \[].validatorsPerChain\[].chain                                 | string         | The chain, i.e. "mainnet" or "fuji".                                                                           |
| \[].validatorsPerChain\[].fees                                  | string         | Amount of fees to deduce for the user.                                                                         |
| \[].validatorsPerChain\[].rewards                               | string         | Amount of rewards in nAvax earned by the user during the period of the report.                                 |
| \[].validatorsPerChain\[].rewardsAfterFees                      | string         | Rewards minus fees for the user.                                                                               |
| \[].validatorsPerChain\[].staked                                | string         | Amount that is being staked in nAvax at the end of the report for all validators.                              |
| \[].validatorsPerChain\[].totalActiveValidators                 | number         | Amount of validators that staked during the report period.                                                     |
| \[].validatorsPerChain\[].totalCurrentValidators                | number         | Amount of validators that are currently staking.                                                               |
| \[].validatorsPerChain\[].totalInactiveValidators               | number         | Amount of validators that did not stake during the report period.                                              |
| \[].validatorsPerChain\[].totalWeightedValidators               | string         | Sum of every day that the validator was staking during the period divided by the number of days of the period. |
| \[].validatorsPerChain\[].validatorsActive                      | object\[]      | Array of validators that staked during the report's period.                                                    |
| \[].validatorsPerChain\[].validatorsActive\[].activeDays        | number         | Number of days the validator has been staking during the period.                                               |
| \[].validatorsPerChain\[].validatorsActive\[].avalancheNodeId   | string         | Avalanche Id from the network of validators.                                                                   |
| \[].validatorsPerChain\[].validatorsActive\[].createdAt         | string         | Validator's creation date.                                                                                     |
| \[].validatorsPerChain\[].validatorsActive\[].fees              | string         | Amount of fees to deduce for the validator.                                                                    |
| \[].validatorsPerChain\[].validatorsActive\[].rewards           | string         | Amount of rewards earned by the validator during the period of the report.                                     |
| \[].validatorsPerChain\[].validatorsActive\[].rewardsAfterFees  | string         | Validator's rewards minus fees.                                                                                |
| \[].validatorsPerChain\[].validatorsActive\[].runningDays       | string         | Number of days the validator's been running since its creation until the present day or its deletion.          |
| \[].validatorsPerChain\[].validatorsActive\[].staked            | string         | Amount that is being staked in nAvax at the end of the report.                                                 |
| \[].validatorsPerChain\[].validatorsInactive                    | object \[]     | Array of validators that did not stake during the report's period.                                             |
| \[].validatorsPerChain\[].validatorsInactive\[].avalancheNodeId | string         | Avalanche Id from the network of validators.                                                                   |
| \[].validatorsPerChain\[].validatorsInactive\[].createdAt       | string         | Validator's creation date.                                                                                     |
| \[].validatorsPerChain\[].validatorsInactive\[].deletedAt       | string \| null | Validator's deletion date.                                                                                     |
| \[].validatorsPerChain\[].validatorsInactive\[].runningDays     | string         | Number of days the validator's been running since its creation until the present day or its deletion.          |

#### Sample response

```json
[
  {
    "organization": "org-00000000-0000-5000-b000-000000000000",
    "organizationName": "Org test",
    "reportFrom": "2023-01-27",
    "reportTo": "2023-02-25",
    "user": "user-00000000-0000-4000-00000000000000000",
    "userEmail": "test@bloq.com",
    "userName": "Test user",
    "validatorsPerChain": [
      {
        "chain": "mainnet",
        "fees": "28703148",
        "rewards": "717578700",
        "rewardsAfterFees": "688875552",
        "staked": "2000000000",
        "totalActiveValidators": 1,
        "totalCurrentValidators": 0,
        "totalInactiveValidators": 0,
        "totalWeightedValidators": 0.6,
        "validatorsActive": [
          {
            "activeDays": 15,
            "avalancheNodeId": "NodeID-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "createdAt": "2022-12-29T18:07:27.364Z",
            "fees": "28703148",
            "rewards": "717578700",
            "rewardsAfterFees": "688875552",
            "runningDays": 60,
            "staked": "2000000000"
          }
        ],
        "validatorsInactive": []
      },
      {
        "chain": "fuji",
        "fees": "0",
        "rewards": "23331848",
        "rewardsAfterFees": "23331848",
        "staked": "2500000000",
        "totalActiveValidators": 1,
        "totalCurrentValidators": 1,
        "totalInactiveValidators": 1,
        "totalWeightedValidators": 0.5,
        "validatorsActive": [
          {
            "activeDays": 14,
            "avalancheNodeId": "NodeID-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
            "createdAt": "2023-01-04T20:59:35.909Z",
            "fees": "0",
            "rewards": "23331848",
            "rewardsAfterFees": "23331848",
            "runningDays": 54,
            "staked": "2500000000"
          }
        ],
        "validatorsInactive": [
          {
            "avalancheNodeId": "NodeID-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
            "createdAt": "2023-01-04T20:59:35.909Z",
            "runningDays": 54
          }
        ]
      }
    ]
  }
]
```

#### If the `accept` header is `text/csv`

| Property         | Type           | Description                                                                                           |
| ---------------- | -------------- | ----------------------------------------------------------------------------------------------------- |
| activeDays       | number         | Number of days the validator has been staking during the period.                                      |
| avalancheNodeId  | string         | Avalanche Id from the network of validators.                                                          |
| chain            | string         | The chain, i.e. "mainnet" or "fuji".                                                                  |
| createdAt        | string         | Validator's creation date.                                                                            |
| deletedAt        | string \| null | Validator's deletion date.                                                                            |
| fees             | string         | Amount of fees to deduce for the validator.                                                           |
| organization     | string         | The organization Id where the user belongs to.                                                        |
| organizationName | string         | The organization name the validator belongs to.                                                       |
| reportFrom       | string         | Report's starting date.                                                                               |
| reportTo         | string         | Report's end date.                                                                                    |
| rewards          | string         | Amount of rewards earned by the validator during the period of the report.                            |
| rewardsAfterFees | string         | Validator's rewards minus fees.                                                                       |
| runningDays      | string         | Number of days the validator's been running since its creation until the present day or its deletion. |
| staked           | string         | Amount that is being staked in nAvax at the end of the report.                                        |
| user             | string         | User Id.                                                                                              |
| userEmail        | string         | The user email.                                                                                       |
| userName         | string         | The user name.                                                                                        |

#### Sample response

```
activeDays,avalancheNodeId,chain,createdAt,deletedAt,fees,organization,organizationName,reportFrom,reportTo,rewards,rewardsAfterFees,runningDays,staked,user,userEmail,userName
15,NodeID-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,mainnet,2022-12-29T18:07:27.364Z,,28703148,org-00000000-0000-5000-b000-000000000000,Org test,2023-01-27,2023-02-25,717578700,688875552,60,2000000000,user-00000000-0000-4000-00000000000000000,test@bloq.com,Test user
14,NodeID-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,fuji,2023-01-04T20:59:35.909Z,,0,org-00000000-0000-5000-b000-000000000000,Org test,2023-01-27,2023-02-25,23331848,23331848,54,2500000000,user-00000000-0000-4000-00000000000000000,test@bloq.com,Test user
,NodeID-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz,fuji,2023-01-04T20:59:35.909Z,,0,org-00000000-0000-5000-b000-000000000000,Org test,2023-01-27,2023-02-25,,,54,,user-00000000-0000-4000-00000000000000000,test@bloq.com,Test user
```

## DELETE /staking/avalanche/{chain}/validators/{id}

Terminates a validator.

### Parameters

| Name          | In     | Type   | Required | Description                                 |
| ------------- | ------ | ------ | -------- | ------------------------------------------- |
| chain         | path   | string | yes      | The validator's chain: "mainnet" or "fuji". |
| id            | path   | string | yes      | The validator's Id.                         |
| Authorization | header | string | yes      | The authentication token.                   |

#### Sample request

```shell
curl -X DELETE https://api.bloq.com/staking/avalanche/fuji/validators/node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -H 'Authorization: Bearer <auth-token>'
```

### Response

| Status | Description                                               |
| ------ | --------------------------------------------------------- |
| 204    | The validator was deleted.                                |
| 403    | The authorization token is invalid.                       |
| 404    | The validator was not found.                              |
| 409    | The validator is actively staking, and cannot be deleted. |

## Error responses

All error responses are JSON objects that loosely follow the [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) specification.

```json
{
  "status": 403,
  "title": "Forbidden",
  "detail": "The authorization token is expired."
}
```


# Developers Guide


# Client Tokens

Client Tokens are JWT (JSON Web Tokens) that grant access to Bloq services, such as Nodes. There are two types of Client Tokens: `Client Access Tokens` and `Client Refresh Tokens`. These tokens are necessary for accounts but are not useful to interact with accounts endpoints. For more information about Bloq authentication, please check the [Technical Reference](/advanced-documentation/technical-reference/accounts-api).

{% hint style="success" %}
**TIP**

Client tokens do not grant permissions for Accounts services. This makes the `Client Access Token` especially useful for sharing access to Nodes service with other users or applications, as the sensitive account billing and location information remain out-of-reach.
{% endhint %}

## Generate Client Tokens

Before you can generate Client Tokens, you first need to [setup your Bloq account](/readme/bloq-account-setup) and [generate a pair of client keys](/readme/create-client-keys). If you have not done so, please refer to the corresponding guides.

There are two ways to use the generate Client Tokens: using the [Command Line Interface (CLI)](/advanced-documentation/technical-reference/cli) or using the [Accounts REST API](/advanced-documentation/technical-reference/accounts-api).

### Using the CLI

The CLI is a friendly tool and the easiest way to interact with Bloq services.

Open a terminal window and start you session by running `bcl login`.

The CLI has the `client-keys` command which enables you to generate a `Client Access Token`and a `Client Refresh Token`.

```shell
bcl client-token
```

```
? Do you want bcl to store your tokens locally for future usage? Yes
✔ Generated new tokens:
  * clientAccessToken: xxxxxx.xxxxxxxxxx.xxxxxx
  * refreshToken: xxxxxx.xxxxxxxxxx.xxxxxx

WARN  Be sure to copy and save these keys since it will not be possible to obtain them again.
```

### Using the REST API

Creating Client Tokens using the REST API requires more steps than the CLI (which automates the whole authentication process).

As previously stated, a valid pair of client keys is required prior to using the service. The client keys let you generate your Client Access and Client Refresh tokens. The `Client Acccess Token` grants you access to the BloqNodes services, but for security reasons, the `Client Acccess Token` is a short term token (expires after one hour). When the token expires, you can use the `Client Refresh Token` (expires after one year but could be revoked) to get a new valid `Client Acccess Token`.

It is important to specify `grantType` as part of body request becuase this endpoint could also be used to refresh tokens. In this case the `grantType` value should be `clientCredentials`

### **Code Sample**

```shell
curl -X POST https://accounts.bloq.cloud/auth/token
  -H 'Content-Type: application/json' \
  -d '{
  "grantType": "clientCredentials",
  "clientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "clientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}'
```

### **Response**

```json
{
  "accessToken": "xxxxxx.xxxxxxxxxx.xxxxxx",
  "refreshToken": "xxxxxx.xxxxxxxxxx.xxxxxx"
}
```

## Refreshing the Client Access Token

Since the `Client Access Token` is a short term JWT (JSON Web Token), when it expires, you have two alternatives: generate a new `Client Access Token` using your `client-keys` or generate a new access token using the `Client Refresh Token`. This latter process is what we refer to as a *token refresh*.

{% hint style="success" %}
**TIP**

If you are using Bloq services through the [CLI](/advanced-documentation/technical-reference/cli) or [JavaScript SDK](/advanced-documentation/technical-reference/javascript-sdk) you don't need to refresh tokens manually because they will do it for you in background. This process will be needed if you are using Bloq services through the REST API.\\
{% endhint %}

To renew your `Client Access Token`, you simply need to call the **Accounts REST API**, `/auth/token` endpoint passing `refreshToken` and setting the corresponding `grantType` as part of your body request. In this case the `grantType` value should be `refreshToken`.

### **Code Sample**

```shell
curl -X POST https://accounts.bloq.cloud/auth/token
  -H 'Content-Type: application/json' \
  -d '{
  "grantType": "refreshToken",
  "refreshToken": "xxxxxx.xxxxxxxxxx.xxxxxx",
}'
```

### **Response**

```json
{
  "accessToken": "xxxxxx.xxxxxxxxxx.xxxxxx"
}
```


# BloqNodes Setup

Nodes is one of the core services of Bloq. In this tutorial you will learn how to set up and start using a Bloq node on your network of choice.

Before you can create a new node, you first need to [set up your Bloq account](/readme/bloq-account-setup). If you have not done so, please refer to the corresponding guide.

**In order to create a new node you must always use** [**Bloq Console**](https://console.bloq.cloud/). We also provide the [Command Line Interface (CLI)](/advanced-documentation/technical-reference/cli) and the [REST API](/advanced-documentation/technical-reference/nodes-api) where you can perform some other actions like retrieve node info or stop a running node.

## Use the [Bloq Console](https://console.bloq.cloud/nodes/single/new) to Create a New Node

Log into [Bloq Console](https://console.bloq.cloud/nodes/single/new) to spin up a new node. You can pick among different chains and networks and you can customize the performance, the region, and the authentication type.

Once you finish with the configuration, choose the billing plan that fits best and select your payment method.

After your payment is confirmed, you will see your new node in the [Nodes View](https://console.bloq.cloud/nodes/single) and you will be able to access it.

## Use the CLI to check your node info <a href="#use-the-cli-to-check-your-node-info" id="use-the-cli-to-check-your-node-info"></a>

Open the terminal and make sure that you have a valid session. If not, you can start one running `bcl login`.

The CLI has the `nodes` command which lets you list, remove or get info about your nodes. You can run `bcl nodes info` to retrieve your node information:

```shell
bcl nodes info -i node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

```
✔ Retrieved node with id node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
   * ID:    node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
   * Started At:  2019-08-01T21:55:46.612Z
   * Stopped At:  N/A
   * Chain:    btc
   * Network:    mainnet
   * Version:    core-0.17
   * Performance:  standard
   * State:    started
   * IP:    3.215.178.169
   * User:    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   * Password:    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

## Use the REST API to check your node info <a href="#use-the-rest-api-to-check-your-node-info" id="use-the-rest-api-to-check-your-node-info"></a>

Retrieving the node information using the REST API requires more steps than the CLI (which automates the whole authentication process). Aside from authentication, the CLI provides the same capabilities as the REST API.

As previously stated, a valid pair of client keys is required prior to using the service. The client keys let you generate your access and refresh tokens. The `access token` grants you access to the **Nodes Service**, but for security reasons, the `access token` is a short term token (expires after one hour). When the `access token` expires, you can use the `refresh token` (expires after one year but could be revoked) to get a new valid `access token`.

### Generate the `access` and `refresh` tokens. <a href="#generate-the-access-and-refresh-tokens" id="generate-the-access-and-refresh-tokens"></a>

The first step is to use the client keys to generate access and refresh tokens. In this step you will request access directly to our **Accounts Service**.

#### Code Sample

```shell
curl -X POST https://accounts.bloq.cloud/auth/token
  -H 'Content-Type: application/json' \
  -d '{
  "grantType": "clientCredentials",
  "clientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "clientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}'
```

#### Response

```json
{
  "accessToken": "xxxxxx.xxxxxxxxxx.xxxxxx",
  "refreshToken": "xxxxxx.xxxxxxxxxx.xxxxxx"
}
```

*To check how to renew your access token check* [*this*](/advanced-documentation/developers-guide/client-tokens#refreshing-the-client-access-token) *section*

### Check Node Info and `PublicIpAddress` <a href="#check-node-info-and-publicipaddress" id="check-node-info-and-publicipaddress"></a>

#### Code Sample

```shell
curl -X GET \ https://nodes.bloq.cloud/users/me/nodes/node-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -H 'Authorization: Bearer xxxxxx.xxxxxxxxxx.xxxxxx'
```

#### Response

```json
{
  "stoppedAt": "2020-04-21T05:00:18.586Z",
  "serviceData": {
    "amiPrefix": "btc",
    "performance": "standard",
    "software": "core-0.17",
    "ports": [8080, 8332]
  },
  "ip": "18.213.193.254",
  "createdAt": "2020-04-21T00:45:07.687Z",
  "ttl": "1588050018",
  "user": "user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "userPlanData": {
    "startsAt": "2020-04-21T00:45:05.324Z",
    "id": "user-plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "plan": "plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "expiresAt": "2020-05-21T00:45:05.324Z"
  },
  "instance": {
    "region": "us-east-1",
    "id": "i-02cb186c0808950f6",
    "imageId": "ami-01ee6543215d4006b"
  },
  "vendor": {
    "name": "aws",
    "subnet": "subnet-41daba24",
    "securityGroups": [
      "sg-50d39921",
      "sg-0a52e56ee0c02fd7a",
      "sg-784d5703",
      "sg-0769b9650222e64ce"
    ],
    "region": "us-east-1",
    "instanceType": "t3.large",
    "quickSync": true
  },
  "network": "mainnet",
  "state": "stopped",
  "service": "service-f409a426-8bdd-5c65-bcd3-7c6d0424a5ac",
  "auth": {
    "type": "basic",
    "user": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "pass": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "updatedAt": "2020-04-21T00:45:09.419Z",
  "chain": "btc",
  "id": "node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

{% hint style="success" %}
**TIP**

* **IP** is the URL that you are going to use to connect and access your node.
* At the moment, the supported chains are **btc**, **btctestnet**, **bch**, **bchtestnet**, **ltc**, **eth**, and **ethropsten**.
  {% endhint %}

### Accessing your Node <a href="#accesing-your-node" id="accesing-your-node"></a>

In addition to the Bloq Console, CLI, and REST API, nodes may also be accessed via interfaces supported by their chain. These include REST, JSON RPC, and WebSocket RPC. Please see the [Blockchain Node API](/advanced-documentation/technical-reference/blockchain-node-api) section for more information.

### Accessing your BTC / BCH / LTC Node <a href="#accessing-your-btc-bch-ltc-node" id="accessing-your-btc-bch-ltc-node"></a>

Mainnet and testnet Bloq nodes on Bitcoin, Bitcoin Cash, and Litecoin (mainnet only) are all accessible through REST and JSON RPC interfaces. To access your node, you must use the proper `IP` port corresponding to the node's chain:

| Protocol           | Chain   | Port  |
| ------------------ | ------- | ----- |
| Bitcoin (BTC)      | Mainnet | 8332  |
| Bitcoin            | Testnet | 18332 |
| Bitcoin Cash (BCH) | Mainnet | 8332  |
| Bitcoin Cash       | Testnet | 18332 |
| Litecoin (LTC)     | Mainnet | 9332  |

#### REST Code Sample

```shell
curl -k -X GET \
  --user <NodeUser>:<NodePass> \
  https://<ip-address>:8332/rest/chaininfo.json
```

#### JSON RPC Code Sample

```shell
curl -k -X POST \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": [] }' \
  https://<ip-address>:8332/
```

#### Response

```json
{
  "chain": "main",
  "blocks": 567245,
  "headers": 567245,
  "bestblockhash": "0000000000000000002a127c4e914d03cac111ec2921018eb05b7e4e5516edc3",
  "difficulty": 6068891541676.553,
  "mediantime": 1552684564,
  "verificationprogress": 0.9999988860202572,
  "initialblockdownload": false,
  "chainwork": "000000000000000000000000000000000000000005712777e7fc462e2363baa4",
  "size_on_disk": 237377254316,
  "pruned": false,
  "softforks": [
    {
      "id": "bip34",
      "version": 2,
      "reject": {
        "status": true
      }
    },
    {
      "id": "bip66",
      "version": 3,
      "reject": {
        "status": true
      }
    },
    {
      "id": "bip65",
      "version": 4,
      "reject": {
        "status": true
      }
    }
  ],
  "bip9_softforks": {
    "csv": {
      "status": "active",
      "startTime": 1462060800,
      "timeout": 1493596800,
      "since": 419328
    },
    "segwit": {
      "status": "active",
      "startTime": 1479168000,
      "timeout": 1510704000,
      "since": 481824
    }
  },
  "warnings": ""
}
```

### Accessing Your ETH <a href="#accessing-your-eth" id="accessing-your-eth"></a>

Mainnet and Ropsten testnet Ethereum nodes are accessible through JSON and WebSocket RPC interfaces. ETH nodes do not support REST interface. To access your node, you must use the proper `IP` port corresponding to the node's chain. There is a different port required for `JSON RPC` and `WebSocket RPC` commands:

| Protocol           | Chain   | Port | Interface |
| ------------------ | ------- | ---- | --------- |
| Ethereum (ETH)     | Mainnet | 8545 | JSON      |
| Ethereum (Ropsten) | Testnet | 8545 | JSON      |
| Ethereum (ETH)     | Mainnet | 8546 | WebSocket |
| Ethereum (Ropsten) | Testnet | 8546 | WebSocket |

#### JSON RPC Code Sample

```shell
curl -X POST \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  -d '{ "jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1 }' \
  https://<ip-address>:8545/
```

#### Response

```json
{
  "jsonrpc": "2.0",
  "result": "0x981fb8",
  "id": 1
}
```

### Accessing Your Avalanche Node <a href="#accessing-your-avalanche-node" id="accessing-your-avalanche-node"></a>

Mainnet and testnet nodes are accessible through a JSON RPC interface. Avalanche nodes listen on the following ports:

| Protocol         | Chain   | Port       |
| ---------------- | ------- | ---------- |
| Avalanche (AVAX) | Mainnet | 9650, 8080 |
| Avalanche        | Testnet | 9650, 8080 |

#### JSON RPC Code Sample

```shell
curl -X POST \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  -d '{ "jsonrpc": "2.0", "method": "health.getLiveness", "params": [], "id": 1 }' \
  https://<ip-address>:9650/ext/health
```

#### Response

```json
{
  "jsonrpc": "2.0",
  "result": {
    "checks": {
      "chains.default.bootstrapped": {
        "timestamp": "2020-09-17T21:27:31.776773-07:00",
        "duration": 5891,
        "contiguousFailures": 0,
        "timeOfFirstFailure": null
      },
      "network.validators.heartbeat": {
        "message": {
          "heartbeat": 1600403244
        },
        "timestamp": "2020-09-17T21:27:31.776793-07:00",
        "duration": 4000,
        "contiguousFailures": 0,
        "timeOfFirstFailure": null
      }
    },
    "healthy": true
  },
  "id": 1
}
```

{% hint style="success" %}
**TIP**

* Your `NodeUser` and `NodePassword` are hexadecimal strings that are accessible through CLI or REST commands above, as well as through the Console website.
* This username/password pair is unique for each node, and separate from your Bloq username and password.
  {% endhint %}

You now have everything you need to create and request data from your nodes. For more information, please refer to the [Nodes Service Technical Reference](/advanced-documentation/technical-reference/nodes-api).


# Authentication

All Bloq services require authentication

To authorize the requests, a bearer JSON Web Token must be sent in the Authorization header.

Example:

```shell
curl -X GET \
  https://api.bloq.cloud/nodes/v1/status \
  -H 'Authorization: Bearer xxxxxx.xxxxxxxxxx.xxxxxx'
```

{% hint style="success" %}
**TIP**

Bloq provides libraries to interact with its services making authentication easier. If you use the [CLI](/advanced-documentation/technical-reference/cli) or [Javascript SDK](/advanced-documentation/technical-reference/javascript-sdk), some of these steps will not be required.
{% endhint %}

## Requirements

In order to authenticate to Bloq services, you must have a Bloq account. To create an account, follow [these instructions](/readme/bloq-account-setup).

## Reference

This reference section for the Authentication API outlines key concepts when authenticating to use Bloq services. Key concepts and details of `Client-Keys` and the various types of `Tokens` are described in this section.

### Tokens

Bloq uses different tokens across its services. Here are the types and usages of these tokens:

#### **Account Access Token:**

The `Account Access Token` is a JSON Web Token created by the Accounts service that enables the user to interact with account related services such as: retrieve profile information, update password, create client IDs and secrets. This token can also be used to interact with the BloqNodes services. The `Account Access Token` expires after 12 hours.

#### **Client Access Token:**

The `Client Access Token` is a JSON Web Token created by the Accounts service that enables the user to interact with [Nodes](/advanced-documentation/technical-reference/nodes-api) services. This is a short-lived token that expires after 1 hour.

To create a Client Access Token follow [these instructions](/advanced-documentation/developers-guide/client-tokens).

#### **Client Refresh Token:**

The `Client Refresh Token` is a JSON Web Token created by the Accounts service that enables the user to create a new `Client Access Token`. This is a long-lived token, and expires after 1 year. Store this token carefully.

To create a Client Refresh Token follow [these instructions](/advanced-documentation/developers-guide/client-tokens#refreshing-the-client-access-token).

### Client Keys

#### Overview

Client keys are pairs (Client ID + Client Secret) composed of random hexadecimal numbers which enables your code / program to authenticate with our servers and grants access to various Bloq services.

{% hint style="success" %}
**TIP**

Client keys are sensitive information. You should avoid sharing or exposing them. Always keep them safe.
{% endhint %}

{% hint style="danger" %}
**WARNING**

Once you generate a client key pair, you will not be able to retrieve the **Client Secret** from Bloq services again. Bloq is unable to help you recover this key.
{% endhint %}

Client keys are used by programs to create `Client Access Tokens` and `Client Refresh Tokens`

#### **Create Client Keys**

To create a client key pair follow [these instructions](/readme/create-client-keys).

## Usage

The type of token/authentication that should be used will depend on the Bloq service. This usage section outlines the type of tokens/authentication required per Bloq service.

### Accounts

To interact with accounts, the user needs an `Account Access Token`. There are two ways of creating this token:

#### **Using the CLI**

The Bloq CLI provides this functionality out of the box using the `bcl login` command. The `Account Access Token` may additionally be retrieved with the `bcl conf accessToken` command.

#### **Using Accounts HTTP REST API**

Using HTTP Basic Authentication by providing username (User ID or email) and password, this endpoint retrieves an authentication token to be passed to other Accounts API functions for authentication.

#### **Code sample**

```shell
curl -u username:password -X POST https://api.bloq.com/auth/login
```

### Nodes

To interact with the Nodes service, the user may use their `Account Access Token` or a `Client Access Token`. To create a `Client Access Token`, a `Client Key Pair` (Client ID + Client Secret) is required.

{% hint style="warning" %}
**WARNING**

The `Account Access Token` and `Client Access Token` are not interchangeable. In other words, a `Client Access Token` cannot be used for Accounts services.
{% endhint %}


# Technical Reference


# CLI

Access to the Bloq CLI is through bcl.

*Jump to:*

* [Client Keys](#client-keys)
* [Client Token](#client-token)
* [Clusters](#clusters)
* [Conf](#conf)
* [Events](#events)
* [Help](#help)
* [Login](#login)
* [Logout](#logout)
* [Nodes](#nodes)
* [Profile](#profile)
* [Status](#status)
* [Update-Password](#update-password)

Usage: `bcl <COMMAND>`

The following commands are available:

| Command           | Description                                     |
| ----------------- | ----------------------------------------------- |
| `client-keys`     | Manage Bloq client key(s)                       |
| `client-token`    | Generate new client token(s)                    |
| `clusters`        | Manage Bloq node clusters                       |
| `conf`            | Manage configuration                            |
| `events`          | Get Bloq Events                                 |
| `help`            | Display help for `bcl`                          |
| `login`           | Login to Bloq account                           |
| `logout`          | Clear local user data                           |
| `nodes`           | Manage Bloq nodes                               |
| `profile`         | Retrieve user profile                           |
| `signup`          | Setup a new Bloq account                        |
| `status`          | Get Bloq services status                        |
| `update-password` | Update user password                            |
| `verify`          | Verify Bloq account and complete signup process |

### Client Keys <a href="#client-keys" id="client-keys"></a>

Client Keys are required to access Bloq services and generate Access and Refresh tokens.

The following operations are supported within `bcl client-keys <OPERATION>`

| Operation      | Description             |
| -------------- | ----------------------- |
| create         | Create a new client-key |
| list (default) | Get list of client-keys |
| remove         | Remove a client-key     |

#### Create Client Keys <a href="#create-client-keys" id="create-client-keys"></a>

The `bcl client-keys create` operation enables users to create a *Client Key ID* and *Client Key Secret* pair.

A user must create a client-key in order to use Bloq services.

{% hint style="warning" %}
**WARNING**

Make sure to save your *Client Key Secret* in a secure location. Secrets are not viewable in the future. Upon *Client Key Secret* generation, the secret is automatically copied to the clipboard for easy storage.
{% endhint %}

#### List Client Keys <a href="#list-client-keys" id="list-client-keys"></a>

The `bcl client-keys list` operation enables users to list existing keys by *Client Key ID*. *Client Key Secret* are not viewable.

#### Remove Client Keys <a href="#remove-client-keys" id="remove-client-keys"></a>

The `bcl client-keys remove` operation enables users to remove a *Client Key ID* and *Client Key Secret* pair.

### Client Token <a href="#client-token" id="client-token"></a>

The `bcl client-token` command creates a *clientAccessToken* and *refreshToken* for use with Bloq services.

{% hint style="success" %}
**TIP**

A client-key pair must be created prior to creating a *clientAccessToken* or *refreshToken*. Use the `bcl client-keys` command if `client-keys` do not currently exist.
{% endhint %}

A *clientAccessToken* is a short-lived (1 hr) token that is required by applications to access Bloq services (Nodes, etc).

A *refreshToken* is a longer term (1 year) token that enables your application to request a new *clientAccessToken* to the authentication server. When the *clientAccessToken* expires, the *refreshToken* will let you obtain a new *clientAccessToken*. The *refreshToken* is renewed every time a new *clientAccessToken* is requested.

{% hint style="warning" %}
**WARNING**

Make sure to save your *clientAccessToken* and *refreshToken* in a secure location. Upon token generation, the they will no longer be possible to access again.
{% endhint %}

### Clusters <a href="#clusters" id="clusters"></a>

The `bcl clusters <METHOD> <OPTIONAL FLAGS>` command enables the user to interact with and manage their registered Bloq clusters. The `<METHOD>` is the clusters method that can be invoked.

Valid `<METHOD>` options are:

* chains
* info
* list
* remove
* services

#### Optional Flags <a href="#optional-flags" id="optional-flags"></a>

The following are the list of optional flags for the `bcl clusters` command:

| Optional Flag   | Description                                                                                 |
| --------------- | ------------------------------------------------------------------------------------------- |
| -a, --all       | List all clusters                                                                           |
| -c, --capacity  | Specify the node capacity for the cluster (default: 2)                                      |
| -i, --clusterId | Specify the cluster to interact with                                                        |
| -s, --serviceId | Specify a specific clusters service                                                         |
| -t, --authType  | Speciy the authentication type for clusters (default: basic) Options include `basic`, `jwt` |

{% hint style="success" %}
**TIP**

`bcl clusters` methods do not require any additional flags. If more input is required, the client will prompt you for that information upon command execution.
{% endhint %}

### Conf <a href="#conf" id="conf"></a>

#### Set Client Keys <a href="#set-client-keys" id="set-client-keys"></a>

In order to reload your previous Client Keys to the CLI, use the following commands:

`bcl conf --key clientId --value <Previous_clientId>`

`bcl conf --key clientSecret --value <Previous_clientSecret>`

#### Retrieve Account Access Token <a href="#retrieve-account-access-token" id="retrieve-account-access-token"></a>

To retrieve the `Account Access Token` that is generated upon `bcl login`, use the following command:

`bcl conf accessToken`

### Events <a href="#events" id="events"></a>

The `bcl events` command provides a history of the most recent events.

Use the `-s=<service>` flag to filter events by services.

Valid options for `<service>` are:

* accounts
* nodes

### Help <a href="#help" id="help"></a>

The `bcl help` command provides the help screen.

### Login <a href="#login" id="login"></a>

The `bcl login -u <Account ID>` command authenticates and logs the user into the CLI.

The *Account ID* is contained within the user signup confirmation email.

### Logout <a href="#logout" id="logout"></a>

The `bcl logout` command logs the user out of the CLI and removes any local user data from the CLI.

### Nodes <a href="#nodes" id="nodes"></a>

The `bcl nodes <METHOD> <OPTIONAL FLAGS>` command enables the user to access Bloq Nodes services and manage their registered Bloq Nodes. The `<METHOD>` is the Nodes service method that can be invoked.

Valid `<METHOD>` options are:

* chains
* info
* list
* remove
* services

#### Optional Flags <a href="#optional-flags-3" id="optional-flags-3"></a>

The following are the list of optional flags for the `bcl nodes` command:

| Optional Flag   | Description                                                                               |
| --------------- | ----------------------------------------------------------------------------------------- |
| -a, --all       | List all nodes                                                                            |
| -i, --nodeId    | Specify the node to interact with                                                         |
| -s, --serviceId | Specify an exact service encompassed by Bloq Nodes                                        |
| -t, --authType  | Speciy the authentication type for a node (default: basic) Options include `basic`, `jwt` |

{% hint style="success" %}
**TIP**

`bcl nodes` methods do not require any additional flags. If more input is required, the client will prompt you for that information upon command execution.
{% endhint %}

### Profile <a href="#profile" id="profile"></a>

The `bcl profile` command provides information about the user including:

* Account ID
* Display Name
* Email Address
* Verification Status

### Status <a href="#status" id="status"></a>

The `bcl status` command provides the online status of Bloq services.

### Update-Password <a href="#update-password" id="update-password"></a>

The `bcl update-password` command provides the ability for the user to change their existing password associated with their Bloq account.


# Accounts API

This Accounts API reference guide describes the endpoints to access Bloq Accounts services.

Jump to:

* [DELETE /users/me/client-keys/{id}](#delete-users-me-client-keys-id)
* [GET /users/me](#get-users-me)
* [GET /users/me/client-keys](#get-users-me-client-keys)
* [GET /users/me/events](#get-users-me-events)
* [POST /auth](#post-auth)
* [POST /auth/token](#post-auth-token)
* [POST /users/me/client-keys](#post-users-me-client-keys)
* [PUT /users/{userId}/token/{token}](#put-users-userid-token-token)
* [PUT /users/me/password](#put-users-me-password)

## PUT /users/{userId}/token/{token}

This resource verifies a new created user by User Id and verification token.

### Parameters

| Name   | In   | Type   | Required | Description                       |
| ------ | ---- | ------ | -------- | --------------------------------- |
| userId | path | string | true     | none                              |
| token  | path | string | true     | verification token sent via email |

### Responses

| Status | Meaning                                                 | Description          |
| ------ | ------------------------------------------------------- | -------------------- |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation |

### Code sample

```shell
curl -X PUT https://accounts.bloq.cloud/users/user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/token/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

## GET /users/me

This resource fetches the user profile information.

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Example responses

> 200 Response

```json
{
  "displayName": "Example User",
  "entityType": "individual",
  "verifiedAt": "2020-04-24T20:01:55.634Z",
  "updatedAt": "2020-04-24T20:01:55.634Z",
  "billingAddress": {
    "country": "US",
    "zipCode": "12345",
    "address": "123 Abc Street",
    "state": "CA"
  },
  "createdAt": "2020-04-24T19:57:48.878Z",
  "email": "email@example.com",
  "id": "user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

### Code sample

```shell
curl -X GET https://accounts.bloq.cloud/users/me \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```

## PUT /users/me/password

This resource updates a user password.

> Body parameter

```json
{
  "oldPassword": "Old Password...",
  "newPassword": "New Password..."
}
```

### Parameters

| Name          | Type   | In   | Required | Description |
| ------------- | ------ | ---- | -------- | ----------- |
| body          | object | body | true     | none        |
| » oldPassword | string | body | true     | none        |
| » newPassword | string | body | true     | none        |

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Code sample

```shell
curl -X PUT https://accounts.bloq.cloud/users/me/password \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <AUTH_TOKEN>' \
  -d '{
 "oldPassword": "Old Password...",
 "newPassword": "New Password..."
}'
```

## POST /auth

Using HTTP Basic Authentication to provide username (ID or email) and password, this resource retrieves an `Account Access Token` to be passed to other Accounts API functions, for their authentication. The token expires after 12 hours and a new token may be generated at any time.

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Example responses

> 200 Response

```json
{
  "accessToken": "xxxxxx.xxxxxxxxxx.xxxxxx"
}
```

### Code sample

```shell
# Using user email
curl -u email@example.com:password -X POST https://accounts.bloq.cloud/auth
```

```shell
# Using user ID
curl -u user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:password -X POST https://accounts.bloq.cloud/auth
```

## POST /auth/token

This endpoint provides a `Client Access Token` and a `Client Refresh Token`, these tokens are used to interact with cloud services like Nodes.

The Client Access Token expires after one hour and the Client Refresh Token expires after one year. The refresh access token is used to create new client access tokens.

> Body parameter to create an Access and Refresh token using `clientCredentials` as grant type

```json
{
  "grantType": "clientCredentials",
  "clientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "clientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
```

> Body parameter to create an access token using refreshToken as grant type

```json
{
  "grantType": "refreshToken",
  "refreshToken": "xxxxxx.xxxxxxxxxx.xxxxxx"
}
```

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Example Responses

> 200 Response

```json
{
  "accessToken": "xxxxxx.xxxxxxxxxx.xxxxxx",
  "refreshToken": "xxxxxx.xxxxxxxxxx.xxxxxx"
}
```

### Code sample

```shell
# Using Client Credentials Grant Type
curl -X POST https://accounts.bloq.cloud/auth/token \
  -H 'Content-Type: application/json' \
  -d '{
 "grantType": "clientCredentials",
 "clientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
 "clientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}'
```

```shell
# Using Refresh Token Grant Type
curl -X POST https://accounts.bloq.cloud/auth/token \
  -H 'Content-Type: application/json' \
  -d '{
 "grantType": "refreshToken",
 "refreshToken": "xxxxxx.xxxxxxxxxx.xxxxxx"
}'
```

## POST /users/me/client-keys

This resource creates a new client key pair. The key pair is used to generate a `Client Access Token`, these access token are used to interact with cloud services like Nodes API. To access this endpoint an `Account Access Token` must be provided as Bearer token in the authorization header.

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Example responses

> 200 Response

```json
{
  "clientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "clientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "createdAt": "2020-04-24T20:35:22.808Z"
}
```

### Code sample

```shell
curl -X POST https://accounts.bloq.cloud/users/me/client-keys \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```

## GET /users/me/client-keys

This resource fetches Client Keys

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Example responses

> 200 Response

```json
[
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "createdAt": "2019-03-11T13:58:53.151Z"
  },
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "createdAt": "2019-03-08T19:28:00.538Z"
  }
]
```

### Code sample

```shell
curl -X GET https://accounts.bloq.cloud/users/me/client-keys \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```

## DELETE /users/me/client-keys/{id}

This resource removes a Client Key by ID

### Parameters

| Name | In   | Type   | Required | Description |
| ---- | ---- | ------ | -------- | ----------- |
| id   | path | string | true     | Key ID      |

### Responses

| Status | Meaning                                                         | Description          | Schema |
| ------ | --------------------------------------------------------------- | -------------------- | ------ |
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | Successful operation | Inline |

### Code sample

```shell
curl -X DELETE https://accounts.bloq.cloud/users/me/client-keys/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```

## GET /users/me/events

This resource fetches the user events

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Example Responses

> 200 Response

```json
[
  {
    "service": "cloud-accounts",
    "output": {
      "startTime": "2020-04-24T19:57:48.988Z",
      "endTime": "2020-04-24T19:57:49.065Z",
      "httpStatusCode": 200,
      "bytesOut": 385
    },
    "serviceData": {},
    "user": "user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "input": {},
    "createdAt": "2020-04-24T19:57:49.093Z",
    "id": "event-bfe91423-8b6b-44d1-a264-483aab8a7f0d"
  },
  {
    "service": "cloud-accounts",
    "output": {
      "startTime": "2020-04-24T20:00:34.581Z",
      "endTime": "2020-04-24T20:00:35.057Z",
      "httpStatusCode": 401,
      "bytesOut": 0
    }
  }
]
```

### Code sample

```shell
curl -X GET https://accounts.bloq.cloud/users/me/events \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```


# Nodes API

This Nodes API reference guide describes the endpoints to access Bloq Nodes services and manage your Bloq Nodes.

{% hint style="success" %}
**TIP**

Clusters utilize the same API as Bloq Nodes. To interact with your node clusters, change the `/nodes/` path in the API URL to `/clusters/`.
{% endhint %}

Jump to:

* [DELETE /users/me/nodes/{id}](#delete-users-me-nodes-id)
* [GET /chains](#get-chains)
* [GET /users/me/nodes](#get-users-me-nodes)
* [GET /users/me/nodes/{id}](#get-users-me-nodes-id)
* [POST /users/me/nodes](#post-users-me-nodes)

## GET /chains

This resource lists the chains and versions available for creating new nodes.

### Responses

| Status | Meaning                                                 | Description          |
| ------ | ------------------------------------------------------- | -------------------- |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation |

### Example responses

> 200 Response

```json
[
  {
    "chain": "bch",
    "network": "mainnet",
    "software": "abc-0.19"
  },
  {
    "chain": "bch",
    "network": "testnet",
    "software": "abc-0.19"
  },
  {
    "chain": "btc",
    "network": "mainnet",
    "software": "core-0.17"
  },
  {
    "chain": "btc",
    "network": "testnet",
    "software": "core-0.17"
  }
  {
    "chain": "eth",
    "network": "mainnet",
    "software": "geth-1.8"
  },
  {
    "chain": "ltc",
    "network": "mainnet",
    "software": "litecoin-0.17"
  }
]
```

### Code sample

```shell
curl -X GET https://nodes.bloq.cloud/chains
```

## POST /users/me/nodes

This resource creates a new node.

### Parameters

| Name  | In   | Type    | Required | Description                                                                                       |
| ----- | ---- | ------- | -------- | ------------------------------------------------------------------------------------------------- |
| image | body | string  | true     | Blockchain id. `btc`, `bch`, `ltc`, `btctestnet`, `bchtestnet`, and `eth` are currently supported |
| large | body | boolean | false    | Set true to request a larger/faster node.                                                         |
| jwt   | body | boolean | false    | Use jwt Bearer token for auth.                                                                    |

> Body parameter

```json
{
  "image": "btc",
  "large": false,
  "jwt:" false
}
```

### Responses

| Status | Meaning                                                 | Description          |
| ------ | ------------------------------------------------------- | -------------------- |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation |

**Example responses**

> 200 Response

```json
{
  "user": "user-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "id": "node-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "image": "btc",
  "version": "core-0.17",
  "state": "started",
  "nodeUser": "xxxxxxxxxx",
  "nodePass": "xxxxxxxxxx",
  "instance": {
    "vendor": "aws",
    "id": "i-032155ff0235d2dbb",
    "imageId": "ami-021e0f4b36b068ccb",
    "type": "t2.large"
  },
  "startedAt": "2019-03-27T18:40:19.878Z"
}
```

### Code sample

```shell
curl -X POST https://nodes.bloq.cloud/users/me/nodes \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
  -d '{
   "image": "btc"
  }'
```

## GET /users/me/nodes

This resource list created nodes

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

**Example responses**

> 200 Response

```json
[
  {
    "stoppedAt": "2020-04-21T05:00:18.586Z",
    "serviceData": {
      "amiPrefix": "btc",
      "performance": "standard",
      "software": "core-0.17",
      "ports": [8080, 8332]
    },
    "ip": "18.213.193.254",
    "createdAt": "2020-04-21T00:45:07.687Z",
    "ttl": "1588050018",
    "user": "user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "userPlanData": {
      "startsAt": "2020-04-21T00:45:05.324Z",
      "id": "user-plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "plan": "plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "expiresAt": "2020-05-21T00:45:05.324Z"
    },
    "instance": {
      "region": "us-east-1",
      "id": "i-02cb186c0808950f6",
      "imageId": "ami-01ee6543215d4006b"
    },
    "vendor": {
      "name": "aws",
      "subnet": "subnet-41daba24",
      "securityGroups": [
        "sg-50d39921",
        "sg-0a52e56ee0c02fd7a",
        "sg-784d5703",
        "sg-0769b9650222e64ce"
      ],
      "region": "us-east-1",
      "instanceType": "t3.large",
      "quickSync": true
    },
    "network": "mainnet",
    "state": "stopped",
    "service": "service-f409a426-8bdd-5c65-bcd3-7c6d0424a5ac",
    "auth": {
      "type": "basic",
      "user": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "pass": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "updatedAt": "2020-04-21T00:45:09.419Z",
    "chain": "btc",
    "id": "node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  },
  {
    "stoppedAt": "2020-04-21T05:00:18.586Z",
    "serviceData": {
      "amiPrefix": "btc",
      "performance": "standard",
      "software": "core-0.17",
      "ports": [8080, 8332]
    },
    "ip": "18.213.193.254",
    "createdAt": "2020-04-21T00:45:07.687Z",
    "ttl": "1588050018",
    "user": "user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "userPlanData": {
      "startsAt": "2020-04-21T00:45:05.324Z",
      "id": "user-plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "plan": "plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "expiresAt": "2020-05-21T00:45:05.324Z"
    },
    "instance": {
      "region": "us-east-1",
      "id": "i-02cb186c0808950f6",
      "imageId": "ami-01ee6543215d4006b"
    },
    "vendor": {
      "name": "aws",
      "subnet": "subnet-41daba24",
      "securityGroups": [
        "sg-50d39921",
        "sg-0a52e56ee0c02fd7a",
        "sg-784d5703",
        "sg-0769b9650222e64ce"
      ],
      "region": "us-east-1",
      "instanceType": "t3.large",
      "quickSync": true
    },
    "network": "mainnet",
    "state": "stopped",
    "service": "service-f409a426-8bdd-5c65-bcd3-7c6d0424a5ac",
    "auth": {
      "type": "basic",
      "user": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "pass": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "updatedAt": "2020-04-21T00:45:09.419Z",
    "chain": "btc",
    "id": "node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  }
]
```

### Code sample

```shell
curl -X GET https://nodes.bloq.cloud/users/me/nodes \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```

## GET /users/me/nodes/{id}

This resource fetches a node by ID.

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

**Example responses**

> 200 Response

```json
{
  "stoppedAt": "2020-04-21T05:00:18.586Z",
  "serviceData": {
    "amiPrefix": "btc",
    "performance": "standard",
    "software": "core-0.17",
    "ports": [8080, 8332]
  },
  "ip": "18.213.193.254",
  "createdAt": "2020-04-21T00:45:07.687Z",
  "ttl": "1588050018",
  "user": "user-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "userPlanData": {
    "startsAt": "2020-04-21T00:45:05.324Z",
    "id": "user-plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "plan": "plan-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "expiresAt": "2020-05-21T00:45:05.324Z"
  },
  "instance": {
    "region": "us-east-1",
    "id": "i-02cb186c0808950f6",
    "imageId": "ami-01ee6543215d4006b"
  },
  "vendor": {
    "name": "aws",
    "subnet": "subnet-41daba24",
    "securityGroups": [
      "sg-50d39921",
      "sg-0a52e56ee0c02fd7a",
      "sg-784d5703",
      "sg-0769b9650222e64ce"
    ],
    "region": "us-east-1",
    "instanceType": "t3.large",
    "quickSync": true
  },
  "network": "mainnet",
  "state": "stopped",
  "service": "service-f409a426-8bdd-5c65-bcd3-7c6d0424a5ac",
  "auth": {
    "type": "basic",
    "user": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "pass": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "updatedAt": "2020-04-21T00:45:09.419Z",
  "chain": "btc",
  "id": "node-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

### Code sample

```shell
curl -X GET https://nodes.bloq.cloud/users/me/nodes/node-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```

## DELETE /users/me/nodes/{id}

This resource removes a node by ID.

### Responses

| Status | Meaning                                                 | Description          | Schema |
| ------ | ------------------------------------------------------- | -------------------- | ------ |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation | Inline |

### Code sample

```shell
curl -X DELETE https://nodes.bloq.cloud/users/me/nodes/node-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -H 'Authorization: Bearer <AUTH_TOKEN>'
```


# Blockchain Node API

This reference guide outlines the interfaces to access blockchain nodes that are created as part of the Bloq Nodes service.

Any key deviations from the standard node interface (by blockchain) are highlighted as part of the reference guide.

{% hint style="success" %}
**TIP**

Testnet nodes use the same API calls as their mainnet counterparts. Just make sure the address port matches your node's chain!
{% endhint %}

*Jump to:*

* [BTC](#btc)
* [BCH](#bch)
* [ETH](#eth)
* [Avalanche](#avalanche)

## BTC <a href="#btc" id="btc"></a>

{% hint style="success" %}
**TIP**

The Bitcoin Node API is largely interoperable with Litecoin, with a few documented distinctions. Please see the [Litecoin REST API documentation](https://github.com/litecoin-project/litecoin/blob/master/doc/REST-interface.md#supported-api) and [Litecoin JSON-RPC methods](https://litecoin.info/index.php/Litecoin_API) for more information.
{% endhint %}

### REST API <a href="#rest-api" id="rest-api"></a>

{% hint style="success" %}
**TIP**

A key-client pair must be created prior to using the Nodes service. Use the `bcl client-keys` command if `client-keys` do not currently exist.

If a key-client pair already exists, use the `bcl conf` command to load your keypair.
{% endhint %}

{% hint style="success" %}
**TIP**

In addition to having a client-key pair generated, a *clientAccessToken* and *refreshToken* are also required to access the Nodes service. Use the `bcl client-token` command to generate the tokens.
{% endhint %}

To learn more about the REST API that this node provides please see the [REST API documentation](https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/REST-interface.md#supported-api).

### JSON-RPC <a href="#json-rpc" id="json-rpc"></a>

The Nodes service supports the standard Bitcoin JSON-RPC calls with a number that are blacklisted. RPC calls that would negatively impact the running of the service are blacklisted. Wallet specific RPC calls are also currently not allowed as all nodes are run with `--disable-wallet`.

#### **POST getblock**

```shell
curl -k -X POST \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc": "1.0", "method": "getblock", "params": ["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", true] }' \
  https://<ip-address>:8332/
```

**Response**

```json
{
  "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
  "confirmations": 633169,
  "size": 285,
  "height": 0,
  "version": 1,
  "versionHex": "00000001",
  "merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  "tx": ["4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"],
  "time": 1231006505,
  "mediantime": 1231006505,
  "nonce": 2083236893,
  "bits": "1d00ffff",
  "difficulty": 1,
  "chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
  "nTx": 1,
  "nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
}
```

#### **POST getdifficulty**

```shell
curl -k -X POST \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc": "1.0", "method": "getdifficulty", "params": [] }' \
  https://<ip-address>:8332/
```

**Response**

```json
{
  "result": 15958652328578.1588
}
```

#### **Full BTC JSON-RPC call list**

For a full list of Bitcoin JSON-RPC commands please see [Bitcoin JSON-RPC methods](https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list).

#### **Blacklisted BTC JSON-RPC Calls**

The following list of JSON-RPC calls are NOT available for the Nodes Bitcoin (BTC) service:

* `stop`
* `generate`
* `generatetoaddress`

#### **Disabled BTC Wallet Specific Calls**

Wallet specific RPC calls are currently disabled. For the full list of unsupported wallet RPCs, please see [Wallet RPC methods](https://bitcoin.org/en/developer-reference#wallet-rpcs).

## BCH <a href="#bch" id="bch"></a>

### REST API <a href="#rest-api-2" id="rest-api-2"></a>

{% hint style="success" %}
**TIP**

A key-client pair must be created prior to using the Nodes service. Use the `bcl client-keys` command if `client-keys` do not currently exist.

If a key-client pair already exists, use the `bcl conf` command to load your keypair.
{% endhint %}

{% hint style="success" %}
**TIP**

In addition to having a client-key pair generated, a *clientAccessToken* and *refreshToken* are also required to access the Nodes service. Use the `bcl client-token` command to generate the tokens.
{% endhint %}

To learn more about the REST API that this node provides please see the [REST API documentation](https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/REST-interface.md#supported-api).

### JSON-RPC <a href="#json-rpc-2" id="json-rpc-2"></a>

The Nodes service supports the standard Bitcoin Cash JSON-RPC calls with a number that are blacklisted. RPC calls that would negatively impact the running of the service are blacklisted. Wallet specific RPC calls are also currently not allowed as all nodes are run with `--disable-wallet`.

#### **Full BCH JSON-RPC call list**

For a full list of Bitcoin JSON-RPC commands please see [Bitcoin Cash JSON-RPC methods](https://docs.bitcoincashnode.org/doc/json-rpc/).

#### **Blacklisted BCH JSON-RPC Calls**

The following list of JSON-RPC calls are NOT available for the Nodes Bitcoin Cash (BCH) service:

* `stop`
* `generate`
* `generatetoaddress`

#### **Disabled BCH Wallet Specific Calls**

Wallet specific RPC calls are currently disabled. For the full list of unsupported wallet RPCs, please see [Wallet RPC methods](https://bitcoin.org/en/developer-reference#wallet-rpcs).

## ETH <a href="#eth" id="eth"></a>

### JSON-RPC <a href="#json-rpc-3" id="json-rpc-3"></a>

The Nodes service supports the standard Ethereum JSON-RPC calls with a number that are blacklisted. RPC calls that would negatively impact the running of the service are blacklisted.

#### **POST blockNumber**

```shell
curl -X POST \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  -d '{ "jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1 }' \
  https://<ip-address>:8545/
```

**Response**

```json
{
  "jsonrpc": "2.0",
  "result": "0x981fb8", //9969592
  "id": 1
}
```

#### **Full ETH JSON-RPC call list**

For a full list of Ethereum JSON-RPC commands see [Ethereum JSON-RPC methods](https://github.com/ethereum/wiki/wiki/JSON-RPC).

#### **Blacklisted ETH JSON-RPC Calls**

The following list of JSON-RPC calls are NOT available for the Nodes Ethereum (ETH) service:

* `eth_accounts`
* `shh_newIdentity`

## Avalanche <a href="#avalanche" id="avalanche"></a>

Bloq Avalanche nodes support the JSON RPC described in the [Avalanche API reference](https://docs.avax.network/build/tools/public-api#using-the-public-api-nodes).

### Management API <a href="#management-api" id="management-api"></a>

A special API is provided on port 8080 for all nodes with calls to help manage the nodes.

#### GET /status <a href="#get-status" id="get-status"></a>

Request the status of a node.

**Responses**

| Status | Meaning                                                 | Description          |
| ------ | ------------------------------------------------------- | -------------------- |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation |

**Example responses**

> 200 Response

```
"healthy"
```

**Code Sample**

```shell
curl -k -X GET \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  https://<ip-address>:8080/status
```

#### GET /logs <a href="#get-logs" id="get-logs"></a>

Request the logs from the running blockchain daemon.

**Parameters**

| Name  | In   | Type   | Required | Description                                                |
| ----- | ---- | ------ | -------- | ---------------------------------------------------------- |
| lines | body | number | false    | Number of log lines to retrieve. Leave blank for full log. |

**Responses**

| Status | Meaning                                                 | Description          |
| ------ | ------------------------------------------------------- | -------------------- |
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Successful operation |

**Example responses**

> 200 Response

```json
[
  "B2019-07-01T19:43:21Z Bitcoin Core version v0.17.1 (release build)",
  "z2019-07-01T19:43:21Z InitParameterInteraction: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1",
  "2019-07-01T19:43:21Z Assuming ancestors of block 0000000000000000002e63058c023a9a1de233554f28c7b21380b6c9003f36a8 have valid signatures.",
  "p2019-07-01T19:43:21Z Setting nMinimumChainWork=0000000000000000000000000000000000000000028822fef1c230963535a90d"
]
```

**Code Sample**

```shell
curl -k -X GET \
  --user <NodeUser>:<NodePass> \
  -H 'Content-Type: application/json' \
  https://<ip-address>:8080/logs
```


# Javascript SDK

The Bloq Javascript SDK enables you to work with Bloq services easily by simplifying authentication.

### Requirements <a href="#requirements" id="requirements"></a>

The Javascript SDK has the following system requirements to install the library:

* [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/)

### Install <a href="#install" id="install"></a>

To install the Bloq Javascript SDK, use either:

`npm install --save @bloq/cloud-sdk`

OR

`yarn add @bloq/cloud-sdk`

### Auth API <a href="#auth-api" id="auth-api"></a>

The auth API helps to simplify the authentication process.

#### Access Token <a href="#access-token" id="access-token"></a>

`accessToken()`

This method returns a promise that resolves in a new created access token using the provided client ID and secret.

The `Access Token` is required to interact with Bloq services. It usually travels in an Authorization header value.

**Code sample**

```javascript
const { auth } = require('@bloq/cloud-sdk')

const clientId = 'CLIENT_ID'
const clientSecret = 'CLIENT_SECRET'

const client = auth({ clientId, clientSecret })

client.accessToken().then(function (accessToken) {
  // Use access token
})
```


# Knowledge Base


# How do I connect my Ethereum Node using the Web3 interface?

The web3.js library makes it simple to connect and interact with Ethereum nodes.

This knowledgebase article contains sample JS Code that should help explain how to use the web3.js library to connect to your Bloq Ethereum node.

If you haven't done so already, please see the [Bloq Node Setup](/advanced-documentation/developers-guide/bloqnode-setup) page to spin up your Ethereum node.

### Requirements <a href="#requirements" id="requirements"></a>

First, ensure the Web3 libraries are installed by following this [guide](https://web3js.readthedocs.io/en/v1.2.1/getting-started.html).

Once the libraries have been installed, you can connect to your Ethereum node with the sample code. Some of the key steps within the sample code includes:

1. Setting up parameters
2. Creating a Web3 http provider with credentials
3. Disregarding self-signed certificates
4. Creating the Web3 instance
5. Using the Web3 interface to fetch the current block number

### 1. Setting up Parameters <a href="#id-1-setting-up-parameters" id="id-1-setting-up-parameters"></a>

```javascript
'use strict'

const https = require('https')
const Web3 = require('web3')

const nodeUrl = 'https://<BLOQ_ETH_NODE_IP_ADDRESS>:8545'
```

### 2. Creating a Web3 http provider with credentials <a href="#id-2-creating-a-web3-http-provider-with-credentials" id="id-2-creating-a-web3-http-provider-with-credentials"></a>

#### Option 1: Basic Authentication <a href="#option-1-basic-authentication" id="option-1-basic-authentication"></a>

```javascript
const user = 'USER'
const password = 'PASSWORD'

// Create a Web3 HTTP provider with the basic auth credentials set
const web3Provider = new Web3.providers.HttpProvider(nodeUrl, {
  headers: [
    {
      name: 'Authorization',
      value: `Basic ${Buffer.from(`${user}:${password}`).toString('base64')}`
    }
  ]
})
```

#### Option 2: Using JWT <a href="#option-2-using-jwt" id="option-2-using-jwt"></a>

```javascript
const token = 'TOKEN'

// Create a Web3 HTTP provider with JWT set
const web3Provider = new Web3.providers.HttpProvider(nodeUrl, {
  headers: [
    {
      name: 'Authorization',
      value: `Bearer ${token}`
    }
  ]
})
```

### 3. Creating a Web3 websocket provider with credentials <a href="#id-3-creating-a-web3-websocket-provider-with-credentials" id="id-3-creating-a-web3-websocket-provider-with-credentials"></a>

#### Option 1: Basic Authentication <a href="#option-1-basic-authentication-2" id="option-1-basic-authentication-2"></a>

```javascript
const user = 'USER'
const password = 'PASSWORD'

// Create a Web3 WS provider with the basic auth credentials set
const web3Provider = new Web3.providers.WebsocketProvider(nodeUrl, {
  headers: {
    authorization: `Basic ${Buffer.from(`${user}:${password}`).toString(
      'base64'
    )}`
  }
})
```

#### Option 2: Using JWT <a href="#option-2-using-jwt-2" id="option-2-using-jwt-2"></a>

```javascript
const token = 'TOKEN'

// Create a Web3 WS provider with JWT set
const web3Provider = new Web3.providers.HttpProvider(nodeUrl, {
  headers: { authorization: `Bearer ${token}` }
})
```

### 4. Disregarding Self-Signed Certificates <a href="#id-4-disregarding-self-signed-certificates" id="id-4-disregarding-self-signed-certificates"></a>

```javascript
// Create a Web3 WS provider with basic auth credentials
// that disregards self-signed certificates
const web3Provider = new Web3.providers.WebsocketProvider(nodeUrl, {
  requestOptions: { rejectUnauthorized: false },
  headers: {
    authorization: `Basic ${Buffer.from(`${user}:${password}`).toString(
      'base64'
    )}`
  }
})

// Set the HTTPS agent in that provider to avoid complaining about
// self-signed certificates
web3Provider.httpsAgent = new https.Agent({ rejectUnauthorized: false })
```

### Additional Resources <a href="#additional-resources" id="additional-resources"></a>

Web3 Documentation: <https://web3js.readthedocs.io/en/v1.2.0/web3-eth.html>


