binance_api/
endpoints.rs

1//! All endpoints for HTTP requests.
2pub(crate) use reqwest::Method as HttpVerb;
3
4/// Fully describes the HTTP endpoint:
5///
6/// - path;
7/// - HTTP method (verb);
8/// - weight (how much API limits will be affected by the query);
9/// - additional security to access the endpoint.
10pub trait Endpoint {
11    /// The HTTP path for the given request.
12    fn as_endpoint(&self) -> String;
13
14    /// HTTP method (verb) used to access the endpoint. The most common are:
15    ///
16    /// - GET
17    /// - POST
18    /// - PUT
19    /// - DELETE
20    fn http_verb(&self) -> HttpVerb;
21
22    /// The API weight regarding [IP limits](https://binance-docs.github.io/apidocs/spot/en/#ip-limits)
23    /// for the given request.
24    ///
25    /// Endpoints share the 1200 per minute limit based on IP.
26    ///
27    /// Responses contain the header `X-MBX-USED-WEIGHT-(intervalNum)(intervalLetter)`,
28    /// defining the weight used by the current IP.
29    fn ip_weight(&self) -> Option<u16>;
30
31    /// The API weight regarding [UID (account) limits](https://binance-docs.github.io/apidocs/spot/en/#order-rate-limits)
32    /// for the given request.
33    ///
34    /// The order rate limit is counted against each account.
35    ///
36    /// Successful order responses contain the header `X-MBX-ORDER-COUNT-(intervalNum)(intervalLetter)`,
37    /// defining the order limit used by the UID.
38    ///
39    /// To monitor order count usage, refer to `GET api/v3/rateLimit/order`.
40    fn order_weight(&self) -> Option<u16>;
41
42    /// Determines access to the endpoint.
43    fn security_type(&self) -> SecurityType;
44}
45
46#[derive(Debug, Copy, Clone)]
47/// Each endpoint has a security type that determines how you will interact with it.
48///
49/// - API-keys are passed into the Rest API via the `X-MBX-APIKEY` header.
50/// - API-keys and secret-keys are case sensitive.
51/// - API-keys can be configured to only access certain types of secure endpoints.
52///   For example, one API-key could be used for [TRADE][Self::Trade] only,
53///   while another API-key can access everything except for [TRADE][Self::Trade] routes.
54/// - By default, API-keys can access all secure routes.
55///
56/// More on it: <https://binance-docs.github.io/apidocs/spot/en/#endpoint-security-type>
57pub enum SecurityType {
58    /// Those endpoints include:
59    ///
60    /// - general info about exchange;
61    /// - recent market data.
62    ///
63    /// Endpoints can be accessed freely.
64    ///
65    /// Usually accessed via the `GET` (idempotent and not able to change server state).
66    ///
67    /// Those endpoints can be found at:
68    ///
69    /// - [spot](https://binance-docs.github.io/apidocs/spot/en/#market-data-endpoints);
70    /// - [futures](https://binance-docs.github.io/apidocs/futures/en/#market-data-endpoints).
71    None,
72
73    /// Query of historical market data.
74    ///
75    /// Can be accessed with the API-key.
76    ///
77    /// Usually accessed via the `GET` (idempotent and not able to change server state).
78    MarketData,
79
80    /// Management of Websocket streams to receive any account updates.
81    ///
82    /// Those endpoints can be found at:
83    ///
84    /// - [spot and margin](https://binance-docs.github.io/apidocs/spot/en/#user-data-streams);
85    /// - [futures](https://binance-docs.github.io/apidocs/futures/en/#user-data-streams).
86    UserStream,
87
88    /// The endpoints changing the actual trading status of an account:
89    ///
90    /// - placing a new order (usually `POST`);
91    /// - cancelling an active order (usually `DELETE`);
92    /// - requesting the order count usage (usually `GET`).
93    ///
94    /// Can only be accessed with the API-key and signed with the secret key.
95    ///
96    /// Those endpoints can be found at:
97    ///
98    /// - [spot](https://binance-docs.github.io/apidocs/spot/en/#spot-account-trade);
99    /// - [futures](https://binance-docs.github.io/apidocs/futures/en/#account-trades-endpoints);
100    /// - [margin](https://binance-docs.github.io/apidocs/spot/en/#margin-account-trade).
101    Trade,
102
103    /// Query User data.
104    ///
105    /// Can only be accessed with the API-key and signed with the secret key.
106    ///
107    /// Usually accessed via the `GET` (idempotent and not able to change server state).
108    ///
109    /// Those endpoints can be found at:
110    ///
111    /// - [spot](https://binance-docs.github.io/apidocs/spot/en/#spot-account-trade);
112    /// - [futures](https://binance-docs.github.io/apidocs/futures/en/#account-trades-endpoints);
113    /// - [margin](https://binance-docs.github.io/apidocs/spot/en/#margin-account-trade).
114    UserData,
115
116    /// Account action associated with transferring of funds on Margin trading.
117    ///
118    /// Can only be accessed with the API-key and signed with the secret key.
119    ///
120    /// Those endpoints can be found at:
121    /// - [margin](https://binance-docs.github.io/apidocs/spot/en/#margin-account-trade).
122    Margin,
123}
124
125impl SecurityType {
126    /// Endpoint requires sending a valid API-Key.
127    pub fn is_key_required(self) -> bool {
128        match self {
129            Self::None => false,
130            Self::MarketData | Self::UserStream | Self::Trade | Self::UserData | Self::Margin => {
131                true
132            }
133        }
134    }
135
136    /// Endpoint requires sending a valid API-Key and signature.
137    ///
138    /// - Signed endpoints require an additional parameter, `signature`,
139    ///   to be sent in the query string or request body.
140    /// - Endpoints use HMAC SHA256 signatures. The HMAC SHA256 signature is a keyed HMAC SHA256 operation.
141    /// - Use your `secretKey` as the key and `totalParams` as the value for the HMAC operation.
142    /// - The signature is **not case sensitive**.
143    /// - `totalParams` is defined as the query string concatenated with the request body.
144    ///
145    /// ### Timing security
146    ///
147    /// - A signed endpoint also requires a parameter, `timestamp`,
148    ///   to be sent which should be the millisecond timestamp of when
149    ///   the request was created and sent.
150    /// - An additional parameter, `recvWindow`, may be sent to specify the number of milliseconds
151    ///   after timestamp the request is valid for. If `recvWindow` is not sent, it defaults to 5000.
152    ///
153    ///   The logic is as follows:
154    ///
155    ///   ```no-compile
156    ///   if timestamp < (server_time + 1000) &&
157    ///     (server_time - timestamp) <= recv_window {
158    ///     // process request
159    ///   }
160    ///   else {
161    ///     // reject request
162    ///   }
163    ///   ```
164    ///
165    /// **Serious trading is about timing.** Networks can be unstable and unreliable,
166    /// which can lead to requests taking varying amounts of time to reach the servers.
167    /// With `recvWindow`, you can specify that the request must be processed within
168    /// a certain number of milliseconds or be rejected by the server.
169    /// It is recommended to use a small `recvWindow` of `5000` or less!
170    /// The max cannot go beyond `60,000`!
171    pub fn is_signature_required(self) -> bool {
172        match self {
173            Self::None => false,
174            Self::MarketData | Self::UserStream => false,
175            Self::Trade | Self::UserData | Self::Margin => true,
176        }
177    }
178
179    pub fn http_method_hint(self) -> Option<HttpVerb> {
180        match self {
181            // idempotent and not able to change server state
182            Self::None | Self::MarketData | Self::UserData => Some(HttpVerb::GET),
183            Self::UserStream | Self::Trade | Self::Margin => None,
184        }
185    }
186}