crypto_rest_client/exchanges/bitz/
bitz_swap.rs

1use super::super::utils::http_get;
2use crate::error::{Error, Result};
3use std::collections::{BTreeMap, HashMap};
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8const BASE_URL: &str = "https://apiv2.bitz.com";
9
10/// The RESTful client for BitZ swap markets.
11///
12/// * RESTful API doc: <https://apidocv2.bitz.plus/en/>
13/// * Trading at: <https://swap.bitz.plus/en/>
14/// * Rate Limits: <https://apidocv2.bitz.plus/en/#limit>
15///   * no more than 30 times within 1 sec
16pub struct BitzSwapRestClient {
17    _api_key: Option<String>,
18    _api_secret: Option<String>,
19}
20
21impl BitzSwapRestClient {
22    pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
23        BitzSwapRestClient { _api_key: api_key, _api_secret: api_secret }
24    }
25
26    /// Get the latest Level2 snapshot of orderbook.
27    ///
28    /// Top 100 bids and asks are returned.
29    ///
30    /// For example: <https://apiv2.bitz.com/V2/Market/getContractOrderBook?contractId=101&depth=100>,
31    pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
32        let symbol_id_map = get_symbol_id_map()?;
33        if !symbol_id_map.contains_key(symbol) {
34            return Err(Error(format!("Can NOT find contractId for the pair {symbol}")));
35        }
36        let contract_id = symbol_id_map.get(symbol).unwrap();
37        gen_api!(format!("/V2/Market/getContractOrderBook?contractId={contract_id}&depth=100"))
38    }
39
40    /// Get open interest.
41    ///
42    /// For example: <https://apiv2.bitz.com/V2/Market/getContractTickers>
43    pub fn fetch_open_interest(symbol: Option<&str>) -> Result<String> {
44        if let Some(symbol) = symbol {
45            let symbol_id_map = get_symbol_id_map()?;
46            if !symbol_id_map.contains_key(symbol) {
47                return Err(Error(format!("Can NOT find contractId for the pair {symbol}")));
48            }
49            let contract_id = symbol_id_map.get(symbol).unwrap();
50            gen_api!(format!("/V2/Market/getContractTickers?contractId={contract_id}"))
51        } else {
52            gen_api!("/V2/Market/getContractTickers")
53        }
54    }
55}
56
57#[derive(Clone, Serialize, Deserialize)]
58#[allow(non_snake_case)]
59struct SwapMarket {
60    contractId: String, // contract id
61    pair: String,       //contract market
62    status: String,
63    #[serde(flatten)]
64    extra: HashMap<String, Value>,
65}
66
67#[derive(Serialize, Deserialize)]
68struct Response {
69    status: i64,
70    msg: String,
71    data: Vec<SwapMarket>,
72    time: i64,
73    microtime: String,
74    source: String,
75}
76
77fn get_symbol_id_map() -> Result<HashMap<String, String>> {
78    let params = BTreeMap::new();
79    let txt = http_get("https://apiv2.bitz.com/Market/getContractCoin", &params)?;
80    let resp = serde_json::from_str::<Response>(&txt)?;
81    if resp.status != 200 {
82        return Err(Error(txt));
83    }
84
85    let mut symbol_id_map = HashMap::<String, String>::new();
86    for x in resp.data.iter() {
87        if x.status == "1" {
88            symbol_id_map.insert(x.pair.clone(), x.contractId.clone());
89        }
90    }
91    Ok(symbol_id_map)
92}