diff --git a/ethereum/.gitignore b/ethereum/.gitignore index ecd54f7..9aae968 100644 --- a/ethereum/.gitignore +++ b/ethereum/.gitignore @@ -7,3 +7,6 @@ lib node_modules wormhole ts-scripts/output +ts-scripts/.env +ts-scripts/.env.testnet +ts-scripts/.env.mainnet diff --git a/ethereum/package.json b/ethereum/package.json index 3a67052..2f666c7 100644 --- a/ethereum/package.json +++ b/ethereum/package.json @@ -23,7 +23,7 @@ "flatten": "mkdir -p node_modules/@poanet/solidity-flattener/contracts && cp -r contracts/* node_modules/@poanet/solidity-flattener/contracts/ && poa-solidity-flattener", "registerChains": "ts-node ./ts-scripts/registerChains.ts", "messageTest": "ts-node ./ts-scripts/messageTest.ts", - "deployAndConfigureTilt": "ENV=tilt ts-node ./ts-scripts/deployAndConfigure.ts" + "deployAndConfigureTilt": "ENV=tilt bash ./ts-scripts/shell/deployConfigureTest.sh" }, "author": "", "license": "ISC", diff --git a/ethereum/ts-scripts/config/tilt.json b/ethereum/ts-scripts/config/tilt.json deleted file mode 100644 index f7a5e7c..0000000 --- a/ethereum/ts-scripts/config/tilt.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "chains": [ - { - "id": 1337, - "wormholeId": 2, - "rpc": "http://localhost:8545", - "wormholeAddress": "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550" - }, - { - "id": 1397, - "wormholeId": 4, - "rpc": "http://localhost:8546", - "wormholeAddress": "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550" - } - ], - "defaultCoreRelayerConfig": {}, - "defaultRelayProviderConfig": { - "deliverGasOverhead": "350000", - "updatePriceGas": "300000000000", - "updatePriceNative": "100000", - "maximumBudget": "1000000000000000000" - } -} diff --git a/ethereum/ts-scripts/config/tilt/chains.json b/ethereum/ts-scripts/config/tilt/chains.json new file mode 100644 index 0000000..5302785 --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/chains.json @@ -0,0 +1,17 @@ +{ + "description": "This file contains the chains against which all the scripts should run.", + "chains": [ + { + "evmNetworkId": 1337, + "chainId": 2, + "rpc": "http://localhost:8545", + "wormholeAddress": "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550" + }, + { + "evmNetworkId": 1397, + "chainId": 4, + "rpc": "http://localhost:8546", + "wormholeAddress": "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550" + } + ] +} diff --git a/ethereum/ts-scripts/config/tilt/contracts.json b/ethereum/ts-scripts/config/tilt/contracts.json new file mode 100644 index 0000000..c2dde40 --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/contracts.json @@ -0,0 +1,34 @@ +{ + "description": "This file contains the addresses for the relayProviderProxy and CoreRelayerProxy on each chain. If useLastRun is true, this file will be ignored, and the addresses will be taken from the lastrun.json of the deployment scripts.", + "useLastRun": true, + "relayProviders": [ + { + "chainId": 2, + "address": "" + }, + { + "chainId": 4, + "address": "" + } + ], + "coreRelayers": [ + { + "chainId": 2, + "address": "" + }, + { + "chainId": 4, + "address": "" + } + ], + "mockIntegrations": [ + { + "chainId": 2, + "address": "" + }, + { + "chainId": 4, + "address": "" + } + ] +} diff --git a/ethereum/ts-scripts/config/tilt/scriptConfigs/configureCoreRelayer.json b/ethereum/ts-scripts/config/tilt/scriptConfigs/configureCoreRelayer.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/scriptConfigs/configureCoreRelayer.json @@ -0,0 +1 @@ +{} diff --git a/ethereum/ts-scripts/config/tilt/scriptConfigs/configureRelayProvider.json b/ethereum/ts-scripts/config/tilt/scriptConfigs/configureRelayProvider.json new file mode 100644 index 0000000..99cce8b --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/scriptConfigs/configureRelayProvider.json @@ -0,0 +1,37 @@ +{ + "addresses": [ + { + "chainId": 2, + "rewardAddress": "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1", + "approvedSenders": { + "address": "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1", + "approved": true + } + }, + { + "chainId": 4, + "rewardAddress": "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1", + "approvedSenders": { + "address": "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1", + "approved": true + } + } + ], + + "pricingInfo": [ + { + "chainId": 2, + "deliverGasOverhead": "350000", + "updatePriceGas": "300000000000", + "updatePriceNative": "100000", + "maximumBudget": "1000000000000000000" + }, + { + "chainId": 4, + "deliverGasOverhead": "350000", + "updatePriceGas": "300000000000", + "updatePriceNative": "100000", + "maximumBudget": "1000000000000000000" + } + ] +} diff --git a/ethereum/ts-scripts/config/tilt/scriptConfigs/deployCoreRelayer.json b/ethereum/ts-scripts/config/tilt/scriptConfigs/deployCoreRelayer.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/scriptConfigs/deployCoreRelayer.json @@ -0,0 +1 @@ +{} diff --git a/ethereum/ts-scripts/config/tilt/scriptConfigs/deployRelayProvider.json b/ethereum/ts-scripts/config/tilt/scriptConfigs/deployRelayProvider.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/scriptConfigs/deployRelayProvider.json @@ -0,0 +1 @@ +{} diff --git a/ethereum/ts-scripts/config/tilt/scriptConfigs/registerChainsCoreRelayer.json b/ethereum/ts-scripts/config/tilt/scriptConfigs/registerChainsCoreRelayer.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/scriptConfigs/registerChainsCoreRelayer.json @@ -0,0 +1 @@ +{} diff --git a/ethereum/ts-scripts/config/tilt/scriptConfigs/registerChainsRelayProvider.json b/ethereum/ts-scripts/config/tilt/scriptConfigs/registerChainsRelayProvider.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/ethereum/ts-scripts/config/tilt/scriptConfigs/registerChainsRelayProvider.json @@ -0,0 +1 @@ +{} diff --git a/ethereum/ts-scripts/coreRelayer/deployCoreRelayer.ts b/ethereum/ts-scripts/coreRelayer/deployCoreRelayer.ts new file mode 100644 index 0000000..bc6b7e3 --- /dev/null +++ b/ethereum/ts-scripts/coreRelayer/deployCoreRelayer.ts @@ -0,0 +1,104 @@ +import { CoreRelayerProxy__factory } from "../../../sdk/src/ethers-contracts/factories/CoreRelayerProxy__factory" +import { CoreRelayerSetup__factory } from "../../../sdk/src/ethers-contracts/factories/CoreRelayerSetup__factory" +import { CoreRelayerImplementation__factory } from "../../../sdk/src/ethers-contracts/factories/CoreRelayerImplementation__factory" +import { + init, + loadChains, + writeOutputFiles, + ChainInfo, + Deployment, + getRelayProviderAddress, + getSigner, +} from "../helpers/env" + +import { ethers } from "ethers" + +const processName = "deployCoreRelayer" +init() +const chains = loadChains() + +async function run() { + console.log("Start! " + processName) + + const output: any = { + coreRelayerImplementations: [], + coreRelayerSetups: [], + coreRelayerProxies: [], + } + + for (let i = 0; i < chains.length; i++) { + const coreRelayerImplementation = await deployCoreRelayerImplementation(chains[i]) + const coreRelayerSetup = await deployCoreRelayerSetup(chains[i]) + const coreRelayerProxy = await deployCoreRelayerProxy( + chains[i], + coreRelayerSetup.address, + coreRelayerImplementation.address, + chains[i].wormholeAddress, + getRelayProviderAddress(chains[i]) + ) + + output.coreRelayerImplementations.push(coreRelayerImplementation) + output.coreRelayerSetups.push(coreRelayerSetup) + output.coreRelayerProxies.push(coreRelayerProxy) + } + + writeOutputFiles(output, processName) +} + +async function deployCoreRelayerImplementation(chain: ChainInfo): Promise { + console.log("deployCoreRelayerImplementation " + chain.chainId) + const signer = getSigner(chain) + const contractInterface = CoreRelayerImplementation__factory.createInterface() + const bytecode = CoreRelayerImplementation__factory.bytecode + //@ts-ignore + const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) + const contract = await factory.deploy() + return await contract.deployed().then((result) => { + console.log("Successfully deployed contract at " + result.address) + return { address: result.address, chainId: chain.chainId } + }) +} +async function deployCoreRelayerSetup(chain: ChainInfo): Promise { + console.log("deployCoreRelayerSetup " + chain.chainId) + const signer = getSigner(chain) + const contractInterface = CoreRelayerSetup__factory.createInterface() + const bytecode = CoreRelayerSetup__factory.bytecode + //@ts-ignore + const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) + const contract = await factory.deploy() + return await contract.deployed().then((result) => { + console.log("Successfully deployed contract at " + result.address) + return { address: result.address, chainId: chain.chainId } + }) +} +async function deployCoreRelayerProxy( + chain: ChainInfo, + coreRelayerSetupAddress: string, + coreRelayerImplementationAddress: string, + wormholeAddress: string, + relayProviderProxyAddress: string +): Promise { + console.log("deployCoreRelayerProxy " + chain.chainId) + const signer = getSigner(chain) + const contractInterface = CoreRelayerProxy__factory.createInterface() + const bytecode = CoreRelayerProxy__factory.bytecode + //@ts-ignore + const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) + + let ABI = ["function setup(address,uint16,address,address)"] + let iface = new ethers.utils.Interface(ABI) + let encodedData = iface.encodeFunctionData("setup", [ + coreRelayerImplementationAddress, + chain.chainId, + wormholeAddress, + relayProviderProxyAddress, + ]) + + const contract = await factory.deploy(coreRelayerSetupAddress, encodedData) + return await contract.deployed().then((result) => { + console.log("Successfully deployed contract at " + result.address) + return { address: result.address, chainId: chain.chainId } + }) +} + +run().then(() => console.log("Done! " + processName)) diff --git a/ethereum/ts-scripts/coreRelayer/registerChainsCoreRelayer.ts b/ethereum/ts-scripts/coreRelayer/registerChainsCoreRelayer.ts new file mode 100644 index 0000000..0a295a9 --- /dev/null +++ b/ethereum/ts-scripts/coreRelayer/registerChainsCoreRelayer.ts @@ -0,0 +1,41 @@ +import { tryNativeToHexString } from "@certusone/wormhole-sdk" +import { + init, + loadChains, + ChainInfo, + getCoreRelayer, + getRelayProviderAddress, + getCoreRelayerAddress, +} from "../helpers/env" + +const processName = "registerChainsCoreRelayer" +init() +const chains = loadChains() + +async function run() { + console.log("Start! " + processName) + + for (let i = 0; i < chains.length; i++) { + await registerChainsCoreRelayer(chains[i]) + } +} + +async function registerChainsCoreRelayer(chain: ChainInfo) { + console.log("registerChainsCoreRelayer " + chain.chainId) + + const coreRelayer = getCoreRelayer(chain) + const relayProviderAddress = getRelayProviderAddress(chain) + + await coreRelayer.setDefaultRelayProvider(relayProviderAddress) + + for (let i = 0; i < chains.length; i++) { + await coreRelayer.registerCoreRelayerContract( + chains[i].chainId, + "0x" + tryNativeToHexString(getCoreRelayerAddress(chains[i]), "ethereum") + ) + } + + console.log("Did all contract registrations for the core relayer on " + chain.chainId) +} + +run().then(() => console.log("Done! " + processName)) diff --git a/ethereum/ts-scripts/deployAndConfigure.ts b/ethereum/ts-scripts/deployAndConfigure.ts deleted file mode 100644 index dedf432..0000000 --- a/ethereum/ts-scripts/deployAndConfigure.ts +++ /dev/null @@ -1,306 +0,0 @@ -import { ChainId, tryNativeToHexString } from "@certusone/wormhole-sdk" - -import { CoreRelayer__factory } from "../../sdk/src/ethers-contracts/factories/CoreRelayer__factory" -import { CoreRelayerProxy__factory } from "../../sdk/src/ethers-contracts/factories/CoreRelayerProxy__factory" -import { CoreRelayerSetup__factory } from "../../sdk/src/ethers-contracts/factories/CoreRelayerSetup__factory" -import { CoreRelayerImplementation__factory } from "../../sdk/src/ethers-contracts/factories/CoreRelayerImplementation__factory" -import { RelayProvider__factory } from "../../sdk/src/ethers-contracts/factories/RelayProvider__factory" -import { RelayProviderProxy__factory } from "../../sdk/src/ethers-contracts/factories/RelayProviderProxy__factory" -import { RelayProviderSetup__factory } from "../../sdk/src/ethers-contracts/factories/RelayProviderSetup__factory" -import { RelayProviderImplementation__factory } from "../../sdk/src/ethers-contracts/factories/RelayProviderImplementation__factory" -import { MockRelayerIntegration__factory } from "../../sdk/src/ethers-contracts/factories/MockRelayerIntegration__factory" - -import { ethers } from "ethers" -import fs from "fs" - -type Deployment = { chainId: ChainId; address: string } - -function get_env_var(env: string): string { - const v = process.env[env] - return v || "" -} - -const env = get_env_var("ENV") -if (!env) { - console.log("No environment was specified, using default environment files") -} - -import * as dotenv from "dotenv" -dotenv.config({ - path: `./ts-scripts/.env${env ? "." + env : ""}`, -}) - -const configFile = fs.readFileSync(`./ts-scripts/config/${env ? env : "config"}.json`) -const config = JSON.parse(configFile.toString()) -const guardianKey = get_env_var("GUARDIAN_KEY") -const privateKey = get_env_var("WALLET_KEY") - -if (!config) { - console.log("Failed to pull config file.") -} -if (!guardianKey) { - console.log("Failed to pull guardian key.") -} -if (!privateKey) { - console.log("Failed to pull wallet pk.") -} - -async function run() { - console.log("Start!") - const output: any = { - relayProviderImplementations: [], - relayProviderSetups: [], - relayProviderProxys: [], - coreRelayerImplementations: [], - coreRelayerSetups: [], - coreRelayerProxys: [], - mockRelayerIntegrations: [], - } - - for (let i = 0; i < config.chains.length; i++) { - const relayProviderImplementation = await deployRelayProviderImplementation( - config.chains[i] - ) - const relayProviderSetup = await deployRelayProviderSetup(config.chains[i]) - const relayProviderProxy = await deployRelayProviderProxy( - config.chains[i], - relayProviderSetup.address, - relayProviderImplementation.address - ) - const coreRelayerImplementation = await deployCoreRelayerImplementation( - config.chains[i] - ) - const coreRelayerSetup = await deployCoreRelayerSetup(config.chains[i]) - const coreRelayerProxy = await deployCoreRelayerProxy( - config.chains[i], - coreRelayerSetup.address, - coreRelayerImplementation.address, - config.chains[i].wormholeAddress, - relayProviderProxy.address - ) - const mockRelayerIntegration = await deployMockRelayerIntegration( - config.chains[i], - config.chains[i].wormholeAddress, - coreRelayerProxy.address - ) - - output.relayProviderImplementations.push(relayProviderImplementation) - output.relayProviderSetups.push(relayProviderSetup) - output.relayProviderProxys.push(relayProviderProxy) - output.coreRelayerImplementations.push(coreRelayerImplementation) - output.coreRelayerSetups.push(coreRelayerSetup) - output.coreRelayerProxys.push(coreRelayerProxy) - output.mockRelayerIntegrations.push(mockRelayerIntegration) - } - - for (let i = 0; i < config.chains.length; i++) { - await configureCoreRelayer(config.chains[i], output.coreRelayerProxys) - await configureRelayProvider( - output.relayProviderProxys.find( - (x: any) => x.chainId == config.chains[i].wormholeId - ), - config.chains - ) - } - - writeOutputFiles(output) -} - -async function deployRelayProviderImplementation(chain: any): Promise { - console.log("deployRelayProviderImplementation " + chain.wormholeId) - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - - const contractInterface = RelayProviderImplementation__factory.createInterface() - const bytecode = RelayProviderImplementation__factory.bytecode - //@ts-ignore - const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) - const contract = await factory.deploy() - return await contract.deployed().then((result) => { - console.log("Successfully deployed contract at " + result.address) - return { address: result.address, chainId: chain.wormholeId } - }) -} - -async function deployRelayProviderSetup(chain: any): Promise { - console.log("deployRelayProviderSetup " + chain.wormholeId) - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - const contractInterface = RelayProviderSetup__factory.createInterface() - const bytecode = RelayProviderSetup__factory.bytecode - //@ts-ignore - const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) - const contract = await factory.deploy() - return await contract.deployed().then((result) => { - console.log("Successfully deployed contract at " + result.address) - return { address: result.address, chainId: chain.wormholeId } - }) -} -async function deployRelayProviderProxy( - chain: any, - relayProviderSetupAddress: string, - relayProviderImplementationAddress: string -): Promise { - console.log("deployRelayProviderProxy " + chain.wormholeId) - - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - const contractInterface = RelayProviderProxy__factory.createInterface() - const bytecode = RelayProviderProxy__factory.bytecode - //@ts-ignore - const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) - - let ABI = ["function setup(address,uint16)"] - let iface = new ethers.utils.Interface(ABI) - let encodedData = iface.encodeFunctionData("setup", [ - relayProviderImplementationAddress, - chain.wormholeId, - ]) - - const contract = await factory.deploy(relayProviderSetupAddress, encodedData) - return await contract.deployed().then((result) => { - console.log("Successfully deployed contract at " + result.address) - return { address: result.address, chainId: chain.wormholeId } - }) -} -async function deployCoreRelayerImplementation(chain: any): Promise { - console.log("deployCoreRelayerImplementation " + chain.wormholeId) - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - const contractInterface = CoreRelayerImplementation__factory.createInterface() - const bytecode = CoreRelayerImplementation__factory.bytecode - //@ts-ignore - const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) - const contract = await factory.deploy() - return await contract.deployed().then((result) => { - console.log("Successfully deployed contract at " + result.address) - return { address: result.address, chainId: chain.wormholeId } - }) -} -async function deployCoreRelayerSetup(chain: any): Promise { - console.log("deployCoreRelayerSetup " + chain.wormholeId) - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - const contractInterface = CoreRelayerSetup__factory.createInterface() - const bytecode = CoreRelayerSetup__factory.bytecode - //@ts-ignore - const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) - const contract = await factory.deploy() - return await contract.deployed().then((result) => { - console.log("Successfully deployed contract at " + result.address) - return { address: result.address, chainId: chain.wormholeId } - }) -} -async function deployCoreRelayerProxy( - chain: any, - coreRelayerSetupAddress: string, - coreRelayerImplementationAddress: string, - wormholeAddress: string, - relayProviderProxyAddress: string -): Promise { - console.log("deployCoreRelayerProxy " + chain.wormholeId) - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - const contractInterface = CoreRelayerProxy__factory.createInterface() - const bytecode = CoreRelayerProxy__factory.bytecode - //@ts-ignore - const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) - - let ABI = ["function setup(address,uint16,address,address)"] - let iface = new ethers.utils.Interface(ABI) - let encodedData = iface.encodeFunctionData("setup", [ - coreRelayerImplementationAddress, - chain.wormholeId, - wormholeAddress, - relayProviderProxyAddress, - ]) - - const contract = await factory.deploy(coreRelayerSetupAddress, encodedData) - return await contract.deployed().then((result) => { - console.log("Successfully deployed contract at " + result.address) - return { address: result.address, chainId: chain.wormholeId } - }) -} -async function deployMockRelayerIntegration( - chain: any, - wormholeAddress: string, - coreRelayerProxy: string -): Promise { - console.log("deployMockRelayerIntegration " + chain.wormholeId) - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - const contractInterface = MockRelayerIntegration__factory.createInterface() - const bytecode = MockRelayerIntegration__factory.bytecode - //@ts-ignore - const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) - const contract = await factory.deploy(wormholeAddress, coreRelayerProxy) - return await contract.deployed().then((result) => { - console.log("Successfully deployed contract at " + result.address) - return { address: result.address, chainId: chain.wormholeId } - }) -} - -async function configureCoreRelayer(chain: any, contracts: Deployment[]) { - console.log("configureCoreRelayer " + chain.wormholeId) - let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) - let signer = new ethers.Wallet(privateKey, provider) - const contract = CoreRelayer__factory.connect( - contracts.find((x) => x.chainId == chain.wormholeId)?.address || "", - signer - ) - for (let i = 0; i < config.chains.length; i++) { - await contract.registerCoreRelayerContract( - contracts[i].chainId, - "0x" + tryNativeToHexString(contracts[i].address, "ethereum") - ) - } - console.log("registered all core relayers for " + chain.wormholeId) -} - -async function configureRelayProvider(deployment: Deployment, chains: any) { - console.log("configureCoreRelayer " + deployment.chainId) - let provider = new ethers.providers.StaticJsonRpcProvider( - chains.find((x: any) => x.wormholeId == deployment.chainId).rpc || "" - ) - let signer = new ethers.Wallet(privateKey, provider) - const contract = RelayProvider__factory.connect(deployment.address, signer) - const walletAddress = signer.address - const walletAddresswh = "0x" + tryNativeToHexString(walletAddress, "ethereum") - - await contract.updateRewardAddress(walletAddress) - - for (let i = 0; i < config.chains.length; i++) { - await contract.updateDeliverGasOverhead( - chains[i].wormholeId, - config.defaultRelayProviderConfig.deliverGasOverhead - ) - await contract.updateDeliveryAddress(chains[i].wormholeId, walletAddresswh) - await contract.updateMaximumBudget( - chains[i].wormholeId, - config.defaultRelayProviderConfig.maximumBudget - ) - await contract.updatePrice( - chains[i].wormholeId, - config.defaultRelayProviderConfig.updatePriceGas, - config.defaultRelayProviderConfig.updatePriceNative - ) - } - - console.log("configured relay provider for " + deployment.chainId) -} - -function writeOutputFiles(output: any) { - fs.mkdirSync("./ts-scripts/output/deployAndConfigure/", { recursive: true }) - fs.writeFileSync( - `./ts-scripts/output/deployAndConfigure/zlastrun-${env}.json`, - JSON.stringify(output), - { flag: "w" } - ) - fs.writeFileSync( - `./ts-scripts/output/deployAndConfigure/${Date.now()}-${env}.json`, - JSON.stringify(output), - { flag: "w" } - ) -} - -run().then(() => console.log("Done!")) diff --git a/ethereum/ts-scripts/helpers/env.ts b/ethereum/ts-scripts/helpers/env.ts new file mode 100644 index 0000000..2ed20fc --- /dev/null +++ b/ethereum/ts-scripts/helpers/env.ts @@ -0,0 +1,219 @@ +import { ChainId } from "@certusone/wormhole-sdk" +import { ethers, Signer } from "ethers" +import fs from "fs" +import { + CoreRelayer, + RelayProvider, + RelayProvider__factory, + CoreRelayer__factory, + MockRelayerIntegration, + MockRelayerIntegration__factory, +} from "../../../sdk/src" + +export type ChainInfo = { + evmNetworkId: number + chainId: ChainId + rpc: string + wormholeAddress: string +} + +export type Deployment = { + chainId: ChainId + address: string +} + +let env = "" + +export function init() { + env = get_env_var("ENV") + if (!env) { + console.log("No environment was specified, using default environment files") + env = "default" + } + + require("dotenv").config({ + path: `./ts-scripts/.env${env != "default" ? "." + env : ""}`, + }) +} + +function get_env_var(env: string): string { + const v = process.env[env] + return v || "" +} + +export function loadScriptConfig(processName: string): any { + const configFile = fs.readFileSync( + `./ts-scripts/config/${env}/scriptConfigs/${processName}.json` + ) + const config = JSON.parse(configFile.toString()) + if (!config) { + throw Error("Failed to pull config file!") + } + return config +} + +export function loadChains(): ChainInfo[] { + const chainFile = fs.readFileSync(`./ts-scripts/config/${env}/chains.json`) + const chains = JSON.parse(chainFile.toString()) + if (!chains.chains) { + throw Error("Failed to pull chain config file!") + } + return chains.chains +} + +export function loadPrivateKey(): string { + const privateKey = get_env_var("WALLET_KEY") + if (!privateKey) { + throw Error("Failed to find private key for this process!") + } + return privateKey +} + +export function loadRelayProviders(): Deployment[] { + const contractsFile = fs.readFileSync(`./ts-scripts/config/${env}/contracts.json`) + if (!contractsFile) { + throw Error("Failed to find contracts file for this process!") + } + const contracts = JSON.parse(contractsFile.toString()) + if (contracts.useLastRun) { + const lastRunFile = fs.readFileSync( + `./ts-scripts/output/${env}/deployRelayProvider/lastrun.json` + ) + if (!lastRunFile) { + throw Error("Failed to find last run file for the deployRelayProvider process!") + } + const lastRun = JSON.parse(lastRunFile.toString()) + return lastRun.relayProviderProxies + } else if (contracts.useLastRun == false) { + return contracts.relayProviders + } else { + throw Error("useLastRun was an invalid value from the contracts config") + } +} + +export function loadCoreRelayers(): Deployment[] { + const contractsFile = fs.readFileSync(`./ts-scripts/config/${env}/contracts.json`) + if (!contractsFile) { + throw Error("Failed to find contracts file for this process!") + } + const contracts = JSON.parse(contractsFile.toString()) + if (contracts.useLastRun) { + const lastRunFile = fs.readFileSync( + `./ts-scripts/output/${env}/deployCoreRelayer/lastrun.json` + ) + if (!lastRunFile) { + throw Error("Failed to find last run file for the Core Relayer process!") + } + const lastRun = JSON.parse(lastRunFile.toString()) + return lastRun.coreRelayerProxies + } else { + return contracts.coreRelayers + } +} + +export function loadMockIntegrations(): Deployment[] { + const contractsFile = fs.readFileSync(`./ts-scripts/config/${env}/contracts.json`) + if (!contractsFile) { + throw Error("Failed to find contracts file for this process!") + } + const contracts = JSON.parse(contractsFile.toString()) + if (contracts.useLastRun) { + const lastRunFile = fs.readFileSync( + `./ts-scripts/output/${env}/deployMockIntegration/lastrun.json` + ) + if (!lastRunFile) { + throw Error("Failed to find last run file for the deploy mock integration process!") + } + const lastRun = JSON.parse(lastRunFile.toString()) + return lastRun.mockIntegrations + } else { + return contracts.mockIntegrations + } +} + +export function loadGuardianKey(): string { + const guardianKey = get_env_var("GUARDIAN_KEY") + if (!guardianKey) { + throw Error("Failed to find guardian key for this process!") + } + return guardianKey +} + +export function writeOutputFiles(output: any, processName: string) { + fs.mkdirSync(`./ts-scripts/output/${env}/${processName}`, { recursive: true }) + fs.writeFileSync( + `./ts-scripts/output/${env}/${processName}/lastrun.json`, + JSON.stringify(output), + { flag: "w" } + ) + fs.writeFileSync( + `./ts-scripts/output/${env}/${processName}/${Date.now()}.json`, + JSON.stringify(output), + { flag: "w" } + ) +} + +export function getSigner(chain: ChainInfo): Signer { + let provider = new ethers.providers.StaticJsonRpcProvider( + loadChains().find((x: any) => x.chainId == chain.chainId)?.rpc || "" + ) + let signer = new ethers.Wallet(loadPrivateKey(), provider) + return signer +} + +export function getRelayProviderAddress(chain: ChainInfo): string { + const thisChainsProvider = loadRelayProviders().find( + (x: any) => x.chainId == chain.chainId + )?.address + if (!thisChainsProvider) { + throw new Error( + "Failed to find a RelayProvider contract address on chain " + chain.chainId + ) + } + return thisChainsProvider +} + +export function getRelayProvider(chain: ChainInfo): RelayProvider { + const thisChainsProvider = getRelayProviderAddress(chain) + const contract = RelayProvider__factory.connect(thisChainsProvider, getSigner(chain)) + return contract +} + +export function getCoreRelayerAddress(chain: ChainInfo): string { + const thisChainsRelayer = loadCoreRelayers().find( + (x: any) => x.chainId == chain.chainId + )?.address + if (!thisChainsRelayer) { + throw new Error( + "Failed to find a CoreRelayer contract address on chain " + chain.chainId + ) + } + return thisChainsRelayer +} + +export function getCoreRelayer(chain: ChainInfo): CoreRelayer { + const thisChainsRelayer = getCoreRelayerAddress(chain) + const contract = CoreRelayer__factory.connect(thisChainsRelayer, getSigner(chain)) + return contract +} + +export function getMockIntegrationAddress(chain: ChainInfo): string { + const thisMock = loadMockIntegrations().find( + (x: any) => x.chainId == chain.chainId + )?.address + if (!thisMock) { + throw new Error( + "Failed to find a mock integration contract address on chain " + chain.chainId + ) + } + return thisMock +} + +export function getMockIntegration(chain: ChainInfo): MockRelayerIntegration { + const thisIntegration = getMockIntegrationAddress(chain) + const contract = MockRelayerIntegration__factory.connect( + thisIntegration, + getSigner(chain) + ) + return contract +} diff --git a/ethereum/ts-scripts/messageTest.ts b/ethereum/ts-scripts/messageTest.ts deleted file mode 100644 index 4d1a23b..0000000 --- a/ethereum/ts-scripts/messageTest.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { ChainId, RefundEscrow, tryNativeToHexString } from "@certusone/wormhole-sdk" -import { CoreRelayer__factory, MockRelayerIntegration__factory } from "../../sdk/src" -import { CoreRelayerStructs } from "../../sdk/src/ethers-contracts/CoreRelayer" -import { ethers } from "ethers" -import fs from "fs" - -// tilt -// const CHAIN_INFOS = [ -// { -// id: 1337, -// wormholeId: 2, -// rpc: "http://localhost:8545", -// contractAddress: "foo", -// }, -// { -// id: 1397, -// wormholeId: 4, -// rpc: "http://localhost:8546", -// contractAddress: "foo", -// }, -// ] - -const CHAIN_INFOS = [ - { - id: 44787, - wormholeId: 14, - rpc: "https://alfajores-forno.celo-testnet.org", - mockIntegrationAddress: "celo", - relayerAddress: "", - }, - { - id: 43113, - wormholeId: 6, - rpc: "https://api.avax-test.network/ext/bc/C/rpc", - mockIntegrationAddress: "fuji", - relayerAddress: "", - }, -] - -async function run() { - if (!process.env["PRIVATE_KEY"]) { - console.log("Missing private key env var, falling back to tilt private key") - } - const pk = - process.env["PRIVATE_KEY"] || - "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d" - - //first collect all contract addresses - const promises = CHAIN_INFOS.map(async (info) => { - const file = await fs.readFileSync( - `./broadcast/deploy_contracts.sol/${info.id}/run-latest.json` - ) - const content = JSON.parse(file.toString()) - const createTransaction = content.transactions.find((x: any, index: any) => { - return x.contractName == "MockRelayerIntegration" - }) - const createTransaction2 = content.transactions.find((x: any, index: any) => { - return x.contractName == "RelayProviderProxy" && index > 4 - }) - info.mockIntegrationAddress = createTransaction.contractAddress - info.relayerAddress = createTransaction2.contractAddress - - console.log(`${info.wormholeId}: CoreRelayer: ${info.relayerAddress}`) - }) - - await Promise.all(promises) - const sourceChain = CHAIN_INFOS[1] - const targetChain = CHAIN_INFOS[0] - - const sourceProvider = new ethers.providers.StaticJsonRpcProvider(sourceChain.rpc) - const targetProvider = new ethers.providers.StaticJsonRpcProvider(targetChain.rpc) - - // signers - const sourceWallet = new ethers.Wallet(pk, sourceProvider) - const targetWallet = new ethers.Wallet(pk, targetProvider) - - const mockIntegration = MockRelayerIntegration__factory.connect( - sourceChain.mockIntegrationAddress, - sourceWallet - ) - - const coreRelayer = CoreRelayer__factory.connect( - sourceChain.relayerAddress, - sourceWallet - ) - - // todo: remove - const x = await CoreRelayer__factory.connect( - targetChain.relayerAddress, - targetWallet - ).registeredCoreRelayerContract(sourceChain.wormholeId) - console.log("should be fuji address", x) - - const defaultRelayerProvider = await coreRelayer.getDefaultRelayProvider() - console.log("Default relay provider: ", defaultRelayerProvider) - - const relayQuote = await ( - await coreRelayer.quoteGasDeliveryFee( - targetChain.wormholeId, - 2000000, - coreRelayer.getDefaultRelayProvider() - ) - ).add(10000000000) - - const tx = await mockIntegration.sendMessageWithForwardedResponse( - Buffer.from("Hello World 3"), - targetChain.wormholeId, - targetChain.mockIntegrationAddress, - { - gasLimit: 1000000, - value: relayQuote, - } - ) - const rx = await tx.wait() - console.log(rx, "da receipt") -} -// const tx = await mockIntegration.sendMessage( -// Buffer.from("Hello World 2"), -// targetChain.wormholeId, -// targetChain.mockIntegrationAddress, -// { -// gasLimit: 1000000, -// value: relayQuote, -// } -// ) -// const rx = await tx.wait() -// console.log(rx, "da receipt") -// } - -run().then(() => console.log("Done!")) - -console.log("Start!") diff --git a/ethereum/ts-scripts/mockIntegration/deployMockIntegration.ts b/ethereum/ts-scripts/mockIntegration/deployMockIntegration.ts new file mode 100644 index 0000000..1847357 --- /dev/null +++ b/ethereum/ts-scripts/mockIntegration/deployMockIntegration.ts @@ -0,0 +1,50 @@ +import { + init, + loadChains, + loadPrivateKey, + writeOutputFiles, + ChainInfo, + Deployment, +} from "../helpers/env" + +import { ethers } from "ethers" +import { getCoreRelayerAddress, getSigner } from "../helpers/env" +import { MockRelayerIntegration__factory } from "../../../sdk/src" + +const processName = "deployMockIntegration" +init() +const chains = loadChains() + +async function run() { + console.log("Start!") + const output: any = { + mockIntegrations: [], + } + + for (let i = 0; i < chains.length; i++) { + const mockIntegration = await deployMockIntegration(chains[i]) + + output.mockIntegrations.push(mockIntegration) + } + + writeOutputFiles(output, processName) +} + +async function deployMockIntegration(chain: ChainInfo): Promise { + console.log("deployMockIntegration " + chain.chainId) + + let signer = getSigner(chain) + const contractInterface = MockRelayerIntegration__factory.createInterface() + const bytecode = MockRelayerIntegration__factory.bytecode + const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) + const contract = await factory.deploy( + chain.wormholeAddress, + getCoreRelayerAddress(chain) + ) + return await contract.deployed().then((result) => { + console.log("Successfully deployed contract at " + result.address) + return { address: result.address, chainId: chain.chainId } + }) +} + +run().then(() => console.log("Done!")) diff --git a/ethereum/ts-scripts/mockIntegration/messageTest.ts b/ethereum/ts-scripts/mockIntegration/messageTest.ts new file mode 100644 index 0000000..f37b628 --- /dev/null +++ b/ethereum/ts-scripts/mockIntegration/messageTest.ts @@ -0,0 +1,63 @@ +import { + getCoreRelayer, + getCoreRelayerAddress, + getMockIntegration, + getMockIntegrationAddress, + getRelayProviderAddress, + init, + loadChains, +} from "../helpers/env" + +init() +const chains = loadChains() + +async function run() { + const sourceChain = chains[0] + const targetChain = chains[1] + + const sourceRelayer = getCoreRelayer(sourceChain) + + // todo: remove + const registeredChain = await sourceRelayer.registeredCoreRelayerContract( + sourceChain.chainId + ) + console.log("The source chain should be registered to itself") + console.log(registeredChain) + console.log(getCoreRelayerAddress(sourceChain)) + console.log("") + + const defaultRelayerProvider = await sourceRelayer.getDefaultRelayProvider() + console.log("Default relay provider should be this chains relayProvider ") + console.log(defaultRelayerProvider) + console.log(getRelayProviderAddress(sourceChain)) + console.log("") + + const relayQuote = await ( + await sourceRelayer.quoteGasDeliveryFee( + targetChain.chainId, + 2000000, + sourceRelayer.getDefaultRelayProvider() + ) + ).add(10000000000) + console.log("relay quote: " + relayQuote) + + const mockIntegration = getMockIntegration(sourceChain) + const targetAddress = getMockIntegrationAddress(targetChain) + + const tx = await mockIntegration.sendMessageWithForwardedResponse( + Buffer.from("Hello World 3"), + targetChain.chainId, + targetAddress, + targetAddress, + { + gasLimit: 1000000, + value: relayQuote, + } + ) + const rx = await tx.wait() + console.log(rx, "da receipt") +} + +run().then(() => console.log("Done!")) + +console.log("Start!") diff --git a/ethereum/ts-scripts/registerChains.ts b/ethereum/ts-scripts/registerChains.ts deleted file mode 100644 index 0e57017..0000000 --- a/ethereum/ts-scripts/registerChains.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { ChainId, RefundEscrow, tryNativeToHexString } from "@certusone/wormhole-sdk" -import { CoreRelayer__factory, MockRelayerIntegration__factory } from "../../sdk/src" -import { CoreRelayerStructs } from "../../sdk/src/ethers-contracts/CoreRelayer" -import { ethers } from "ethers" -import fs from "fs" - -// tilt -// const CHAIN_INFOS = [ -// { -// id: 1337, -// wormholeId: 2, -// rpc: "http://localhost:8545", -// contractAddress: "foo", -// }, -// { -// id: 1397, -// wormholeId: 4, -// rpc: "http://localhost:8546", -// contractAddress: "foo", -// }, -// ] - -const CHAIN_INFOS = [ - { - id: 44787, - wormholeId: 14, - rpc: "https://alfajores-forno.celo-testnet.org", - contractAddress: "celo", - }, - { - id: 43113, - wormholeId: 6, - rpc: "https://api.avax-test.network/ext/bc/C/rpc", - contractAddress: "fuji", - }, -] - -async function run() { - if (!process.env["PRIVATE_KEY"]) { - console.log("Missing private key env var, falling back to tilt private key") - } - const pk = - process.env["PRIVATE_KEY"] || - "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d" - - //first collect all contract addresses - await Promise.all( - CHAIN_INFOS.map(async (info) => { - const file = await fs.readFileSync( - `./broadcast/deploy_contracts.sol/${info.id}/run-latest.json` - ) - const content = JSON.parse(file.toString()) - const createTransaction = content.transactions.find((x: any, index: any) => { - return x.contractName == "RelayProviderProxy" && index > 4 - }) - info.contractAddress = createTransaction.contractAddress - }) - ) - - await Promise.all( - CHAIN_INFOS.map(async (info) => { - const provider = new ethers.providers.StaticJsonRpcProvider(info.rpc) - - // signers - const wallet = new ethers.Wallet(pk, provider) - - const coreRelayer = CoreRelayer__factory.connect(info.contractAddress, wallet) - - for (const info2 of CHAIN_INFOS) { - if (info.wormholeId != info2.wormholeId) { - await coreRelayer.registerCoreRelayerContract( - info2.wormholeId, - "0x" + tryNativeToHexString(info2.contractAddress, "ethereum") - ) - } - } - }) - ) -} - -run().then(() => console.log("Done!")) - -console.log("Start!") diff --git a/ethereum/ts-scripts/relayProvider/configureRelayProvider.ts b/ethereum/ts-scripts/relayProvider/configureRelayProvider.ts new file mode 100644 index 0000000..caa5cff --- /dev/null +++ b/ethereum/ts-scripts/relayProvider/configureRelayProvider.ts @@ -0,0 +1,76 @@ +import { + init, + loadChains, + ChainInfo, + loadScriptConfig, + getRelayProvider, +} from "../helpers/env" + +const processName = "configureRelayProvider" +init() +const chains = loadChains() +const config = loadScriptConfig(processName) + +async function run() { + console.log("Start! " + processName) + + for (let i = 0; i < chains.length; i++) { + await configureChainsRelayProvider(chains[i]) + } +} + +async function configureChainsRelayProvider(chain: ChainInfo) { + console.log("about to perform configurations for chain " + chain.chainId) + + const relayProvider = getRelayProvider(chain) + const thisChainsConfigInfo = config.addresses.find( + (x: any) => x.chainId == chain.chainId + ) + + if (!thisChainsConfigInfo) { + throw new Error("Failed to find address config info for chain " + chain.chainId) + } + if (!thisChainsConfigInfo.rewardAddress) { + throw new Error("Failed to find reward address info for chain " + chain.chainId) + } + if (!thisChainsConfigInfo.approvedSenders) { + throw new Error("Failed to find approvedSenders info for chain " + chain.chainId) + } + + //Set address info + await relayProvider.updateRewardAddress(thisChainsConfigInfo.rewardAddress) + for (let i = 0; i < thisChainsConfigInfo.approvedSenders.length; i++) { + await relayProvider.updateApprovedSender( + thisChainsConfigInfo.approvedSenders[i].address, + thisChainsConfigInfo.approvedSenders[i].approved + ) + } + + //TODO refactor to use the batch price update, probably + for (let i = 0; i < chains.length; i++) { + const targetChainPriceUpdate = config.pricingInfo.find( + (x: any) => x.chainId == chains[i].chainId + ) + if (!targetChainPriceUpdate) { + throw new Error("Failed to find pricingInfo for chain " + chains[i].chainId) + } + //delivery addresses are not done by this script, but rather the register chains script. + await relayProvider.updateDeliverGasOverhead( + chains[i].chainId, + targetChainPriceUpdate.deliverGasOverhead + ) + await relayProvider.updatePrice( + chains[i].chainId, + targetChainPriceUpdate.updatePriceGas, + targetChainPriceUpdate.updatePriceNative + ) + await relayProvider.updateMaximumBudget( + chains[i].chainId, + targetChainPriceUpdate.maximumBudget + ) + } + + console.log("done with registrations on " + chain.chainId) +} + +run().then(() => console.log("Done! " + processName)) diff --git a/ethereum/ts-scripts/relayProvider/deployRelayProvider.ts b/ethereum/ts-scripts/relayProvider/deployRelayProvider.ts new file mode 100644 index 0000000..62a7f49 --- /dev/null +++ b/ethereum/ts-scripts/relayProvider/deployRelayProvider.ts @@ -0,0 +1,103 @@ +import { RelayProviderProxy__factory } from "../../../sdk/src/ethers-contracts/factories/RelayProviderProxy__factory" +import { RelayProviderSetup__factory } from "../../../sdk/src/ethers-contracts/factories/RelayProviderSetup__factory" +import { RelayProviderImplementation__factory } from "../../../sdk/src/ethers-contracts/factories/RelayProviderImplementation__factory" +import { + init, + loadChains, + loadPrivateKey, + writeOutputFiles, + ChainInfo, + Deployment, +} from "../helpers/env" + +import { ethers } from "ethers" + +const processName = "deployRelayProvider" +init() +const chains = loadChains() +const privateKey = loadPrivateKey() + +async function run() { + console.log("Start!") + const output: any = { + relayProviderImplementations: [], + relayProviderSetups: [], + relayProviderProxies: [], + } + + for (let i = 0; i < chains.length; i++) { + const relayProviderImplementation = await deployRelayProviderImplementation(chains[i]) + const relayProviderSetup = await deployRelayProviderSetup(chains[i]) + const relayProviderProxy = await deployRelayProviderProxy( + chains[i], + relayProviderSetup.address, + relayProviderImplementation.address + ) + + output.relayProviderImplementations.push(relayProviderImplementation) + output.relayProviderSetups.push(relayProviderSetup) + output.relayProviderProxies.push(relayProviderProxy) + } + + writeOutputFiles(output, processName) +} + +async function deployRelayProviderImplementation(chain: ChainInfo): Promise { + console.log("deployRelayProviderImplementation " + chain.chainId) + let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) + let signer = new ethers.Wallet(privateKey, provider) + + const contractInterface = RelayProviderImplementation__factory.createInterface() + const bytecode = RelayProviderImplementation__factory.bytecode + //@ts-ignore + const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) + const contract = await factory.deploy() + return await contract.deployed().then((result) => { + console.log("Successfully deployed contract at " + result.address) + return { address: result.address, chainId: chain.chainId } + }) +} + +async function deployRelayProviderSetup(chain: ChainInfo): Promise { + console.log("deployRelayProviderSetup " + chain.chainId) + let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) + let signer = new ethers.Wallet(privateKey, provider) + const contractInterface = RelayProviderSetup__factory.createInterface() + const bytecode = RelayProviderSetup__factory.bytecode + //@ts-ignore + const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) + const contract = await factory.deploy() + return await contract.deployed().then((result) => { + console.log("Successfully deployed contract at " + result.address) + return { address: result.address, chainId: chain.chainId } + }) +} +async function deployRelayProviderProxy( + chain: ChainInfo, + relayProviderSetupAddress: string, + relayProviderImplementationAddress: string +): Promise { + console.log("deployRelayProviderProxy " + chain.chainId) + + let provider = new ethers.providers.StaticJsonRpcProvider(chain.rpc) + let signer = new ethers.Wallet(privateKey, provider) + const contractInterface = RelayProviderProxy__factory.createInterface() + const bytecode = RelayProviderProxy__factory.bytecode + //@ts-ignore + const factory = new ethers.ContractFactory(contractInterface, bytecode, signer) + + let ABI = ["function setup(address,uint16)"] + let iface = new ethers.utils.Interface(ABI) + let encodedData = iface.encodeFunctionData("setup", [ + relayProviderImplementationAddress, + chain.chainId, + ]) + + const contract = await factory.deploy(relayProviderSetupAddress, encodedData) + return await contract.deployed().then((result) => { + console.log("Successfully deployed contract at " + result.address) + return { address: result.address, chainId: chain.chainId } + }) +} + +run().then(() => console.log("Done!")) diff --git a/ethereum/ts-scripts/relayProvider/registerChainsRelayProvider.ts b/ethereum/ts-scripts/relayProvider/registerChainsRelayProvider.ts new file mode 100644 index 0000000..c05e4fb --- /dev/null +++ b/ethereum/ts-scripts/relayProvider/registerChainsRelayProvider.ts @@ -0,0 +1,41 @@ +import { tryNativeToHexString } from "@certusone/wormhole-sdk" + +import { + init, + loadChains, + ChainInfo, + getCoreRelayerAddress, + getRelayProvider, + getRelayProviderAddress, +} from "../helpers/env" + +const processName = "registerChainsRelayProvider" +init() +const chains = loadChains() + +async function run() { + console.log("Start! " + processName) + + for (let i = 0; i < chains.length; i++) { + await registerChainsRelayProvider(chains[i]) + } +} + +async function registerChainsRelayProvider(chain: ChainInfo) { + console.log("about to perform registrations for chain " + chain.chainId) + + const relayProvider = getRelayProvider(chain) + const coreRelayerAddress = getCoreRelayerAddress(chain) + + await relayProvider.updateCoreRelayer(coreRelayerAddress) + + for (let i = 0; i < chains.length; i++) { + const targetChainProviderAddress = getRelayProviderAddress(chains[i]) + const whAddress = "0x" + tryNativeToHexString(targetChainProviderAddress, "ethereum") + await relayProvider.updateDeliveryAddress(chains[i].chainId, whAddress) + } + + console.log("done with registrations on " + chain.chainId) +} + +run().then(() => console.log("Done! " + processName)) diff --git a/ethereum/ts-scripts/setDeliveryAddress.ts b/ethereum/ts-scripts/setDeliveryAddress.ts deleted file mode 100644 index 8534c3d..0000000 --- a/ethereum/ts-scripts/setDeliveryAddress.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { RelayProvider__factory } from "../../sdk/src" -import { ethers } from "ethers" -import fs from "fs" -import { tryNativeToHexString } from "@certusone/wormhole-sdk" - -const CHAIN_INFOS = [ - { - id: 44787, - wormholeId: 14, - rpc: "https://alfajores-forno.celo-testnet.org", - mockIntegrationAddress: "celo", - relayerAddress: "", - relayProvider: "", - }, - { - id: 43113, - wormholeId: 6, - rpc: "https://api.avax-test.network/ext/bc/C/rpc", - mockIntegrationAddress: "fuji", - relayerAddress: "", - relayProvider: "", - }, -] - -async function run() { - if (!process.env["PRIVATE_KEY"]) { - console.log("Missing private key env var, falling back to tilt private key") - } - const pk = - process.env["PRIVATE_KEY"] || - "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d" - - //first collect all contract addresses - await Promise.all( - CHAIN_INFOS.map(async (info) => { - const file = await fs.readFileSync( - `./broadcast/deploy_contracts.sol/${info.id}/run-latest.json` - ) - const content = JSON.parse(file.toString()) - const createTransaction = content.transactions.find((x: any, index: any) => { - return x.contractName == "MockRelayerIntegration" - }) - const relayProviderTx = content.transactions.find((x: any, index: any) => { - return x.contractName == "RelayProviderProxy" && index <= 4 - }) - const createTransaction2 = content.transactions.find((x: any, index: any) => { - return x.contractName == "RelayProviderProxy" && index > 4 - }) - info.mockIntegrationAddress = createTransaction.contractAddress - info.relayerAddress = createTransaction2.contractAddress - info.relayProvider = relayProviderTx.contractAddress - }) - ) - - for (const info of CHAIN_INFOS) { - const rpc = new ethers.providers.StaticJsonRpcProvider(info.rpc) - const wallet = new ethers.Wallet(pk, rpc) - const relayerProvider = RelayProvider__factory.connect(info.relayProvider, wallet) - - for (const { wormholeId } of CHAIN_INFOS) { - await relayerProvider - .updateDeliveryAddress( - wormholeId, - "0x" + tryNativeToHexString(wallet.address, "ethereum") - ) - .then((tx) => tx.wait()) - await relayerProvider - .updateRewardAddress(wallet.address) - .then((tx) => tx.wait()) - - console.log( - `Delivery address for chain ${wormholeId} on chain ${ - info.wormholeId - }: ${await relayerProvider.getDeliveryAddress(wormholeId)}` - ) - } - } -} - -run().then(() => console.log("Done!")) - -console.log("Start!") diff --git a/ethereum/ts-scripts/shell/deployConfigureTest.sh b/ethereum/ts-scripts/shell/deployConfigureTest.sh new file mode 100644 index 0000000..98ad836 --- /dev/null +++ b/ethereum/ts-scripts/shell/deployConfigureTest.sh @@ -0,0 +1 @@ +ts-node ./ts-scripts/relayProvider/deployRelayProvider.ts && ts-node ./ts-scripts/coreRelayer/deployCoreRelayer.ts && ts-node ./ts-scripts/relayProvider/registerChainsRelayProvider.ts && ts-node ./ts-scripts/coreRelayer/registerChainsCoreRelayer.ts && ts-node ./ts-scripts/relayProvider/configureRelayProvider.ts && ts-node ./ts-scripts/mockIntegration/deployMockIntegration.ts && ts-node ./ts-scripts/mockIntegration/messageTest.ts \ No newline at end of file