UNPKG

@hyperlane-xyz/cli

Version:

A command-line utility for common Hyperlane operations

113 lines 5.2 kB
import { stringify as yamlStringify } from 'yaml'; import { HyperlaneCore, HyperlaneRelayer, MultiProtocolProvider, ProviderType, TokenAmount, WarpCore, } from '@hyperlane-xyz/sdk'; import { parseWarpRouteMessage, timeout } from '@hyperlane-xyz/utils'; import { EXPLORER_URL, MINIMUM_TEST_SEND_GAS } from '../consts.js'; import { runPreflightChecksForChains } from '../deploy/utils.js'; import { log, logBlue, logGreen, logRed } from '../logger.js'; import { indentYamlOrJson } from '../utils/files.js'; import { stubMerkleTreeConfig } from '../utils/relay.js'; import { runTokenSelectionStep } from '../utils/tokens.js'; export const WarpSendLogs = { SUCCESS: 'Transfer was self-relayed!', }; export async function sendTestTransfer({ context, warpCoreConfig, chains, amount, recipient, timeoutSec, skipWaitForDelivery, selfRelay, }) { await runPreflightChecksForChains({ context, chains, minGas: MINIMUM_TEST_SEND_GAS, }); for (let i = 0; i < chains.length; i++) { const origin = chains[i]; const destination = chains[i + 1]; if (destination) { logBlue(`Sending a message from ${origin} to ${destination}`); await timeout(executeDelivery({ context, origin, destination, warpCoreConfig, amount, recipient, skipWaitForDelivery, selfRelay, }), timeoutSec * 1000, 'Timed out waiting for messages to be delivered'); } } } async function executeDelivery({ context, origin, destination, warpCoreConfig, amount, recipient, skipWaitForDelivery, selfRelay, }) { const { multiProvider, registry } = context; const signer = multiProvider.getSigner(origin); const recipientSigner = multiProvider.getSigner(destination); const recipientAddress = await recipientSigner.getAddress(); const signerAddress = await signer.getAddress(); recipient ||= recipientAddress; const chainAddresses = await registry.getAddresses(); const core = HyperlaneCore.fromAddressesMap(chainAddresses, multiProvider); const provider = multiProvider.getProvider(origin); const connectedSigner = signer.connect(provider); const warpCore = WarpCore.FromConfig(MultiProtocolProvider.fromMultiProvider(multiProvider), warpCoreConfig); let token; const tokensForRoute = warpCore.getTokensForRoute(origin, destination); if (tokensForRoute.length === 0) { logRed(`No Warp Routes found from ${origin} to ${destination}`); throw new Error('Error finding warp route'); } else if (tokensForRoute.length === 1) { token = tokensForRoute[0]; } else { logBlue(`Please select a token from the Warp config`); const routerAddress = await runTokenSelectionStep(tokensForRoute); token = warpCore.findToken(origin, routerAddress); } const errors = await warpCore.validateTransfer({ originTokenAmount: token.amount(amount), destination, recipient, sender: signerAddress, }); if (errors) { logRed('Error validating transfer', JSON.stringify(errors)); throw new Error('Error validating transfer'); } // TODO: override hook address for self-relay const transferTxs = await warpCore.getTransferRemoteTxs({ originTokenAmount: new TokenAmount(amount, token), destination, sender: signerAddress, recipient, }); const txReceipts = []; for (const tx of transferTxs) { if (tx.type === ProviderType.EthersV5) { const txResponse = await connectedSigner.sendTransaction(tx.transaction); const txReceipt = await multiProvider.handleTx(origin, txResponse); txReceipts.push(txReceipt); } } const transferTxReceipt = txReceipts[txReceipts.length - 1]; const messageIndex = 0; const message = HyperlaneCore.getDispatchedMessages(transferTxReceipt)[messageIndex]; const parsed = parseWarpRouteMessage(message.parsed.body); logBlue(`Sent transfer from sender (${signerAddress}) on ${origin} to recipient (${recipient}) on ${destination}.`); logBlue(`Message ID: ${message.id}`); logBlue(`Explorer Link: ${EXPLORER_URL}/message/${message.id}`); log(`Message:\n${indentYamlOrJson(yamlStringify(message, null, 2), 4)}`); log(`Body:\n${indentYamlOrJson(yamlStringify(parsed, null, 2), 4)}`); if (selfRelay) { const relayer = new HyperlaneRelayer({ core }); const hookAddress = await core.getSenderHookAddress(message); const merkleAddress = chainAddresses[origin].merkleTreeHook; stubMerkleTreeConfig(relayer, origin, hookAddress, merkleAddress); log('Attempting self-relay of transfer...'); await relayer.relayMessage(transferTxReceipt, messageIndex, message); logGreen(WarpSendLogs.SUCCESS); return; } if (skipWaitForDelivery) return; // Max wait 10 minutes await core.waitForMessageProcessed(transferTxReceipt, 10000, 60); logGreen(`Transfer sent to ${destination} chain!`); } //# sourceMappingURL=transfer.js.map