sign method

  1. @override
GsplTxData sign()
override

Implementation

@override
GsplTxData sign() {
  // Deserialize and identify transaction information, get readable transaction structure
  final transaction = 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
    Uint8List sigHash;
    if (_shouldUseSegwitSignature()) {
      sigHash = transaction.hashForWitnessV0(i, prevOutScript, value, hashType);
    } else {
      sigHash = transaction.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 Uint8List signatureBytes = Uint8List.fromList(hexToBytes(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 newHex = transactionSigned.toHex();

  txData.hex = newHex;
  txData.inputs = signedInputs;
  txData.isSigned = true;
  txData.message = newHex;
  txData.signature = "";

  return txData;
}