# Binance Spot Rest
[](LICENSE.md)
[](https://hex.pm/packages/binance_spot_rest)
[](https://hexdocs.pm/binance_spot_rest)
Elixir library for interacting with the **Binance Spot REST API**.
Provides a unified entry point for building, validating, signing, and executing REST requests.
## Features
* **Up-to-date with Binance Spot REST API** — Implements all current Spot endpoints according to [official docs](https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md).
* **Polymorphic query struct interface** — Every endpoint is represented by a query struct. Whether it has parameters or not, you always call `BinanceSpotRest.request/1`.
* **Built-in validation** — Queries with parameters are validated before sending, preventing mistakes and unnecessary API calls.
* **Enum helpers** — Use provided Enums to safely build queries consistently.
* **Testable and mockable** — Easily override execution, base URL, timestamps, or signature functions for testing without hitting Binance servers.
- Built on top of [`Req`](https://hex.pm/packages/req) and [`Decimal`](https://hex.pm/packages/decimal)
- Uses [`Valpa`](https://hex.pm/packages/valpa), [`Loe`](https://hex.pm/packages/loe), and [`Numa`](https://hex.pm/packages/numa) internally for validation and composition
## Installation
Add to your `mix.exs`:
```elixir
def deps do
[
{:binance_spot_rest, "~> 0.1.0"}
]
end
```
Then fetch deps:
```bash
mix deps.get
```
## Configuration
The library reads credentials from your application configuration under `:binance_spot_rest`.
### Direct configuration
```elixir
import Config
config :binance_spot_rest,
base_url: "https://testnet.binance.vision", # or "https://api.binance.com" for production
api_key: "your_api_key",
secret_key: "your_secret_key"
```
> **Security tip:** Do not commit real API keys to your repository.
### Environment variables (optional, recommended)
```elixir
import Config
config :binance_spot_rest,
base_url: System.get_env("BINANCE_SPOT_REST_BASE_URL"),
api_key: System.get_env("BINANCE_SPOT_REST_API_KEY"),
secret_key: System.get_env("BINANCE_SPOT_REST_SECRET_KEY")
```
Then set your credentials in your environment:
```bash
# Linux/macOS
export BINANCE_SPOT_REST_API_KEY="your_real_api_key"
export BINANCE_SPOT_REST_SECRET_KEY="your_real_secret_key"
export BINANCE_SPOT_REST_BASE_URL="https://api.binance.com" # optional
# Windows (PowerShell)
setx BINANCE_SPOT_REST_API_KEY "your_real_api_key"
setx BINANCE_SPOT_REST_SECRET_KEY "your_real_secret_key"
setx BINANCE_SPOT_REST_BASE_URL "https://api.binance.com"
```
This keeps credentials out of code and version control.
## Usage
### High-level API
All endpoints are represented as **query structs**. You call them the same way, regardless of whether they have parameters:
```elixir
# Parameterized query
alias BinanceSpotRest.Endpoints.Trading.OrderPost.LimitQuery
query = %LimitQuery{
symbol: "LTCBTC",
side: BinanceSpotRest.Enums.Side._BUY(),
type: BinanceSpotRest.Enums.OrderType._LIMIT(),
timeInForce: BinanceSpotRest.Enums.TimeInForce._GTC(),
quantity: Decimal.new("1.0"),
price: Decimal.new("0.00029")
}
{:ok, result} = BinanceSpotRest.request(query)
# Empty query (e.g., ping or time endpoints)
query = %BinanceSpotRest.Endpoints.General.Time.Query{}
{:ok, result} = BinanceSpotRest.request(query)
```
Override behavior for testing:
```elixir
BinanceSpotRest.request(query,
execute: false,
base_url: "https://mock.url",
timestamp_fn: fn -> 1_740_000_000_000 end,
signature_fn: fn _qs, _key -> "mock-signature" end
)
```
> **Tip for testing:** Use `execute: false` and a mock `signature_fn` to run tests without hitting Binance.
### Low-level API (optional)
You can chain internal steps manually:
```elixir
import Loe
alias BinanceSpotRest.Endpoints.Trading.OrderPost.LimitQuery
query = %LimitQuery{...}
query
~>> BinanceSpotRest.Query.validate()
~>> BinanceSpotRest.Query.prepare()
~>> BinanceSpotRest.Client.create_request()
~>> BinanceSpotRest.Client.make_request()
```
With overrides:
```elixir
query
~>> BinanceSpotRest.Query.prepare()
~>> BinanceSpotRest.Client.create_request(
base_url: "https://mock.url",
headers: [{"FAKE_API_KEY", "fake_api_key"}],
timestamp_fn: fn -> 1_740_000_000_000 end,
signature_fn: fn _qs, _key -> "mock-signature" end
)
```
## Endpoint Queries
Each endpoint has its own query struct module:
```
BinanceSpotRest.Endpoints.<Category>.<EndpointPath>.<QueryModule>
```
Examples:
* `/api/v3/ticker/bookTicker` (`GET`) → `BinanceSpotRest.Endpoints.MarketData.TickerBookTicker`
* `/api/v3/order/amend/keepPriority` (`PUT`) → `BinanceSpotRest.Endpoints.Trading.OrderAmendKeepPriorityPut`
## Development / Updating
This library aims to stay aligned with the **official Binance Spot REST API**.
1. **Monitor official docs:** [Binance REST API](https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md)
2. **Compare endpoints:** Look for new endpoints, changed parameters, or removed endpoints.
3. **Update query structs:** Add new endpoints or adjust parameters/validation using `Valpa`.
4. **Update enums:** Adjust Enum modules to reflect new or changed values.
5. **Test thoroughly:** Use the testnet to verify requests and responses.
6. **Document version:** Optionally indicate the library version or date it is synced with Binance API.
> **Tip for contributors:** Each PR updating endpoints should reference the official API section it implements or fixes.
## Adding a New Endpoint
Contributors can add new endpoints by creating a query struct under the proper module namespace.
The library is designed to be polymorphic — any query struct works with `BinanceSpotRest.request/1`.
Please refer to existing endpoint modules for examples.
## Documentation
Full docs: [HexDocs](https://hexdocs.pm/binance_spot_rest)
## Contributing
Contributions are welcome via issues or pull requests.
Created and maintained by [Centib](https://github.com/Centib).
## License
Released under the [MIT License](LICENSE.md)