The on-chain API for receiving cross-chain messages
Receive messages from other chains by implementing the handle() method in your cross-chain application.
Interface
The handle method passes a cross-chain message to the application.
_origin is a Nomad domain. List of domains here
_nonce is unique for each message within a (origin domain, destination domain) tuple. Many apps won't need to use this field, but it can be used to ensure uniqueness of a message.
_sender is the address that sent the message on the origin domain
_message contains the contents of the cross-chain message
/* * @notice Receive a message from a sender on the origin domain * @param _origin Domain of the origin chain * @param _nonce Unique nonce for the (origin, destination) tuple. * @param _sender Address of sender on origin chain as bytes32 * @param _message Raw bytes content of message */functionhandle(uint32_origin,uint32_nonce,bytes32_sender,bytesmemory_message) external;
Hello World
import {TypeCasts} from"@nomad-xyz/contracts-core/libs/TypeCasts.sol";contract HelloWorld {// emitted when a Hello message is received eventHello(uint32 origin, address sender, string memory message);/* * @notice Receive a Hello message from any sender :) * @param _origin Domain of the origin chain * @param _sender Address of sender on origin chain as bytes32 * @param _message Raw bytes content of message */functionhandle(uint32_origin,uint32_nonce,bytes32_sender,bytesmemory_message ) onlyReplica {address _sendr = TypeCasts.bytes32ToAddress(_sender);// emit the message so off-chain friends can see itemitHello(_origin, _sendr, _message); }}
Example Usage
contract PingPong {// registry of opponents on each chainmapping(uint32=>bytes32) public opponents;// emitted when a Ping volley is receivedeventPing(uint32 domain, bytes32 opponent, uint256 volleyNumber);// emitted when a Pong volley is receivedeventPong(uint32 domain, bytes32 opponent, uint256 volleyNumber);/** * @notice Start a PingPong match with the destination chain * by serving the ball. * @param _destination The domain to initiate the match with */functionhandle(uint32_origin,uint32_nonce,bytes32_sender,bytesmemory_message ) onlyReplica {// validate the message comes from a known opponentrequire(opponents[_origin] == _sender,"not a registered opponent!");// decode the message contents using abi.decodebool _ping;uint256 _volley; (_ping, _volley) = abi.decode(_message, (bool,uint256));// emit an event for your off-chain spectatorsif (ping) {emitPing(_origin, _sender, _volley); } else {emitPong(_origin, _sender, _volley); }// send a PingPong message back to your opponent!bytesmemory _message = abi.encode(!_ping, _volley +1);// dispatch your message across chains home.dispatch(_origin, _sender, _message); }}