Explorar o código

新交易所htx

hl hai 1 ano
pai
achega
bed16928a1
Modificáronse 4 ficheiros con 313 adicións e 298 borrados
  1. 5 1
      exchanges/Cargo.toml
  2. 3 3
      exchanges/src/http_tool.rs
  3. 256 160
      exchanges/src/htx_swap_rest.rs
  4. 49 134
      exchanges/tests/htx_swap_test.rs

+ 5 - 1
exchanges/Cargo.toml

@@ -15,6 +15,7 @@ tokio-tungstenite= { git = "https://github.com/HonestHouLiang/tokio-tungstenite.
 futures-util = { version = "0.3.28", default-features = false, features = ["sink", "std"] }
 futures-channel = "0.3.28"
 
+
 url = "2.4.0"
 base64 = "0.13"
 tokio = { version = "1.31.0", features = ["full"] }
@@ -46,4 +47,7 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
 ##生成 xlsx
 rust_xlsxwriter = "0.58.0"
 
-once_cell = "1.18.0"
+once_cell = "1.18.0"
+
+##url编码
+percent-encoding = "2.1.0"

+ 3 - 3
exchanges/src/http_tool.rs

@@ -3,7 +3,7 @@ use crate::response_base::ResponseData;
 
 #[derive(Clone)]
 pub struct RestTool {
-    pub base_url: String
+    pub base_url: String,
 }
 
 impl RestTool {
@@ -77,7 +77,7 @@ impl RestTool {
                 if res_data.code != 0 {
                     res_data
                 } else {
-                    let json_value= res_data.data;
+                    let json_value = res_data.data;
 
                     let code = json_value["code"].as_str().unwrap();
                     let data = serde_json::to_string(&json_value["data"]).unwrap();
@@ -94,7 +94,7 @@ impl RestTool {
                 }
             }
             Err(err) => {
-                let error = ResponseData::error("".to_string(),format!("json 解析失败:{}", err));
+                let error = ResponseData::error("".to_string(), format!("json 解析失败:{}", err));
                 error
             }
         }

+ 256 - 160
exchanges/src/htx_swap_rest.rs

@@ -1,17 +1,34 @@
 use std::collections::BTreeMap;
-use reqwest::header::HeaderMap;
-use ring::{digest};
+use base64::encode;
+
+use chrono::Utc;
 use hex;
-use hmac::{Hmac, Mac, NewMac};
+use percent_encoding::{AsciiSet, CONTROLS, utf8_percent_encode};
 use reqwest::Client;
+use reqwest::header::HeaderMap;
+use ring::hmac;
 use rust_decimal::Decimal;
 use rust_decimal::prelude::FromPrimitive;
 use rust_decimal_macros::dec;
-use serde_json::Value;
+use serde_json::{Map, Value};
+use sha2::Sha256;
+use tracing::{error, info, trace};
+
 use crate::http_tool::RestTool;
 use crate::response_base::ResponseData;
-use sha2::Sha512;
-use tracing::{error, info, trace};
+
+// 定义用于 URL 编码的字符集
+const FRAGMENT: &AsciiSet = &CONTROLS
+    .add(b' ')
+    .add(b':')
+    .add(b'=')
+    .add(b'+')
+// .add(b'/').add(b'?').add(b'#')
+// .add(b'[').add(b']').add(b'@').add(b'!').add(b'$').add(b'&')
+// .add(b'\'').add(b'(').add(b')').add(b'*').add(b',')
+// .add(b';').add(b'"').add(b'%')
+;
+
 
 #[derive(Clone)]
 pub struct HtxSwapRest {
@@ -62,110 +79,70 @@ impl HtxSwapRest {
         let data = self.request("GET".to_string(),
                                 "/api/v1".to_string(),
                                 format!("/timestamp"),
+                                false,
+                                params,
+        ).await;
+        data
+    }
+
+    //查询合约账户(【全仓】获取用户账户信息)
+    pub async fn get_account(&mut self) -> ResponseData {
+        let params = serde_json::json!({
+            "valuation_asset":"USDT"
+         });
+        let data = self.request("POST".to_string(),
+                                "/linear-swap-api/v1".to_string(),
+                                format!("/swap_balance_valuation"),
                                 true,
-                                params.to_string(),
+                                params,
         ).await;
         data
     }
-    //
-    // //查询个人交易费率
-    // pub async fn wallet_fee(&mut self) -> ResponseData {
-    //     let params = serde_json::json!({
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/wallet/fee"),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    // //查询合约账户
-    // pub async fn get_account(&mut self, settle: String) -> ResponseData {
-    //     let params = serde_json::json!({
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/futures/{}/accounts", settle),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    // //用户仓位列表
-    // pub async fn get_user_position(&mut self, settle: String) -> ResponseData {
-    //     let params = serde_json::json!({
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/futures/{}/positions", settle),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    // //双仓模式下的持仓信息
-    // pub async fn get_position(&mut self, settle: String, contract: String) -> ResponseData {
-    //     let params = serde_json::json!({
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/futures/{}/dual_comp/positions/{}", settle, contract),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    // //获取所有合约交易行情统计
-    // pub async fn get_ticker(&mut self, settle: String) -> ResponseData {
-    //     let params = serde_json::json!({
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/futures/{}/tickers", settle),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    // //查询所有的合约信息
-    // pub async fn get_market_details(&mut self, settle: String) -> ResponseData {
-    //     let params = serde_json::json!({
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/futures/{}/contracts", settle),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    // //查询单个订单详情
-    // pub async fn get_order_details(&mut self, settle: String, order_id: String) -> ResponseData {
-    //     let params = serde_json::json!({
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/futures/{}/orders/{}", settle, order_id),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    // //查询合约订单列表
-    // pub async fn get_orders(&mut self, settle: String, status: String) -> ResponseData {
-    //     let params = serde_json::json!({
-    //         "status":status
-    //      });
-    //     let data = self.request("GET".to_string(),
-    //                             "/api/v4".to_string(),
-    //                             format!("/futures/{}/orders", settle),
-    //                             true,
-    //                             params.to_string(),
-    //     ).await;
-    //     data
-    // }
-    //
+
+    //用户仓位列表(【全仓】获取用户持仓信息)
+    pub async fn get_user_position(&mut self) -> ResponseData {
+        let params = serde_json::json!({
+            "contract_type":"swap"
+         });
+        let data = self.request("POST".to_string(),
+                                "/linear-swap-api/v1".to_string(),
+                                format!("/swap_cross_position_info"),
+                                true,
+                                params,
+        ).await;
+        data
+    }
+
+    //查询合约订单列表 (【全仓】获取合约订单信息)
+    pub async fn get_orders(&mut self, order_id: String) -> ResponseData {
+        let mut params = serde_json::json!({
+         });
+        if order_id.len() > 0 {
+            params.as_object_mut().unwrap().insert("order_id".to_string(), Value::from(order_id.clone()));
+        }
+        let data = self.request("POST".to_string(),
+                                "/linear-swap-api/v1".to_string(),
+                                format!("/swap_cross_order_info"),
+                                true,
+                                params,
+        ).await;
+        data
+    }
+
+
+    //查询单个订单详情 (【全仓】获取订单明细信息)
+    pub async fn get_order_details(&mut self,order_id: String) -> ResponseData {
+        let params = serde_json::json!({
+         });
+        let data = self.request("POST".to_string(),
+                                "/linear-swap-api/v1".to_string(),
+                                format!("/swap_cross_order_detail"),
+                                true,
+                                params,
+        ).await;
+        data
+    }
+
     // //下单:side-下单方向,pos_side-持仓方向
     // pub async fn order(&mut self,
     //                    settle: String,
@@ -426,14 +403,13 @@ impl HtxSwapRest {
         self.avg_delay = (sum_v / len_v).round_dp(1);
         self.delays = last_100.clone().into_iter().collect();
     }
-
     //调用请求
     async fn request(&mut self,
                      requesst_type: String,
                      prefix_url: String,
                      request_url: String,
                      is_login: bool,
-                     params: String) -> ResponseData
+                     params: Value) -> ResponseData
     {
         // trace!("login_param:{:?}", self.login_param);
         //解析账号信息
@@ -452,7 +428,6 @@ impl HtxSwapRest {
 
         //请求头配置-如果需要登录则存在额外配置
         let mut body = "".to_string();
-        let timestamp = chrono::Utc::now().timestamp().to_string();
 
         let mut headers = HeaderMap::new();
         if requesst_type == "GET" {
@@ -463,28 +438,56 @@ impl HtxSwapRest {
             headers.insert("Content-Type", "application/json".parse().unwrap());
         }
 
-        if requesst_type == "POST" {
-            body = params.clone();
-        }
-
+        let utc_now = Utc::now();
+        let mut timestamp = utc_now.format("%Y-%m-%dT%H:%M:%S").to_string();
+        let mut params_str = "".to_string();
         //是否需要登录-- 组装sing
+        let mut sing = "".to_string();
         if is_login {
             if !is_login_param {
                 let e = ResponseData::error(self.label.clone(), "登录参数错误!".to_string());
                 return e;
             } else {//需要登录-且登录参数齐全
+                let mut login_param = serde_json::json!({});
+                login_param["AccessKeyId"] = Value::from(access_key);
+                login_param["SignatureMethod"] = Value::from("HmacSHA256");
+                login_param["SignatureVersion"] = Value::from("2");
+                login_param["Timestamp"] = Value::from(timestamp);
+
+                //如果是get 所有参所也要参与校验,如果是post 只有校验参数需要校验
+                let mut verify_param = serde_json::json!({});
+                if requesst_type == "GET" {
+                    merge_json(&mut verify_param, &params);
+                    merge_json(&mut verify_param, &login_param);
+                    body = "{}".to_string();
+                } else if (requesst_type == "POST") {
+                    merge_json(&mut verify_param, &login_param);
+                    body = params.to_string();
+                }
+                trace!("需要校验参数:\n{}", verify_param.to_string());
+
+
+                //4. ASCII码的顺序对参数名进行排序
+                // let sorted_params = sort_json_keys(params);
+                // let params_str_sort = format!("{}", serde_json::to_string_pretty(&sorted_params).unwrap());
+                // trace!("排序后的参数:\n{}", params_str_sort);
+                let verify_param_str = json_to_query_string(verify_param);
+                trace!("排序后的拼接参数:\n{}", verify_param_str);
+                params_str = verify_param_str.to_string().clone();
+
                 //组装sing
-                let sing = Self::sign(secret_key.clone(),
-                                      requesst_type.clone(),
-                                      prefix_url.clone(),
-                                      request_url.clone(),
-                                      params.clone(),
-                                      body.clone(),
-                                      timestamp.clone(),
+                sing = Self::sign(secret_key.clone(),
+                                  requesst_type.clone(),
+                                  prefix_url.clone(),
+                                  request_url.clone(),
+                                  verify_param_str.clone(),
                 );
-                // trace!("sing:{}", sing);
-                //组装header
-                headers.extend(Self::headers(access_key, timestamp, sing));
+                // sing = utf8_percent_encode(sing.as_str(), FRAGMENT).to_string();
+                // sing = sing.to_uppercase();
+                trace!("sing:{}", sing);
+                // ?AccessKeyId=e2xxxxxx-99xxxxxx-84xxxxxx-7xxxx&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2017-05-11T15%3A19%3A30&Signature=    4F65x5A2bLyMWVQj3Aqp%2BB4w%2BivaA7n5Oi2SuYtCJ9o%3D
+                // ?AccessKeyId=58edb6bb-qz5c4v5b6n-24498508-c5919&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2024-04-29T07%3A26%3A39&Signature=  R0SAEWSEC+A6HS5URSHZIFOZBYQBRCLH0DTDSAL0HLS=
+                //                                                                                                                                             4F65x5A2bLyMWVQj3Aqp+B4w+ivaA7n5Oi2SuYtCJ9o=
             }
         }
 
@@ -494,7 +497,9 @@ impl HtxSwapRest {
         let response = self.http_tool(
             base_url.clone(),
             requesst_type.to_string(),
-            params.clone(),
+            params_str,
+            body.clone(),
+            sing.clone(),
             headers,
         ).await;
 
@@ -507,55 +512,60 @@ impl HtxSwapRest {
 
     pub fn headers(access_key: String, timestamp: String, sign: String) -> HeaderMap {
         let mut headers = HeaderMap::new();
-        headers.insert("KEY", access_key.clone().parse().unwrap());
-        headers.insert("Timestamp", timestamp.clone().parse().unwrap());
-        headers.insert("SIGN", sign.clone().parse().unwrap());
+        // headers.insert("KEY", access_key.clone().parse().unwrap());
+        // headers.insert("Timestamp", timestamp.clone().parse().unwrap());
+        // headers.insert("SIGN", sign.clone().parse().unwrap());
         headers
     }
-    pub fn sign(secret_key: String,
-                requesst_type: String, prefix_url: String, request_url: String,
-                params: String, body_data: String, timestamp: String) -> String
+    pub fn sign(secret_key: String, requesst_type: String,
+                prefix_url: String, request_url: String,
+                verify_param: String) -> String
     {
-        let url = format!("{}{}", prefix_url, request_url);
-        let params_str = RestTool::parse_params_to_str(params);
-        let body = Some(body_data);
-        let hashed_payload = if let Some(body) = body {
-            let mut m = digest::Context::new(&digest::SHA512);
-            m.update(body.as_bytes());
-            hex::encode(m.finish().as_ref())
-        } else {
-            String::new()
-        };
-        // trace!("hashed_payload:{}", hashed_payload);
-
-        let message = format!("{}\n{}\n{}\n{}\n{}",
-                              requesst_type,
-                              url,
-                              params_str,
-                              hashed_payload,
-                              timestamp);
+        let mut message = format!("{}\napi.hbdm.com\n{}{}\n{}",
+                                  requesst_type,
+                                  prefix_url, request_url,
+                                  verify_param
+        );
         // trace!("**********", );
-        // trace!("组装数据:{}", message);
+        trace!("组装数据:\n{}", message);
         // trace!("**********", );
 
-        let mut mac = Hmac::<Sha512>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
-        mac.update(message.as_bytes());
-        let result = mac.finalize().into_bytes();
-        let sign = hex::encode(result);
+        let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
+        let result = hmac::sign(&hmac_key, &message.as_bytes());
+        let sign = base64::encode(result);
         sign
     }
 
 
-    async fn http_tool(&mut self, request_path: String, request_type: String, params: String, headers: HeaderMap) -> ResponseData {
+    async fn http_tool(&mut self, request_path: String,
+                       request_type: String,
+                       params: String,
+                       body: String,
+                       sing: String, headers: HeaderMap) -> ResponseData {
         /****请求接口与 地址*/
         let url = format!("{}{}", self.base_url.to_string(), request_path);
         let request_type = request_type.clone().to_uppercase();
-        let addrs_url = format!("{}?{}", url.clone(), RestTool::parse_params_to_str(params.clone()));
+        let params_str = if sing.len() > 0 {
+            format!("{}&Signature={}", params.clone(), sing)
+        } else {
+            format!("{}", params.clone())
+        };
+        let addrs_url = if params_str.len() > 0 {
+            format!("{}?{}", url.clone(), params_str)
+        } else {
+            format!("{}", url.clone())
+        };
+
+        trace!("url-----:???{}",url.clone());
+        trace!("addrs_url-----:???{}",addrs_url.clone());
+        trace!("param-----:???{}",params.clone());
+        trace!("param_str-----:???{}",params_str.clone());
+        trace!("body-----:???{}",body.clone());
 
         let request_builder = match request_type.as_str() {
             "GET" => self.client.get(addrs_url.clone()).headers(headers),
-            "POST" => self.client.post(addrs_url.clone()).body(params.clone()).headers(headers),
-            "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
+            "POST" => self.client.post(addrs_url.clone()).body(body).headers(headers),
+            // "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
             // "PUT" => self.client.put(url.clone()).json(&params),
             _ => {
                 panic!("{}", format!("错误的请求类型:{}", request_type.clone()))
@@ -575,9 +585,22 @@ impl HtxSwapRest {
     }
 
     pub fn on_success_data(&mut self, text: &String) -> ResponseData {
-        let data = serde_json::from_str(text.as_str()).unwrap();
-
-        ResponseData::new(self.label.clone(), 200, "success".to_string(), data)
+        let json_value = serde_json::from_str::<Value>(&text).unwrap();
+        let status = json_value["status"].as_str().unwrap();
+        match status {
+            "ok" => {
+                //判断是否有code ,没有表示特殊接口,直接返回
+                if json_value.get("data").is_some() {
+                    let data = json_value.get("data").unwrap();
+                    ResponseData::new(self.label.clone(), 200, "success".to_string(), data.clone())
+                } else {
+                    ResponseData::new(self.label.clone(), 200, "success".to_string(), json_value)
+                }
+            }
+            _ => {
+                ResponseData::new(self.label.clone(), 400, "error".to_string(), json_value)
+            }
+        }
     }
 
     pub fn on_error_data(&mut self, text: &String, base_url: &String, params: &String) -> ResponseData {
@@ -605,4 +628,77 @@ impl HtxSwapRest {
             }
         }
     }
+}
+
+//对 json 的数据进行 排序
+fn sort_json_object(value: &Value) -> Value {
+    match value {
+        Value::Object(obj) => {
+            let mut map = BTreeMap::new();
+            for (k, v) in obj {
+                // 注意这里使用了clone()来获取键的所有权
+                map.insert(k.clone(), sort_json_object(v));
+            }
+            // 将BTreeMap转换为Map<String, Value>,确保键类型正确
+            Value::Object(map.into_iter().collect::<Map<String, Value>>())
+        }
+        Value::Array(arr) => {
+            // 对数组中的每个元素递归排序
+            Value::Array(arr.iter().map(sort_json_object).collect())
+        }
+        // 其他类型的Value不需要排序,直接返回
+        _ => value.clone(),
+    }
+}
+
+
+// 合并两个 JSON 对象的函数
+fn merge_json(a: &mut Value, b: &Value) {
+    match (a, b) {
+        (Value::Object(ref mut a_map), Value::Object(b_map)) => {
+            for (k, v) in b_map {
+                merge_json(a_map.entry(k.clone()).or_insert(Value::Null), v);
+            }
+        }
+        (a, b) => {
+            *a = b.clone();
+        }
+    }
+}
+
+// 函数:将 JSON 对象的键按 ASCII 码排序
+fn sort_json_keys(value: Value) -> Value {
+    match value {
+        Value::Object(obj) => {
+            let mut map = BTreeMap::new();
+            for (k, v) in obj {
+                map.insert(k, sort_json_keys(v));
+            }
+            Value::Object(map.into_iter().collect::<Map<String, Value>>())
+        }
+        _ => value,
+    }
+}
+
+// 函数:将 JSON 对象转换为排序后的查询字符串
+fn json_to_query_string(value: Value) -> String {
+    let mut params = BTreeMap::new();
+
+    if let Value::Object(obj) = value {
+        for (k, v) in obj {
+            // 确保只处理字符串值
+            if let Value::String(v_str) = v {
+                params.insert(k, v_str);
+            } else {
+                // 对于非字符串值,我们可以转换为字符串或执行其他处理
+                params.insert(k, v.to_string());
+            }
+        }
+    }
+
+    // 拼接键值对为查询字符串
+    params.iter()
+        .map(|(k, v)| format!("{}={}", utf8_percent_encode(k, FRAGMENT), utf8_percent_encode(v, FRAGMENT)))
+        .collect::<Vec<String>>()
+        .join("&")
 }

+ 49 - 134
exchanges/tests/htx_swap_test.rs

@@ -120,140 +120,55 @@ async fn rest_get_server_time_test() {
     trace!("htx--服务器时间戳--{}", req_data.data);
 }
 
-//
-// #[tokio::test]
-// async fn rest_account_book_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.get_account().await;
-//     let res_data_json: Value = req_data.data;
-//     println!("coinex--查询合约账户--{:?}", res_data_json);
-//     let result = res_data_json.as_array().unwrap().get(0).unwrap();
-//     println!("coinex--查询合约账户--{:?}", result["ccy"]);
-// }
-//
-// #[tokio::test]
-// async fn rest_position_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.get_position("BOMEUSDT".to_string()).await;
-//     println!("coinex--查询仓位--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_positions_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.get_user_position().await;
-//     println!("coinex--查询用户所有仓位--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_ticker_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.get_ticker("BOMEUSDT".to_string()).await;
-//     println!("coinex--查询ticker--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_market_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.get_market_details("BOMEUSDT".to_string()).await;
-//     println!("coinex--查询market--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_market_list_test() {
-//     let symbol = "FTMUSDT".to_string();
-//     let price = Decimal::from_str("0.92").unwrap();
-//     let custom_id = "1234567890000";
-//     let order_side;
-//     let position_side;
-//     let amount = Decimal::from_str("10").unwrap();
-//     let ct_val = Decimal::from_str("1").unwrap();
-//     let origin_side = "kd";
-//     let size = (amount / ct_val).floor();
-//     match origin_side {
-//         "kd" => {
-//             position_side = "long";
-//             order_side = "buy";
-//         }
-//         "pd" => {
-//             position_side = "long";
-//             order_side = "sell";
-//         }
-//         "kk" => {
-//             position_side = "short";
-//             order_side = "buy";
-//         }
-//         "pk" => {
-//             position_side = "short";
-//             order_side = "sell";
-//         }
-//         _ => {
-//             error!("下单参数错误");
-//             position_side = "error";
-//             order_side = "error";
-//         }
-//     };
-//     let mut ret = get_rest();
-//     let req_data = ret.order(symbol, position_side.to_string(), order_side.to_string(), size, price, custom_id.to_string()).await;
-//     println!("coinex--查询swap_order--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_cancel_order_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.cancel_order("FTMUSDT".to_string(), "", "175974369as").await;
-//
-//     println!("coinex--查询cancel_order--{} {:?}",req_data.data.is_null(), req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_cancel_all_order_test() {
-//     let mut ret = get_rest();
-//     let ct_val = Decimal::ONE;
-//     let orders_res_data = ret.get_pending_orders().await;
-//     let mut result = vec![];
-//     if orders_res_data.code == 200 {
-//         let orders_res_data_json = orders_res_data.data.as_array().unwrap();
-//         for order in orders_res_data_json {
-//             let cancel_res_data = ret.cancel_order_all( order["market"].as_str().unwrap().to_string()).await;
-//             if cancel_res_data.code == 200 {
-//                 result.push(order.clone())
-//             }
-//         }
-//     }
-//     println!("coinex--查询cancel_all_order--{:?}", result);
-// }
-//
-// #[tokio::test]
-// async fn rest_finish_order_list_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.get_finished_orders().await;
-//     println!("coinex--查询finish_order--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_pending_order_list_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.get_pending_orders().await;
-//     println!("coinex--查询finish_order--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_setting_dual_leverage_test() {
-//     let mut ret = get_rest();
-//     let req_data = ret.setting_dual_leverage("FTMUSDT".to_string(), 10).await;
-//     println!("coinex--查询setting_dual_leverage--{:?}", req_data);
-// }
-//
-// #[tokio::test]
-// async fn rest_time() {
-//     let mut ret = get_rest();
-//     let res_data = ret.get_server_time().await;
-//     let res_data_json: Value = res_data.data;
-//     let result = res_data_json["timestamp"].to_string();
-//     println!("coinex--time--{:?}", result);
-// }
-//
+/*查询合约账户*/
+#[tokio::test]
+async fn rest_get_account_test() {
+    global::log_utils::init_log_with_trace();
+    // proxy_handle();
+
+    let mut ret = get_rest();
+    let req_data = ret.get_account().await;
+    trace!("htx--查询合约账户--{:?}", req_data);
+    trace!("htx--查询合约账户--{}", req_data.data);
+}
+
+/*用户仓位列表*/
+#[tokio::test]
+async fn rest_get_user_position_test() {
+    global::log_utils::init_log_with_trace();
+    // proxy_handle();
+
+    let mut ret = get_rest();
+    let req_data = ret.get_user_position().await;
+    trace!("htx--用户仓位列表--{:?}", req_data);
+    trace!("htx--用户仓位列表--{}", req_data.data);
+}
+
+/*查询合约订单列表*/
+#[tokio::test]
+async fn rest_get_orders_test() {
+    global::log_utils::init_log_with_trace();
+    // proxy_handle();
+
+    let mut ret = get_rest();
+    let req_data = ret.get_orders("123".to_string()).await;
+    trace!("htx--查询合约订单列表--{:?}", req_data);
+    trace!("htx--查询合约订单列表--{}", req_data.data);
+}
+
+/*查询单个订单详情*/
+#[tokio::test]
+async fn rest_get_order_details_test() {
+    global::log_utils::init_log_with_trace();
+    // proxy_handle();
+
+    let mut ret = get_rest();
+    let req_data = ret.get_order_details("123".to_string()).await;
+    trace!("htx--查询单个订单详情--{:?}", req_data);
+    trace!("htx--查询单个订单详情--{}", req_data.data);
+}
+
+
 fn get_rest() -> HtxSwapRest {
     let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
     btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());