https://github.com/binance/binance-sbe-cpp-sample-app
Sample app in CPP that decodes Binance API SBE
https://github.com/binance/binance-sbe-cpp-sample-app
binance-api cpp crypto decoder sample-app sbe
Last synced: 12 months ago
JSON representation
Sample app in CPP that decodes Binance API SBE
- Host: GitHub
- URL: https://github.com/binance/binance-sbe-cpp-sample-app
- Owner: binance
- License: mit
- Created: 2023-11-27T09:49:00.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2024-10-03T06:48:06.000Z (over 1 year ago)
- Last Synced: 2025-04-15T01:13:42.537Z (12 months ago)
- Topics: binance-api, cpp, crypto, decoder, sample-app, sbe
- Language: C++
- Homepage:
- Size: 231 KB
- Stars: 9
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# C++ SBE Sample Application
This sample application is designed to decode responses from multiple endpoints, when using [Binance Spot API Simple Binary Encoding (SBE)](https://github.com/binance/binance-spot-api-docs/blob/master/faqs/sbe_faq.md):
- [`REST GET /api/v3/exchangeInfo`](#pipe-rest-exchangeinfo-sbe-response-into-sbe-sample-app)
- [`REST GET /api/v3/account`](#pipe-rest-account-sbe-response-into-sbe-sample-app)
- [`REST POST /api/v3/order`](#pipe-rest-new-order-sbe-response-into-sbe-sample-app)
- [`REST GET /api/v3/order`](#pipe-rest-query-order-info-sbe-response-into-sbe-sample-app)
- [`WebSocket exchangeInfo method`](#pipe-websocket-exchangeinfo-sbe-response-into-sbe-sample-app)
It decodes a payload from STDIN and prints it as JSON to STDOUT.
This sample application is currently supported on Linux and macOS.
## Getting Started
1. Clone the source code:
```shell
git clone git@github.com:binance/binance-sbe-cpp-sample-app.git
```
2. Navigate to the directory where the `main.cpp` file is located and use the following command to generate `sbe-sample-app`:
```shell
c++ -std=c++20 -Wextra -Wall -o sbe-sample-app ./main.cpp
```
## Usage
### Pipe REST ExchangeInfo SBE response into sbe-sample-app
The following command fetches the `exchangeInfo` SBE response from the REST API and has `sbe-sample-app` decode it and output it as JSON to STDOUT:
```shell
curl -X GET -H 'Accept: application/sbe' -H 'X-MBX-SBE: 1:0' \
'https://api.binance.com/api/v3/exchangeInfo' \
| ./sbe-sample-app
```
### Pipe REST Account SBE response into sbe-sample-app
The following commands fetch the `account` SBE response from the REST API and have `sbe-sample-app` decode it and output it as JSON to STDOUT:
#### HMAC keys
```shell
hmac_api_key=""; \
hmac_secret_key=""; \
url_sans_query="https://api.binance.com/api/v3/account"; \
query="timestamp=$(date +%s000)"; \
signature=$(echo -n "${query}" | openssl dgst -sha256 -hmac "${hmac_secret_key}"); \
signature=${signature#*= }; \
curl -X GET -H "X-MBX-APIKEY: ${hmac_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
#### RSA keys
```shell
rsa_api_key=""; \
rsa_secret_path=""; \
url_sans_query="https://api.binance.com/api/v3/account"; \
query="timestamp=$(date +%s000)"; \
signature=$(echo -n "${query}" | openssl dgst -sha256 -sign "${rsa_secret_path}" | openssl enc -base64 -A); \
signature=${signature#*= }; \
curl -X GET -H "X-MBX-APIKEY: ${rsa_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
#### ED25519 keys
```shell
ed25519_api_key=""; \
ed25519_secret_path=""; \
url_sans_query="https://api.binance.com/api/v3/account"; \
query="timestamp=$(date +%s000)"; \
echo -n "${query}" > to_be_signed.txt; \
signature=$(openssl pkeyutl -sign -inkey "${ed25519_secret_path}" -rawin -in to_be_signed.txt | openssl enc -base64 -A); \
signature=${signature#*= }; \
curl -X GET -H "X-MBX-APIKEY: ${ed25519_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
### Pipe REST New Order SBE response into sbe-sample-app
The following commands fetch the new `order` SBE response from the REST API when the `newOrderRespType` parameter is set to `RESULT` and have `sbe-sample-app` decode it and output it as JSON to STDOUT:
#### HMAC keys
```shell
hmac_api_key=""; \
hmac_secret_key=""; \
url_sans_query="https://api.binance.com/api/v3/order"; \
query="symbol=BNBUSDT&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=250&newOrderRespType=RESULT×tamp=$(date +%s000)"; \
signature=$(echo -n "${query}" | openssl dgst -sha256 -hmac "${hmac_secret_key}"); \
signature=${signature#*= }; \
curl -X POST -H "X-MBX-APIKEY: ${hmac_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
#### RSA keys
```shell
rsa_api_key=""; \
rsa_secret_path=""; \
url_sans_query="https://api.binance.com/api/v3/order"; \
query="symbol=BNBUSDT&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=250&newOrderRespType=RESULT×tamp=$(date +%s000)"; \
signature=$(echo -n "${query}" | openssl dgst -sha256 -sign "${rsa_secret_path}" | openssl enc -base64 -A); \
signature=${signature#*= }; \
curl -X POST -H "X-MBX-APIKEY: ${rsa_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
#### ED25519 keys
```shell
ed25519_api_key=""; \
ed25519_secret_path=""; \
url_sans_query="https://api.binance.com/api/v3/order"; \
query="symbol=BNBUSDT&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=250&newOrderRespType=RESULT×tamp=$(date +%s000)"; \
echo -n "${query}" > to_be_signed.txt; \
signature=$(openssl pkeyutl -sign -inkey "${ed25519_secret_path}" -rawin -in to_be_signed.txt | openssl enc -base64 -A); \
signature=${signature#*= }; \
curl -X POST -H "X-MBX-APIKEY: ${ed25519_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
### Pipe REST Query Order info SBE response into sbe-sample-app
The following commands fetch the `order` info SBE response from the REST API and have `sbe-sample-app` decode it and output it as JSON to STDOUT:
#### HMAC keys
```shell
hmac_api_key=""; \
hmac_secret_key=""; \
order_id=""; \
url_sans_query="https://api.binance.com/api/v3/order"; \
query="symbol=BNBUSDT&orderId=${order_id}×tamp=$(date +%s000)"; \
signature=$(echo -n "${query}" | openssl dgst -sha256 -hmac "${hmac_secret_key}"); \
signature=${signature#*= }; \
curl -X GET -H "X-MBX-APIKEY: ${hmac_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
#### RSA keys
```shell
rsa_api_key=""; \
rsa_secret_path=""; \
order_id=""; \
url_sans_query="https://api.binance.com/api/v3/order"; \
query="symbol=BNBUSDT&orderId=${order_id}×tamp=$(date +%s000)"; \
signature=$(echo -n "${query}" | openssl dgst -sha256 -sign "${rsa_secret_path}" | openssl enc -base64 -A); \
signature=${signature#*= }; \
curl -X GET -H "X-MBX-APIKEY: ${rsa_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
#### ED25519 keys
```shell
ed25519_api_key=""; \
ed25519_secret_path=""; \
order_id=""; \
url_sans_query="https://api.binance.com/api/v3/order"; \
query="symbol=BNBUSDT&orderId=${order_id}×tamp=$(date +%s000)"; \
echo -n "${query}" > to_be_signed.txt; \
signature=$(openssl pkeyutl -sign -inkey "${ed25519_secret_path}" -rawin -in to_be_signed.txt | openssl enc -base64 -A); \
signature=${signature#*= }; \
curl -X GET -H "X-MBX-APIKEY: ${ed25519_api_key}" -H "Accept: application/sbe" -H "X-MBX-SBE: 1:0" \
"${url_sans_query}?${query}&signature=${signature}" \
| ./sbe-sample-app
```
### Pipe WebSocket ExchangeInfo SBE response into sbe-sample-app
The following command fetches the `exchangeInfo` SBE response from the WebSocket API and has `sbe-sample-app` decode it and output it as JSON to STDOUT:
```shell
echo '{"id":"93fb61ef-89f8-4d6e-b022-4f035a3fadad","method":"exchangeInfo","params":{"symbol":"BTCUSDT"}}' \
| ./tools/websocket_send.py 'wss://ws-api.binance.com:443/ws-api/v3?responseFormat=sbe&sbeSchemaId=1&sbeSchemaVersion=0' \
| ./sbe-sample-app
```
### Notes
- The code in the `main.cpp` file, along with the accompanying header files, is designed specifically for decoding the responses from the `exchangeInfo`, `account`, and `order` endpoints.
- There are additional decoder classes in the `spot_sbe` folder that can be useful for decoding SBE responses from other endpoints in the Binance Spot API.
### Testnet
To use the Spot Testnet API, you only need to replace:
- `api.binance.com` with `testnet.binance.vision` for the REST API
- `ws-api.binance.com` with `testnet.binance.vision` for the WebSocket API
### Code formatting
The C++ code in this repository was formatted by running:
```shell
clang-format-15 -i --style '{BasedOnStyle: chromium, IndentWidth: 4, ColumnLimit: 100}' *.h *.cpp
```
## Updates
### C++ decoders
The `spot_sbe` directory contains code generated by [simple-binary-encoding](https://github.com/real-logic/simple-binary-encoding), which you will likely want to reuse verbatim. However, if you would like to update it, please navigate to the root of this project and follow these steps:
1) Download the schema file ([spot_prod_latest.xml](https://github.com/binance/binance-spot-api-docs/blob/master/sbe/schemas/spot_prod_latest.xml)):
```shell
curl -o spot_latest.xml https://raw.githubusercontent.com/binance/binance-spot-api-docs/master/sbe/schemas/$(curl -s https://raw.githubusercontent.com/binance/binance-spot-api-docs/master/sbe/schemas/spot_prod_latest.xml)
```
**Note:** If you are using the Spot Testnet API, replace `spot_prod_latest.xml` with `spot_testnet_latest.xml` in the above `curl ` command.
2) Clone & build [simple-binary-encoding](https://github.com/real-logic/simple-binary-encoding):
```shell
git clone https://github.com/real-logic/simple-binary-encoding.git --branch 1.30.0 \
&& cd simple-binary-encoding \
&& ./gradlew \
&& cd ..
```
3) Run the SBE tool code generator built in the previous step:
```shell
java \
-Dsbe.output.dir=. \
-Dsbe.target.language=Cpp \
-jar simple-binary-encoding/sbe-all/build/libs/sbe-all-1.30.0.jar \
spot_latest.xml
```