Search code examples
phpguzzlecoinbase-api

How to fix Coinbase api invalid signature error?


I want to know all my accounts by coinbase api endpoint so following this link: https://developers.coinbase.com/api/v2?shell#list-accounts i have done this:

        $path = '/v2/accounts';
        $signature = $this->signature($path);

        try {
            $client = new \GuzzleHttp\Client();

            $response = $client->request('GET', 'https://api.coinbase.com' . $path, [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'CB-ACCESS-KEY' => $this->key,
                    'CB-ACCESS-SIGN' => $signature,
                    'CB-ACCESS-TIMESTAMP' => time(),
                    'CB-VERSION' => '2015-04-08',
                ]
            ]);

            echo $response->getBody();
        } catch (\Throwable $th) {
            dd($th);
        }

And the signature function is:

    public function signature($request_path = '', $body = '', $timestamp = false, $method = 'GET')
    {
        $body = is_array($body) ? json_encode($body) : $body;
        $timestamp = $timestamp ? $timestamp : time();

        $what = $timestamp . $method . $request_path . $body;

        return base64_encode(hash_hmac("sha256", $what, base64_decode($this->secret)), true);
    }

When i write $path = '/v2/time' it works but with $path = '/v2/accounts/' it gaves me an error:

{"errors":[{"id":"authentication_error","message":"invalid signature"}]


Solution

  • I have changed my signature function to this:

        public function signature($cbPro, $request_path = '', $body = '', $method = 'GET', $timestamp = false)
        {
            $body = is_array($body) ? json_encode($body) : $body;
            $timestamp = $timestamp ? $timestamp : time();
    
            $what = $timestamp . $method . $request_path . $body;
    
            if ($cbPro)
                return base64_encode(hash_hmac("sha256", $what, base64_decode($this->secret), true)); // For CB Pro/Exchange
            else
                return hash_hmac('SHA256', $what, $this->secret); // The solution for CB api v2
        }
    

    Seems Coinbase and Coinbase Pro doesn't have the same signature. For now that i am using Coinbase api, i take the 2nd return of my function,the first one is for CB Pro, or Exchange. a simple hash_hmac() solved my problem. I was looking further uselessly