1use crate::response_types::{BuySell, LedgerEntryType, OrderFlag, OrderType};
4use rust_decimal::Decimal;
5use serde::{Deserialize, Serialize};
6use serde_with::formats::CommaSeparator;
7use serde_with::StringWithSeparator;
8use serde_with::{serde_as, skip_serializing_none};
9use simple_builder::Builder;
10use std::fmt::{Display, Formatter};
11use to_query_params::{QueryParams, ToQueryParams};
12
13#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
15#[serde(untagged)]
16pub enum IntOrString {
17 Int(i64),
18 String(String),
19}
20
21impl From<i64> for IntOrString {
22 fn from(value: i64) -> Self {
23 IntOrString::Int(value)
24 }
25}
26
27impl From<&str> for IntOrString {
28 fn from(value: &str) -> Self {
29 IntOrString::String(value.to_string())
30 }
31}
32
33impl From<String> for IntOrString {
34 fn from(value: String) -> Self {
35 IntOrString::String(value)
36 }
37}
38
39impl Display for IntOrString {
40 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
41 match self {
42 IntOrString::Int(i) => write!(f, "{i}"),
43 IntOrString::String(s) => write!(f, "{s}"),
44 }
45 }
46}
47
48#[derive(Debug, Clone, PartialEq, Eq)]
50pub enum CloseTime {
51 Open,
52 Close,
53 Both,
54}
55
56impl Display for CloseTime {
57 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
58 match self {
59 CloseTime::Open => write!(f, "open"),
60 CloseTime::Close => write!(f, "close"),
61 CloseTime::Both => write!(f, "both"),
62 }
63 }
64}
65
66#[derive(Debug, Clone, PartialEq, Eq)]
70pub enum AssetPairInfo {
71 Info,
72 Leverage,
73 Fees,
74 Margin,
75}
76
77impl Display for AssetPairInfo {
78 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
79 match self {
80 AssetPairInfo::Info => write!(f, "info"),
81 AssetPairInfo::Leverage => write!(f, "leverage"),
82 AssetPairInfo::Fees => write!(f, "fees"),
83 AssetPairInfo::Margin => write!(f, "margin"),
84 }
85 }
86}
87
88#[derive(Debug, Clone, PartialEq, Eq)]
90pub enum CandlestickInterval {
91 Minute,
92 Minutes5,
93 Minutes15,
94 Minutes30,
95 Hour,
96 Hours4,
97 Day,
98 Week,
99 Days15,
100}
101
102impl Display for CandlestickInterval {
103 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
104 match self {
105 CandlestickInterval::Minute => write!(f, "1"),
106 CandlestickInterval::Minutes5 => write!(f, "5"),
107 CandlestickInterval::Minutes15 => write!(f, "15"),
108 CandlestickInterval::Minutes30 => write!(f, "30"),
109 CandlestickInterval::Hour => write!(f, "60"),
110 CandlestickInterval::Hours4 => write!(f, "240"),
111 CandlestickInterval::Day => write!(f, "1440"),
112 CandlestickInterval::Week => write!(f, "10080"),
113 CandlestickInterval::Days15 => write!(f, "21600"),
114 }
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq)]
120pub enum TradeType {
121 All,
122 AnyPosition,
123 ClosedPosition,
124 ClosingPosition,
125 NoPosition,
126}
127
128impl Display for TradeType {
129 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130 match self {
131 TradeType::All => write!(f, "all"),
132 TradeType::AnyPosition => write!(f, "any position"),
133 TradeType::ClosedPosition => write!(f, "closed position"),
134 TradeType::ClosingPosition => write!(f, "closing position"),
135 TradeType::NoPosition => write!(f, "no position"),
136 }
137 }
138}
139
140#[derive(Debug, Clone, PartialEq, Eq)]
142pub struct OrderFlags(Vec<OrderFlag>);
143
144impl OrderFlags {
145 pub fn new(order_flags: Vec<OrderFlag>) -> OrderFlags {
146 OrderFlags(order_flags)
147 }
148}
149
150impl From<OrderFlag> for OrderFlags {
151 fn from(value: OrderFlag) -> Self {
152 OrderFlags::new(vec![value])
153 }
154}
155
156impl Display for OrderFlags {
157 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
158 let strings: Vec<String> = self.0.iter().map(|flag| flag.to_string()).collect();
159 write!(f, "{}", strings.join(","))
160 }
161}
162
163#[derive(Debug, Clone, PartialEq)]
165pub enum ReportType {
166 Trades,
167 Ledgers,
168}
169
170impl Display for ReportType {
171 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
172 match self {
173 ReportType::Trades => write!(f, "trades"),
174 ReportType::Ledgers => write!(f, "ledgers"),
175 }
176 }
177}
178
179#[derive(Debug, Clone, PartialEq)]
181pub enum ReportFormatType {
182 Csv,
183 Tsv,
184}
185
186impl Display for ReportFormatType {
187 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
188 match self {
189 ReportFormatType::Csv => write!(f, "CSV"),
190 ReportFormatType::Tsv => write!(f, "TSV"),
191 }
192 }
193}
194
195#[derive(Debug, Clone, PartialEq)]
197pub enum DeleteExportType {
198 Cancel,
199 Delete,
200}
201
202impl Display for DeleteExportType {
203 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
204 match self {
205 DeleteExportType::Cancel => write!(f, "cancel"),
206 DeleteExportType::Delete => write!(f, "delete"),
207 }
208 }
209}
210
211#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
216#[serde(rename_all = "lowercase")]
217pub enum TriggerType {
218 Index,
219 Last,
220}
221
222impl Display for TriggerType {
223 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
224 match self {
225 TriggerType::Index => write!(f, "index"),
226 TriggerType::Last => write!(f, "last"),
227 }
228 }
229}
230
231#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
233#[serde(rename_all = "snake_case")]
234pub enum SelfTradePrevention {
235 CancelNewest,
236 CancelOldest,
237 CancelBoth,
238}
239
240impl Display for SelfTradePrevention {
241 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
242 match self {
243 SelfTradePrevention::CancelNewest => write!(f, "cancel_newest"),
244 SelfTradePrevention::CancelOldest => write!(f, "cancel_oldest"),
245 SelfTradePrevention::CancelBoth => write!(f, "cancel_both"),
246 }
247 }
248}
249
250#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
256pub enum TimeInForce {
257 GTC,
258 IOC,
259 GTD,
260}
261
262#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
268#[serde(rename_all = "lowercase")]
269pub enum TimeInForceV2 {
270 GTC,
271 IOC,
272 GTD,
273}
274
275impl Display for TimeInForce {
276 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
277 match self {
278 TimeInForce::GTC => write!(f, "GTC"),
279 TimeInForce::IOC => write!(f, "IOC"),
280 TimeInForce::GTD => write!(f, "GTD"),
281 }
282 }
283}
284
285#[derive(Debug, Clone, Copy, Eq, PartialEq)]
287pub enum LockType {
288 Flex,
289 Bonded,
290 Timed,
291 Instant,
292}
293
294impl Display for LockType {
295 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
296 match self {
297 LockType::Flex => write!(f, "flex"),
298 LockType::Bonded => write!(f, "bonded"),
299 LockType::Timed => write!(f, "timed"),
300 LockType::Instant => write!(f, "instant"),
301 }
302 }
303}
304
305#[derive(Debug, Clone, PartialEq, Deserialize)]
307pub struct StringCSV(pub Vec<String>);
308
309impl StringCSV {
310 pub fn new(strings: Vec<String>) -> StringCSV {
311 StringCSV(strings)
312 }
313}
314
315impl From<&str> for StringCSV {
316 fn from(value: &str) -> Self {
317 StringCSV::new(vec![value.to_string()])
318 }
319}
320
321impl From<String> for StringCSV {
322 fn from(value: String) -> Self {
323 StringCSV::new(vec![value])
324 }
325}
326
327impl From<&String> for StringCSV {
328 fn from(value: &String) -> Self {
329 StringCSV::new(vec![value.clone()])
330 }
331}
332
333impl Display for StringCSV {
334 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
335 write!(f, "{}", self.0.join(","))
336 }
337}
338
339#[derive(Debug, Clone, QueryParams, Builder)]
343pub struct AssetInfoRequest {
344 pub asset: Option<StringCSV>,
345 #[query(rename = "aclass")]
346 pub asset_class: Option<String>,
347}
348
349#[derive(Debug, Clone, QueryParams, Builder)]
353pub struct TradableAssetPairsRequest {
354 pub pair: Option<StringCSV>,
355 pub info: Option<AssetPairInfo>,
356 pub country_code: Option<String>,
357}
358
359#[derive(Debug, Clone, QueryParams, Builder)]
363pub struct TickerRequest {
364 pub pair: Option<StringCSV>,
365}
366
367#[derive(Debug, Clone, QueryParams, Builder)]
370pub struct OHLCRequest {
371 #[query(required)]
372 #[builder(required)]
373 pub pair: String,
374 pub interval: Option<CandlestickInterval>,
375 pub since: Option<i64>,
376}
377
378#[derive(Debug, Clone, QueryParams, Builder)]
381pub struct OrderbookRequest {
382 #[query(required)]
383 #[builder(required)]
384 pub pair: String,
385 pub count: Option<i64>,
386}
387
388#[derive(Debug, Clone, QueryParams, Builder)]
395pub struct RecentTradesRequest {
396 #[query(required)]
397 #[builder(required)]
398 pub pair: String,
399 pub since: Option<String>,
400 pub count: Option<i64>,
401}
402
403#[derive(Debug, Clone, QueryParams, Builder)]
406pub struct RecentSpreadsRequest {
407 #[query(required)]
408 #[builder(required)]
409 pub pair: String,
410 pub since: Option<i64>,
411}
412
413#[derive(Debug, Clone, QueryParams, Builder)]
415pub struct TradeBalanceRequest {
416 pub asset: Option<String>,
417}
418
419#[derive(Debug, Clone, QueryParams, Builder)]
424pub struct OpenOrdersRequest {
425 pub trades: Option<bool>,
426 pub userref: Option<i64>,
427 #[query(rename = "cl_ord_id")]
428 pub client_order_id: Option<String>,
429}
430
431#[derive(Debug, Clone, QueryParams, Builder)]
436pub struct ClosedOrdersRequest {
437 pub trades: Option<bool>,
438 pub userref: Option<i64>,
439 pub start: Option<i64>,
440 pub end: Option<i64>,
441 #[query(rename = "ofs")]
442 pub offset: Option<i64>,
443 #[query(rename = "closetime")]
444 pub close_time: Option<CloseTime>,
445 #[query(rename = "cl_ord_id")]
446 pub client_order_id: Option<String>,
447 pub consolidate_taker: Option<bool>,
448 pub without_count: Option<bool>,
449}
450
451#[derive(Debug, Clone, QueryParams, Builder)]
455pub struct OrderRequest {
456 #[builder(required)]
457 #[query(required, rename = "txid")]
458 pub tx_id: StringCSV,
459 pub trades: Option<bool>,
460 pub userref: Option<i64>,
461 pub consolidate_taker: Option<bool>,
462}
463
464#[derive(Debug, Clone, Serialize, Builder)]
465pub struct OrderAmendsRequest {
466 #[builder(required)]
467 order_id: String,
468}
469
470#[derive(Debug, Clone, QueryParams, Builder, PartialEq, Eq)]
475pub struct TradesHistoryRequest {
476 #[query(rename = "type")]
477 pub trade_type: Option<TradeType>,
478 pub trades: Option<bool>,
479 pub start: Option<i64>,
480 pub end: Option<i64>,
481 #[query(rename = "ofs")]
482 pub offset: Option<i64>,
483 pub consolidate_taker: Option<bool>,
484 pub ledgers: Option<bool>,
485}
486
487#[derive(Debug, Clone, QueryParams, Builder)]
489pub struct TradeInfoRequest {
490 #[builder(required)]
491 #[query(required, rename = "txid")]
492 pub tx_id: StringCSV,
493 pub trades: Option<bool>,
494}
495
496#[derive(Debug, Clone, QueryParams, Builder)]
498pub struct OpenPositionsRequest {
499 #[query(rename = "txid")]
500 pub tx_id: Option<String>,
501 #[query(rename = "docalcs")]
502 pub do_calcs: Option<bool>,
503 pub consolidation: Option<String>,
504}
505
506#[derive(Debug, Clone, QueryParams, Builder)]
511pub struct LedgersInfoRequest {
512 pub asset: Option<StringCSV>,
513 #[query(rename = "aclass")]
514 pub asset_class: Option<String>,
515 #[query(rename = "type")]
516 pub entry_type: Option<LedgerEntryType>,
517 pub start: Option<i64>,
518 pub end: Option<i64>,
519 #[query(rename = "ofs")]
520 pub offset: Option<i64>,
521 pub without_count: Option<bool>,
522}
523
524#[derive(Debug, Clone, QueryParams, Builder)]
526pub struct QueryLedgerRequest {
527 #[query(required)]
528 #[builder(required)]
529 pub id: StringCSV,
530 pub trades: Option<bool>,
531}
532
533#[derive(Debug, Clone, QueryParams, Builder)]
537pub struct TradeVolumeRequest {
538 pub pair: Option<StringCSV>,
539}
540
541#[derive(Debug, Clone, QueryParams, Builder)]
543pub struct ExportReportRequest {
544 #[builder(required)]
545 #[query(required)]
546 pub report: ReportType,
547 pub format: Option<ReportFormatType>,
548 #[builder(required)]
549 #[query(required)]
550 pub description: String,
551 pub fields: Option<String>,
552 #[query(rename = "starttm")]
553 pub start_time: Option<i64>,
554 #[query(rename = "endtm")]
555 pub end_time: Option<i64>,
556}
557
558#[derive(Debug, Clone, QueryParams, Builder)]
560pub struct ExportReportStatusRequest {
561 #[builder(required)]
562 #[query(required)]
563 pub report: ReportType,
564}
565
566#[derive(Debug, Clone, QueryParams, Builder)]
568pub struct RetrieveExportReportRequest {
569 #[builder(required)]
570 #[query(required)]
571 pub id: String,
572}
573
574#[derive(Debug, Clone, QueryParams, Builder)]
576pub struct DeleteExportRequest {
577 #[builder(required)]
578 #[query(required)]
579 pub id: String,
580 #[builder(required)]
581 #[query(required, rename = "type")]
582 pub delete_type: DeleteExportType,
583}
584
585#[derive(Debug, Clone, QueryParams, Builder, PartialEq, Eq)]
587pub struct AddOrderRequest {
588 #[query(rename = "userref")]
589 pub user_ref: Option<i64>,
590 #[query(rename = "cl_ord_id")]
591 pub client_order_id: Option<String>,
592 #[builder(required)]
593 #[query(required, rename = "ordertype")]
594 pub order_type: OrderType,
595 #[builder(required)]
596 #[query(required, rename = "type")]
597 pub side: BuySell,
598 #[builder(required)]
599 #[query(required)]
600 pub volume: Decimal,
601 #[query(rename = "displayvol")]
602 pub display_volume: Option<Decimal>,
603 #[builder(required)]
604 #[query(required)]
605 pub pair: String,
606 #[query(rename = "reqid")]
607 pub req_id: Option<i64>,
608 pub price: Option<Decimal>,
609 #[query(rename = "price2")]
610 pub price_2: Option<Decimal>,
611 pub trigger: Option<TriggerType>,
612 pub leverage: Option<i64>,
613 pub reduce_only: Option<bool>,
614 #[query(rename = "stptype")]
615 pub stp_type: Option<SelfTradePrevention>,
616 #[query(rename = "oflags")]
617 pub order_flags: Option<OrderFlags>,
618 #[query(rename = "timeinforce")]
619 pub time_in_force: Option<TimeInForce>,
620 #[query(rename = "starttm")]
621 pub start_time: Option<String>,
622 #[query(rename = "expiretm")]
623 pub expire_time: Option<String>,
624 #[query(rename = "close[ordertype]")]
625 pub close_order_type: Option<String>,
626 #[query(rename = "close[price]")]
627 pub close_price: Option<Decimal>,
628 #[query(rename = "close[price2]")]
629 pub close_price_2: Option<Decimal>,
630 pub deadline: Option<String>,
631 pub validate: Option<bool>,
632}
633
634#[skip_serializing_none]
636#[derive(Debug, Clone, Serialize, Builder)]
637pub struct AddBatchedOrderRequest {
638 #[builder(required)]
639 pub orders: Vec<BatchedOrderRequest>,
640 #[builder(required)]
641 pub pair: String,
642 pub deadline: Option<String>,
643 pub validate: Option<bool>,
644}
645
646#[serde_as]
648#[skip_serializing_none]
649#[derive(Debug, Clone, Builder, Serialize)]
650pub struct BatchedOrderRequest {
651 #[serde(rename = "userref")]
652 pub user_ref: Option<i64>,
653 #[serde(rename = "cl_ord_id")]
654 pub client_order_id: Option<String>,
655 #[builder(required)]
656 #[serde(rename = "ordertype")]
657 pub order_type: OrderType,
658 #[builder(required)]
659 #[serde(rename = "type")]
660 pub side: BuySell,
661 #[builder(required)]
662 pub volume: Decimal,
663 #[serde(rename = "displayvol")]
664 pub display_volume: Option<Decimal>,
665 pub price: Option<Decimal>,
666 #[serde(rename = "price2")]
667 pub price_2: Option<Decimal>,
668 pub trigger: Option<TriggerType>,
669 pub leverage: Option<i64>,
670 pub reduce_only: Option<bool>,
671 #[serde(rename = "stptype")]
672 pub stp_type: Option<String>,
673 #[serde(rename = "oflags")]
674 #[serde(default)]
675 #[serde_as(as = "Option<StringWithSeparator::<CommaSeparator, OrderFlag>>")]
676 pub order_flags: Option<Vec<OrderFlag>>,
677 #[serde(rename = "timeinforce")]
678 pub time_in_force: Option<TimeInForce>,
679 #[serde(rename = "starttm")]
680 pub start_time: Option<String>,
681 #[serde(rename = "expiretm")]
682 pub expire_time: Option<String>,
683}
684
685#[derive(Debug, Clone, Serialize, Builder)]
686pub struct AmendOrderRequest {
687 #[serde(rename = "txid")]
688 pub tx_id: Option<String>,
689 #[serde(rename = "cl_ord_id")]
690 pub client_order_id: Option<String>,
691 #[serde(rename = "order_qty")]
692 pub order_quantity: Option<Decimal>,
693 #[serde(rename = "display_qty")]
694 pub display_quantity: Option<Decimal>,
695 pub limit_price: Option<String>,
696 pub trigger_price: Option<String>,
697 pub post_only: Option<bool>,
698 pub deadline: Option<String>, }
700
701#[derive(Debug, Clone, QueryParams, Builder)]
703pub struct EditOrderRequest {
704 #[query(rename = "userref")]
705 pub user_ref: Option<i64>,
706 #[query(required, rename = "txid")]
707 #[builder(required)]
708 pub tx_id: String,
709 #[builder(required)]
710 #[query(required)]
711 pub volume: Decimal,
712 #[query(rename = "displayvol")]
713 pub display_volume: Option<Decimal>,
714 #[builder(required)]
715 #[query(required)]
716 pub pair: String,
717 pub price: Option<Decimal>,
718 #[query(rename = "price2")]
719 pub price_2: Option<Decimal>,
720 #[query(rename = "oflags")]
721 pub order_flags: Option<OrderFlags>,
722 pub deadline: Option<String>,
723 pub cancel_response: Option<bool>,
724 pub validate: Option<bool>,
725}
726
727#[derive(Debug, Clone, QueryParams, Builder)]
729pub struct CancelOrderRequest {
730 #[query(required, rename = "txid")]
731 #[builder(required)]
732 pub tx_id: IntOrString,
733 #[query(rename = "cl_ord_id")]
734 pub client_order_id: Option<String>,
735}
736
737#[derive(Debug, Clone, QueryParams, Builder)]
742pub struct CancelAllOrdersAfterRequest {
743 #[builder(required)]
744 #[query(required)]
745 pub timeout: i64,
746}
747
748#[derive(Debug, Clone, Builder, Serialize)]
750pub struct CancelBatchOrdersRequest {
751 #[builder(required)]
752 pub orders: Vec<IntOrString>,
753 #[serde(rename = "cl_ord_ids")]
754 pub client_order_ids: Option<Vec<String>>,
755}
756
757impl CancelBatchOrdersRequest {
758 pub fn from_user_refs(refs: Vec<i64>) -> CancelBatchOrdersRequest {
759 CancelBatchOrdersRequest {
760 orders: refs.into_iter().map(IntOrString::Int).collect(),
761 client_order_ids: None,
762 }
763 }
764
765 pub fn from_tx_ids(ids: Vec<String>) -> CancelBatchOrdersRequest {
766 CancelBatchOrdersRequest {
767 orders: ids.into_iter().map(IntOrString::String).collect(),
768 client_order_ids: None,
769 }
770 }
771
772 pub fn from_client_order_ids(ids: Vec<String>) -> CancelBatchOrdersRequest {
773 CancelBatchOrdersRequest {
774 orders: vec![],
775 client_order_ids: Some(ids),
776 }
777 }
778}
779
780#[derive(Debug, Clone, Builder, QueryParams)]
782pub struct DepositMethodsRequest {
783 #[builder(required)]
784 #[query(required)]
785 pub asset: String,
786 pub aclass: Option<String>,
787}
788
789#[derive(Debug, Clone, Builder, QueryParams)]
791pub struct DepositAddressesRequest {
792 #[query(required)]
793 #[builder(required)]
794 pub asset: String,
795 #[query(required)]
796 #[builder(required)]
797 pub method: String,
798 #[query(rename = "new")]
799 pub is_new: Option<bool>,
800 pub amount: Option<Decimal>, }
802
803#[derive(Debug, Clone, Builder, QueryParams)]
805pub struct WithdrawalMethodsRequest {
806 pub asset: Option<String>,
807 #[query(rename = "aclass")]
808 pub asset_class: Option<String>,
809 pub network: Option<String>,
810}
811
812#[derive(Debug, Clone, Builder, QueryParams)]
814pub struct WithdrawalAddressesRequest {
815 pub asset: Option<String>,
816 #[query(rename = "aclass")]
817 pub asset_class: Option<String>,
818 pub method: Option<String>,
819 pub key: Option<String>,
820 pub verified: Option<bool>,
821}
822
823#[derive(Debug, Clone)]
825pub enum Cursor {
826 String(String),
827 Bool(bool),
828}
829
830impl Display for Cursor {
831 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
832 match self {
833 Cursor::String(str) => write!(f, "{str}"),
834 Cursor::Bool(b) => write!(f, "{b}"),
835 }
836 }
837}
838
839#[derive(Debug, Clone, Builder, QueryParams)]
841pub struct StatusOfDepositWithdrawRequest {
842 pub asset: Option<String>,
843 #[query(rename = "aclass")]
844 pub asset_class: Option<String>,
845 pub method: Option<String>,
846 pub start: Option<String>,
847 pub end: Option<String>,
848 pub cursor: Option<Cursor>,
849 pub limit: Option<i64>,
850}
851
852#[derive(Debug, Clone, Builder, QueryParams)]
854pub struct WithdrawalInfoRequest {
855 #[builder(required)]
856 #[query(required)]
857 pub asset: String,
858 #[builder(required)]
859 #[query(required)]
860 pub key: String,
861 #[builder(required)]
862 #[query(required)]
863 pub amount: Decimal,
864}
865
866#[derive(Debug, Clone, Builder, QueryParams)]
868pub struct WithdrawFundsRequest {
869 #[builder(required)]
870 #[query(required)]
871 pub asset: String,
872 #[builder(required)]
873 #[query(required)]
874 pub key: String,
875 #[builder(required)]
876 #[query(required)]
877 pub amount: Decimal,
878 pub address: Option<String>,
879 pub max_fee: Option<Decimal>,
880}
881
882#[derive(Debug, Clone, Builder, QueryParams)]
884pub struct WithdrawCancelRequest {
885 #[builder(required)]
886 #[query(required)]
887 pub asset: String,
888 #[builder(required)]
889 #[query(required, rename = "refid")]
890 pub ref_id: String,
891}
892
893#[derive(Debug, Clone, Builder, QueryParams)]
895pub struct WalletTransferRequest {
896 #[builder(required)]
897 #[query(required)]
898 pub asset: String,
899 #[builder(required)]
900 #[query(required)]
901 pub from: String,
902 #[builder(required)]
903 #[query(required)]
904 pub to: String,
905 #[builder(required)]
906 #[query(required)]
907 pub amount: Decimal,
908}
909
910#[derive(Debug, Clone, Builder, QueryParams)]
912pub struct CreateSubAccountRequest {
913 #[builder(required)]
914 #[query(required)]
915 pub username: String,
916 #[builder(required)]
917 #[query(required)]
918 pub email: String,
919}
920
921#[derive(Debug, Clone, Builder, QueryParams)]
923pub struct AccountTransferRequest {
924 #[builder(required)]
925 #[query(required)]
926 pub asset: String,
927 #[builder(required)]
928 #[query(required)]
929 pub amount: Decimal,
930 #[builder(required)]
931 #[query(required)]
932 pub from: String,
933 #[builder(required)]
934 #[query(required)]
935 pub to: String,
936}
937
938#[derive(Debug, Clone, Builder, QueryParams)]
940pub struct AllocateEarnFundsRequest {
941 #[builder(required)]
942 #[query(required)]
943 pub amount: Decimal,
944 #[builder(required)]
945 #[query(required)]
946 pub strategy_id: String,
947}
948
949#[derive(Debug, Clone, Builder, QueryParams)]
951pub struct EarnAllocationStatusRequest {
952 #[builder(required)]
953 #[query(required)]
954 pub strategy_id: String,
955}
956
957#[derive(Debug, Clone, Builder, QueryParams)]
961pub struct ListEarnStrategiesRequest {
962 pub ascending: Option<bool>,
963 pub asset: Option<String>,
964 pub cursor: Option<String>,
965 pub limit: Option<u16>,
966 pub lock_type: Option<LockType>,
967}
968
969#[derive(Debug, Clone, Builder, QueryParams)]
971pub struct ListEarnAllocationsRequest {
972 pub ascending: Option<bool>,
973 pub converted_asset: Option<String>,
974 pub hide_zero_allocations: Option<bool>,
975}
976
977#[cfg(test)]
978mod tests {
979 use crate::request_types::{CancelBatchOrdersRequest, IntOrString, OrderFlags, StringCSV};
980 use crate::response_types::OrderFlag;
981
982 #[test]
983 fn test_cancel_batch_order_request_ids() {
984 let request =
985 CancelBatchOrdersRequest::from_tx_ids(vec!["M97YKE-HHCTY-2GRVXU".to_string()]);
986
987 let expected = vec![IntOrString::String("M97YKE-HHCTY-2GRVXU".to_string())];
988 assert_eq!(expected, request.orders);
989 }
990
991 #[test]
992 fn test_cancel_batch_order_request_user_refs() {
993 let request = CancelBatchOrdersRequest::from_user_refs(vec![42]);
994
995 let expected = vec![IntOrString::Int(42)];
996 assert_eq!(expected, request.orders);
997 }
998
999 #[test]
1000 fn test_string_csv_conversions() {
1001 let expected_string_csv = StringCSV::new(vec!["post".to_string()]);
1002
1003 let from_str: StringCSV = "post".into();
1004 let from_string: StringCSV = "post".to_string().into();
1005
1006 let string_ref: &String = &("post".to_string());
1007 let from_string_ref: StringCSV = string_ref.into();
1008
1009 assert_eq!(expected_string_csv, from_str);
1010 assert_eq!(expected_string_csv, from_string);
1011 assert_eq!(expected_string_csv, from_string_ref);
1012 }
1013
1014 #[test]
1015 fn test_order_flag_conversions() {
1016 let expected_order_flag = OrderFlags::new(vec![OrderFlag::NoMarketPriceProtection]);
1017
1018 let order_flags: OrderFlags = OrderFlag::NoMarketPriceProtection.into();
1019
1020 assert_eq!(expected_order_flag, order_flags);
1021 }
1022
1023 #[test]
1024 fn test_int_or_string_conversions() {
1025 let expected_int = IntOrString::Int(42);
1026 let expected_string = IntOrString::String("someString".to_string());
1027
1028 let int: IntOrString = 42.into();
1029 let str: IntOrString = "someString".into();
1030 let string: IntOrString = "someString".to_string().into();
1031
1032 assert_eq!(expected_int, int);
1033 assert_eq!(expected_string, str);
1034 assert_eq!(expected_string, string);
1035 }
1036}