tokio_binance/client/account.rs
1use reqwest::{Url, Client};
2use crate::param::{
3 Parameters,
4 OrderType,
5 Side,
6 TimeInForce,
7 ID
8};
9use crate::builder::ParamBuilder;
10use crate::types::*;
11use crate::client::*;
12
13/// Client for dealing with orders
14#[derive(Clone)]
15pub struct AccountClient {
16 api_key: String,
17 secret_key: String,
18 url: Url,
19 client: Client
20}
21
22impl AccountClient {
23 /// Creates new client instance.
24 /// # Example
25 ///
26 /// ```no_run
27 /// use tokio_binance::{AccountClient, BINANCE_US_URL};
28 ///
29 /// #[tokio::main]
30 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
31 /// let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
32 /// Ok(())
33 /// }
34 /// ```
35 pub fn connect<A, S, U>(api_key: A, secret_key: S, url: U) -> crate::error::Result<Self>
36 where
37 A: Into<String>,
38 S: Into<String>,
39 U: Into<String>
40 {
41 Ok(Self {
42 api_key: api_key.into(),
43 secret_key: secret_key.into(),
44 url: url.into().parse::<Url>()?,
45 client: Client::new()
46 })
47 }
48 /// Place a new limit order.
49 /// # Example
50 ///
51 /// ```no_run
52 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
53 /// use tokio_binance::{Side::Sell, TimeInForce::Fok, OrderRespType::Full};
54 /// use serde_json::Value;
55 ///
56 /// # #[tokio::main]
57 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
58 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
59 /// let response = client
60 /// // false will send as test, true will send as a real order.
61 /// .place_limit_order("BNBUSDT", Sell, 20.00, 5.00, false)
62 /// // optional: lifetime of order; default is Gtc.
63 /// .with_time_in_force(Fok)
64 /// // optional: unique id; auto generated by default.
65 /// .with_new_client_order_id("<uuid>")
66 /// // optional: splits quantity; sets time in force to Gtc.
67 /// .with_iceberg_qty(1.00)
68 /// // optional: output verbosity; default is Ack.
69 /// .with_new_order_resp_type(Full)
70 /// // optional: converts Limit to Stop-Limit; triggers when price hits below 21.00.
71 /// .with_stop_loss_limit(21.00)
72 /// // optional: converts Limit to Stop-Limit; triggers when price hits above 21.00.
73 /// .with_take_profit_limit(21.00)
74 /// // optional: processing time for request; default is 5000, can't be above 60000.
75 /// .with_recv_window(8000)
76 /// // optional: converts Limit to Limit-Maker; consumes builder and returns a different one.
77 /// .into_limit_maker_order()
78 /// //
79 /// .json::<Value>()
80 /// .await?;
81 /// # Ok(())
82 /// # }
83 /// ```
84 pub fn place_limit_order<'a>(
85 &self, symbol: &'a str,
86 side: Side,
87 price: f64,
88 quantity: f64,
89 execute: bool
90 ) -> ParamBuilder<'a, '_, LimitOrderParams>{
91 let Self { ref api_key, ref secret_key, url, client } = self;
92
93 let url = if execute {
94 url.join("/api/v3/order").unwrap()
95 } else {
96 url.join("/api/v3/order/test").unwrap()
97 };
98
99 ParamBuilder::new(
100 Parameters {
101 symbol: Some(symbol),
102 side: Some(side),
103 order_type: Some(OrderType::Limit),
104 price: Some(price),
105 quantity: Some(quantity),
106 time_in_force: Some(TimeInForce::Gtc),
107 ..Parameters::default()
108 },
109 client.post(url),
110 Some(api_key),
111 Some(secret_key)
112 )
113 }
114 /// Place a new market order.
115 /// # Example
116 ///
117 /// ```no_run
118 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
119 /// use tokio_binance::{Side::Sell, TimeInForce::Fok, OrderRespType::Full};
120 /// use serde_json::Value;
121 ///
122 /// # #[tokio::main]
123 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
124 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
125 /// let response = client
126 /// // false will send as test, true will send as a real order.
127 /// .place_market_order("BNBUSDT", Sell, 5.00, false)
128 /// // optional: unique id; auto generated by default.
129 /// .with_new_client_order_id("<uuid>")
130 /// // optional: output verbosity; default is Ack.
131 /// .with_new_order_resp_type(Full)
132 /// // optional: converts Market to Stop-Loss; triggers when price hits below 21.00.
133 /// .with_stop_loss(21.00)
134 /// // optional: converts Market to Stop-Loss; triggers when price hits above 21.00.
135 /// .with_take_profit(21.00)
136 /// // optional: processing time for request; default is 5000, can't be above 60000.
137 /// .with_recv_window(8000)
138 /// //
139 /// .json::<Value>()
140 /// .await?;
141 /// # Ok(())
142 /// # }
143 /// ```
144 pub fn place_market_order<'a>(
145 &self, symbol: &'a str,
146 side: Side,
147 quantity: f64,
148 execute: bool
149 ) -> ParamBuilder<'a, '_, MarketOrderParams>{
150 let Self { ref api_key, ref secret_key, url, client } = self;
151
152 let url = if execute {
153 url.join("/api/v3/order").unwrap()
154 } else {
155 url.join("/api/v3/order/test").unwrap()
156 };
157
158 ParamBuilder::new(
159 Parameters {
160 symbol: Some(symbol),
161 side: Some(side),
162 order_type: Some(OrderType::Market),
163 quantity: Some(quantity),
164 ..Parameters::default()
165 },
166 client.post(url),
167 Some(api_key),
168 Some(secret_key)
169 )
170 }
171 /// Get order.
172 /// # Example
173 ///
174 /// ```no_run
175 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
176 /// use tokio_binance::ID;
177 /// use serde_json::Value;
178 ///
179 /// # #[tokio::main]
180 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
181 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
182 /// let response = client
183 /// .get_order("BNBUSDT", ID::ClientOId("<uuid>"))
184 /// // optional: processing time for request; default is 5000, can't be above 60000.
185 /// .with_recv_window(8000)
186 /// //
187 /// .json::<Value>()
188 /// .await?;
189 /// # Ok(())
190 /// # }
191 /// ```
192 pub fn get_order<'a>(&self, symbol: &'a str, id: ID<'a>) -> ParamBuilder<'a, '_, OrderStatusParams>{
193 let Self { ref api_key, ref secret_key, url, client } = self;
194
195 let url = url.join("/api/v3/order").unwrap();
196
197 let order_id = if let ID::OrderId(id) = id {
198 Some(id)
199 } else {
200 None
201 };
202
203 let orig_client_order_id = if let ID::ClientOId(id) = id {
204 Some(id)
205 } else {
206 None
207 };
208
209 ParamBuilder::new(
210 Parameters {
211 symbol: Some(symbol),
212 order_id,
213 orig_client_order_id,
214 ..Parameters::default()
215 },
216 client.get(url),
217 Some(api_key),
218 Some(secret_key)
219 )
220 }
221 /// Cancel order.
222 /// # Example
223 ///
224 /// ```no_run
225 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
226 /// use tokio_binance::ID;
227 /// use serde_json::Value;
228 ///
229 /// # #[tokio::main]
230 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
231 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
232 /// let response = client
233 /// .cancel_order("BNBUSDT", ID::ClientOId("<uuid>"))
234 /// // optional: unique id; auto generated by default.
235 /// .with_new_client_order_id("<uuid>")
236 /// // optional: processing time for request; default is 5000, can't be above 60000.
237 /// .with_recv_window(8000)
238 /// //
239 /// .json::<Value>()
240 /// .await?;
241 /// # Ok(())
242 /// # }
243 /// ```
244 pub fn cancel_order<'a>(&self, symbol: &'a str, id: ID<'a>) -> ParamBuilder<'a, '_, CancelOrderParams>{
245 let Self { ref api_key, ref secret_key, url, client } = self;
246
247 let url = url.join("/api/v3/order").unwrap();
248
249 let order_id = if let ID::OrderId(id) = id {
250 Some(id)
251 } else {
252 None
253 };
254
255 let orig_client_order_id = if let ID::ClientOId(id) = id {
256 Some(id)
257 } else {
258 None
259 };
260
261 ParamBuilder::new(
262 Parameters {
263 symbol: Some(symbol),
264 order_id,
265 orig_client_order_id,
266 ..Parameters::default()
267 },
268 client.delete(url),
269 Some(api_key),
270 Some(secret_key)
271 )
272 }
273 /// Get open orders.
274 /// # Example
275 ///
276 /// ```no_run
277 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
278 /// use serde_json::Value;
279 ///
280 /// # #[tokio::main]
281 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
282 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
283 /// let response = client
284 /// .get_open_orders()
285 /// // optional: filter by symbol; gets all symbols by default.
286 /// .with_symbol("BNBUSDT")
287 /// // optional: processing time for request; default is 5000, can't be above 60000.
288 /// .with_recv_window(8000)
289 /// //
290 /// .json::<Value>()
291 /// .await?;
292 /// # Ok(())
293 /// # }
294 /// ```
295 pub fn get_open_orders(&self) -> ParamBuilder<'_, '_, OpenOrderParams>{
296 let Self { ref api_key, ref secret_key, url, client } = self;
297
298 let url = url.join("/api/v3/openOrders").unwrap();
299
300 ParamBuilder::new(
301 Parameters::default(),
302 client.get(url),
303 Some(api_key),
304 Some(secret_key)
305 )
306 }
307 /// Get all orders.
308 /// # Example
309 ///
310 /// ```no_run
311 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
312 /// use chrono::{Utc, Duration};
313 /// use serde_json::Value;
314 ///
315 /// # #[tokio::main]
316 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
317 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
318 /// let end = Utc::now();
319 /// let start = end - Duration::hours(23);
320 ///
321 /// let response = client
322 /// .get_all_orders("BNBUSDT")
323 /// // optional: filter by orders greater than or equal to the provided id.
324 /// // If supplied, neither startTime or endTime can be provided
325 /// .with_order_id(1230494)
326 /// // optional: get orders from; pass 24 hours of orders is the default.
327 /// .with_start_time(start)
328 /// // optional: get orders until; default is now.
329 /// .with_end_time(end)
330 /// // optional: limit the amount of orders; default 500; max 1000.
331 /// .with_limit(100)
332 /// // optional: processing time for request; default is 5000, can't be above 60000.
333 /// .with_recv_window(8000)
334 /// //
335 /// .json::<Value>()
336 /// .await?;
337 /// # Ok(())
338 /// # }
339 /// ```
340 pub fn get_all_orders<'a>(&self, symbol: &'a str) -> ParamBuilder<'a, '_, AllOrdersParams>{
341 let Self { ref api_key, ref secret_key, url, client } = self;
342
343 let url = url.join("/api/v3/allOrders").unwrap();
344
345 ParamBuilder::new(
346 Parameters { symbol: Some(symbol), ..Parameters::default() },
347 client.get(url),
348 Some(api_key),
349 Some(secret_key)
350 )
351 }
352 /// Place a new oco order.
353 /// # Price Restrictions:
354 /// - SELL: Limit Price > Last Price > Stop Price
355 /// - BUY: Limit Price < Last Price < Stop Price
356 /// # Example
357 ///
358 /// ```no_run
359 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
360 /// use tokio_binance::{Side::Sell, TimeInForce::Gtc, OrderRespType::Full};
361 /// use serde_json::Value;
362 ///
363 /// # #[tokio::main]
364 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
365 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
366 /// let response = client
367 /// // Limit to sell at 30.00 and Stop-Loss at 20.00; One cancels the other.
368 /// .place_oco_order("BNBUSDT", Sell, 30.00, 20.00, 5.00)
369 /// // optional: A unique Id for the entire orderList; auto generated by default.
370 /// .with_list_client_order_id("<uuid>")
371 /// // optional: A unique Id for the limit order; auto generated by default.
372 /// .with_limit_client_order_id("<uuid>")
373 /// // optional: splits quantity for the limit order leg;
374 /// .with_limit_iceberg_qty(1.00)
375 /// // optional: A unique Id for the stop loss/stop loss limit leg; auto generated by default.
376 /// .with_stop_client_order_id("<uuid>")
377 /// // optional: Converts Stop-Loss to Stop-Limit; triggers bellow 20.00.
378 /// .with_stop_limit_price(19.00, Gtc)
379 /// // optional: splits quantity for the stop order leg;
380 /// .with_stop_iceberg_qty(1.00)
381 /// // optional: output verbosity; default is Ack.
382 /// .with_new_order_resp_type(Full)
383 /// // optional: processing time for request; default is 5000, can't be above 60000.
384 /// .with_recv_window(8000)
385 /// //
386 /// .json::<Value>()
387 /// .await?;
388 /// # Ok(())
389 /// # }
390 /// ```
391 pub fn place_oco_order<'a>(
392 &self, symbol: &'a str,
393 side: Side,
394 price: f64,
395 stop_price: f64,
396 quantity: f64,
397 ) -> ParamBuilder<'a, '_, OcoParams>{
398 let Self { ref api_key, ref secret_key, url, client } = self;
399
400 let url = url.join("/api/v3/order/oco").unwrap();
401
402 ParamBuilder::new(
403 Parameters {
404 symbol: Some(symbol),
405 side: Some(side),
406 price: Some(price),
407 stop_price: Some(stop_price),
408 quantity: Some(quantity),
409 ..Parameters::default()
410 },
411 client.post(url),
412 Some(api_key),
413 Some(secret_key)
414 )
415 }
416 /// Cancel oco order.
417 /// # Example
418 ///
419 /// ```no_run
420 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
421 /// use tokio_binance::ID;
422 /// use serde_json::Value;
423 ///
424 /// # #[tokio::main]
425 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
426 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
427 /// let response = client
428 /// .cancel_oco_order("BNBUSDT", ID::ClientOId("<uuid>"))
429 /// // optional: unique id; auto generated by default.
430 /// .with_new_client_order_id("<uuid>")
431 /// // optional: processing time for request; default is 5000, can't be above 60000.
432 /// .with_recv_window(8000)
433 /// //
434 /// .json::<Value>()
435 /// .await?;
436 /// # Ok(())
437 /// # }
438 /// ```
439 pub fn cancel_oco_order<'a>(&self, symbol: &'a str, id: ID<'a>) -> ParamBuilder<'a, '_, CancelOcoParams>{
440 let Self { ref api_key, ref secret_key, url, client } = self;
441
442 let url = url.join("/api/v3/orderList").unwrap();
443
444 let order_list_id = if let ID::OrderId(id) = id {
445 Some(id)
446 } else {
447 None
448 };
449
450 let list_client_order_id = if let ID::ClientOId(id) = id {
451 Some(id)
452 } else {
453 None
454 };
455
456 ParamBuilder::new(
457 Parameters {
458 symbol: Some(symbol),
459 order_list_id,
460 list_client_order_id,
461 ..Parameters::default()
462 },
463 client.delete(url),
464 Some(api_key),
465 Some(secret_key)
466 )
467 }
468 /// Get oco order.
469 /// # Example
470 ///
471 /// ```no_run
472 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
473 /// use tokio_binance::ID;
474 /// use serde_json::Value;
475 ///
476 /// # #[tokio::main]
477 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
478 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
479 /// let response = client
480 /// .get_oco_order(ID::ClientOId("<uuid>"))
481 /// // optional: processing time for request; default is 5000, can't be above 60000.
482 /// .with_recv_window(8000)
483 /// //
484 /// .json::<Value>()
485 /// .await?;
486 /// # Ok(())
487 /// # }
488 /// ```
489 pub fn get_oco_order<'a>(&self, id: ID<'a>) -> ParamBuilder<'a, '_, OcoStatusParams>{
490 let Self { ref api_key, ref secret_key, url, client } = self;
491
492 let url = url.join("/api/v3/orderList").unwrap();
493
494 let order_list_id = if let ID::OrderId(id) = id {
495 Some(id)
496 } else {
497 None
498 };
499
500 let orig_client_order_id = if let ID::ClientOId(id) = id {
501 Some(id)
502 } else {
503 None
504 };
505
506 ParamBuilder::new(
507 Parameters {
508 order_list_id,
509 orig_client_order_id,
510 ..Parameters::default()
511 },
512 client.get(url),
513 Some(api_key),
514 Some(secret_key)
515 )
516 }
517 /// Get all oco orders.
518 /// # Example
519 ///
520 /// ```no_run
521 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
522 /// use chrono::{Utc, Duration};
523 /// use serde_json::Value;
524 ///
525 /// # #[tokio::main]
526 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
527 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
528 /// let end = Utc::now();
529 /// let start = end - Duration::hours(23);
530 ///
531 /// let response = client
532 /// .get_all_oco_orders()
533 /// // optional: filter by orders greater than or equal to the provided id.
534 /// // If supplied, neither startTime or endTime can be provided
535 /// .with_from_id(1230494)
536 /// // optional: get orders from; pass 24 hours of orders is the default.
537 /// .with_start_time(start)
538 /// // optional: get orders until; default is now.
539 /// .with_end_time(end)
540 /// // optional: limit the amount of orders; default 500; max 1000.
541 /// .with_limit(100)
542 /// // optional: processing time for request; default is 5000, can't be above 60000.
543 /// .with_recv_window(8000)
544 /// //
545 /// .json::<Value>()
546 /// .await?;
547 /// # Ok(())
548 /// # }
549 /// ```
550 pub fn get_all_oco_orders(&self) -> ParamBuilder<'_, '_, AllOcoParams>{
551 let Self { ref api_key, ref secret_key, url, client } = self;
552
553 let url = url.join("/api/v3/allOrderList").unwrap();
554
555 ParamBuilder::new(
556 Parameters::default(),
557 client.get(url),
558 Some(api_key),
559 Some(secret_key)
560 )
561 }
562 /// Get open oco orders.
563 /// # Example
564 ///
565 /// ```no_run
566 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
567 /// use serde_json::Value;
568 ///
569 /// # #[tokio::main]
570 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
571 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
572 /// let response = client
573 /// .get_open_oco_orders()
574 /// // optional: processing time for request; default is 5000, can't be above 60000.
575 /// .with_recv_window(8000)
576 /// //
577 /// .json::<Value>()
578 /// .await?;
579 /// # Ok(())
580 /// # }
581 /// ```
582 pub fn get_open_oco_orders(&self) -> ParamBuilder<'_, '_, OpenOcoParams>{
583 let Self { ref api_key, ref secret_key, url, client } = self;
584
585 let url = url.join("/api/v3/openOrderList").unwrap();
586
587 ParamBuilder::new(
588 Parameters::default(),
589 client.get(url),
590 Some(api_key),
591 Some(secret_key)
592 )
593 }
594 /// Get current account information.
595 /// # Example
596 ///
597 /// ```no_run
598 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
599 /// use serde_json::Value;
600 ///
601 /// # #[tokio::main]
602 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
603 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
604 /// let response = client
605 /// .get_account()
606 /// // optional: processing time for request; default is 5000, can't be above 60000.
607 /// .with_recv_window(8000)
608 /// //
609 /// .json::<Value>()
610 /// .await?;
611 /// # Ok(())
612 /// # }
613 /// ```
614 pub fn get_account(&self) -> ParamBuilder<'_, '_, AccountParams>{
615 let Self { ref api_key, ref secret_key, url, client } = self;
616
617 let url = url.join("/api/v3/account").unwrap();
618
619 ParamBuilder::new(
620 Parameters::default(),
621 client.get(url),
622 Some(api_key),
623 Some(secret_key)
624 )
625 }
626 /// Get trades for a specific account and symbol.
627 /// # Example
628 ///
629 /// ```no_run
630 /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
631 /// use chrono::{Utc, Duration};
632 /// use serde_json::Value;
633 ///
634 /// # #[tokio::main]
635 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
636 /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
637 /// let end = Utc::now();
638 /// let start = end - Duration::hours(23);
639 ///
640 /// let response = client
641 /// .get_account_trades("BNBUSDT")
642 /// // optional: filter by orders greater than or equal to the provided id.
643 /// // If supplied, neither startTime or endTime can be provided
644 /// .with_from_id(1230494)
645 /// // optional: get orders from; pass 24 hours of orders is the default.
646 /// .with_start_time(start)
647 /// // optional: get orders until; default is now.
648 /// .with_end_time(end)
649 /// // optional: limit the amount of orders; default 500; max 1000.
650 /// .with_limit(100)
651 /// // optional: processing time for request; default is 5000, can't be above 60000.
652 /// .with_recv_window(8000)
653 /// //
654 /// .json::<Value>()
655 /// .await?;
656 /// # Ok(())
657 /// # }
658 /// ```
659 pub fn get_account_trades<'a>(&self, symbol: &'a str) -> ParamBuilder<'a, '_, AccountTradesParams>{
660 let Self { ref api_key, ref secret_key, url, client } = self;
661
662 let url = url.join("/api/v3/myTrades").unwrap();
663
664 ParamBuilder::new(
665 Parameters { symbol: Some(symbol), ..Parameters::default() },
666 client.get(url),
667 Some(api_key),
668 Some(secret_key)
669 )
670 }
671 /// Helper method for getting a withdraw client instance.
672 pub fn to_withdraw_client(&self) -> WithdrawalClient {
673 WithdrawalClient {
674 api_key: self.api_key.clone(),
675 secret_key: self.secret_key.clone(),
676 url: self.url.clone(),
677 client: self.client.clone()
678 }
679 }
680 /// Helper method for getting a market client instance.
681 pub fn to_market_data_client(&self) -> MarketDataClient {
682 MarketDataClient {
683 api_key: self.api_key.clone(),
684 url: self.url.clone(),
685 client: self.client.clone()
686 }
687 }
688 /// Helper method for getting a general client instance.
689 pub fn to_general_client(&self) -> GeneralClient {
690 GeneralClient { url: self.url.clone(), client: self.client.clone() }
691 }
692
693}