# Class BSV::Transaction::Beef <a id="class-BSV-Transaction-Beef"></a>

**Inherits:** `Object`

Background Evaluation Extended Format (BEEF) for SPV-ready transaction
bundles. Encodes one or more transactions together with their merkle proofs
(BUMPs), enabling recipients to verify inclusion without querying a block
explorer.

Supports BRC-62 (V1), BRC-96 (V2), and BRC-95 (Atomic BEEF) formats.

**@example Parse a BEEF bundle and find a transaction**
```ruby
beef = BSV::Transaction::Beef.from_hex(beef_hex)
tx = beef.find_transaction(wtxid)
```

## Constants
### Version constants
#### `ATOMIC_BEEF` <a id="constant-ATOMIC_BEEF"></a> <a id="ATOMIC_BEEF-constant"></a>
BRC-96

#### `BEEF_V1` <a id="constant-BEEF_V1"></a> <a id="BEEF_V1-constant"></a>
Version magic bytes as LE uint32 (matching pack('V') / unpack1('V')). Stream
bytes: 01 00 BE EF / 02 00 BE EF / 01 01 01 01

#### `BEEF_V2` <a id="constant-BEEF_V2"></a> <a id="BEEF_V2-constant"></a>
BRC-62
### Transaction format flags
#### `FORMAT_RAW_TX` <a id="constant-FORMAT_RAW_TX"></a> <a id="FORMAT_RAW_TX-constant"></a>
Raw transaction without a merkle proof.

#### `FORMAT_RAW_TX_AND_BUMP` <a id="constant-FORMAT_RAW_TX_AND_BUMP"></a> <a id="FORMAT_RAW_TX_AND_BUMP-constant"></a>
Raw transaction with an associated BUMP index.

#### `FORMAT_TXID_ONLY` <a id="constant-FORMAT_TXID_ONLY"></a> <a id="FORMAT_TXID_ONLY-constant"></a>
Only the transaction ID (no raw data).

## Attributes
### `bumps` [R] <a id="attribute-i-bumps"></a> <a id="bumps-instance_method"></a>
- **@return** [Array<MerklePath>] merkle proofs (BUMPs) referenced by transactions

### `subject_wtxid` [R] <a id="attribute-i-subject_wtxid"></a> <a id="subject_wtxid-instance_method"></a>
- **@return** [String, nil] 32-byte wire-order subject txid (Atomic BEEF only)

### `transactions` [R] <a id="attribute-i-transactions"></a> <a id="transactions-instance_method"></a>
- **@return** [Array<BeefTx>] the transactions in dependency order

### `txs_not_valid` [R] <a id="attribute-i-txs_not_valid"></a> <a id="txs_not_valid-instance_method"></a>
Returns transactions that could not be sorted due to cycles, or nil.

Populated by {#sort_transactions!} when cycles are detected (F5.5).
- **@return** [Array<BeefTx>, nil]

### `version` [RW] <a id="attribute-i-version"></a> <a id="version-instance_method"></a>
- **@return** [Integer] BEEF version constant

## Public Class Methods
### `from_binary(data)` <a id="method-c-from_binary"></a> <a id="from_binary-class_method"></a>
Deserialise a BEEF bundle from binary data.

Supports V1 (BRC-62), V2 (BRC-96), and Atomic (BRC-95) formats. After parsing,
input source transactions are wired automatically.
- **@param** `data` [String] raw BEEF binary
- **@raise** [ArgumentError]
- **@return** [Transaction::Beef] the parsed BEEF bundle

### `from_hex(hex)` <a id="method-c-from_hex"></a> <a id="from_hex-class_method"></a>
Deserialise a BEEF bundle from a hex string.
- **@param** `hex` [String] hex-encoded BEEF data
- **@return** [Transaction::Beef] the parsed BEEF bundle

## Public Instance Methods
### `clone()` <a id="method-i-clone"></a> <a id="clone-instance_method"></a>
Return a shallow copy of this Transaction::Beef.

Both +@bumps+ and +@transactions+ arrays are duplicated (new arrays), but the
`BeefTx` and `MerklePath` objects they contain are shared references. This
mirrors the TS SDK's `clone` contract: entries are effectively immutable once
added to a bundle, so shallow semantics are correct. If a deeper copy is ever
required, add a separate `deep_dup` rather than changing this method's
contract.

+@subject_wtxid+ (Atomic BEEF) and +@txs_not_valid+ (cyclic-graph metadata)
are preserved on the copy.
- **@return** [Transaction::Beef] a new shallow copy

### `find_atomic_transaction(wtxid)` <a id="method-i-find_atomic_transaction"></a> <a id="find_atomic_transaction-instance_method"></a>
Find a transaction and recursively wire its ancestry (source transactions and
merkle paths) for atomic proof validation.
- **@param** `wtxid` [String] 32-byte wire-order wtxid
- **@return** [Transaction::Tx, nil] the transaction with full proof tree, or nil

### `find_bump(wtxid)` <a id="method-i-find_bump"></a> <a id="find_bump-instance_method"></a>
Find the merkle path (BUMP) for a transaction by its wire-order txid.

First checks the transaction-table entries, then scans @bumps directly for a
BUMP whose level-0 leaves contain the wtxid.
- **@param** `wtxid` [String] 32-byte wire-order wtxid
- **@return** [MerklePath, nil] the merkle path, or nil if not found

### `find_transaction(wtxid)` <a id="method-i-find_transaction"></a> <a id="find_transaction-instance_method"></a>
Find a transaction in the bundle by its wire-order transaction ID.
- **@param** `wtxid` [String] 32-byte wire-order wtxid
- **@return** [Transaction::Tx, nil] the matching transaction, or nil

### `find_transaction_for_signing(wtxid)` <a id="method-i-find_transaction_for_signing"></a> <a id="find_transaction_for_signing-instance_method"></a>
Find a transaction with all source_transactions wired for signing.
- **@param** `wtxid` [String] 32-byte wire-order wtxid
- **@return** [Transaction::Tx, nil] the transaction with wired inputs, or nil

### `initialize(version: = BEEF_V1, bumps: = [], transactions: = [])` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `version` [Integer] BEEF version constant (default: BEEF_V1, matching to_binary's
default for ARC compatibility; from_binary overwrites this with the parsed version)
- **@param** `bumps` [Array<MerklePath>] merkle proofs
- **@param** `transactions` [Array<BeefTx>] transaction entries
- **@return** [Beef] a new instance of Beef

### `make_txid_only(wtxid)` <a id="method-i-make_txid_only"></a> <a id="make_txid_only-instance_method"></a>
Convert a transaction entry to TXID-only format.
- **@param** `wtxid` [String] 32-byte wire-order wtxid
- **@return** [BeefTx, nil] the converted entry, or nil if not found

### `merge(other)` <a id="method-i-merge"></a> <a id="merge-instance_method"></a>
Merge all BUMPs and transactions from another BEEF bundle.

BUMP indices are remapped during merge. New BeefTx instances are constructed
rather than sharing references with the source bundle (F5.9).
- **@param** `other` [Transaction::Beef] the BEEF bundle to merge from
- **@raise** [ArgumentError] if a transaction in +other+ has a +bump_index+
that does not point to any BUMP in +other.bumps+ (i.e. the source
bundle is internally inconsistent)
- **@return** [self]

### `merge_bump(merkle_path)` <a id="method-i-merge_bump"></a> <a id="merge_bump-instance_method"></a>
Add or deduplicate a merkle path (BUMP) in this BEEF bundle.

If an existing BUMP shares the same block_height and merkle root, it is
combined (via MerklePath#combine) and the existing index is returned.
Otherwise the BUMP is appended.

After the BUMP is stored, any existing FORMAT_RAW_TX transactions whose txid
appears in the new BUMP's level-0 leaves are retroactively upgraded to
FORMAT_RAW_TX_AND_BUMP (F5.6).
- **@param** `merkle_path` [MerklePath] the BUMP to merge
- **@return** [Integer] the index of the (possibly merged) BUMP

### `merge_raw_tx(raw_bytes, bump_index: = nil)` <a id="method-i-merge_raw_tx"></a> <a id="merge_raw_tx-instance_method"></a>
Add a transaction from raw binary data.

If the transaction already exists, upgrades weaker entries to stronger formats
when a raw tx or bump_index is now available (F5.7).
- **@param** `raw_bytes` [String] raw transaction binary
- **@param** `bump_index` [Integer, nil] optional BUMP index
- **@return** [BeefTx] the new or upgraded BeefTx entry

### `merge_transaction(tx)` <a id="method-i-merge_transaction"></a> <a id="merge_transaction-instance_method"></a>
Add a transaction to this BEEF bundle.

Recursively merges the transaction's ancestors (via source_transaction
references on inputs) and their merkle paths. Duplicate transactions (same
txid) are upgraded if a stronger format is now available (F5.7): TXID_ONLY →
RAW_TX or RAW_TX_AND_BUMP; RAW_TX → RAW_TX_AND_BUMP.
- **@param** `tx` [Transaction::Tx] the transaction to merge
- **@return** [BeefTx] the (possibly existing or upgraded) BeefTx entry

### `merge_txid_only(wtxid)` <a id="method-i-merge_txid_only"></a> <a id="merge_txid_only-instance_method"></a>
Add a TXID-only entry for `wtxid` if no entry exists yet.

If an entry already exists (in any format), the call is a no-op —TXID-only is
the weakest format, so an existing stronger entry is kept.
- **@param** `wtxid` [String] 32-byte wire-order binary txid
- **@return** [BeefTx] the existing or newly added entry

### `sort_transactions!()` <a id="method-i-sort_transactions-21"></a> <a id="sort_transactions!-instance_method"></a>
Sort transactions in topological (dependency) order in place.

After sorting, every transaction's input ancestors appear before it in the
array. This is required for correct BEEF serialisation.

Transactions that form a cycle (i.e. cannot be topologically sorted) are moved
to +@txs_not_valid+ rather than being silently dropped (F5.5).
- **@return** [self]

### `subject_dtxid()` <a id="method-i-subject_dtxid"></a> <a id="subject_dtxid-instance_method"></a>
Display-order subject txid as a hex string (Atomic BEEF only).
- **@return** [String, nil] hex-encoded display-order txid, or nil

### `to_atomic_binary(subject_wtxid)` <a id="method-i-to_atomic_binary"></a> <a id="to_atomic_binary-instance_method"></a>
Serialise as Atomic BEEF (BRC-95), wrapping V2 data with a subject txid.
- **@param** `subject_wtxid` [String] 32-byte wire-order subject transaction ID
- **@return** [String] raw Atomic BEEF binary

### `to_atomic_hex(subject_wtxid)` <a id="method-i-to_atomic_hex"></a> <a id="to_atomic_hex-instance_method"></a>
Serialise as Atomic BEEF (BRC-95) hex string.
- **@param** `subject_wtxid` [String] 32-byte wire-order subject transaction ID
- **@return** [String] hex-encoded Atomic BEEF

### `to_binary(version: = BEEF_V1)` <a id="method-i-to_binary"></a> <a id="to_binary-instance_method"></a>
Serialise the BEEF bundle to binary format.

Defaults to V1 (BRC-62) for compatibility with ARC and the reference TS SDK.
Pass +version: BEEF_V2+ for BRC-96 format.
- **@param** `version` [Integer] BEEF_V1 (default) or BEEF_V2
- **@raise** [ArgumentError] if version is BEEF_V1 and the bundle contains
any FORMAT_TXID_ONLY entries (V1 / BRC-62 has no TXID-only format;
pass +version: BEEF_V2+ to serialise such bundles)
- **@return** [String] raw BEEF binary

### `to_hex()` <a id="method-i-to_hex"></a> <a id="to_hex-instance_method"></a>
Serialise the BEEF bundle to a hex string.

Uses the bundle's own +@version+, so a BEEF parsed from V2 round-trips to V2
hex, and a BEEF parsed from V1 (or freshly constructed via the default
constructor) round-trips to V1 hex.
- **@return** [String] hex-encoded BEEF data

### `trim_known_wtxids(known_wtxids)` <a id="method-i-trim_known_wtxids"></a> <a id="trim_known_wtxids-instance_method"></a>
Return a new Transaction::Beef with TXID-only entries removed for any wtxid in
`known_wtxids`.

RAW_TX and RAW_TX_AND_BUMP entries are always retained, even when their wtxid
appears in `known_wtxids`. Only `TxidOnlyEntry` records are candidates for
removal (they carry no proof data the recipient needs).

After dropping TXID-only entries, any BUMP that is no longer referenced by any
remaining `ProvenTxEntry` is removed, and all `bump_index` fields are
renumbered to match the new bumps array (mirrors TS `trimKnownTxids` at
<code>Beef.ts:861-914</code>).

Does not mutate `self`. Starts from a {#clone} so the caller's state is
preserved.
- **@param** `known_wtxids` [Array<String>] binary wtxids the recipient already has
- **@return** [Transaction::Beef] a new bundle with the specified entries trimmed

### `valid?(allow_txid_only: = false)` <a id="method-i-valid-3F"></a> <a id="valid?-instance_method"></a>
Check structural validity of the BEEF bundle.

A valid BEEF has every transaction either:
*   proven (has a BUMP / merkle_path), or
*   all its inputs reference transactions that are themselves valid within
    this bundle.

For FORMAT_RAW_TX_AND_BUMP entries, the BUMP linkage and computed root are
also verified (F5.4).
- **@param** `allow_txid_only` [Boolean] whether TXID-only entries count as valid (default: false)
- **@return** [Boolean] true if structurally valid

### `valid_wtxids()` <a id="method-i-valid_wtxids"></a> <a id="valid_wtxids-instance_method"></a>
Return the wtxids of transactions that are "valid" in this bundle.

A transaction is valid when it either:
*   has a merkle proof (is a `ProvenTxEntry`), or
*   all of its inputs chain back to proven transactions within the bundle.

TXID-only entries are excluded. Cyclic transactions (from +@txs_not_valid+)
are also excluded.

Used by {Transaction::BeefParty} to record which wtxids a party gains
knowledge of after a {#merge_beef_from_party} call.
- **@return** [Array<String>] binary wire-order wtxids

### `verify(chain_tracker = nil, allow_txid_only: = false)` <a id="method-i-verify"></a> <a id="verify-instance_method"></a>
Verify the BEEF bundle against a chain tracker (SPV).

Calls {#valid?} first for structural checks, then optionally verifies each
BUMP's computed merkle root against the chain tracker (F5.3).
- **@param** `chain_tracker` [#valid_root_for_height?] optional chain tracker
(see {ChainTracker}) that responds to
+valid_root_for_height?(root_hex, block_height)+
- **@param** `allow_txid_only` [Boolean] passed to {#valid?}
- **@return** [Boolean] true if the bundle is structurally valid and, when a
chain tracker is provided, all BUMP roots are confirmed by the chain
