SimpleMessageTest.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title IXTalkBeacon Interface
 * @dev Interface for the XTalkBeacon contract.
 * It defines the functions that this contract will interact with.
 */
// =================================================================================================
// ================================= XTalk Infrastructure Interface ================================
// =================================================================================================
interface IXTalkBeacon {
    /**
     * @dev Registers a message to be sent to a destination chain.
     * @param _destinationChainId The chain ID of the destination chain.
     * @param _destinationAddress The address of the contract on the destination chain.
     * @param _messageData The data to be sent.
     * @param _messageType The type of the message.
     * @param _messageNonce The nonce for this message from the sender.
     */
    function registerMessage(uint32 _destinationChainId, bytes32 _destinationAddress, bytes memory _messageData, uint32 _messageType, uint256 _messageNonce) external;

    /**
     * @dev Gets the next nonce for a sender.
     * @param _sender The address of the sender.
     * @return The next nonce.
     */
    function getSenderRegistrationNextNonce(address _sender) external view returns (uint256);

    /**
     * @dev Generates a unique message ID.
     * This can be used to track the message.
     */
    function generateMessageId(uint32 _destinationChainId, bytes32 _destinationAddress, bytes memory _messageData, uint32 _messageType, uint256 _messageNonce) external view returns (bytes32);
}

/**
 * @title SimpleMessageTest Contract
 * @dev This contract is a simple example of how to use the XTalkBeacon to send and receive cross-chain messages.
 * It allows invoking a message to a destination chain and handles received messages.
 */
contract SimpleMessageTest {

    // =================================================================================================
    // ================================= XTalk Infrastructure Setup ====================================
    // =================================================================================================
    address public immutable xtalkBeaconAddress;


    // =================================================================================================
    // ===================================== User-Defined Logic ========================================
    // =================================================================================================

    // Struct to store details of a received message.
    struct Message {
        bytes32 messageId;
        address sourceInvokerAddress;
        uint32 sourceChainId;
        uint32 messageType;
        bytes messageData;
    }

    // Mapping from messageId to the received Message struct.
    mapping(bytes32 => Message) public receivedMessages;

    /**
     * @dev Emitted when a message is received from another chain.
     */
    event MessageReceived(bytes32 indexed messageId, address sourceInvokerAddress, uint32 sourceChainId, uint32 messageType, bytes messageData);

    // =================================================================================================
    // ================================= XTalk Infrastructure Setup ====================================
    // =================================================================================================
    
    /**
     * @dev Constructor to set the address of the XTalkBeacon contract.
     * @param _beaconAddress The address of the XTalkBeacon contract.
     */
    constructor(address _beaconAddress) {
        require(_beaconAddress != address(0), "Invalid beacon address");
        xtalkBeaconAddress = _beaconAddress;
    }

    // =================================================================================================
    // ===================================== User-Defined Logic ========================================
    // =================================================================================================

    /**
     * @dev Invokes a message to be sent to a destination chain via the XTalkBeacon.
     * @param _destinationChainId The chain ID of the destination chain.
     * @param _destinationAddress The address of the contract on the destination chain.
     * @param _message The string message to be sent.
     */
    function invokeMessage(uint32 _destinationChainId, bytes32 _destinationAddress, string memory _message) public {
        // ----------------- User-Defined part -----------------
        uint32 messageType = 1; // Example message type
        bytes memory messageData = abi.encode(_message);
        // -----------------------------------------------------

        // ----------------- XTalk Infrastructure part -----------------
        uint256 nonce = IXTalkBeacon(xtalkBeaconAddress).getSenderRegistrationNextNonce(address(this));
        IXTalkBeacon(xtalkBeaconAddress).registerMessage(_destinationChainId, _destinationAddress, messageData, messageType, nonce);
        // ---------------------------------------------------------

    }

    // =================================================================================================
    // ================================= XTalk Infrastructure Callback =================================
    // =================================================================================================

    /**
     * @dev This function is called by the XTalkBeacon when a cross-chain message is received for this contract.
     * The function name and signature must be `_xtalkMessageReceived(bytes32,address,uint32,uint32,bytes)`.
     * @param _messageId The unique ID of the message.
     * @param _sourceInvokerAddress The address of the invoker on the source chain.
     * @param _sourceChainId The chain ID of the source chain.
     * @param _messageType The type of the message.
     * @param _messageData The actual message data.
     */
    function _xtalkMessageReceived(bytes32 _messageId, address _sourceInvokerAddress, uint32 _sourceChainId, uint32 _messageType, bytes memory _messageData) public {
        // ----------------- XTalk Infrastructure part -----------------
        require(msg.sender == xtalkBeaconAddress, "Caller is not the XTalkBeacon");
        // ---------------------------------------------------------

        // ----------------- User-Defined part -----------------
        receivedMessages[_messageId] = Message({
            messageId: _messageId,
            sourceInvokerAddress: _sourceInvokerAddress,
            sourceChainId: _sourceChainId,
            messageType: _messageType,
            messageData: _messageData
        });

        emit MessageReceived(_messageId, _sourceInvokerAddress, _sourceChainId, _messageType, _messageData);
        // -----------------------------------------------------
    }
}

Last updated