gate_swap_rest_utils.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. use std::collections::BTreeMap;
  2. use hex;
  3. use hmac::{Hmac, Mac, NewMac};
  4. use ring::digest;
  5. use rust_decimal::Decimal;
  6. use rust_decimal_macros::dec;
  7. use serde_json::Value;
  8. use sha2::Sha512;
  9. use tracing::info;
  10. use crate::http::request::Response;
  11. use crate::utils::utils::parse_params_to_str;
  12. #[derive(Clone)]
  13. #[allow(dead_code)]
  14. pub struct GateSwapRest {
  15. label: String,
  16. base_url: String,
  17. client: reqwest::Client,
  18. /*******参数*/
  19. //登陆所需参数
  20. login_param: BTreeMap<String, String>,
  21. delays: Vec<i64>,
  22. max_delay: i64,
  23. avg_delay: Decimal,
  24. }
  25. impl GateSwapRest {
  26. /*******************************************************************************************************/
  27. /*****************************************获取一个对象****************************************************/
  28. /*******************************************************************************************************/
  29. pub fn new(is_colo: bool, login_param: BTreeMap<String, String>) -> GateSwapRest
  30. {
  31. return GateSwapRest::new_label("default-GateSwapRest".to_string(), is_colo, login_param);
  32. }
  33. pub fn new_label(label: String, is_colo: bool, login_param: BTreeMap<String, String>) -> GateSwapRest
  34. {
  35. let base_url = if is_colo {
  36. let url = "https://apiv4-private.gateapi.io".to_string();
  37. info!("开启高速通道:{:?}",url);
  38. url
  39. } else {
  40. let url = "https://api.gateio.ws".to_string();
  41. info!("走普通通道:{}",url);
  42. url
  43. };
  44. if is_colo {} else {}
  45. /*****返回结构体*******/
  46. GateSwapRest {
  47. label,
  48. base_url: base_url.to_string(),
  49. client: reqwest::Client::new(),
  50. login_param,
  51. delays: vec![],
  52. max_delay: 0,
  53. avg_delay: dec!(0.0),
  54. }
  55. }
  56. /*******************************************************************************************************/
  57. /*****************************************rest请求函数********************************************************/
  58. //查询个人成交记录
  59. pub async fn my_trades(&mut self, settle: String, contract: String, limit: i64) -> Response {
  60. let mut params = serde_json::json!({
  61. "contract":contract,
  62. "limit":1000
  63. });
  64. if limit > 0 {
  65. params["limit"] = serde_json::json!(limit);
  66. }
  67. let data = self.request("GET".to_string(),
  68. "/api/v4".to_string(),
  69. format!("/futures/{}/my_trades", settle),
  70. true,
  71. params.to_string(),
  72. ).await;
  73. data
  74. }
  75. //查询合约账户变更历史
  76. pub async fn account_book(&mut self, settle: String, start_time: i64, end_time: i64) -> Response {
  77. let params = serde_json::json!({
  78. "limit":1000,
  79. "from":start_time-60*60*24*5,
  80. "to":end_time
  81. });
  82. let data = self.request("GET".to_string(),
  83. "/api/v4".to_string(),
  84. format!("/futures/{}/account_book", settle),
  85. true,
  86. params.to_string(),
  87. ).await;
  88. data
  89. }
  90. pub async fn fill_account_book(&mut self, settle: String, _start_time: i64, end_time: i64) -> Response {
  91. let params = serde_json::json!({
  92. "limit":1,
  93. "from":end_time-60*60*24*30,
  94. "to":end_time
  95. });
  96. let data = self.request("GET".to_string(),
  97. "/api/v4".to_string(),
  98. format!("/futures/{}/account_book", settle),
  99. true,
  100. params.to_string(),
  101. ).await;
  102. data
  103. }
  104. //调用请求
  105. async fn request(&mut self,
  106. request_type: String,
  107. prefix_url: String,
  108. request_url: String,
  109. is_login: bool,
  110. params: String) -> Response
  111. {
  112. // trace!("login_param:{:?}", self.login_param);
  113. //解析账号信息
  114. let mut access_key = "".to_string();
  115. let mut secret_key = "".to_string();
  116. if self.login_param.contains_key("access_key") {
  117. access_key = self.login_param.get("access_key").unwrap().to_string();
  118. }
  119. if self.login_param.contains_key("secret_key") {
  120. secret_key = self.login_param.get("secret_key").unwrap().to_string();
  121. }
  122. let mut is_login_param = true;
  123. if access_key == "" || secret_key == "" {
  124. is_login_param = false
  125. }
  126. //请求头配置-如果需要登陆则存在额外配置
  127. let mut body = "".to_string();
  128. let timestamp = chrono::Utc::now().timestamp().to_string();
  129. let mut headers = reqwest::header::HeaderMap::new();
  130. if request_type == "GET" {
  131. headers.insert("Content-type", "application/x-www-form-urlencoded".parse().unwrap());
  132. headers.insert("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ".parse().unwrap());
  133. } else {
  134. headers.insert("Accept", "application/json".parse().unwrap());
  135. headers.insert("Content-Type", "application/json".parse().unwrap());
  136. }
  137. if request_type == "POST" {
  138. body = params.clone();
  139. }
  140. //是否需要登陆-- 组装sing
  141. if is_login {
  142. if !is_login_param {
  143. let mut res = Response::new();
  144. res.code = "-1".to_string();
  145. res.msg = "登陆参数错误".to_string();
  146. return res;
  147. } else {//需要登陆-且登陆参数齐全
  148. //组装sing
  149. let sing = Self::sign(secret_key.clone(),
  150. request_type.clone(),
  151. prefix_url.clone(),
  152. request_url.clone(),
  153. params.clone(),
  154. body.clone(),
  155. timestamp.clone(),
  156. );
  157. // trace!("sing:{}", sing);
  158. //组装header
  159. headers.extend(Self::headers(access_key, timestamp, sing));
  160. }
  161. }
  162. // trace!("headers:{:?}", headers);
  163. let base_url = format!("{}{}", prefix_url.clone(), request_url.clone());
  164. let get_response = self.http_toll(
  165. base_url.clone(),
  166. request_type.to_string(),
  167. params.clone(),
  168. headers,
  169. ).await;
  170. let res_data = Self::res_data_analysis(get_response, base_url, params);
  171. res_data
  172. }
  173. pub fn headers(access_key: String, timestamp: String, sign: String) -> reqwest::header::HeaderMap {
  174. let mut headers = reqwest::header::HeaderMap::new();
  175. headers.insert("KEY", access_key.clone().parse().unwrap());
  176. headers.insert("Timestamp", timestamp.clone().parse().unwrap());
  177. headers.insert("SIGN", sign.clone().parse().unwrap());
  178. headers
  179. }
  180. pub fn sign(secret_key: String,
  181. request_type: String, prefix_url: String, request_url: String,
  182. params: String, body_data: String, timestamp: String) -> String
  183. {
  184. let url = format!("{}{}", prefix_url, request_url);
  185. let params_str = parse_params_to_str(params);
  186. let body = Some(body_data);
  187. let hashed_payload = if let Some(body) = body {
  188. let mut m = digest::Context::new(&digest::SHA512);
  189. m.update(body.as_bytes());
  190. hex::encode(m.finish().as_ref())
  191. } else {
  192. String::new()
  193. };
  194. // trace!("hashed_payload:{}", hashed_payload);
  195. let message = format!("{}\n{}\n{}\n{}\n{}",
  196. request_type,
  197. url,
  198. params_str,
  199. hashed_payload,
  200. timestamp);
  201. // trace!("**********", );
  202. // trace!("组装数据:{}", message);
  203. // trace!("**********", );
  204. let mut mac = Hmac::<Sha512>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
  205. mac.update(message.as_bytes());
  206. let result = mac.finalize().into_bytes();
  207. let sign = hex::encode(result);
  208. sign
  209. }
  210. async fn http_toll(&mut self, request_path: String, request_type: String, params: String, headers: reqwest::header::HeaderMap) -> Result<Response, reqwest::Error> {
  211. /****请求接口与 地址*/
  212. let url = format!("{}{}", self.base_url.to_string(), request_path);
  213. let request_type = request_type.clone().to_uppercase();
  214. let addrs_url = format!("{}?{}", url.clone(), parse_params_to_str(params.clone()));
  215. // let params_json: serde_json::Value = serde_json::from_str(&params).unwrap();
  216. // trace!("url:{}",url);
  217. // trace!("addrs_url:{}",url);
  218. // trace!("params_json:{}",params_json);
  219. // trace!("headers:{:?}",headers);
  220. let req = match request_type.as_str() {
  221. "GET" => self.client.get(addrs_url.clone()).headers(headers),
  222. "POST" => self.client.post(addrs_url.clone()).body(params).headers(headers),
  223. "DELETE" => self.client.delete(addrs_url.clone()).headers(headers),
  224. // "PUT" => self.client.put(url.clone()).json(&params),
  225. _ => {
  226. let mut res = Response::new();
  227. res.code = "-1".to_string();
  228. res.msg = "请求类型错误".to_string();
  229. res.data = "".to_string();
  230. return Ok(res);
  231. }
  232. };
  233. let response = req.send().await?;
  234. let mut res = Response::new();
  235. if response.status().is_success() {
  236. // 读取响应的内容
  237. let body = response.text().await?;
  238. res.code = "200".to_string();
  239. res.msg = "success".to_string();
  240. res.data = body;
  241. // trace!("ok-----{}", body);
  242. } else {
  243. let body = response.text().await?;
  244. res.code = "-1".to_string();
  245. res.msg = body;
  246. res.data = "".to_string();
  247. }
  248. Ok(res)
  249. }
  250. //res_data 解析
  251. pub fn res_data_analysis(result: Result<Response, reqwest::Error>, base_url: String, params: String) -> Response {
  252. let res = Response::new();
  253. match result {
  254. Ok(res_data) => {
  255. // info!("原数据:{:?}",res_data);
  256. if res_data.code != "200" {
  257. let message = res_data.msg;
  258. // let json_value: serde_json::Value = serde_json::from_str(&message).unwrap();//这种方式会触发 解析错误
  259. let json_value = serde_json::from_str::<Value>(&message);
  260. match json_value {
  261. Ok(_data) => {
  262. let mut error = Response::new();
  263. error.code = "-1".to_string();
  264. error.msg = format!("请求错误{:?}", res.msg);
  265. error.data = format!("请求地址:{},请求参数:{}", base_url, params);
  266. error
  267. }
  268. Err(e) => {
  269. // error!("解析错误:{:?}",e);
  270. let mut error = Response::new();
  271. error.code = "-1".to_string();
  272. error.msg = format!("json 解析失败:{},相关参数:{}", e, message);
  273. error.data = "".to_string();
  274. error
  275. }
  276. }
  277. } else {
  278. res_data
  279. }
  280. }
  281. Err(err) => {
  282. let mut error = Response::new();
  283. error.code = "-1".to_string();
  284. error.msg = format!("json 解析失败:{},相关参数:{}", err, params);
  285. error.data = "".to_string();
  286. error
  287. }
  288. }
  289. }
  290. }