Send messages to other chains by calling the dispatch() method on the Home contract.
Interface
The dispatch method is simple. Just specify the destination chain, the message recipient, and the message you want to send!
_destination is a Nomad domain. List of domains here
_recipient is the address that will receive the message on the destination chain. The _recipient must be set up to receive Nomad messages by implementing handle.
_message contains the contents of your cross-chain message
/* * @notice Dispatch the message to the destination domain & recipient * @param _destination Domain of destination chain * @param _recipient Address of recipient on destination chain as bytes32 * @param _message Raw bytes content of message */functiondispatch(uint32_destination,bytes32_recipient,bytesmemory_message ) external {// message is sent to recipient address on destination chain }
Hello World
import {TypeCasts} from"@nomad-xyz/contracts-core/libs/TypeCasts.sol";contract HelloWorld {// address of the Nomad Home contractimmutableaddresspublic home;/* * @notice Send a Hello message to another chain :) * @param _destination Domain of destination chain * @param _recipient Address of recipient on destination chain */functionhello(uint32_destination,address_recipient) {// craft your hello messagebytesmemory _message ="hello world >:~)";// cast recipient to bytes32bytes32 _recip = TypeCasts.addressToBytes32(_recipient);// dispatch your message across chains! home.dispatch(_destination, _recipient, _message); }}
Example Usage
contract PingPong {// registry of opponents on each chainmapping(uint32=>bytes32) public opponents;/** * @notice Start a PingPong match with the destination chain * by serving the ball. * @param _destination The domain to initiate the match with */functionserve(uint32_destination) external {// serve to your opponent on the destination domainbytes32 _recipient = opponents[_destination];// Create a message for the first volley.// the PingPong match always begins with a Pingbool _ping =true;// the volley count always starts at 0uint256 _volley =0;// encode the PingPong message using abi.encodebytesmemory _message = abi.encode(_ping, _volley);// dispatch your message across chains! home.dispatch(_destination, _recipient, _message); }}
Chain IDs change during intentional consensus splits such as the merge to Eth2.0; additionally, not all chains even have a Chain ID! We created Nomad domains to have a clean standard for chains supported by Nomad which didn't suffer from these challenges.
Why are recipients bytes32 instead of address?
We use bytes32 instead of address so that, in the future, messages will be compatible with other chain VMs like Cosmos and Polkadot. In the EVM, addresses are 20 bytes long, but most other chains have 32 byte addresses. Worry not - we have a TypeCasts.sol library to help convert between these types easily.