# Class BSV::Network::PeerDelivery <a id="class-BSV-Network-PeerDelivery"></a>

**Inherits:** `Object`

Wallet→peer BEEF delivery over HTTP (#385 Task 5, #390).

The v1 transport for <code>Engine::Transmission</code>. Synchronous HTTP POST
of the BRC-29 envelope to a caller-supplied endpoint, with ACK validation that
includes wtxid binding (so a captive portal / wrong host returning 200 OK can
never get recorded as a successful delivery).

The class composes `EndpointPolicy` for SSRF defence and is injected into
<code>Engine::Transmission</code> via the <code>delivery:</code> kwarg.
Phase-2 will swap this object for a daemon-async deliverer without touching
<code>Engine::Transmission</code> — the seam is the whole point.

No new gem dependencies: plain <code>Net::HTTP</code>. Body cap, TLS verify,
explicit timeouts, no redirect follow.

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

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

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

## Public Instance Methods
### `deliver(endpoint:, envelope:, subject_wtxid:)` <a id="method-i-deliver"></a> <a id="deliver-instance_method"></a>
POST the envelope to the peer endpoint and validate the ACK.

The wire envelope is the JSON encoding of `envelope` with <code>beef:</code>
rendered as hex (BEEF is binary; JSON is text). Mirror of the existing
<code>bin/create</code> → <code>bin/receive</code> stdin/stdout shape, lifted
to HTTP for Phase-1 transport.

ACK contract (Phase-1):
    - 200 OK
    - +Content-Type+ starting with +application/json+
    - body = +{ "accepted": true, "wtxid": "<dtxid>" }+
    - +wtxid+ must match the +subject_wtxid+ we delivered

Without the wtxid binding, a captive portal or a wrong-host endpoint returning
generic 200 OK would be recorded as a successful delivery — the BeefParty
trimmer would then over-trim the next transmit to that "peer", and the actual
peer would silently miss everything thereafter.
- **@param** `endpoint` [String] absolute URI (https:// in prod)
- **@param** `envelope` [Hash] +{ beef:, outputs:, sender_identity_key:,
protocol_version: }+ — keys consumed by the receiver's
+internalize_action+.
- **@param** `subject_wtxid` [String] 32-byte wire-order wtxid for the
subject of this delivery. Used for ACK binding.
- **@return** [Result]

### `initialize(policy: = EndpointPolicy.new, connect_timeout: = DEFAULT_CONNECT_TIMEOUT, read_timeout: = DEFAULT_READ_TIMEOUT)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `policy` [EndpointPolicy] SSRF gate. Default is the
+EndpointPolicy.new+ at construction time (reads the
+BSV_WALLET_ALLOW_PRIVATE_ENDPOINTS+ env var once).
- **@param** `connect_timeout` [Integer] seconds; default 5.
- **@param** `read_timeout` [Integer] seconds; default 30. Slow peer
must not silently wedge the wallet.
- **@return** [PeerDelivery] a new instance of PeerDelivery
