Class: BSV::Wallet::CoinSelector
- Inherits:
-
Object
- Object
- BSV::Wallet::CoinSelector
- Defined in:
- lib/bsv/wallet_interface/coin_selector.rb
Overview
Selects UTXOs from an available pool to fund a transaction.
Given a target amount and a fee model, the selector chooses the minimum set of UTXOs needed to cover ‘target + fee`. It supports two strategies:
-
‘:standard` — tries an exact match, then smallest-sufficient, then falls back to largest-first accumulation.
-
‘:largest_first` — skips exact/smallest checks and goes straight to largest-first accumulation.
Fee estimation uses FeeEstimator with P2PKH size constants. During accumulation a potential change output is included in the fee estimate, so the caller can always produce change if needed.
Constant Summary collapse
- VALID_STRATEGIES =
%i[standard largest_first].freeze
Instance Method Summary collapse
-
#initialize(fee_estimator: nil, fee_model: nil, strategy: :standard) ⇒ CoinSelector
constructor
A new instance of CoinSelector.
-
#select(available:, target_satoshis:, num_outputs:) ⇒ Hash
Selects UTXOs to cover
target_satoshisplus estimated fees.
Constructor Details
#initialize(fee_estimator: nil, fee_model: nil, strategy: :standard) ⇒ CoinSelector
Returns a new instance of CoinSelector.
31 32 33 34 35 36 37 |
# File 'lib/bsv/wallet_interface/coin_selector.rb', line 31 def initialize(fee_estimator: nil, fee_model: nil, strategy: :standard) raise ArgumentError, "unknown strategy #{strategy.inspect}; use :standard or :largest_first" unless VALID_STRATEGIES.include?(strategy) raise ArgumentError, 'provide fee_estimator: or fee_model:, not both' if fee_estimator && fee_model @fee_model = fee_estimator || fee_model || raise(ArgumentError, 'fee_estimator: (or fee_model:) is required') @strategy = strategy end |
Instance Method Details
#select(available:, target_satoshis:, num_outputs:) ⇒ Hash
Selects UTXOs to cover target_satoshis plus estimated fees.
46 47 48 49 50 51 52 53 54 55 |
# File 'lib/bsv/wallet_interface/coin_selector.rb', line 46 def select(available:, target_satoshis:, num_outputs:) raise InsufficientFundsError.new(available: 0, required: target_satoshis) if available.empty? result = case @strategy when :standard then standard_select(available, target_satoshis, num_outputs) when :largest_first then accumulate(available, target_satoshis, num_outputs) end result || raise_insufficient(available, target_satoshis) end |