# Implementing your callback

Now, we’ll write the callback function on **Chiado** using the `onMessage` implementation you provided. This contract will handle the message sent from **Sepolia**.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ChiadoReceiver {
    /// @dev Yaru contract on the Chiado w.r.t the Sepolia
    address public YARU = 0xBA9165973963a6E5608f03b9648c34A737E48f68;  
    /// @dev Source chain ID of Sepolia
    uint256 public SOURCE_CHAIN_ID = 11155111;
    /// @dev Expected threshold to be met by the adapters
    uint256 public EXPECTED_THRESHOLD;
    /// @dev Sender SepoliaSender contract address
    address public SOURCE_SENDER_ADDRESS;
    /// @dev hash of adapters address 
    bytes32 public ADAPTERS_HASH;
    /// @dev message that is last received from sender contract's sendMessageToTarget function
    string public lastReceivedMessage;
    

    constructor(uint256 expectedThreshold, address sourceSender, address[] memory adapters){
        EXPECTED_THRESHOLD = expectedThreshold;
        SOURCE_SENDER_ADDRESS = sourceSender;
        ADAPTERS_HASH = keccak256(abi.encodePacked(adapters));
    }

    /// @dev Function that gets triggered when the message is relayed, called by Yaru contract
    /// @param chainId chainId of the chain where message is sending from
    /// @param sender sender contract
    /// @param threshold threshold of the message that should be met by adapters
    /// @param adapters an array of adapters to check the threshold with
    /// @param data abi-encoded message
    /// @return 
    function onMessage(
        uint256, /*messageId*/
        uint256 chainId,
        address sender,
        uint256 threshold,
        address[] memory adapters,
        bytes memory data
    ) external returns (bytes memory) {
        require(msg.sender == YARU, "only called by Yaru");
        require(chainId == SOURCE_CHAIN_ID, "invalid source chain ID");
        require(threshold == EXPECTED_THRESHOLD, "invalid number of threshold");
        require(sender == SOURCE_SENDER_ADDRESS, "invalid sender address from source chain");
        require( keccak256(abi.encodePacked(adapters)) == ADAPTERS_HASH, "invalid adapters hash");
    
        // Decode the message and store it
        (string memory message) = abi.decode(data, (string));
        lastReceivedMessage = message;

        return "";
    }
}
```

**Explanation**:

* The `onMessage` function implements the callback, which is triggered when the **Yaru** contract on **Chiado** relays the message.
* The function checks that the **Yaru** contract on **Chiado** is the sender, that the **chainId**, **sender address**, and **threshold** match what was expected, and that the list of adapters matches the expected hash.
* After the validations pass, the message is decoded and stored in the contract.

**Deployment**:

* Deploy this contract on **Chiado**. Ensure that the values like **SOURCE\_SENDER\_ADDRESS** (Sepolia sender contract), **EXPECTED\_THRESHOLD**, and **ADAPTERS** are correctly configured.
* Yaru address with respect to the source chain can be found in [#yaho-and-yaru](https://crosschain-alliance.gitbook.io/hashi/deployments/blockchains#yaho-and-yaru "mention")
* A list of adapters on the target chain can be found in [oracles](https://crosschain-alliance.gitbook.io/hashi/deployments/oracles "mention")
