Используя новый ключ 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 находится здесь:

https://github.com/Luth/CoinbasePhpGem

Другие вопросы по тегам