sign method

Transaction sign({
  1. required int inputN,
  2. required ECPrivateKey key,
  3. SigHashType hashType = const SigHashType.all(),
  4. BigInt? value,
  5. List<Output>? prevOuts,
})

Sign the input at inputN with the key and hashType and return a new Transaction with the signed input. The input must be a signable P2PKHInput, P2WPKHInput, P2SHMultisigInput or TaprootKeyInput. Otherwise CannotSignInput will be thrown. Other inputs may be signed seperately and inserted back into the transaction via replaceInput. value is only required for P2WPKH. prevOuts is only required for Taproot inputs.

Implementation

Transaction sign({
  required int inputN,
  required ECPrivateKey key,
  SigHashType hashType = const SigHashType.all(),
  BigInt? value,
  List<Output>? prevOuts,
}) {

  if (inputN >= inputs.length) {
    throw ArgumentError.value(inputN, "inputN", "outside range of inputs");
  }

  if (!hashType.none && outputs.isEmpty) {
    throw CannotSignInput("Cannot sign input without any outputs");
  }

  final input = inputs[inputN];

  // Sign input
  late Input signedIn;

  if (input is LegacyInput) {
    signedIn = input.sign(
      tx: this,
      inputN: inputN,
      key: key,
      hashType: hashType,
    );
  } else if (input is LegacyWitnessInput) {

    if (value == null) {
      throw CannotSignInput("Prevout values are required for witness inputs");
    }

    signedIn = input.sign(
      tx: this,
      inputN: inputN,
      key: key,
      value: value,
      hashType: hashType,
    );

  } else if (input is TaprootKeyInput) {

    if (prevOuts == null) {
      throw CannotSignInput(
        "Previous outputs are required when signing a taproot input",
      );
    }

    if (prevOuts.length != inputs.length) {
      throw CannotSignInput(
        "The number of previous outputs must match the number of inputs",
      );
    }

    signedIn = input.sign(
      tx: this,
      inputN: inputN,
      key: key,
      prevOuts: prevOuts,
      hashType: hashType,
    );

  } else {
    throw CannotSignInput("${input.runtimeType} not a signable input");
  }

  // Replace input in input list
  final newInputs = inputs.asMap().map(
    (index, input) => MapEntry(
      index, index == inputN ? signedIn : input,
    ),
  ).values;

  return Transaction(
    version: version,
    inputs: newInputs,
    outputs: outputs,
    locktime: locktime,
  );

}