From e322270477c515c6f76af7cea7baaec629ee3823 Mon Sep 17 00:00:00 2001 From: J M Rossy Date: Wed, 22 Feb 2023 17:01:03 -0500 Subject: [PATCH] Update infra package for SDK 1.2.0 (#1836) - Update infra code to work with update SDK types - Include some minor cosmetic code improvements --- typescript/helloworld | 2 +- .../config/environments/mainnet2/agent.ts | 8 +- .../config/environments/mainnet2/chains.ts | 38 ++--- .../config/environments/mainnet2/core.ts | 4 +- .../environments/mainnet2/helloworld.ts | 10 +- .../config/environments/mainnet2/index.ts | 10 +- .../environments/mainnet2/token-bridge.ts | 9 +- .../environments/mainnet2/validators.ts | 12 +- .../infra/config/environments/test/agent.ts | 4 +- .../infra/config/environments/test/chains.ts | 10 +- .../infra/config/environments/test/core.ts | 4 +- .../infra/config/environments/test/index.ts | 14 +- .../environments/test/liquidityLayer.ts | 22 +-- .../config/environments/test/validators.ts | 4 +- .../config/environments/testnet3/agent.ts | 8 +- .../config/environments/testnet3/chains.ts | 22 +-- .../config/environments/testnet3/core.ts | 4 +- .../environments/testnet3/helloworld.ts | 10 +- .../config/environments/testnet3/index.ts | 10 +- .../environments/testnet3/token-bridge.ts | 22 +-- .../environments/testnet3/validators.ts | 28 ++-- typescript/infra/config/utils.ts | 16 +-- typescript/infra/hardhat.config.ts | 21 +-- typescript/infra/package.json | 9 +- .../infra/scripts/announce-validators.ts | 19 +-- typescript/infra/scripts/check-deploy.ts | 4 +- typescript/infra/scripts/core.ts | 2 +- typescript/infra/scripts/debug-message.ts | 20 +-- typescript/infra/scripts/deploy-agents.ts | 2 +- .../fund-deterministic-key-from-deployer.ts | 16 ++- .../funding/fund-keys-from-deployer.ts | 131 +++++++++--------- .../infra/scripts/funding/reclaim-from-igp.ts | 11 +- typescript/infra/scripts/govern.ts | 5 +- typescript/infra/scripts/helloworld/deploy.ts | 10 +- typescript/infra/scripts/helloworld/kathy.ts | 12 +- typescript/infra/scripts/helloworld/utils.ts | 49 +++---- .../list-validator-checkpoint-indices.ts | 4 +- .../scripts/middleware/circle-relayer.ts | 6 +- .../scripts/middleware/deploy-accounts.ts | 2 +- .../middleware/deploy-liquidity-layer.ts | 2 +- .../scripts/middleware/deploy-queries.ts | 2 +- .../scripts/middleware/portal-relayer.ts | 6 +- .../infra/scripts/output-agent-env-vars.ts | 7 +- .../infra/scripts/remove-agent-deploys.ts | 2 +- typescript/infra/scripts/safe-delegate.ts | 3 +- .../infra/scripts/update-agents-diff.ts | 2 +- typescript/infra/scripts/utils.ts | 28 ++-- typescript/infra/scripts/verify-validators.ts | 4 +- typescript/infra/scripts/verify.ts | 4 +- typescript/infra/src/agents/aws/key.ts | 2 +- typescript/infra/src/agents/aws/user.ts | 8 +- .../infra/src/agents/aws/validator-user.ts | 8 +- typescript/infra/src/agents/index.ts | 41 +++--- typescript/infra/src/agents/key-utils.ts | 30 ++-- typescript/infra/src/config/agent.ts | 50 +++---- typescript/infra/src/config/chain.ts | 19 +-- typescript/infra/src/config/environment.ts | 14 +- typescript/infra/src/config/helloworld.ts | 10 +- typescript/infra/src/core/deploy.ts | 30 ++-- typescript/infra/src/core/govern.ts | 55 ++++---- typescript/infra/src/core/multisend.ts | 40 +++--- typescript/infra/src/create2/index.ts | 26 ++-- typescript/infra/src/deploy.ts | 4 +- .../infra/src/funding/deploy-key-funder.ts | 12 +- typescript/infra/src/helloworld/kathy.ts | 16 +-- .../src/middleware/liquidity-layer-relayer.ts | 14 +- typescript/infra/src/scraper/deploy.ts | 10 +- .../src/testcontracts/testquerysender.ts | 13 +- .../infra/src/testcontracts/testrecipient.ts | 14 +- typescript/infra/src/utils/safe.ts | 19 ++- typescript/infra/src/utils/utils.ts | 4 +- typescript/infra/test/core.test.ts | 20 +-- yarn.lock | 45 +++--- 73 files changed, 529 insertions(+), 629 deletions(-) diff --git a/typescript/helloworld b/typescript/helloworld index b5087155c..75d40a83f 160000 --- a/typescript/helloworld +++ b/typescript/helloworld @@ -1 +1 @@ -Subproject commit b5087155c1ee3a6c5f9033150668e02481de7383 +Subproject commit 75d40a83fda061c37704e7de8bcc3cdbca498b55 diff --git a/typescript/infra/config/environments/mainnet2/agent.ts b/typescript/infra/config/environments/mainnet2/agent.ts index f22b91cbf..262d7df26 100644 --- a/typescript/infra/config/environments/mainnet2/agent.ts +++ b/typescript/infra/config/environments/mainnet2/agent.ts @@ -9,7 +9,7 @@ import { import { Contexts } from '../../contexts'; import { helloworldMatchingList, routerMatchingList } from '../../utils'; -import { MainnetChains, chainNames, environment } from './chains'; +import { chainNames, environment } from './chains'; import { helloWorld } from './helloworld'; import interchainQueryRouters from './middleware/queries/addresses.json'; import { validators } from './validators'; @@ -23,7 +23,7 @@ const interchainQueriesMatchingList = routerMatchingList( interchainQueryRouters, ); -export const hyperlane: AgentConfig = { +export const hyperlane: AgentConfig = { environment, namespace: environment, runEnv: environment, @@ -67,7 +67,7 @@ export const hyperlane: AgentConfig = { rolesWithKeys: ALL_KEY_ROLES, }; -export const releaseCandidate: AgentConfig = { +export const releaseCandidate: AgentConfig = { environment, namespace: environment, runEnv: environment, @@ -98,7 +98,7 @@ export const releaseCandidate: AgentConfig = { transactionGasLimit: BigInt(750000), // Skipping arbitrum because the gas price estimates are inclusive of L1 // fees which leads to wildly off predictions. - skipTransactionGasLimitFor: [chainMetadata.arbitrum.id], + skipTransactionGasLimitFor: [chainMetadata.arbitrum.chainId], }, }, rolesWithKeys: [KEY_ROLE_ENUM.Relayer, KEY_ROLE_ENUM.Kathy], diff --git a/typescript/infra/config/environments/mainnet2/chains.ts b/typescript/infra/config/environments/mainnet2/chains.ts index de6028905..fa4164466 100644 --- a/typescript/infra/config/environments/mainnet2/chains.ts +++ b/typescript/infra/config/environments/mainnet2/chains.ts @@ -1,35 +1,41 @@ -import { chainConnectionConfigs } from '@hyperlane-xyz/sdk'; +import { ChainMap, ChainMetadata, chainMetadata } from '@hyperlane-xyz/sdk'; -export const mainnetConfigs = { +export const mainnetConfigs: ChainMap = { bsc: { - ...chainConnectionConfigs.bsc, - overrides: { + ...chainMetadata.bsc, + transactionOverrides: { gasPrice: 7 * 10 ** 9, // 7 gwei }, }, - avalanche: chainConnectionConfigs.avalanche, + avalanche: chainMetadata.avalanche, polygon: { - ...chainConnectionConfigs.polygon, - confirmations: 3, - overrides: { + ...chainMetadata.polygon, + blocks: { + ...chainMetadata.polygon.blocks, + confirmations: 3, + }, + transactionOverrides: { maxFeePerGas: 500 * 10 ** 9, // 500 gwei maxPriorityFeePerGas: 100 * 10 ** 9, // 100 gwei // gasPrice: 50 * 10 ** 9, // 50 gwei }, }, - celo: chainConnectionConfigs.celo, - arbitrum: chainConnectionConfigs.arbitrum, - optimism: chainConnectionConfigs.optimism, + celo: chainMetadata.celo, + arbitrum: chainMetadata.arbitrum, + optimism: chainMetadata.optimism, ethereum: { - ...chainConnectionConfigs.ethereum, - confirmations: 3, - overrides: { + ...chainMetadata.ethereum, + blocks: { + ...chainMetadata.ethereum.blocks, + confirmations: 3, + }, + transactionOverrides: { maxFeePerGas: 150 * 10 ** 9, // gwei maxPriorityFeePerGas: 5 * 10 ** 9, // gwei }, }, - moonbeam: chainConnectionConfigs.moonbeam, - gnosis: chainConnectionConfigs.gnosis, + moonbeam: chainMetadata.moonbeam, + gnosis: chainMetadata.gnosis, }; export type MainnetChains = keyof typeof mainnetConfigs; diff --git a/typescript/infra/config/environments/mainnet2/core.ts b/typescript/infra/config/environments/mainnet2/core.ts index 17e3733ea..57b40f375 100644 --- a/typescript/infra/config/environments/mainnet2/core.ts +++ b/typescript/infra/config/environments/mainnet2/core.ts @@ -1,8 +1,6 @@ import { ChainMap, CoreConfig } from '@hyperlane-xyz/sdk'; -import { MainnetChains } from './chains'; - -export const core: ChainMap = { +export const core: ChainMap = { celo: { owner: '0x1DE69322B55AC7E0999F8e7738a1428C8b130E4d', multisigIsm: { diff --git a/typescript/infra/config/environments/mainnet2/helloworld.ts b/typescript/infra/config/environments/mainnet2/helloworld.ts index ed67a3ef2..e49ca7227 100644 --- a/typescript/infra/config/environments/mainnet2/helloworld.ts +++ b/typescript/infra/config/environments/mainnet2/helloworld.ts @@ -3,11 +3,11 @@ import { ConnectionType } from '../../../src/config/agent'; import { HelloWorldKathyRunMode } from '../../../src/config/helloworld'; import { Contexts } from '../../contexts'; -import { MainnetChains, environment } from './chains'; +import { environment } from './chains'; import hyperlaneAddresses from './helloworld/hyperlane/addresses.json'; import rcAddresses from './helloworld/rc/addresses.json'; -export const hyperlane: HelloWorldConfig = { +export const hyperlane: HelloWorldConfig = { addresses: hyperlaneAddresses, kathy: { docker: { @@ -28,7 +28,7 @@ export const hyperlane: HelloWorldConfig = { }, }; -export const releaseCandidate: HelloWorldConfig = { +export const releaseCandidate: HelloWorldConfig = { addresses: rcAddresses, kathy: { docker: { @@ -47,9 +47,7 @@ export const releaseCandidate: HelloWorldConfig = { }, }; -export const helloWorld: Partial< - Record> -> = { +export const helloWorld: Partial> = { [Contexts.Hyperlane]: hyperlane, [Contexts.ReleaseCandidate]: releaseCandidate, }; diff --git a/typescript/infra/config/environments/mainnet2/index.ts b/typescript/infra/config/environments/mainnet2/index.ts index d0601c809..7903a217c 100644 --- a/typescript/infra/config/environments/mainnet2/index.ts +++ b/typescript/infra/config/environments/mainnet2/index.ts @@ -5,19 +5,15 @@ import { ConnectionType } from '../../../src/config/agent'; import { Contexts } from '../../contexts'; import { agents } from './agent'; -import { - MainnetChains, - environment as environmentName, - mainnetConfigs, -} from './chains'; +import { environment as environmentName, mainnetConfigs } from './chains'; import { core } from './core'; import { keyFunderConfig } from './funding'; import { helloWorld } from './helloworld'; import { infrastructure } from './infrastructure'; -export const environment: CoreEnvironmentConfig = { +export const environment: CoreEnvironmentConfig = { environment: environmentName, - transactionConfigs: mainnetConfigs, + chainMetadataConfigs: mainnetConfigs, getMultiProvider: ( context: Contexts = Contexts.Hyperlane, role: KEY_ROLE_ENUM = KEY_ROLE_ENUM.Deployer, diff --git a/typescript/infra/config/environments/mainnet2/token-bridge.ts b/typescript/infra/config/environments/mainnet2/token-bridge.ts index 83ab5daf3..66838a802 100644 --- a/typescript/infra/config/environments/mainnet2/token-bridge.ts +++ b/typescript/infra/config/environments/mainnet2/token-bridge.ts @@ -7,15 +7,12 @@ import { } from '@hyperlane-xyz/sdk'; const circleDomainMapping = [ - { hyperlaneDomain: chainMetadata[Chains.goerli].id, circleDomain: 0 }, - { hyperlaneDomain: chainMetadata[Chains.fuji].id, circleDomain: 1 }, + { hyperlaneDomain: chainMetadata[Chains.goerli].chainId, circleDomain: 0 }, + { hyperlaneDomain: chainMetadata[Chains.fuji].chainId, circleDomain: 1 }, ]; // Circle deployed contracts -export const circleBridgeAdapterConfig: ChainMap< - any, - CircleBridgeAdapterConfig -> = { +export const circleBridgeAdapterConfig: ChainMap = { [Chains.goerli]: { type: BridgeAdapterType.Circle, tokenMessengerAddress: '0xdabec94b97f7b5fca28f050cc8eeac2dc9920476', diff --git a/typescript/infra/config/environments/mainnet2/validators.ts b/typescript/infra/config/environments/mainnet2/validators.ts index d676e47db..88324c84e 100644 --- a/typescript/infra/config/environments/mainnet2/validators.ts +++ b/typescript/infra/config/environments/mainnet2/validators.ts @@ -1,20 +1,18 @@ -import { ChainName } from '@hyperlane-xyz/sdk'; +import { CoreChainName } from '@hyperlane-xyz/sdk'; import { ChainValidatorConfigs, CheckpointSyncerType, } from '../../../src/config/agent'; -import { MainnetChains, environment } from './chains'; +import { environment } from './chains'; const s3BucketRegion = 'us-east-1'; -const s3BucketName = ( - chainName: Chain, - index: number, -) => `hyperlane-${environment}-${chainName}-validator-${index}`; +const s3BucketName = (chainName: CoreChainName, index: number) => + `hyperlane-${environment}-${chainName}-validator-${index}`; -export const validators: ChainValidatorConfigs = { +export const validators: ChainValidatorConfigs = { celo: { interval: 5, reorgPeriod: 0, diff --git a/typescript/infra/config/environments/test/agent.ts b/typescript/infra/config/environments/test/agent.ts index 809e9ea74..57ece10e6 100644 --- a/typescript/infra/config/environments/test/agent.ts +++ b/typescript/infra/config/environments/test/agent.ts @@ -6,10 +6,10 @@ import { } from '../../../src/config/agent'; import { Contexts } from '../../contexts'; -import { TestChains, chainNames } from './chains'; +import { chainNames } from './chains'; import { validators } from './validators'; -export const hyperlane: AgentConfig = { +export const hyperlane: AgentConfig = { environment: 'test', namespace: 'test', runEnv: 'test', diff --git a/typescript/infra/config/environments/test/chains.ts b/typescript/infra/config/environments/test/chains.ts index ca235955e..b6d0a3b24 100644 --- a/typescript/infra/config/environments/test/chains.ts +++ b/typescript/infra/config/environments/test/chains.ts @@ -1,9 +1,9 @@ -import { chainConnectionConfigs } from '@hyperlane-xyz/sdk'; +import { ChainMap, ChainMetadata, chainMetadata } from '@hyperlane-xyz/sdk'; -export const testConfigs = { - test1: chainConnectionConfigs.test1, - test2: chainConnectionConfigs.test2, - test3: chainConnectionConfigs.test3, +export const testConfigs: ChainMap = { + test1: chainMetadata.test1, + test2: chainMetadata.test2, + test3: chainMetadata.test3, }; export type TestChains = keyof typeof testConfigs; diff --git a/typescript/infra/config/environments/test/core.ts b/typescript/infra/config/environments/test/core.ts index 2ee9926f5..0587a2da2 100644 --- a/typescript/infra/config/environments/test/core.ts +++ b/typescript/infra/config/environments/test/core.ts @@ -1,8 +1,6 @@ import { ChainMap, CoreConfig } from '@hyperlane-xyz/sdk'; -import { TestChains } from './chains'; - -export const core: ChainMap = { +export const core: ChainMap = { // Owner is hardhat account 0 // Validators are hardhat accounts 1-3 test1: { diff --git a/typescript/infra/config/environments/test/index.ts b/typescript/infra/config/environments/test/index.ts index e8e1d747a..a64620ad3 100644 --- a/typescript/infra/config/environments/test/index.ts +++ b/typescript/infra/config/environments/test/index.ts @@ -1,24 +1,26 @@ import { JsonRpcProvider } from '@ethersproject/providers'; -import { getTestMultiProvider } from '@hyperlane-xyz/sdk'; +import { MultiProvider } from '@hyperlane-xyz/sdk'; import { CoreEnvironmentConfig } from '../../../src/config'; import { agents } from './agent'; -import { TestChains, testConfigs } from './chains'; +import { testConfigs } from './chains'; import { core } from './core'; import { infra } from './infra'; -export const environment: CoreEnvironmentConfig = { +export const environment: CoreEnvironmentConfig = { environment: 'test', - transactionConfigs: testConfigs, + chainMetadataConfigs: testConfigs, agents, core, infra, // NOTE: Does not work from hardhat.config.ts getMultiProvider: async () => { - const provider = testConfigs.test1.provider! as JsonRpcProvider; + const mp = MultiProvider.createTestMultiProvider(); + const provider = mp.getProvider('test1') as JsonRpcProvider; const signer = provider.getSigner(0); - return getTestMultiProvider(signer, testConfigs); + mp.setSharedSigner(signer); + return mp; }, }; diff --git a/typescript/infra/config/environments/test/liquidityLayer.ts b/typescript/infra/config/environments/test/liquidityLayer.ts index 5e0ec10aa..bba05105d 100644 --- a/typescript/infra/config/environments/test/liquidityLayer.ts +++ b/typescript/infra/config/environments/test/liquidityLayer.ts @@ -7,19 +7,25 @@ import { } from '@hyperlane-xyz/sdk'; const circleDomainMapping = [ - { hyperlaneDomain: chainMetadata[Chains.goerli].id, circleDomain: 0 }, - { hyperlaneDomain: chainMetadata[Chains.fuji].id, circleDomain: 1 }, + { hyperlaneDomain: chainMetadata[Chains.goerli].chainId, circleDomain: 0 }, + { hyperlaneDomain: chainMetadata[Chains.fuji].chainId, circleDomain: 1 }, ]; const wormholeDomainMapping = [ - { hyperlaneDomain: chainMetadata[Chains.goerli].id, wormholeDomain: 2 }, - { hyperlaneDomain: chainMetadata[Chains.fuji].id, wormholeDomain: 6 }, - { hyperlaneDomain: chainMetadata[Chains.mumbai].id, wormholeDomain: 5 }, - { hyperlaneDomain: chainMetadata[Chains.bsctestnet].id, wormholeDomain: 4 }, - { hyperlaneDomain: chainMetadata[Chains.alfajores].id, wormholeDomain: 14 }, + { hyperlaneDomain: chainMetadata[Chains.goerli].chainId, wormholeDomain: 2 }, + { hyperlaneDomain: chainMetadata[Chains.fuji].chainId, wormholeDomain: 6 }, + { hyperlaneDomain: chainMetadata[Chains.mumbai].chainId, wormholeDomain: 5 }, + { + hyperlaneDomain: chainMetadata[Chains.bsctestnet].chainId, + wormholeDomain: 4, + }, + { + hyperlaneDomain: chainMetadata[Chains.alfajores].chainId, + wormholeDomain: 14, + }, ]; -export const bridgeAdapterConfigs: ChainMap = { +export const bridgeAdapterConfigs: ChainMap = { [Chains.goerli]: { portal: { type: BridgeAdapterType.Portal, diff --git a/typescript/infra/config/environments/test/validators.ts b/typescript/infra/config/environments/test/validators.ts index a913e44b0..74a7b40e1 100644 --- a/typescript/infra/config/environments/test/validators.ts +++ b/typescript/infra/config/environments/test/validators.ts @@ -5,12 +5,10 @@ import { CheckpointSyncerType, } from '../../../src/config/agent'; -import { TestChains } from './chains'; - const localStoragePath = (chainName: ChainName) => `/tmp/hyperlane-test-${chainName}-validator`; -export const validators: ChainValidatorConfigs = { +export const validators: ChainValidatorConfigs = { test1: { interval: 5, reorgPeriod: 0, diff --git a/typescript/infra/config/environments/testnet3/agent.ts b/typescript/infra/config/environments/testnet3/agent.ts index f5f57e1ee..1364ca8a1 100644 --- a/typescript/infra/config/environments/testnet3/agent.ts +++ b/typescript/infra/config/environments/testnet3/agent.ts @@ -9,7 +9,7 @@ import { import { Contexts } from '../../contexts'; import { helloworldMatchingList, routerMatchingList } from '../../utils'; -import { TestnetChains, chainNames, environment } from './chains'; +import { chainNames, environment } from './chains'; import { helloWorld } from './helloworld'; import interchainQueryRouters from './middleware/queries/addresses.json'; import { validators } from './validators'; @@ -23,7 +23,7 @@ const interchainQueriesMatchingList = routerMatchingList( interchainQueryRouters, ); -export const hyperlane: AgentConfig = { +export const hyperlane: AgentConfig = { environment, namespace: environment, runEnv: environment, @@ -64,7 +64,7 @@ export const hyperlane: AgentConfig = { rolesWithKeys: ALL_KEY_ROLES, }; -export const releaseCandidate: AgentConfig = { +export const releaseCandidate: AgentConfig = { environment, namespace: environment, runEnv: environment, @@ -95,7 +95,7 @@ export const releaseCandidate: AgentConfig = { transactionGasLimit: BigInt(750000), // Skipping arbitrum because the gas price estimates are inclusive of L1 // fees which leads to wildly off predictions. - skipTransactionGasLimitFor: [chainMetadata.arbitrumgoerli.id], + skipTransactionGasLimitFor: [chainMetadata.arbitrumgoerli.chainId], }, }, rolesWithKeys: [KEY_ROLE_ENUM.Relayer, KEY_ROLE_ENUM.Kathy], diff --git a/typescript/infra/config/environments/testnet3/chains.ts b/typescript/infra/config/environments/testnet3/chains.ts index 59cafa8ce..ef542bf8e 100644 --- a/typescript/infra/config/environments/testnet3/chains.ts +++ b/typescript/infra/config/environments/testnet3/chains.ts @@ -1,20 +1,20 @@ -import { chainConnectionConfigs } from '@hyperlane-xyz/sdk'; +import { ChainMap, ChainMetadata, chainMetadata } from '@hyperlane-xyz/sdk'; -export const testnetConfigs = { - alfajores: chainConnectionConfigs.alfajores, - fuji: chainConnectionConfigs.fuji, +export const testnetConfigs: ChainMap = { + alfajores: chainMetadata.alfajores, + fuji: chainMetadata.fuji, mumbai: { - ...chainConnectionConfigs.mumbai, - overrides: { + ...chainMetadata.mumbai, + transactionOverrides: { maxFeePerGas: 70 * 10 ** 9, // 70 gwei maxPriorityFeePerGas: 40 * 10 ** 9, // 40 gwei }, }, - bsctestnet: chainConnectionConfigs.bsctestnet, - goerli: chainConnectionConfigs.goerli, - moonbasealpha: chainConnectionConfigs.moonbasealpha, - optimismgoerli: chainConnectionConfigs.optimismgoerli, - arbitrumgoerli: chainConnectionConfigs.arbitrumgoerli, + bsctestnet: chainMetadata.bsctestnet, + goerli: chainMetadata.goerli, + moonbasealpha: chainMetadata.moonbasealpha, + optimismgoerli: chainMetadata.optimismgoerli, + arbitrumgoerli: chainMetadata.arbitrumgoerli, }; export type TestnetChains = keyof typeof testnetConfigs; diff --git a/typescript/infra/config/environments/testnet3/core.ts b/typescript/infra/config/environments/testnet3/core.ts index 2e7e07547..c16d8dcbf 100644 --- a/typescript/infra/config/environments/testnet3/core.ts +++ b/typescript/infra/config/environments/testnet3/core.ts @@ -1,8 +1,6 @@ import { ChainMap, CoreConfig } from '@hyperlane-xyz/sdk'; -import { TestnetChains } from './chains'; - -export const core: ChainMap = { +export const core: ChainMap = { alfajores: { owner: '0xfaD1C94469700833717Fa8a3017278BC1cA8031C', multisigIsm: { diff --git a/typescript/infra/config/environments/testnet3/helloworld.ts b/typescript/infra/config/environments/testnet3/helloworld.ts index 426a5f88a..236013ea1 100644 --- a/typescript/infra/config/environments/testnet3/helloworld.ts +++ b/typescript/infra/config/environments/testnet3/helloworld.ts @@ -3,11 +3,11 @@ import { ConnectionType } from '../../../src/config/agent'; import { HelloWorldKathyRunMode } from '../../../src/config/helloworld'; import { Contexts } from '../../contexts'; -import { TestnetChains, environment } from './chains'; +import { environment } from './chains'; import hyperlaneAddresses from './helloworld/hyperlane/addresses.json'; import rcAddresses from './helloworld/rc/addresses.json'; -export const hyperlane: HelloWorldConfig = { +export const hyperlane: HelloWorldConfig = { addresses: hyperlaneAddresses, kathy: { docker: { @@ -27,7 +27,7 @@ export const hyperlane: HelloWorldConfig = { }, }; -export const releaseCandidate: HelloWorldConfig = { +export const releaseCandidate: HelloWorldConfig = { addresses: rcAddresses, kathy: { docker: { @@ -46,9 +46,7 @@ export const releaseCandidate: HelloWorldConfig = { }, }; -export const helloWorld: Partial< - Record> -> = { +export const helloWorld: Partial> = { [Contexts.Hyperlane]: hyperlane, [Contexts.ReleaseCandidate]: releaseCandidate, }; diff --git a/typescript/infra/config/environments/testnet3/index.ts b/typescript/infra/config/environments/testnet3/index.ts index 8e432b992..ad598be53 100644 --- a/typescript/infra/config/environments/testnet3/index.ts +++ b/typescript/infra/config/environments/testnet3/index.ts @@ -5,20 +5,16 @@ import { ConnectionType } from '../../../src/config/agent'; import { Contexts } from '../../contexts'; import { agents } from './agent'; -import { - TestnetChains, - environment as environmentName, - testnetConfigs, -} from './chains'; +import { environment as environmentName, testnetConfigs } from './chains'; import { core } from './core'; import { keyFunderConfig } from './funding'; import { helloWorld } from './helloworld'; import { infrastructure } from './infrastructure'; import { liquidityLayerRelayerConfig } from './middleware'; -export const environment: CoreEnvironmentConfig = { +export const environment: CoreEnvironmentConfig = { environment: environmentName, - transactionConfigs: testnetConfigs, + chainMetadataConfigs: testnetConfigs, getMultiProvider: ( context: Contexts = Contexts.Hyperlane, role: KEY_ROLE_ENUM = KEY_ROLE_ENUM.Deployer, diff --git a/typescript/infra/config/environments/testnet3/token-bridge.ts b/typescript/infra/config/environments/testnet3/token-bridge.ts index 5e0ec10aa..bba05105d 100644 --- a/typescript/infra/config/environments/testnet3/token-bridge.ts +++ b/typescript/infra/config/environments/testnet3/token-bridge.ts @@ -7,19 +7,25 @@ import { } from '@hyperlane-xyz/sdk'; const circleDomainMapping = [ - { hyperlaneDomain: chainMetadata[Chains.goerli].id, circleDomain: 0 }, - { hyperlaneDomain: chainMetadata[Chains.fuji].id, circleDomain: 1 }, + { hyperlaneDomain: chainMetadata[Chains.goerli].chainId, circleDomain: 0 }, + { hyperlaneDomain: chainMetadata[Chains.fuji].chainId, circleDomain: 1 }, ]; const wormholeDomainMapping = [ - { hyperlaneDomain: chainMetadata[Chains.goerli].id, wormholeDomain: 2 }, - { hyperlaneDomain: chainMetadata[Chains.fuji].id, wormholeDomain: 6 }, - { hyperlaneDomain: chainMetadata[Chains.mumbai].id, wormholeDomain: 5 }, - { hyperlaneDomain: chainMetadata[Chains.bsctestnet].id, wormholeDomain: 4 }, - { hyperlaneDomain: chainMetadata[Chains.alfajores].id, wormholeDomain: 14 }, + { hyperlaneDomain: chainMetadata[Chains.goerli].chainId, wormholeDomain: 2 }, + { hyperlaneDomain: chainMetadata[Chains.fuji].chainId, wormholeDomain: 6 }, + { hyperlaneDomain: chainMetadata[Chains.mumbai].chainId, wormholeDomain: 5 }, + { + hyperlaneDomain: chainMetadata[Chains.bsctestnet].chainId, + wormholeDomain: 4, + }, + { + hyperlaneDomain: chainMetadata[Chains.alfajores].chainId, + wormholeDomain: 14, + }, ]; -export const bridgeAdapterConfigs: ChainMap = { +export const bridgeAdapterConfigs: ChainMap = { [Chains.goerli]: { portal: { type: BridgeAdapterType.Portal, diff --git a/typescript/infra/config/environments/testnet3/validators.ts b/typescript/infra/config/environments/testnet3/validators.ts index ddbd25c8d..dec6b1d94 100644 --- a/typescript/infra/config/environments/testnet3/validators.ts +++ b/typescript/infra/config/environments/testnet3/validators.ts @@ -1,23 +1,21 @@ -import { ChainName, chainMetadata } from '@hyperlane-xyz/sdk'; +import { CoreChainName, chainMetadata } from '@hyperlane-xyz/sdk'; import { ChainValidatorConfigs, CheckpointSyncerType, } from '../../../src/config/agent'; -import { TestnetChains, environment } from './chains'; +import { environment } from './chains'; const s3BucketRegion = 'us-east-1'; -const s3BucketName = ( - chainName: Chain, - index: number, -) => `hyperlane-${environment}-${chainName}-validator-${index}`; +const s3BucketName = (chainName: CoreChainName, index: number) => + `hyperlane-${environment}-${chainName}-validator-${index}`; -export const validators: ChainValidatorConfigs = { +export const validators: ChainValidatorConfigs = { alfajores: { interval: 5, - reorgPeriod: chainMetadata.alfajores.blocks.reorgPeriod, + reorgPeriod: chainMetadata.alfajores.blocks!.reorgPeriod!, validators: [ { address: '0xe6072396568e73ce6803b12b7e04164e839f1e54', @@ -50,7 +48,7 @@ export const validators: ChainValidatorConfigs = { }, fuji: { interval: 5, - reorgPeriod: chainMetadata.fuji.blocks.reorgPeriod, + reorgPeriod: chainMetadata.fuji.blocks!.reorgPeriod!, validators: [ { address: '0x9fa19ead5ec76e437948b35e227511b106293c40', @@ -83,7 +81,7 @@ export const validators: ChainValidatorConfigs = { }, mumbai: { interval: 5, - reorgPeriod: chainMetadata.mumbai.blocks.reorgPeriod, + reorgPeriod: chainMetadata.mumbai.blocks!.reorgPeriod!, validators: [ { address: '0x0a664ea799447da6b15645cf8b9e82072a68343f', @@ -116,7 +114,7 @@ export const validators: ChainValidatorConfigs = { }, bsctestnet: { interval: 5, - reorgPeriod: chainMetadata.bsctestnet.blocks.reorgPeriod, + reorgPeriod: chainMetadata.bsctestnet.blocks!.reorgPeriod!, validators: [ { address: '0x23338c8714976dd4a57eaeff17cbd26d7e275c08', @@ -149,7 +147,7 @@ export const validators: ChainValidatorConfigs = { }, goerli: { interval: 5, - reorgPeriod: chainMetadata.goerli.blocks.reorgPeriod, + reorgPeriod: chainMetadata.goerli.blocks!.reorgPeriod!, validators: [ { address: '0xf43fbd072fd38e1121d4b3b0b8a35116bbb01ea9', @@ -182,7 +180,7 @@ export const validators: ChainValidatorConfigs = { }, moonbasealpha: { interval: 5, - reorgPeriod: chainMetadata.moonbasealpha.blocks.reorgPeriod, + reorgPeriod: chainMetadata.moonbasealpha.blocks!.reorgPeriod!, validators: [ { address: '0x890c2aeac157c3f067f3e42b8afc797939c59a32', @@ -215,7 +213,7 @@ export const validators: ChainValidatorConfigs = { }, optimismgoerli: { interval: 5, - reorgPeriod: chainMetadata.optimismgoerli.blocks.reorgPeriod, + reorgPeriod: chainMetadata.optimismgoerli.blocks!.reorgPeriod!, validators: [ { address: '0xbb8d77eefbecc55db6e5a19b0fc3dc290776f189', @@ -248,7 +246,7 @@ export const validators: ChainValidatorConfigs = { }, arbitrumgoerli: { interval: 5, - reorgPeriod: chainMetadata.arbitrumgoerli.blocks.reorgPeriod, + reorgPeriod: chainMetadata.arbitrumgoerli.blocks!.reorgPeriod!, validators: [ { address: '0xce798fa21e323f6b24d9838a10ffecdefdfc4f30', diff --git a/typescript/infra/config/utils.ts b/typescript/infra/config/utils.ts index 92c313a36..6dff934bd 100644 --- a/typescript/infra/config/utils.ts +++ b/typescript/infra/config/utils.ts @@ -1,4 +1,4 @@ -import { ChainMap, ChainName, chainMetadata } from '@hyperlane-xyz/sdk'; +import { ChainMap, chainMetadata } from '@hyperlane-xyz/sdk'; import { HelloWorldConfig } from '../src/config'; import { MatchingList } from '../src/config/agent'; @@ -14,8 +14,8 @@ export const MATCHING_LIST_ALL_WILDCARDS = [ }, ]; -export function helloworldMatchingList( - helloWorldConfigs: Partial>>, +export function helloworldMatchingList( + helloWorldConfigs: Partial>, context: Contexts, ) { const helloWorldConfig = helloWorldConfigs[context]; @@ -25,10 +25,8 @@ export function helloworldMatchingList( return routerMatchingList(helloWorldConfig.addresses); } -export function routerMatchingList( - routers: ChainMap, -) { - const chains = Object.keys(routers) as Chain[]; +export function routerMatchingList(routers: ChainMap<{ router: string }>) { + const chains = Object.keys(routers); const matchingList: MatchingList = []; @@ -39,9 +37,9 @@ export function routerMatchingList( } matchingList.push({ - originDomain: chainMetadata[source].id, + originDomain: chainMetadata[source].chainId, senderAddress: routers[source].router, - destinationDomain: chainMetadata[destination].id, + destinationDomain: chainMetadata[destination].chainId, recipientAddress: routers[destination].router, }); } diff --git a/typescript/infra/hardhat.config.ts b/typescript/infra/hardhat.config.ts index cc2a5ab3a..b18721c9c 100644 --- a/typescript/infra/hardhat.config.ts +++ b/typescript/infra/hardhat.config.ts @@ -4,20 +4,11 @@ import { task } from 'hardhat/config'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; import { TestSendReceiver__factory } from '@hyperlane-xyz/core'; -import { - ChainName, - ChainNameToDomainId, - HyperlaneCore, - getTestMultiProvider, -} from '@hyperlane-xyz/sdk'; +import { ChainName, HyperlaneCore, MultiProvider } from '@hyperlane-xyz/sdk'; -import { getCoreEnvironmentConfig } from './scripts/utils'; import { sleep } from './src/utils/utils'; -const chainSummary = async ( - core: HyperlaneCore, - chain: Chain, -) => { +const chainSummary = async (core: HyperlaneCore, chain: ChainName) => { const coreContracts = core.getContracts(chain); const mailbox = coreContracts.mailbox.contract; const dispatched = await mailbox.count(); @@ -50,12 +41,8 @@ task('kathy', 'Dispatches random hyperlane messages') const timeout = Number.parseInt(taskArgs.timeout); const environment = 'test'; const interchainGasPayment = hre.ethers.utils.parseUnits('100', 'gwei'); - const config = getCoreEnvironmentConfig(environment); const [signer] = await hre.ethers.getSigners(); - const multiProvider = getTestMultiProvider( - signer, - config.transactionConfigs, - ); + const multiProvider = MultiProvider.createTestMultiProvider({ signer }); const core = HyperlaneCore.fromEnvironment(environment, multiProvider); const randomElement = (list: T[]) => @@ -72,7 +59,7 @@ task('kathy', 'Dispatches random hyperlane messages') while (run_forever || rounds-- > 0) { const local = core.chains()[0]; const remote: ChainName = randomElement(core.remoteChains(local)); - const remoteId = ChainNameToDomainId[remote]; + const remoteId = multiProvider.getDomainId(remote); const coreContracts = core.getContracts(local); const mailbox = coreContracts.mailbox.contract; const paymaster = coreContracts.interchainGasPaymaster; diff --git a/typescript/infra/package.json b/typescript/infra/package.json index 2b1770008..4ad1ed52f 100644 --- a/typescript/infra/package.json +++ b/typescript/infra/package.json @@ -1,7 +1,7 @@ { "name": "@hyperlane-xyz/infra", "description": "Infrastructure utilities for the Hyperlane Network", - "version": "1.1.4", + "version": "1.2.0", "dependencies": { "@arbitrum/sdk": "^3.0.0", "@aws-sdk/client-iam": "^3.74.0", @@ -14,10 +14,9 @@ "@gnosis.pm/safe-core-sdk": "^2.3.2", "@gnosis.pm/safe-ethers-lib": "^1.4.0", "@gnosis.pm/safe-service-client": "^1.2.0", - "@hyperlane-xyz/celo-ethers-provider": "^0.1.1", - "@hyperlane-xyz/helloworld": "1.1.4", - "@hyperlane-xyz/sdk": "1.1.4", - "@hyperlane-xyz/utils": "1.1.4", + "@hyperlane-xyz/helloworld": "1.2.0", + "@hyperlane-xyz/sdk": "1.2.0", + "@hyperlane-xyz/utils": "1.2.0", "@nomiclabs/hardhat-etherscan": "^3.0.3", "@safe-global/safe-core-sdk": "3.2.0", "@safe-global/safe-ethers-lib": "^1.7.0", diff --git a/typescript/infra/scripts/announce-validators.ts b/typescript/infra/scripts/announce-validators.ts index 7bc9cc132..f6814dd85 100644 --- a/typescript/infra/scripts/announce-validators.ts +++ b/typescript/infra/scripts/announce-validators.ts @@ -4,11 +4,7 @@ import { readFileSync } from 'fs'; import * as path from 'path'; import yargs from 'yargs'; -import { - AllChains, - ChainNameToDomainId, - HyperlaneCore, -} from '@hyperlane-xyz/sdk'; +import { AllChains, ChainName, HyperlaneCore } from '@hyperlane-xyz/sdk'; import { S3Validator } from '../src/agents/aws/validator'; import { CheckpointSyncerType } from '../src/config/agent'; @@ -54,13 +50,13 @@ async function main() { // environments union doesn't work well with typescript const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); const announcements = []; - const chains = []; + const chains: ChainName[] = []; if (location) { - chains.push(chain); + chains.push(chain!); if (location.startsWith('s3://')) { const validator = await S3Validator.fromStorageLocation(location); announcements.push(await validator.getAnnouncement()); @@ -89,9 +85,8 @@ async function main() { validatorBaseConfig.checkpointSyncer.type == CheckpointSyncerType.S3 ) { - // @ts-ignore const contracts = core.getContracts(chain); - const localDomain = ChainNameToDomainId[chain]; + const localDomain = multiProvider.getDomainId(chain); const validator = new S3Validator( validatorBaseConfig.address, localDomain, @@ -111,7 +106,6 @@ async function main() { for (let i = 0; i < announcements.length; i++) { const announcement = announcements[i]; const chain = chains[i]; - // @ts-ignore why? const contracts = core.getContracts(chain); const validatorAnnounce = contracts.validatorAnnounce; const address = announcement.value.validator; @@ -123,12 +117,11 @@ async function main() { if (!announced) { const signature = ethers.utils.joinSignature(announcement.signature); console.log(`Announcing ${address} checkpoints at ${location}`); - const chainConnection = multiProvider.tryGetChainConnection(chain); await validatorAnnounce.announce( address, location, signature, - chainConnection?.overrides, + multiProvider.getTransactionOverrides(chain), ); } else { console.log(`Already announced ${address} checkpoints at ${location}`); diff --git a/typescript/infra/scripts/check-deploy.ts b/typescript/infra/scripts/check-deploy.ts index 44138ebc0..e6191e0fa 100644 --- a/typescript/infra/scripts/check-deploy.ts +++ b/typescript/infra/scripts/check-deploy.ts @@ -12,9 +12,9 @@ async function check() { // environments union doesn't work well with typescript const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); - const coreChecker = new HyperlaneCoreChecker( + const coreChecker = new HyperlaneCoreChecker( multiProvider, core, config.core, diff --git a/typescript/infra/scripts/core.ts b/typescript/infra/scripts/core.ts index b6f73a9fd..e1098f430 100644 --- a/typescript/infra/scripts/core.ts +++ b/typescript/infra/scripts/core.ts @@ -18,7 +18,7 @@ import { async function main() { const environment = await getEnvironment(); - const config = getCoreEnvironmentConfig(environment) as any; + const config = getCoreEnvironmentConfig(environment); const multiProvider = await config.getMultiProvider(); const deployer = new HyperlaneCoreInfraDeployer( multiProvider, diff --git a/typescript/infra/scripts/debug-message.ts b/typescript/infra/scripts/debug-message.ts index ad39c7cd6..eb2699a87 100644 --- a/typescript/infra/scripts/debug-message.ts +++ b/typescript/infra/scripts/debug-message.ts @@ -2,10 +2,8 @@ import { IMessageRecipient__factory } from '@hyperlane-xyz/helloworld/dist/src/t import { ChainName, DispatchedMessage, - DomainIdToChainName, HyperlaneCore, MultiProvider, - chainConnectionConfigs, } from '@hyperlane-xyz/sdk'; import { utils } from '@hyperlane-xyz/utils'; @@ -41,14 +39,14 @@ async function main() { // Intentionally use public RPC providers to avoid requiring access to our GCP secrets // to run this script - const multiProvider = new MultiProvider(chainConnectionConfigs); + const multiProvider = new MultiProvider(); const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], multiProvider, ); - const originProvider = multiProvider.getChainProvider(argv.originChain); + const originProvider = multiProvider.getProvider(argv.originChain); const dispatchReceipt = await originProvider.getTransactionReceipt( argv.txHash, ); @@ -66,8 +64,8 @@ async function main() { } async function checkMessage( - core: HyperlaneCore, - multiProvider: MultiProvider, + core: HyperlaneCore, + multiProvider: MultiProvider, message: DispatchedMessage, ) { const messageId = utils.messageId(message.message); @@ -75,7 +73,9 @@ async function checkMessage( console.log(`Raw bytes: ${message.message}`); console.log('Parsed message:', message.parsed); - const destinationChain = DomainIdToChainName[message.parsed.destination]; + const destinationChain = multiProvider.getChainName( + message.parsed.destination, + ); if (destinationChain === undefined) { console.error( @@ -120,7 +120,7 @@ async function checkMessage( return; } - const destinationProvider = multiProvider.getChainProvider(destinationChain); + const destinationProvider = multiProvider.getProvider(destinationChain); const recipient = IMessageRecipient__factory.connect( recipientAddress, destinationProvider, @@ -159,11 +159,11 @@ async function checkMessage( } async function isContract( - multiProvider: MultiProvider, + multiProvider: MultiProvider, chain: ChainName, address: string, ) { - const provider = multiProvider.getChainProvider(chain); + const provider = multiProvider.getProvider(chain); const code = await provider.getCode(address); // "Empty" code return code !== '0x'; diff --git a/typescript/infra/scripts/deploy-agents.ts b/typescript/infra/scripts/deploy-agents.ts index ab703d996..6e7d3cbe9 100644 --- a/typescript/infra/scripts/deploy-agents.ts +++ b/typescript/infra/scripts/deploy-agents.ts @@ -24,7 +24,7 @@ async function deploy() { // While this function still has these side effects, the workaround is to just // run the create-keys script first. await Promise.all( - agentConfig.contextChainNames.map((name: any) => + agentConfig.contextChainNames.map((name: string) => runAgentHelmCommand(HelmCommand.InstallOrUpgrade, agentConfig, name), ), ); diff --git a/typescript/infra/scripts/funding/fund-deterministic-key-from-deployer.ts b/typescript/infra/scripts/funding/fund-deterministic-key-from-deployer.ts index 5fe1662d5..49641be8d 100644 --- a/typescript/infra/scripts/funding/fund-deterministic-key-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-deterministic-key-from-deployer.ts @@ -1,7 +1,7 @@ import { BigNumber } from 'ethers'; import { format } from 'util'; -import { objMap, promiseObjAll } from '@hyperlane-xyz/sdk'; +import { promiseObjAll } from '@hyperlane-xyz/sdk'; import { error } from '@hyperlane-xyz/utils'; import { Contexts } from '../../config/contexts'; @@ -59,16 +59,18 @@ async function main() { ).address; await promiseObjAll( - objMap(multiProvider.chainMap, async (chain, dc) => { + multiProvider.mapKnownChains(async (chain) => { if (argv.chainsToSkip?.includes(chain)) { return; } // fund signer on each network with gas * gasPrice - const actual = await dc.provider.getBalance(address); + const provider = multiProvider.getProvider(chain); + const overrides = multiProvider.getTransactionOverrides(chain); + const actual = await provider.getBalance(address); const gasPrice = BigNumber.from( - await (dc.overrides.gasPrice || - dc.overrides.maxFeePerGas || - dc.provider.getGasPrice()), + await (overrides.gasPrice || + overrides.maxFeePerGas || + provider.getGasPrice()), ); const desired = gasPrice.mul(argv.gasAmount!); const value = desired.sub(actual); @@ -76,7 +78,7 @@ async function main() { console.log( `Funding ${address} on chain '${chain}' with ${value} native tokens`, ); - await dc.sendTransaction({ + await multiProvider.sendTransaction(chain, { to: address, value, }); diff --git a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts index a79f5661d..bcc538673 100644 --- a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts @@ -5,11 +5,9 @@ import { format } from 'util'; import { AllChains, - ChainConnection, ChainName, - ChainNameToDomainId, Chains, - CompleteChainMap, + CoreChainName, MultiProvider, } from '@hyperlane-xyz/sdk'; import { ChainMap } from '@hyperlane-xyz/sdk/dist/types'; @@ -51,7 +49,7 @@ const L2Chains: ChainName[] = [ Chains.arbitrumgoerli, ]; -const L2ToL1: ChainMap = { +const L2ToL1: ChainMap = { optimismgoerli: 'goerli', arbitrumgoerli: 'goerli', optimism: 'ethereum', @@ -94,7 +92,7 @@ const MIN_DELTA_DENOMINATOR = ethers.BigNumber.from(10); const RC_FUNDING_DISCOUNT_NUMERATOR = ethers.BigNumber.from(2); const RC_FUNDING_DISCOUNT_DENOMINATOR = ethers.BigNumber.from(10); -const desiredBalancePerChain: CompleteChainMap = { +const desiredBalancePerChain: ChainMap = { celo: '0.3', alfajores: '1', avalanche: '0.3', @@ -211,7 +209,7 @@ class ContextFunder { public readonly chains: ChainName[]; constructor( - public readonly multiProvider: MultiProvider, + public readonly multiProvider: MultiProvider, public readonly keys: BaseCloudAgentKey[], public readonly context: Contexts, public readonly rolesToFund: KEY_ROLE_ENUM[], @@ -224,7 +222,7 @@ class ContextFunder { } static fromSerializedAddressFile( - multiProvider: MultiProvider, + multiProvider: MultiProvider, path: string, contextsAndRolesToFund: ContextAndRolesMap, ) { @@ -240,7 +238,7 @@ class ContextFunder { // references newer chains. return ( parsed.chainName === undefined || - AllChains.includes(parsed.chainName as ChainName) + AllChains.includes(parsed.chainName as CoreChainName) ); }) .map((idAndAddress: any) => @@ -281,7 +279,7 @@ class ContextFunder { // which require credentials to fetch. If you want to avoid requiring credentials, use // fromSerializedAddressFile instead. static async fromContext( - multiProvider: MultiProvider, + multiProvider: MultiProvider, context: Contexts, rolesToFund: KEY_ROLE_ENUM[], ) { @@ -322,7 +320,7 @@ class ContextFunder { const entries = AllChains.map((c) => { return [c, []]; }); - const chainKeys: CompleteChainMap = + const chainKeys: ChainMap = Object.fromEntries(entries); for (const role of this.rolesToFund) { const keys = this.getKeysWithRole(role); @@ -348,8 +346,8 @@ class ContextFunder { key: BaseCloudAgentKey, chain: ChainName, ): Promise { - const chainConnection = this.multiProvider.tryGetChainConnection(chain); - if (!chainConnection) { + const provider = this.multiProvider.tryGetProvider(chain); + if (!provider) { error('Cannot get chain connection', { chain, }); @@ -361,24 +359,27 @@ class ContextFunder { let failureOccurred = false; try { - await this.fundKeyIfRequired(chainConnection, chain, key, desiredBalance); + await this.fundKeyIfRequired(chain, key, desiredBalance); } catch (err) { error('Error funding key', { - key: await getKeyInfo(key, chain, chainConnection), + key: await getKeyInfo( + key, + chain, + this.multiProvider.getProvider(chain), + ), context: this.context, error: err, }); failureOccurred = true; } - await this.updateWalletBalanceGauge(chainConnection, chain); + await this.updateWalletBalanceGauge(chain); return failureOccurred; } private async bridgeIfL2(chain: ChainName) { if (L2Chains.includes(chain)) { - const chainConnection = this.multiProvider.tryGetChainConnection(chain)!; - const funderAddress = await chainConnection.getAddress()!; + const funderAddress = await this.multiProvider.getSignerAddress(chain)!; const desiredBalanceEther = ethers.utils.parseUnits( desiredBalancePerChain[chain], 'ether', @@ -387,7 +388,7 @@ class ContextFunder { // By bridging the funder with 10x the desired balance we save // on L1 gas. const bridgeAmount = await this.getFundingAmount( - chainConnection, + chain, funderAddress, desiredBalanceEther.mul(10), ); @@ -398,11 +399,13 @@ class ContextFunder { } private async getFundingAmount( - chainConnection: ChainConnection, + chain: ChainName, address: string, desiredBalance: BigNumber, ): Promise { - const currentBalance = await chainConnection.provider.getBalance(address); + const currentBalance = await this.multiProvider + .getProvider(chain) + .getBalance(address); const delta = desiredBalance.sub(currentBalance); const minDelta = desiredBalance .mul(MIN_DELTA_NUMERATOR) @@ -413,7 +416,6 @@ class ContextFunder { // Tops up the key's balance to the desired balance if the current balance // is lower than the desired balance by the min delta private async fundKeyIfRequired( - chainConnection: ChainConnection, chain: ChainName, key: BaseCloudAgentKey, desiredBalance: string, @@ -430,12 +432,16 @@ class ContextFunder { : desiredBalanceEther; const fundingAmount = await this.getFundingAmount( - chainConnection, + chain, key.address, adjustedDesiredBalance, ); - const keyInfo = await getKeyInfo(key, chain, chainConnection); - const funderAddress = await chainConnection.getAddress()!; + const keyInfo = await getKeyInfo( + key, + chain, + this.multiProvider.getProvider(chain), + ); + const funderAddress = await this.multiProvider.getSignerAddress(chain); if (fundingAmount.eq(0)) { log('Skipping funding for key', { @@ -452,28 +458,28 @@ class ContextFunder { funder: { address: funderAddress, balance: ethers.utils.formatEther( - await chainConnection.signer!.getBalance(), + await this.multiProvider.getSigner(chain).getBalance(), ), }, context: this.context, }); } - const tx = await chainConnection.signer!.sendTransaction({ + const tx = await this.multiProvider.sendTransaction(chain, { to: key.address, value: fundingAmount, - ...chainConnection.overrides, }); log('Sent transaction', { key: keyInfo, - txUrl: chainConnection.getTxUrl(tx), + txUrl: this.multiProvider.getExplorerTxUrl(chain, { + hash: tx.transactionHash, + }), context: this.context, chain, }); - const receipt = await tx.wait(chainConnection.confirmations); log('Got transaction receipt', { key: keyInfo, - receipt, + tx, context: this.context, chain, }); @@ -481,20 +487,18 @@ class ContextFunder { private async bridgeToL2(l2Chain: L2Chain, to: string, amount: BigNumber) { const l1Chain = L2ToL1[l2Chain]; - const l1ChainConnection = await this.multiProvider.tryGetChainConnection( - l1Chain, - )!; - const l2ChainConnection = await this.multiProvider.tryGetChainConnection( - l2Chain, - )!; log('Bridging ETH to L2', { amount: ethers.utils.formatEther(amount), l1Funder: await getAddressInfo( - await l1ChainConnection.getAddress()!, + await this.multiProvider.getSignerAddress(l1Chain), l1Chain, - l1ChainConnection, + this.multiProvider.getProvider(l1Chain), + ), + l2Funder: await getAddressInfo( + to, + l2Chain, + this.multiProvider.getProvider(l2Chain), ), - l2Funder: await getAddressInfo(to, l2Chain, l2ChainConnection), }); let tx; if (l2Chain.includes('optimism')) { @@ -504,9 +508,7 @@ class ContextFunder { } else { throw new Error(`${l2Chain} is not an L2`); } - await this.multiProvider - .tryGetChainConnection(L2ToL1[l2Chain])! - .handleTx(tx); + await this.multiProvider.handleTx(l1Chain, tx); } private async bridgeToOptimism( @@ -515,40 +517,33 @@ class ContextFunder { to: string, ) { const l1Chain = L2ToL1[l2Chain]; - const l1ChainConnection = - this.multiProvider.tryGetChainConnection(l1Chain)!; - const l2ChainConnection = - this.multiProvider.tryGetChainConnection(l2Chain)!; const crossChainMessenger = new CrossChainMessenger({ - l1ChainId: ChainNameToDomainId[l1Chain], - l2ChainId: ChainNameToDomainId[l2Chain], - l1SignerOrProvider: l1ChainConnection.signer!, - l2SignerOrProvider: l2ChainConnection.provider, + l1ChainId: this.multiProvider.getDomainId(l1Chain), + l2ChainId: this.multiProvider.getDomainId(l2Chain), + l1SignerOrProvider: this.multiProvider.getSignerOrProvider(l1Chain), + l2SignerOrProvider: this.multiProvider.getSignerOrProvider(l2Chain), }); return crossChainMessenger.depositETH(amount, { recipient: to, - overrides: l1ChainConnection.overrides, + overrides: this.multiProvider.getTransactionOverrides(l1Chain), }); } private async bridgeToArbitrum(l2Chain: L2Chain, amount: BigNumber) { const l1Chain = L2ToL1[l2Chain]; - const l1ChainConnection = - this.multiProvider.tryGetChainConnection(l1Chain)!; - const l2Network = await getL2Network(ChainNameToDomainId[l2Chain]); + const l2Network = await getL2Network( + this.multiProvider.getDomainId(l2Chain), + ); const ethBridger = new EthBridger(l2Network); return ethBridger.deposit({ amount, - l1Signer: l1ChainConnection.signer!, - overrides: l1ChainConnection.overrides, + l1Signer: this.multiProvider.getSigner(l1Chain), + overrides: this.multiProvider.getTransactionOverrides(l1Chain), }); } - private async updateWalletBalanceGauge( - chainConnection: ChainConnection, - chain: ChainName, - ) { - const funderAddress = await chainConnection.getAddress(); + private async updateWalletBalanceGauge(chain: ChainName) { + const funderAddress = await this.multiProvider.getSignerAddress(chain); walletBalanceGauge .labels({ chain, @@ -560,7 +555,9 @@ class ContextFunder { }) .set( parseFloat( - ethers.utils.formatEther(await chainConnection.signer!.getBalance()), + ethers.utils.formatEther( + await this.multiProvider.getSigner(chain).getBalance(), + ), ), ); } @@ -573,13 +570,11 @@ class ContextFunder { async function getAddressInfo( address: string, chain: ChainName, - chainConnection: ChainConnection, + provider: ethers.providers.Provider, ) { return { chain, - balance: ethers.utils.formatEther( - await chainConnection.provider.getBalance(address), - ), + balance: ethers.utils.formatEther(await provider.getBalance(address)), address, }; } @@ -587,10 +582,10 @@ async function getAddressInfo( async function getKeyInfo( key: BaseCloudAgentKey, chain: ChainName, - chainConnection: ChainConnection, + provider: ethers.providers.Provider, ) { return { - ...(await getAddressInfo(key.address, chain, chainConnection)), + ...(await getAddressInfo(key.address, chain, provider)), context: key.context, originChain: key.chainName, role: key.role, diff --git a/typescript/infra/scripts/funding/reclaim-from-igp.ts b/typescript/infra/scripts/funding/reclaim-from-igp.ts index 414a8b8da..36b90568c 100644 --- a/typescript/infra/scripts/funding/reclaim-from-igp.ts +++ b/typescript/infra/scripts/funding/reclaim-from-igp.ts @@ -5,14 +5,14 @@ import { HyperlaneCore, objMap, promiseObjAll } from '@hyperlane-xyz/sdk'; import { deployEnvToSdkEnv } from '../../src/config/environment'; import { getEnvironment, getEnvironmentConfig } from '../utils'; -// Some arbitrary treshold for now +// Some arbitrary threshold for now const RECLAIM_BALANCE_THRESHOLD = BigNumber.from(10).pow(17); async function main() { const environment = await getEnvironment(); const coreConfig = await getEnvironmentConfig(); const multiProvider = await coreConfig.getMultiProvider(); - const core: HyperlaneCore = HyperlaneCore.fromEnvironment( + const core: HyperlaneCore = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], multiProvider, ); @@ -22,8 +22,8 @@ async function main() { ); const balances = await promiseObjAll( - multiProvider.map((chain, chainConnection) => { - const provider = chainConnection.provider; + multiProvider.mapKnownChains((chain) => { + const provider = multiProvider.getProvider(chain); const paymasterAddress = paymasters[chain].address; return provider.getBalance(paymasterAddress); }), @@ -39,8 +39,7 @@ async function main() { return 'N/A'; } const tx = await paymaster.contract.claim(); - const chainConnection = multiProvider.getChainConnection(chain); - return chainConnection.getTxUrl(tx); + return multiProvider.getExplorerTxUrl(chain, tx); }), ); diff --git a/typescript/infra/scripts/govern.ts b/typescript/infra/scripts/govern.ts index 782000621..1897b1c8a 100644 --- a/typescript/infra/scripts/govern.ts +++ b/typescript/infra/scripts/govern.ts @@ -11,13 +11,12 @@ async function check() { const multiProvider = await config.getMultiProvider(); - // environments union doesn't work well with typescript const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); - const coreChecker = new HyperlaneCoreChecker( + const coreChecker = new HyperlaneCoreChecker( multiProvider, core, config.core, diff --git a/typescript/infra/scripts/helloworld/deploy.ts b/typescript/infra/scripts/helloworld/deploy.ts index 47a994625..7a94d8112 100644 --- a/typescript/infra/scripts/helloworld/deploy.ts +++ b/typescript/infra/scripts/helloworld/deploy.ts @@ -37,7 +37,7 @@ async function main() { const configMap = await getConfiguration(environment, multiProvider); const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); const deployer = new HelloWorldDeployer(multiProvider, configMap, core); const dir = path.join( @@ -46,11 +46,14 @@ async function main() { context, ); - let previousContracts: ChainMap = {}; + let previousContracts: ChainMap = {}; let existingVerificationInputs = {}; try { const addresses = readJSON(dir, 'addresses.json'); - previousContracts = buildContracts(addresses, helloWorldFactories) as any; + previousContracts = buildContracts( + addresses, + helloWorldFactories, + ) as ChainMap; existingVerificationInputs = readJSON(dir, 'verification.json'); } catch (e) { console.info(`Could not load previous deployment, file may not exist`); @@ -66,7 +69,6 @@ async function main() { writeJSON( dir, 'addresses.json', - // @ts-ignore serializeContracts(deployer.deployedContracts), ); writeJSON( diff --git a/typescript/infra/scripts/helloworld/kathy.ts b/typescript/infra/scripts/helloworld/kathy.ts index 875e57213..d720ec581 100644 --- a/typescript/infra/scripts/helloworld/kathy.ts +++ b/typescript/infra/scripts/helloworld/kathy.ts @@ -152,7 +152,7 @@ async function main(): Promise { ); const gasCalculator = InterchainGasCalculator.fromEnvironment( deployEnvToSdkEnv[environment], - app.multiProvider as any, + app.multiProvider, ); const appChains = app.chains(); @@ -355,10 +355,10 @@ async function main(): Promise { } async function sendMessage( - app: HelloWorldApp, + app: HelloWorldApp, origin: ChainName, destination: ChainName, - gasCalc: InterchainGasCalculator, + gasCalc: InterchainGasCalculator, messageSendTimeout: number, messageReceiptTimeout: number, ) { @@ -442,7 +442,7 @@ async function sendMessage( } async function messageIsProcessed( - core: HyperlaneCore, + core: HyperlaneCore, origin: ChainName, destination: ChainName, message: DispatchedMessage, @@ -452,10 +452,10 @@ async function messageIsProcessed( } async function updateWalletBalanceMetricFor( - app: HelloWorldApp, + app: HelloWorldApp, chain: ChainName, ): Promise { - const provider = app.multiProvider.getChainConnection(chain).provider; + const provider = app.multiProvider.getProvider(chain); const signerAddress = await app .getContracts(chain) .router.signer.getAddress(); diff --git a/typescript/infra/scripts/helloworld/utils.ts b/typescript/infra/scripts/helloworld/utils.ts index 74c448ada..e6e20f596 100644 --- a/typescript/infra/scripts/helloworld/utils.ts +++ b/typescript/infra/scripts/helloworld/utils.ts @@ -5,13 +5,10 @@ import { } from '@hyperlane-xyz/helloworld'; import { ChainMap, - ChainName, HyperlaneCore, MultiProvider, RouterConfig, buildContracts, - objMap, - promiseObjAll, } from '@hyperlane-xyz/sdk'; import { Contexts } from '../../config/contexts'; @@ -21,33 +18,27 @@ import { ConnectionType } from '../../src/config/agent'; import { deployEnvToSdkEnv } from '../../src/config/environment'; import { HelloWorldConfig } from '../../src/config/helloworld'; -export async function getConfiguration( +export async function getConfiguration( environment: DeployEnvironment, - multiProvider: MultiProvider, -): Promise> { - const signerMap = await promiseObjAll( - multiProvider.map(async (_, dc) => dc.signer!), - ); - const ownerMap = await promiseObjAll( - objMap(signerMap, async (_, signer) => { - return { - owner: await signer.getAddress(), - }; - }), - ); + multiProvider: MultiProvider, +): Promise> { + const ownerMap: ChainMap<{ owner: string }> = {}; + for (const chain of multiProvider.getKnownChainNames()) { + ownerMap[chain] = { + owner: await multiProvider.getSignerAddress(chain), + }; + } - // Currently can't be typed as per https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/594/files#diff-40a12589668de942078f498e0ab0fda512e1eb7397189d6d286b590ae87c45d1R31 - // @ts-ignore - const core: HyperlaneCore = HyperlaneCore.fromEnvironment( + const core: HyperlaneCore = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); return core.extendWithConnectionClientConfig(ownerMap); } -export async function getApp( - coreConfig: CoreEnvironmentConfig, +export async function getApp( + coreConfig: CoreEnvironmentConfig, context: Contexts, keyRole: KEY_ROLE_ENUM, keyContext: Contexts = context, @@ -57,23 +48,23 @@ export async function getApp( const contracts = buildContracts( helloworldConfig.addresses, helloWorldFactories, - ) as ChainMap; - const multiProvider: MultiProvider = await coreConfig.getMultiProvider( + ) as ChainMap; + const multiProvider: MultiProvider = await coreConfig.getMultiProvider( keyContext, keyRole, connectionType, ); const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[coreConfig.environment], - multiProvider as any, - ) as HyperlaneCore; + multiProvider, + ) as HyperlaneCore; return new HelloWorldApp(core, contracts, multiProvider); } -export function getHelloWorldConfig( - coreConfig: CoreEnvironmentConfig, +export function getHelloWorldConfig( + coreConfig: CoreEnvironmentConfig, context: Contexts, -): HelloWorldConfig { +): HelloWorldConfig { const helloWorldConfigs = coreConfig.helloWorld; if (!helloWorldConfigs) { throw new Error( diff --git a/typescript/infra/scripts/list-validator-checkpoint-indices.ts b/typescript/infra/scripts/list-validator-checkpoint-indices.ts index cd8b69807..c37c2b225 100644 --- a/typescript/infra/scripts/list-validator-checkpoint-indices.ts +++ b/typescript/infra/scripts/list-validator-checkpoint-indices.ts @@ -10,10 +10,9 @@ async function main() { const environment = await getEnvironment(); const config = getCoreEnvironmentConfig(environment); const multiProvider = await config.getMultiProvider(); - // environments union doesn't work well with typescript const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); const validators = Object.entries(config.core).flatMap(([chain, set]) => @@ -24,7 +23,6 @@ async function main() { 4, validators, async ({ chain, validator }) => { - // @ts-ignore Not sure why I need to do this.. const validatorAnnounce = core.getContracts(chain).validatorAnnounce; const storageLocations = await validatorAnnounce.getAnnouncedStorageLocations([validator]); diff --git a/typescript/infra/scripts/middleware/circle-relayer.ts b/typescript/infra/scripts/middleware/circle-relayer.ts index 47fb04f73..861b0adb6 100644 --- a/typescript/infra/scripts/middleware/circle-relayer.ts +++ b/typescript/infra/scripts/middleware/circle-relayer.ts @@ -4,6 +4,7 @@ import { ChainMap, Chains, LiquidityLayerApp, + LiquidityLayerContracts, buildContracts, liquidityLayerFactories, } from '@hyperlane-xyz/sdk'; @@ -27,11 +28,10 @@ async function check() { 'middleware/liquidity-layer', ); const addresses = readJSON(dir, 'addresses.json'); - // @ts-ignore - const contracts: ChainMap = buildContracts( + const contracts = buildContracts( addresses, liquidityLayerFactories, - ); + ) as ChainMap; const app = new LiquidityLayerApp( contracts, multiProvider, diff --git a/typescript/infra/scripts/middleware/deploy-accounts.ts b/typescript/infra/scripts/middleware/deploy-accounts.ts index e9d6c8d82..3a9dfefa6 100644 --- a/typescript/infra/scripts/middleware/deploy-accounts.ts +++ b/typescript/infra/scripts/middleware/deploy-accounts.ts @@ -24,7 +24,7 @@ async function main() { const multiProvider = await coreConfig.getMultiProvider(); const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); const dir = path.join( diff --git a/typescript/infra/scripts/middleware/deploy-liquidity-layer.ts b/typescript/infra/scripts/middleware/deploy-liquidity-layer.ts index 9e94dde89..2a5f8a918 100644 --- a/typescript/infra/scripts/middleware/deploy-liquidity-layer.ts +++ b/typescript/infra/scripts/middleware/deploy-liquidity-layer.ts @@ -23,7 +23,7 @@ async function main() { const multiProvider = await coreConfig.getMultiProvider(); const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); const dir = path.join( diff --git a/typescript/infra/scripts/middleware/deploy-queries.ts b/typescript/infra/scripts/middleware/deploy-queries.ts index 1074cb552..6f3e40105 100644 --- a/typescript/infra/scripts/middleware/deploy-queries.ts +++ b/typescript/infra/scripts/middleware/deploy-queries.ts @@ -22,7 +22,7 @@ async function main() { const multiProvider = await coreConfig.getMultiProvider(); const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); const dir = path.join( diff --git a/typescript/infra/scripts/middleware/portal-relayer.ts b/typescript/infra/scripts/middleware/portal-relayer.ts index 414194d28..3f9d05d86 100644 --- a/typescript/infra/scripts/middleware/portal-relayer.ts +++ b/typescript/infra/scripts/middleware/portal-relayer.ts @@ -3,6 +3,7 @@ import path from 'path'; import { ChainMap, LiquidityLayerApp, + LiquidityLayerContracts, buildContracts, liquidityLayerFactories, } from '@hyperlane-xyz/sdk'; @@ -26,11 +27,10 @@ async function relayPortalTransfers() { 'middleware/liquidity-layer', ); const addresses = readJSON(dir, 'addresses.json'); - // @ts-ignore - const contracts: ChainMap = buildContracts( + const contracts = buildContracts( addresses, liquidityLayerFactories, - ); + ) as ChainMap; const app = new LiquidityLayerApp( contracts, multiProvider, diff --git a/typescript/infra/scripts/output-agent-env-vars.ts b/typescript/infra/scripts/output-agent-env-vars.ts index 16cf672c2..3456fbd01 100644 --- a/typescript/infra/scripts/output-agent-env-vars.ts +++ b/typescript/infra/scripts/output-agent-env-vars.ts @@ -11,12 +11,7 @@ async function main() { .require('f').argv; const agentConfig = await getContextAgentConfig(); - const envVars = await getAgentEnvVars( - argv.c, - argv.r, - agentConfig, - argv.i, - ); + const envVars = await getAgentEnvVars(argv.c, argv.r, agentConfig, argv.i); await writeFile(argv.f, envVars.join('\n')); } diff --git a/typescript/infra/scripts/remove-agent-deploys.ts b/typescript/infra/scripts/remove-agent-deploys.ts index 82c5c17e7..96ded5d78 100644 --- a/typescript/infra/scripts/remove-agent-deploys.ts +++ b/typescript/infra/scripts/remove-agent-deploys.ts @@ -16,7 +16,7 @@ async function deploy() { await assertCorrectKubeContext(config); - const allChains = Object.keys(config.transactionConfigs); + const allChains = Object.keys(config.chainMetadataConfigs); await Promise.all( allChains .filter((_) => !agentConfig.contextChainNames.includes(_)) diff --git a/typescript/infra/scripts/safe-delegate.ts b/typescript/infra/scripts/safe-delegate.ts index de780a4cb..8a51ce0a0 100644 --- a/typescript/infra/scripts/safe-delegate.ts +++ b/typescript/infra/scripts/safe-delegate.ts @@ -33,9 +33,8 @@ async function delegate() { const { chain, delegate, safe, action } = await getArgs(); const multiProvider = await config.getMultiProvider(); - const connection = multiProvider.getChainConnection(chain); - const safeService = getSafeService(chain, connection); + const safeService = getSafeService(chain, multiProvider); const delegates = await getSafeDelegates(safeService, safe); console.log('Connecting to ledger, ensure plugged in and unlocked...'); diff --git a/typescript/infra/scripts/update-agents-diff.ts b/typescript/infra/scripts/update-agents-diff.ts index 0fcfd1b13..31d8ce8f6 100644 --- a/typescript/infra/scripts/update-agents-diff.ts +++ b/typescript/infra/scripts/update-agents-diff.ts @@ -17,7 +17,7 @@ async function deploy() { const agentConfig = await getContextAgentConfig(config); for (const chain of agentConfig.contextChainNames) { - await runAgentHelmCommand(HelmCommand.UpgradeDiff, agentConfig, chain); + await runAgentHelmCommand(HelmCommand.UpgradeDiff, agentConfig, chain); } } diff --git a/typescript/infra/scripts/utils.ts b/typescript/infra/scripts/utils.ts index dbc5ae820..56fff02be 100644 --- a/typescript/infra/scripts/utils.ts +++ b/typescript/infra/scripts/utils.ts @@ -4,8 +4,8 @@ import yargs from 'yargs'; import { AllChains, ChainMap, + ChainMetadata, ChainName, - IChainConnection, MultiProvider, objMap, promiseObjAll, @@ -55,7 +55,7 @@ export function assertEnvironment(env: string): DeployEnvironment { export function getCoreEnvironmentConfig( env: Env, -): CoreEnvironmentConfig { +): CoreEnvironmentConfig { return environments[env]; } @@ -74,8 +74,8 @@ export async function getContext(defaultContext?: string): Promise { } // Gets the agent config for the context that has been specified via yargs. -export async function getContextAgentConfig( - coreEnvironmentConfig?: CoreEnvironmentConfig, +export async function getContextAgentConfig( + coreEnvironmentConfig?: CoreEnvironmentConfig, defaultContext?: string, ) { return getAgentConfig( @@ -85,9 +85,9 @@ export async function getContextAgentConfig( } // Gets the agent config of a specific context. -export async function getAgentConfig( +export async function getAgentConfig( context: Contexts, - coreEnvironmentConfig?: CoreEnvironmentConfig, + coreEnvironmentConfig?: CoreEnvironmentConfig, ) { const coreConfig = coreEnvironmentConfig ? coreEnvironmentConfig @@ -103,10 +103,10 @@ export async function getAgentConfig( return agentConfig; } -async function getKeyForRole( +async function getKeyForRole( environment: DeployEnvironment, context: Contexts, - chain: Chain, + chain: ChainName, role: KEY_ROLE_ENUM, index?: number, ): Promise { @@ -115,14 +115,14 @@ async function getKeyForRole( return getCloudAgentKey(agentConfig, role, chain, index); } -export async function getMultiProviderForRole( - txConfigs: ChainMap, +export async function getMultiProviderForRole( + txConfigs: ChainMap, environment: DeployEnvironment, context: Contexts, role: KEY_ROLE_ENUM, index?: number, connectionType?: ConnectionType, -): Promise> { +): Promise { const connections = await promiseObjAll( objMap(txConfigs, async (chain, config) => { const provider = await fetchProvider(environment, chain, connectionType); @@ -135,7 +135,7 @@ export async function getMultiProviderForRole( }; }), ); - return new MultiProvider(connections); + return new MultiProvider(connections); } export function getCoreContractsSdkFilepath() { @@ -173,8 +173,8 @@ export function getKeyRoleAndChainArgs() { .number('i'); } -export async function assertCorrectKubeContext( - coreConfig: CoreEnvironmentConfig, +export async function assertCorrectKubeContext( + coreConfig: CoreEnvironmentConfig, ) { const currentKubeContext = await getCurrentKubernetesContext(); if ( diff --git a/typescript/infra/scripts/verify-validators.ts b/typescript/infra/scripts/verify-validators.ts index de39b9175..1e50cff55 100644 --- a/typescript/infra/scripts/verify-validators.ts +++ b/typescript/infra/scripts/verify-validators.ts @@ -9,14 +9,12 @@ async function main() { const environment = await getEnvironment(); const config = getCoreEnvironmentConfig(environment); const multiProvider = await config.getMultiProvider(); - // environments union doesn't work well with typescript const core = HyperlaneCore.fromEnvironment( deployEnvToSdkEnv[environment], - multiProvider as any, + multiProvider, ); objMap(config.core, async (chain, coreConfig) => { - // @ts-ignore Not sure why I need to do this.. const validatorAnnounce = core.getContracts(chain).validatorAnnounce; const storageLocations = await validatorAnnounce.getAnnouncedStorageLocations( diff --git a/typescript/infra/scripts/verify.ts b/typescript/infra/scripts/verify.ts index 1397e3e0a..e65881ddc 100644 --- a/typescript/infra/scripts/verify.ts +++ b/typescript/infra/scripts/verify.ts @@ -1,6 +1,6 @@ import { + ChainMap, CompilerOptions, - CompleteChainMap, ContractVerifier, } from '@hyperlane-xyz/sdk'; @@ -54,7 +54,7 @@ async function main() { await execCmd(`solc-select use ${matches[1]}`); await execCmd(`solc ${sourcePath}`); - const apiKeys: CompleteChainMap = await fetchGCPSecret( + const apiKeys: ChainMap = await fetchGCPSecret( 'explorer-api-keys', true, ); diff --git a/typescript/infra/src/agents/aws/key.ts b/typescript/infra/src/agents/aws/key.ts index 15099a498..e49c80511 100644 --- a/typescript/infra/src/agents/aws/key.ts +++ b/typescript/infra/src/agents/aws/key.ts @@ -43,7 +43,7 @@ export class AgentAwsKey extends CloudAgentKey { public remoteKey: RemoteKey = { fetched: false }; constructor( - agentConfig: AgentConfig, + agentConfig: AgentConfig, role: KEY_ROLE_ENUM, chainName?: ChainName, index?: number, diff --git a/typescript/infra/src/agents/aws/user.ts b/typescript/infra/src/agents/aws/user.ts index 479b5038f..437c34de7 100644 --- a/typescript/infra/src/agents/aws/user.ts +++ b/typescript/infra/src/agents/aws/user.ts @@ -21,7 +21,7 @@ import { KEY_ROLE_ENUM } from '../roles'; import { AgentAwsKey } from './key'; -export class AgentAwsUser { +export class AgentAwsUser { private adminIamClient: IAMClient; private _arn: string | undefined; @@ -31,7 +31,7 @@ export class AgentAwsUser { public readonly context: Contexts, public readonly role: KEY_ROLE_ENUM, public readonly region: string, - public readonly chainName?: Chain, + public readonly chainName?: ChainName, ) { this.adminIamClient = new IAMClient({ region }); } @@ -106,11 +106,11 @@ export class AgentAwsUser { ); } - key(agentConfig: AgentConfig): AgentAwsKey { + key(agentConfig: AgentConfig): AgentAwsKey { return new AgentAwsKey(agentConfig, this.role, this.chainName); } - async createKeyIfNotExists(agentConfig: AgentConfig) { + async createKeyIfNotExists(agentConfig: AgentConfig) { const key = this.key(agentConfig); await key.createIfNotExists(); await key.putKeyPolicy(this.arn); diff --git a/typescript/infra/src/agents/aws/validator-user.ts b/typescript/infra/src/agents/aws/validator-user.ts index 3b3d9fb76..f90923606 100644 --- a/typescript/infra/src/agents/aws/validator-user.ts +++ b/typescript/infra/src/agents/aws/validator-user.ts @@ -14,15 +14,13 @@ import { KEY_ROLE_ENUM } from '../roles'; import { AgentAwsKey } from './key'; import { AgentAwsUser } from './user'; -export class ValidatorAgentAwsUser< - Chain extends ChainName, -> extends AgentAwsUser { +export class ValidatorAgentAwsUser extends AgentAwsUser { private adminS3Client: S3Client; constructor( environment: string, context: Contexts, - public readonly chainName: Chain, + public readonly chainName: ChainName, public readonly index: number, region: string, public readonly bucket: string, @@ -85,7 +83,7 @@ export class ValidatorAgentAwsUser< await this.adminS3Client.send(cmd); } - key(agentConfig: AgentConfig): AgentAwsKey { + key(agentConfig: AgentConfig): AgentAwsKey { return new AgentAwsKey(agentConfig, this.role, this.chainName, this.index); } diff --git a/typescript/infra/src/agents/index.ts b/typescript/infra/src/agents/index.ts index 523849763..063cfba1b 100644 --- a/typescript/infra/src/agents/index.ts +++ b/typescript/infra/src/agents/index.ts @@ -25,9 +25,9 @@ import { KEY_ROLE_ENUM } from './roles'; const helmChartPath = '../../rust/helm/hyperlane-agent/'; -async function helmValuesForChain( - chainName: Chain, - agentConfig: AgentConfig, +async function helmValuesForChain( + chainName: ChainName, + agentConfig: AgentConfig, ) { const chainAgentConfig = new ChainAgentConfig(agentConfig, chainName); const gelatoApiKeyRequired = @@ -94,10 +94,10 @@ async function helmValuesForChain( }; } -export async function getAgentEnvVars( - outboxChainName: Chain, +export async function getAgentEnvVars( + outboxChainName: ChainName, role: KEY_ROLE_ENUM, - agentConfig: AgentConfig, + agentConfig: AgentConfig, index?: number, ) { const chainNames = agentConfig.contextChainNames; @@ -165,7 +165,7 @@ export async function getAgentEnvVars( } else { // AWS keys - let user: AgentAwsUser; + let user: AgentAwsUser; if (role === KEY_ROLE_ENUM.Validator && agentConfig.validators) { const checkpointSyncer = @@ -271,9 +271,7 @@ function configEnvVars( return envVars; } -export async function getSecretAwsCredentials( - agentConfig: AgentConfig, -) { +export async function getSecretAwsCredentials(agentConfig: AgentConfig) { return { accessKeyId: await fetchGCPSecret( `${agentConfig.runEnv}-aws-access-key-id`, @@ -312,10 +310,7 @@ export async function getSecretDeployerKey( return key.privateKey; } -async function getSecretRpcEndpoints( - agentConfig: AgentConfig, - quorum = false, -) { +async function getSecretRpcEndpoints(agentConfig: AgentConfig, quorum = false) { const environment = agentConfig.runEnv; return Object.fromEntries( agentConfig.contextChainNames.map((chainName) => [ @@ -325,9 +320,9 @@ async function getSecretRpcEndpoints( ); } -export async function doesAgentReleaseExist( - agentConfig: AgentConfig, - outboxChainName: Chain, +export async function doesAgentReleaseExist( + agentConfig: AgentConfig, + outboxChainName: ChainName, ) { try { await execCmd( @@ -345,10 +340,10 @@ export async function doesAgentReleaseExist( } } -export async function runAgentHelmCommand( +export async function runAgentHelmCommand( action: HelmCommand, - agentConfig: AgentConfig, - outboxChainName: Chain, + agentConfig: AgentConfig, + outboxChainName: ChainName, ) { if (action === HelmCommand.Remove) { return execCmd( @@ -408,9 +403,9 @@ export async function runAgentHelmCommand( return; } -function getHelmReleaseName( - outboxChainName: Chain, - agentConfig: AgentConfig, +function getHelmReleaseName( + outboxChainName: ChainName, + agentConfig: AgentConfig, ): string { // For backward compatibility reasons, don't include the context // in the name of the helm release if the context is the default "hyperlane" diff --git a/typescript/infra/src/agents/key-utils.ts b/typescript/infra/src/agents/key-utils.ts index 24043a659..9e5505edb 100644 --- a/typescript/infra/src/agents/key-utils.ts +++ b/typescript/infra/src/agents/key-utils.ts @@ -15,10 +15,10 @@ interface KeyAsAddress { address: string; } -export function getCloudAgentKey( - agentConfig: AgentConfig, +export function getCloudAgentKey( + agentConfig: AgentConfig, role: KEY_ROLE_ENUM, - chainName?: Chain, + chainName?: ChainName, index?: number, ): CloudAgentKey { if ( @@ -40,7 +40,7 @@ export function getCloudAgentKey( } export function getValidatorCloudAgentKeys( - agentConfig: AgentConfig, + agentConfig: AgentConfig, ): Array { // For each chainName, create validatorCount keys return agentConfig.contextChainNames.flatMap((chainName) => { @@ -60,7 +60,7 @@ export function getValidatorCloudAgentKeys( } export function getRelayerCloudAgentKeys( - agentConfig: AgentConfig, + agentConfig: AgentConfig, ): Array { return agentConfig.contextChainNames.map((chainName) => getCloudAgentKey(agentConfig, KEY_ROLE_ENUM.Relayer, chainName), @@ -68,7 +68,7 @@ export function getRelayerCloudAgentKeys( } export function getAllCloudAgentKeys( - agentConfig: AgentConfig, + agentConfig: AgentConfig, ): Array { return agentConfig.rolesWithKeys.flatMap((role) => { if (role === KEY_ROLE_ENUM.Validator) { @@ -81,7 +81,7 @@ export function getAllCloudAgentKeys( }); } -export async function deleteAgentKeys(agentConfig: AgentConfig) { +export async function deleteAgentKeys(agentConfig: AgentConfig) { const keys = getAllCloudAgentKeys(agentConfig); await Promise.all(keys.map((key) => key.delete())); await execCmd( @@ -92,9 +92,7 @@ export async function deleteAgentKeys(agentConfig: AgentConfig) { ); } -export async function createAgentKeysIfNotExists( - agentConfig: AgentConfig, -) { +export async function createAgentKeysIfNotExists(agentConfig: AgentConfig) { const keys = getAllCloudAgentKeys(agentConfig); await Promise.all( @@ -110,10 +108,10 @@ export async function createAgentKeysIfNotExists( ); } -export async function rotateKey( - agentConfig: AgentConfig, +export async function rotateKey( + agentConfig: AgentConfig, role: KEY_ROLE_ENUM, - chainName: Chain, + chainName: ChainName, ) { const key = getCloudAgentKey(agentConfig, role, chainName); await key.update(); @@ -150,9 +148,9 @@ async function persistAddresses( } // This function returns all keys for a given outbox chain in a dictionary where the key is the identifier -export async function fetchKeysForChain( - agentConfig: AgentConfig, - chainName: Chain, +export async function fetchKeysForChain( + agentConfig: AgentConfig, + chainName: ChainName, ): Promise> { // Get all keys for the chainName. Include keys where chainName is undefined, // which are keys that are not chain-specific but should still be included diff --git a/typescript/infra/src/config/agent.ts b/typescript/infra/src/config/agent.ts index 8e0557818..6dcabe924 100644 --- a/typescript/infra/src/config/agent.ts +++ b/typescript/infra/src/config/agent.ts @@ -13,15 +13,15 @@ import { gcpSecretExists } from '../utils/gcloud'; import { DeployEnvironment } from './environment'; // Allows a "default" config to be specified and any per-chain overrides. -interface ChainOverridableConfig { +interface ChainOverridableConfig { default: T; - chainOverrides?: Partial>>; + chainOverrides?: ChainMap>; } -// Returns the default config with any overriden values specified for the provided chain. -export function getChainOverriddenConfig( - overridableConfig: ChainOverridableConfig, - chain: Chain, +// Returns the default config with any overridden values specified for the provided chain. +export function getChainOverriddenConfig( + overridableConfig: ChainOverridableConfig, + chain: ChainName, ): T { return { ...overridableConfig.default, @@ -75,10 +75,7 @@ interface BaseRelayerConfig { } // Per-chain relayer agent configs -type ChainRelayerConfigs = ChainOverridableConfig< - Chain, - BaseRelayerConfig ->; +type ChainRelayerConfigs = ChainOverridableConfig; interface SerializableGasPaymentEnforcementConfig extends Omit { @@ -149,10 +146,7 @@ interface ValidatorChainConfig { } // Validator agents for each chain. -export type ChainValidatorConfigs = ChainMap< - Chain, - ValidatorChainConfig ->; +export type ChainValidatorConfigs = ChainMap; // Helm config for a single validator interface ValidatorHelmConfig { @@ -198,9 +192,9 @@ export interface DockerConfig { tag: string; } -export interface GelatoConfig { +export interface GelatoConfig { // List of chains in which using Gelato is enabled for - enabledChains: Chain[]; + enabledChains: ChainName[]; } export enum TransactionSubmissionType { @@ -208,7 +202,7 @@ export enum TransactionSubmissionType { Gelato = 'gelato', } -export interface AgentConfig { +export interface AgentConfig { environment: string; namespace: string; runEnv: DeployEnvironment; @@ -219,13 +213,13 @@ export interface AgentConfig { index?: IndexingConfig; aws?: AwsConfig; // Names of all chains in the environment - environmentChainNames: Chain[]; + environmentChainNames: ChainName[]; // Names of chains this context cares about - contextChainNames: Chain[]; - gelato?: GelatoConfig; + contextChainNames: ChainName[]; + gelato?: GelatoConfig; // RC contexts do not provide validators - validators?: ChainValidatorConfigs; - relayer?: ChainRelayerConfigs; + validators?: ChainValidatorConfigs; + relayer?: ChainRelayerConfigs; // Roles to manage keys for rolesWithKeys: KEY_ROLE_ENUM[]; } @@ -267,9 +261,9 @@ export type RustChainSetup = { index?: { from: string }; }; -export type RustConfig = { +export type RustConfig = { environment: DeployEnvironment; - chains: Partial>; + chains: Partial>; // TODO: Separate DBs for each chain (fold into RustChainSetup) db: string; tracing: { @@ -279,10 +273,10 @@ export type RustConfig = { }; // Helper to get chain-specific agent configurations -export class ChainAgentConfig { +export class ChainAgentConfig { constructor( - public readonly agentConfig: AgentConfig, - public readonly chainName: Chain, + public readonly agentConfig: AgentConfig, + public readonly chainName: ChainName, ) {} // Credentials are only needed if AWS keys are needed -- otherwise, the @@ -475,7 +469,7 @@ export class ChainAgentConfig { } } - transactionSubmissionType(chain: Chain): TransactionSubmissionType { + transactionSubmissionType(chain: ChainName): TransactionSubmissionType { if (this.agentConfig.gelato?.enabledChains.includes(chain)) { return TransactionSubmissionType.Gelato; } diff --git a/typescript/infra/src/config/chain.ts b/typescript/infra/src/config/chain.ts index ba73ca6c7..13031f089 100644 --- a/typescript/infra/src/config/chain.ts +++ b/typescript/infra/src/config/chain.ts @@ -1,7 +1,6 @@ import { FallbackProviderConfig } from '@ethersproject/providers'; import { ethers } from 'ethers'; -import { StaticCeloJsonRpcProvider } from '@hyperlane-xyz/celo-ethers-provider'; import { ChainName, RetryJsonRpcProvider } from '@hyperlane-xyz/sdk'; import { getSecretRpcEndpoint } from '../agents'; @@ -9,15 +8,7 @@ import { getSecretRpcEndpoint } from '../agents'; import { ConnectionType } from './agent'; import { DeployEnvironment } from './environment'; -const CELO_CHAIN_NAMES = new Set(['alfajores', 'baklava', 'celo']); - -const providerBuilder = (url: string, chainName: ChainName, retry = true) => { - // TODO: get StaticCeloJsonRpcProvider to be compatible with the RetryJsonRpcProvider. - // For now, the two are incompatible, so even if retrying is requested for a Celo chain, - // we don't use a RetryJsonRpcProvider. - if (CELO_CHAIN_NAMES.has(chainName)) { - return new StaticCeloJsonRpcProvider(url); - } +const providerBuilder = (url: string, retry = true) => { const baseProvider = new ethers.providers.JsonRpcProvider(url); return retry ? new RetryJsonRpcProvider(baseProvider, { @@ -36,20 +27,18 @@ export async function fetchProvider( const rpcData = await getSecretRpcEndpoint(environment, chainName, !single); switch (connectionType) { case ConnectionType.Http: { - return providerBuilder(rpcData, chainName); + return providerBuilder(rpcData); } case ConnectionType.HttpQuorum: { return new ethers.providers.FallbackProvider( - (rpcData as string[]).map((url) => - providerBuilder(url, chainName, false), - ), // disable retry for quorum + (rpcData as string[]).map((url) => providerBuilder(url, false)), // disable retry for quorum ); } case ConnectionType.HttpFallback: { return new ethers.providers.FallbackProvider( (rpcData as string[]).map((url, index) => { const fallbackProviderConfig: FallbackProviderConfig = { - provider: providerBuilder(url, chainName), + provider: providerBuilder(url), // Priority is used by the FallbackProvider to determine // how to order providers using ascending ordering. // When not specified, all providers have the same priority diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index 1ea7bdfa9..16ac62807 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -1,8 +1,8 @@ import { ChainMap, + ChainMetadata, ChainName, CoreConfig, - EnvironmentConfig, MultiProvider, } from '@hyperlane-xyz/sdk'; import { CoreEnvironment } from '@hyperlane-xyz/sdk/dist/core/HyperlaneCore'; @@ -24,19 +24,19 @@ export type EnvironmentChain = Extract< ChainName >; -export type CoreEnvironmentConfig = { +export type CoreEnvironmentConfig = { environment: DeployEnvironment; - transactionConfigs: EnvironmentConfig; + chainMetadataConfigs: ChainMap; // Each AgentConfig, keyed by the context - agents: Partial>>; - core: ChainMap; + agents: Partial>; + core: ChainMap; infra: InfrastructureConfig; getMultiProvider: ( context?: Contexts, role?: KEY_ROLE_ENUM, connectionType?: ConnectionType, - ) => Promise>; - helloWorld?: Partial>>; + ) => Promise; + helloWorld?: Partial>; keyFunderConfig?: KeyFunderConfig; liquidityLayerRelayerConfig?: LiquidityLayerRelayerConfig; }; diff --git a/typescript/infra/src/config/helloworld.ts b/typescript/infra/src/config/helloworld.ts index db622fb01..29541f751 100644 --- a/typescript/infra/src/config/helloworld.ts +++ b/typescript/infra/src/config/helloworld.ts @@ -9,11 +9,11 @@ export enum HelloWorldKathyRunMode { Service, } -export interface HelloWorldKathyConfig { +export interface HelloWorldKathyConfig { docker: DockerConfig; runEnv: string; namespace: string; - chainsToSkip: Chain[]; + chainsToSkip: ChainName[]; runConfig: | { mode: HelloWorldKathyRunMode.CycleOnce; @@ -34,7 +34,7 @@ export interface HelloWorldKathyConfig { cyclesBetweenEthereumMessages?: number; } -export interface HelloWorldConfig { - addresses: ChainMap; - kathy: HelloWorldKathyConfig; +export interface HelloWorldConfig { + addresses: ChainMap<{ router: string }>; + kathy: HelloWorldKathyConfig; } diff --git a/typescript/infra/src/core/deploy.ts b/typescript/infra/src/core/deploy.ts index 390090500..0756cc24a 100644 --- a/typescript/infra/src/core/deploy.ts +++ b/typescript/infra/src/core/deploy.ts @@ -24,22 +24,20 @@ import { DeployEnvironment, RustChainSetup, RustConfig } from '../config'; import { ConnectionType } from '../config/agent'; import { writeJSON } from '../utils/utils'; -export class HyperlaneCoreInfraDeployer< - Chain extends ChainName, -> extends HyperlaneCoreDeployer { +export class HyperlaneCoreInfraDeployer extends HyperlaneCoreDeployer { environment: DeployEnvironment; constructor( - multiProvider: MultiProvider, - configMap: ChainMap, + multiProvider: MultiProvider, + configMap: ChainMap, environment: DeployEnvironment, ) { super(multiProvider, configMap); this.environment = environment; } - async deployInterchainGasPaymaster( - chain: LocalChain, + async deployInterchainGasPaymaster( + chain: ChainName, proxyAdmin: ProxyAdmin, ): Promise< ProxiedContract @@ -53,8 +51,8 @@ export class HyperlaneCoreInfraDeployer< return super.deployInterchainGasPaymaster(chain, proxyAdmin, deployOpts); } - async deployDefaultIsmInterchainGasPaymaster( - chain: LocalChain, + async deployDefaultIsmInterchainGasPaymaster( + chain: ChainName, interchainGasPaymasterAddress: types.Address, ): Promise { const deployOpts = { @@ -70,8 +68,8 @@ export class HyperlaneCoreInfraDeployer< ); } - async deployMailbox( - chain: LocalChain, + async deployMailbox( + chain: ChainName, defaultIsmAddress: types.Address, proxyAdmin: ProxyAdmin, ): Promise> { @@ -89,8 +87,8 @@ export class HyperlaneCoreInfraDeployer< ); } - async deployValidatorAnnounce( - chain: LocalChain, + async deployValidatorAnnounce( + chain: ChainName, mailboxAddress: types.Address, ): Promise { const deployOpts = { @@ -103,7 +101,7 @@ export class HyperlaneCoreInfraDeployer< } writeRustConfigs(directory: string) { - const rustConfig: RustConfig = { + const rustConfig: RustConfig = { environment: this.environment, chains: {}, db: 'db_path', @@ -127,7 +125,7 @@ export class HyperlaneCoreInfraDeployer< const chainConfig: RustChainSetup = { name: chain, - domain: metadata.id.toString(), + domain: metadata.chainId.toString(), addresses: { mailbox: contracts.mailbox.contract.address, interchainGasPaymaster: contracts.interchainGasPaymaster.address, @@ -135,7 +133,7 @@ export class HyperlaneCoreInfraDeployer< }, signer: null, protocol: 'ethereum', - finalityBlocks: metadata.blocks.reorgPeriod.toString(), + finalityBlocks: metadata.blocks!.reorgPeriod!.toString(), connection: { type: ConnectionType.Http, url: '', diff --git a/typescript/infra/src/core/govern.ts b/typescript/infra/src/core/govern.ts index f240733cb..677142733 100644 --- a/typescript/infra/src/core/govern.ts +++ b/typescript/infra/src/core/govern.ts @@ -4,7 +4,6 @@ import { InterchainGasPaymaster__factory } from '@hyperlane-xyz/core'; import { ChainMap, ChainName, - ChainNameToDomainId, CoreContracts, CoreViolationType, EnrolledValidatorsViolation, @@ -39,12 +38,12 @@ type AnnotatedCallData = types.CallData & { description: string; }; -export class HyperlaneCoreGovernor { - readonly checker: HyperlaneCoreChecker; - private calls: ChainMap; - private canPropose: ChainMap>; +export class HyperlaneCoreGovernor { + readonly checker: HyperlaneCoreChecker; + private calls: ChainMap; + private canPropose: ChainMap>; - constructor(checker: HyperlaneCoreChecker) { + constructor(checker: HyperlaneCoreChecker) { this.checker = checker; this.calls = objMap(this.checker.app.contractsMap, () => []); this.canPropose = objMap(this.checker.app.contractsMap, () => new Map()); @@ -59,12 +58,12 @@ export class HyperlaneCoreGovernor { // 3. Prompt the user to confirm that the count, description, // and submission methods look correct before submitting. - for (const chain of Object.keys(this.calls) as Chain[]) { + for (const chain of Object.keys(this.calls)) { await this.sendCalls(chain); } } - protected async sendCalls(chain: Chain) { + protected async sendCalls(chain: ChainName) { const calls = this.calls[chain]; console.log(`\nFound ${calls.length} transactions for ${chain}`); const filterCalls = (submissionType: SubmissionType) => @@ -109,21 +108,19 @@ export class HyperlaneCoreGovernor { } }; - const connection = this.checker.multiProvider.getChainConnection(chain); - await sendCallsForType( SubmissionType.SIGNER, - new SignerMultiSend(connection), + new SignerMultiSend(this.checker.multiProvider, chain), ); const owner = this.checker.configMap[chain!].owner!; await sendCallsForType( SubmissionType.SAFE, - new SafeMultiSend(connection, chain, owner), + new SafeMultiSend(this.checker.multiProvider, chain, owner), ); await sendCallsForType(SubmissionType.MANUAL, new ManualMultiSend(chain)); } - protected pushCall(chain: Chain, call: AnnotatedCallData) { + protected pushCall(chain: ChainName, call: AnnotatedCallData) { this.calls[chain].push(call); } @@ -150,7 +147,7 @@ export class HyperlaneCoreGovernor { handleProxyViolation(violation: ProxyViolation) { const contracts: CoreContracts = - this.checker.app.contractsMap[violation.chain as Chain]; + this.checker.app.contractsMap[violation.chain]; let initData = '0x'; switch (violation.data.name) { case 'InterchainGasPaymaster': @@ -162,7 +159,7 @@ export class HyperlaneCoreGovernor { default: throw new Error(`Unsupported proxy violation ${violation.data.name}`); } - this.pushCall(violation.chain as Chain, { + this.pushCall(violation.chain, { to: contracts.proxyAdmin.address, data: contracts.proxyAdmin.interface.encodeFunctionData( 'upgradeAndCall', @@ -177,7 +174,7 @@ export class HyperlaneCoreGovernor { } protected async inferCallSubmissionTypes() { - for (const chain of Object.keys(this.calls) as Chain[]) { + for (const chain of Object.keys(this.calls)) { for (const call of this.calls[chain]) { const submissionType = await this.inferCallSubmissionType(chain, call); call.submissionType = submissionType; @@ -186,13 +183,13 @@ export class HyperlaneCoreGovernor { } protected async inferCallSubmissionType( - chain: Chain, + chain: ChainName, call: AnnotatedCallData, ): Promise { - const connection = this.checker.multiProvider.getChainConnection(chain); + const multiProvider = this.checker.multiProvider; // 1. Check if the call will succeed with the default signer. try { - await connection.estimateGas(call); + await multiProvider.estimateGas(chain, call); return SubmissionType.SIGNER; } catch (_) {} // eslint-disable-line no-empty @@ -202,7 +199,7 @@ export class HyperlaneCoreGovernor { // 2a. Confirm that the signer is a Safe owner or delegate. // This should implicitly check whether or not the owner is a gnosis // safe. - const signer = connection.signer; + const signer = multiProvider.getSigner(chain); if (!signer) throw new Error(`no signer found`); const signerAddress = await signer.getAddress(); if (!this.canPropose[chain].has(safeAddress)) { @@ -211,7 +208,7 @@ export class HyperlaneCoreGovernor { await canProposeSafeTransactions( signerAddress, chain, - connection, + multiProvider, safeAddress, ), ); @@ -220,7 +217,7 @@ export class HyperlaneCoreGovernor { // 2b. Check if calling from the owner will succeed. if (this.canPropose[chain].get(safeAddress)) { try { - await connection.provider.estimateGas({ + await multiProvider.getProvider(chain).estimateGas({ ...call, from: safeAddress, }); @@ -242,21 +239,21 @@ export class HyperlaneCoreGovernor { // add expected - actual elements utils .difference(reconcile.expected, reconcile.actual) - .forEach((elem) => - this.pushCall(reconcile.chain as Chain, reconcile.add(elem)), - ); + .forEach((elem) => this.pushCall(reconcile.chain, reconcile.add(elem))); // remote actual - expected elements utils .difference(reconcile.actual, reconcile.expected) .forEach((elem) => - this.pushCall(reconcile.chain as Chain, reconcile.remove(elem)), + this.pushCall(reconcile.chain, reconcile.remove(elem)), ); } handleMultisigIsmViolation(violation: MultisigIsmViolation) { const multisigIsm = violation.contract; - const remoteDomainId = ChainNameToDomainId[violation.remote]; + const remoteDomainId = this.checker.multiProvider.getDomainId( + violation.remote, + ); switch (violation.subType) { case MultisigIsmViolationType.EnrolledValidators: { const baseDescription = `as ${violation.remote} validator on ${violation.chain}`; @@ -282,7 +279,7 @@ export class HyperlaneCoreGovernor { break; } case MultisigIsmViolationType.Threshold: { - this.pushCall(violation.chain as Chain, { + this.pushCall(violation.chain, { to: multisigIsm.address, data: multisigIsm.interface.encodeFunctionData('setThreshold', [ remoteDomainId, @@ -300,7 +297,7 @@ export class HyperlaneCoreGovernor { } handleOwnerViolation(violation: OwnerViolation) { - this.pushCall(violation.chain as Chain, { + this.pushCall(violation.chain, { to: violation.contract.address, data: violation.contract.interface.encodeFunctionData( 'transferOwnership', diff --git a/typescript/infra/src/core/multisend.ts b/typescript/infra/src/core/multisend.ts index 93cd620ae..bc7c9650c 100644 --- a/typescript/infra/src/core/multisend.ts +++ b/typescript/infra/src/core/multisend.ts @@ -1,4 +1,4 @@ -import { ChainConnection, ChainName } from '@hyperlane-xyz/sdk'; +import { ChainName, MultiProvider } from '@hyperlane-xyz/sdk'; import { types } from '@hyperlane-xyz/utils'; import { getSafe, getSafeService } from '../utils/safe'; @@ -8,16 +8,19 @@ export abstract class MultiSend { } export class SignerMultiSend extends MultiSend { - readonly connection: ChainConnection; - - constructor(connection: ChainConnection) { + constructor( + public readonly multiProvider: MultiProvider, + public readonly chain: ChainName, + ) { super(); - this.connection = connection; } async sendTransactions(calls: types.CallData[]) { for (const call of calls) { - const receipt = await this.connection.sendTransaction(call); + const receipt = await this.multiProvider.sendTransaction( + this.chain, + call, + ); console.log(`confirmed tx ${receipt.transactionHash}`); } } @@ -38,23 +41,20 @@ export class ManualMultiSend extends MultiSend { } export class SafeMultiSend extends MultiSend { - readonly connection: ChainConnection; - readonly chain: ChainName; - readonly safeAddress: string; - constructor( - connection: ChainConnection, - chain: ChainName, - safeAddress: string, + public readonly multiProvider: MultiProvider, + public readonly chain: ChainName, + public readonly safeAddress: string, ) { super(); - this.connection = connection; - this.chain = chain; - this.safeAddress = safeAddress; } async sendTransactions(calls: types.CallData[]) { - const safeSdk = await getSafe(this.connection, this.safeAddress); + const safeSdk = await getSafe( + this.chain, + this.multiProvider, + this.safeAddress, + ); const safeTransactionData = calls.map((call) => { return { to: call.to, data: call.data.toString(), value: '0' }; }); @@ -64,13 +64,13 @@ export class SafeMultiSend extends MultiSend { const safeTxHash = await safeSdk.getTransactionHash(safeTransaction); const senderSignature = await safeSdk.signTransactionHash(safeTxHash); - const safeService = getSafeService(this.chain, this.connection); - if (!this.connection.signer) throw new Error('missing signer'); + const safeService = getSafeService(this.chain, this.multiProvider); + const senderAddress = await this.multiProvider.getSignerAddress(this.chain); await safeService.proposeTransaction({ safeAddress: this.safeAddress, safeTransactionData: safeTransaction.data, safeTxHash, - senderAddress: await this.connection.signer.getAddress()!, + senderAddress, senderSignature: senderSignature.data, }); } diff --git a/typescript/infra/src/create2/index.ts b/typescript/infra/src/create2/index.ts index d498096ce..ef025b60c 100644 --- a/typescript/infra/src/create2/index.ts +++ b/typescript/infra/src/create2/index.ts @@ -18,22 +18,22 @@ type Contracts = { const CREATE2FACTORYBYTECODE = '0x608060405234801561001057600080fd5b50610640806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634af63f0214610046578063c2b1041c14610082578063cf4d643214610095575b600080fd5b610059610054366004610486565b6100a8565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610059610090366004610514565b6100e7565b6100596100a336600461058a565b6101f4565b604080513360208201529081018290526000906100e09084906060015b604051602081830303815290604052805190602001206102c6565b9392505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602082015290810182905260009081906060016040516020818303038152906040528051906020012090503081878760405161013f9291906105fa565b6040519081900381206101b49392916020017fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209695505050505050565b604080513360208201529081018490526000906102159086906060016100c5565b905060008173ffffffffffffffffffffffffffffffffffffffff1684846040516102409291906105fa565b6000604051808303816000865af19150503d806000811461027d576040519150601f19603f3d011682016040523d82523d6000602084013e610282565b606091505b50509050806102bd576040517f4f77232300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949350505050565b60008251600003610303576040517f21744a5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818351602085016000f5905073ffffffffffffffffffffffffffffffffffffffff811661035c576040517f4102e83a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251602084012060405173ffffffffffffffffffffffffffffffffffffffff83169184917f27b8e3132afa95254770e1c1d214eafde52bc47d1b6e1f5dfcbb380c3ca3f53290600090a492915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126103ec57600080fd5b813567ffffffffffffffff80821115610407576104076103ac565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561044d5761044d6103ac565b8160405283815286602085880101111561046657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561049957600080fd5b823567ffffffffffffffff8111156104b057600080fd5b6104bc858286016103db565b95602094909401359450505050565b60008083601f8401126104dd57600080fd5b50813567ffffffffffffffff8111156104f557600080fd5b60208301915083602082850101111561050d57600080fd5b9250929050565b6000806000806060858703121561052a57600080fd5b843567ffffffffffffffff81111561054157600080fd5b61054d878288016104cb565b909550935050602085013573ffffffffffffffffffffffffffffffffffffffff8116811461057a57600080fd5b9396929550929360400135925050565b600080600080606085870312156105a057600080fd5b843567ffffffffffffffff808211156105b857600080fd5b6105c4888389016103db565b95506020870135945060408701359150808211156105e157600080fd5b506105ee878288016104cb565b95989497509550505050565b818382376000910190815291905056fea2646970667358221220959b7947b895d33da4de69733c07a0543161262edcf0e8d1784935027b47462c64736f6c63430008110033'; -export class Create2FactoryDeployer< - Chain extends ChainName, -> extends HyperlaneDeployer { - constructor(multiProvider: MultiProvider) { +export class Create2FactoryDeployer extends HyperlaneDeployer< + any, + Contracts, + typeof factories +> { + constructor(multiProvider: MultiProvider) { super( multiProvider, - multiProvider.map(() => ({})), + multiProvider.mapKnownChains(() => ({})), factories, ); } - async deployContracts(chain: Chain) { - const chainConnection = this.multiProvider.getChainConnection(chain); - const signer = this.multiProvider.getChainSigner(chain); - if ( - (await chainConnection.provider.getCode(CREATE2FACTORY_ADDRESS)) === '0x' - ) { + async deployContracts(chain: ChainName) { + const provider = this.multiProvider.getProvider(chain); + const signer = this.multiProvider.getSigner(chain); + if ((await provider.getCode(CREATE2FACTORY_ADDRESS)) === '0x') { const tx = await signer.signTransaction({ data: CREATE2FACTORYBYTECODE, chainId: 0, @@ -43,9 +43,7 @@ export class Create2FactoryDeployer< nonce: 0, }); - await chainConnection.handleTx( - chainConnection.provider.sendTransaction(tx), - ); + await this.multiProvider.handleTx(chain, provider.sendTransaction(tx)); } const Create2Factory = Create2Factory__factory.connect( diff --git a/typescript/infra/src/deploy.ts b/typescript/infra/src/deploy.ts index ea6da095b..723ab6413 100644 --- a/typescript/infra/src/deploy.ts +++ b/typescript/infra/src/deploy.ts @@ -12,9 +12,9 @@ import { readJSON, writeJSON } from './utils/utils'; export async function deployWithArtifacts( dir: string, factories: T, - deployer: HyperlaneDeployer, + deployer: HyperlaneDeployer, ) { - let contracts: ChainMap = {}; + let contracts: ChainMap = {}; try { const addresses = readJSON(dir, 'addresses.json'); contracts = buildContracts(addresses, factories) as any; diff --git a/typescript/infra/src/funding/deploy-key-funder.ts b/typescript/infra/src/funding/deploy-key-funder.ts index c5528f5ed..57391a4a4 100644 --- a/typescript/infra/src/funding/deploy-key-funder.ts +++ b/typescript/infra/src/funding/deploy-key-funder.ts @@ -1,13 +1,11 @@ -import { ChainName } from '@hyperlane-xyz/sdk'; - import { AgentConfig, CoreEnvironmentConfig } from '../config'; import { KeyFunderConfig } from '../config/funding'; import { HelmCommand, helmifyValues } from '../utils/helm'; import { execCmd } from '../utils/utils'; -export async function runKeyFunderHelmCommand( +export async function runKeyFunderHelmCommand( helmCommand: HelmCommand, - agentConfig: AgentConfig, + agentConfig: AgentConfig, keyFunderConfig: KeyFunderConfig, ) { const values = getKeyFunderHelmValues(agentConfig, keyFunderConfig); @@ -36,8 +34,8 @@ export async function runKeyFunderHelmCommand( ); } -function getKeyFunderHelmValues( - agentConfig: AgentConfig, +function getKeyFunderHelmValues( + agentConfig: AgentConfig, keyFunderConfig: KeyFunderConfig, ) { const values = { @@ -64,7 +62,7 @@ function getKeyFunderHelmValues( } export function getKeyFunderConfig( - coreConfig: CoreEnvironmentConfig, + coreConfig: CoreEnvironmentConfig, ): KeyFunderConfig { const keyFunderConfig = coreConfig.keyFunderConfig; if (!keyFunderConfig) { diff --git a/typescript/infra/src/helloworld/kathy.ts b/typescript/infra/src/helloworld/kathy.ts index 647d032f9..2eb46b19c 100644 --- a/typescript/infra/src/helloworld/kathy.ts +++ b/typescript/infra/src/helloworld/kathy.ts @@ -1,5 +1,3 @@ -import { ChainName } from '@hyperlane-xyz/sdk'; - import { Contexts } from '../../config/contexts'; import { AgentAwsUser } from '../agents/aws'; import { KEY_ROLE_ENUM } from '../agents/roles'; @@ -11,14 +9,14 @@ import { import { HelmCommand, helmifyValues } from '../utils/helm'; import { execCmd } from '../utils/utils'; -export async function runHelloworldKathyHelmCommand( +export async function runHelloworldKathyHelmCommand( helmCommand: HelmCommand, - agentConfig: AgentConfig, - kathyConfig: HelloWorldKathyConfig, + agentConfig: AgentConfig, + kathyConfig: HelloWorldKathyConfig, ) { // If using AWS keys, ensure the Kathy user and key has been created if (agentConfig.aws) { - const awsUser = new AgentAwsUser( + const awsUser = new AgentAwsUser( agentConfig.environment, agentConfig.context, KEY_ROLE_ENUM.Kathy, @@ -50,9 +48,9 @@ function getHelmReleaseName(context: Contexts): string { }`; } -function getHelloworldKathyHelmValues( - agentConfig: AgentConfig, - kathyConfig: HelloWorldKathyConfig, +function getHelloworldKathyHelmValues( + agentConfig: AgentConfig, + kathyConfig: HelloWorldKathyConfig, ) { const cycleOnce = kathyConfig.runConfig.mode === HelloWorldKathyRunMode.CycleOnce; diff --git a/typescript/infra/src/middleware/liquidity-layer-relayer.ts b/typescript/infra/src/middleware/liquidity-layer-relayer.ts index bec062e68..2b361df3d 100644 --- a/typescript/infra/src/middleware/liquidity-layer-relayer.ts +++ b/typescript/infra/src/middleware/liquidity-layer-relayer.ts @@ -1,15 +1,11 @@ -import { ChainName } from '@hyperlane-xyz/sdk'; - import { AgentConfig, CoreEnvironmentConfig } from '../config'; import { LiquidityLayerRelayerConfig } from '../config/middleware'; import { HelmCommand, helmifyValues } from '../utils/helm'; import { execCmd } from '../utils/utils'; -export async function runLiquidityLayerRelayerHelmCommand< - Chain extends ChainName, ->( +export async function runLiquidityLayerRelayerHelmCommand( helmCommand: HelmCommand, - agentConfig: AgentConfig, + agentConfig: AgentConfig, relayerConfig: LiquidityLayerRelayerConfig, ) { const values = getLiquidityLayerRelayerHelmValues(agentConfig, relayerConfig); @@ -38,8 +34,8 @@ export async function runLiquidityLayerRelayerHelmCommand< ); } -function getLiquidityLayerRelayerHelmValues( - agentConfig: AgentConfig, +function getLiquidityLayerRelayerHelmValues( + agentConfig: AgentConfig, relayerConfig: LiquidityLayerRelayerConfig, ) { const values = { @@ -61,7 +57,7 @@ function getLiquidityLayerRelayerHelmValues( } export function getLiquidityLayerRelayerConfig( - coreConfig: CoreEnvironmentConfig, + coreConfig: CoreEnvironmentConfig, ): LiquidityLayerRelayerConfig { const relayerConfig = coreConfig.liquidityLayerRelayerConfig; if (!relayerConfig) { diff --git a/typescript/infra/src/scraper/deploy.ts b/typescript/infra/src/scraper/deploy.ts index badc51f11..e9090b1e7 100644 --- a/typescript/infra/src/scraper/deploy.ts +++ b/typescript/infra/src/scraper/deploy.ts @@ -1,5 +1,3 @@ -import { ChainName } from '@hyperlane-xyz/sdk'; - import { AgentConfig } from '../config'; import { ConnectionType } from '../config/agent'; import { @@ -11,9 +9,9 @@ import { execCmd } from '../utils/utils'; const helmChartPath = '../../rust/helm/hyperlane-agent/'; -export async function runScraperHelmCommand( +export async function runScraperHelmCommand( action: HelmCommand, - agentConfig: AgentConfig, + agentConfig: AgentConfig, ) { const values = await scraperHelmValues(agentConfig); @@ -51,9 +49,7 @@ export async function runScraperHelmCommand( ); } -async function scraperHelmValues( - agentConfig: AgentConfig, -) { +async function scraperHelmValues(agentConfig: AgentConfig) { // By default, if a context only enables a subset of chains, the // connection url (or urls, when HttpQuorum is used) are not fetched // from GCP secret manager. For Http/Ws, the `url` param is expected, diff --git a/typescript/infra/src/testcontracts/testquerysender.ts b/typescript/infra/src/testcontracts/testquerysender.ts index 4517e1972..244ffcd50 100644 --- a/typescript/infra/src/testcontracts/testquerysender.ts +++ b/typescript/infra/src/testcontracts/testquerysender.ts @@ -17,22 +17,19 @@ type Contracts = { TestQuerySender: TestQuerySender; }; -export class TestQuerySenderDeployer< - Chain extends ChainName, -> extends HyperlaneDeployer< - Chain, +export class TestQuerySenderDeployer extends HyperlaneDeployer< TestQuerySenderConfig, Contracts, typeof factories > { constructor( - multiProvider: MultiProvider, - queryRouters: ChainMap, - protected core: HyperlaneCore, + multiProvider: MultiProvider, + queryRouters: ChainMap, + protected core: HyperlaneCore, ) { super(multiProvider, queryRouters, factories); } - async deployContracts(chain: Chain, config: TestQuerySenderConfig) { + async deployContracts(chain: ChainName, config: TestQuerySenderConfig) { const initCalldata = TestQuerySender__factory.createInterface().encodeFunctionData( 'initialize', diff --git a/typescript/infra/src/testcontracts/testrecipient.ts b/typescript/infra/src/testcontracts/testrecipient.ts index 23809d4fc..691328b3f 100644 --- a/typescript/infra/src/testcontracts/testrecipient.ts +++ b/typescript/infra/src/testcontracts/testrecipient.ts @@ -20,17 +20,19 @@ type Contracts = { TestTokenRecipient: TestTokenRecipient; }; -export class TestRecipientDeployer< - Chain extends ChainName, -> extends HyperlaneDeployer { - constructor(multiProvider: MultiProvider) { +export class TestRecipientDeployer extends HyperlaneDeployer< + any, + Contracts, + typeof factories +> { + constructor(multiProvider: MultiProvider) { super( multiProvider, - multiProvider.map(() => ({})), + multiProvider.mapKnownChains(() => ({})), factories, ); } - async deployContracts(chain: Chain) { + async deployContracts(chain: ChainName) { const TestRecipient = await this.deployContract( chain, 'TestRecipient', diff --git a/typescript/infra/src/utils/safe.ts b/typescript/infra/src/utils/safe.ts index efc62910e..e94307f8d 100644 --- a/typescript/infra/src/utils/safe.ts +++ b/typescript/infra/src/utils/safe.ts @@ -3,14 +3,13 @@ import EthersAdapter from '@safe-global/safe-ethers-lib'; import SafeServiceClient from '@safe-global/safe-service-client'; import { ethers } from 'ethers'; -import { ChainConnection, ChainName, chainMetadata } from '@hyperlane-xyz/sdk'; +import { ChainName, MultiProvider, chainMetadata } from '@hyperlane-xyz/sdk'; export function getSafeService( chain: ChainName, - connection: ChainConnection, + multiProvider: MultiProvider, ): SafeServiceClient { - const signer = connection.signer; - if (!signer) throw new Error(`no signer found for ${chain}`); + const signer = multiProvider.getSigner(chain); const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer }); const txServiceUrl = chainMetadata[chain].gnosisSafeTransactionServiceUrl; if (!txServiceUrl) @@ -19,11 +18,11 @@ export function getSafeService( } export function getSafe( - connection: ChainConnection, + chain: ChainName, + multiProvider: MultiProvider, safeAddress: string, ): Promise { - const signer = connection.signer; - if (!signer) throw new Error(`no signer found`); + const signer = multiProvider.getSigner(chain); const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer }); return Safe.create({ ethAdapter, @@ -42,11 +41,11 @@ export async function getSafeDelegates( export async function canProposeSafeTransactions( proposer: string, chain: ChainName, - connection: ChainConnection, + multiProvider: MultiProvider, safeAddress: string, ): Promise { - const safeService = getSafeService(chain, connection); - const safe = await getSafe(connection, safeAddress); + const safeService = getSafeService(chain, multiProvider); + const safe = await getSafe(chain, multiProvider, safeAddress); const delegates = await getSafeDelegates(safeService, safeAddress); const owners = await safe.getOwners(); return delegates.includes(proposer) || owners.includes(proposer); diff --git a/typescript/infra/src/utils/utils.ts b/typescript/infra/src/utils/utils.ts index d726fea89..b6c32b2bd 100644 --- a/typescript/infra/src/utils/utils.ts +++ b/typescript/infra/src/utils/utils.ts @@ -5,7 +5,7 @@ import { ethers } from 'ethers'; import fs from 'fs'; import path from 'path'; -import { AllChains, ChainName } from '@hyperlane-xyz/sdk'; +import { AllChains, ChainName, CoreChainName } from '@hyperlane-xyz/sdk'; import { Contexts } from '../../config/contexts'; import { ALL_KEY_ROLES, KEY_ROLE_ENUM } from '../agents/roles'; @@ -187,7 +187,7 @@ export function assertRole(roleStr: string) { export function assertChain(chainStr: string) { const chain = chainStr as ChainName; - if (!AllChains.includes(chain)) { + if (!AllChains.includes(chain as CoreChainName)) { throw Error(`Invalid chain ${chain}`); } return chain; diff --git a/typescript/infra/test/core.test.ts b/typescript/infra/test/core.test.ts index 4f6fa22e6..bcfafd3cd 100644 --- a/typescript/infra/test/core.test.ts +++ b/typescript/infra/test/core.test.ts @@ -10,32 +10,30 @@ import { HyperlaneCore, HyperlaneCoreChecker, MultiProvider, - getTestMultiProvider, objMap, serializeContracts, } from '@hyperlane-xyz/sdk'; import { environment as testConfig } from '../config/environments/test'; -import { TestChains } from '../config/environments/test/chains'; import { HyperlaneCoreInfraDeployer } from '../src/core/deploy'; import { writeJSON } from '../src/utils/utils'; describe('core', async () => { const environment = 'test'; - let multiProvider: MultiProvider; - let deployer: HyperlaneCoreInfraDeployer; - let core: HyperlaneCore; - let contracts: CoreContractsMap; - let coreConfig: ChainMap; + let multiProvider: MultiProvider; + let deployer: HyperlaneCoreInfraDeployer; + let core: HyperlaneCore; + let contracts: CoreContractsMap; + let coreConfig: ChainMap; - let owners: ChainMap; + let owners: ChainMap; beforeEach(async () => { const [signer, owner] = await ethers.getSigners(); // This is kind of awkward and really these tests shouldn't live here - multiProvider = getTestMultiProvider(signer, testConfig.transactionConfigs); + multiProvider = MultiProvider.createTestMultiProvider({ signer }); coreConfig = testConfig.core; - owners = objMap(testConfig.transactionConfigs, () => owner.address); + owners = objMap(testConfig.chainMetadataConfigs, () => owner.address); }); it('deploys', async () => { @@ -91,7 +89,9 @@ describe('core', async () => { it('can be resumed from partial contracts', async () => { sinon.restore(); // restore normal deployer behavior + //@ts-ignore operand not optional, ignore for this test delete deployer.deployedContracts.test2!.multisigIsm; + //@ts-ignore operand not optional, ignore for this test delete deployer.deployedContracts.test2!.mailbox; const result = await deployer.deploy(); diff --git a/yarn.lock b/yarn.lock index 61e1f9ef2..abe908fa3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3970,11 +3970,11 @@ __metadata: languageName: node linkType: hard -"@hyperlane-xyz/helloworld@1.1.4, @hyperlane-xyz/helloworld@workspace:typescript/helloworld": +"@hyperlane-xyz/helloworld@1.2.0, @hyperlane-xyz/helloworld@workspace:typescript/helloworld": version: 0.0.0-use.local resolution: "@hyperlane-xyz/helloworld@workspace:typescript/helloworld" dependencies: - "@hyperlane-xyz/sdk": 1.1.4 + "@hyperlane-xyz/sdk": 1.2.0 "@nomiclabs/hardhat-ethers": ^2.2.1 "@nomiclabs/hardhat-waffle": ^2.0.3 "@openzeppelin/contracts-upgradeable": ^4.8.0 @@ -4051,10 +4051,9 @@ __metadata: "@gnosis.pm/safe-core-sdk": ^2.3.2 "@gnosis.pm/safe-ethers-lib": ^1.4.0 "@gnosis.pm/safe-service-client": ^1.2.0 - "@hyperlane-xyz/celo-ethers-provider": ^0.1.1 - "@hyperlane-xyz/helloworld": 1.1.4 - "@hyperlane-xyz/sdk": 1.1.4 - "@hyperlane-xyz/utils": 1.1.4 + "@hyperlane-xyz/helloworld": 1.2.0 + "@hyperlane-xyz/sdk": 1.2.0 + "@hyperlane-xyz/utils": 1.2.0 "@nomiclabs/hardhat-ethers": ^2.2.1 "@nomiclabs/hardhat-etherscan": ^3.0.3 "@nomiclabs/hardhat-waffle": ^2.0.3 @@ -4097,23 +4096,7 @@ __metadata: languageName: unknown linkType: soft -"@hyperlane-xyz/sdk@npm:1.1.4": - version: 1.1.4 - resolution: "@hyperlane-xyz/sdk@npm:1.1.4" - dependencies: - "@hyperlane-xyz/celo-ethers-provider": ^0.1.1 - "@hyperlane-xyz/core": 1.1.4 - "@hyperlane-xyz/utils": 1.1.4 - "@wagmi/chains": ^0.2.6 - coingecko-api: ^1.0.10 - cross-fetch: ^3.1.5 - debug: ^4.3.4 - ethers: ^5.7.2 - checksum: 600d81648cdbdad2be4200bd772d49128b9bcd5de10d1f811008291ed268610a0bb1cac8061dfa30b5040dc20c7b8919b39ed206d7993f63c65abf3df663c125 - languageName: node - linkType: hard - -"@hyperlane-xyz/sdk@workspace:typescript/sdk": +"@hyperlane-xyz/sdk@1.2.0, @hyperlane-xyz/sdk@workspace:typescript/sdk": version: 0.0.0-use.local resolution: "@hyperlane-xyz/sdk@workspace:typescript/sdk" dependencies: @@ -4142,6 +4125,22 @@ __metadata: languageName: unknown linkType: soft +"@hyperlane-xyz/sdk@npm:1.1.4": + version: 1.1.4 + resolution: "@hyperlane-xyz/sdk@npm:1.1.4" + dependencies: + "@hyperlane-xyz/celo-ethers-provider": ^0.1.1 + "@hyperlane-xyz/core": 1.1.4 + "@hyperlane-xyz/utils": 1.1.4 + "@wagmi/chains": ^0.2.6 + coingecko-api: ^1.0.10 + cross-fetch: ^3.1.5 + debug: ^4.3.4 + ethers: ^5.7.2 + checksum: 600d81648cdbdad2be4200bd772d49128b9bcd5de10d1f811008291ed268610a0bb1cac8061dfa30b5040dc20c7b8919b39ed206d7993f63c65abf3df663c125 + languageName: node + linkType: hard + "@hyperlane-xyz/utils@1.2.0, @hyperlane-xyz/utils@workspace:typescript/utils": version: 0.0.0-use.local resolution: "@hyperlane-xyz/utils@workspace:typescript/utils"