UNPKG

@hyperlane-xyz/sdk

Version:

The official SDK for the Hyperlane Network

115 lines 5.87 kB
import { ethers } from 'ethers'; import { InterchainAccountRouter__factory } from '@hyperlane-xyz/core'; import { addressToBytes32, bytes32ToAddress, difference, rootLogger, } from '@hyperlane-xyz/utils'; import { serializeContracts } from '../contracts/contracts.js'; import { EvmIcaRouterReader } from '../ica/EvmIcaReader.js'; import { InterchainAccountDeployer } from '../middleware/account/InterchainAccountDeployer.js'; import { HyperlaneModule, } from './AbstractHyperlaneModule.js'; export class EvmIcaModule extends HyperlaneModule { multiProvider; logger = rootLogger.child({ module: 'EvmIcaModule' }); icaRouterReader; domainId; chainId; constructor(multiProvider, args) { super(args); this.multiProvider = multiProvider; this.icaRouterReader = new EvmIcaRouterReader(multiProvider, this.args.chain); this.domainId = multiProvider.getDomainId(args.chain); this.chainId = multiProvider.getEvmChainId(args.chain); } async read() { return this.icaRouterReader.deriveConfig(this.args.addresses.interchainAccountRouter); } async update(expectedConfig) { const actualConfig = await this.read(); const transactions = [ ...(await this.updateRemoteRoutersEnrollment(actualConfig.remoteRouters, expectedConfig.remoteRouters)), ]; return transactions; } async updateRemoteRoutersEnrollment(actualConfig, expectedConfig = {}) { const transactions = [ ...(await this.getEnrollRemoteRoutersTxs(actualConfig, expectedConfig)), ...(await this.getUnenrollRemoteRoutersTxs(actualConfig, expectedConfig)), ]; return transactions; } async getEnrollRemoteRoutersTxs(actualConfig, expectedConfig = {}) { if (!actualConfig) { return []; } const transactions = []; const routesToEnroll = Array.from(difference(new Set(Object.keys(expectedConfig)), new Set(Object.keys(actualConfig)))); if (routesToEnroll.length === 0) { return transactions; } const domainsToEnroll = []; const remoteDomainIca = []; const remoteIsm = []; for (const domainId of routesToEnroll) { domainsToEnroll.push(domainId); remoteDomainIca.push(addressToBytes32(expectedConfig[domainId].address)); remoteIsm.push(ethers.utils.hexZeroPad('0x', 32)); } const remoteTransactions = domainsToEnroll.map((domainId) => ({ annotation: `Enrolling InterchainAccountRouter on domain ${this.domainId} on InterchainAccountRouter at ${expectedConfig[domainId].address} on domain ${domainId}`, chainId: this.multiProvider.getEvmChainId(domainId), to: expectedConfig[domainId].address, data: InterchainAccountRouter__factory.createInterface().encodeFunctionData('enrollRemoteRouter(uint32,bytes32)', [ this.domainId, addressToBytes32(this.args.addresses.interchainAccountRouter), ]), })); transactions.push({ annotation: `Enrolling remote InterchainAccountRouters on domain ${this.domainId}`, chainId: this.chainId, to: this.args.addresses.interchainAccountRouter, data: InterchainAccountRouter__factory.createInterface().encodeFunctionData('enrollRemoteRouterAndIsms(uint32[],bytes32[],bytes32[])', [domainsToEnroll, remoteDomainIca, remoteIsm]), }); transactions.push(...remoteTransactions); return transactions; } async getUnenrollRemoteRoutersTxs(actualConfig, expectedConfig = {}) { if (!actualConfig) { return []; } const transactions = []; const routesToUnenroll = Array.from(difference(new Set(Object.keys(actualConfig)), new Set(Object.keys(expectedConfig)))); if (routesToUnenroll.length === 0) { return transactions; } transactions.push({ annotation: `Unenrolling remote InterchainAccountRouters from chain ${this.domainId}`, chainId: this.chainId, to: this.args.addresses.interchainAccountRouter, data: InterchainAccountRouter__factory.createInterface().encodeFunctionData('unenrollRemoteRouters(uint32[])', [routesToUnenroll]), }); const remoteTransactions = routesToUnenroll.map((domainId) => ({ annotation: `Removing InterchainAccountRouter on domain ${this.domainId} from InterchainAccountRouter at ${actualConfig[domainId].address} on domain ${domainId}`, chainId: this.multiProvider.getEvmChainId(domainId), to: bytes32ToAddress(actualConfig[domainId].address), data: InterchainAccountRouter__factory.createInterface().encodeFunctionData('unenrollRemoteRouter(uint32)', [this.domainId]), })); transactions.push(...remoteTransactions); return transactions; } /** * Creates a new EvmIcaModule instance by deploying an ICA with an ICA ISM. * * @param chain - The chain on which to deploy the ICA. * @param config - The configuration for the ICA. * @param multiProvider - The MultiProvider instance to use for deployment. * @returns {Promise<EvmIcaModule>} - A new EvmIcaModule instance. */ static async create({ chain, config, multiProvider, contractVerifier, }) { const interchainAccountDeployer = new InterchainAccountDeployer(multiProvider, contractVerifier); const deployedContracts = await interchainAccountDeployer.deployContracts(multiProvider.getChainName(chain), config); return new EvmIcaModule(multiProvider, { addresses: serializeContracts(deployedContracts), chain, config, }); } } //# sourceMappingURL=EvmIcaModule.js.map