0

I have my two functions, the access attempt and the HMAC signing. It runs and returns an error(401) unauthorized, however in addition I feel my code is longer than it needs to be or redundant somehow, pointing that out would be very helpful to me, thanks in advance!

void AccessAttempt(){


        var message = Epoch.ToString () + "GET" + "/v2/payment-methods";


        const string WEBSERVICE_URL = "https://api.coinbase.com/v2/payment-methods";
        try
        {
            var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
            if (webRequest != null)
            {
                webRequest.Method = "POST";
                webRequest.ContentType = "application/json";

                webRequest.Headers.Add("CB-ACCESS-SIGN", genHMAC(message));
                webRequest.Headers.Add("CB-ACCESS-TIMESTAMP", Epoch.ToString());
                webRequest.Headers.Add("CB-ACCESS-KEY", _apiKey);

                webRequest.Headers.Add("CB-VERSION",_apiVersion);



                using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
                {
                    using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
                    {
                        var jsonResponse = sr.ReadToEnd();
                        OutputText.text = jsonResponse.ToString();
                    }
                }
            }
        }
        catch (Exception ex)
        {
            OutputText.text = ex.ToString();
        }



    }

Below is the HMAC signing function called within main function above:

private string genHMAC(string message)
    {


        byte [] APISecret_Bytes = System.Text.Encoding.UTF8.GetBytes(_apiSecret);
        HMACSHA256 hmac = new HMACSHA256(APISecret_Bytes);

        hmac.Initialize ();
        byte [] MESSAGE_Bytes = System.Text.Encoding.UTF8.GetBytes(message);
        var rawHmac = hmac.ComputeHash(MESSAGE_Bytes);



        string rawHmacString = string.Empty;
        for (int i=0; i<rawHmac.Length; i++)
        {
            rawHmacString += rawHmac[i];
        }



        string hexString = string.Empty;
        for (int i=0; i<rawHmac.Length; i++)
        {
            hexString += rawHmac[i].ToString("X2");
        }

        return hexString;

    }
DroneLord
  • 53
  • 12

1 Answers1

1

This is a pretty old question, but in case you don't have an answer yet, it looks like there are a few things wrong with your request - here is some code that works for me

public class CoinbaseV2
{
    private string APIKey;
    private string Secret;

    private const string URL_BASE = "https://api.coinbase.com";
    private const string URL_BASE_VERSION = URL_BASE + "/v2/";
    private const String GET = "GET";
    private const String POST = "POST";
    private const String PUT = "PUT";
    private const String DELETE = "DELETE";

    public CoinbaseV2(string inAPIKey, string inSecret)
    {
        APIKey = inAPIKey;
        Secret = inSecret;
    }

    public string GetUser()
    {
        return JsonRequest(URL_BASE_VERSION + "user", GET);
    }

    public string GetUserAccounts()
    {
        return JsonRequest(URL_BASE_VERSION + "accounts", GET);
    }



    private string JsonRequest(string url, string method)
    {
        // take care of any spaces in params
        url = Uri.EscapeUriString(url);

        string returnData = String.Empty;

        var webRequest = HttpWebRequest.Create(url) as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.Method = method;
            webRequest.ContentType = "application/json";

            string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(CultureInfo.CurrentCulture);
            string body = "";
            string sigurl = url.Replace(URL_BASE,"");
            string signature = GenerateSignature(timestamp,method,sigurl,body,Secret);

            var whc = new WebHeaderCollection();
            whc.Add("CB-ACCESS-SIGN", signature);
            whc.Add("CB-ACCESS-TIMESTAMP", timestamp);
            whc.Add("CB-ACCESS-KEY", APIKey);
            whc.Add("CB-VERSION", "2017-08-07");
            webRequest.Headers = whc;

            using (WebResponse response = webRequest.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(stream);
                    returnData = reader.ReadToEnd();
                }
            }
        }

        return returnData;
    }

    //https://github.com/bchavez/Coinbase
    public static string GenerateSignature(string timestamp, string method, string url, string body, string appSecret)
    {
        return GetHMACInHex(appSecret, timestamp + method + url + body).ToLower();
    }
    internal static string GetHMACInHex(string key, string data)
    {
        var hmacKey = Encoding.UTF8.GetBytes(key);
        var dataBytes = Encoding.UTF8.GetBytes(data);

        using (var hmac = new HMACSHA256(hmacKey))
        {
            var sig = hmac.ComputeHash(dataBytes);
            return ByteToHexString(sig);
        }
    }
    //https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa/14333437#14333437
    static string ByteToHexString(byte[] bytes)
    {
        char[] c = new char[bytes.Length * 2];
        int b;
        for (int i = 0; i < bytes.Length; i++)
        {
            b = bytes[i] >> 4;
            c[i * 2] = (char)(87 + b + (((b - 10) >> 31) & -39));
            b = bytes[i] & 0xF;
            c[i * 2 + 1] = (char)(87 + b + (((b - 10) >> 31) & -39));
        }
        return new string(c);
    }
}
Mike DeFehr
  • 1,164
  • 7
  • 10