createDRTransaction function

Future createDRTransaction(
  1. DataRequestOutput dataRequestOutput,
  2. WitPrivateKey privateKey,
  3. Address? changeAddress,
  4. dynamic networkSource,
  5. FeeType feeType,
  6. UtxoSelectionStrategy utxoStrategy, [
  7. int fee = 0,
])

Implementation

Future<dynamic> createDRTransaction(
    DataRequestOutput dataRequestOutput,
    WitPrivateKey privateKey,
    Address? changeAddress,
    dynamic networkSource,
    FeeType feeType,
    UtxoSelectionStrategy utxoStrategy,
    [int fee = 0]) async {
  List<Input> inputs = [];
  List<ValueTransferOutput> outputs = [];
  // value owed from the data request
  int droValue =
      dataRequestOutput.witnesses * dataRequestOutput.witnessReward.toInt();
  int amountOwed = droValue;
  print('Total Witness Reward -> $droValue');
  dataRequestOutput;
  Address signerAddress = Address.fromAddress(privateKey.publicKey.address);
  // if the changeAddress param is left blank send the change to the signer
  Address _changeAddress = changeAddress ?? signerAddress;

  await signerAddress.getUtxoInfo(source: networkSource);
  List<Utxo> utxoPool = signerAddress.utxoPool!.sortUtxos(utxoStrategy);
  int totalUtxoValue = 0;

  utxoPool.forEach((utxo) {
    totalUtxoValue += utxo.value;
  });
  if (utxoPool.isEmpty) {
    return TransactionError(-1, 'Insufficient funds.');
  }
  assert(totalUtxoValue > amountOwed, 'Insufficient funds.');
  List<Utxo> selectedUtxos = [];
  int selectedUtxoValue = 0;
  switch (feeType) {
    case FeeType.Absolute:
      amountOwed += fee;
      var _outputValue = amountOwed;
      while (_outputValue > 0) {
        Utxo utxo = utxoPool.first;
        utxoPool.removeAt(0);
        selectedUtxos.add(utxo);
        _outputValue -= utxo.value;
      }
      selectedUtxos.forEach((Utxo utxo) {
        inputs.add(utxo.toInput());
        selectedUtxoValue += utxo.value;
      });
      int change = selectedUtxoValue - amountOwed;
      if (change > 0) {
        outputs.add(_changeAddress.receive(change));
      }

      break;
    case FeeType.Weighted:
      // get utxos to cover the base value before weight
      var _outputValue = amountOwed;
      while (_outputValue > 0) {
        Utxo utxo = utxoPool.first;
        utxoPool.removeAt(0);
        selectedUtxos.add(utxo);
        _outputValue -= utxo.value;
      }
      selectedUtxos.forEach((Utxo utxo) {
        inputs.add(utxo.toInput());
        selectedUtxoValue += utxo.value;
      });

      int change = selectedUtxoValue - amountOwed;
      int inputCount = inputs.length;
      int outputCount = outputs.length;
      int droWeight = dataRequestOutput.weight;
      int droExtraWeight = dataRequestOutput.extraWeight;

      // estimate at least 1 output, currently zero in the list
      int currentWeight =
          drWeight(inputCount, outputCount + 1, droWeight, droExtraWeight);

      if (currentWeight == change) {
      } else if (currentWeight < change) {
        outputs.add(_changeAddress.receive(change - currentWeight));
      } else {}

      break;
  }
  DRTransactionBody body = DRTransactionBody(
      inputs: inputs, outputs: outputs, drOutput: dataRequestOutput);
  DRTransaction transaction = DRTransaction(body: body, signatures: []);
  KeyedSignature signature =
      signerAddress.signHash(transaction.transactionID, privateKey);
  for (int i = 0; i < transaction.body.inputs.length; i++) {
    transaction.signatures.add(signature);
  }
  return transaction;
}