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}