upgrade_evm_entropy_contracts.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import yargs from "yargs";
  2. import { hideBin } from "yargs/helpers";
  3. import { DefaultStore, loadHotWallet, toPrivateKey } from "../src";
  4. import { readFileSync } from "fs";
  5. import { PythCluster } from "@pythnetwork/client/lib/cluster";
  6. import {
  7. COMMON_UPGRADE_OPTIONS,
  8. getSelectedChains,
  9. makeCacheFunction,
  10. } from "./common";
  11. const EXECUTOR_CACHE_FILE = ".cache-upgrade-evm-executor-contract";
  12. const ENTROPY_CACHE_FILE = ".cache-upgrade-evm-entropy-contract";
  13. const parser = yargs(hideBin(process.argv))
  14. .usage(
  15. "Deploys a new Upgradeable contract for Executor or Entropy to a set of chains where Entropy is deployed and creates a governance proposal for it.\n" +
  16. `Uses a cache file to avoid deploying contracts twice\n` +
  17. "Usage: $0 --chain <chain_1> --chain <chain_2> --private-key <private_key> --ops-key-path <ops_key_path> --std-output <std_output>",
  18. )
  19. .options({
  20. ...COMMON_UPGRADE_OPTIONS,
  21. "contract-type": {
  22. type: "string",
  23. choices: ["executor", "entropy"],
  24. demandOption: true,
  25. },
  26. });
  27. // Override these URLs to use a different RPC node for mainnet / testnet.
  28. // TODO: extract these RPCs to a config file (?)
  29. const RPCS = {
  30. "mainnet-beta": "https://api.mainnet-beta.solana.com",
  31. testnet: "https://api.testnet.solana.com",
  32. devnet: "https://api.devnet.solana.com",
  33. } as Record<PythCluster, string>;
  34. function registry(cluster: PythCluster): string {
  35. return RPCS[cluster];
  36. }
  37. async function main() {
  38. const argv = await parser.argv;
  39. const cacheFile =
  40. argv["contract-type"] === "executor"
  41. ? EXECUTOR_CACHE_FILE
  42. : ENTROPY_CACHE_FILE;
  43. const runIfNotCached = makeCacheFunction(cacheFile);
  44. const selectedChains = getSelectedChains(argv);
  45. const vault =
  46. DefaultStore.vaults[
  47. "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
  48. ];
  49. console.log("Using cache file", cacheFile);
  50. // Try to deploy on every chain, then collect any failures at the end. This logic makes it simpler to
  51. // identify deployment problems (e.g., not enough gas) on every chain where they occur.
  52. const payloads: Buffer[] = [];
  53. const failures: string[] = [];
  54. for (const contract of Object.values(DefaultStore.entropy_contracts)) {
  55. if (selectedChains.includes(contract.chain)) {
  56. const artifact = JSON.parse(readFileSync(argv["std-output"], "utf8"));
  57. console.log("Deploying contract to", contract.chain.getId());
  58. try {
  59. const address = await runIfNotCached(
  60. `deploy-${contract.chain.getId()}`,
  61. () => {
  62. return contract.chain.deploy(
  63. toPrivateKey(argv["private-key"]),
  64. artifact["abi"],
  65. artifact["bytecode"],
  66. [],
  67. 2,
  68. );
  69. },
  70. );
  71. console.log(
  72. `Deployed contract at ${address} on ${contract.chain.getId()}`,
  73. );
  74. const payload =
  75. argv["contract-type"] === "executor"
  76. ? await contract.generateUpgradeExecutorContractsPayload(address)
  77. : await contract.generateUpgradeEntropyContractPayload(address);
  78. console.log(payload.toString("hex"));
  79. payloads.push(payload);
  80. } catch (e) {
  81. console.log(`error deploying: ${e}`);
  82. failures.push(contract.chain.getId());
  83. }
  84. }
  85. }
  86. if (failures.length > 0) {
  87. throw new Error(
  88. `Some chains could not be deployed: ${failures.join(
  89. ", ",
  90. )}. Scroll up to see the errors from each chain.`,
  91. );
  92. }
  93. console.log("Using vault at for proposal", vault.getId());
  94. const wallet = await loadHotWallet(argv["ops-key-path"]);
  95. console.log("Using wallet ", wallet.publicKey.toBase58());
  96. vault.connect(wallet, registry);
  97. const proposal = await vault.proposeWormholeMessage(payloads);
  98. console.log("Proposal address", proposal.address.toBase58());
  99. }
  100. main();