I'm trying to use the advanced trade API from Coinbase in PHP. They decided to go with JWT but didn't give an example in PHP.
So I tried this code of mine but it is returning NULL. I have checked many times the API key. The details are correct. Here is the link to the Coinbase doc: https://docs.cloud.coinbase.com/advanced-trade-api/docs/rest-api-auth
use Firebase\JWT\JWT;
$keyName = 'organizations/b0f974e{redacted}860/apiKeys/d840f8{redacted}b6d';
$keySecret = "-----BEGIN EC PRIVATE KEY-----\nMHcC{redacted}bHEzMVwDhg==\n-----END EC PRIVATE KEY-----\n";
$requestMethod = "GET";
$requestHost = "api.coinbase.com";
$requestPath = "/api/v3/brokerage/accounts";
function buildJwt($uri, $keyName, $keySecret) {
$privateKeyResource = openssl_pkey_get_private($keySecret);
if (!$privateKeyResource) {
throw new Exception('Private key could not be parsed or is invalid.');
}
$payload = [
'sub' => $keyName,
'iss' => 'coinbase-cloud',
'iat' => time(),
'exp' => time() + 120, // Token expiration time (example: 120 seconds from now)
'uri' => $uri,
];
$jwt = JWT::encode($payload, $privateKeyResource, 'ES256');
return $jwt;
}
function main($requestMethod, $requestHost, $requestPath, $keyName, $keySecret) {
$uri = "$requestMethod $requestHost$requestPath";
$jwtToken = buildJwt($uri, $keyName, $keySecret);
return $jwtToken;
}
$myjwt = main($requestMethod, $requestHost, $requestPath, $keyName, $keySecret);
function getAccountDetails($jwt, $requestMethod, $requestHost, $requestPath) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://$requestHost$requestPath",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => $requestMethod,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $jwt",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
return json_decode($response, true);
}
}
$res = getAccountDetails($myjwt, $requestMethod, $requestHost, $requestPath);
var_dump($res);
I too had this error and this was how I solved it. There really isn't much documentation or resources online on how to do this via PHP so hopefully this can help others.
I essentially did this by converting the provided python example code from coinbase into php, and then tweaked it until it worked. It was a very long convoluted testing process so I wont note it all down here but for any other PHP conversions it is best to start with a working example in another language and recreate it best you can in php. If that fails, chatGPT.
This method will generate a JWT for any GET request. To create one for POST requests you need to change the $request_method variable.
A new JWT token needs to be created for each unique request.
<?php
require '../../vendor/autoload.php';
use \Firebase\JWT\JWT;
function createMyJWT($request_path)
{
$key_name = 'organizations/9xxxxxxa-93ce-4f50-bee9-4xxxxxxxxxxd/apiKeys/2xxxxxxx0-5aea-47c8-9445-cxxxxxxxxxxf';
$key_secret = "-----BEGIN EC PRIVATE KEY-----\nMxxxxxxxxxxxxxxxxxxxxxxxxxl4/NxxxxxxxxxS/rtxxxxxxxxxxxxxxxxxxxxxxxxM49\nAxxxxxxxxxQgAEc2/6Bxxxxxxxl+oxxxxxxxxxxhc/SxxxxxxxxxxxxxxxxxxxxxxY\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9A==\n-----END EC PRIVATE KEY-----\n";
$request_method = 'GET';
$url = 'api.coinbase.com';
$algorithm = 'ES256';
$uri = $request_method . ' ' . $url . $request_path;
$token = JWT::encode(
[
'iss' => 'coinbase-cloud',
'nbf' => time(),
'exp' => time() + 120,
'sub' => $key_name,
'uri' => $uri
],
$key_secret,
$algorithm,
null,
[
'kid' => $key_name,
'nonce' => bin2hex(random_bytes(16))
]
);
return $token;
}
?>