IntroductionCosmos GMPSolidity UtilitiesSandbox
InterchainTokenServiceInterchainTokenFactoryTokenManagerAxelarGateway AxelarGasServiceAxelarExecutableAxelarJS SDK
Bug Bounty
Crosschain Message FlowaxlUSDCSecurity OverviewInterchain Transaction DurationEVM Contract Governance

Pay Gas

An application that wants Axelar to automatically execute contract calls on the destination chain must do the following:

  1. Estimate the gasLimit that the contract call will require in the executable contract on the destination chain.
  2. EVM L2 chains: For execution of GMP calls where the destination chain is an EVM L2 chain, it is important to note that all L2 chains have an extra cost of posting the executed transaction back to the L1 chain.
  3. Get the value of the source gas fee in the desired gas-payment token on the destination chain by calling estimateGasFee().
    • estimateGasFee() will estimate the fee amount (including, if needed, any additional fees for L2 chains as mentioned above) in the destination token, convert it to the same price in the source token, and return that converted amount.
  4. Pay the AxelarGasService smart contract on the source chain with payNativeGasForContractCall() or payNativeGasForContractCallWithToken().

The AxelarGasService contract provides methods to pay gas for both callContract() and callContractWithToken(). Gas fees are paid in the native token of the source chain.

Prerequisites

The AxelarJS SDK must be installed.

Pay gas fees to an AxelarGasService contract

The following is an example of how gas fees can be paid to an AxelarGasService contract. Assume that SimpleTransferContract is a smart contract deployed on a source chain:

contract SimpleTransferContract {
  ...
  function sendToMany(
      string memory destinationChain,
      string memory destinationContractAddress,
      address[] calldata destinationAddresses,
      string memory symbol,
      uint256 amount
  ) external payable {
      address tokenAddress = gateway.tokenAddresses(symbol);
      IERC20(tokenAddress).transferFrom(msg.sender, address(this), amount);
      IERC20(tokenAddress).approve(address(gateway), amount);
      bytes memory payload = abi.encode(destinationAddresses);

      // msg.value is the gas amount paid to the contract.
      if(msg.value > 0) {
          // Pay the gas fee.
          gasReceiver.payNativeGasForContractCallWithToken{value: msg.value}(
              address(this),
              destinationChain,
              destinationContractAddress,
              payload,
              symbol,
              amount,
              msg.sender
          );
      }
      gateway.callContractWithToken(destinationChain, destinationContractAddress, payload, symbol, amount);
  }
}

msg.value is the gas amount paid to the AxelarGasService contract. Thus, the value returned from a call to estimateGasFee() must be passed to msg.value on the front end:

await contract.sendToMany("moonbeam", "0x...", ["0x.."], "USDC", 1, {
  value: sourceGasFee, // Value returned from calling estimateGasFee()
});

After sending a transaction out, Axelar’s Gas Service will do the following:

  • Monitor AxelarGasReceiver for receipt of payment and get the amount paid as amountPaid.
  • Match the gas paid to the correct contract calls.
  • Submit the transaction to the Axelar network for confirmation.
  • Execute the contract call with the gasLimit specified by the application.

Alternative gas payment methods

See the AxelarGasService interface for alternative gas payment methods.

When passing in arguments for these methods:

  • sender must match the address that calls callContract() or callContractWithToken() on the AxelarGateway. If the AxelarGasReceiver is called by the same contract that will call the Gateway, specify address(this) as sender.
  • refundAddress is the address that will eventually be able to receive the excess amount paid for gas. Refunds are made on the source chain.

payNativeGasForContractCall()

For payNativeGasForContractCall(), the following must match the arguments of a contractCall() on the AxelarGateway:

  • destinationChain
  • destinationAddress
  • payload

msg.value specifies the amount of funds received.

payNativeGasForContractCallWithToken()

For payNativeGasForContractCallWithToken(), the following must match the arguments of a contractCallWithToken() on the AxelarGateway:

  • destinationChain
  • destinationAddress
  • payload
  • symbol
  • amount

msg.value specifies the amount of funds received.

Edit this page