Example: Cross-Chain Messaging Demo
Sending a simple string across chains.
In the Telepathy Messager Demo, we demonstrate how to concatenate together a string message that includes:
- arbitrary text
- the sender's balance

The full source code for the contracts used in this demo can be found at the Messenger Demo Github in contracts/src/CrossChainMailbox.sol. This contains the source contract
CrossChainMailer
and destination contract CrossChainMailbox
.This contract needs a reference to the Telepathy Router, so we pass in that information to the constructor:
constructor(address _telepathyRouter) {
telepathyRouter = ITelepathyRouter(_telepathyRouter);
}
The entrypoint for this contract is the
sendMail
function, which a user (EOA) calls to send a message across chains.function sendMail(
uint32 _destinationChainId,
address _destinationMailbox,
bytes memory _message
) external payable
{
if (msg.value < fee) {
revert InsufficientFee(msg.value, fee);
}
string memory data = StringHelper.formatMessage(
_message, msg.sender.balance, ENSHelper.getName(msg.sender)
);
telepathyRouter.send(_destinationChainId, _destinationMailbox, bytes(data));
}
The user calling this function specifies which destination chain they would like to send their message to (with the parameter
_destinationChainId
) as well as the _destinationMailbox
contract address (a CrossChainMailbox
deployed on the destination chain). The body of
sendMail
uses the StringHelper
library to piece together the information of message + balance + ENS name in one formatted string. Then we use send
to send that actual message to our CrossChainMailbox
through Telepathy.contract CrossChainMailbox is TelepathyHandler
This gives convenient functionality for ensuring that ONLY the Telepathy Router can call this function, and gives a function to override to receive messages. To set up this contract a TelepathyHandler, pass in the Router's address in the constructor:
constructor(address _telepathyRouter) TelepathyHandler(_telepathyRouter) {}
function handleTelepathyImpl(uint32 _sourceChainId, address _sourceAddress, bytes memory _message)
internal
override
{
messages.push(string(_message));
emit MessageReceived(_sourceChainId, _sourceAddress, string(_message));
}
In this case, we store the message and emit an event.
Last modified 8mo ago