I'm modifying the current Coinbase Php Gem to use the new Key+Secret API authentication. I think I'm following their instructions perfectly, but I always get a response: "error":"ACCESS_SIGNATURE does not validate"
So far, I have:
- Confirmed that the signature is a lowercase hex hash
- Confirmed from the CB callback that my access key is accepted
- Confirmed from the CB callback that my nonce is valid
- Confirmed that my API Secret Key is correct
My test is a POST request to https://coinbase.com/api/v1/buttons
with a few $params. It worked using the old API method. I'm not sure what I'm doing wrong under this new API method.
Here's the modified Coinbase_Rpc::request method:
public function request($method, $url, $params)
{
if ($this->_apiKey === null) {
throw new Coinbase_ApiException("Invalid API key", 500, "An invalid API key was provided.");
}
$url = Coinbase::API_BASE . $url;
$nonce = (int)(microtime(true) * 100);
// Create query string
$queryString = http_build_query($params);
// Initialize CURL
$curl = curl_init();
$curlOpts = array();
// HTTP method
$method = strtolower($method);
if ($method == 'get') {
$curlOpts[CURLOPT_HTTPGET] = 1;
$url .= "?" . $queryString;
} else if ($method == 'post') {
$curlOpts[CURLOPT_POST] = 1;
$curlOpts[CURLOPT_POSTFIELDS] = $queryString;
} else if ($method == 'delete') {
$curlOpts[CURLOPT_CUSTOMREQUEST] = "DELETE";
$url .= "?" . $queryString;
} else if ($method == 'put') {
$curlOpts[CURLOPT_CUSTOMREQUEST] = "PUT";
$curlOpts[CURLOPT_POSTFIELDS] = $queryString;
}
// Headers
$headers = array(
'User-Agent: CoinbasePHP/v1',
'Accept: */*',
'Connection: close',
'Host: coinbase.com',
'ACCESS_KEY: ' . $this->_apiKey,
'ACCESS_NONCE: ' . $nonce,
'ACCESS_SIGNATURE: ' . hash_hmac("sha256", $nonce . $url, $this->_apiSecret)
);
// CURL options
$curlOpts[CURLOPT_URL] = $url;
$curlOpts[CURLOPT_HTTPHEADER] = $headers;
$curlOpts[CURLOPT_CAINFO] = dirname(__FILE__) . '/ca-coinbase.crt';
$curlOpts[CURLOPT_RETURNTRANSFER] = true;
// Do request
curl_setopt_array($curl, $curlOpts);
$response = $this->_requestor->doCurlRequest($curl);
// Decode response
try {
$json = json_decode($response['body']);
} catch (Exception $e) {
throw new Coinbase_ConnectionException("Invalid response body", $response['statusCode'], $response['body']);
}
if ($json === null) {
throw new Coinbase_ApiException("Invalid response body", $response['statusCode'], $response['body']);
}
if (isset($json->error)) {
throw new Coinbase_ApiException($json->error, $response['statusCode'], $response['body']);
} else if (isset($json->errors)) {
throw new Coinbase_ApiException(implode($json->errors, ', '), $response['statusCode'], $response['body']);
}
return $json;
}
Any ideas?
EDIT: Though not modified above, it is fixed, and the full PHP Gem is available here: https://github.com/Luth/CoinbasePhpGem