How to create new account with ECDSA key

Hi, I develop the client that are compatible with ACME v2.

I tried to create new account with ECDSA key, but run into an problem.
Can you please teach me the right way to create new account with ECDSA key?

In case of RSA key, I succeeded in creation new account.

<?php

namespace {
    require_once __DIR__ . '/../vendor/autoload.php';

    $resource = openssl_pkey_new([
        'private_key_type' => OPENSSL_KEYTYPE_RSA,
        'private_key_bits' => 2048,
    ]);

    openssl_pkey_export($resource, $privkey);
    $details = openssl_pkey_get_details($resource);
    openssl_free_key($resource);

    $guzzle   = new \GuzzleHttp\Client();
    $response = $guzzle->head('https://acme-staging-v02.api.letsencrypt.org/directory');
    $nonce    = $response->getHeaderLine('Replay-Nonce');

    $header = base64_url_safe_encode(json_encode([
            'alg' => 'RS256',
            'jwk' => [
                'kty' => 'RSA',
                'n'   => base64_url_safe_encode($details['rsa']['n']),
                'e'   => base64_url_safe_encode($details['rsa']['e']),
            ],
            'nonce' => $nonce,
            'url'   => 'https://acme-staging-v02.api.letsencrypt.org/acme/new-acct',
    ]));

    $payload = base64_url_safe_encode(json_encode([
        'contact' => [],
        'termsOfServiceAgreed' => true,
    ]));

    openssl_sign($header . '.' . $payload, $signature, $privkey, 'sha256');

    $jws = json_encode([
        'protected' => $header,
        'payload'   => $payload,
        'signature' => base64_url_safe_encode($signature),
    ]);

    $response = $guzzle->post('https://acme-staging-v02.api.letsencrypt.org/acme/new-acct', [
        'headers' => [
            'Accept'       => 'application/jose+json',
            'Content-Type' => 'application/jose+json',
        ],
        'body' => $jws,
    ]);

    var_dump((string)$response->getBody());
}

In case of ECDSA key, I failed to create new account.

<?php

namespace {
    require_once __DIR__ . '/../vendor/autoload.php';

    $resource = openssl_pkey_new([
        'private_key_type' => OPENSSL_KEYTYPE_EC,
        'curve_name' => 'prime256v1',
    ]);

    openssl_pkey_export($resource, $privkey);
    $details = openssl_pkey_get_details($resource);
    openssl_free_key($resource);

    $guzzle   = new \GuzzleHttp\Client();
    $response = $guzzle->head('https://acme-staging-v02.api.letsencrypt.org/directory');
    $nonce    = $response->getHeaderLine('Replay-Nonce');

    $header = base64_url_safe_encode(json_encode([
        'alg' => 'ES256',
        'jwk' => [
            'kty' => 'EC',
            'crv' => 'P-256',
            'x'   => base64_url_safe_encode($details['ec']['x']),
            'y'   => base64_url_safe_encode($details['ec']['y']),
        ],
        'nonce' => $nonce,
        'url'   => 'https://acme-staging-v02.api.letsencrypt.org/acme/new-acct',
    ]));

    $payload = base64_url_safe_encode(json_encode([
        'contact' => [],
        'termsOfServiceAgreed' => true,
    ]));

    openssl_sign($header . '.' . $payload, $signature, $privkey, 'sha256');

    $jws = json_encode([
        'protected' => $header,
        'payload'   => $payload,
        'signature' => base64_url_safe_encode($signature),
    ]);

    $response = $guzzle->post('https://acme-staging-v02.api.letsencrypt.org/acme/new-acct', [
        'headers' => [
            'Accept'       => 'application/jose+json',
            'Content-Type' => 'application/jose+json',
        ],
        'body' => $jws,
    ]);

    var_dump((string)$response->getBody());
}

Thanks.