Class: BSV::Wallet::FeeEstimator

Inherits:
Object
  • Object
show all
Defined in:
lib/bsv/wallet_interface/fee_estimator.rb

Overview

Estimates transaction fees before a Transaction::Transaction object exists.

Wraps Transaction::FeeModels::SatoshisPerKilobyte to provide pre-construction fee estimation given only input and output counts. Once a real Transaction is available, delegates directly to the underlying SDK fee model via #estimate_for_tx.

The default rate is 100 sat/kB, matching the ARC mining policy endpoint and the SDK’s own SatoshisPerKilobyte default.

Examples:

Pre-construction estimate

estimator = BSV::Wallet::FeeEstimator.new
fee = estimator.estimate(p2pkh_inputs: 2, p2pkh_outputs: 3)
# => 41 (at 100 sat/kB, ceil(408/1000 * 100) = 41)

Custom rate

estimator = BSV::Wallet::FeeEstimator.new(sats_per_kb: 50)
fee = estimator.estimate(p2pkh_inputs: 1, p2pkh_outputs: 1)
# => 10 (ceil(192/1000 * 50) = 10)

Constant Summary collapse

P2PKH_RAW_INPUT_SIZE =

Estimated size in bytes of an unsigned P2PKH input in raw format.

BSV::Transaction::Transaction::UNSIGNED_P2PKH_INPUT_SIZE
EF_INPUT_OVERHEAD =

Extended Format (BRC-30/EF) adds source_satoshis (8 bytes) + varint(25) (1 byte) + P2PKH locking script (25 bytes) = 34 bytes per input. ARC validates fees against the EF size, not raw.

34
P2PKH_INPUT_SIZE =

Total estimated input size including EF overhead. This is the size ARC sees and charges fees against.

P2PKH_RAW_INPUT_SIZE + EF_INPUT_OVERHEAD
P2PKH_OUTPUT_SIZE =

Estimated size in bytes of a P2PKH output (8 satoshis + varint(25) + 25-byte script).

34
EF_VERSION_OVERHEAD =

EF version marker: 6 bytes (x00x00x00x00x00xEF) follows the 4-byte version field, adding 6 bytes of fixed overhead.

6
FIXED_OVERHEAD =

Fixed overhead in bytes for version (4) + EF marker (6) + lock_time (4).

14
OVERHEAD =

Approximate overhead including typical 1-byte varints for input/output counts. Retained for backward compatibility with code that referenced FeeModel::OVERHEAD.

10
DEFAULT_SATS_PER_KB =

Default fee rate in satoshis per kilobyte, matching ARC’s mining policy endpoint (/v1/policy → miningFee 100/1000).

100

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sats_per_kb: DEFAULT_SATS_PER_KB) ⇒ FeeEstimator

Returns a new instance of FeeEstimator.

Parameters:

  • sats_per_kb (Integer) (defaults to: DEFAULT_SATS_PER_KB)

    fee rate in satoshis per kilobyte

Raises:

  • (ArgumentError)

    if sats_per_kb is zero or negative



60
61
62
63
64
65
# File 'lib/bsv/wallet_interface/fee_estimator.rb', line 60

def initialize(sats_per_kb: DEFAULT_SATS_PER_KB)
  raise ArgumentError, 'sats_per_kb must be greater than zero' unless sats_per_kb.positive?

  @sats_per_kb = sats_per_kb
  @sdk_model = BSV::Transaction::FeeModels::SatoshisPerKilobyte.new(value: sats_per_kb)
end

Instance Attribute Details

#sats_per_kbInteger (readonly)

Returns the satoshis-per-kilobyte rate used for estimation.

Returns:

  • (Integer)

    the satoshis-per-kilobyte rate used for estimation



56
57
58
# File 'lib/bsv/wallet_interface/fee_estimator.rb', line 56

def sats_per_kb
  @sats_per_kb
end

Instance Method Details

#dust_floorInteger

Minimum viable change output value at the configured rate.

An output is economically viable only if its value exceeds twice the cost of spending it. The cost to spend a single P2PKH input is estimated as the fee for a minimal 1-input / 1-output transaction.

Returns:

  • (Integer)

    minimum satoshis for a change output to be worth creating



104
105
106
107
# File 'lib/bsv/wallet_interface/fee_estimator.rb', line 104

def dust_floor
  cost = (spend_one_p2pkh_bytes / 1000.0 * @sats_per_kb).ceil
  [1, cost * 2].max
end

#estimate(p2pkh_inputs:, p2pkh_outputs:, extra_bytes: 0) ⇒ Integer

Estimate the fee for a transaction described by input and output counts.

Computes the serialised byte size using standard P2PKH sizes and correct Bitcoin varint encoding for the input/output count fields, then applies the configured sat/kB rate. Returns at least 1 satoshi.

Parameters:

  • p2pkh_inputs (Integer)

    number of P2PKH inputs

  • p2pkh_outputs (Integer)

    number of P2PKH outputs

  • extra_bytes (Integer) (defaults to: 0)

    additional bytes to include (e.g. OP_RETURN data)

Returns:

  • (Integer)

    estimated fee in satoshis (minimum 1)



77
78
79
80
81
# File 'lib/bsv/wallet_interface/fee_estimator.rb', line 77

def estimate(p2pkh_inputs:, p2pkh_outputs:, extra_bytes: 0)
  total_bytes = byte_size(p2pkh_inputs, p2pkh_outputs) + extra_bytes
  fee = (total_bytes / 1000.0 * @sats_per_kb).ceil
  [1, fee].max
end

#estimate_for_tx(tx) ⇒ Integer Also known as: compute

Compute the fee for a fully-constructed transaction.

Delegates to the underlying Transaction::FeeModels::SatoshisPerKilobyte model, which uses Transaction::Transaction#estimated_size internally.

Parameters:

  • tx (BSV::Transaction::Transaction)

    the transaction to compute the fee for

Returns:

  • (Integer)

    fee in satoshis



90
91
92
# File 'lib/bsv/wallet_interface/fee_estimator.rb', line 90

def estimate_for_tx(tx)
  @sdk_model.compute_fee(tx)
end