---
title: 'Telepathy Validator for OmniBridge'
---
Telepathy Validator for OmniBridge
===
[TOC]
## Introduction
The [Telepathy Protocol](https://www.telepathy.xyz/) has been [launched](https://twitter.com/SuccinctLabs/status/1636429568172228609), which removes the need to trust centralized actors or permissioned multisigs when passing information between chains.
For developers wishing to use Telepathy for cross-chain messaging, the standard path is to plug into the [Telepathy Router](https://docs.telepathy.xyz/protocol/contracts#router) by using the send function:
```Solidity
send(uint32 destinationChainId, bytes32 destinationAddress, bytes calldata data)
```
For *existing* contracts that are cannot be modified to make this external call, Telepathy provides a different system: **On-Chain PubSub for events**. Since the [TokenBridge contracts](https://github.com/omni/tokenbridge-contracts) fall into the category, we will demonstrate how this system is used to create a Validator secured by the [Telepathy Light Client](https://docs.telepathy.xyz/protocol/contracts#light-client):
![gnosis-validator](https://i.imgur.com/Be6IAg7.png)
For additional information on the protocol, please refer to the official [Telepathy docs](https://docs.telepathy.xyz/). This specific document will focus on the PubSub system and the Validator.
Telepathy PubSub Technical Walkthrough
---
To listen to any arbitrary event that was emitted on-chain, a contract must first [subscribe](https://github.com/succinctlabs/telepathy-contracts/blob/9ed099dc2eed7a000b2b3d5309da8ccf813a896d/src/pubsub/interfaces/IPubSub.sol#L45-L52) to it:
```Solidity
function subscribe(
uint32 sourceChainId,
address sourceAddress,
address callbackAddress,
bytes32 eventSig,
uint64 startSlot,
uint64 endSlot
) external returns (bytes32 subscriptionId)
```
Then, the subscribed contract specified by `callbackAddress` will receive updates from the [publisher](https://github.com/succinctlabs/telepathy-contracts/blob/9ed099dc2eed7a000b2b3d5309da8ccf813a896d/src/pubsub/TelepathyPublisher.sol#L16) whenever a new event is emitted for that `sourceChainId` + `sourceAddress` + `eventSig`. All events that are published are verified with the Light Client and event proof in [publishEvent()](https://github.com/succinctlabs/telepathy-contracts/blob/9ed099dc2eed7a000b2b3d5309da8ccf813a896d/src/pubsub/TelepathyPublisher.sol#L26).
The subscribed contract *must* implement [ISubscriptionReceiver](https://github.com/succinctlabs/telepathy-contracts/blob/9ed099dc2eed7a000b2b3d5309da8ccf813a896d/src/pubsub/interfaces/ISubscriptionReceiver.sol#L3). We also provide an abstract contract, [SubscriptionReceiver](https://github.com/succinctlabs/telepathy-contracts/blob/9ed099dc2eed7a000b2b3d5309da8ccf813a896d/src/pubsub/interfaces/SubscriptionReceiver.sol#L6), for ensuring that all the checks for handling this event are met. This means that all that needs to be done is implementing this function:
```Solidity
function handlePublishImpl(
bytes32 _subscriptionId,
uint32 _sourceChainId,
address _sourceAddress,
uint64 _slot,
bytes32[] memory _eventTopics,
bytes memory _eventdata
) internal virtual;
```
Gnosis Validator Technical Walkthrough
---
To create a trustless ETH->Gnosis Validator on top of this system, we simply subscribe to the [UserRequestForAffirmation](https://github.com/succinctlabs/tokenbridge-contracts/blob/908a48107919d4ab127f9af07d44d47eac91547e/contracts/upgradeable_contracts/arbitrary_message/ForeignAMB.sol#L6) event emitted by the [ForeignAMB](https://github.com/succinctlabs/tokenbridge-contracts/blob/908a48107919d4ab127f9af07d44d47eac91547e/contracts/upgradeable_contracts/arbitrary_message/ForeignAMB.sol#L5):
```Solidity
event UserRequestForAffirmation(bytes32 indexed messageId, bytes encodedData);
```
In the [Telepathy Validator](https://github.com/succinctlabs/telepathy-contracts/blob/9ed099dc2eed7a000b2b3d5309da8ccf813a896d/examples/pubsub/gnosis/TelepathyValidator.sol#L11) contract deployed on Gnosis, we specify the Ethereum ForeignAMB and the event via its signature:
```Solidity
bytes32 constant AFFIRMATION_EVENT_SIG = keccak256("UserRequestForAffirmation(bytes32,bytes)");
function subscribeToAffirmationEvent() external onlyOwner returns (bytes32) {
subscriptionId = telepathyPubSub.subscribe(
EVENT_SOURCE_CHAIN_ID,
EVENT_SOURCE_ADDRESS,
address(this),
AFFIRMATION_EVENT_SIG,
START_SLOT,
END_SLOT
);
return subscriptionId;
}
```
The contract now receives updates whenever this event is emitted. It handles these in the [handlePublishImpl](https://github.com/succinctlabs/telepathy-contracts/blob/9ed099dc2eed7a000b2b3d5309da8ccf813a896d/examples/pubsub/gnosis/TelepathyValidator.sol#L67) function, where additional validation is done:
```Solidity
function handlePublishImpl(
bytes32 _subscriptionId,
uint32 _sourceChainId,
address _sourceAddress,
uint64 _slot,
bytes32[] memory eventTopics,
bytes memory eventdata
) internal override {
if (_sourceChainId != EVENT_SOURCE_CHAIN_ID) {
revert InvalidSourceChain(_sourceChainId);
}
if (_sourceAddress != EVENT_SOURCE_ADDRESS) {
revert InvalidSourceAddress(_sourceAddress);
}
if (_slot < START_SLOT || (END_SLOT != 0 && _slot > END_SLOT)) {
revert InvalidSlot(_slot);
}
if (_subscriptionId != subscriptionId) {
revert InvalidSubscriptionId(_subscriptionId);
}
(bytes memory header, bytes memory data) = abi.decode(eventdata, (bytes, bytes));
if (executeAffirmationsEnabled) {
HOME_AMB.executeAffirmation(data);
}
emit AffirmationHandled(eventTopics[1], header, data);
}
```
When this contract is added as a Validator, `executeAffirmationsEnabled` can be set to true and the HomeAMB's [executeAffirmation()](https://github.com/succinctlabs/tokenbridge-contracts/blob/908a48107919d4ab127f9af07d44d47eac91547e/contracts/upgradeable_contracts/arbitrary_message/BasicHomeAMB.sol#L20) function.
For now, we emit `AffirmationHandled` with the event data.
Results
---
The Telepathy Validator contract is deployed, and the source code can be viewed on GnosisScan [here](https://gnosisscan.io/address/0xbfe15ccbf28c504ddcebcef60753abfff731a675#code). As shown in the [events](https://gnosisscan.io/address/0xbfe15ccbf28c504ddcebcef60753abfff731a675#events) tab, we can see these results successfully handled:
![https://gnosisscan.io/address/0xbfe15ccbf28c504ddcebcef60753abfff731a675#events](https://i.imgur.com/TrTsoPw.png)
You can also find this and the PubSub system in our [contracts repository](https://github.com/succinctlabs/telepathy-contracts) on GitHub.
Next Steps
---
The Telepathy Validator contract needs to be added as one of the validators. Its address is: [0xbFe15ccbF28C504DdCEBCEf60753Abfff731a675](https://gnosisscan.io/address/0xbfe15ccbf28c504ddcebcef60753abfff731a675)
Once the reliability and liveness has been demonstrated, it can then act as a *required* validator for all messages.