bitbank_api/private/
mod.rs

1use super::*;
2use reqwest::Client;
3
4/// Get asset list.
5pub mod assets;
6mod auth;
7/// Cancel an order.
8pub mod cancel_order;
9/// Cancel multiple orders.
10pub mod cancel_orders;
11/// Create an order.
12pub mod create_order;
13/// Get deposit history.
14pub mod deposit_history;
15/// Get active orders.
16pub mod fetch_active_orders;
17/// Get an order information.
18pub mod fetch_order;
19/// Get multiple orders.
20pub mod fetch_orders;
21/// Get trade history.
22pub mod trade_history;
23
24pub use auth::Credential;
25
26struct ApiExec {
27    cred: auth::Credential,
28}
29impl ApiExec {
30    /// path: /v1/x/y/z
31    /// params: a=b&c=d
32    async fn get<R: serde::de::DeserializeOwned>(
33        self,
34        path: impl Into<String>,
35        params: String,
36    ) -> anyhow::Result<R> {
37        let path = path.into();
38        let params = if params.len() > 0 {
39            format!("?{params}")
40        } else {
41            format!("")
42        };
43
44        let auth_headers = auth::GetAuth {
45            path: path.clone(),
46            params: params.clone(),
47        }
48        .create(self.cred)?;
49
50        let url = format!("https://api.bitbank.cc{path}{params}");
51        let (cli, req) = Client::new().get(url).headers(auth_headers).build_split();
52        let resp: Response = cli.execute(req?).await?.json().await?;
53        let data = resp.result()?;
54        let data: R = serde_json::from_value(data)?;
55        Ok(data)
56    }
57
58    /// path: /v1/x/y/z
59    /// body: json
60    async fn post<R: serde::de::DeserializeOwned>(
61        self,
62        path: impl Into<String>,
63        body: String,
64    ) -> anyhow::Result<R> {
65        let path = path.into();
66        let auth_headers = auth::PostAuth { body: body.clone() }.create(self.cred)?;
67        let url = format!("https://api.bitbank.cc{path}");
68        let (cli, req) = Client::new()
69            .post(url)
70            .headers(auth_headers)
71            .body(body)
72            .build_split();
73        let resp: Response = cli.execute(req?).await?.json().await?;
74        let data = resp.result()?;
75        let data: R = serde_json::from_value(data)?;
76        Ok(data)
77    }
78}
79
80#[serde_as]
81#[derive(Deserialize, Debug)]
82pub struct OrderInfo {
83    pub order_id: u64,
84    #[serde_as(as = "DisplayFromStr")]
85    pub pair: Pair,
86    #[serde_as(as = "DisplayFromStr")]
87    pub side: Side,
88    #[serde_as(as = "DisplayFromStr")]
89    #[serde(rename = "type")]
90    pub order_type: OrderType,
91    #[serde_as(as = "DisplayFromStr")]
92    pub start_amount: f64,
93    #[serde_as(as = "DisplayFromStr")]
94    pub remaining_amount: f64,
95    #[serde_as(as = "DisplayFromStr")]
96    pub executed_amount: f64,
97    #[serde_as(as = "DisplayFromStr")]
98    pub price: f64,
99    /// post_only only exists iff the order-type is limit otherwise omitted.
100    #[serde_as(deserialize_as = "DefaultOnNull")]
101    pub post_only: Option<bool>,
102    #[serde_as(as = "DisplayFromStr")]
103    pub average_price: f64,
104    #[serde_as(as = "TimestampMilliSeconds")]
105    pub ordered_at: NaiveDateTime,
106    #[serde_as(as = "Option<TimestampMilliSeconds>")]
107    pub expire_at: Option<NaiveDateTime>,
108    #[serde_as(as = "Option<TimestampMilliSeconds>")]
109    pub triggered_at: Option<NaiveDateTime>,
110    #[serde_as(as = "Option<DisplayFromStr>")]
111    pub trigger_price: Option<f64>,
112    #[serde_as(as = "Option<TimestampMilliSeconds>")]
113    pub canceled_at: Option<NaiveDateTime>,
114    #[serde_as(as = "DisplayFromStr")]
115    pub status: OrderStatus,
116}
117
118#[cfg(test)]
119mod tests {
120    use super::*;
121
122    #[test]
123    fn test_url_parse() -> anyhow::Result<()> {
124        let url = format!("https://api.bitbank.cc/v1/some_api?a=b&c=d");
125        let cli = Client::new();
126        let req = cli.get(url).build()?;
127        dbg!(&req);
128        Ok(())
129    }
130}