원클릭으로
hyperlane-message-utils
// Encode and decode raw Hyperlane messages to/from packed hex bytes using the CLI. Use when you need to construct a message for testing, inspect a raw message from logs or a transaction, or decode a warp transfer body.
// Encode and decode raw Hyperlane messages to/from packed hex bytes using the CLI. Use when you need to construct a message for testing, inspect a raw message from logs or a transaction, or decode a warp transfer body.
Check token balances for each leg of a warp route. Shows collateral locked (for collateral/native legs) and total circulating supply (for synthetic legs). Use when you want to inspect the current state of a warp route's liquidity.
First step of deploying a new warp route (steps 1–9). Reads a Linear ticket to extract token details and chain configuration, looks up mailbox addresses from the local registry, generates the deploy.yaml, runs the deploy, and optionally runs a send test. Follow up with /warp-deploy-update-owners.
Post-deployment ownership transfer and registry PR for a warp route. Transfers ownership from the temporary deployer address to real owners, adds CoinGecko ID, commits, and opens a registry PR. Run after warp-deploy-init completes deployment.
Debug validator checkpoint inconsistencies where some validators are behind others. Use when alerts mention "checkpoint inconsistency", "validators behind", or "inconsistent latest checkpoints", or when asked to debug validator sets, investigate validator delays, or troubleshoot metadata fetch failures for a chain. Defaults to default_ism app context if not specified.
Debug RPC provider health issues for a chain. Use when alerts mention RPC failures, high latency, stale blocks, or provider errors. Diagnoses the issue and recommends fixes.
Apply RPC URL changes for a chain. Use after /debug-rpc-provider has diagnosed the issue and recommended new URLs. The user invoking this skill is the confirmation gate.
| name | hyperlane-message-utils |
| description | Encode and decode raw Hyperlane messages to/from packed hex bytes using the CLI. Use when you need to construct a message for testing, inspect a raw message from logs or a transaction, or decode a warp transfer body. |
You are a specialized agent for encoding and decoding raw Hyperlane messages using the hyperlane message CLI commands.
A Hyperlane message is a packed binary blob with this layout:
| Field | Type | Bytes |
|-------------|---------|-------|
| version | uint8 | 1 |
| nonce | uint32 | 4 |
| origin | uint32 | 4 |
| sender | bytes32 | 32 |
| destination | uint32 | 4 |
| recipient | bytes32 | 32 |
| body | bytes | var |
Total fixed header: 77 bytes. Body is variable length.
The message ID is keccak256 of the packed bytes.
# From monorepo
cd typescript/cli && pnpm hyperlane
# Or if globally installed
hyperlane
hyperlane message decodeParse a packed message hex string into its fields.
Syntax:
hyperlane message decode --bytes <hex>
Parameters:
--bytes / -b — packed message hex (with or without 0x) (required)Output:
bytes32 (protocol-address) when chain is in registryExample:
hyperlane message decode --bytes 0x030000000100000001000000000000000000000000BEA3Da2758523301415C609ac4ADEBb638F0eadf00000038000000000000000000000000BEA3Da2758523301415C609ac4ADEBb638F0eadf...
Example output:
Message ID: 0x11c59b50...
Version: 3
Nonce: 1
Origin: 1 (ethereum)
Sender: 0x000...cb527f... (0xBEA3Da2758523301415C609ac4ADEBb638F0eadf)
Destination: 56 (bsc)
Recipient: 0x000...cb527f... (0xBEA3Da2758523301415C609ac4ADEBb638F0eadf)
Body (possible warp transfer):
Recipient: 0x000...cb527f... (0xBEA3Da2758523301415C609ac4ADEBb638F0eadf)
Amount: 2000
hyperlane message encodePack message fields into a hex-encoded message and compute its ID.
Syntax:
hyperlane message encode \
--nonce <n> \
--origin <chain-or-domain> \
--sender <address> \
--destination <chain-or-domain> \
--recipient <address> \
[--msg-version <n>] \
[--body <hex> | --warpRecipient <address> --warpAmount <amount>]
Parameters:
| Flag | Required | Description |
|---|---|---|
--nonce / -n | yes | Message nonce (uint32) |
--origin / -o | yes | Origin chain name (ethereum) or domain ID (1) |
--sender | yes | Sender address — auto-converted to bytes32 |
--destination / -d | yes | Destination chain name (bsc) or domain ID (56) |
--recipient | yes | Recipient address — auto-converted to bytes32 |
--msg-version | no | Message version (default: 3) |
--body | no | Raw message body as hex (default: 0x) |
--warpRecipient | no | Warp transfer recipient — builds body automatically |
--warpAmount | no | Warp transfer token amount (required with --warpRecipient) |
--body and --warpRecipient/--warpAmount are mutually exclusive — passing both is a CLI error. --warpRecipient and --warpAmount must always be used together.
Output:
Example — plain message:
hyperlane message encode \
--nonce 1 \
--origin ethereum \
--sender 0xBEA3Da2758523301415C609ac4ADEBb638F0eadf \
--destination bsc \
--recipient 0xBEA3Da2758523301415C609ac4ADEBb638F0eadf
Example — warp transfer:
hyperlane message encode \
--nonce 1 \
--origin ethereum \
--sender 0xBEA3Da2758523301415C609ac4ADEBb638F0eadf \
--destination bsc \
--recipient 0xBEA3Da2758523301415C609ac4ADEBb638F0eadf \
--warpRecipient 0xBEA3Da2758523301415C609ac4ADEBb638F0eadf \
--warpAmount 1000000000000000000
Example output:
Bytes: 0x03000000010000000100000000...
Message ID: 0x11c59b50...
Version: 3
Nonce: 1
Origin: 1 (ethereum)
Sender: 0x000000000000000000000000cb527f...
Destination: 56 (bsc)
Recipient: 0x000000000000000000000000cb527f...
Body: 0x000000000000000000000000cb527f...0000000000000000000000000000000000000000000000000de0b6b3a7640000
When --warpRecipient is used, the body is constructed as:
bytes32 recipient (32 bytes)
uint256 amount (32 bytes)
─────────────────────────────
Total: 64 bytes (128 hex chars + 0x prefix)
The decode command does a best-effort detection: if the body is exactly 64 bytes it attempts to decode and display the recipient and amount fields, labelled as "possible warp transfer" since not all 64-byte bodies are warp transfers.
Copy the calldata from Mailbox.process(metadata, message) and decode the message argument:
hyperlane message decode --bytes 0x<message-hex-from-calldata>
MSG=$(hyperlane message encode \
--nonce 0 \
--origin ethereum \
--sender 0xDeadBeef... \
--destination arbitrum \
--recipient 0xDeadBeef... \
--body 0xdeadbeef \
| grep "^Bytes:" | awk '{print $2}')
echo "Message bytes: $MSG"
hyperlane message encode \
--nonce 42 \
--origin 1 \
--sender 0x... \
--destination 42161 \
--recipient 0x... \
| grep "Message ID:"
BYTES=$(hyperlane message encode \
--nonce 1 --origin ethereum --sender 0xABC... \
--destination bsc --recipient 0xDEF... \
| grep "^Bytes:" | awk '{print $2}')
hyperlane message decode --bytes $BYTES
When a user asks to encode or decode a Hyperlane message:
Decode: Run hyperlane message decode --bytes <hex> and interpret the output. If the body looks like a warp transfer, explain the recipient and amount.
Encode: Collect the required fields (nonce, origin, sender, destination, recipient). Ask if they want a warp transfer body or a custom body. Run the command and return the packed bytes and message ID.
Chain names vs domain IDs: Both are accepted for --origin and --destination. Prefer chain names when known (e.g. ethereum, bsc, arbitrum, optimism, polygon).
Address format: Sender and recipient are auto-converted to bytes32 — pass the native address directly. No need to pre-convert.