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 theWithTokenvariant) BEFORE callinggateway.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, NOTexecute(). Your contract inheritsAxelarExecutableand overrides_execute(string calldata sourceChain, string calldata sourceAddress, bytes calldata payload). The publicexecute()function is called by the Axelar relayer and routes to your_execute()after Gateway validation. Never overrideexecute()directly.- You MUST validate
sourceChainandsourceAddressin_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 thatsourceChainandsourceAddressmatch 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. sourceAddressis a STRING, not an address type. Cross-chain messages come from non-EVM chains too. ThesourceAddressparameter in_execute()is astring, 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
tokenIdfor an ITS-deployed token iskeccak256(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. callContractWithTokenrequires the token to be an Axelar-supported asset. You cannot send arbitrary ERC-20s throughcallContractWithToken. 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, notmsg.sender. When paying gas viaAxelarGasService, excess gas is refunded to therefundAddressparameter. If you passaddress(0)or a contract that cannot receive ETH, the refund is lost.