WormholeTest.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { Cell, contractAddress, ContractProvider, Sender } from "@ton/core";
  2. import { BaseWrapper } from "./BaseWrapper";
  3. import {
  4. createCellChain,
  5. parseGuardianSetKeys,
  6. } from "@pythnetwork/pyth-ton-js";
  7. export type WormholeTestConfig = {
  8. guardianSetIndex: number;
  9. guardianSet: string[];
  10. chainId: number;
  11. governanceChainId: number;
  12. governanceContract: string;
  13. };
  14. export class WormholeTest extends BaseWrapper {
  15. static createFromConfig(
  16. config: WormholeTestConfig,
  17. code: Cell,
  18. workchain = 0
  19. ) {
  20. const data = WormholeTest.getWormholeInitData(config);
  21. const init = { code, data };
  22. return new WormholeTest(contractAddress(workchain, init), init);
  23. }
  24. static getWormholeInitData(config: WormholeTestConfig): Cell {
  25. return BaseWrapper.createInitData({
  26. guardianSetIndex: config.guardianSetIndex,
  27. guardianSet: config.guardianSet,
  28. chainId: config.chainId,
  29. governanceChainId: config.governanceChainId,
  30. governanceContract: config.governanceContract,
  31. });
  32. }
  33. async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) {
  34. await super.sendDeploy(provider, via, value);
  35. }
  36. async getParseEncodedUpgrade(
  37. provider: ContractProvider,
  38. currentGuardianSetIndex: number,
  39. encodedUpgrade: Buffer
  40. ) {
  41. const result = await provider.get("test_parse_encoded_upgrade", [
  42. { type: "int", value: BigInt(currentGuardianSetIndex) },
  43. { type: "slice", cell: createCellChain(encodedUpgrade) },
  44. ]);
  45. return {
  46. action: result.stack.readNumber(),
  47. chain: result.stack.readNumber(),
  48. module: result.stack.readBigNumber(),
  49. newGuardianSetKeys: parseGuardianSetKeys(result.stack.readCell()),
  50. newGuardianSetIndex: result.stack.readNumber(),
  51. };
  52. }
  53. async getParseAndVerifyWormholeVm(provider: ContractProvider, vm: Buffer) {
  54. const cell = createCellChain(vm);
  55. const result = await provider.get("test_parse_and_verify_wormhole_vm", [
  56. { type: "slice", cell: cell },
  57. ]);
  58. const version = result.stack.readNumber();
  59. const vm_guardian_set_index = result.stack.readNumber();
  60. const timestamp = result.stack.readNumber();
  61. const nonce = result.stack.readNumber();
  62. const emitter_chain_id = result.stack.readNumber();
  63. const emitter_address = result.stack
  64. .readBigNumber()
  65. .toString(16)
  66. .padStart(64, "0");
  67. const sequence = result.stack.readNumber();
  68. const consistency_level = result.stack.readNumber();
  69. const payloadCell = result.stack.readCell();
  70. let payload = "";
  71. let currentCell = payloadCell;
  72. for (let i = 0; i < 4; i++) {
  73. // Original cell + up to 3 references since payload span across 4 cells
  74. const slice = currentCell.beginParse();
  75. payload += slice.loadBits(slice.remainingBits).toString().toLowerCase();
  76. if (slice.remainingRefs === 0) break;
  77. currentCell = slice.loadRef();
  78. }
  79. const hash = result.stack.readBigNumber().toString(16);
  80. return {
  81. version,
  82. vm_guardian_set_index,
  83. timestamp,
  84. nonce,
  85. emitter_chain_id,
  86. emitter_address,
  87. sequence,
  88. consistency_level,
  89. payload,
  90. hash,
  91. };
  92. }
  93. async getCurrentGuardianSetIndex(provider: ContractProvider) {
  94. return await super.getCurrentGuardianSetIndex(
  95. provider,
  96. "test_get_current_guardian_set_index"
  97. );
  98. }
  99. async getGuardianSet(provider: ContractProvider, index: number) {
  100. const result = await provider.get("test_get_guardian_set", [
  101. { type: "int", value: BigInt(index) },
  102. ]);
  103. const expirationTime = result.stack.readNumber();
  104. const keys = parseGuardianSetKeys(result.stack.readCell());
  105. const keyCount = result.stack.readNumber();
  106. return {
  107. expirationTime,
  108. keys,
  109. keyCount,
  110. };
  111. }
  112. async getGovernanceChainId(provider: ContractProvider) {
  113. const result = await provider.get("test_get_governance_chain_id", []);
  114. return result.stack.readNumber();
  115. }
  116. async getChainId(provider: ContractProvider) {
  117. return await super.getChainId(provider, "test_get_chain_id");
  118. }
  119. async getGovernanceContract(provider: ContractProvider) {
  120. const result = await provider.get("test_get_governance_contract", []);
  121. const bigNumber = result.stack.readBigNumber();
  122. return bigNumber.toString(16).padStart(64, "0");
  123. }
  124. async getGovernanceActionIsConsumed(
  125. provider: ContractProvider,
  126. hash: bigint
  127. ) {
  128. const result = await provider.get("test_governance_action_is_consumed", [
  129. { type: "int", value: hash },
  130. ]);
  131. return result.stack.readBoolean();
  132. }
  133. async sendUpdateGuardianSet(
  134. provider: ContractProvider,
  135. via: Sender,
  136. vm: Buffer
  137. ) {
  138. await super.sendUpdateGuardianSet(provider, via, vm);
  139. }
  140. }