LCOV - code coverage report
Current view: top level - crypto/utxo/entities/payments - input_selection.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 52.8 % 36 19
Test Date: 2025-06-07 01:20:49 Functions: - 0 0

            Line data    Source code
       1              : library coin_selection;
       2              : 
       3              : import 'dart:math';
       4              : 
       5              : import 'package:walletkit_dart/walletkit_dart.dart';
       6              : 
       7              : const kMinInputs = 2;
       8              : 
       9            1 : List<ElectrumOutput> singleRandomDrawUTXOSelection(
      10              :   List<ElectrumOutput> utxos,
      11              :   BigInt targetAmount,
      12              : ) {
      13            1 :   List<ElectrumOutput> selectedUTXOs = [];
      14            1 :   BigInt selectedAmount = BigInt.zero;
      15            1 :   Random random = Random();
      16              : 
      17              :   // try to use at least 2 UTXOs if possible
      18            3 :   while (selectedAmount < targetAmount || (selectedUTXOs.length < kMinInputs && utxos.isNotEmpty)) {
      19            1 :     if (utxos.isEmpty) {
      20            0 :       throw SendFailure('Insufficient UTXOs to reach the target amount');
      21              :     }
      22              : 
      23              :     // Randomly select a UTXO and remove it from the available list.
      24            2 :     int randomIndex = random.nextInt(utxos.length);
      25            1 :     ElectrumOutput selectedUTXO = utxos.removeAt(randomIndex);
      26              : 
      27              :     // Add the chosen UTXO to the selected list and update the selected amount.
      28            1 :     selectedUTXOs.add(selectedUTXO);
      29            2 :     selectedAmount += selectedUTXO.value;
      30              :   }
      31              :   return selectedUTXOs;
      32              : }
      33              : 
      34            1 : List<ElectrumOutput> smallestFirstUTXOSelection(
      35              :   List<ElectrumOutput> utxos,
      36              :   BigInt targetAmount,
      37              : ) {
      38              :   // Sort UTXOs by value, smallest first.
      39            5 :   utxos.sort((a, b) => a.value.compareTo(b.value));
      40              : 
      41            1 :   List<ElectrumOutput> selectedUTXOs = [];
      42            1 :   BigInt selectedAmount = BigInt.zero;
      43              : 
      44            2 :   for (ElectrumOutput utxo in utxos) {
      45            1 :     selectedUTXOs.add(utxo);
      46            2 :     selectedAmount += utxo.value;
      47              : 
      48            1 :     if (selectedAmount >= targetAmount) {
      49              :       break;
      50              :     }
      51              :   }
      52              : 
      53            1 :   if (selectedAmount < targetAmount) {
      54            0 :     throw Exception('Insufficient UTXOs to reach the target amount');
      55              :   }
      56              : 
      57              :   return selectedUTXOs;
      58              : }
      59              : 
      60              : ///
      61              : /// FIFO: TODO: Get blockheigt information for each Input
      62              : ///
      63              : // List<Input> fifoUTXOSelection(List<Input> utxos, int targetAmount) {
      64              : //   // Sort UTXOs by block height, older first.
      65              : //   utxos.sort((a, b) => a.blockHeight.compareTo(b.blockHeight));
      66              : 
      67              : //   List<Input> selectedUTXOs = [];
      68              : //   int selectedAmount = 0;
      69              : 
      70              : //   for (Input utxo in utxos) {
      71              : //     selectedUTXOs.add(utxo);
      72              : //     selectedAmount += utxo.vout;
      73              : 
      74              : //     if (selectedAmount >= targetAmount) {
      75              : //       break;
      76              : //     }
      77              : //   }
      78              : 
      79              : //   if (selectedAmount < targetAmount) {
      80              : //     throw Exception('Insufficient UTXOs to reach the target amount');
      81              : //   }
      82              : 
      83              : //   return selectedUTXOs;
      84              : // }
      85              : 
      86              : ///
      87              : ///
      88              : ///
      89            0 : List<ElectrumOutput> fillUpToTargetAmount(
      90              :   List<ElectrumOutput> alreadyUsedUTXOs,
      91              :   List<ElectrumOutput> utxos,
      92              :   BigInt targetAmount,
      93              : ) {
      94            0 :   List<ElectrumOutput> selectedUTXOs = [...alreadyUsedUTXOs];
      95            0 :   BigInt selectedAmount = selectedUTXOs.fold(
      96            0 :     BigInt.zero,
      97            0 :     (preV, utxo) => preV + utxo.value,
      98              :   );
      99              : 
     100              :   /// Remove already used UTXOs from the available list.
     101            0 :   utxos.removeWhere((element) => alreadyUsedUTXOs.contains(element));
     102              : 
     103              :   // try to use at least 2 UTXOs if possible
     104            0 :   while (selectedAmount < targetAmount || (selectedUTXOs.length < kMinInputs && utxos.isNotEmpty)) {
     105            0 :     if (utxos.isEmpty) {
     106            0 :       throw SendFailure(
     107            0 :         'Insufficient UTXOs for Fee + Target Amount ($targetAmount)',
     108              :       );
     109              :     }
     110              : 
     111            0 :     final max = utxos.reduce(
     112            0 :       (value, element) => value.value > element.value ? value : element,
     113              :     );
     114              : 
     115            0 :     utxos.remove(max);
     116              : 
     117              :     // Add the chosen UTXO to the selected list and update the selected amount.
     118            0 :     selectedUTXOs.add(max);
     119            0 :     selectedAmount += max.value;
     120              :   }
     121              :   return selectedUTXOs;
     122              : }
        

Generated by: LCOV version 2.0-1