# Class BSV::Wallet::Engine::TxBuilder <a id="class-BSV-Wallet-Engine-TxBuilder"></a>

**Inherits:** `Object`
**Includes:** `BSV::Wallet::Interface::TxBuilder`

Transaction construction for outbound actions.

The scribe: given a **resolved** input set (by value), caller outputs, and an
injected key deriver, the builder assembles `TransactionInput` /
`TransactionOutput` objects, derives BRC-42 change keys, runs the fee
fixpoint, optionally shuffles outputs, and signs P2PKH inputs the wallet owns.
See <code>Interface::TxBuilder</code> for the full contract.

Store-free: never resolves inputs itself, never reaches back for state. The
build seam is one-way — done-or-shortfall is returned by value; the
quartermaster (`FundingStrategy` / `Action`) decides whether to top up.

## Public Class Methods
### `resolve_locking_script(script_data)` <a id="method-c-resolve_locking_script"></a> <a id="resolve_locking_script-class_method"></a>
Resolve a locking script value to a Script object.

Binary strings (ASCII-8BIT / non-hex) are wrapped via `from_binary`. Hex
strings are decoded via `from_hex`.

## Public Instance Methods
### `apply_spends(tx:, resolved_inputs:, spends:)` <a id="method-i-apply_spends"></a> <a id="apply_spends-instance_method"></a>
See +Interface::TxBuilder#apply_spends+.

The finalise-and-sign core of the deferred-signing path: walks the resolved
inputs, attaches source data via `InputSource`, applies caller-provided
unlocking scripts from `spends`, and signs any remaining wallet-owned P2PKH
inputs. The transaction builder signs.

Validation that `spends`' vins actually exist in the transaction is the
caller's responsibility (Action#apply_spends validates and then delegates
here).

### `build(resolved_inputs:, caller_outputs:, caller_inputs:, lock_time:, version:, randomize:, sign:)` <a id="method-i-build"></a> <a id="build-instance_method"></a>
See +Interface::TxBuilder#build+.

### `build_change(resolved_inputs:, caller_outputs:, caller_inputs:, lock_time:, version:, randomize:, change_count:, change_basket: = nil)` <a id="method-i-build_change"></a> <a id="build_change-instance_method"></a>
See +Interface::TxBuilder#build_change+.

Build a transaction with BRC-42 change derivation, explicit fee detection, and
shortfall reporting.

Order of operations:
    build -> attach templates -> fee check -> distribute_change -> shuffle -> sign
    Templates before fee (estimated_size needs them).
    Fee check before distribute_change so a shortfall is reported
      before any change is allocated.
    Distribute before shuffle (Benford remainder targets @outputs.last).
    Shuffle before sign (sighash commits to final output positions).

The SDK's +Transaction::Tx#fee+ does not raise on insufficient inputs:
`distribute_change` silently drops all change outputs when +available <= 0+.
To get an explicit shortfall we call
+FeeModels::SatoshisPerKilobyte#compute_fee(tx)+ against the templated tx and
compare to +total_input_satoshis - sum(caller outputs)+. Only when the surplus
exceeds the required fee do we delegate to <code>tx.fee</code> for change
distribution.
- **@raise** [ArgumentError]

### `initialize(key_deriver:, fee_model:)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
Construct a transaction builder. Explicit DI: no engine back-reference. The
builder calls `key_deriver` for BRC-42 change derivation and P2PKH signing-key
derivation, and `fee_model` to compute the required fee for the
change-distribution fixpoint.
- **@return** [TxBuilder] a new instance of TxBuilder
