private string GetAuthForWebSocket() { string apiKey = PublicApiKey.ToUnsecureString(); string param = "api_key=" + apiKey + "&secret_key=" + PrivateApiKey.ToUnsecureString(); string sign = CryptoUtility.MD5Sign(param); return($"{{ \"event\": \"login\", \"parameters\": {{ \"api_key\": \"{apiKey}\", \"sign\": \"{sign}\" }} }}"); }
protected override void ProcessRequest(HttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { request.Headers["API-key"] = PublicApiKey.ToUnsecureString(); request.Headers["Sign"] = CryptoUtility.SHA256Sign(request.RequestUri.Query.Length > 1 ? request.RequestUri.Query.Substring(1) : request.RequestUri.Query, PrivateApiKey.ToUnsecureString()).ToUpper(); } }
protected override Task ProcessRequestAsync(HttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { request.Headers["X-MBX-APIKEY"] = PublicApiKey.ToUnsecureString(); } return(base.ProcessRequestAsync(request, payload)); }
private string GetPayloadForm(Dictionary <string, object> payload) { payload["api_key"] = PublicApiKey.ToUnsecureString(); string form = CryptoUtility.GetFormForPayload(payload, false); string sign = form + "&secret_key=" + PrivateApiKey.ToUnsecureString(); sign = CryptoUtility.MD5Sign(sign); return(form + "&sign=" + sign); }
protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary <string, object> payload, string method) { if (CanMakeAuthenticatedRequest(payload)) { // payload is ignored, except for the nonce which is added to the url query - bittrex puts all the "post" parameters in the url query instead of the request body var query = (url.Query ?? string.Empty).Trim('?', '&'); url.Query = "apikey=" + PublicApiKey.ToUnsecureString() + "&nonce=" + payload["nonce"].ToStringInvariant() + (query.Length != 0 ? "&" + query : string.Empty); } return(url.Uri); }
protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { // payload is ignored, except for the nonce which is added to the url query var query = HttpUtility.ParseQueryString(url.Query); url.Query = "apikey=" + PublicApiKey.ToUnsecureString() + "&nonce=" + payload["nonce"].ToStringInvariant() + (query.Count == 0 ? string.Empty : "&" + query.ToString()); } return(url.Uri); }
protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { string payloadForm = CryptoUtility.GetFormForPayload(payload, false); request.AddHeader("API-Key", PublicApiKey.ToUnsecureString()); request.AddHeader("Sign", CryptoUtility.SHA256Sign(payloadForm, PrivateApiKey.ToBytesUTF8()).ToUpperInvariant()); await request.WriteToRequestAsync(payloadForm); } }
protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { string form = CryptoUtility.GetFormForPayload(payload); request.AddHeader("Key", PublicApiKey.ToUnsecureString()); request.AddHeader("Sign", CryptoUtility.SHA512Sign(form, PrivateApiKey.ToUnsecureString())); request.Method = "POST"; await CryptoUtility.WriteToRequestAsync(request, form); } }
protected override void ProcessRequest(HttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { string form = GetFormForPayload(payload); request.Headers["Key"] = PublicApiKey.ToUnsecureString(); request.Headers["Sign"] = CryptoUtility.SHA512Sign(form, PrivateApiKey.ToUnsecureString()); request.Method = "POST"; WriteFormToRequest(request, form); } }
//GetAmounts 8 protected override async Task <Dictionary <string, decimal> > OnGetAmountsAsync() { Dictionary <string, object> payload = new Dictionary <string, object> { { "api_key", PublicApiKey.ToUnsecureString() } }; JToken resp = await MakeJsonRequestAsync <JToken>("/user_info.do", null, (Dictionary <string, object>) payload, "POST"); CheckResponseToken(resp); return(ParseAmounts(resp, true)); }
protected override void ProcessRequest(HttpWebRequest request, Dictionary <string, object> payload) { if (payload != null && payload.ContainsKey("nonce") && PrivateApiKey != null && PublicApiKey != null) { string form = GetFormForPayload(payload); request.Headers["Key"] = PublicApiKey.ToUnsecureString(); request.Headers["Sign"] = CryptoUtility.SHA512Sign(form, PrivateApiKey.ToUnsecureString()); request.Method = "POST"; PostFormToRequest(request, form); } }
protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary <string, object> payload) { if (payload != null && payload.ContainsKey("nonce") && PrivateApiKey != null && PublicApiKey != null) { // payload is ignored, except for the nonce which is added to the url query - bittrex puts all the "post" parameters in the url query instead of the request body var query = HttpUtility.ParseQueryString(url.Query); url.Query = "apikey=" + PublicApiKey.ToUnsecureString() + "&nonce=" + payload["nonce"].ToString() + (query.Count == 0 ? string.Empty : "&" + query.ToString()); return(url.Uri); } return(url.Uri); }
//CancelOrder 12 protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) { Dictionary <string, object> payload = new Dictionary <string, object> { { "api_key", PublicApiKey.ToUnsecureString() }, { "order_id", orderId }, { "symbol", symbol }, }; JToken resp = await MakeJsonRequestAsync <JToken>("/cancel_order.do", null, payload, "POST"); CheckResponseToken(resp); }
protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary <string, object> payload) { var formData = await request.WritePayloadFormToRequestAsync(payload) .ConfigureAwait(false); if (CanMakeAuthenticatedRequest(payload)) { request.AddHeader("Rest-Key", PublicApiKey.ToUnsecureString()); var signKey = GetSignKey(request, formData); request.AddHeader("Rest-Sign", signKey); } }
protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary <string, object> payload, string method) { if (CanMakeAuthenticatedRequest(payload)) { if (!payload.ContainsKey("method")) { return(url.Uri); } method = payload["method"].ToStringInvariant(); payload.Remove("method"); var dict = new Dictionary <string, object> { ["Timestamp"] = DateTime.UtcNow.ToString("s"), ["AccessKeyId"] = PublicApiKey.ToUnsecureString(), ["SignatureMethod"] = "HmacSHA256", ["SignatureVersion"] = "2" }; string msg = null; if (method == "GET") { dict = dict.Concat(payload).ToDictionary(x => x.Key, x => x.Value); } msg = CryptoUtility.GetFormForPayload(dict, false); // must sort case sensitive msg = string.Join("&", new SortedSet <string>(msg.Split('&'), StringComparer.Ordinal)); StringBuilder sb = new StringBuilder(); sb.Append(method).Append("\n") .Append(url.Host).Append("\n") .Append(url.Path).Append("\n") .Append(msg); var sign = CryptoUtility.SHA256SignBase64(sb.ToString(), PrivateApiKey.ToBytesUTF8()); var signUrl = sign.UrlEncode(); msg += $"&Signature={signUrl}"; /* * // Huobi rolled this back, it is no longer needed. Leaving it here in case they change their minds again. * // https://github.com/huobiapi/API_Docs_en/wiki/Signing_API_Requests * // API Authentication Change * var privateSign = GetPrivateSignatureStr(Passphrase.ToUnsecureString(), sign); * var privateSignUrl = privateSign.UrlEncode(); * msg += $"&PrivateSignature={privateSignUrl}"; */ url.Query = msg; } return(url.Uri); }
//GetCompletedOrderDetails 11 protected override async Task <IEnumerable <ExchangeOrderResult> > OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime?afterDate = null) { Dictionary <string, object> payload = new Dictionary <string, object> { { "api_key", PublicApiKey.ToUnsecureString() }, { "symbol", marketSymbol } }; JToken resp = await MakeJsonRequestAsync <JToken>("/orders_info_history.do", null, payload, "POST"); CheckResponseToken(resp); return(ParseOrderList(resp, ExchangeAPIOrderResult.Filled)); }
protected override Task ProcessRequestAsync(IHttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { request.AddHeader("X-MBX-APIKEY", PublicApiKey.ToUnsecureString()); } // Needed in order to get listening key if (payload == null && request.RequestUri.AbsoluteUri.Contains("userDataStream")) { request.AddHeader("X-MBX-APIKEY", PublicApiKey.ToUnsecureString()); } return(base.ProcessRequestAsync(request, payload)); }
protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary <string, object> payload) { // Only Private APIs are POST and need Authorization if (CanMakeAuthenticatedRequest(payload) && request.Method == "POST") { var msg = CryptoUtility.GetFormForPayload(payload); var sig = CryptoUtility.SHA512Sign(msg, PrivateApiKey.ToUnsecureString()); request.AddHeader("Key", PublicApiKey.ToUnsecureString()); request.AddHeader("Sign", sig.ToLowerInvariant()); byte[] content = msg.ToBytesUTF8(); await request.WriteAllAsync(content, 0, content.Length); } }
protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary <string, object> payload, string method) { if (CanMakeAuthenticatedRequest(payload)) { /* * 基于安全考虑,除行情API 外的 API 请求都必须进行签名运算。一个合法的请求由以下几部分组成: * 方法请求地址 即访问服务器地址:api.huobi.pro,api.hadax.com或者api.dm.huobi.br.com后面跟上方法名,比如api.huobi.pro/v1/order/orders。 * API 访问密钥(AccessKeyId) 您申请的 APIKEY 中的AccessKey。 * 签名方法(SignatureMethod) 用户计算签名的基于哈希的协议,此处使用 HmacSHA256。 * 签名版本(SignatureVersion) 签名协议的版本,此处使用2。 * 时间戳(DateTime) 您发出请求的时间 (UTC 时区) (UTC 时区) (UTC 时区) 。在查询请求中包含此值有助于防止第三方截取您的请求。如:2017-05-11T16:22:06。再次强调是 (UTC 时区) 。 * 必选和可选参数 每个方法都有一组用于定义 API 调用的必需参数和可选参数。可以在每个方法的说明中查看这些参数及其含义。 请一定注意:对于GET请求,每个方法自带的参数都需要进行签名运算; 对于POST请求,每个方法自带的参数不进行签名认证,即POST请求中需要进行签名运算的只有AccessKeyId、SignatureMethod、SignatureVersion、Timestamp四个参数,其它参数放在body中。 * 签名 签名计算得出的值,用于确保签名有效和未被篡改。 */ // must sort case sensitive var dict = new SortedDictionary <string, object>(StringComparer.Ordinal) { ["DateTime"] = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(payload["nonce"].ConvertInvariant <long>()) .ToString("s"), //这里的逻辑是生成一个随机数,然后把这个随机数转成正常的日期。然后转成UTC时间 带T的那种 。有点脱了裤子放屁的感觉。 ["AccessKeyId"] = PublicApiKey.ToUnsecureString(), ["SignatureMethod"] = "HmacSHA256", ["SignatureVersion"] = "2" }; if (method == "GET") //只有get需要验证参数内的内容 { foreach (var kv in payload) { dict.Add(kv.Key, kv.Value); } } string msg = dict.GetFormForPayload(false, false, false); string toSign = $"{method}\n{url.Host}\n{url.Path}\n{msg}"; // calculate signature var sign = CryptoUtility.SHA256SignBase64(toSign, PrivateApiKey.ToUnsecureBytesUTF8()).UrlEncode(); // append signature to end of message msg += $"&Signature={sign}"; url.Query = msg; } return(url.Uri); }
protected override async Task ProcessRequestAsync(HttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { payload.Remove("nonce"); payload["api_key"] = PublicApiKey.ToUnsecureString(); var msg = CryptoUtility.GetFormForPayload(payload, false); msg = string.Join("&", new SortedSet <string>(msg.Split('&'), StringComparer.Ordinal)); var sign = msg + "&secret_key=" + PrivateApiKey.ToUnsecureString(); sign = CryptoUtility.MD5Sign(sign); msg += "&sign=" + sign; await CryptoUtility.WriteToRequestAsync(request, msg); } }
protected override void ProcessRequest(HttpWebRequest request, Dictionary <string, object> payload) { if (payload != null && payload.ContainsKey("nonce") && PrivateApiKey != null && PublicApiKey != null) { payload.Add("request", request.RequestUri.AbsolutePath); string json = JsonConvert.SerializeObject(payload); string json64 = System.Convert.ToBase64String(Encoding.ASCII.GetBytes(json)); string hexSha384 = CryptoUtility.SHA384Sign(json64, PrivateApiKey.ToUnsecureString()); request.Headers["X-BFX-PAYLOAD"] = json64; request.Headers["X-BFX-SIGNATURE"] = hexSha384; request.Headers["X-BFX-APIKEY"] = PublicApiKey.ToUnsecureString(); request.Method = "POST"; // bitfinex doesn't put the payload in the post body it puts it in as a http header, so no need to write to request stream } }
//CancelOrder 12 protected override async Task OnCancelOrderAsync(string orderId, string symbol = null, bool isClientOrderId = false) { if (isClientOrderId) { throw new NotSupportedException("Cancelling by client order ID is not supported in ExchangeSharp. Please submit a PR if you are interested in this feature"); } Dictionary <string, object> payload = new Dictionary <string, object> { { "api_key", PublicApiKey.ToUnsecureString() }, { "order_id", orderId }, { "symbol", symbol }, }; JToken resp = await MakeJsonRequestAsync <JToken>("/cancel_order.do", null, payload, "POST"); CheckResponseToken(resp); }
protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { // ensure nonce is the last parameter string nonce = payload["nonce"].ToStringInvariant(); payload.Remove("nonce"); var msg = CryptoUtility.GetFormForPayload(payload) + "&nonce=" + nonce; var sig = CryptoUtility.SHA512Sign(msg, CryptoUtility.ToBytesUTF8(PrivateApiKey)).ToLowerInvariant(); request.AddHeader("Sign", sig); request.AddHeader("Key", PublicApiKey.ToUnsecureString()); byte[] content = msg.ToBytesUTF8(); await request.WriteAllAsync(content, 0, content.Length); } }
protected override async Task ProcessRequestAsync(HttpWebRequest request, Dictionary <string, object> payload) { // Only Private APIs are POST and need Authorization if (CanMakeAuthenticatedRequest(payload) && request.Method == "POST") { var msg = CryptoUtility.GetFormForPayload(payload); var sig = CryptoUtility.SHA512Sign(msg, PrivateApiKey.ToUnsecureString()); request.Headers.Add("Key", PublicApiKey.ToUnsecureString()); request.Headers.Add("Sign", sig.ToLower()); using (Stream stream = await request.GetRequestStreamAsync()) { byte[] content = Encoding.UTF8.GetBytes(msg); stream.Write(content, 0, content.Length); } } }
//PlaceOrder 9 protected override async Task <ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrderRequest order) { Dictionary <string, object> payload = new Dictionary <string, object> { { "amount", order.Amount }, { "api_key", PublicApiKey.ToUnsecureString() }, { "price", order.Price }, { "symbol", order.MarketSymbol }, { "type", order.IsBuy ? "buy" : "sell" } }; JToken resp = await MakeJsonRequestAsync <JToken>("/create_order.do", null, payload, "POST"); CheckResponseToken(resp); return(ParsePlaceOrder(resp, payload)); }
protected override async Task ProcessRequestAsync(HttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { var nonce = payload["nonce"].ConvertInvariant <long>(); payload.Remove("nonce"); var msg = CryptoUtility.GetJsonForPayload(payload); var sign = $"{request.Method}{request.RequestUri.AbsolutePath}{request.RequestUri.Query}{nonce}{msg}"; string signature = CryptoUtility.SHA256Sign(sign, CryptoUtility.ToBytes(PrivateApiKey)); request.Headers["api-nonce"] = nonce.ToStringInvariant(); request.Headers["api-key"] = PublicApiKey.ToUnsecureString(); request.Headers["api-signature"] = signature; await CryptoUtility.WritePayloadJsonToRequestAsync(request, payload); } }
protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { // convert nonce to long, trim off milliseconds var nonce = payload["nonce"].ConvertInvariant <long>(); payload.Remove("nonce"); var msg = CryptoUtility.GetJsonForPayload(payload); var sign = $"{request.Method}{request.RequestUri.AbsolutePath}{request.RequestUri.Query}{nonce}{msg}"; string signature = CryptoUtility.SHA256Sign(sign, CryptoUtility.ToUnsecureBytesUTF8(PrivateApiKey)); request.AddHeader("api-expires", nonce.ToStringInvariant()); request.AddHeader("api-key", PublicApiKey.ToUnsecureString()); request.AddHeader("api-signature", signature); await CryptoUtility.WritePayloadJsonToRequestAsync(request, payload); } }
protected override async Task ProcessRequestAsync(HttpWebRequest request, Dictionary <string, object> payload) { if (CanMakeAuthenticatedRequest(payload)) { if (string.IsNullOrWhiteSpace(CustomerId)) { throw new APIException("Customer ID is not set for Bitstamp"); } // messageToSign = nonce + customer_id + api_key string apiKey = PublicApiKey.ToUnsecureString(); string messageToSign = payload["nonce"].ToStringInvariant() + CustomerId + apiKey; string signature = CryptoUtility.SHA256Sign(messageToSign, PrivateApiKey.ToUnsecureString()).ToUpperInvariant(); payload["signature"] = signature; payload["key"] = apiKey; await CryptoUtility.WritePayloadFormToRequestAsync(request, payload); } }
//GetOrderDetails 13 protected override async Task <ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string symbol = null) { Dictionary <string, object> payload = new Dictionary <string, object> { { "api_key", PublicApiKey.ToUnsecureString() }, { "order_id", orderId }, { "symbol", symbol } }; JToken resp = await MakeJsonRequestAsync <JToken>("/orders_info.do", null, payload, "POST"); CheckResponseToken(resp); var orderResultList = ParseOrderList(resp, ExchangeAPIOrderResult.Unknown); CheckResponseList(orderResultList, orderId); return(orderResultList[0]); }
protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary <string, object> payload, string method) { if (CanMakeAuthenticatedRequest(payload)) { if (!payload.ContainsKey("method")) { return(url.Uri); } method = payload["method"].ToStringInvariant(); payload.Remove("method"); var dict = new Dictionary <string, object> { ["Timestamp"] = DateTime.UtcNow.ToString("s"), ["AccessKeyId"] = PublicApiKey.ToUnsecureString(), ["SignatureMethod"] = "HmacSHA256", ["SignatureVersion"] = "2" }; string msg = null; if (method == "GET") { dict = dict.Concat(payload).ToDictionary(x => x.Key, x => x.Value); } msg = CryptoUtility.GetFormForPayload(dict, false); // must sort case sensitive msg = string.Join("&", new SortedSet <string>(msg.Split('&'), StringComparer.Ordinal)); StringBuilder sb = new StringBuilder(); sb.Append(method).Append("\n") .Append(url.Host).Append("\n") .Append(url.Path).Append("\n") .Append(msg); var sig = CryptoUtility.SHA256SignBase64(sb.ToString(), PrivateApiKey.ToBytes()); msg += "&Signature=" + Uri.EscapeDataString(sig); url.Query = msg; } return(url.Uri); }