feat(contract_manager): upgrade deploy scripts to use wormhole store (#1523)
* upgrade deploy scripts to use wormhole store * deploy not find * deploy price feed and entropy to taiko * rename type * rename method * address feedback * update js docs * deploy to olive testnet * pre commit * rename deploy config to base deploy config
This commit is contained in:
parent
a592c6bc33
commit
587a6fa524
|
@ -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))
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,29 +5,23 @@ import { DefaultStore } from "../src/store";
|
|||
import {
|
||||
DeploymentType,
|
||||
EvmEntropyContract,
|
||||
EvmPriceFeedContract,
|
||||
getDefaultDeploymentConfig,
|
||||
PrivateKey,
|
||||
toDeploymentType,
|
||||
toPrivateKey,
|
||||
EvmWormholeContract,
|
||||
} from "../src";
|
||||
import {
|
||||
COMMON_DEPLOY_OPTIONS,
|
||||
deployIfNotCached,
|
||||
getWeb3Contract,
|
||||
getOrDeployWormholeContract,
|
||||
BaseDeployConfig,
|
||||
} from "./common";
|
||||
import Web3 from "web3";
|
||||
|
||||
type DeploymentConfig = {
|
||||
interface DeploymentConfig extends BaseDeployConfig {
|
||||
type: DeploymentType;
|
||||
gasMultiplier: number;
|
||||
gasPriceMultiplier: number;
|
||||
privateKey: PrivateKey;
|
||||
jsonOutputDir: string;
|
||||
wormholeAddr: string;
|
||||
saveContract: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
const CACHE_FILE = ".cache-deploy-evm-entropy-contracts";
|
||||
const ENTROPY_DEFAULT_PROVIDER = {
|
||||
|
@ -51,7 +45,8 @@ const parser = yargs(hideBin(process.argv))
|
|||
|
||||
async function deployExecutorContracts(
|
||||
chain: EvmChain,
|
||||
config: DeploymentConfig
|
||||
config: DeploymentConfig,
|
||||
wormholeAddr: string
|
||||
): Promise<string> {
|
||||
const executorImplAddr = await deployIfNotCached(
|
||||
CACHE_FILE,
|
||||
|
@ -72,7 +67,7 @@ async function deployExecutorContracts(
|
|||
|
||||
const executorInitData = executorImplContract.methods
|
||||
.initialize(
|
||||
config.wormholeAddr,
|
||||
wormholeAddr,
|
||||
0, // lastExecutedSequence,
|
||||
chain.getWormholeChainId(),
|
||||
governanceDataSource.emitterChain,
|
||||
|
@ -161,19 +156,6 @@ async function topupProviderIfNecessary(
|
|||
}
|
||||
}
|
||||
|
||||
async function findWormholeAddress(
|
||||
chain: EvmChain
|
||||
): Promise<string | undefined> {
|
||||
for (const contract of Object.values(DefaultStore.contracts)) {
|
||||
if (
|
||||
contract instanceof EvmPriceFeedContract &&
|
||||
contract.getChain().getId() === chain.getId()
|
||||
) {
|
||||
return (await contract.getWormholeContract()).address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const argv = await parser.argv;
|
||||
|
||||
|
@ -185,12 +167,6 @@ async function main() {
|
|||
throw new Error(`Chain ${chainName} is not an EVM chain`);
|
||||
}
|
||||
|
||||
const wormholeAddr = await findWormholeAddress(chain);
|
||||
if (!wormholeAddr) {
|
||||
// TODO: deploy wormhole if necessary and maintain a wormhole store
|
||||
throw new Error(`Wormhole contract not found for chain ${chain.getId()}`);
|
||||
}
|
||||
|
||||
const deploymentConfig: DeploymentConfig = {
|
||||
type: toDeploymentType(argv.deploymentType),
|
||||
gasMultiplier: argv.gasMultiplier,
|
||||
|
@ -198,18 +174,14 @@ async function main() {
|
|||
privateKey: toPrivateKey(argv.privateKey),
|
||||
jsonOutputDir: argv.stdOutputDir,
|
||||
saveContract: argv.saveContract,
|
||||
wormholeAddr,
|
||||
};
|
||||
const wormholeContract = new EvmWormholeContract(
|
||||
|
||||
const wormholeContract = await getOrDeployWormholeContract(
|
||||
chain,
|
||||
deploymentConfig.wormholeAddr
|
||||
deploymentConfig,
|
||||
CACHE_FILE
|
||||
);
|
||||
const wormholeChainId = await wormholeContract.getChainId();
|
||||
if (chain.getWormholeChainId() != wormholeChainId) {
|
||||
throw new Error(
|
||||
`Wormhole chain id mismatch. Expected ${chain.getWormholeChainId()} but got ${wormholeChainId}`
|
||||
);
|
||||
}
|
||||
|
||||
await topupProviderIfNecessary(chain, deploymentConfig);
|
||||
|
||||
console.log(
|
||||
|
@ -218,7 +190,11 @@ async function main() {
|
|||
|
||||
console.log(`Deploying entropy contracts on ${chain.getId()}...`);
|
||||
|
||||
const executorAddr = await deployExecutorContracts(chain, deploymentConfig);
|
||||
const executorAddr = await deployExecutorContracts(
|
||||
chain,
|
||||
deploymentConfig,
|
||||
wormholeContract.address
|
||||
);
|
||||
const entropyAddr = await deployEntropyContracts(
|
||||
chain,
|
||||
deploymentConfig,
|
||||
|
|
|
@ -6,27 +6,23 @@ import {
|
|||
DeploymentType,
|
||||
EvmPriceFeedContract,
|
||||
getDefaultDeploymentConfig,
|
||||
PrivateKey,
|
||||
toDeploymentType,
|
||||
toPrivateKey,
|
||||
EvmWormholeContract,
|
||||
} from "../src";
|
||||
import {
|
||||
COMMON_DEPLOY_OPTIONS,
|
||||
deployIfNotCached,
|
||||
getWeb3Contract,
|
||||
getOrDeployWormholeContract,
|
||||
BaseDeployConfig,
|
||||
} from "./common";
|
||||
|
||||
type DeploymentConfig = {
|
||||
interface DeploymentConfig extends BaseDeployConfig {
|
||||
type: DeploymentType;
|
||||
validTimePeriodSeconds: number;
|
||||
singleUpdateFeeInWei: number;
|
||||
gasMultiplier: number;
|
||||
gasPriceMultiplier: number;
|
||||
privateKey: PrivateKey;
|
||||
jsonOutputDir: string;
|
||||
saveContract: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
const CACHE_FILE = ".cache-deploy-evm";
|
||||
|
||||
|
@ -51,65 +47,6 @@ const parser = yargs(hideBin(process.argv))
|
|||
},
|
||||
});
|
||||
|
||||
async function deployWormholeReceiverContracts(
|
||||
chain: EvmChain,
|
||||
config: DeploymentConfig
|
||||
): Promise<string> {
|
||||
const receiverSetupAddr = await deployIfNotCached(
|
||||
CACHE_FILE,
|
||||
chain,
|
||||
config,
|
||||
"ReceiverSetup",
|
||||
[]
|
||||
);
|
||||
|
||||
const receiverImplAddr = await deployIfNotCached(
|
||||
CACHE_FILE,
|
||||
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(
|
||||
CACHE_FILE,
|
||||
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()}`);
|
||||
}
|
||||
|
||||
return wormholeReceiverAddr;
|
||||
}
|
||||
|
||||
async function deployPriceFeedContracts(
|
||||
chain: EvmChain,
|
||||
config: DeploymentConfig,
|
||||
|
@ -183,14 +120,16 @@ async function main() {
|
|||
|
||||
console.log(`Deploying price feed contracts on ${chain.getId()}...`);
|
||||
|
||||
const wormholeAddr = await deployWormholeReceiverContracts(
|
||||
const wormholeContract = await getOrDeployWormholeContract(
|
||||
chain,
|
||||
deploymentConfig
|
||||
deploymentConfig,
|
||||
CACHE_FILE
|
||||
);
|
||||
|
||||
const priceFeedAddr = await deployPriceFeedContracts(
|
||||
chain,
|
||||
deploymentConfig,
|
||||
wormholeAddr
|
||||
wormholeContract.address
|
||||
);
|
||||
|
||||
if (deploymentConfig.saveContract) {
|
||||
|
|
|
@ -569,3 +569,8 @@
|
|||
rpcUrl: https://olive-network-testnet.rpc.caldera.xyz/http
|
||||
networkId: 8101902
|
||||
type: EvmChain
|
||||
- id: taiko_hekla
|
||||
mainnet: false
|
||||
rpcUrl: https://rpc.hekla.taiko.xyz/
|
||||
networkId: 167009
|
||||
type: EvmChain
|
||||
|
|
|
@ -43,3 +43,6 @@
|
|||
- chain: injective
|
||||
address: inj17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9l2q74d
|
||||
type: CosmWasmWormholeContract
|
||||
- chain: xion_testnet
|
||||
address: xion14ycw3tx0hpz3aawmzm6cufs6hx94d64ht5qawd0ej9ug9j2ffzsqmpecys
|
||||
type: CosmWasmWormholeContract
|
||||
|
|
|
@ -61,3 +61,6 @@
|
|||
- chain: sei_evm_devnet
|
||||
address: "0x23f0e8FAeE7bbb405E7A7C3d60138FCfd43d7509"
|
||||
type: EvmEntropyContract
|
||||
- chain: taiko_hekla
|
||||
address: "0x98046Bd286715D3B0BC227Dd7a956b83D8978603"
|
||||
type: EvmEntropyContract
|
||||
|
|
|
@ -316,6 +316,9 @@
|
|||
- chain: flow_previewnet
|
||||
address: "0x2880aB155794e7179c9eE2e38200202908C17B43"
|
||||
type: EvmPriceFeedContract
|
||||
- chain: olive_testnet
|
||||
- chain: taiko_hekla
|
||||
address: "0x2880aB155794e7179c9eE2e38200202908C17B43"
|
||||
type: EvmPriceFeedContract
|
||||
- chain: olive_testnet
|
||||
address: "0x41c9e39574F40Ad34c79f1C99B66A45eFB830d4c"
|
||||
type: EvmPriceFeedContract
|
||||
|
|
|
@ -295,3 +295,9 @@
|
|||
- chain: linea_goerli
|
||||
address: "0xfA25E653b44586dBbe27eE9d252192F0e4956683"
|
||||
type: EvmWormholeContract
|
||||
- chain: taiko_hekla
|
||||
address: "0xb27e5ca259702f209a29225d0eDdC131039C9933"
|
||||
type: EvmWormholeContract
|
||||
- chain: olive_testnet
|
||||
address: "0x74f09cb3c7e2A01865f424FD14F6dc9A14E3e94E"
|
||||
type: EvmWormholeContract
|
||||
|
|
|
@ -145,7 +145,8 @@ export const RECEIVER_CHAINS = {
|
|||
boba_sepolia: 50068,
|
||||
astar_zkyoto_testnet: 50069,
|
||||
xion_testnet: 50070,
|
||||
olive_testnet: 50071,
|
||||
taiko_hekla: 50071,
|
||||
olive_testnet: 50072,
|
||||
};
|
||||
|
||||
// If there is any overlapping value the receiver chain will replace the wormhole
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@pythnetwork/pyth-evm-js",
|
||||
"version": "1.45.0",
|
||||
"version": "1.46.0",
|
||||
"description": "Pyth Network EVM Utils in JS",
|
||||
"homepage": "https://pyth.network",
|
||||
"author": {
|
||||
|
|
|
@ -103,7 +103,7 @@ export const CONTRACT_ADDR: Record<string, string> = {
|
|||
movement_evm_devnet: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729",
|
||||
mumbai: "0xFC6bd9F9f0c6481c6Af3A7Eb46b296A5B85ed379",
|
||||
neon_devnet: "0x0708325268dF9F66270F1401206434524814508b",
|
||||
olive_testnet: "0x2880aB155794e7179c9eE2e38200202908C17B43",
|
||||
olive_testnet: "0x41c9e39574F40Ad34c79f1C99B66A45eFB830d4c",
|
||||
optimism_celestia_raspberry: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729",
|
||||
optimism_goerli: "0xDd24F84d36BF92C65F92307595335bdFab5Bbd21",
|
||||
optimism_sepolia: "0x0708325268dF9F66270F1401206434524814508b",
|
||||
|
@ -116,6 +116,7 @@ export const CONTRACT_ADDR: Record<string, string> = {
|
|||
scroll_sepolia: "0x41c9e39574F40Ad34c79f1C99B66A45eFB830d4c",
|
||||
sepolia: "0xDd24F84d36BF92C65F92307595335bdFab5Bbd21",
|
||||
shimmer_testnet: "0x8D254a21b3C86D32F7179855531CE99164721933",
|
||||
taiko_hekla: "0x2880aB155794e7179c9eE2e38200202908C17B43",
|
||||
viction_testnet: "0x5D289Ad1CE59fCC25b6892e7A303dfFf3a9f7167",
|
||||
wemix_testnet: "0x26DD80569a8B23768A1d80869Ed7339e07595E85",
|
||||
zetachain_testnet: "0x0708325268dF9F66270F1401206434524814508b",
|
||||
|
|
Loading…
Reference in New Issue