createLocalnetGovernanceVaa.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. const abi = require("web3-eth-abi");
  2. const utils = require("web3-utils");
  3. const elliptic = require("elliptic");
  4. const testSigner1PK = "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0";
  5. const testGovernanceChain = "1"; // ethereum
  6. const testGovernanceEmitter = "0x0000000000000000000000000000000000000000000000000000000000001234";
  7. function zeroPadBytes(value, length) {
  8. while (value.length < 2 * length) {
  9. value = "0" + value;
  10. }
  11. return value;
  12. }
  13. const signAndEncodeVM = function (
  14. timestamp,
  15. nonce,
  16. emitterChainId,
  17. emitterAddress,
  18. sequence,
  19. data,
  20. signers,
  21. guardianSetIndex,
  22. consistencyLevel
  23. ) {
  24. const body = [
  25. abi
  26. .encodeParameter("uint32", timestamp)
  27. .substring(2 + (64 - 8)),
  28. abi.encodeParameter("uint32", nonce).substring(2 + (64 - 8)),
  29. abi
  30. .encodeParameter("uint16", emitterChainId)
  31. .substring(2 + (64 - 4)),
  32. abi.encodeParameter("bytes32", emitterAddress).substring(2),
  33. abi
  34. .encodeParameter("uint64", sequence)
  35. .substring(2 + (64 - 16)),
  36. abi
  37. .encodeParameter("uint8", consistencyLevel)
  38. .substring(2 + (64 - 2)),
  39. data.substr(2),
  40. ];
  41. const hash = utils.soliditySha3(
  42. utils.soliditySha3("0x" + body.join(""))
  43. );
  44. let signatures = "";
  45. for (let i in signers) {
  46. const ec = new elliptic.ec("secp256k1");
  47. const key = ec.keyFromPrivate(signers[i]);
  48. const signature = key.sign(hash.substr(2), { canonical: true });
  49. const packSig = [
  50. abi.encodeParameter("uint8", i).substring(2 + (64 - 2)),
  51. zeroPadBytes(signature.r.toString(16), 32),
  52. zeroPadBytes(signature.s.toString(16), 32),
  53. abi
  54. .encodeParameter("uint8", signature.recoveryParam)
  55. .substr(2 + (64 - 2)),
  56. ];
  57. signatures += packSig.join("");
  58. }
  59. const vm = [
  60. abi.encodeParameter("uint8", 1).substring(2 + (64 - 2)),
  61. abi
  62. .encodeParameter("uint32", guardianSetIndex)
  63. .substring(2 + (64 - 8)),
  64. abi
  65. .encodeParameter("uint8", signers.length)
  66. .substring(2 + (64 - 2)),
  67. signatures,
  68. body.join(""),
  69. ].join("");
  70. return vm;
  71. };
  72. function createVAAFromUint8Array(
  73. dataBuffer,
  74. emitterChainId,
  75. emitterAddress,
  76. sequence,
  77. ) {
  78. const dataHex = "0x" + dataBuffer.toString("hex");
  79. return "0x" + signAndEncodeVM(
  80. 0,
  81. 0,
  82. emitterChainId,
  83. emitterAddress,
  84. sequence,
  85. dataHex,
  86. [testSigner1PK],
  87. 0,
  88. 0
  89. );
  90. }
  91. module.exports = function createLocalnetGovernanceVAA(dataBuffer, sequence) {
  92. return createVAAFromUint8Array(
  93. dataBuffer,
  94. testGovernanceChain,
  95. testGovernanceEmitter,
  96. sequence
  97. );
  98. }