CoinSelection constructor
CoinSelection({})
Selects all the inputs from selected
to send to the recipients
outputs
and provide change to the changeProgram
. The feePerKb
specifies the
required fee in sats per KB with a minimum fee specified with
minFee
. The minChange
is the minimum allowed change.
Implementation
CoinSelection({
this.version = Transaction.currentVersion,
required Iterable<InputCandidate> selected,
required Iterable<Output> recipients,
required this.changeProgram,
required this.feePerKb,
required this.minFee,
required this.minChange,
this.locktime = 0,
}) : selected = List.unmodifiable(selected),
recipients = List.unmodifiable(recipients) {
if (selected.any((candidate) => candidate.input.signedSize == null)) {
throw ArgumentError("Cannot select inputs without known max signed size");
}
// Get input and recipient values
inputValue = selected
.fold(BigInt.zero, (acc, candidate) => acc + candidate.value);
recipientValue = recipients
.fold(BigInt.zero, (acc, output) => acc + output.value);
// Get unchanging size
final int fixedSize
// Version and locktime
= 8
// Fully signed inputs
+ MeasureWriter.varIntSizeOfInt(selected.length)
+ selected.fold(0, (acc, candidate) => acc + candidate.input.signedSize!);
// Determine size and fee with change
final sizeWithChange = _sizeGivenChange(fixedSize, true);
final feeWithChange = _feeForSize(sizeWithChange);
final includedChangeValue = inputValue - recipientValue - feeWithChange;
// If change is under the required minimum, remove the change output
if (includedChangeValue.compareTo(minChange) < 0) {
final changelessSize = _sizeGivenChange(fixedSize, false);
final feeForSize = _feeForSize(changelessSize);
final excess = inputValue - recipientValue - feeForSize;
if (!excess.isNegative) {
// Exceeded without change. Fee is the input value minus the recipient
// value
signedSize = changelessSize;
fee = inputValue - recipientValue;
changeValue = BigInt.zero;
return;
}
// Else haven't met requirement
}
// Either haven't met requirement, or have met requirement with change so
// provide details of change-containing transaction
signedSize = sizeWithChange;
fee = feeWithChange;
changeValue = includedChangeValue;
}