Skip to Content
DocumentationAnalog GMPDevelopers' GuideGetting Started

Getting Started

This quick start guide outlines how to connect your contract with Analog Gateway contracts to enable cross-chain messaging. On the origin chain, the source contract sends encoded data via the submitMessage function. The payload is then routed to the destination chain, where the destination contract receives and processes it using the onGmpReceived function.

Prerequisites

  1. Basic knowledge of Solidity.
  2. Network IDs for source and destination chains. See Gateway Addresses & Network IDs for more details.
  3. An EVM wallet set up and funded with enough tokens for the chains you’ll be working with. For testnet tokens, use the following faucet links:

Procedure

Follow these steps to send a GMP request from chain A to chain B.

Step 1: Implement Receiver Contract

All destination contracts must implement IGmpReceiver:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IGmpReceiver} from "./IGmpReceiver.sol"; contract CrossChainReceiver is IGmpReceiver { // Store the Gateway address for security checks address public immutable gateway; // Events to track received messages event MessageReceived(bytes32 id, uint128 sourceNetwork, bytes32 source, bytes payload); constructor(address _gateway) { gateway = _gateway; } function onGmpReceived( bytes32 id, uint128 sourceNetwork, bytes32 source, uint64 nonce, bytes calldata payload ) external payable override returns (bytes32) { // Security check: only the Gateway can call this function require(msg.sender == gateway, "Unauthorized sender"); // Process the received message emit MessageReceived(id, sourceNetwork, source, payload); // Implement your cross-chain logic here // ... // Return a result (can be used for verification or additional logic) return keccak256(abi.encodePacked(id, block.timestamp)); } }

Step 2: Send Cross-Chain Messages

Use the Gateway to send messages between chains:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IGateway} from "./IGateway.sol"; contract CrossChainSender { // Gateway contract reference IGateway public immutable gateway; // Events to track sent messages event MessageSent(bytes32 messageId, address destination, uint16 destinationNetwork); constructor(address _gateway) { gateway = IGateway(_gateway); } function sendCrossChainMessage( address destinationContract, uint16 destinationNetwork, bytes calldata payload ) external payable returns (bytes32) { // Estimate the cost of sending the message uint256 gasCost = gateway.estimateMessageCost( destinationNetwork, payload.length, 100000 // Gas limit for execution on destination chain ); // Ensure enough funds are provided require(msg.value >= gasCost, "Insufficient funds for cross-chain message"); // Send the message bytes32 messageId = gateway.submitMessage{value: msg.value}( destinationContract, destinationNetwork, 100000, // Gas limit payload ); emit MessageSent(messageId, destinationContract, destinationNetwork); return messageId; } }

Gas Management:

  • When sending messages, always ensure you provide enough gas for execution on the destination chain. Use estimateMessageCost to estimate costs:
gateway.estimateMessageCost(networkId, messageSize, gasLimit)
  • Use destinationNetwork from Gateway's networkId()

Step 3: Make a GMP request

  • Deploy your source and destination chain contracts using the gateway addresses for the specified networks. You can find these addresses on the Gateway Addresses & Network ID page.
  • Estimate the gas cost by calling estimateMessageCost on the gateway by passing in the appropriate networkid, messageSize, and gasLimit.
  • Make the GMP call using the submitMessage method. Here's an example:
gateway.submitMessage{value: msg.value}(dest_address, dest_network, GMP_GAS_LIMIT, payload);

When making the GMP call using the submitMessage method, ensure that the gas fee is included as a value in the request. If the value provided is less than the estimated message cost, the transaction will fail with the error: "execution reverted: insufficient tx value."

  • Upon finalizing the transaction on the source chain, a Task ID will be created on the Timechain. You can track the status of your task on the Timechain Explorer . For more details, see Track GMP Messages.
  • Once your task is completed, your destination chain contract state will be updated.

Congratulations! You just sent your first GMP request using Analog GMP. Next, try tracking the status of the GMP call after you send it.

Next Steps

Try tracking the status of the GMP call after you send it.

Build your first cross-chain DApp using Analog GMP.

See how Foundry can help you set up your cross-chain project.