An unspent transaction output (UTXO) selection module for bitcoin.

WARNING: Value units are in satoshis, not Bitcoin.


dart pub add dart_coinselect


ModuleAlgorithmRe-orders UTXOs?
nullBlackjack, with Accumulative fallbackBy Descending Value
AlgorithmsEnum.accumulativeAccumulative - accumulates inputs until the target value (+fees) is reached, skipping detrimental inputs-
AlgorithmsEnum.blackjackBlackjack - accumulates inputs until the target value (+fees) is matched, does not accumulate inputs that go over the target value (within a threshold)-
AlgorithmsEnum.breakAlgoBreak - breaks the input values into equal denominations of output (as provided)-
AlgorithmsEnum.splitSplit - splits the input values evenly between all outputs, any provided output with .value remains unchanged-

Note: Each algorithm will add a change output if the input - output - fee value difference is over a dust threshold. This is calculated independently by utils.finalize, irrespective of the algorithm chosen, for the purposes of safety.

Pro-tip: if you want to send-all inputs to an output address, AlgorithmsEnum.split with a partial output (.address defined, no .value) can be used to send-all, while leaving an appropriate amount for the fee.


import 'package:dart_coinselect/coinselect.dart';

const feeRate = 55;

void main() {
  List<InputModel> utxos = [
        i: 0,
        value: 10000),

  List<OutputModel> outputs = [
    OutputModel(address: '1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm', value: 5000)

  final selection = coinSelect(utxos, outputs, feeRate);

  // Output is '{"fee": "10560"}"
  // the accumulated fee is always returned for analysis

  // .inputs and .outputs will be null if no solution was found
  if (selection.inputs == null || selection.outputs == null) return;

  // Create raw transaciton and sign it...

License MIT


Support for doing something awesome.