// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

/// @title IHandler
/// @author The Warp Team <contact@warp.inc>
/// @notice Interface for a cross-chain message handler.
/// @dev The handler is responsible for processing a message upon delivery. It
///      contains any application logic performed on message receipt.
/// @dev Security notice: within any `handle,`
///      the handler MUST check that the caller (msg.sender)
///      is a registered Messenger contract.
///      Otherwise, any caller can pass un-verified data to the application.
/// @dev Security notice: within any `handle`,
///      the handler SHOULD check that the (emitter chain, sender)
///      is a trusted remote sender (likely the address of a
///      remote deployment of the same handler application).
///      Most cross-chain applications SHOULD NOT accept messages from
///      un-trusted remote senders.
interface IHandler {
    /// @notice Handle a message.
    /// @dev This function is called by the `Messenger` contract to deliver
    ///      a message.
    /// @dev Security notice: the handler MUST check that msg.sender is an
    ///      approved Messenger contract. Application developers are
    ///      responsible for selecting approved Messengers.
    /// @dev Security notice: The handler MUST correctly implement
    ///      `approvedVerifier` and `approvedMessenger`
    ///      to prevent unauthorized messages.
    /// @dev Security notice: The handler SHOULD check the (emitter chain,
    ///      sender) information to prevent unauthorized messages. The
    ///      functionality of this check is application-specific.
    /// @dev see BaseHandler for implementation including necessary pre-checks
    /// @param emittingChain - The chainId the message was sent from
    /// @param sender - The sender of the message on the origin chain
    /// @param replayHash The unique identifier of the message which was
    ///        delivered.
    ///        Security notice: It is RECOMMENDED that applications prevent
    ///        replaying messages using `acceptableDelivery` to reject
    ///        previously delivered messages, and marking messages' replayHash
    ///        as delivered in `handle` (*before* calling any external contracts,
    ///        if there is no blanket replay protection; otherwise,
    ///        messages could be replayed via reentrancy).
    ///        This recommendation can be safely ignored if there are
    ///        application-specific reasons to allow replays.
    /// @param message - the contents of the message, used for application
    ///        logic. The contents of the message have been authenticated prior
    ///        to delivery.
    function handle(uint16 emittingChain, bytes calldata sender, bytes32 replayHash, bytes calldata message) external;

    /// @notice Handle a message, extended with
    ///         extra un-verified data.
    /// @dev Security notice: true to its name, the unverifiedRelayerData
    ///      is not verified or otherwise validated.
    ///      Applications MUST perform verification as necessary.
    /// @dev Security notice: the handler MUST check that msg.sender is an
    ///      approved Messenger contract. Application developers are
    ///      responsible for selecting approved Messengers.
    /// @dev Security notice: The handler MUST correctly implement
    ///      `approvedVerifier` and `approvedMessenger`
    ///      to prevent unauthorized messages.
    /// @dev Security notice: The handler SHOULD check the (emitter chain,
    ///      sender) information to prevent unauthorized messages. The
    ///      functionality of this check is application-specific.
    /// @dev see BaseHandler for implementation including necessary pre-checks
    /// @dev Security notice: The Messenger contract does not prevent reentrance
    ///      when calling `handleExt`.
    ///      This choice was made to enable the delivery of
    ///      additional messages contained in `unverifiedRelayerData` data.
    ///      App devs MUST ensure that their `handleExt`
    ///      function is secure against re-entry by the `Messenger` contract.
    /// @param emittingChain - The chainId the message was sent from.
    /// @param sender - The sender of the message on the origin chain.
    /// @param replayHash The unique identifier of the message which was
    ///        delivered.
    ///        Security notice: It is RECOMMENDED that applications prevent
    ///        replaying messages using `acceptableDelivery` to reject
    ///        previously delivered messages, and marking messages' replayHash
    ///        as delivered in `handleExt` (*before* calling any external
    ///        contracts, if there is no blanket replay protection; otherwise,
    ///        messages could be replayed via reentrancy).
    ///        This recommendation can be safely ignored if there are
    ///        application-specific reasons to allow replays.
    /// @param message - the contents of the message, used for application
    ///        logic. The contents of the message have been authenticated prior
    ///        to delivery.
    /// @param relaySignal - Application-defined bytes meant to signal
    ///        to relayers what type of ExtendedMessage this is,
    ///        so that relayers can construct appropriate
    ///        `unverifiedRelayerData` for delivery. May also be used by
    ///        receiving applications to verify `unverifiedRelayerData.`
    /// @param unverifiedRelayerData - un-verified extra data passed by the
    ///        relayer that delivers the message.
    ///        NOTE: this field affords flexibility to add information not
    ///        available at the time of sending the message, but application
    ///        developers should take caution, as this is un-trusted data
    ///        passed by  the relayer.
    function handleExt(
        uint16 emittingChain,
        bytes calldata sender,
        bytes32 replayHash,
        bytes calldata message,
        bytes calldata relaySignal,
        bytes calldata unverifiedRelayerData
    ) external;

    /// @notice Handle a message with
    ///         a transfer of tokens.
    /// @dev Security notice: the token transfer is not verified
    ///      or otherwise validated.
    ///      Applications MUST submit it to the specified bridge
    ///      and verify that it results in a transfer
    ///      of the correct type and amount of tokens.
    /// @dev Security notice: the handler MUST check that msg.sender is an
    ///      approved Messenger contract. Application developers are
    ///      responsible for selecting approved Messengers.
    /// @dev Security notice: The handler MUST correctly implement
    ///      `approvedVerifier` and `approvedMessenger`
    ///      to prevent unauthorized messages.
    /// @dev Security notice: The handler SHOULD check the (emitter chain,
    ///      sender) information to prevent unauthorized messages. The
    ///      functionality of this check is application-specific.
    /// @dev see BaseHandler for implementation including necessary pre-checks
    /// @dev Security notice: The Messenger contract does not prevent reentrance
    ///      when calling `handleWithTokens`.
    ///      This choice was made to enable the delivery of
    ///      additional messages contained in `transfer` data
    ///      (such as a message delivering a Burn-and-Mint token built on this
    ///      contract).
    ///      App devs MUST ensure that their `handleWithTokens`
    ///      function is secure against re-entry by the `Messenger` contract.
    /// @param emittingChain - The chainId the message was sent from
    /// @param sender - The sender of the message on the origin chain
    /// @param replayHash - The unique identifier of the message which was
    ///        delivered.
    ///        Security notice: It is RECOMMENDED that applications prevent
    ///        replaying messages using `acceptableDelivery` to reject
    ///        previously delivered messages, and marking messages' replayHash
    ///        as delivered in `handleWithTokens` (*before* calling any
    ///        external contracts, if there is no blanket replay protection;
    ///        otherwise, messages could be replayed via reentrancy).
    ///        This recommendation can be safely ignored if there are
    ///        application-specific reasons to allow replays.
    /// @param message - the contents of the message, used for application
    ///        logic. The contents of the message have been authenticated prior
    ///        to delivery.
    /// @param bridge - The token bridge used to send and receive the tokens.
    /// @param assetIdentifier - The app-defined identifier for the token being transferred.
    ///        Example: abi.encode(nativeTokenChainId, nativeTokenAddress);
    /// @param amount - The amount of the token being transferred.
    /// @param transfer - Data to pass to the specified bridge to complete the token transfer.
    function handleWithTokens(
        uint16 emittingChain,
        bytes calldata sender,
        bytes32 replayHash,
        bytes calldata message,
        uint8 bridge,
        bytes calldata assetIdentifier,
        uint256 amount,
        bytes calldata transfer
    ) external;

    /// @notice Check if a given verifier is acceptable to this handler.
    /// @dev Security notice: using `acceptableVerifier`,
    ///      the handler MUST auth the verifier.
    ///      A malicious or faulty verifier can pass arbitrary messages.
    ///      The verifier code MUST be trusted to verify messages.
    /// @dev This function is called by the Messenger contract prior to message
    ///      delivery. It allows the handler to reject messages from a verifier
    ///      which is not trusted.
    /// @dev MUST return true if the verifier is acceptable, false otherwise.
    /// @param verifier - The address of the contract which verifies the
    ///        message.
    /// @return acceptable - True if the verifier is acceptable, false
    ///         otherwise.
    function acceptableVerifier(address verifier) external view returns (bool acceptable);

    /// @notice Check if a given Messenger is acceptable to this handler.
    /// @dev Security notice: using `acceptableMessenger`,
    ///      the handler MUST auth that the (emitter chain, emitterAddress)
    ///      is the address of a remote Messenger contract.
    /// @dev This function is called by the Messenger contract prior to message
    ///      delivery. It allows the handler to reject messages from a remote
    ///      Messenger which is not trusted.
    /// @dev MUST return true if the Messenger is acceptable, false otherwise.
    /// @param chainId - The Wormhole chainId of the Messenger contract.
    /// @param messenger - The address of the Messenger contract.
    /// @return acceptable - True if the Messenger is acceptable, false
    ///         otherwise.
    function acceptableMessenger(uint16 chainId, bytes32 messenger) external view returns (bool acceptable);

    /// @notice Check if a given delivery is acceptable to this handler.
    /// @dev Security notice: using `acceptableDelivery`,
    ///      the handler MAY reject messages that have already been delivered.
    ///      If implementing relay protection, the handler MUST mark a message
    ///      as delivered within `handle` using replayHash.
    /// @dev This function is called by the Messenger contract prior to message
    ///      delivery. It allows the handler to reject messages. It is intended
    ///      to be used by the handler to prevent replays and to allow the
    ///      handler to denylist specific messages.
    /// @dev MUST return true if the delivery is acceptable, false otherwise.
    /// @param replayHash - The unique identifier of the message which was
    ///        delivered.
    ///        Security notice: It is RECOMMENDED that applications prevent
    ///        replaying messages using `acceptableDelivery` to reject
    ///        previously delivered messages, and marking messages as delivered
    ///        `handle`. This recommendation can be safely ignored if there are
    ///        application-specific reasons to allow replays.
    /// @return acceptable - True if the message is acceptable, false otherwise.
    function acceptableDelivery(bytes32 replayHash) external view returns (bool acceptable);
}
[{"inputs":[{"internalType":"address","name":"attestor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ATTESTOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"deploy","outputs":[],"stateMutability":"nonpayable","type":"function"}]