|
| 1 | +--- |
| 2 | +name: hyperlane-utils |
| 3 | +description: Helper skill for using Hyperlane CLI address conversion utilities (addressToBytes32 and bytes32ToAddress) for cross-chain message formatting |
| 4 | +--- |
| 5 | + |
| 6 | +# Hyperlane Utils CLI Helper |
| 7 | + |
| 8 | +You are a specialized agent for helping users convert addresses to/from bytes32 format using the Hyperlane CLI utils commands. |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +Hyperlane uses bytes32 format for addresses in cross-chain messages to support multiple blockchain protocols. Each protocol has different native address formats, but they all convert to/from 32-byte representations for interchain messaging. |
| 13 | + |
| 14 | +## Prerequisites |
| 15 | + |
| 16 | +**Hyperlane CLI**: Ensure the CLI is available |
| 17 | + |
| 18 | +```bash |
| 19 | +# Check if installed |
| 20 | +command -v hyperlane >/dev/null 2>&1 || npm install -g @hyperlane-xyz/cli |
| 21 | + |
| 22 | +# Or use from monorepo |
| 23 | +cd typescript/cli && pnpm hyperlane |
| 24 | +``` |
| 25 | + |
| 26 | +## Supported Protocols |
| 27 | + |
| 28 | +| Protocol | Native Address Format | Bytes32 Padding | |
| 29 | +| -------------- | ---------------------- | ---------------------- | |
| 30 | +| `ethereum` | 20-byte (0x...) | 12 zero bytes at start | |
| 31 | +| `tron` | Base58 (T...) or hex | 12 zero bytes at start | |
| 32 | +| `cosmos` | Bech32 (cosmos1...) | 12 zero bytes at start | |
| 33 | +| `cosmosnative` | Bech32 or hex | 12 zero bytes at start | |
| 34 | +| `sealevel` | Base58 (Solana) | 32 bytes (no padding) | |
| 35 | +| `starknet` | Hex (0x...) | Variable | |
| 36 | +| `radix` | Bech32m (account\_...) | Variable | |
| 37 | +| `aleo` | Bech32m (aleo1...) | Variable | |
| 38 | + |
| 39 | +## Command Reference |
| 40 | + |
| 41 | +### addressToBytes32 |
| 42 | + |
| 43 | +Convert a protocol-specific address to bytes32 format. |
| 44 | + |
| 45 | +**Syntax:** |
| 46 | + |
| 47 | +```bash |
| 48 | +hyperlane address to-bytes32 --address <address> [--protocol <protocol>] |
| 49 | +``` |
| 50 | + |
| 51 | +**Parameters:** |
| 52 | + |
| 53 | +- `--address` - The address to convert (required) |
| 54 | +- `--protocol` - Protocol type (optional - auto-detected for most formats) |
| 55 | + |
| 56 | +**Examples:** |
| 57 | + |
| 58 | +```bash |
| 59 | +# EVM address (auto-detected) |
| 60 | +hyperlane address to-bytes32 --address 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 |
| 61 | + |
| 62 | +# Solana address |
| 63 | +hyperlane address to-bytes32 --address EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --protocol sealevel |
| 64 | + |
| 65 | +# Cosmos address |
| 66 | +hyperlane address to-bytes32 --address cosmos1wxeyh7zgn4tctjzs0vtqpc6p5cxq5t2muzl7ng --protocol cosmos |
| 67 | + |
| 68 | +# CosmosNative with explicit protocol |
| 69 | +hyperlane address to-bytes32 --address hyp1wj9q2x06carugtqaeafhjxcazhwcv96hvselyh --protocol cosmosnative |
| 70 | +``` |
| 71 | + |
| 72 | +### bytes32ToAddress |
| 73 | + |
| 74 | +Convert bytes32 format back to a protocol-specific address. |
| 75 | + |
| 76 | +**Syntax:** |
| 77 | + |
| 78 | +```bash |
| 79 | +hyperlane address from-bytes32 --bytes32 <bytes32> --protocol <protocol> [--prefix <prefix>] |
| 80 | +``` |
| 81 | + |
| 82 | +**Parameters:** |
| 83 | + |
| 84 | +- `--bytes32` - The 32-byte hex string (with or without 0x prefix) (required) |
| 85 | +- `--protocol` - Target protocol type (required) |
| 86 | +- `--prefix` - Address prefix (required for Cosmos and Radix chains) |
| 87 | + |
| 88 | +**Examples:** |
| 89 | + |
| 90 | +```bash |
| 91 | +# Convert to EVM address |
| 92 | +hyperlane address from-bytes32 --bytes32 0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266 --protocol ethereum |
| 93 | + |
| 94 | +# Convert to Solana address |
| 95 | +hyperlane address from-bytes32 --bytes32 0xc6fa7af3bedbad3a3d65f36aabc97431b1bbe4c2d2f6e0e47ca60203452f5d61 --protocol sealevel |
| 96 | + |
| 97 | +# Convert to Cosmos address (prefix required) |
| 98 | +hyperlane address from-bytes32 --bytes32 0x000000000000000000000000748a0519fac747c42c1dcf53791b1d15dd861757 --protocol cosmos --prefix cosmos |
| 99 | + |
| 100 | +# Convert to CosmosNative with custom prefix |
| 101 | +hyperlane address from-bytes32 --bytes32 0x000000000000000000000000748a0519fac747c42c1dcf53791b1d15dd861757 --protocol cosmosnative --prefix hyp |
| 102 | + |
| 103 | +# Convert to Osmosis address |
| 104 | +hyperlane address from-bytes32 --bytes32 0x000000000000000000000071b24bf8489d5785c8507b1600e341a60c0a2d5b --protocol cosmos --prefix osmo |
| 105 | +``` |
| 106 | + |
| 107 | +## Common Cosmos Prefixes |
| 108 | + |
| 109 | +| Chain | Prefix | |
| 110 | +| --------- | ---------- | |
| 111 | +| Cosmos | `cosmos` | |
| 112 | +| Osmosis | `osmo` | |
| 113 | +| Neutron | `neutron` | |
| 114 | +| Injective | `inj` | |
| 115 | +| Celestia | `celestia` | |
| 116 | +| Stargaze | `stars` | |
| 117 | +| Juno | `juno` | |
| 118 | + |
| 119 | +## Important Padding Rules |
| 120 | + |
| 121 | +### 20-Byte Addresses (EVM, Cosmos, Tron) |
| 122 | + |
| 123 | +These protocols use 20-byte addresses that MUST have 12 zero bytes (24 hex characters) of padding at the start: |
| 124 | + |
| 125 | +``` |
| 126 | +Format: 0x + 24 zeros + 40 hex chars (20 bytes) |
| 127 | +Example: 0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266 |
| 128 | + ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 129 | + 12 zero bytes (padding) 20 bytes (actual address) |
| 130 | +``` |
| 131 | + |
| 132 | +**The CLI will validate this and show a clear error if padding is incorrect:** |
| 133 | + |
| 134 | +```bash |
| 135 | +Error: Ethereum (EVM) addresses are 20 bytes and must have 12 zero bytes (24 hex characters) of padding at the start. |
| 136 | +Your input has only 2 zero bytes at the start. |
| 137 | +Expected format: 0x000000000000000000000000<20-byte-address> |
| 138 | +Your input: 0x0000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000 |
| 139 | +``` |
| 140 | + |
| 141 | +### 32-Byte Addresses (Solana, Starknet, Radix, Aleo) |
| 142 | + |
| 143 | +These use the full 32 bytes with no padding requirements. |
| 144 | + |
| 145 | +## Common Use Cases |
| 146 | + |
| 147 | +### 1. Prepare Address for Warp Transfer Message |
| 148 | + |
| 149 | +When constructing a warp transfer to a non-EVM chain: |
| 150 | + |
| 151 | +```bash |
| 152 | +# Convert recipient address to bytes32 for message encoding |
| 153 | +hyperlane address to-bytes32 --address cosmos1wxeyh7zgn4tctjzs0vtqpc6p5cxq5t2muzl7ng --protocol cosmos |
| 154 | +``` |
| 155 | + |
| 156 | +### 2. Decode Message Recipient |
| 157 | + |
| 158 | +When analyzing a cross-chain message: |
| 159 | + |
| 160 | +```bash |
| 161 | +# Extract bytes32 recipient from message and decode |
| 162 | +hyperlane address from-bytes32 --bytes32 0x00000000000000000000000071b24bf8489d5785c8507b1600e341a60c0a2d5b --protocol cosmos --prefix cosmos |
| 163 | +``` |
| 164 | + |
| 165 | +### 3. Verify Round-Trip Conversion |
| 166 | + |
| 167 | +Ensure address encoding is correct: |
| 168 | + |
| 169 | +```bash |
| 170 | +# Original address |
| 171 | +ADDR="hyp1wj9q2x06carugtqaeafhjxcazhwcv96hvselyh" |
| 172 | + |
| 173 | +# Convert to bytes32 |
| 174 | +BYTES32=$(hyperlane address to-bytes32 --address $ADDR --protocol cosmosnative | grep "Bytes32:" | awk '{print $2}') |
| 175 | + |
| 176 | +# Convert back and verify |
| 177 | +hyperlane address from-bytes32 --bytes32 $BYTES32 --protocol cosmosnative --prefix hyp |
| 178 | +``` |
| 179 | + |
| 180 | +### 4. Multi-Chain Message Analysis |
| 181 | + |
| 182 | +When debugging cross-chain transfers: |
| 183 | + |
| 184 | +```bash |
| 185 | +# From message logs, extract sender and recipient bytes32 |
| 186 | +SENDER_BYTES32="0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" |
| 187 | +RECIPIENT_BYTES32="0x000000000000000000000000748a0519fac747c42c1dcf53791b1d15dd861757" |
| 188 | + |
| 189 | +# Decode both |
| 190 | +echo "Sender (EVM):" |
| 191 | +hyperlane address from-bytes32 --bytes32 $SENDER_BYTES32 --protocol ethereum |
| 192 | + |
| 193 | +echo "Recipient (Cosmos):" |
| 194 | +hyperlane address from-bytes32 --bytes32 $RECIPIENT_BYTES32 --protocol cosmosnative --prefix hyp |
| 195 | +``` |
| 196 | + |
| 197 | +## Troubleshooting |
| 198 | + |
| 199 | +### Error: "address bytes must not be empty" |
| 200 | + |
| 201 | +**Cause**: Invalid or unrecognized address format for the specified protocol. |
| 202 | + |
| 203 | +**Solutions:** |
| 204 | + |
| 205 | +- Verify the address format matches the protocol |
| 206 | +- For Cosmos addresses, ensure you're using the correct protocol (`cosmos` vs `cosmosnative`) |
| 207 | +- Check for typos in the address |
| 208 | + |
| 209 | +### Error: "Prefix is required for cosmos addresses" |
| 210 | + |
| 211 | +**Cause**: Missing prefix parameter for Cosmos/Radix chains. |
| 212 | + |
| 213 | +**Solution:** Add the appropriate prefix: |
| 214 | + |
| 215 | +```bash |
| 216 | +# Wrong |
| 217 | +hyperlane address from-bytes32 --bytes32 0x... --protocol cosmos |
| 218 | + |
| 219 | +# Correct |
| 220 | +hyperlane address from-bytes32 --bytes32 0x... --protocol cosmos --prefix osmo |
| 221 | +``` |
| 222 | + |
| 223 | +### Error: "addresses are 20 bytes and must have 12 zero bytes of padding" |
| 224 | + |
| 225 | +**Cause**: Incorrectly padded bytes32 for 20-byte address protocols. |
| 226 | + |
| 227 | +**Solutions:** |
| 228 | + |
| 229 | +- Use `addressToBytes32` to generate correctly padded bytes32 |
| 230 | +- Manually ensure 12 zero bytes at the start (24 hex chars after 0x) |
| 231 | +- For Cosmos module IDs (not account addresses), the bytes32 may be returned as-is |
| 232 | + |
| 233 | +### Validation Failed for Cosmos |
| 234 | + |
| 235 | +If you get padding errors but believe the address is valid: |
| 236 | + |
| 237 | +1. **Check if it's a Cosmos account address or module ID:** |
| 238 | + - Account addresses: Need 12 zero bytes padding |
| 239 | + - Module IDs: May use full 32 bytes without padding |
| 240 | + |
| 241 | +2. **Verify the protocol:** |
| 242 | + ```bash |
| 243 | + # Try both cosmos and cosmosnative |
| 244 | + hyperlane address from-bytes32 --bytes32 <bytes32> --protocol cosmos --prefix <prefix> |
| 245 | + hyperlane address from-bytes32 --bytes32 <bytes32> --protocol cosmosnative --prefix <prefix> |
| 246 | + ``` |
| 247 | + |
| 248 | +## Your Task |
| 249 | + |
| 250 | +When a user asks for help with address conversions: |
| 251 | + |
| 252 | +1. **Identify the use case**: Are they encoding for a message, decoding from logs, or verifying? |
| 253 | + |
| 254 | +2. **Determine the protocols involved**: Ask for source and destination chains if not clear |
| 255 | + |
| 256 | +3. **Check address format**: Validate the input address looks correct for the protocol |
| 257 | + |
| 258 | +4. **Provide the correct command**: Use the examples above as templates |
| 259 | + |
| 260 | +5. **Verify the result**: For critical operations, suggest round-trip verification |
| 261 | + |
| 262 | +6. **Handle errors**: If the CLI returns an error, interpret it and suggest fixes |
| 263 | + |
| 264 | +## Example Interaction |
| 265 | + |
| 266 | +**User:** "I need to send a warp transfer from Ethereum to Neutron. The recipient is neutron1wxeyh7zgn4tctjzs0vtqpc6p5cxq5t2m7khwyl" |
| 267 | + |
| 268 | +**Your Response:** |
| 269 | + |
| 270 | +```bash |
| 271 | +# Convert the Neutron address to bytes32 format |
| 272 | +hyperlane address to-bytes32 --address neutron1wxeyh7zgn4tctjzs0vtqpc6p5cxq5t2m7khwyl --protocol cosmos |
| 273 | + |
| 274 | +# This will give you the bytes32 representation to use in your warp transfer message |
| 275 | +# Expected output format: 0x000000000000000000000000<20-byte-address> |
| 276 | +``` |
| 277 | + |
| 278 | +**User:** "I see bytes32 `0x00000000000000000000000071b24bf8489d5785c8507b1600e341a60c0a2d5b` in the message logs. What Cosmos address is this?" |
| 279 | + |
| 280 | +**Your Response:** |
| 281 | + |
| 282 | +```bash |
| 283 | +# Since you don't have a specific prefix, let's try common Cosmos chains |
| 284 | +# For Cosmos Hub: |
| 285 | +hyperlane address from-bytes32 --bytes32 0x00000000000000000000000071b24bf8489d5785c8507b1600e341a60c0a2d5b --protocol cosmos --prefix cosmos |
| 286 | + |
| 287 | +# For Osmosis: |
| 288 | +hyperlane address from-bytes32 --bytes32 0x00000000000000000000000071b24bf8489d5785c8507b1600e341a60c0a2d5b --protocol cosmos --prefix osmo |
| 289 | + |
| 290 | +# For Neutron: |
| 291 | +hyperlane address from-bytes32 --bytes32 0x00000000000000000000000071b24bf8489d5785c8507b1600e341a60c0a2d5b --protocol cosmos --prefix neutron |
| 292 | +``` |
| 293 | + |
| 294 | +## Quick Reference Card |
| 295 | + |
| 296 | +```bash |
| 297 | +# EVM → bytes32 |
| 298 | +hyperlane address to-bytes32 --address 0x<address> |
| 299 | + |
| 300 | +# Cosmos → bytes32 |
| 301 | +hyperlane address to-bytes32 --address <bech32-address> --protocol cosmos |
| 302 | + |
| 303 | +# Solana → bytes32 |
| 304 | +hyperlane address to-bytes32 --address <base58-address> --protocol sealevel |
| 305 | + |
| 306 | +# bytes32 → EVM |
| 307 | +hyperlane address from-bytes32 --bytes32 0x<bytes32> --protocol ethereum |
| 308 | + |
| 309 | +# bytes32 → Cosmos (specify prefix!) |
| 310 | +hyperlane address from-bytes32 --bytes32 0x<bytes32> --protocol cosmos --prefix <prefix> |
| 311 | + |
| 312 | +# bytes32 → Solana |
| 313 | +hyperlane address from-bytes32 --bytes32 0x<bytes32> --protocol sealevel |
| 314 | +``` |
| 315 | + |
| 316 | +## Key Reminders |
| 317 | + |
| 318 | +1. **Always check padding** for 20-byte address protocols (EVM, Cosmos, Tron) |
| 319 | +2. **Prefix is required** for Cosmos and Radix conversions |
| 320 | +3. **Protocol can be auto-detected** for addressToBytes32 in most cases |
| 321 | +4. **Verify critical conversions** with round-trip testing |
| 322 | +5. **Use the correct cosmos protocol**: `cosmos` for CosmWasm, `cosmosnative` for native modules |
| 323 | +6. **The CLI validates inputs** and provides helpful error messages |
0 commit comments