| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import yargs from "yargs";
- import { hideBin } from "yargs/helpers";
- import { DefaultStore, EvmChain, loadHotWallet, toPrivateKey } from "../src";
- import { existsSync, readFileSync, writeFileSync } from "fs";
- const CACHE_FILE = ".cache-upgrade-evm";
- const parser = yargs(hideBin(process.argv))
- .usage(
- "Deploys a new PythUpgradable contract to a set of chains and creates a governance proposal for it.\n" +
- `Uses a cache file (${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({
- testnet: {
- type: "boolean",
- default: false,
- desc: "Upgrade testnet contracts instead of mainnet",
- },
- "all-chains": {
- type: "boolean",
- default: false,
- desc: "Upgrade the contract on all chains. Use with --testnet flag to upgrade all testnet contracts",
- },
- chain: {
- type: "array",
- string: true,
- desc: "Chains to upgrade the contract on",
- },
- "private-key": {
- type: "string",
- demandOption: true,
- desc: "Private key to use for the deployment",
- },
- "ops-key-path": {
- type: "string",
- demandOption: true,
- desc: "Path to the private key of the proposer to use for the operations multisig governance proposal",
- },
- "std-output": {
- type: "string",
- demandOption: true,
- desc: "Path to the standard JSON output of the pyth contract (build artifact)",
- },
- });
- async function run_if_not_cached(
- cache_key: string,
- fn: () => Promise<string>
- ): Promise<string> {
- const cache = existsSync(CACHE_FILE)
- ? JSON.parse(readFileSync(CACHE_FILE, "utf8"))
- : {};
- if (cache[cache_key]) {
- return cache[cache_key];
- }
- const result = await fn();
- cache[cache_key] = result;
- writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
- return result;
- }
- async function main() {
- const argv = await parser.argv;
- const selectedChains: EvmChain[] = [];
- if (argv.allChains && argv.chain)
- throw new Error("Cannot use both --all-chains and --chain");
- if (!argv.allChains && !argv.chain)
- throw new Error("Must use either --all-chains or --chain");
- for (const chain of Object.values(DefaultStore.chains)) {
- if (!(chain instanceof EvmChain)) continue;
- if (
- (argv.allChains && chain.isMainnet() !== argv.testnet) ||
- argv.chain?.includes(chain.getId())
- )
- selectedChains.push(chain);
- }
- if (argv.chain && selectedChains.length !== argv.chain.length)
- throw new Error(
- `Some chains were not found ${selectedChains
- .map((chain) => chain.getId())
- .toString()}`
- );
- for (const chain of selectedChains) {
- if (chain.isMainnet() != selectedChains[0].isMainnet())
- throw new Error("All chains must be either mainnet or testnet");
- }
- const vault =
- DefaultStore.vaults[
- "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
- ];
- console.log("Using cache file", CACHE_FILE);
- console.log(
- "Upgrading on chains",
- selectedChains.map((c) => c.getId())
- );
- const payloads: Buffer[] = [];
- for (const chain of selectedChains) {
- const artifact = JSON.parse(readFileSync(argv["std-output"], "utf8"));
- console.log("Deploying contract to", chain.getId());
- const address = await run_if_not_cached(`deploy-${chain.getId()}`, () => {
- return chain.deploy(
- toPrivateKey(argv["private-key"]),
- artifact["abi"],
- artifact["bytecode"],
- []
- );
- });
- console.log(`Deployed contract at ${address} on ${chain.getId()}`);
- payloads.push(
- chain.generateGovernanceUpgradePayload(address.replace("0x", ""))
- );
- }
- console.log("Using vault at for proposal", vault.getId());
- const wallet = await loadHotWallet(argv["ops-key-path"]);
- console.log("Using wallet ", wallet.publicKey.toBase58());
- await vault.connect(wallet);
- const proposal = await vault.proposeWormholeMessage(payloads);
- console.log("Proposal address", proposal.address.toBase58());
- }
- main();
|