axelar

Installation
SKILL.md

Axelar

Axelar is a cross-chain communication network that connects blockchains through a proof-of-stake validator set. It provides two core primitives: General Message Passing (GMP) for sending arbitrary contract calls across chains, and Interchain Token Service (ITS) for deploying and managing tokens that exist natively on multiple chains. Contracts receive cross-chain messages by inheriting AxelarExecutable and implementing the _execute() callback, which the Axelar Gateway invokes after validator consensus. Gas for destination-chain execution must be prepaid on the source chain via AxelarGasService.

What You Probably Got Wrong

AI agents frequently confuse Axelar's chain naming, gas payment model, and ITS vs. Gateway token transfers. These corrections are critical.

  • Chain identifiers are STRINGS, not numeric IDs. Axelar uses human-readable chain names like "ethereum", "arbitrum", "base". These are NOT EVM chain IDs (1, 42161, 8453) and NOT LayerZero eids. Passing a numeric chain ID will silently fail or route to a nonexistent chain. Always use the exact string from Axelar's chain registry.
  • Gas MUST be paid upfront on the source chain. Unlike protocols with automatic relayers, Axelar requires you to call AxelarGasService.payNativeGasForContractCall() (or the WithToken variant) BEFORE calling gateway.callContract(). If you skip gas payment, the message is submitted to the network but never executed on the destination. There is no retry mechanism -- you must send a new transaction.
  • _execute() is the callback, NOT execute(). Your contract inherits AxelarExecutable and overrides _execute(string calldata sourceChain, string calldata sourceAddress, bytes calldata payload). The public execute() function is called by the Axelar relayer and routes to your _execute() after Gateway validation. Never override execute() directly.
  • You MUST validate sourceChain and sourceAddress in _execute(). The Gateway validates that the message came through Axelar, but it does NOT validate the sender's identity. Anyone can send a GMP message. Your _execute() must check that sourceChain and sourceAddress match your trusted remote contract. Without this, any contract on any chain can trigger your _execute().
  • ITS is NOT the same as Gateway token transfers. gateway.callContractWithToken() moves Axelar-wrapped tokens (axlUSDC, axlWETH). ITS (InterchainTokenService) deploys and manages tokens that are canonical on every chain -- burn on source, mint on destination with the same token address derivation. Use ITS for new token deployments; use Gateway for existing Axelar-wrapped assets.
  • sourceAddress is a STRING, not an address type. Cross-chain messages come from non-EVM chains too. The sourceAddress parameter in _execute() is a string, which is the lowercase hex representation of the sender address. To compare with an EVM address, convert: keccak256(bytes(sourceAddress)) == keccak256(bytes(Strings.toHexString(trustedAddress))).
  • ITS token IDs are deterministic, derived from the deployer and salt. The tokenId for an ITS-deployed token is keccak256(abi.encode(address(deployer), salt)). If you deploy from different addresses or with different salts on different chains, the tokens will NOT be linked. Always use the same deployer and salt on every chain.
  • callContractWithToken requires the token to be an Axelar-supported asset. You cannot send arbitrary ERC-20s through callContractWithToken. Only tokens registered in the Axelar Gateway (like axlUSDC, axlWETH, WBTC, etc.) are supported. For arbitrary tokens, use ITS or bridge first.
  • Gas refunds go to the refundAddress, not msg.sender. When paying gas via AxelarGasService, excess gas is refunded to the refundAddress parameter. If you pass address(0) or a contract that cannot receive ETH, the refund is lost.

Quick Start

Installs
1
First Seen
Aug 4, 2026
axelar — justaname-id/cryptoskills