# Cross-Chain Messaging

With Telepathy, you can send messages from any supported **source chain** that uses Ethereum consensus to any **destination chain** that can run the Telepathy light client (currently implemented in EVM).&#x20;

To use Telepathy to send a message, you need a *sending* contract on the source chain and a *destination* contract on the destination chain. We'll go through the process of writing both while integrating with the [Telepathy Router](https://docs.telepathy.xyz/telepathy-protocol/contracts#router).

The data contained in a cross-chain message can be anything that fits your needs:

* simple informational strings
* complex data structures
* function calls

This arbitrary message passing is the basis for any kind of cross-chain application you may want to develop.

## Sending Messages

1\) To send a message to another chain from your *sending* contract, you will need to add the following [ITelepathyRouter](https://github.com/succinctlabs/telepathy-contracts/blob/fe9566b7837487dfb6d39e708a2c0bfb7c52ceaf/src/amb/interfaces/ITelepathy.sol#L19) interface:

```solidity
interface ITelepathyRouter {
    function send(uint32 destinationChainId, address destinationAddress, bytes calldata data)
        external
        returns (bytes32);
}
```

2\) Store the address of the [Router](https://docs.telepathy.xyz/telepathy-protocol/contracts#router) inside your contract. See the full [contract address list](https://docs.telepathy.xyz/resources/contract-addresses) to determine which address to use for a given chain. For example, on Mainnet the address is `0x41EA857C32c8Cb42EEFa00AF67862eCFf4eB795a` so we store this in our sending contract as

```solidity
address TELEPATHY_ROUTER = 0x41EA857C32c8Cb42EEFa00AF67862eCFf4eB795a;
ITelepathyRouter router = ITelepathyRouter(TELEPATHY_ROUTER);
```

3\) Send a message using your *destination* contract address and chainId. To find the chainId number that corresponds to a destination chain, refer to this [website](https://chainlist.org/). For example, the chainId for Gnosis chain is`100`:

<pre class="language-solidity"><code class="lang-solidity">contract TelepathySenderExample {
    address TELEPATHY_ROUTER = 0x41EA857C32c8Cb42EEFa00AF67862eCFf4eB795a;
    ITelepathyRouter router = ITelepathyRouter(TELEPATHY_ROUTER);

<strong>    function sendMessageWithTelepathy() external {
</strong>        uint16 destinationChainId = 100;
        // A contract I deployed on Gnosis Chain
        address destinationAddress = 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990;
<strong>        router.send(
</strong>            destinationChainId,
            destinationAddress,
            bytes("Hello world!")
        );
<strong>    }
</strong>}
</code></pre>

## Receiving Messages

1\) Store the address of the Telepathy Router inside your *destination* contract. Once again, refer to the [contract address list](https://docs.telepathy.xyz/resources/contract-addresses).

```solidity
address TELEPATHY_ROUTER = 0x41EA857C32c8Cb42EEFa00AF67862eCFf4eB795a;
ITelepathyRouter router = ITelepathyRouter(TELEPATHY_ROUTER);
```

2\) Implement the `handleTelepathy` function from the [ITelepathyHandler](https://github.com/succinctlabs/telepathy-contracts/blob/fe9566b7837487dfb6d39e708a2c0bfb7c52ceaf/src/amb/interfaces/ITelepathy.sol#L66) interface on your *destination* contract:

```solidity
contract TelepathyRecipientExample is ITelepathyHandler {
    address TELEPATHY_ROUTER = 0x41EA857C32c8Cb42EEFa00AF67862eCFf4eB795a;
    ITelepathyRouter router = ITelepathyRouter(TELEPATHY_ROUTER);
    // The contract I deployed on Ethereum
    address sourceChainContract = 0x71C7656EC7ab88b098defB751B7401B5f6d8976F;
    
    event SentMessage(uint32 srcChain, address srcSender, bytes message);
 
    function handleTelepathy(
        uint32 _sourceChainId, address _senderAddress, bytes memory _data
    ) external {
        require(msg.sender == address(router));
        require(_senderAddress == sourceChainContract);

        emit SentMessage(_sourceChainId, _senderAddress, _data);

        return ITelepathyHandler.handleTelepathy.selector;
    }
}
```

{% hint style="danger" %}
You must require that `msg.sender` is the Telepathy Router, or else any contract can call `handleTelepathy`.
{% endhint %}

{% hint style="danger" %}
You must require that the `_senderAddress` is the address of the sending contract on the source chain. Otherwise any contract on the source chain can send messages to your contract on the destination chain.
{% endhint %}

{% hint style="danger" %}
You must return `ITelepathyHandler.handleTelepathy.selector`to have our contracts correctly record your message execution status.
{% endhint %}

If you would like to not worry about the above checks, use our abstract contract [TelepathyHandler](https://github.com/succinctlabs/telepathy-contracts/blob/fe9566b7837487dfb6d39e708a2c0bfb7c52ceaf/src/amb/interfaces/TelepathyHandler.sol#L5). You can refer to an example of using the abstract contract [here](https://github.com/succinctlabs/telepathy-contracts/blob/main/examples/example-counter/ExampleCounter.sol#L22).

### Relaying Messages

The Succinct team currently runs a relayer that relays all messages sent on any of the supported source chains with 200k gas for message execution. If your project or team is looking for SLAs around relaying or looking to change these gas parameters, please fill out [this form](https://airtable.com/shrKT6HrHi2oDcmrf) to discuss options with the Succinct team.

## FAQ

**Do these need to be separate contracts?**

The *sending* and *destination* contract can be the same bytecode deployed to both chains, as long the logic for both sending and receiving is present. Alternatively, these contracts can be totally distinct if the separation of code is cleaner for your use-case.

**How can I see the status of a message?**

Use the Telepathy [Explorer](https://docs.telepathy.xyz/resources/telepathy-explorer) for message tracking.

**How long does it take for a message to be relayed?**

[Finality](https://hackmd.io/@prysmaticlabs/finality) on Ethereum takes \~12 minutes, and there are additional time delays for security purposes. We recommend waiting \~20 minutes before troubleshooting a message.
