sign method

  1. @override
GsplTxData sign()
override

Implementation

@override
GsplTxData sign() {
  // Deserialize and identify transaction information, get readable transaction structure
  final tx = btc.Transaction.fromHex(txData.hex);
  final inputAddress = wallet.publicKeyToAddress(wallet.publicKey);
  final payments = txData.toJson()['payments'];
  if (payments == null || payments.isEmpty) {
    throw Exception('No valid output found in transaction outputs');
  }

  // Iterate through inputs, use wallet.sign to sign sigHash
  final List<GsplItem> signedInputs = [];
  for (int i = 0; i < txData.inputs.length; i++) {
    final input = txData.inputs[i];
    if (input.path == null) throw Exception('Input path cannot be null');

    int hashType = input.signHashType ?? btc.SIGHASH_ALL;
    if (isBch) hashType |= btc.SIGHASH_BITCOINCASHBIP143;

    if (input.amount == null) throw Exception('Input amount required for sigHash');

    final prevOutScript = btc.Address.addressToOutputScript(inputAddress, networkType)!;
    final value = input.amount!;

    // Choose correct signature hash method based on wallet type and configuration
    final sigHash = _shouldUseSegwitSignature() ?
      tx.hashForWitnessV0(i, prevOutScript, value, hashType) :
      tx.hashForSignature(i, prevOutScript, hashType);

    String sigResult;
    final sigHashHex = dynamicToString(sigHash);
    if (isLtc && (wallet as LtcCoin).isTaproot) {
      sigResult = (wallet as LtcCoin).sign(sigHashHex);
    } else if (isDoge) {
      sigResult = (wallet as DogeCoin).sign(sigHashHex);
    } else if (isBch) {
      sigResult = (wallet as BchCoin).sign(sigHashHex);
    } else {
      sigResult = wallet.sign(sigHashHex);
    }

    final signatureBytes = dynamicToUint8List(sigResult);

    // Construct new GsplItem to replace
    signedInputs.add(GsplItem(
      path: input.path,
      amount: input.amount,
      address: inputAddress,
      signHashType: input.signHashType,
      signature: signatureBytes,
    ));
  }

  final transactionSigned = btc.Transaction.fromHex(txData.hex);
  for (int i = 0; i < signedInputs.length; i++) {
    final sig = signedInputs[i].signature;
    if (sig == null) {
      throw Exception('Missing signature for input $i');
    }
    final pubkey = wallet.publicKey;
    final scriptSig = compile([sig, pubkey]);
    transactionSigned.ins[i].script = scriptSig;
  }
  final signedHex = transactionSigned.toHex();
  txData.hex = signedHex;
  txData.inputs = signedInputs;
  txData.isSigned = true;
  txData.message = signedHex;
  txData.signature = '';

  return txData;
}