Contact Sales

Using gRPCurl with BOS API

Introduction

gRPC is a high-performance, open-source, universal RPC framework that allows you to define services and message types using Protocol Buffers. It is widely used for building efficient and reliable distributed systems.

grpcurl is a command-line utility akin to curl but designed for gRPC servers. It's invaluable for testing, debugging, and interacting with gRPC API services, such as the Braiins OS Public API.

Braiins OS Public API, launched in Braiins OS version 23.03, marks a major milestone in the evolution of our platform. This API establishes a uniform standard for all current and future hardware variants, regardless of the manufacturer. Initially released in beta, it provided a preview of our platform's potential. Since Braiins OS version 24.03, it has reached its stable release, version 1.0.0.

This guide should help streamline the process of installing and using grpcurl on Ubuntu for interacting with gRPC servers, specifically for operations related to the Braiins OS Public API.

Installation and Setup

Installation Method: Using Precompiled Binaries

There are multiple methods to install grpcurl, with the most common being the download of a precompiled binary.

  • Download grpcurl: Navigate to the grpcurl releases page on GitHub to identify the latest version. Use the following command pattern to download the selected version, substituting VERSION with the actual version number:
wget https://github.com/fullstorydev/grpcurl/releases/download/vVERSION/grpcurl_<VERSION>_linux_x86_64.tar.gz

For instance, for version 1.8.9, you would run:

wget https://github.com/fullstorydev/grpcurl/releases/download/v1.8.9/grpcurl_1.8.9_linux_x86_64.tar.gz
  • Extract and Install grpcurl: After downloading, extract the archive and move the grpcurl binary to a directory in your PATH, such as /usr/local/bin, to make it globally accessible.
tar -xzf grpcurl_1.8.9_linux_x86_64.tar.gz
sudo mv grpcurl /usr/local/bin/
  • Launching grpcurl: Execute grpcurl -help without arguments to see the help message and verify that it's working as expected.
grpcurl -help

This command should display the grpcurl help information, indicating a successful installation.

  • Flags and Options: The following are some common flags and options used with grpcurl commands:

The -plaintext option indicates that the connection should not be encrypted. This is suitable for local testing.

The -v flag is to get verbose output, helping understand the gRPC calls better and display the request and response headers.

The -d flag is used to specify the request data.

The -H flag is used to specify a request header.

The -msg-template option is used to generate a message template for the request, providing a skeleton with all the fields you need to populate for your actual request.

The -import-path option is used to specify the path to the directory containing the proto files.

The -proto option is used to specify the proto file for the service you are interacting with.

Getting Started

The Braiins OS Public API provides a gRPC interface for interacting with Braiins OS miners. You can use grpcurl to make requests to the API and retrieve information or perform actions on the miner. The port for the BOS Public API is 50051 *.

Exploring Services

To explore services on a gRPC server, there are two primary approaches:

  • Using Server Reflection: This method allows you to dynamically discover available services on the server, offering a straightforward way to understand its capabilities without external dependencies.
  • Importing Proto Files: For more details, gRPC services can be defined and interacted with through Protocol Buffers (proto files). Importing these proto file definitions is essential for accessing the service specifications.

In the end, you choose which approach fits better for your use cases.

Using Server Reflection

To demonstrate how to utilize Server Reflection, we'll showcase listing all available services of the Braiins OS Public API. For this example, use the following command:

Sample Request:
grpcurl -plaintext <MINER_IP>:50051 list
  • Ensure to replace <MINER_IP> with the actual IP address of your miner.

  • Here we are using the -plaintext option to indicate that the connection should not be encrypted. This is suitable for local testing.

Expected Response:
braiins.bos.ApiVersionService
braiins.bos.v1.ActionsService
braiins.bos.v1.AuthenticationService
braiins.bos.v1.ConfigurationService
braiins.bos.v1.CoolingService
braiins.bos.v1.LicenseService
braiins.bos.v1.MinerService
braiins.bos.v1.NetworkService
braiins.bos.v1.PerformanceService
braiins.bos.v1.PoolService
grpc.reflection.v1alpha.ServerReflection

Importing Proto Files

If you wish to work with a specific service or need to interact with a service that requires a specific proto file, you can import the proto file directly. You can download the proto files from the Braiins OS Public API repository and use them with grpcurl.

Here we are using the -proto option to specify proto file's path and -import-path option to specify the path to the directory containing the proto files.

Suppose you have the miner.proto file located in the ./bos-plus-api/proto/bos/v1/ directory. Remember to use the -proto flag to specify the path to the proto file, especially if there are any dependencies on the proto file.

Sample Request:
grpcurl -plaintext -import-path './proto' -proto './proto/bos/v1/miner.proto' <MINER_IP>:50051 list
  • Ensure to replace <MINER_IP> with the actual IP address of your miner.
Expected Response:
braiins.bos.v1.CoolingService
braiins.bos.v1.MinerService
braiins.bos.v1.PoolService

Describing Services with grpcurl

Understanding the structure and capabilities of your gRPC services is crucial for effective interaction and testing. grpcurl provides a straightforward way to describe services and their methods, allowing you to view the available operations and their request-response structures.

Describing a Service

To obtain detailed information about a specific service or method, use the describe option in grpcurl. This will show you the service's methods, request types, and response types.

Command Syntax:

grpcurl -plaintext '<MINER_IP>:50051' describe 'Your.ServiceName/YourMethodName'

Replace Your.ServiceName/YourMethodName with the actual service and method name. For example, to describe the AuthenticationService in a Braiins OS miner, your command would look like this:

Sample Request:
grpcurl -plaintext '<MINER_IP>:50051' describe 'braiins.bos.v1.AuthenticationService'
  • Ensure to replace <MINER_IP> with the actual IP address of your miner.
Expected Response:
braiins.bos.v1.AuthenticationService is a service:
service AuthenticationService {
  // Method to login and retrieve authentication token
  rpc Login ( .braiins.bos.v1.LoginRequest ) returns ( .braiins.bos.v1.LoginResponse );
  // Method to set password
  rpc SetPassword ( .braiins.bos.v1.SetPasswordRequest ) returns ( .braiins.bos.v1.SetPasswordResponse );
}

This response outlines the methods available under the AuthenticationService, including Login and SetPassword, along with their request and response message types.

Getting Message Templates

After identifying the service and method you're interested in, you might want to know the expected request format. grpcurl can generate a message template for the request, providing a skeleton with all the fields you need to populate for your actual request.

Sample Request:
grpcurl -plaintext -msg-template '<MINER_IP>:50051' describe 'braiins.bos.v1.LoginRequest'

This command will output a template for the LoginRequest message, indicating the fields you need to include in your request.

Expected Response:
braiins.bos.v1.LoginRequest is a message:
// Request for login action.
message LoginRequest {
  string username = 1;
  string password = 2;
}

Message template:
{
  "username": "",
  "password": ""
}

In the expected response above, the Message Template shows you exactly how to structure your JSON payload when making a Login request, requiring username and password fields.

By following these steps, you can effectively interact with gRPC API services, understand their structures, and craft requests using grpcurl.

Making Your First Request

Sending a Login Request (Obtaining a Session Token)

This section will focus on the process of obtaining a session token, essential for interacting with the Braiins OS Public API, and understanding its management including expiration and renewal.

Session Token Characteristics:

  • The session token acts similarly to the session logic utilized by the Braiins OS GUI.
  • It has an expiration period of 3600 seconds (1 hour).
  • The token's validity extends with each API request, meaning consistent use within the expiration period keeps the session alive.
  • If no requests are made within the expiration period, a new login is required to obtain a new session token.

Authentication Command:

Now we understand how to use describe and -msg-template to structure our login request for braiins.bos.v1.LoginRequest.

To initiate a session and obtain a token, execute the following grpcurl command:

Sample Request:
grpcurl -plaintext -v -d '{"username": "root", "password": ""}' <MINER_IP>:50051 'braiins.bos.v1.AuthenticationService/Login' 2>&1 | grep authorization:
  • Replace <MINER_IP> with the IP address of your miner.

  • The grep command 2>&1 | grep authorization: at the end of the request is for simplifying the output of the response.

Expected Response:
authorization: pHbLw9hwZ0gWnxYx

The response will contain the authorization: <YOUR_SESSION_TOKEN> header, which holds the session token. This token is essential for making authenticated requests to the Braiins OS Public API.

Making Authenticated API Calls

With the session token, you can make authenticated requests to other services within the Braiins OS Public API. This section outlines how to use the obtained session token for further API interactions.

To use the session token for authenticated requests, include it as a header -H in your grpcurl commands. Here's a general approach:

Command Syntax:

grpcurl -plaintext -H 'authorization:<YOUR_SESSION_TOKEN>' <MINER_IP>:50051 'ServiceName/MethodName'
  • Replace <YOUR_SESSION_TOKEN> with the token obtained from the login response and, <MINER_IP> with the actual IP address of your miner.

  • Specify ServiceName/MethodName with the target service and method you wish to call.

Examples

Get Request

Mostly used for retrieving information, the Get request is a common operation in API interactions. Here are a few examples of Get requests using the Braiins OS Public API.

In most get requests you don't need to send specific JSON data, and you can use the -d flag to specify an empty JSON object {}, and the obtained session token as a header -H 'authorization:<YOUR_SESSION_TOKEN>'.

Get Tuner State

To check the current state of the tuner, use the GetTunerState method from the PerformanceService. This request provides details about the tuner's status, hash rate target, power target, and more.

Sample Request:
grpcurl -plaintext -H 'authorization:<YOUR_SESSION_TOKEN>' -d '{}' <MINER_IP>:50051 'braiins.bos.v1.PerformanceService/GetTunerState'
  • Replace <YOUR_SESSION_TOKEN> with the token obtained from the login response and, <MINER_IP> with the actual IP address of your miner.
Expected Response:
{
    "overall_tuner_state": "TUNER_STATE_STABLE",
    "power_target_mode_state": {
        "profile": {
            "created": null,
            "target": {
                "watt": "1712"
            },
            "measured_hashrate": {
                "gigahash_per_second": 39693.738556032
            },
            "estimated_power_consumption": {
                "watt": "1181"
            }
        },
        "current_target": {
            "watt": "1712"
        }
    }
}

Get Miner Details

As another example, to retrieve detailed information about the miner, including its identity, platform, BOS version, hostname, MAC address, and more, use the GetMinerDetails method from the MinerService.

Sample Request:
grpcurl -plaintext -H 'authorization:<YOUR_SESSION_TOKEN>' <MINER_IP>:50051 'braiins.bos.v1.MinerService/GetMinerDetails'
  • Replace <YOUR_SESSION_TOKEN> with the token obtained from the login response and, <MINER_IP> with the actual IP address of your miner.
Expected Response:
{
    "uid": "LQakFUOmGRvnG7pb",
    "miner_identity": {
        "brand": "MINER_BRAND_ANTMINER",
        "model": "MINER_MODEL_ANTMINER_S19J",
        "name": "Antminer S19J88",
        "miner_model": "Antminer S19J88"
    },
    "platform": "PLATFORM_AM3_AML",
    "bos_mode": "BOS_MODE_NAND",
    "bos_version": {
        "current": "2024-02-23-0-b19385b7-24.02-plus-rc",
        "major": "2022-09-13-0-11012d53-22.08-plus",
        "bos_plus": true
    },
    "hostname": "Antminer",
    "mac_address": "02:7a:01:27:3d:4c",
    "system_uptime": "73094",
    "sticker_hashrate": {
        "gigahash_per_second": 87000
    },
    "bosminer_uptime_s": "73037",
    "system_uptime_s": "73094"
}

Set Request

The Set request is used to modify configurations or settings on the miner.

To send a Set request, we need to:

  1. Obtain a session token
  2. Find the right method (By calling list Services/methods)
  3. Get the message template for the request(By calling describe and -msg-template over the services).
  4. Adjust the request data and "Save Action" type and make the request.
Save Action Field Explanation

The SaveAction field specifies how changes made via API calls should be handled regarding the miner's configuration:

  • SAVE_ACTION_UNSPECIFIED: Default behavior without explicit save action.
  • SAVE_ACTION_SAVE: Saves changes without applying them immediately.
  • SAVE_ACTION_SAVE_AND_APPLY: Saves and applies changes right away.
  • SAVE_ACTION_SAVE_AND_FORCE_APPLY: Forces immediate application of changes, bypassing any normal checks.

Set Power Target

To adjust the power target of the miner, use the SetPowerTarget method from the PerformanceService. This request allows you to specify the desired power target in watts.

  • Replace <MINER_IP> with the IP address of your miner in the sample requests below.

Step 1: Obtained the session token.

Sample Request:
grpcurl -plaintext -v -d '{"username": "root", "password": ""}' <MINER_IP>:50051 'braiins.bos.v1.AuthenticationService/Login' 2>&1 | grep authorization:

Sample Response:

authorization: pHbLw9hwZ0gWnxYx

Step 2: Described the SetPowerTarget method from the PerformanceService service:

Sample Request:
grpcurl -plaintext <MINER_IP>:50051 describe 'braiins.bos.v1.PerformanceService.SetPowerTarget'
Expected Response:
braiins.bos.v1.PerformanceService.SetPowerTarget is a method:
// Method to set absolute power target for tuner
rpc SetPowerTarget ( .braiins.bos.v1.SetPowerTargetRequest ) returns ( .braiins.bos.v1.SetPowerTargetResponse );

Step 2: Utilized the message template for the request:

Sample Request:
grpcurl -plaintext -msg-template <MINER_IP>:50051 'describe braiins.bos.v1.SetPowerTargetRequest'
Expected Response:
braiins.bos.v1.SetPowerTargetRequest is a message:
// Request for set absolute power target action.
message SetPowerTargetRequest {
  // Save action
  .braiins.bos.v1.SaveAction save_action = 1;
  // Absolute value of power target
  .braiins.bos.v1.Power power_target = 2;
}

Message template:
{
  "saveAction": "SAVE_ACTION_UNSPECIFIED",
  "powerTarget": {
    "watt": "0"
  }
}

Step 3: Adjust the power target:

  • Replace <YOUR_SESSION_TOKEN> with the token obtained from the login response and, <MINER_IP> with the actual IP address of your miner.

  • Set the watt value to your desired power target. Be careful about the power target value you set, as it can affect the miner's performance and stability.

  • The saveAction* field specifies how changes made via API calls should be handled regarding the miner's configuration.

Sample Request:
grpcurl -plaintext -H 'authorization <YOUR_SESSION_TOKEN>' -d '{ "power_target": { "watt": "1712" }, "save_action": 2 }' <MINER_IP>:50051 'braiins.bos.v1.PerformanceService/SetPowerTarget'
Expected Response:
{
    "powerTarget": {
        "watt": "1712"
    }
}

Stream Request

To call a streaming method like MinerServive/GetMinerStatus using grpcurl, you'll need to follow the basic structure of making a gRPC call with grpcurl, with an emphasis on handling streaming responses.

Below is a general example of how to do this, tailored to the GetMinerStatus method of the MinerService:

Sample Request:
grpcurl -plaintext -H 'authorization: <YOUR_SESSION_TOKEN>' -d '{}' <MINER_IP>:50051 'braiins.bos.v1.MinerService/GetMinerStatus'
Expected Response:
{
    "status": "MINER_STATUS_NORMAL"
}
  • For streaming responses, grpcurl will print out each message as it's received until the server closes the stream or until you terminate the command (e.g., by pressing Ctrl+C).

Handling Streamed Responses: Streamed responses will be printed to your console as they are received. Each message from the stream will be formatted as a separate JSON object. If you're scripting or processing this output programmatically, ensure your script can handle multiple JSON objects.

Footnotes

Port 50051

BOS Public API uses port number 50051 and it's open on Braiins OS, Only if you are using Braiins OS 23.03 you need to open API port manually ssh root@MINER_IP 'iptables -A INPUT -p tcp --dport 50051 -j ACCEPT'.

Grep Authorization Token

The 2>&1 | grep authorization: command at the end of authorization command is used to extract the authorization header from the response, which contains the session token.

External Resources

For those new to gRPC or seeking to deepen their understanding, the following resources can be incredibly helpful:

  • grpcurl GitHub Repository: The official GitHub repository for grpcurl, including comprehensive usage instructions, examples, and advanced features.
  • gRPC Quick Start: A guide to getting started with gRPC in various programming languages, providing a solid foundation in gRPC concepts and usage.
  • Protocol Buffers Documentation: Detailed documentation on protocol buffers (proto files), which are central to defining gRPC services and messages.

Was this helpful?