cross-chain-message-transfer
Transfer messages between different blockchain networks using the Hyperlane protocol. Specify origin and destination chains, recipient address, and message content to enable cross-chain communication.
Instructions
Transfers a cross-chain message.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| origin | Yes | Origin chain | |
| destination | Yes | Destination chain | |
| recipient | Yes | Recipient address | |
| messageBody | Yes | Message body |
Implementation Reference
- src/index.ts:192-268 (handler)The primary handler function for the 'cross-chain-message-transfer' tool. It sets up chain metadata, multi-provider with signers, logs progress, calls the msgTransfer helper to dispatch the message, and returns the transaction hash and message ID.async ({ origin, destination, recipient, messageBody }) => { server.server.sendLoggingMessage({ level: 'info', data: `Starting cross-chain message transfer... Parameters: origin=${origin}, destination=${destination}, recipient=${recipient}, messageBody=${messageBody}`, }); server.server.sendLoggingMessage({ level: 'info', data: `Using signer with address: ${signer.address}`, }); server.server.sendLoggingMessage({ level: 'info', data: 'Initializing Github Registry...', }); registry.listRegistryContent(); const originChainMetadata = (await registry.getChainMetadata(origin))!; const destinationChainMetadata = (await registry.getChainMetadata( destination ))!; const chainMetadata: ChainMap<ChainMetadata> = { [origin]: originChainMetadata, [destination]: destinationChainMetadata, }; server.server.sendLoggingMessage({ level: 'info', data: `Chain metadata fetched: ${JSON.stringify(chainMetadata, null, 2)}`, }); const multiProvider = new MultiProvider(chainMetadata, { signers: { [origin]: signer, [destination]: signer, }, }); server.server.sendLoggingMessage({ level: 'info', data: `MultiProvider initialized with chains: ${JSON.stringify( multiProvider, null, 2 )}`, }); server.server.sendLoggingMessage({ level: 'info', data: 'Initiating message transfer...', }); const [dispatchTx, message] = await msgTransfer({ origin, destination, recipient, messageBody: ethers.utils.formatBytes32String(messageBody), registry, multiProvider, }); server.server.sendLoggingMessage({ level: 'info', data: 'Message transfer completed successfully', }); return { content: [ { type: 'text', text: `Message dispatched successfully. Transaction Hash: ${dispatchTx.transactionHash}.\n Message ID for the dispatched message: ${message.id}`, }, ], }; }
- src/index.ts:182-191 (schema)Zod input schema defining parameters for the tool: origin chain, destination chain, recipient address (validated as EVM address), and message body.{ origin: z.string().describe('Origin chain'), destination: z.string().describe('Destination chain'), recipient: z .string() .length(42) .regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid EVM address') .describe('Recipient address'), messageBody: z.string().describe('Message body'), },
- src/index.ts:179-269 (registration)Registration of the tool with McpServer using server.tool(), including name, description, input schema, and handler function.server.tool( 'cross-chain-message-transfer', 'Transfers a cross-chain message.', { origin: z.string().describe('Origin chain'), destination: z.string().describe('Destination chain'), recipient: z .string() .length(42) .regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid EVM address') .describe('Recipient address'), messageBody: z.string().describe('Message body'), }, async ({ origin, destination, recipient, messageBody }) => { server.server.sendLoggingMessage({ level: 'info', data: `Starting cross-chain message transfer... Parameters: origin=${origin}, destination=${destination}, recipient=${recipient}, messageBody=${messageBody}`, }); server.server.sendLoggingMessage({ level: 'info', data: `Using signer with address: ${signer.address}`, }); server.server.sendLoggingMessage({ level: 'info', data: 'Initializing Github Registry...', }); registry.listRegistryContent(); const originChainMetadata = (await registry.getChainMetadata(origin))!; const destinationChainMetadata = (await registry.getChainMetadata( destination ))!; const chainMetadata: ChainMap<ChainMetadata> = { [origin]: originChainMetadata, [destination]: destinationChainMetadata, }; server.server.sendLoggingMessage({ level: 'info', data: `Chain metadata fetched: ${JSON.stringify(chainMetadata, null, 2)}`, }); const multiProvider = new MultiProvider(chainMetadata, { signers: { [origin]: signer, [destination]: signer, }, }); server.server.sendLoggingMessage({ level: 'info', data: `MultiProvider initialized with chains: ${JSON.stringify( multiProvider, null, 2 )}`, }); server.server.sendLoggingMessage({ level: 'info', data: 'Initiating message transfer...', }); const [dispatchTx, message] = await msgTransfer({ origin, destination, recipient, messageBody: ethers.utils.formatBytes32String(messageBody), registry, multiProvider, }); server.server.sendLoggingMessage({ level: 'info', data: 'Message transfer completed successfully', }); return { content: [ { type: 'text', text: `Message dispatched successfully. Transaction Hash: ${dispatchTx.transactionHash}.\n Message ID for the dispatched message: ${message.id}`, }, ], }; } );
- src/msgTransfer.ts:11-46 (helper)Helper function that creates HyperlaneCore from registry addresses and multi-provider, then dispatches the cross-chain message using core.sendMessage, returning the transaction receipt and dispatched message.export async function msgTransfer({ origin, destination, recipient, messageBody, registry, multiProvider, }: { origin: ChainName; destination: ChainName; recipient: string; messageBody: string; registry: BaseRegistry; multiProvider: MultiProvider; // log: (params: any) => Promise<void>; }): Promise<[TransactionReceipt, DispatchedMessage]> { const updatedChainAddresses = { [origin]: (await registry.getAddresses())[origin], [destination]: (await registry.getAddresses())[destination], }; const core = HyperlaneCore.fromAddressesMap( updatedChainAddresses, multiProvider ); const formattedRecipient = addressToBytes32(recipient); const { dispatchTx, message } = await core.sendMessage( origin, destination, formattedRecipient, messageBody ); return [dispatchTx, message]; }