Используя новый ключ Coinbase + Secret, я не могу создать действительный ADDRESS_SIGNATURE. Что не так с этим кодом?
Я модифицирую текущий Gem Coinbase Php для использования новой аутентификации Key+Secret API. Я думаю, что я отлично следую их инструкциям, но я всегда получаю ответ: "error":"ACCESS_SIGNATURE does not validate"
Пока что у меня есть:
- Подтверждено, что подпись является шестнадцатеричным хешем в нижнем регистре
- От обратного вызова CB подтвердил, что мой ключ доступа принят
- От обратного вызова CB подтвердил, что мой nonce действителен
- Подтвердил, что мой секретный ключ API правильный
Мой тест - это POST-запрос к https://coinbase.com/api/v1/buttons
с несколькими $params. Это работало с использованием старого метода API. Я не уверен, что я делаю неправильно в этом новом методе API.
Вот модифицированный метод Coinbase_Rpc::request:
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;
}
Есть идеи?
РЕДАКТИРОВАТЬ: хотя не изменено выше, это исправлено, и полный Gem PHP доступен здесь: https://github.com/Luth/CoinbasePhpGem
2 ответа
РЕДАКТИРОВАТЬ: Вот что я в конечном итоге использовать:
<?php
function coinbaseRequest($what,$getOrPost,$parameters){
$apikey = "blahblahblah";
$apisecret = "blahblahblahblah";
$nonce = file_get_contents("nonce.txt") + 1;
file_put_contents("nonce.txt", $nonce, LOCK_EX);
$url = "https://coinbase.com/api/v1/" . $what . "?nonce=" . $nonce;
if($parameters != ""){
$parameters = http_build_query(json_decode($parameters), true);
}
$signature = hash_hmac("sha256", $nonce . $url . $parameters, $apisecret);
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
"ACCESS_KEY: " . $apikey,
"ACCESS_NONCE: " . $nonce,
"ACCESS_SIGNATURE: " . $signature
)));
if($getOrPost == "post"){
curl_setopt_array($ch, array(
CURLOPT_POSTFIELDS => $parameters,
CURLOPT_POST => true,
));
}
$results = curl_exec($ch);
curl_close($ch);
echo $results;
}
//This is a POST example
coinbaseRequest("buttons", "post",
'{
"button": {
"name": "test",
"price_string": "1.23",
"price_currency_iso": "USD",
"variable_price": true
}
}');
//This is a GET example. Note that the 3rd parameter is false.
coinbaseRequest("account/balance", "get", false);
?>
Вы должны быть в состоянии просто скопировать и вставить это, заменить $apisecret
а также $apikey
, и вы будете готовы к рок!
Глупый я, CURLOPT_POSTFIELDS тоже нужно хэшировать. Полная версия Coinbase PHP Gem с использованием авторизации Key + Secret находится здесь: