entropy-accept-admin-and-ownership.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* eslint-disable @typescript-eslint/no-floating-promises */
  2. /* eslint-disable unicorn/prefer-top-level-await */
  3. /* eslint-disable no-console */
  4. import yargs from "yargs";
  5. import { hideBin } from "yargs/helpers";
  6. import { EvmChain } from "../src/core/chains";
  7. import { loadHotWallet } from "../src/node/utils/governance";
  8. import { DefaultStore } from "../src/node/utils/store";
  9. const parser = yargs(hideBin(process.argv))
  10. .usage(
  11. "Creates governance proposal to accept pending admin or ownership transfer for Pyth entropy contracts.\n" +
  12. "Usage: $0 --chain <chain_1> --chain <chain_2> --ops-key-path <ops_key_path>",
  13. )
  14. .options({
  15. testnet: {
  16. type: "boolean",
  17. default: false,
  18. desc: "Accept for testnet contracts instead of mainnet",
  19. },
  20. "all-chains": {
  21. type: "boolean",
  22. default: false,
  23. desc: "Accept for contract on all chains. Use with --testnet flag to accept for all testnet contracts",
  24. },
  25. chain: {
  26. type: "array",
  27. string: true,
  28. desc: "Accept for contract on given chains",
  29. },
  30. "ops-key-path": {
  31. type: "string",
  32. demandOption: true,
  33. desc: "Path to the private key of the proposer to use for the operations multisig governance proposal",
  34. },
  35. });
  36. async function main() {
  37. const argv = await parser.argv;
  38. const selectedChains: EvmChain[] = [];
  39. if (argv.allChains && argv.chain)
  40. throw new Error("Cannot use both --all-chains and --chain");
  41. if (!argv.allChains && !argv.chain)
  42. throw new Error("Must use either --all-chains or --chain");
  43. for (const chain of Object.values(DefaultStore.chains)) {
  44. if (!(chain instanceof EvmChain)) continue;
  45. if (
  46. (argv.allChains && chain.isMainnet() !== argv.testnet) ||
  47. argv.chain?.includes(chain.getId())
  48. )
  49. selectedChains.push(chain);
  50. }
  51. if (argv.chain && selectedChains.length !== argv.chain.length)
  52. throw new Error(
  53. `Some chains were not found ${selectedChains
  54. .map((chain) => chain.getId())
  55. .toString()}`,
  56. );
  57. for (const chain of selectedChains) {
  58. if (chain.isMainnet() != selectedChains[0]?.isMainnet())
  59. throw new Error("All chains must be either mainnet or testnet");
  60. }
  61. const vault =
  62. DefaultStore.vaults[
  63. "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
  64. ];
  65. const payloads: Buffer[] = [];
  66. for (const contract of Object.values(DefaultStore.entropy_contracts)) {
  67. if (selectedChains.includes(contract.chain)) {
  68. console.log("Creating payload for chain:", contract.chain.getId());
  69. const pendingOwner = await contract.getPendingOwner();
  70. const adminPayload = contract.generateAcceptAdminPayload(pendingOwner);
  71. const ownerPayload =
  72. contract.generateAcceptOwnershipPayload(pendingOwner);
  73. payloads.push(adminPayload, ownerPayload);
  74. }
  75. }
  76. console.log("Using vault at for proposal", vault?.getId());
  77. const wallet = await loadHotWallet(argv["ops-key-path"]);
  78. console.log("Using wallet", wallet.publicKey.toBase58());
  79. // eslint-disable-next-line @typescript-eslint/await-thenable
  80. await vault?.connect(wallet);
  81. const proposal = await vault?.proposeWormholeMessage(payloads);
  82. console.log("Proposal address", proposal?.address.toBase58());
  83. }
  84. main();