|
|
@@ -1,11 +1,18 @@
|
|
|
-import { DefaultStore, EvmChain, EvmEntropyContract, PrivateKey } from "../src";
|
|
|
+import {
|
|
|
+ DefaultStore,
|
|
|
+ EvmChain,
|
|
|
+ EvmEntropyContract,
|
|
|
+ EvmWormholeContract,
|
|
|
+ getDefaultDeploymentConfig,
|
|
|
+ PrivateKey,
|
|
|
+} from "../src";
|
|
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
|
import { join } from "path";
|
|
|
import Web3 from "web3";
|
|
|
import { Contract } from "web3-eth-contract";
|
|
|
import { InferredOptionType } from "yargs";
|
|
|
|
|
|
-interface DeployConfig {
|
|
|
+export interface BaseDeployConfig {
|
|
|
gasMultiplier: number;
|
|
|
gasPriceMultiplier: number;
|
|
|
jsonOutputDir: string;
|
|
|
@@ -19,7 +26,7 @@ interface DeployConfig {
|
|
|
export async function deployIfNotCached(
|
|
|
cacheFile: string,
|
|
|
chain: EvmChain,
|
|
|
- config: DeployConfig,
|
|
|
+ config: BaseDeployConfig,
|
|
|
artifactName: string,
|
|
|
deployArgs: any[], // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
|
cacheKey?: string
|
|
|
@@ -212,3 +219,118 @@ export function findEvmChain(chainName: string): EvmChain {
|
|
|
}
|
|
|
return chain;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Finds the wormhole contract for a given EVM chain.
|
|
|
+ * @param {EvmChain} chain The EVM chain to find the wormhole contract for.
|
|
|
+ * @returns If found, the wormhole contract for the given EVM chain. Else, undefined
|
|
|
+ */
|
|
|
+export function findWormholeContract(
|
|
|
+ chain: EvmChain
|
|
|
+): EvmWormholeContract | undefined {
|
|
|
+ for (const contract of Object.values(DefaultStore.wormhole_contracts)) {
|
|
|
+ if (
|
|
|
+ contract instanceof EvmWormholeContract &&
|
|
|
+ contract.getChain().getId() === chain.getId()
|
|
|
+ ) {
|
|
|
+ return contract;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export interface DeployWormholeReceiverContractsConfig
|
|
|
+ extends BaseDeployConfig {
|
|
|
+ saveContract: boolean;
|
|
|
+ type: "stable" | "beta";
|
|
|
+}
|
|
|
+/**
|
|
|
+ * Deploys the wormhole receiver contract for a given EVM chain.
|
|
|
+ * @param {EvmChain} chain The EVM chain to find the wormhole receiver contract for.
|
|
|
+ * @param {DeployWormholeReceiverContractsConfig} config The deployment configuration.
|
|
|
+ * @param {string} cacheFile The path to the cache file.
|
|
|
+ * @returns {EvmWormholeContract} The wormhole contract for the given EVM chain.
|
|
|
+ */
|
|
|
+export async function deployWormholeContract(
|
|
|
+ chain: EvmChain,
|
|
|
+ config: DeployWormholeReceiverContractsConfig,
|
|
|
+ cacheFile: string
|
|
|
+): Promise<EvmWormholeContract> {
|
|
|
+ const receiverSetupAddr = await deployIfNotCached(
|
|
|
+ cacheFile,
|
|
|
+ chain,
|
|
|
+ config,
|
|
|
+ "ReceiverSetup",
|
|
|
+ []
|
|
|
+ );
|
|
|
+
|
|
|
+ const receiverImplAddr = await deployIfNotCached(
|
|
|
+ cacheFile,
|
|
|
+ chain,
|
|
|
+ config,
|
|
|
+ "ReceiverImplementation",
|
|
|
+ []
|
|
|
+ );
|
|
|
+
|
|
|
+ // Craft the init data for the proxy contract
|
|
|
+ const setupContract = getWeb3Contract(
|
|
|
+ config.jsonOutputDir,
|
|
|
+ "ReceiverSetup",
|
|
|
+ receiverSetupAddr
|
|
|
+ );
|
|
|
+
|
|
|
+ const { wormholeConfig } = getDefaultDeploymentConfig(config.type);
|
|
|
+
|
|
|
+ const initData = setupContract.methods
|
|
|
+ .setup(
|
|
|
+ receiverImplAddr,
|
|
|
+ wormholeConfig.initialGuardianSet.map((addr: string) => "0x" + addr),
|
|
|
+ chain.getWormholeChainId(),
|
|
|
+ wormholeConfig.governanceChainId,
|
|
|
+ "0x" + wormholeConfig.governanceContract
|
|
|
+ )
|
|
|
+ .encodeABI();
|
|
|
+
|
|
|
+ const wormholeReceiverAddr = await deployIfNotCached(
|
|
|
+ cacheFile,
|
|
|
+ chain,
|
|
|
+ config,
|
|
|
+ "WormholeReceiver",
|
|
|
+ [receiverSetupAddr, initData]
|
|
|
+ );
|
|
|
+
|
|
|
+ const wormholeContract = new EvmWormholeContract(chain, wormholeReceiverAddr);
|
|
|
+
|
|
|
+ if (config.type === "stable") {
|
|
|
+ console.log(`Syncing mainnet guardian sets for ${chain.getId()}...`);
|
|
|
+ // TODO: Add a way to pass gas configs to this
|
|
|
+ await wormholeContract.syncMainnetGuardianSets(config.privateKey);
|
|
|
+ console.log(`✅ Synced mainnet guardian sets for ${chain.getId()}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (config.saveContract) {
|
|
|
+ DefaultStore.wormhole_contracts[wormholeContract.getId()] =
|
|
|
+ wormholeContract;
|
|
|
+ DefaultStore.saveAllContracts();
|
|
|
+ }
|
|
|
+
|
|
|
+ return wormholeContract;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Returns the wormhole contract for a given EVM chain.
|
|
|
+ * If there was no wormhole contract deployed for the given chain, it will deploy the wormhole contract and save it to the default store.
|
|
|
+ * @param {EvmChain} chain The EVM chain to find the wormhole contract for.
|
|
|
+ * @param {DeployWormholeReceiverContractsConfig} config The deployment configuration.
|
|
|
+ * @param {string} cacheFile The path to the cache file.
|
|
|
+ * @returns {EvmWormholeContract} The wormhole contract for the given EVM chain.
|
|
|
+ */
|
|
|
+export async function getOrDeployWormholeContract(
|
|
|
+ chain: EvmChain,
|
|
|
+ config: DeployWormholeReceiverContractsConfig,
|
|
|
+ cacheFile: string
|
|
|
+): Promise<EvmWormholeContract> {
|
|
|
+ return (
|
|
|
+ findWormholeContract(chain) ??
|
|
|
+ (await deployWormholeContract(chain, config, cacheFile))
|
|
|
+ );
|
|
|
+}
|