# Class BSV::Auth::Certificate <a id="class-BSV-Auth-Certificate"></a>

**Inherits:** `Object`

Identity certificate as per the BRC-52 Wallet interface specification.

A certificate binds identity attributes (fields) to a subject public key, and
is signed by a certifier. The binary serialisation format is shared across all
BSV SDKs (Go, TypeScript, Python, Ruby) so that certificates produced by one
SDK can be verified by another.

All field values are expected to be Base64-encoded encrypted strings. Signing
and verification use BRC-42 key derivation:

*   Protocol:    +[2, 'certificate signature']+
*   Key ID:      +"#{type} #{serial_number}"+
*   Counterparty on sign:   +'anyone'+ (default for `create_signature`)
*   Counterparty on verify: the certifier's compressed public key hex

Wallet parameters are duck-typed — any object responding to
`create_signature`, `verify_signature`, and `get_public_key` is accepted. No
direct dependency on <code>BSV::Wallet::Client</code> is introduced here.

- **@see** `https://hub.bsvblockchain.org/brc/wallet/0052` BRC-52

## Constants
### `CERT_FIELD_ENC_PROTOCOL` <a id="constant-CERT_FIELD_ENC_PROTOCOL"></a> <a id="CERT_FIELD_ENC_PROTOCOL-constant"></a>
Not documented.

### `CERT_SIG_PROTOCOL` <a id="constant-CERT_SIG_PROTOCOL"></a> <a id="CERT_SIG_PROTOCOL-constant"></a>
Not documented.

## Attributes
### `certifier` [RW] <a id="attribute-i-certifier"></a> <a id="certifier-instance_method"></a>
- **@return** [String] compressed public key hex (66 characters)

### `fields` [R] <a id="attribute-i-fields"></a> <a id="fields-instance_method"></a>
- **@return** [Hash] mapping field name strings to value strings

### `revocation_outpoint` [R] <a id="attribute-i-revocation_outpoint"></a> <a id="revocation_outpoint-instance_method"></a>
- **@return** [String] outpoint string +"<txid_hex>.<output_index>"+

### `serial_number` [R] <a id="attribute-i-serial_number"></a> <a id="serial_number-instance_method"></a>
- **@return** [String] Base64 string decoding to 32 bytes

### `signature` [RW] <a id="attribute-i-signature"></a> <a id="signature-instance_method"></a>
- **@return** [String, nil] DER-encoded signature as hex string, or nil if unsigned

### `subject` [R] <a id="attribute-i-subject"></a> <a id="subject-instance_method"></a>
- **@return** [String] compressed public key hex (66 characters)

### `type` [R] <a id="attribute-i-type"></a> <a id="type-instance_method"></a>
- **@return** [String] Base64 string decoding to 32 bytes

## Public Class Methods
### `certificate_field_encryption_details(field_name, serial_number = nil)` <a id="method-c-certificate_field_encryption_details"></a> <a id="certificate_field_encryption_details-class_method"></a>
Returns the protocol ID and key ID for certificate field encryption.

When `serial_number` is provided (for verifier keyring creation) the key ID is
+"#{serial_number} #{field_name}"+. Without a serial number (for master
keyring creation) the key ID is just the `field_name`.
- **@param** `field_name` [String] name of the certificate field
- **@param** `serial_number` [String, nil] certificate serial number (Base64)
- **@return** [Hash] +{ protocol_id:, key_id: }+

### `from_binary(data)` <a id="method-c-from_binary"></a> <a id="from_binary-class_method"></a>
Deserialise a certificate from its binary format.

When a signature is present in the trailing bytes, it is parsed via
{BSV::Primitives::Signature.from_der} to ensure strict DER normalisation
before being re-serialised as hex.
- **@param** `data` [String] binary string
- **@raise** [ArgumentError]
- **@return** [Certificate]

### `from_hash(hash)` <a id="method-c-from_hash"></a> <a id="from_hash-class_method"></a>
Construct a Certificate from a plain Hash.

Accepts both snake_case and camelCase key variants for each field so that
wire-format hashes can be passed in directly.
- **@param** `hash` [Hash] certificate data with snake_case or camelCase keys
- **@return** [Certificate]

## Public Instance Methods
### `initialize(type:, serial_number:, subject:, certifier:, revocation_outpoint:, fields:, signature: = nil)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `type` [String] Base64 string (32 bytes decoded)
- **@param** `serial_number` [String] Base64 string (32 bytes decoded)
- **@param** `subject` [String] compressed public key hex
- **@param** `certifier` [String] compressed public key hex
- **@param** `revocation_outpoint` [String] +"<txid_hex>.<output_index>"+
- **@param** `fields` [Hash] field name strings to value strings
- **@param** `signature` [String, nil] DER-encoded signature hex, or nil
- **@return** [Certificate] a new instance of Certificate

### `sign(certifier_wallet)` <a id="method-i-sign"></a> <a id="sign-instance_method"></a>
Sign the certificate using the provided certifier wallet.

The certifier field is updated to the wallet's identity key before signing.
Raises if the certificate is already signed.
- **@param** `certifier_wallet` [#create_signature, #get_public_key] certifier wallet
- **@raise** [ArgumentError] if the certificate already has a signature

### `to_binary(include_signature: = true)` <a id="method-i-to_binary"></a> <a id="to_binary-instance_method"></a>
Serialise the certificate into its binary format.

The binary format is byte-compatible with all other BSV SDK implementations.
Fields are sorted lexicographically by name.
- **@param** `include_signature` [Boolean] whether to append the signature bytes
- **@return** [String] binary string

### `to_h()` <a id="method-i-to_h"></a> <a id="to_h-instance_method"></a>
Return the certificate as a plain Hash with snake_case keys.

JSON serialisation is simply <code>cert.to_h.to_json</code>.
- **@return** [Hash]

### `verify(verifier_wallet = nil)` <a id="method-i-verify"></a> <a id="verify-instance_method"></a>
Verify the certificate's signature.

Uses a fresh +'anyone'+ ProtoWallet as the verifier, which matches the TS SDK
behaviour. If no signature is present, raises `ArgumentError`.
- **@param** `verifier_wallet` [#verify_signature, nil] wallet to verify with;
defaults to +BSV::Wallet::ProtoWallet.new('anyone')+
- **@raise** [ArgumentError] if the certificate has no signature
- **@return** [Boolean] +true+ if the signature is valid
