| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /* eslint-disable @typescript-eslint/restrict-template-expressions */
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
- /* eslint-disable no-console */
- import { readFileSync } from "node:fs";
- import type { PythCluster } from "@pythnetwork/client/lib/cluster";
- import yargs from "yargs";
- import { hideBin } from "yargs/helpers";
- import {
- COMMON_UPGRADE_OPTIONS,
- getSelectedChains,
- makeCacheFunction,
- } from "./common";
- import { toPrivateKey } from "../src/core/base";
- import { loadHotWallet } from "../src/node/utils/governance";
- import { DefaultStore } from "../src/node/utils/store";
- const EXECUTOR_CACHE_FILE = ".cache-upgrade-evm-executor-contract";
- const ENTROPY_CACHE_FILE = ".cache-upgrade-evm-entropy-contract";
- const parser = yargs(hideBin(process.argv))
- .usage(
- "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" +
- `Uses a cache file to avoid deploying contracts twice\n` +
- "Usage: $0 --chain <chain_1> --chain <chain_2> --private-key <private_key> --ops-key-path <ops_key_path> --std-output <std_output>",
- )
- .options({
- ...COMMON_UPGRADE_OPTIONS,
- "contract-type": {
- type: "string",
- choices: ["executor", "entropy"],
- demandOption: true,
- },
- });
- // Override these URLs to use a different RPC node for mainnet / testnet.
- // TODO: extract these RPCs to a config file (?)
- const RPCS = {
- "mainnet-beta": "https://api.mainnet-beta.solana.com",
- testnet: "https://api.testnet.solana.com",
- devnet: "https://api.devnet.solana.com",
- } as Record<PythCluster, string>;
- function registry(cluster: PythCluster): string {
- return RPCS[cluster];
- }
- async function main() {
- const argv = await parser.argv;
- const cacheFile =
- argv["contract-type"] === "executor"
- ? EXECUTOR_CACHE_FILE
- : ENTROPY_CACHE_FILE;
- const runIfNotCached = makeCacheFunction(cacheFile);
- const selectedChains = getSelectedChains(argv);
- const vault =
- DefaultStore.vaults[
- "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
- ];
- console.log("Using cache file", cacheFile);
- // Try to deploy on every chain, then collect any failures at the end. This logic makes it simpler to
- // identify deployment problems (e.g., not enough gas) on every chain where they occur.
- const payloads: Buffer[] = [];
- const failures: string[] = [];
- for (const contract of Object.values(DefaultStore.entropy_contracts)) {
- if (selectedChains.includes(contract.chain)) {
- const artifact = JSON.parse(readFileSync(argv["std-output"], "utf8"));
- console.log("Deploying contract to", contract.chain.getId());
- try {
- const address = await runIfNotCached(
- `deploy-${contract.chain.getId()}`,
- () => {
- return contract.chain.deploy(
- toPrivateKey(argv["private-key"]),
- artifact.abi,
- artifact.bytecode.object, // As per the artifacts generated by forge, bytecode is an object with an 'object' property
- [],
- 2,
- );
- },
- );
- console.log(
- `Deployed contract at ${address} on ${contract.chain.getId()}`,
- );
- const payload =
- argv["contract-type"] === "executor"
- ? await contract.generateUpgradeExecutorContractsPayload(address)
- : await contract.generateUpgradeEntropyContractPayload(address);
- console.log(payload.toString("hex"));
- payloads.push(payload);
- } catch (error) {
- console.log(`error deploying: ${error}`);
- failures.push(contract.chain.getId());
- }
- }
- }
- if (failures.length > 0) {
- throw new Error(
- `Some chains could not be deployed: ${failures.join(
- ", ",
- )}. Scroll up to see the errors from each chain.`,
- );
- }
- console.log("Using vault at for proposal", vault?.getId());
- const wallet = await loadHotWallet(argv["ops-key-path"]);
- console.log("Using wallet", wallet.publicKey.toBase58());
- vault?.connect(wallet, registry);
- const proposal = await vault?.proposeWormholeMessage(payloads);
- console.log("Proposal address", proposal?.address.toBase58());
- }
- // eslint-disable-next-line @typescript-eslint/no-floating-promises, unicorn/prefer-top-level-await
- main();
|