// 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));
}
}