polytone-evm 0.3.0

Core interfaces for Polytone Interchain accounts and queries.
Documentation
// SPDX-License-Identifier: Apache
pragma solidity ^0.8.24;

import {MsgType, Packet, EvmMsg, CallMessage} from "../Requests.sol";
import {IbcCoreChannelV1GlobalEnums} from "../IBCTypes.sol";

library PolytoneLib {
    bytes32 public constant EVM_POLYTONE_VERSION = keccak256("polytone-evm-1");
    bytes1 public constant ACK_SUCCESS = 0x00;
    bytes1 public constant ACK_FAILURE = 0x01;

    /**
     * @dev An error indicating that the version is unexpected
     * @param expected Expected version
     * @param actual Actual version
     */
    error ErrProtocolMismatch(bytes32 expected, bytes32 actual);
    /// @dev The caller is not the IbcHandler.
    error ErrNotIBC();
    /// @dev The channel is not known to the protocol.
    error ErrUnknownChannel(string channel);
    /// @dev Only UNORDERED ordering is allowed.
    error ErrExpectUnordered();
    /// @dev The call not made by the contract itself.
    error NotSelf();
    /// @dev The proxy address does not match the expected address.
    error ProxyAddressMismatch();
    /// @dev The message type is unknown.
    error ErrUnknownMsgType(MsgType msgType);
    /// @dev Only connections with a single hop are supported.
    error ErrOnlyOneConnectionHopExpected();
    /// @dev Voice will never send a packet.
    error UnexpectedPacket();

    event Received(string sourceChannel, uint64 indexed sequence);

    /**
     * @dev Reverts if called by any caller than this contract.
     */
    function _checkIsSelf() internal view {
        if (msg.sender != address(this)) {
            revert NotSelf();
        }
    }

    /**
     * @dev Reverts if the protocol does not match polytone.
     */
    function _checkIsPolytone(string memory version) internal pure {
        if (keccak256(bytes(version)) != EVM_POLYTONE_VERSION) {
            revert ErrProtocolMismatch(EVM_POLYTONE_VERSION, keccak256(bytes(version)));
        }
    }

    /**
     * @dev Reverts if the channel is not unordered.
     */
    function _checkUnordered(IbcCoreChannelV1GlobalEnums.Order order) internal pure {
        if (order != IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED) {
            revert PolytoneLib.ErrExpectUnordered();
        }
    }

    /**
     * @dev Reverts if there are more than one channel hop.
     */
    function _checkSingleConnectionHop(string[] memory connectionHops) internal pure {
        if (connectionHops.length != 1) {
            revert PolytoneLib.ErrOnlyOneConnectionHopExpected();
        }
    }

    function decodePacket(bytes memory packet) internal pure returns (Packet memory) {
        return abi.decode(packet, (Packet));
    }

    function decodeEvmMsgs(bytes[] memory data) internal pure returns (EvmMsg[] memory) {
        uint256 length = data.length;
        EvmMsg[] memory evmMsgs = new EvmMsg[](length);

        for (uint256 i = 0; i < length;) {
            evmMsgs[i] = abi.decode(data[i], (EvmMsg));
            unchecked {
                ++i;
            }
        }
        return evmMsgs;
    }

    function decodeCallMessage(bytes memory data) internal pure returns (CallMessage memory) {
        return abi.decode(data, (CallMessage));
    }
}