signSafeTransaction function
String
signSafeTransaction({
- required SafeTransaction tx,
- required List<
SafeUtxoOutput> utxos, - required List<
String> views, - required Key privateKey,
Implementation
String signSafeTransaction({
required SafeTransaction tx,
required List<SafeUtxoOutput> utxos,
required List<String> views,
required Key privateKey,
}) {
final raw = encodeSafeTransaction(tx);
final msg = Uint8List.fromList(blake3(hex.decode(raw)));
assert(privateKey.raw.length >= 32,
'invalid private key length: ${privateKey.raw.length}');
final spenty = sha512Hash(privateKey.raw.sublist(0, 32));
final y = Scalar()..setBytesWithClamping(spenty.sublist(0, 32));
final signaturesMap = <Map<int, String>>[];
for (var i = 0; i < tx.inputs.length; i++) {
final input = tx.inputs[i];
final utxo = utxos[i];
if (utxo.transactionHash != input.hash || utxo.outputIndex != input.index) {
throw Exception('invalid input: $input');
}
final view = hex.decode(views[i]);
final x = Scalar()..setCanonicalBytes(view);
final t = Scalar()..add(x, y);
final key = PrivateKey(t.Bytes());
final index = utxo.keys.indexOf(key.publicKey().hexString());
if (index == -1) {
throw Exception(
'invalid public key for the input: $i ${utxo.keys}, ${key.publicKey().hexString()}');
}
final sigs = <int, String>{};
final sig = key.sign(msg);
sigs[index] = sig.toHexString();
signaturesMap.add(sigs);
}
return encodeSafeTransaction(tx, sigs: signaturesMap);
}