Search code examples
c#apirestsharpbitcoin

RestSharp BitStamp Authentication fails


I'm not able to receive any data from the BitStamp API. What am I doing wrong here? My content form the response results in an error:

{"error": "Missing key, signature and nonce parameters"}

        public ActionResult Index()
        {
            const string BaseUrl = "https://www.bitstamp.net/api/balance/";
            var client = new RestClient();
            var request = new RestRequest();

            client.BaseUrl = BaseUrl;
            AddApiAuthentication(request);
            var response = client.Execute(request);
            var foo = response.Content;
            //{"error": "Missing key, signature and nonce parameters"}
            return View();
        }

        public void AddApiAuthentication(RestRequest restRequest)
        {
            var nonce = DateTime.Now.Ticks;
            var signature = GetSignature(nonce, apiKey, apiSecret, clientId);

            restRequest.AddParameter("key", apiKey);
            restRequest.AddParameter("signature", signature);
            restRequest.AddParameter("nonce", nonce);

        }

        private string GetSignature(long nonce, string key, string secret, string clientId)
        {
            string msg = string.Format("{0}{1}{2}", nonce, clientId, key);
            return ByteArrayToString(SignHMACSHA256(secret, StrinToByteArray(msg))).ToUpper();
        }

        public static byte[] SignHMACSHA256(String key, byte[] data)
        {
            HMACSHA256 hashMaker = new HMACSHA256(Encoding.ASCII.GetBytes(key));
            return hashMaker.ComputeHash(data);
        }

        public static byte[] StrinToByteArray(string str)
        {
            return System.Text.Encoding.ASCII.GetBytes(str);
        }

        public static string ByteArrayToString(byte[] hash)
        {
            return BitConverter.ToString(hash).Replace("-", "").ToLower();
        }

The API authentication seems to work for the user in this post. Am I executing the request in the right way?


Solution

  • For our new application we used the following code:

    public class BitstampAuthenticatedRequest : RestRequest
    {
        #region Data
        private readonly string _clientId = "xxxxx"; // Numbers
    
        private readonly string _apiKey = "xxxxx"; // Random numbers and letters
        private readonly string _apiSecret = "xxxx"; // Random numbers and letters
    
        private long Nonce = DateTime.Now.Ticks;
    
        #endregion
    
        #region Constructor
    
        public BitstampAuthenticatedRequest(string resource, Method method)
        : base(resource, method)
        {
            this.AddParameter("key", _apiKey);            
            this.AddParameter("nonce", Nonce);
            this.AddParameter("signature", CreateSignature());
        }
    
        #endregion
    
        #region Methods
    
        private string CreateSignature()
        {
            string msg = string.Format("{0}{1}{2}", Nonce,
                _clientId,
                _apiKey);
    
            return ByteArrayToString(SignHMACSHA256(_apiSecret, StringToByteArray(msg))).ToUpper();
        }
    
        private static byte[] SignHMACSHA256(String key, byte[] data)
        {
            HMACSHA256 hashMaker = new HMACSHA256(Encoding.ASCII.GetBytes(key));
            return hashMaker.ComputeHash(data);
        }
    
        private static byte[] StringToByteArray(string str)
        {
            return System.Text.Encoding.ASCII.GetBytes(str);
        }
    
        private static string ByteArrayToString(byte[] hash)
        {
            return BitConverter.ToString(hash).Replace("-", "").ToLower();
        }
    
        #endregion
    }
    

    And call it like:

            // Decide which url to use
            var baseUrl = "https://www.bitstamp.net/api/balance/";
    
            // Create the authenticated request
            RestRequest request = new BitstampAuthenticatedRequest(baseUrl, Method.POST);
    
            // Get the response
            var response = new RestClient().Execute(request);
    

    Justed tested the code again in console application and works for sure. If you need further help just comment.