From e6f9d5c4fdd801196560b48ce939e4c76faea8ad Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Wed, 6 Nov 2024 19:57:30 +0000 Subject: [PATCH] feat: add weETHs warp route, some drive-by cleanup (#4826) ### Description - Deploys weETHs between Ethereum and Eclipsemainnet - Removes all the warp route generation scripts in favor of a single one - Renames some things throughout infra to be closer to the canonical warp IDs (e.g. add all chain names, sort them, etc) - Removes a bunch of now unnecessary ts-ignores - Moves toward using router configs for non-EVM chains in the warp configs Waiting to merge https://github.com/hyperlane-xyz/hyperlane-registry/pull/362 before updating the registryrc in here so the warp config checker works ### Drive-by changes ### Related issues ### Backward compatibility ### Testing --- .changeset/shy-taxis-suffer.md | 5 +++ rust/sealevel/client/src/warp_route.rs | 22 +++++++---- .../program-ids.json | 10 +++++ .../token-config.json | 17 +++++++++ .../config/environments/mainnet3/agent.ts | 4 +- .../config/environments/mainnet3/funding.ts | 2 +- .../config/environments/mainnet3/index.ts | 4 +- .../config/environments/mainnet3/owners.ts | 27 ++++++++++++++ ...getEclipseEthereumSolanaUSDCWarpConfig.ts} | 8 ++-- ...getEclipseEthereumSolanaUSDTWarpConfig.ts} | 12 +++--- ...ts => getEclipseEthereumTETHWarpConfig.ts} | 4 +- .../getEclipseEthereumWBTCWarpConfig.ts | 9 +---- .../getEclipseEthereumWeETHsWarpConfig.ts | 36 ++++++++++++++++++ .../getEclipseStrideSTTIAWarpConfig.ts | 7 ++-- .../getEclipseStrideTIAWarpConfig.ts | 8 ++-- .../environments/mainnet3/warp/warpIds.ts | 5 ++- typescript/infra/config/warp.ts | 18 ++++++--- typescript/infra/scripts/agent-utils.ts | 4 ++ .../funding/fund-keys-from-deployer.ts | 35 +++++++++++++++++- ...generate-eclipse-usdt-warp-route-config.ts | 26 ------------- ...generate-eclipse-wbtc-warp-route-config.ts | 26 ------------- .../generate-renzo-ezeth-warp-route-config.ts | 23 ------------ .../generate-renzo-pzeth-warp-route-config.ts | 23 ------------ .../warp-routes/generate-warp-config.ts | 37 +++++++++++++++++++ typescript/infra/src/config/environment.ts | 31 +++++++++++++++- typescript/infra/src/config/warp.ts | 1 + typescript/utils/src/index.ts | 1 + typescript/utils/src/objects.test.ts | 13 +++++++ typescript/utils/src/objects.ts | 8 ++++ 29 files changed, 281 insertions(+), 145 deletions(-) create mode 100644 .changeset/shy-taxis-suffer.md create mode 100644 rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/program-ids.json create mode 100644 rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/token-config.json rename typescript/infra/config/environments/mainnet3/warp/configGetters/{getEthereumEclipseUSDCWarpConfig.ts => getEclipseEthereumSolanaUSDCWarpConfig.ts} (77%) rename typescript/infra/config/environments/mainnet3/warp/configGetters/{getEclipseEthereumUSDTWarpConfig.ts => getEclipseEthereumSolanaUSDTWarpConfig.ts} (66%) rename typescript/infra/config/environments/mainnet3/warp/configGetters/{getEthereumEclipseTETHWarpConfig.ts => getEclipseEthereumTETHWarpConfig.ts} (85%) create mode 100644 typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts delete mode 100644 typescript/infra/scripts/generate-eclipse-usdt-warp-route-config.ts delete mode 100644 typescript/infra/scripts/generate-eclipse-wbtc-warp-route-config.ts delete mode 100644 typescript/infra/scripts/generate-renzo-ezeth-warp-route-config.ts delete mode 100644 typescript/infra/scripts/generate-renzo-pzeth-warp-route-config.ts create mode 100644 typescript/infra/scripts/warp-routes/generate-warp-config.ts diff --git a/.changeset/shy-taxis-suffer.md b/.changeset/shy-taxis-suffer.md new file mode 100644 index 000000000..17d53d2a3 --- /dev/null +++ b/.changeset/shy-taxis-suffer.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/utils': patch +--- + +Added a mustGet helper diff --git a/rust/sealevel/client/src/warp_route.rs b/rust/sealevel/client/src/warp_route.rs index 3cb3328c1..a18554450 100644 --- a/rust/sealevel/client/src/warp_route.rs +++ b/rust/sealevel/client/src/warp_route.rs @@ -192,19 +192,25 @@ impl RouterDeployer for WarpRouteDeployer { app_config: &TokenConfig, program_id: Pubkey, ) { - if let Some(ata_payer_funding_amount) = self.ata_payer_funding_amount { - if matches!( - app_config.token_type, - TokenType::Collateral(_) | TokenType::Synthetic(_) - ) { - fund_ata_payer_up_to(ctx, client, program_id, ata_payer_funding_amount); + let try_fund_ata_payer = |ctx: &mut Context, client: &RpcClient| { + if let Some(ata_payer_funding_amount) = self.ata_payer_funding_amount { + if matches!( + app_config.token_type, + TokenType::Collateral(_) | TokenType::Synthetic(_) + ) { + fund_ata_payer_up_to(ctx, client, program_id, ata_payer_funding_amount); + } } - } + }; let (token_pda, _token_bump) = Pubkey::find_program_address(hyperlane_token_pda_seeds!(), &program_id); if account_exists(client, &token_pda).unwrap() { println!("Warp route token already exists, skipping init"); + + // Fund the ATA payer up to the specified amount. + try_fund_ata_payer(ctx, client); + return; } @@ -398,6 +404,8 @@ impl RouterDeployer for WarpRouteDeployer { println!("Set the {authority} authority to the mint account. Status: {status}"); } } + + try_fund_ata_payer(ctx, client); } /// Sets gas router configs on all deployable chains. diff --git a/rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/program-ids.json b/rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/program-ids.json new file mode 100644 index 000000000..52d56a41a --- /dev/null +++ b/rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/program-ids.json @@ -0,0 +1,10 @@ +{ + "eclipsemainnet": { + "hex": "0x6196f9127d2caa0f4265d0870d077e6bf979c585b87cceb7537fc6d2c81729b7", + "base58": "7Zx4wU1QAw98MfvnPFqRh1oyumek7G5VAX6TKB3U1tcn" + }, + "ethereum": { + "hex": "0x000000000000000000000000ef899e92da472e014be795ecce948308958e25a2", + "base58": "1111111111114LZDAaWurQERWF32Wqjijy9NWQRX" + } +} diff --git a/rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/token-config.json b/rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/token-config.json new file mode 100644 index 000000000..2390192dd --- /dev/null +++ b/rust/sealevel/environments/mainnet3/warp-routes/weETHs-eclipsemainnet-ethereum/token-config.json @@ -0,0 +1,17 @@ +{ + "eclipsemainnet": { + "type": "synthetic", + "decimals": 9, + "remoteDecimals": 18, + "name": "Super Symbiotic LRT", + "symbol": "weETHs", + "uri": "https://raw.githubusercontent.com/hyperlane-xyz/hyperlane-registry/6ce62e9330ae1af0786f60d9fe6da8541b6b2988/deployments/warp_routes/weETHs/metadata.json", + "interchainGasPaymaster": "3Wp4qKkgf4tjXz1soGyTSndCgBPLZFSrZkiDZ8Qp9EEj" + }, + "ethereum": { + "type": "collateral", + "decimals": 18, + "token": "0x917cee801a67f933f2e6b33fc0cd1ed2d5909d88", + "foreignDeployment": "0xef899e92DA472E014bE795Ecce948308958E25A2" + } +} diff --git a/typescript/infra/config/environments/mainnet3/agent.ts b/typescript/infra/config/environments/mainnet3/agent.ts index 0d4389217..df9df0956 100644 --- a/typescript/infra/config/environments/mainnet3/agent.ts +++ b/typescript/infra/config/environments/mainnet3/agent.ts @@ -402,13 +402,13 @@ const metricAppContexts = [ { name: 'eclipse_usdc', matchingList: matchingList( - getWarpAddresses(WarpRouteIds.EthereumEclipseUSDC), + getWarpAddresses(WarpRouteIds.EclipseEthereumSolanaUSDC), ), }, { name: 'eclipse_teth', matchingList: matchingList( - getWarpAddresses(WarpRouteIds.EthereumEclipseTETH), + getWarpAddresses(WarpRouteIds.EclipseEthereumTETH), ), }, { diff --git a/typescript/infra/config/environments/mainnet3/funding.ts b/typescript/infra/config/environments/mainnet3/funding.ts index 7a8251856..73877f955 100644 --- a/typescript/infra/config/environments/mainnet3/funding.ts +++ b/typescript/infra/config/environments/mainnet3/funding.ts @@ -10,7 +10,7 @@ export const keyFunderConfig: KeyFunderConfig< > = { docker: { repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', - tag: 'b1366fa-20241101-173610', + tag: '1b067fe-20241106-190859', }, // We're currently using the same deployer/key funder key as mainnet2. // To minimize nonce clobbering we offset the key funder cron diff --git a/typescript/infra/config/environments/mainnet3/index.ts b/typescript/infra/config/environments/mainnet3/index.ts index a18d929a6..d2061134f 100644 --- a/typescript/infra/config/environments/mainnet3/index.ts +++ b/typescript/infra/config/environments/mainnet3/index.ts @@ -17,7 +17,7 @@ import { helloWorld } from './helloworld.js'; import { igp } from './igp.js'; import { infrastructure } from './infrastructure.js'; import { bridgeAdapterConfigs, relayerConfig } from './liquidityLayer.js'; -import { ethereumChainOwners } from './owners.js'; +import { chainOwners } from './owners.js'; import { supportedChainNames } from './supportedChainNames.js'; import { checkWarpDeployConfig } from './warp/checkWarpDeploy.js'; @@ -48,7 +48,7 @@ export const environment: EnvironmentConfig = { agents, core, igp, - owners: ethereumChainOwners, + owners: chainOwners, infra: infrastructure, helloWorld, keyFunderConfig, diff --git a/typescript/infra/config/environments/mainnet3/owners.ts b/typescript/infra/config/environments/mainnet3/owners.ts index 624ae64e2..811a34a0e 100644 --- a/typescript/infra/config/environments/mainnet3/owners.ts +++ b/typescript/infra/config/environments/mainnet3/owners.ts @@ -179,3 +179,30 @@ export const ethereumChainOwners: ChainMap = Object.fromEntries( ]; }), ); + +export const chainOwners: ChainMap = { + ...ethereumChainOwners, + solanamainnet: { + // Squads multisig + owner: 'BNGDJ1h9brgt6FFVd8No1TVAH48Fp44d7jkuydr1URwJ', + }, + eclipsemainnet: { + owner: 'B32qTbw8iDcVdagMAMBfDFCef88N1KtfRG5QoPVzbj5K', + }, + injective: { + // Native multisig + owner: 'inj1ac6qpt57vhtfzdecd2an052elwgenwtxcn9chl', + }, + neutron: { + // Da0Da0 multisig + owner: 'neutron1fqf5mprg3f5hytvzp3t7spmsum6rjrw80mq8zgkc0h6rxga0dtzqws3uu7', + }, + // We intentionally cause issues if these were to be used, but satisfy the types + // and ensure there's an entry for each supported chain. + stride: { + owner: 'n/a - nothing owned here', + }, + osmosis: { + owner: 'n/a - nothing owned here', + }, +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumEclipseUSDCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDCWarpConfig.ts similarity index 77% rename from typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumEclipseUSDCWarpConfig.ts rename to typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDCWarpConfig.ts index 1d39abb12..078c90776 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumEclipseUSDCWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDCWarpConfig.ts @@ -8,13 +8,12 @@ import { } from '@hyperlane-xyz/sdk'; import { tokens } from '../../../../../src/config/warp.js'; -import { DEPLOYER } from '../../owners.js'; -export const getEthereumEclipseUSDCWarpConfig = async ( +export const getEclipseEthereumSolanaUSDCWarpConfig = async ( routerConfig: ChainMap, ): Promise> => { - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const eclipsemainnet: TokenRouterConfig = { + ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'D6k6T3G74ij6atCtBiWBs5TbFa1hFVcrFUSGZHuV7q3Z', gas: 300_000, @@ -27,6 +26,9 @@ export const getEthereumEclipseUSDCWarpConfig = async ( token: tokens.ethereum.USDC, }; + // Intentionally don't enroll Solana to avoid transferring + // directly between Solana and Ethereum + return { eclipsemainnet, ethereum, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumUSDTWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.ts similarity index 66% rename from typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumUSDTWarpConfig.ts rename to typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.ts index a40303272..781b3caa9 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumUSDTWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.ts @@ -8,20 +8,15 @@ import { } from '@hyperlane-xyz/sdk'; import { tokens } from '../../../../../src/config/warp.js'; -import { getRegistry as getMainnet3Registry } from '../../chains.js'; -export const getEclipseEthereumUSDTWarpConfig = async ( +export const getEclipseEthereumSolanaUSDTWarpConfig = async ( routerConfig: ChainMap, ): Promise> => { - const registry = await getMainnet3Registry(); - - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const eclipsemainnet: TokenRouterConfig = { + ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: '5g5ujyYUNvdydwyDVCpZwPpgYRqH5RYJRi156cxyE3me', gas: 300_000, - mailbox: (await registry.getChainAddresses('eclipsemainnet'))!.mailbox, - owner: '9bRSUPjfS3xS6n5EfkJzHFTRDa4AHLda8BU2pP4HoWnf', interchainSecurityModule: ethers.constants.AddressZero, }; let ethereum: TokenRouterConfig = { @@ -31,6 +26,9 @@ export const getEclipseEthereumUSDTWarpConfig = async ( interchainSecurityModule: ethers.constants.AddressZero, }; + // Intentionally don't enroll Solana to avoid transferring + // directly between Solana and Ethereum + return { eclipsemainnet, ethereum, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumEclipseTETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumTETHWarpConfig.ts similarity index 85% rename from typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumEclipseTETHWarpConfig.ts rename to typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumTETHWarpConfig.ts index 57ed42891..db149da15 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumEclipseTETHWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumTETHWarpConfig.ts @@ -7,13 +7,11 @@ import { TokenType, } from '@hyperlane-xyz/sdk'; -import { DEPLOYER } from '../../owners.js'; - export const getEthereumEclipseTETHWarpConfig = async ( routerConfig: ChainMap, ): Promise> => { - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const eclipsemainnet: TokenRouterConfig = { + ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'BJa3fPvvjKx8gRCWunoSrWBbsmieub37gsGpjp4BfTfW', gas: 300_000, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts index 60628efeb..03bdd55b7 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts @@ -8,23 +8,18 @@ import { } from '@hyperlane-xyz/sdk'; import { tokens } from '../../../../../src/config/warp.js'; -import { getRegistry as getMainnet3Registry } from '../../chains.js'; -import { DEPLOYER } from '../../owners.js'; export const getEclipseEthereumWBTCWarpConfig = async ( routerConfig: ChainMap, ): Promise> => { - const registry = await getMainnet3Registry(); - - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const eclipsemainnet: TokenRouterConfig = { + ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'A7EGCDYFw5R7Jfm6cYtKvY8dmkrYMgwRCJFkyQwpHTYu', gas: 300_000, - mailbox: (await registry.getChainAddresses('eclipsemainnet'))!.mailbox, - owner: '9bRSUPjfS3xS6n5EfkJzHFTRDa4AHLda8BU2pP4HoWnf', interchainSecurityModule: ethers.constants.AddressZero, }; + let ethereum: TokenRouterConfig = { ...routerConfig.ethereum, type: TokenType.collateral, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts new file mode 100644 index 000000000..34da322ad --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts @@ -0,0 +1,36 @@ +import { ethers } from 'ethers'; + +import { + ChainMap, + RouterConfig, + TokenRouterConfig, + TokenType, +} from '@hyperlane-xyz/sdk'; + +import { tokens } from '../../../../../src/config/warp.js'; +import { DEPLOYER } from '../../owners.js'; + +export const getEclipseEthereumWeEthsWarpConfig = async ( + routerConfig: ChainMap, +): Promise> => { + const eclipsemainnet: TokenRouterConfig = { + ...routerConfig.eclipsemainnet, + type: TokenType.synthetic, + foreignDeployment: '7Zx4wU1QAw98MfvnPFqRh1oyumek7G5VAX6TKB3U1tcn', + gas: 300_000, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + let ethereum: TokenRouterConfig = { + ...routerConfig.ethereum, + type: TokenType.collateral, + token: tokens.ethereum.weETHs, + interchainSecurityModule: ethers.constants.AddressZero, + owner: DEPLOYER, + }; + + return { + eclipsemainnet, + ethereum, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts index eaf935f9b..4d8db22a7 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts @@ -6,20 +6,21 @@ import { } from '@hyperlane-xyz/sdk'; export const getEclipseStrideTiaWarpConfig = async ( - _routerConfig: ChainMap, + routerConfig: ChainMap, ): Promise> => { - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const eclipsemainnet: TokenRouterConfig = { + ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'BpXHAiktwjx7fN6M9ST9wr6qKAsH27wZFhdHEhReJsR6', gas: 300_000, }; - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const stride: TokenRouterConfig = { + ...routerConfig.stride, type: TokenType.collateral, foreignDeployment: 'stride1pvtesu3ve7qn7ctll2x495mrqf2ysp6fws68grvcu6f7n2ajghgsh2jdj6', + token: 'stutia', }; return { diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts index aa2cf6a10..9d5bdf578 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts @@ -6,20 +6,22 @@ import { } from '@hyperlane-xyz/sdk'; export const getEclipseStrideStTiaWarpConfig = async ( - _routerConfig: ChainMap, + routerConfig: ChainMap, ): Promise> => { - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const eclipsemainnet: TokenRouterConfig = { + ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'tKUHyJ5NxhnwU94JUmzh1ekukDcHHX8mZF6fqxbMwX6', gas: 300_000, }; - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig const stride: TokenRouterConfig = { + ...routerConfig.stride, type: TokenType.collateral, foreignDeployment: 'stride134axwdlam929m3mar3wv95nvkyep7mr87ravkqcpf8dfe3v0pjlqwrw6ee', + token: + 'ibc/BF3B4F53F3694B66E13C23107C84B6485BD2B96296BB7EC680EA77BBA75B4801', }; return { diff --git a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts index 4ffb986de..d70348b56 100644 --- a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts +++ b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts @@ -4,16 +4,17 @@ export enum WarpRouteIds { ArbitrumEthereumZircuitAMPHRETH = 'AMPHRETH/arbitrum-ethereum-zircuit', ArbitrumNeutronEclip = 'ECLIP/arbitrum-neutron', ArbitrumNeutronTIA = 'TIA/arbitrum-neutron', + EclipseEthereumSolanaUSDC = 'USDC/eclipsemainnet-ethereum-solanamainnet', EclipseEthereumSolanaUSDT = 'USDT/eclipsemainnet-ethereum-solanamainnet', + EclipseEthereumTETH = 'tETH/eclipsemainnet-ethereum', EclipseEthereumWBTC = 'WBTC/eclipsemainnet-ethereum', + EclipseEthereumWeETHs = 'weETHs/eclipsemainnet-ethereum', EclipseSolanaSOL = 'SOL/eclipsemainnet-solanamainnet', EclipseSolanaWIF = 'WIF/eclipsemainnet-solanamainnet', EclipseStrideSTTIA = 'stTIA/eclipse-stride', EclipseStrideTIA = 'TIA/eclipse-stride', EthereumInevmUSDC = 'USDC/ethereum-inevm', EthereumInevmUSDT = 'USDT/ethereum-inevm', - EthereumEclipseTETH = 'tETH/eclipsemainnet-ethereum', - EthereumEclipseUSDC = 'USDC/eclipsemainnet-ethereum-solanamainnet', EthereumSeiFastUSD = 'FASTUSD/ethereum-sei', EthereumVictionETH = 'ETH/ethereum-viction', EthereumVictionUSDC = 'USDC/ethereum-viction', diff --git a/typescript/infra/config/warp.ts b/typescript/infra/config/warp.ts index d1577d116..3a9bf87e0 100644 --- a/typescript/infra/config/warp.ts +++ b/typescript/infra/config/warp.ts @@ -6,14 +6,18 @@ import { } from '@hyperlane-xyz/sdk'; import { getHyperlaneCore } from '../scripts/core-utils.js'; -import { EnvironmentConfig } from '../src/config/environment.js'; +import { + EnvironmentConfig, + getRouterConfigsForAllVms, +} from '../src/config/environment.js'; import { getAncient8EthereumUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getAncient8EthereumUSDCWarpConfig.js'; import { getArbitrumEthereumZircuitAmphrETHWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumEthereumZircuitAmphrETHWarpConfig.js'; import { getArbitrumNeutronEclipWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumNeutronEclipWarpConfig.js'; import { getArbitrumNeutronTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumNeutronTiaWarpConfig.js'; -import { getEclipseEthereumUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumUSDTWarpConfig.js'; +import { getEclipseEthereumSolanaUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.js'; import { getEclipseEthereumWBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.js'; +import { getEclipseEthereumWeEthsWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.js'; import { getEclipseStrideTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.js'; import { getEclipseStrideStTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.js'; import { getEthereumBscLUMIAWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumBscLumiaLUMIAWarpConfig.js'; @@ -58,8 +62,10 @@ export const warpConfigGetterMap: Record< [WarpRouteIds.MantapacificNeutronTIA]: getMantapacificNeutronTiaWarpConfig, [WarpRouteIds.EclipseStrideTIA]: getEclipseStrideTiaWarpConfig, [WarpRouteIds.EclipseStrideSTTIA]: getEclipseStrideStTiaWarpConfig, - [WarpRouteIds.EclipseEthereumSolanaUSDT]: getEclipseEthereumUSDTWarpConfig, + [WarpRouteIds.EclipseEthereumSolanaUSDT]: + getEclipseEthereumSolanaUSDTWarpConfig, [WarpRouteIds.EclipseEthereumWBTC]: getEclipseEthereumWBTCWarpConfig, + [WarpRouteIds.EclipseEthereumWeETHs]: getEclipseEthereumWeEthsWarpConfig, }; export async function getWarpConfig( @@ -67,8 +73,10 @@ export async function getWarpConfig( envConfig: EnvironmentConfig, warpRouteId: string, ): Promise> { - const { core } = await getHyperlaneCore(envConfig.environment, multiProvider); - const routerConfig = core.getRouterConfig(envConfig.owners); + const routerConfig = await getRouterConfigsForAllVms( + envConfig, + multiProvider, + ); const warpConfigGetter = warpConfigGetterMap[warpRouteId]; if (!warpConfigGetter) { diff --git a/typescript/infra/scripts/agent-utils.ts b/typescript/infra/scripts/agent-utils.ts index 2d657b6f3..4fd4c8ec3 100644 --- a/typescript/infra/scripts/agent-utils.ts +++ b/typescript/infra/scripts/agent-utils.ts @@ -177,6 +177,10 @@ export function withWarpRouteId(args: Argv) { return args.describe('warpRouteId', 'warp route id').string('warpRouteId'); } +export function withWarpRouteIdRequired(args: Argv) { + return withWarpRouteId(args).demandOption('warpRouteId'); +} + export function withProtocol(args: Argv) { return args .describe('protocol', 'protocol type') diff --git a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts index 508aa28e6..1e6162462 100644 --- a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts @@ -172,9 +172,32 @@ const sealevelAccountsToTrack: ChainMap = { pubkey: new PublicKey('BH9VfgYaCWbwuupzsTfSy67yR4dwuCbXmFRrm6aAH2NQ'), walletName: 'WBTC/eclipsemainnet-ethereum/ata-payer', }, + // weETHs warp route ATA payer + { + pubkey: new PublicKey('F4Y6kHrq9qVnmkQhQibxh8nCU2quw5y25z7u8jSHMvtq'), + walletName: 'weETHs/eclipsemainnet-ethereum/ata-payer', + }, ], }; +// Kludge, ignore chains that are technically supportedChainNames +// because we want to continue to run agents, but we don't want to +// try to fund them because we no longer have an available IGP address +// to claim from. +// This was easier to do than modifying the funding config due to the types there. +// We can remove this once they're removed from supportedChainNames. +const chainsToIgnore = [ + 'alephzeroevm', + 'chiliz', + 'flow', + 'immutablezkevm', + 'metall2', + 'polynomial', + 'rari', + 'rootstock', + 'superposition', +]; + // Funds key addresses for multiple contexts from the deployer key of the context // specified via the `--context` flag. // The --contexts-and-roles flag is used to specify the contexts and the key roles @@ -332,7 +355,12 @@ class ContextFunder { ); this.igp = HyperlaneIgp.fromAddressesMap( - getEnvAddresses(this.environment), + { + ...getEnvAddresses(this.environment), + lumia: { + interchainGasPaymaster: '0x9024A3902B542C87a5C4A2b3e15d60B2f087Dc3E', + }, + }, multiProvider, ); this.keysToFundPerChain = objMap(roleKeysPerChain, (_chain, roleKeys) => { @@ -503,6 +531,11 @@ class ContextFunder { const chainKeyEntries = Object.entries(this.keysToFundPerChain); const promises = chainKeyEntries.map(async ([chain, keys]) => { let failureOccurred = false; + if (chainsToIgnore.includes(chain)) { + logger.warn({ chain }, 'Ignoring chain'); + return failureOccurred; + } + if (keys.length > 0) { if (!this.skipIgpClaim) { failureOccurred ||= await gracefullyHandleError( diff --git a/typescript/infra/scripts/generate-eclipse-usdt-warp-route-config.ts b/typescript/infra/scripts/generate-eclipse-usdt-warp-route-config.ts deleted file mode 100644 index 8b2be8eef..000000000 --- a/typescript/infra/scripts/generate-eclipse-usdt-warp-route-config.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { writeFileSync } from 'fs'; -import { stringify as yamlStringify } from 'yaml'; - -import { WarpRouteDeployConfigSchema } from '@hyperlane-xyz/sdk'; - -import { getEclipseEthereumUSDTWarpConfig } from '../config/environments/mainnet3/warp/configGetters/getEclipseEthereumUSDTWarpConfig.js'; - -import { getRouterConfig } from './warp-routes/utils.js'; - -async function main() { - const routerConfig = await getRouterConfig(); - const tokenConfig = await getEclipseEthereumUSDTWarpConfig(routerConfig); - const parsed = WarpRouteDeployConfigSchema.safeParse(tokenConfig); - - if (!parsed.success) { - console.dir(parsed.error.format(), { depth: null }); - return; - } - - writeFileSync( - 'eclipse-usdt-warp-route-config.yaml', - yamlStringify(parsed.data, null, 2), - ); -} - -main().catch(console.error).then(console.log); diff --git a/typescript/infra/scripts/generate-eclipse-wbtc-warp-route-config.ts b/typescript/infra/scripts/generate-eclipse-wbtc-warp-route-config.ts deleted file mode 100644 index dce156b23..000000000 --- a/typescript/infra/scripts/generate-eclipse-wbtc-warp-route-config.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { writeFileSync } from 'fs'; -import { stringify as yamlStringify } from 'yaml'; - -import { WarpRouteDeployConfigSchema } from '@hyperlane-xyz/sdk'; - -import { getEclipseEthereumWBTCWarpConfig } from '../config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.js'; - -import { getRouterConfig } from './warp-routes/utils.js'; - -async function main() { - const routerConfig = await getRouterConfig(); - const tokenConfig = await getEclipseEthereumWBTCWarpConfig(routerConfig); - const parsed = WarpRouteDeployConfigSchema.safeParse(tokenConfig); - - if (!parsed.success) { - console.dir(parsed.error.format(), { depth: null }); - return; - } - - writeFileSync( - 'eclipse-wbtc-warp-route-config.yaml', - yamlStringify(parsed.data, null, 2), - ); -} - -main().catch(console.error).then(console.log); diff --git a/typescript/infra/scripts/generate-renzo-ezeth-warp-route-config.ts b/typescript/infra/scripts/generate-renzo-ezeth-warp-route-config.ts deleted file mode 100644 index c8175b0e4..000000000 --- a/typescript/infra/scripts/generate-renzo-ezeth-warp-route-config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { writeFileSync } from 'fs'; -import { stringify as yamlStringify } from 'yaml'; - -import { WarpRouteDeployConfigSchema } from '@hyperlane-xyz/sdk'; - -import { getRenzoEZETHWarpConfig } from '../config/environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.js'; - -async function main() { - const tokenConfig = await getRenzoEZETHWarpConfig(); - const parsed = WarpRouteDeployConfigSchema.safeParse(tokenConfig); - - if (!parsed.success) { - console.dir(parsed.error.format(), { depth: null }); - return; - } - - writeFileSync( - 'renzo-ezeth-warp-route-config.yaml', - yamlStringify(parsed.data, null, 2), - ); -} - -main().catch(console.error).then(console.log); diff --git a/typescript/infra/scripts/generate-renzo-pzeth-warp-route-config.ts b/typescript/infra/scripts/generate-renzo-pzeth-warp-route-config.ts deleted file mode 100644 index b65cca5f0..000000000 --- a/typescript/infra/scripts/generate-renzo-pzeth-warp-route-config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { writeFileSync } from 'fs'; -import { stringify as yamlStringify } from 'yaml'; - -import { WarpRouteDeployConfigSchema } from '@hyperlane-xyz/sdk'; - -import { getRenzoPZETHWarpConfig } from '../config/environments/mainnet3/warp/configGetters/getRenzoPZETHWarpConfig.js'; - -async function main() { - const tokenConfig = await getRenzoPZETHWarpConfig(); - const parsed = WarpRouteDeployConfigSchema.safeParse(tokenConfig); - - if (!parsed.success) { - console.dir(parsed.error.format(), { depth: null }); - return; - } - - writeFileSync( - 'renzo-pzeth-warp-route-config.yaml', - yamlStringify(parsed.data, null, 2), - ); -} - -main().catch(console.error).then(console.log); diff --git a/typescript/infra/scripts/warp-routes/generate-warp-config.ts b/typescript/infra/scripts/warp-routes/generate-warp-config.ts new file mode 100644 index 000000000..61f1cd46f --- /dev/null +++ b/typescript/infra/scripts/warp-routes/generate-warp-config.ts @@ -0,0 +1,37 @@ +import { stringify as yamlStringify } from 'yaml'; + +import { WarpRouteDeployConfigSchema } from '@hyperlane-xyz/sdk'; + +import { getWarpConfig } from '../../config/warp.js'; +import { writeYamlAtPath } from '../../src/utils/utils.js'; +import { getArgs, withWarpRouteIdRequired } from '../agent-utils.js'; +import { getEnvironmentConfig, getHyperlaneCore } from '../core-utils.js'; + +async function main() { + const { warpRouteId, environment, outFile } = await withWarpRouteIdRequired( + getArgs(), + ) + .string('outFile') + .describe('outFile', 'The file to write the config to').argv; + + const { multiProvider } = await getHyperlaneCore(environment); + const envConfig = getEnvironmentConfig(environment); + + const warpConfig = await getWarpConfig(multiProvider, envConfig, warpRouteId); + const parsed = WarpRouteDeployConfigSchema.safeParse(warpConfig); + + if (!parsed.success) { + console.dir(parsed.error.format(), { depth: null }); + return; + } + + console.log('Warp config:'); + console.log(yamlStringify(parsed.data, null, 2)); + + if (outFile) { + console.log(`Writing config to ${outFile}`); + writeYamlAtPath(outFile, parsed.data); + } +} + +main().catch(console.error).then(console.log); diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index ad151393f..25b17abff 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -8,11 +8,13 @@ import { MultiProtocolProvider, MultiProvider, OwnableConfig, + RouterConfig, } from '@hyperlane-xyz/sdk'; -import { objKeys } from '@hyperlane-xyz/utils'; +import { mustGet, objKeys, objMap, objMerge } from '@hyperlane-xyz/utils'; import { Contexts } from '../../config/contexts.js'; import { environments } from '../../config/environments/index.js'; +import { getHyperlaneCore } from '../../scripts/core-utils.js'; import { CloudAgentKey } from '../agents/keys.js'; import { Role } from '../roles.js'; @@ -75,3 +77,30 @@ export function assertEnvironment(env: string): DeployEnvironment { } throw new Error(`Invalid environment ${env}, must be one of ${envNames}`); } + +// Gets the router configs for all chains in the environment. +// Relying solely on HyperlaneCore.getRouterConfig will result +// in missing any non-EVM chains -- here we merge the two. +export async function getRouterConfigsForAllVms( + envConfig: EnvironmentConfig, + multiProvider: MultiProvider, +): Promise> { + const { core, chainAddresses } = await getHyperlaneCore( + envConfig.environment, + multiProvider, + ); + const evmRouterConfig = core.getRouterConfig(envConfig.owners); + + const allRouterConfigs: ChainMap = objMap( + chainAddresses, + (chain, addresses) => { + return { + mailbox: mustGet(addresses, 'mailbox'), + owner: mustGet(envConfig.owners, chain).owner, + }; + }, + ); + + // Merge, giving evmRouterConfig precedence + return objMerge(allRouterConfigs, evmRouterConfig); +} diff --git a/typescript/infra/src/config/warp.ts b/typescript/infra/src/config/warp.ts index e8760a689..27f159079 100644 --- a/typescript/infra/src/config/warp.ts +++ b/typescript/infra/src/config/warp.ts @@ -9,6 +9,7 @@ export const tokens: ChainMap> = { deUSD: '0x15700B564Ca08D9439C58cA5053166E8317aa138', amphrETH: '0x5fD13359Ba15A84B76f7F87568309040176167cd', WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + weETHs: '0x917cee801a67f933f2e6b33fc0cd1ed2d5909d88', }, sei: { fastUSD: '0x37a4dD9CED2b19Cfe8FAC251cd727b5787E45269', diff --git a/typescript/utils/src/index.ts b/typescript/utils/src/index.ts index 97e931a83..0907631ca 100644 --- a/typescript/utils/src/index.ts +++ b/typescript/utils/src/index.ts @@ -112,6 +112,7 @@ export { invertKeysAndValues, isObjEmpty, isObject, + mustGet, objFilter, objKeys, objLength, diff --git a/typescript/utils/src/objects.test.ts b/typescript/utils/src/objects.test.ts index 3318c682e..6bd220585 100644 --- a/typescript/utils/src/objects.test.ts +++ b/typescript/utils/src/objects.test.ts @@ -9,6 +9,7 @@ import { invertKeysAndValues, isObjEmpty, isObject, + mustGet, objFilter, objKeys, objLength, @@ -340,4 +341,16 @@ describe('Object utilities', () => { }); }); }); + + describe('mustGet', () => { + it('should return the value if it exists', () => { + const obj = { a: 1, b: 2 }; + expect(mustGet(obj, 'a')).to.equal(1); + }); + + it('should throw an error if the value does not exist', () => { + const obj = { a: 1, b: 2 }; + expect(() => mustGet(obj, 'c')).to.Throw(); + }); + }); }); diff --git a/typescript/utils/src/objects.ts b/typescript/utils/src/objects.ts index 0c021587f..6446f9736 100644 --- a/typescript/utils/src/objects.ts +++ b/typescript/utils/src/objects.ts @@ -319,3 +319,11 @@ export function diffObjMerge( isInvalid: true, }; } + +export function mustGet(obj: Record, key: string): T { + const value = obj[key]; + if (!value) { + throw new Error(`Missing key ${key} in object ${JSON.stringify(obj)}`); + } + return value; +}