LCOV - code coverage report
Current view: top level - crypto/evm/utils - signing.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 52 0
Test Date: 2025-07-02 01:23:33 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:convert';
       2              : import 'dart:typed_data';
       3              : import 'package:hex/hex.dart';
       4              : import 'package:walletkit_dart/src/utils/keccak.dart';
       5              : import 'package:walletkit_dart/walletkit_dart.dart';
       6              : 
       7              : const stakingPartnerAddress =
       8              :     "0x6B984d04761E5CCD16e3ed54a51F1454f950F0E3"; // this address is configured in the AVINOC-staking-contract and the Safir-backoffice holds a private key for this address
       9              : 
      10            0 : (RawEvmTransaction, Signature) signEvmTransaction({
      11              :   required String messageHex,
      12              :   required Uint8List privateKey,
      13              : }) {
      14            0 :   final rawTx = RawEvmTransaction.fromUnsignedHex(messageHex);
      15              : 
      16              :   final signature = switch (rawTx) {
      17            0 :     RawEVMTransactionType0 type0 => Signature.createSignature(
      18            0 :         type0.serializedUnsigned(type0.chainId),
      19              :         privateKey,
      20            0 :         chainId: type0.chainId,
      21              :       ),
      22            0 :     RawEVMTransactionType1 type1 => Signature.createSignature(
      23            0 :         type1.serializedUnsigned,
      24              :         privateKey,
      25              :         txType: TransactionType.Type1,
      26              :       ),
      27            0 :     RawEVMTransactionType2 type2 => Signature.createSignature(
      28            0 :         type2.serializedUnsigned,
      29              :         privateKey,
      30              :         txType: TransactionType.Type2,
      31              :       ),
      32              :   };
      33              : 
      34            0 :   final signedTx = rawTx.addSignature(signature);
      35              : 
      36              :   return (signedTx, signature);
      37              : }
      38              : 
      39            0 : String recoverEthMessageSigner({
      40              :   required String message,
      41              :   required String signature,
      42              : }) {
      43            0 :   final messageHash = _createEthStyleMessageHash(message);
      44            0 :   final sig = _parseEthSignature(signature);
      45            0 :   final recoveredSignerPubKey = recoverPublicKey(messageHash, sig);
      46            0 :   final recoveredSignerAddress = publicKeyToAddress(recoveredSignerPubKey).toHex;
      47              : 
      48            0 :   return toChecksumAddress("0x" + recoveredSignerAddress);
      49              : }
      50              : 
      51            0 : String recoverPubKey({
      52              :   required String message,
      53              :   required String sig,
      54              :   required String coin,
      55              :   bool? uncompressed,
      56              : }) {
      57            0 :   final messageHash = _createEthStyleMessageHash(message);
      58            0 :   final parsedSig = _parseEthSignature(sig);
      59            0 :   final pubKeyUncompressed = recoverPublicKey(messageHash, parsedSig);
      60            0 :   if (uncompressed == true) {
      61            0 :     return HEX.encode(pubKeyUncompressed);
      62              :   }
      63              : 
      64            0 :   final uncompressedPrefix = [0x04];
      65            0 :   final pubKeyCompressed = compressPublicKey(
      66            0 :     Uint8List.fromList(uncompressedPrefix + pubKeyUncompressed),
      67              :   );
      68            0 :   String pubKeyHex = HEX.encode(pubKeyCompressed);
      69            0 :   if (pubKeyHex.startsWith("02")) {
      70            0 :     pubKeyHex = pubKeyHex.replaceFirst(
      71              :       "02",
      72              :       "04",
      73              :     ); // workaround for Safir backwards compat
      74              :   }
      75              :   return pubKeyHex;
      76              : }
      77              : 
      78            0 : Uint8List _createEthStyleMessageHash(String message) {
      79              :   List<int> messageBytes;
      80            0 :   if (message.startsWith("0x") && !message.contains('_')) {
      81            0 :     messageBytes = HEX.decode(message.substring(2));
      82              :   } else {
      83            0 :     messageBytes = utf8.encode(message);
      84              :   }
      85            0 :   final prefix = utf8.encode(
      86            0 :     '\u0019Ethereum Signed Message:\n' + messageBytes.length.toString(),
      87              :   );
      88            0 :   final hashInput = Uint8List.fromList(prefix + messageBytes);
      89            0 :   return keccak256(hashInput);
      90              : }
      91              : 
      92            0 : Signature _parseEthSignature(String signature) {
      93            0 :   if (!signature.startsWith("0x")) {
      94            0 :     throw WKFailure("expected to begin with 0x");
      95              :   }
      96            0 :   if (signature.length != 132) {
      97            0 :     throw WKFailure("Unexpected signature length");
      98              :   }
      99              :   // Skip the prefix byte and extract the remaining 129 hex characters as the signature string
     100            0 :   String signatureStr = signature.substring(2);
     101              : 
     102              :   // Extract the r and s values
     103            0 :   BigInt r = BigInt.parse(signatureStr.substring(0, 64), radix: 16);
     104            0 :   BigInt s = BigInt.parse(signatureStr.substring(64, 128), radix: 16);
     105              : 
     106              :   // Extract the recovery identifier (v)
     107            0 :   BigInt v = BigInt.parse(signatureStr.substring(128), radix: 16);
     108              : 
     109            0 :   if (v < BigInt.from(27)) {
     110            0 :     v += BigInt.from(27);
     111              :   }
     112              : 
     113            0 :   return Signature(r, s, v.toInt());
     114              : }
     115              : 
     116            0 : String signEvmMessage({
     117              :   required String message,
     118              :   required Uint8List privateKey,
     119              : }) {
     120            0 :   final payload = Uint8List.fromList(utf8.encode(message));
     121            0 :   final sig = Signature.signPersonalMessageToUint8List(payload, privateKey);
     122            0 :   return "0x" + HEX.encode(sig);
     123              : }
        

Generated by: LCOV version 2.0-1