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

**Inherits:** `Object`

Layer 3 — wallet-vocab primitive surface beneath BRC-100.

Receives Layer 2a components at construction time and exposes 28 spec-aligned
primitive methods (e.g. <code>#build_action</code>, <code>#sign_action</code>,
<code>#encrypt</code>, <code>#get_public_key</code> — per ADR-026 / #397
classification) plus two internals (+Engine::Policy#guard_balance!+,
+Engine#dispatch_broadcast+). BRC-100 spec compliance lives one layer up, in
<code>BSV::Wallet::BRC100</code> (a class composed over an engine instance —
reached via +Engine#brc100+ since #405 Stage 3 of #396 retired the mixin).
Engine contains no SQL, no ARC calls, no thread management — pure
orchestration over the primitives' collaborators.

**@example Via the CLI's auto-discovery (recommended for typical use)**
```ruby
require 'bsv/wallet/cli'    # not autoloaded — CLI is opt-in
ctx = BSV::Wallet::CLI.boot(wallet_name: 'alice')
engine = ctx[:engine]
```

**@example Direct injection (any backend; pass any objects implementing the interfaces)**
```ruby
store = BSV::Wallet::Store.connect('sqlite://wallet.db')
store.migrate!
engine = BSV::Wallet::Engine.new(
  store:         store,
  utxo_pool:     BSV::Wallet::Store::UTXOPool.new(store: store),
  services:      BSV::Network::Services.new(providers: [...]),
  key_deriver:   key_deriver,
  chain_tracker: chain_tracker
)
engine.brc100.create_action(description: 'payment', outputs: [...])
```

## Constants
### `BASKET_UNSPECIFIED` <a id="constant-BASKET_UNSPECIFIED"></a> <a id="BASKET_UNSPECIFIED-constant"></a>
Internal sentinel for "basket filter not applied" — distinct from `nil` (which
means "outputs with no `output_baskets` row"). The constant is private;
external callers achieve "no filter" by **omitting** the <code>basket:</code>
kwarg, not by passing this constant. Mirrors
<code>Store::BASKET_UNSPECIFIED</code>; both live within the wallet's
implementation, never in the public method contract.

### `LIMP_THRESHOLD` <a id="constant-LIMP_THRESHOLD"></a> <a id="LIMP_THRESHOLD-constant"></a>
default: 50K sats

### `LIMP_THRESHOLD_MIN` <a id="constant-LIMP_THRESHOLD_MIN"></a> <a id="LIMP_THRESHOLD_MIN-constant"></a>
hard floor: cannot configure below this

### `RETRYABLE_IMPORT_ATTEMPTS` <a id="constant-RETRYABLE_IMPORT_ATTEMPTS"></a> <a id="RETRYABLE_IMPORT_ATTEMPTS-constant"></a>
Import-path retry budget — see `import_network_call`.

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

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

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

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

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

### `chain_tracker` [R] <a id="attribute-i-chain_tracker"></a> <a id="chain_tracker-instance_method"></a>
Engine collaborator surface exposed for Engine::Action use. Not public API —
these are internal handles for in-process logical models.

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

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

### `key_deriver` [R] <a id="attribute-i-key_deriver"></a> <a id="key_deriver-instance_method"></a>
Engine collaborator surface exposed for Engine::Action use. Not public API —
these are internal handles for in-process logical models.

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

### `network_provider` [R] <a id="attribute-i-network_provider"></a> <a id="network_provider-instance_method"></a>
Engine collaborator surface exposed for Engine::Action use. Not public API —
these are internal handles for in-process logical models.

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

### `store` [R] <a id="attribute-i-store"></a> <a id="store-instance_method"></a>
Engine collaborator surface exposed for Engine::Action use. Not public API —
these are internal handles for in-process logical models.

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

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

### `utxo_pool` [R] <a id="attribute-i-utxo_pool"></a> <a id="utxo_pool-instance_method"></a>
Engine collaborator surface exposed for Engine::Action use. Not public API —
these are internal handles for in-process logical models.

## Public Instance Methods
### `abort_action(reference:)` <a id="method-i-abort_action"></a> <a id="abort_action-instance_method"></a>
- **@raise** [BSV::Wallet::InvalidParameterError]

### `acquire_certificate(type:, certifier:, fields:, serial_number: = nil, revocation_outpoint: = nil, signature: = nil, keyring_for_subject: = nil)` <a id="method-i-acquire_certificate"></a> <a id="acquire_certificate-instance_method"></a>
Direct-acquisition only — the <code>:issuance</code> branch is dispatched +
raised at the BRC100 layer (spec-shape validation per ADR-026 decision 6);
this primitive does the store save unconditionally. *Callers MUST pre-validate
`acquisition_protocol` themselves* —a non-BRC100 caller invoking this with
issuance semantics in mind will get a silent direct-save instead.

### `authenticated?()` <a id="method-i-authenticated-3F"></a> <a id="authenticated?-instance_method"></a>
`true` iff the wallet has a key deriver wired. Authentication in this codebase
is "do we hold the keys to sign?" — sessions / agents / TLS attestation are
out of scope.
- **@return** [Boolean]

### `brc100()` <a id="method-i-brc100"></a> <a id="brc100-instance_method"></a>
BRC-100 wrap layer. Memoised — returns the same
<code>BSV::Wallet::BRC100</code> instance for the lifetime of this engine. The
wrapper holds an +@engine+ reference back to `self`; all 28 BRC-100 method
calls route through it and dispatch to Engine's primitive surface. Callers in
this codebase use this accessor; external callers may also construct
+BSV::Wallet::BRC100.new(engine)+ directly.

### `build_action(description:, input_beef: = nil, inputs: = nil, outputs: = nil, lock_time: = nil, version: = nil, labels: = nil, sign_and_process: = true, accept_delayed_broadcast: = true, no_send: = false, change_count: = nil, randomize_outputs: = true, change_basket: = nil, fee_rate: = nil)` <a id="method-i-build_action"></a> <a id="build_action-instance_method"></a>
Orchestrator. Lifted from <code>Engine::Action.create</code>'s body in #402
Stage 2 commit 5. Drives input acquisition, the build, the headroom guards,
persistence (sign or atomic internal-completion), BEEF assembly + SPV honesty
validation, and broadcast dispatch. Returns wallet vocab; BRC100 wraps to
BRC-100 vocab.
- **@return** [Hash] sync: +{ wtxid:, atomic_beef: }+;
internal (no_send): +{ wtxid:, atomic_beef:, change_outpoints: }+;
deferred: +{ signable: { atomic_beef:, reference: } }+.

### `consolidate_step(target_inputs: = 20, no_send: = false, accept_delayed_broadcast: = true)` <a id="method-i-consolidate_step"></a> <a id="consolidate_step-instance_method"></a>
Consolidate the dustier tail of the UTXO set into a single self-payment.

Picks the `target_inputs` smallest spendable outputs plus the 1 largest (as an
anchor that guarantees fee coverage even when the smallest are below the
per-input marginal fee), then dispatches a `no_send` `create_action` with
+change_count: 1+ so the funding loop produces a single BRC-42 self-payment.
- **@param** `target_inputs` [Integer] minimum smallest outputs to consume per step
- **@param** `no_send` [Boolean] default false (BRC-100 createAction
default — intend to broadcast). Set true only for the "build
locally without broadcasting" case.
- **@param** `accept_delayed_broadcast` [Boolean] only consulted when
+no_send+ is false. Default true (queue for the daemon to push).
- **@return** [Hash, nil] the +create_action+ result, or +nil+ if there are
fewer than +target_inputs+ spendable outputs (the loop's natural exit).

### `create_hmac(data:, protocol_id:, key_id:, counterparty: = 'self', privileged: = false)` <a id="method-i-create_hmac"></a> <a id="create_hmac-instance_method"></a>
Not documented.

### `create_signature(protocol_id:, key_id:, data: = nil, hash_to_directly_sign: = nil, counterparty: = 'self', privileged: = false)` <a id="method-i-create_signature"></a> <a id="create_signature-instance_method"></a>
Not documented.

### `decrypt(ciphertext:, protocol_id:, key_id:, counterparty: = 'self', privileged: = false)` <a id="method-i-decrypt"></a> <a id="decrypt-instance_method"></a>
Not documented.

### `discover_by_attributes(attributes:, limit: = 10, offset: = 0)` <a id="method-i-discover_by_attributes"></a> <a id="discover_by_attributes-instance_method"></a>
Local lookup — same external-discovery caveat as `discover_by_identity_key`.
Currently always empty because the Store doesn't index by cert field values
yet.

### `discover_by_identity_key(identity_key:, limit: = 10, offset: = 0)` <a id="method-i-discover_by_identity_key"></a> <a id="discover_by_identity_key-instance_method"></a>
Local lookup — external discovery is a future concern (no live cert provider
integrated yet). Filters the local cert store by subject pubkey hex.

### `encrypt(plaintext:, protocol_id:, key_id:, counterparty: = 'self', privileged: = false)` <a id="method-i-encrypt"></a> <a id="encrypt-instance_method"></a>
--- Crypto (codes 11-16, 6 primitives) ---

### `estimate_sweep_fee(input_count:, recipient_script:)` <a id="method-i-estimate_sweep_fee"></a> <a id="estimate_sweep_fee-instance_method"></a>
Build a templated skeleton tx with the same shape +TxBuilder#build_change+
will produce (N P2PKH-templated inputs + 1 caller output + 1 change output)
and run `compute_fee` against it. Inputs are sourceless stand-ins — only the
unlocking-script template size matters for fee estimation; `source_satoshis`
does not enter the size formula.

### `generate_receive_address()` <a id="method-i-generate_receive_address"></a> <a id="generate_receive_address-instance_method"></a>
Generate a legacy P2PKH receive address using the WBIKD pattern.

Finds or creates a pre-funded UTXO slot in basket 'p wbikd', locks it with a
zero-output no-send action, then derives a BRC-42 address from the slot's
on-chain coordinates — its source txid and vout.

Derivation params are the slot's display txid (dtxid) and vout, both on-chain
data with no database dependency. That is what makes the scheme recoverable:
if the wallet database is lost but the identity key is retained, addresses are
re-derived by walking the chain for the slot transactions — no original
(action_id, output_id) needed. Recovery cost scales with the number of
addresses ever generated.
- **@return** [Hash] { address:, derivation_prefix:, derivation_suffix: }

### `get_header_for_height(height:)` <a id="method-i-get_header_for_height"></a> <a id="get_header_for_height-instance_method"></a>
- **@raise** [BSV::Wallet::UnsupportedActionError]

### `get_height()` <a id="method-i-get_height"></a> <a id="get_height-instance_method"></a>
--- Static / network (codes 25-28, 4 primitives) ---
- **@raise** [BSV::Wallet::UnsupportedActionError]

### `get_network()` <a id="method-i-get_network"></a> <a id="get_network-instance_method"></a>
Not documented.

### `get_public_key(identity_key: = false, protocol_id: = nil, key_id: = nil, counterparty: = nil, for_self: = false, privileged: = false)` <a id="method-i-get_public_key"></a> <a id="get_public_key-instance_method"></a>
Returns pubkey hex (identity or derived). The `identity_key` flag selects
between the wallet's stable identity pubkey and a derived pubkey under
`protocol_id`/`key_id`/`counterparty`.

### `get_version()` <a id="method-i-get_version"></a> <a id="get_version-instance_method"></a>
Not documented.

### `headroom()` <a id="method-i-headroom"></a> <a id="headroom-instance_method"></a>
How many sats can be spent before hitting the limp threshold.

### `import_beef(tx:, outputs:, description:, labels: = nil, trust_self: = nil, known_txids: = nil)` <a id="method-i-import_beef"></a> <a id="import_beef-instance_method"></a>
Not documented.

### `import_utxo(dtxid:, vout: = 0, basket: = nil, no_send: = false, accept_delayed_broadcast: = true)` <a id="method-i-import_utxo"></a> <a id="import_utxo-instance_method"></a>
Import a root-key UTXO and immediately pay to self on a derived address.

Rescues funds sent directly to the wallet's root key (an error condition or
bootstrap from a non-BRC-100 source). Fetches the transaction and merkle proof
from the network provider, verifies the output is P2PKH to the wallet's root
key, imports it, then immediately spends it to a BRC-42 derived self-address.
The root UTXO is promoted as spendable briefly, then consumed by the
self-payment — only the derived output remains spendable after completion.
- **@param** `dtxid` [String] 64-char hex transaction ID (display order)
- **@param** `vout` [Integer] output index (default: 0)
- **@param** `no_send` [Boolean] default false (BRC-100 createAction
default — intend to broadcast). Phase 2's BRC-42 self-payment
is queued for broadcast, so its output lives on the chain's
UTXO set, making downstream broadcasts referencing it consensus-
valid. The rule is binary: either every action in the run
broadcasts (including this one) or none of them do —
broadcasting a descendant of a +no_send: true+ parent gets
rejected by the network for a non-existent input.

Set true only for the "build locally without ever broadcasting"
case where the wallet intentionally never publishes the action
(rare; downstream broadcasts will fail consensus).
- **@param** `accept_delayed_broadcast` [Boolean] only consulted when
+no_send+ is false. Default true (queue for the daemon to
push). Tests that want "build + queue, never broadcast" leave
this true and don't run walletd — the queue stays full but
nothing reaches the network.
- **@param** `basket` [String, nil] optional basket name for the Phase 2
self-payment's change output. When present, the imported funds
land in the named basket (the application has a stable handle
on them via +listOutputs(basket:)+ or +Engine#spendable_outputs+).
When +nil+ (default), the imported funds land unbasketed in the
wallet's pool — the previous and still-canonical behaviour for
root-key bootstrap. See HLR #436 and ADR-027.
- **@raise** [BSV::Wallet::Error]
- **@return** [Hash] { imported: true, satoshis:, dtxid: }

### `import_wallet(no_send: = false, accept_delayed_broadcast: = true, include_unconfirmed: = false, basket: = nil)` <a id="method-i-import_wallet"></a> <a id="import_wallet-instance_method"></a>
Scan the root key's address for unspent outputs and import each one.

Derives the P2PKH address from the wallet's root key, queries the network for
UTXOs, and calls import_utxo for each. This is the bootstrap path — how a
wallet gets its initial funding.
- **@param** `no_send` [Boolean] forwarded to +import_utxo+ for each
discovered UTXO. Default false (BRC-100 createAction default).
Set true only for the "build locally without broadcasting" case.
- **@param** `accept_delayed_broadcast` [Boolean] forwarded to
+import_utxo+. Only consulted when +no_send+ is false.
- **@param** `include_unconfirmed` [Boolean] when true, scan WoC's
+/unspent/all+ endpoint which includes mempool entries.
Default false uses +/confirmed/unspent+ (safer — confirmed
UTXOs can't be reorged-away under us). The e2e harness's
Phase 4 sets true so SDK can see the just-broadcast sweep
outputs without waiting for a block.
- **@param** `basket` [String, nil] forwarded to +import_utxo+ per
discovered UTXO. Routes the imported funds into a named
basket (excluded from auto-funding by HLR #435's basket
filter). Default +nil+ → unbasketed pool (pre-#462 behaviour).
- **@raise** [BSV::Wallet::Error]
- **@return** [Hash] { imported: Integer, utxos: Array<Hash> }

### `initialize(store:, utxo_pool:, broadcaster:, services: = nil, key_deriver: = nil, chain_tracker: = nil, network_provider: = nil, network: = :mainnet, limp_threshold: = LIMP_THRESHOLD, callback_token: = nil)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@raise** [ArgumentError]
- **@return** [Engine] a new instance of Engine

### `inspect()` <a id="method-i-inspect"></a> <a id="inspect-instance_method"></a>
Elide +@key_deriver+ and +@store+ from inspect output. Same rationale as
`KeyDeriver`: engine ivars include the keyderiver, so an unredacted dump would
expose root material via that path.

### `limp_mode?()` <a id="method-i-limp_mode-3F"></a> <a id="limp_mode?-instance_method"></a>
Is the wallet in limp mode? When true, all outbound operations are blocked.
The wallet can still receive to restore normal operations.
- **@return** [Boolean]

### `list_actions(labels:, label_query_mode: = :any, include_labels: = false, include_inputs: = false, include_input_source_locking_scripts: = false, include_input_unlocking_scripts: = false, include_outputs: = false, include_output_locking_scripts: = false, limit: = 10, offset: = 0)` <a id="method-i-list_actions"></a> <a id="list_actions-instance_method"></a>
--- Action read-side (3 primitives) ---

### `list_certificates(certifiers:, types:, limit: = 10, offset: = 0)` <a id="method-i-list_certificates"></a> <a id="list_certificates-instance_method"></a>
Not documented.

### `list_receive_addresses()` <a id="method-i-list_receive_addresses"></a> <a id="list_receive_addresses-instance_method"></a>
List outstanding (pending) WBIKD receive addresses.

Queries actions with the 'wbikd' label, filters for :internal status (active
locks), and re-derives the P2PKH address from each slot's source transaction
ID and output index (on-chain data).
- **@return** [Array<Hash>] each with :address, :derivation_prefix,
:derivation_suffix, :action_reference, :created_at

### `prove_certificate(certificate:, fields_to_reveal:, verifier:, privileged: = false)` <a id="method-i-prove_certificate"></a> <a id="prove_certificate-instance_method"></a>
Not documented.

### `reject_action(action_id:)` <a id="method-i-reject_action"></a> <a id="reject_action-instance_method"></a>
Operator-facing entry to Store#reject_action. The daemon's resolution loop
calls store directly; this wrapper lets bin/ tools target specific stuck rows
(action_id is a wallet-local integer, not a BRC-100 reference — this isn't a
spec method).
- **@raise** [BSV::Wallet::InvalidParameterError]

### `relinquish_certificate(type:, serial_number:, certifier:)` <a id="method-i-relinquish_certificate"></a> <a id="relinquish_certificate-instance_method"></a>
Not documented.

### `relinquish_output(output_id:)` <a id="method-i-relinquish_output"></a> <a id="relinquish_output-instance_method"></a>
Not documented.

### `reveal_counterparty_key_linkage(counterparty:, verifier:, privileged: = false)` <a id="method-i-reveal_counterparty_key_linkage"></a> <a id="reveal_counterparty_key_linkage-instance_method"></a>
Not documented.

### `reveal_specific_key_linkage(counterparty:, verifier:, protocol_id:, key_id:, privileged: = false)` <a id="method-i-reveal_specific_key_linkage"></a> <a id="reveal_specific_key_linkage-instance_method"></a>
Not documented.

### `scan_receive_addresses()` <a id="method-i-scan_receive_addresses"></a> <a id="scan_receive_addresses-instance_method"></a>
Scan outstanding WBIKD receive addresses for incoming UTXOs.

Queries the network for UTXOs at each outstanding address. When funds are
found, internalizes each UTXO with BRC-42 derivation params and recycles the
slot by aborting the locking action.
- **@return** [Hash] { scanned:, found: } counts

### `send_payment(recipient:, satoshis:, no_send: = false, accept_delayed_broadcast: = true, fee_rate: = nil)` <a id="method-i-send_payment"></a> <a id="send_payment-instance_method"></a>
Send a BRC-42 derived payment to a recipient.

Generates derivation parameters, derives a P2PKH locking script for the
recipient via BRC-42, and calls create_action — which uses
Engine::FundingStrategy to handle UTXO selection, fees, and change via the
funding loop.
- **@param** `recipient` [String] 66-char compressed public key hex (02/03 prefix)
- **@param** `satoshis` [Integer] amount to send
- **@param** `no_send` [Boolean] default false (BRC-100 createAction
default — intend to broadcast). Set true for "build + sign
+ return BEEF for peer-to-peer handoff without ever publishing."
- **@param** `accept_delayed_broadcast` [Boolean] only consulted when
+no_send+ is false. Default true (queue for the daemon to push).
- **@param** `fee_rate` [Integer, nil] sats/kb override for this call.
Default +nil+ (inherit wallet default — 100 sats/kb). HLR #489.
- **@return** [Hash] { wtxid:, atomic_beef:, sender_identity_key:, outputs: [{ vout:, satoshis:, derivation_prefix:, derivation_suffix: }] }

### `sign_action(reference:, spends:, accept_delayed_broadcast: = true, no_send: = false)` <a id="method-i-sign_action"></a> <a id="sign_action-instance_method"></a>
Complete the deferred-signing flow: locate the parked action, apply caller
spends, build + validate BEEF, dispatch broadcast per the intent mapped from
the caller's `no_send` / `accept_delayed_broadcast` params (NOT the action
row's stored `broadcast_intent` — that drives the no_send-override guard
below, not the dispatch).
- **@raise** [BSV::Wallet::InvalidParameterError]
- **@return** [Hash] +{ wtxid:, atomic_beef: }+ — wallet vocab; BRC100 wraps.

### `spendable_outputs(basket: = BASKET_UNSPECIFIED, tags: = nil, tag_query_mode: = :any, aggregate: = nil, include: = nil, include_custom_instructions: = false, include_tags: = false, include_labels: = false, limit: = 10, offset: = 0)` <a id="method-i-spendable_outputs"></a> <a id="spendable_outputs-instance_method"></a>
The wallet's canonical "spendable outputs" query, in wallet vocabulary. Wraps
+Store#query_outputs+ with the BRC-100-pagination upper bound preserved (limit
clamps to 10_000); +BSV::Wallet::BRC100#list_outputs+ wraps **this** to
translate into BRC-100 hash-shape vocabulary.
- **@param** `basket` [String, Array<String>, nil, omitted] - omitted (default) → no basket filter; all spendable outputs match.
- +String+           → outputs in that named basket.
- +Array<String>+    → outputs in any of the named baskets.
- +nil+              → outputs with no +output_baskets+ row (unbasketed).
- **@param** `aggregate` [:sum, :count, nil] - +nil+ (default) → returns +{ total:, outputs: }+.
- +:sum+          → returns Integer satoshi sum.
- +:count+        → returns Integer count.

### `sweep(recipient:, no_send: = false, accept_delayed_broadcast: = true)` <a id="method-i-sweep"></a> <a id="sweep-instance_method"></a>
Sweep every spendable output back to the recipient's root key (less fee).

Selects all spendable outputs, locks one caller output to the recipient's
**root** P2PKH (+hash160(recipient_pubkey)+ — not a BRC-42-derived address),
and dispatches a `no_send` `create_action` that consumes all inputs. The
literal root P2PKH is recoverable from the WIF alone, which is the point of a
sweep: return funds somewhere a bare key can reclaim them (e.g. so the
receiving wallet's DB can be wiped and re-imported by scanning the root
address). Any rounding surplus against the actual fee is dropped
(zero-survival on the single change-key slot the funding loop derives, since
+TxBuilder#build_change+ requires +change_count >= 1+).
- **@param** `recipient` [String] 66-char compressed pubkey hex (02/03)
- **@param** `no_send` [Boolean] default false (BRC-100 createAction
default — intend to broadcast). Set true for "build + sign
+ return BEEF for peer-to-peer handoff without ever publishing."
- **@param** `accept_delayed_broadcast` [Boolean] only consulted when
+no_send+ is false. Default true (queue for the daemon to push).
- **@raise** [BSV::Wallet::InsufficientFundsError]
- **@return** [Hash, nil] the +create_action+ result, or +nil+ when the
wallet has no spendable outputs.

### `sweep_to_root(recipient: = nil, target_inputs: = 20)` <a id="method-i-sweep_to_root"></a> <a id="sweep_to_root-instance_method"></a>
Drain the entire wallet back to a single root P2PKH, broadcasting on-chain.
The operational "tidy up" step: every spendable output is returned to the
recipient's literal <code>1...</code> address, which is recoverable from the
WIF alone — so once this lands the wallet's DB can be wiped and the funds
re-imported from the root key.

A single transaction cannot consume an unbounded number of inputs (tx-size
limit), so this first loops `consolidate_step` to collapse the wallet down to
fewer than `target_inputs` spendable outputs, then emits one terminal `sweep`
to the root address. Every transaction is an inline on-chain broadcast
(+no_send: false+, +accept_delayed_broadcast: false+) — no daemon required.
- **@param** `recipient` [String, nil] 66-char compressed pubkey hex (02/03)
of the root address to drain to. Defaults to the wallet's own
identity key (the "tidy my own wallet" case). Pass another wallet's
identity key for the e2e harness's "return borrowed funds to the
funder" step.
- **@param** `target_inputs` [Integer] consolidation batch size and the
spendable-count threshold below which the loop stops and sweeps.
- **@return** [Hash] +{ consolidation_steps:, sweep: }+ where +sweep+ is the
terminal sweep's +create_action+ result, or +nil+ when the wallet
had no spendable outputs to sweep.

### `verify_hmac(data:, hmac:, protocol_id:, key_id:, counterparty: = 'self', privileged: = false)` <a id="method-i-verify_hmac"></a> <a id="verify_hmac-instance_method"></a>
Returns `true` on match, `false` on mismatch. BRC100 raises `InvalidHmacError`
on `false` per the BRC-100 contract; a non-BRC100 consumer gets the boolean
for their own dispatch.

### `verify_signature(signature:, protocol_id:, key_id:, data: = nil, hash_to_directly_verify: = nil, counterparty: = 'self', for_self: = false, privileged: = false)` <a id="method-i-verify_signature"></a> <a id="verify_signature-instance_method"></a>
Returns `true` on valid, `false` on invalid. BRC100 raises
`InvalidSignatureError` on `false` per the BRC-100 contract.

### `wait_for_authentication()` <a id="method-i-wait_for_authentication"></a> <a id="wait_for_authentication-instance_method"></a>
Raises `Error` (code 2) when not authenticated; returns `true` when
authenticated. BRC100 wraps as +{ authenticated: true }+.
- **@raise** [BSV::Wallet::Error]
