UNPKG

@hyperlane-xyz/sdk

Version:

The official SDK for the Hyperlane Network

77 lines 3.99 kB
import { assert } from '@hyperlane-xyz/utils'; import { buildInterchainAccountApp, } from '../../../middleware/account/InterchainAccount.js'; import { TxSubmitterType } from './TxSubmitterTypes.js'; import { getSubmitter } from './submitterBuilderGetter.js'; export class EvmIcaTxSubmitter { config; submitter; multiProvider; interchainAccountApp; txSubmitterType = TxSubmitterType.INTERCHAIN_ACCOUNT; constructor(config, submitter, multiProvider, interchainAccountApp) { this.config = config; this.submitter = submitter; this.multiProvider = multiProvider; this.interchainAccountApp = interchainAccountApp; } static async fromConfig(config, multiProvider, coreAddressesByChain) { const interchainAccountRouterAddress = config.originInterchainAccountRouter ?? coreAddressesByChain[config.chain].interchainAccountRouter; assert(interchainAccountRouterAddress, `Origin chain InterchainAccountRouter address not supplied and none found in the registry metadata for chain ${config.chain}`); const internalSubmitter = await getSubmitter(multiProvider, config.internalSubmitter, coreAddressesByChain); const interchainAccountApp = await buildInterchainAccountApp(multiProvider, config.chain, { owner: config.owner, origin: config.chain, localRouter: interchainAccountRouterAddress, ismOverride: config.interchainSecurityModule, }, coreAddressesByChain); return new EvmIcaTxSubmitter({ owner: config.owner, chain: config.chain, destinationChain: config.destinationChain, originInterchainAccountRouter: interchainAccountRouterAddress, }, internalSubmitter, multiProvider, interchainAccountApp); } async submit(...txs) { if (txs.length === 0) { return []; } const transactionChains = new Set(txs.map((tx) => tx.chainId)); if (transactionChains.size !== 1) { throw new Error('ICA transactions should have all the same destination chain'); } const [chainId] = transactionChains.values(); if (!chainId) { throw new Error('Destination domain for ICA transactions should be defined'); } const { chainId: destinationEvmChainId, domainId: destinationDomainId } = this.multiProvider.getChainMetadata(this.config.destinationChain); // On the EVM chains the id and domain id might be different so we match either against the // EVM chain id or the Hyperlane domain id if (chainId !== destinationDomainId && chainId !== destinationEvmChainId) { throw new Error(`Destination chain mismatch. Expected EVM chain id ${destinationEvmChainId} or Hyperlane domain id ${destinationDomainId} but received ${chainId}.`); } const innerCalls = txs.map(({ to, data, chainId, value }) => { assert(chainId, 'Invalid PopulatedTransaction: "chainId" is required'); assert(to, 'Invalid PopulatedTransaction: "to" is required'); assert(data, 'Invalid PopulatedTransaction: "data" is required'); return { data, to, value: value?.toString() }; }); const icaTx = await this.interchainAccountApp.getCallRemote({ chain: this.config.chain, destination: this.config.destinationChain, innerCalls, config: { origin: this.config.chain, owner: this.config.owner, ismOverride: this.config.interchainSecurityModule, routerOverride: this.config.destinationInterchainAccountRouter, localRouter: this.config.originInterchainAccountRouter, }, }); return this.submitter.submit({ chainId: this.multiProvider.getDomainId(this.config.chain), ...icaTx, }); } } //# sourceMappingURL=IcaTxSubmitter.js.map