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

**Inherits:** `Object`

BRC-31/BRC-103 mutual authentication peer.

Manages the cryptographic handshake between two parties using a transport for
bidirectional message delivery.

High-level API (preferred):
    peer_a.to_peer(payload, peer_b_identity_key)    — send authenticated message
    peer_a.get_authenticated_session(identity_key)  — obtain/create authenticated session
    peer_a.request_certificates(certs, identity_key) — request certs post-handshake
    peer_a.send_certificate_response(key, certs)    — send certs to a peer

The high-level API auto-initiates the handshake when no authenticated session
exists. The low-level `handle_incoming_message` is called internally by the
transport callback and is not part of the public contract.

Sessions are indexed by `session_nonce` (our nonce), which is the primary key
in the {SessionManager}.

**@example Using Peer with a transport**
```ruby
transport_a, transport_b = PairedTransport.create_pair
peer_a = BSV::Auth::Peer.new(wallet: wallet_a, transport: transport_a)
peer_b = BSV::Auth::Peer.new(wallet: wallet_b, transport: transport_b)

peer_b.on_general_message { |key, payload| puts "received: #{payload}" }
peer_a.to_peer([72, 101, 108, 108, 111], peer_b.identity_key)
```

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

## Attributes
### `last_interacted_peer` [R] <a id="attribute-i-last_interacted_peer"></a> <a id="last_interacted_peer-instance_method"></a>
Returns the value of attribute last_interacted_peer.

### `session_manager` [R] <a id="attribute-i-session_manager"></a> <a id="session_manager-instance_method"></a>
Returns the value of attribute session_manager.

### `wallet` [R] <a id="attribute-i-wallet"></a> <a id="wallet-instance_method"></a>
Returns the value of attribute wallet.

## Public Instance Methods
### `authenticated?(identifier)` <a id="method-i-authenticated-3F"></a> <a id="authenticated?-instance_method"></a>
Checks whether we have an authenticated session with a peer.

Accepts either a `session_nonce` or `peer_identity_key`.
- **@param** `identifier` [String]
- **@return** [Boolean]

### `get_authenticated_session(identity_key = nil)` <a id="method-i-get_authenticated_session"></a> <a id="get_authenticated_session-instance_method"></a>
Returns an authenticated session for a peer, initiating a handshake if needed.

If `identity_key` is given and an authenticated session already exists,
returns it immediately. Otherwise initiates a handshake and blocks until the
response arrives or the timeout expires.
- **@param** `identity_key` [String, nil] peer identity key to look up or connect to
- **@raise** [AuthError] if the handshake fails or times out
- **@return** [PeerSession] an authenticated session

### `identity_key()` <a id="method-i-identity_key"></a> <a id="identity_key-instance_method"></a>
Returns our identity key (cached after first call).
- **@return** [String] compressed public key hex

### `initialize(wallet:, transport:, session_manager: = nil, certificates_to_request: = nil, auto_persist_last_session: = true, handshake_timeout: = 30)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `wallet` [BSV::Wallet::Interface] wallet providing crypto operations
- **@param** `transport` [Transport] transport for message delivery (required)
- **@param** `session_manager` [SessionManager, nil] optional custom session store
- **@param** `certificates_to_request` [Hash, nil] certificate set to request from peers
- **@param** `auto_persist_last_session` [Boolean] whether to track the last-interacted peer (default: true)
- **@param** `handshake_timeout` [Integer] seconds to wait for handshake response (default: 30)
- **@raise** [ArgumentError] if transport is nil
- **@return** [Peer] a new instance of Peer

### `off_certificate_request(callback_id)` <a id="method-i-off_certificate_request"></a> <a id="off_certificate_request-instance_method"></a>
Removes a certificate request callback.
- **@param** `callback_id` [Integer] the ID returned by {#on_certificate_request}

### `off_certificates_received(callback_id)` <a id="method-i-off_certificates_received"></a> <a id="off_certificates_received-instance_method"></a>
Removes a certificates received callback.
- **@param** `callback_id` [Integer] the ID returned by {#on_certificates_received}

### `off_general_message(callback_id)` <a id="method-i-off_general_message"></a> <a id="off_general_message-instance_method"></a>
Removes a general message callback.
- **@param** `callback_id` [Integer] the ID returned by {#on_general_message}

### `on_certificate_request(&block)` <a id="method-i-on_certificate_request"></a> <a id="on_certificate_request-instance_method"></a>
Registers a callback to be called when a certificate request is received from
a peer.
- **@return** [Integer] callback ID (pass to {#off_certificate_request} to deregister)
- **@yield** [sender_key, requested_certs] called with sender's identity key and requested cert set

### `on_certificates_received(&block)` <a id="method-i-on_certificates_received"></a> <a id="on_certificates_received-instance_method"></a>
Registers a callback to be called when certificates are received from a peer.
- **@return** [Integer] callback ID (pass to {#off_certificates_received} to deregister)
- **@yield** [sender_key, certs] called with sender's identity key and certificate array

### `on_general_message(&block)` <a id="method-i-on_general_message"></a> <a id="on_general_message-instance_method"></a>
Registers a callback to be called when a general message is received.
- **@return** [Integer] callback ID (pass to {#off_general_message} to deregister)
- **@yield** [sender_key, payload] called with the sender's identity key and payload bytes

### `request_certificates(certificates_to_request, identity_key = nil)` <a id="method-i-request_certificates"></a> <a id="request_certificates-instance_method"></a>
Sends a certificate request to a peer post-handshake.
- **@param** `certificates_to_request` [Hash] certifiers and types to request
- **@param** `identity_key` [String, nil] peer identity key; falls back to last-interacted peer

### `send_certificate_response(peer_identity_key, certificates)` <a id="method-i-send_certificate_response"></a> <a id="send_certificate_response-instance_method"></a>
Sends a certificate response to a peer.
- **@param** `peer_identity_key` [String] the peer's identity key
- **@param** `certificates` [Array<VerifiableCertificate, Hash>] certificates to send

### `to_peer(payload, identity_key = nil)` <a id="method-i-to_peer"></a> <a id="to_peer-instance_method"></a>
Sends an authenticated general message to a peer, initiating a handshake
automatically if no authenticated session exists.
- **@param** `payload` [Array<Integer>] byte array payload
- **@param** `identity_key` [String, nil] peer identity key; falls back to last-interacted peer
- **@raise** [AuthError] if certificates are required but not yet validated
- **@raise** [AuthError] if handshake times out
