Sepolia Testnet

Contract

0x9dB6143dCF7A81D4113466D1D0FA2f62D6Bd9E0d

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Recv Packet67617682024-09-26 7:11:4869 days ago1727334708IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.08354958269.95019506
Recv Packet67617672024-09-26 7:11:3669 days ago1727334696IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.08227886263.45086351
Recv Packet67617662024-09-26 7:11:2469 days ago1727334684IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07841071242.2483728
Recv Packet67617652024-09-26 7:11:0069 days ago1727334660IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.06976811227.5608633
Recv Packet67617642024-09-26 7:10:3669 days ago1727334636IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07423797242.13062623
Recv Packet67617622024-09-26 7:10:1269 days ago1727334612IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.06806104221.99297772
Recv Packet67617602024-09-26 7:09:4869 days ago1727334588IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.06961939227.07578718
Recv Packet67617582024-09-26 7:09:2469 days ago1727334564IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07012989226.58215428
Recv Packet67617572024-09-26 7:09:0069 days ago1727334540IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.06959131224.86821268
Recv Packet67617562024-09-26 7:08:4869 days ago1727334528IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07038834225.36962401
Recv Packet67617542024-09-26 7:08:2469 days ago1727334504IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07434695240.20702438
Recv Packet67617532024-09-26 7:08:0069 days ago1727334480IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.0729033237.77752082
Recv Packet67617512024-09-26 7:07:3669 days ago1727334456IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07176996234.08108618
Recv Packet67617492024-09-26 7:07:1269 days ago1727334432IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.0742021237.56227422
Recv Packet67617482024-09-26 7:07:0069 days ago1727334420IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07127778230.28193705
Recv Packet67617472024-09-26 7:06:4869 days ago1727334408IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07206164230.77153747
Recv Packet67617462024-09-26 7:06:3669 days ago1727334396IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07417886239.68252087
Recv Packet67617452024-09-26 7:06:2469 days ago1727334384IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07666376245.44342419
Recv Packet67617442024-09-26 7:06:1269 days ago1727334372IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07376562236.19208238
Recv Packet67617432024-09-26 7:06:0069 days ago1727334360IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.07624469246.32887508
Recv Packet67617412024-09-26 7:05:3669 days ago1727334336IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.0776575250.90305966
Recv Packet67617402024-09-26 7:05:1269 days ago1727334312IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.08078897261.06096806
Recv Packet67617392024-09-26 7:05:0069 days ago1727334300IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.08169313263.94174536
Recv Packet67617382024-09-26 7:04:4869 days ago1727334288IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.08504204274.76169642
Recv Packet67617372024-09-26 7:04:3669 days ago1727334276IN
0x9dB6143d...2D6Bd9E0d
0 ETH0.09342902298.77115224
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xd56C4355...a8b3d314E
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
OwnableIBCHandler

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 9999999 runs

Other Settings:
paris EvmVersion
File 1 of 36 : OwnableIBCHandler.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {ILightClient} from "../02-client/ILightClient.sol";
import {IIBCClient} from "../02-client/IIBCClient.sol";
import {IIBCConnection} from "../03-connection/IIBCConnection.sol";
import {
    IIBCChannelHandshake, IIBCChannelPacketSendRecv, IIBCChannelPacketTimeout
} from "../04-channel/IIBCChannel.sol";
import {
    IIBCChannelUpgradeInitTryAck,
    IIBCChannelUpgradeConfirmOpenTimeoutCancel
} from "../04-channel/IIBCChannelUpgrade.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IIBCModule} from "../26-router/IIBCModule.sol";
import {IBCHandler} from "./IBCHandler.sol";

/**
 * @dev OwnableIBCHandler is a contract that implements [ICS-25](https://github.com/cosmos/ibc/tree/main/spec/core/ics-025-handler-interface) and Ownable for host configuration.
 */
contract OwnableIBCHandler is IBCHandler, Ownable {
    /**
     * @dev The arguments of constructor must satisfy the followings:
     * @param ibcClient_ is the address of a contract that implements `IIBCClient`.
     * @param ibcConnection_ is the address of a contract that implements `IIBCConnection`.
     * @param ibcChannelHandshake_ is the address of a contract that implements `IIBCChannelHandshake`.
     * @param ibcChannelPacketSendRecv_ is the address of a contract that implements `IIBCChannelPacketSendRecv`.
     * @param ibcChannelPacketTimeout_ is the address of a contract that implements `IIBCChannelPacketTimeout`.
     * @param ibcChannelUpgradeInitTryAck_ is the address of a contract that implements `IIBCChannelUpgrade`.
     * @param ibcChannelUpgradeConfirmOpenTimeoutCancel_ is the address of a contract that implements `IIBCChannelUpgrade`.
     */
    constructor(
        IIBCClient ibcClient_,
        IIBCConnection ibcConnection_,
        IIBCChannelHandshake ibcChannelHandshake_,
        IIBCChannelPacketSendRecv ibcChannelPacketSendRecv_,
        IIBCChannelPacketTimeout ibcChannelPacketTimeout_,
        IIBCChannelUpgradeInitTryAck ibcChannelUpgradeInitTryAck_,
        IIBCChannelUpgradeConfirmOpenTimeoutCancel ibcChannelUpgradeConfirmOpenTimeoutCancel_
    )
        IBCHandler(
            ibcClient_,
            ibcConnection_,
            ibcChannelHandshake_,
            ibcChannelPacketSendRecv_,
            ibcChannelPacketTimeout_,
            ibcChannelUpgradeInitTryAck_,
            ibcChannelUpgradeConfirmOpenTimeoutCancel_
        )
        Ownable(msg.sender)
    {}

    function registerClient(string calldata clientType, ILightClient client) public onlyOwner {
        super._registerClient(clientType, client);
    }

    function bindPort(string calldata portId, IIBCModule moduleAddress) public onlyOwner {
        super._bindPort(portId, moduleAddress);
    }

    function setExpectedTimePerBlock(uint64 expectedTimePerBlock_) public onlyOwner {
        super._setExpectedTimePerBlock(expectedTimePerBlock_);
    }
}

File 2 of 36 : IBCClientLib.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

library IBCClientLib {
    /**
     * @dev validateClientType validates the client type
     *   - clientType must be non-empty
     *   - clientType must be in the form of `^[a-z][a-z0-9-]*[a-z0-9]$`
     */
    function validateClientType(bytes memory clientTypeBytes) internal pure returns (bool) {
        if (clientTypeBytes.length == 0) {
            return false;
        }
        unchecked {
            for (uint256 i = 0; i < clientTypeBytes.length; i++) {
                uint256 c = uint256(uint8(clientTypeBytes[i]));
                if (0x61 <= c && c <= 0x7a) {
                    // a-z
                    continue;
                } else if (c == 0x2d) {
                    // hyphen cannot be the first or last character
                    if (i == 0 || i == clientTypeBytes.length - 1) {
                        return false;
                    }
                    continue;
                } else if (0x30 <= c && c <= 0x39) {
                    // 0-9
                    continue;
                } else {
                    return false;
                }
            }
        }
        return true;
    }
}

File 3 of 36 : IIBCClient.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";

interface IIBCClient {
    // --------------------- Data Structure --------------------- //

    struct MsgCreateClient {
        string clientType;
        bytes protoClientState;
        bytes protoConsensusState;
    }

    struct MsgUpdateClient {
        string clientId;
        bytes protoClientMessage;
    }

    // --------------------- Events --------------------- //

    /// @notice Emitted when a client identifier is generated
    /// @param clientId client identifier
    event GeneratedClientIdentifier(string clientId);

    /**
     * @dev createClient creates a new client state and populates it with a given consensus state
     */
    function createClient(MsgCreateClient calldata msg_) external returns (string memory clientId);

    /**
     * @dev updateClient updates the consensus state and the state root from a provided header
     */
    function updateClient(MsgUpdateClient calldata msg_) external;

    /**
     * @dev routeUpdateClient returns the lc contract address and the calldata to the receiving function of the client message.
     *      Light client contract may encode a client message as other encoding scheme(e.g. ethereum ABI)
     *      Check ADR-001 for details.
     */
    function routeUpdateClient(MsgUpdateClient calldata msg_) external view returns (address, bytes4, bytes memory);

    /**
     * @dev updateClientCommitments updates the commitments of the light client's states corresponding to the given heights.
     *      Check ADR-001 for details.
     */
    function updateClientCommitments(string calldata clientId, Height.Data[] calldata heights) external;
}

File 4 of 36 : IIBCClientErrors.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";

interface IIBCClientErrors {
    /// @param clientType the client type
    error IBCClientUnregisteredClientType(string clientType);

    /// @param clientId the client identifier
    error IBCClientClientNotFound(string clientId);

    /// @param clientId the client identifier
    /// @param consensusHeight the consensus height
    error IBCClientConsensusStateNotFound(string clientId, Height.Data consensusHeight);

    /// @param clientId the client identifier
    error IBCClientNotActiveClient(string clientId);

    /// @param selector the function selector
    /// @param args the calldata
    error IBCClientFailedUpdateClient(bytes4 selector, bytes args);
}

File 5 of 36 : ILightClient.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";

/**
 * @dev This defines an interface for Light Client contract can be integrated with ibc-solidity.
 * You can register the Light Client contract that implements this through `registerClient` on IBCHandler.
 */
interface ILightClient {
    /**
     * @dev ConsensusStateUpdate represents a consensus state update.
     */
    struct ConsensusStateUpdate {
        // commitment for updated consensusState
        bytes32 consensusStateCommitment;
        // updated height
        Height.Data height;
    }

    /**
     * @dev ClientStatus represents the status of a client.
     */
    enum ClientStatus {
        Active,
        Expired,
        Frozen
    }

    /**
     * @dev initializeClient initializes a new client with the given state.
     *      If succeeded, it returns heights at which the consensus state are stored.
     *      The function must be only called by IBCHandler.
     */
    function initializeClient(
        string calldata clientId,
        bytes calldata protoClientState,
        bytes calldata protoConsensusState
    ) external returns (Height.Data memory height);

    /**
     * @dev routeUpdateClient returns the calldata to the receiving function of the client message.
     *      Light client contract may encode a client message as other encoding scheme(e.g. ethereum ABI)
     *      Check ADR-001 for details.
     */
    function routeUpdateClient(string calldata clientId, bytes calldata protoClientMessage)
        external
        pure
        returns (bytes4 selector, bytes memory args);

    /**
     * @dev getTimestampAtHeight returns the timestamp of the consensus state at the given height.
     *      The timestamp is nanoseconds since unix epoch.
     */
    function getTimestampAtHeight(string calldata clientId, Height.Data calldata height)
        external
        view
        returns (uint64);

    /**
     * @dev getLatestHeight returns the latest height of the client state corresponding to `clientId`.
     */
    function getLatestHeight(string calldata clientId) external view returns (Height.Data memory);

    /**
     * @dev getStatus returns the status of the client corresponding to `clientId`.
     */
    function getStatus(string calldata clientId) external view returns (ClientStatus);

    /**
     * @dev getLatestInfo returns the latest height, the latest timestamp, and the status of the client corresponding to `clientId`.
     */
    function getLatestInfo(string calldata clientId)
        external
        view
        returns (Height.Data memory latestHeight, uint64 latestTimestamp, ClientStatus status);

    /**
     * @dev verifyMembership is a generic proof verification method which verifies a proof of the existence of a value at a given CommitmentPath at the specified height.
     * The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24).
     */
    function verifyMembership(
        string calldata clientId,
        Height.Data calldata height,
        uint64 delayTimePeriod,
        uint64 delayBlockPeriod,
        bytes calldata proof,
        bytes calldata prefix,
        bytes calldata path,
        bytes calldata value
    ) external returns (bool);

    /**
     * @dev verifyNonMembership is a generic proof verification method which verifies the absence of a given CommitmentPath at a specified height.
     * The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24).
     */
    function verifyNonMembership(
        string calldata clientId,
        Height.Data calldata height,
        uint64 delayTimePeriod,
        uint64 delayBlockPeriod,
        bytes calldata proof,
        bytes calldata prefix,
        bytes calldata path
    ) external returns (bool);

    /**
     * @dev getClientState returns the clientState corresponding to `clientId`.
     *      If it's not found, the function returns false.
     */
    function getClientState(string calldata clientId) external view returns (bytes memory, bool);

    /**
     * @dev getConsensusState returns the consensusState corresponding to `clientId` and `height`.
     *      If it's not found, the function returns false.
     */
    function getConsensusState(string calldata clientId, Height.Data calldata height)
        external
        view
        returns (bytes memory, bool);
}

File 6 of 36 : IIBCConnection.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {Version, Counterparty} from "../../proto/Connection.sol";

interface IIBCConnection {
    // --------------------- Data Structure --------------------- //

    struct MsgConnectionOpenInit {
        string clientId;
        Counterparty.Data counterparty;
        Version.Data version;
        uint64 delayPeriod;
    }

    struct MsgConnectionOpenTry {
        Counterparty.Data counterparty; // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier
        uint64 delayPeriod;
        string clientId; // clientID of chainA
        bytes clientStateBytes; // clientState that chainA has for chainB
        Version.Data[] counterpartyVersions; // supported versions of chain A
        bytes proofInit; // proof that chainA stored connectionEnd in state (on ConnOpenInit)
        bytes proofClient; // proof that chainA stored a light client of chainB
        bytes proofConsensus; // proof that chainA stored chainB's consensus state at consensus height
        Height.Data proofHeight; // height at which relayer constructs proof of A storing connectionEnd in state
        Height.Data consensusHeight; // latest height of chain B which chain A has stored in its chain B client
        bytes hostConsensusStateProof; // optional proof data for host state machines that are unable to introspect their own consensus state
    }

    struct MsgConnectionOpenAck {
        string connectionId;
        bytes clientStateBytes; // client state for chainA on chainB
        Version.Data version; // version that ChainB chose in ConnOpenTry
        string counterpartyConnectionId;
        bytes proofTry; // proof that connectionEnd was added to ChainB state in ConnOpenTry
        bytes proofClient; // proof of client state on chainB for chainA
        bytes proofConsensus; // proof that chainB has stored ConsensusState of chainA on its client
        Height.Data proofHeight; // height that relayer constructed proofTry
        Height.Data consensusHeight; // latest height of chainA that chainB has stored on its chainA client
        bytes hostConsensusStateProof; // optional proof data for host state machines that are unable to introspect their own consensus state
    }

    struct MsgConnectionOpenConfirm {
        string connectionId;
        bytes proofAck;
        Height.Data proofHeight;
    }

    // --------------------- Events --------------------- //

    /// @notice Emitted when a connection identifier is generated
    /// @param connectionId connection identifier
    event GeneratedConnectionIdentifier(string connectionId);

    /**
     * @dev connectionOpenInit initialises a connection attempt on chain A. The generated connection identifier
     * is returned.
     */
    function connectionOpenInit(MsgConnectionOpenInit calldata msg_) external returns (string memory connectionId);

    /**
     * @dev connectionOpenTry relays notice of a connection attempt on chain A to chain B (this
     * code is executed on chain B).
     */
    function connectionOpenTry(MsgConnectionOpenTry calldata msg_) external returns (string memory);

    /**
     * @dev connectionOpenAck relays acceptance of a connection open attempt from chain B back
     * to chain A (this code is executed on chain A).
     */
    function connectionOpenAck(MsgConnectionOpenAck calldata msg_) external;

    /**
     * @dev connectionOpenConfirm confirms opening of a connection on chain A to chain B, after
     * which the connection is open on both chains (this code is executed on chain B).
     */
    function connectionOpenConfirm(MsgConnectionOpenConfirm calldata msg_) external;
}

File 7 of 36 : IIBCConnectionErrors.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {ConnectionEnd} from "../../proto/Connection.sol";

interface IIBCConnectionErrors {
    error IBCConnectionAlreadyConnectionExists();

    /// @param counterpartyConnectionId counterparty connection identifier
    error IBCConnectionInvalidCounterpartyConnectionIdentifier(string counterpartyConnectionId);

    error IBCConnectionEmptyConnectionCounterpartyVersions();

    error IBCConnectionNoMatchingVersionFound();

    error IBCConnectionVersionsAlreadySet();

    error IBCConnectionIBCVersionNotSupported();

    error IBCConnectionInvalidSelfClientState();

    error IBCConnectionInvalidHostConsensusStateProof();

    /// @param state connection state
    error IBCConnectionUnexpectedConnectionState(ConnectionEnd.State state);

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param value value
    /// @param proof proof
    /// @param height proof height
    error IBCConnectionFailedVerifyConnectionState(
        string clientId, bytes path, bytes value, bytes proof, Height.Data height
    );

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param value value
    /// @param proof proof
    /// @param height proof height
    error IBCConnectionFailedVerifyClientState(
        string clientId, bytes path, bytes value, bytes proof, Height.Data height
    );

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param value value
    /// @param proof proof
    /// @param height proof height
    error IBCConnectionFailedVerifyClientConsensusState(
        string clientId, bytes path, bytes value, bytes proof, Height.Data height
    );
}

File 8 of 36 : IBCChannelLib.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Channel} from "../../proto/Channel.sol";
import {IIBCChannelErrors} from "./IIBCChannelErrors.sol";

library IBCChannelLib {
    enum PacketReceipt {
        NONE,
        SUCCESSFUL
    }

    string internal constant ORDER_UNORDERED = "ORDER_UNORDERED";
    string internal constant ORDER_ORDERED = "ORDER_ORDERED";

    bytes32 internal constant PACKET_RECEIPT_SUCCESSFUL_KECCAK256 =
        keccak256(abi.encodePacked(PacketReceipt.SUCCESSFUL));

    function receiptCommitmentToReceipt(bytes32 commitment) internal pure returns (PacketReceipt) {
        if (commitment == bytes32(0)) {
            return PacketReceipt.NONE;
        } else if (commitment == PACKET_RECEIPT_SUCCESSFUL_KECCAK256) {
            return PacketReceipt.SUCCESSFUL;
        } else {
            revert IIBCChannelErrors.IBCChannelUnknownPacketReceiptCommitment(commitment);
        }
    }

    function buildConnectionHops(string memory connectionId) internal pure returns (string[] memory hops) {
        hops = new string[](1);
        hops[0] = connectionId;
        return hops;
    }

    function toString(Channel.Order order) internal pure returns (string memory) {
        if (order == Channel.Order.ORDER_UNORDERED) {
            return ORDER_UNORDERED;
        } else if (order == Channel.Order.ORDER_ORDERED) {
            return ORDER_ORDERED;
        } else {
            revert IIBCChannelErrors.IBCChannelUnknownChannelOrder(order);
        }
    }
}

File 9 of 36 : IIBCChannel.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {Channel} from "../../proto/Channel.sol";

/// @notice Packet defines a type that carries data across different chains through IBC.
/// @param sequence corresponds to the order of sends and receives, where a packet with an earlier sequence number must be sent and received before a packet with a later sequence number
/// @param sourcePort identifies the port on the sending chain
/// @param sourceChannel identifies the channel end on the sending chain
/// @param destPort identifies the port on the receiving chain
/// @param destChannel identifies the channel end on the receiving chain
/// @param data is an opaque value which can be defined by the application logic of the associated modules
/// @param timeoutHeight indicates a consensus height on the destination chain after which the packet will no longer be processed, and will instead count as having timed-out
/// @param timeoutTimestamp indicates a timestamp on the destination chain after which the packet will no longer be processed, and will instead count as having timed-out
struct Packet {
    uint64 sequence;
    string sourcePort;
    string sourceChannel;
    string destinationPort;
    string destinationChannel;
    bytes data;
    Height.Data timeoutHeight;
    uint64 timeoutTimestamp;
}

interface IIBCChannelHandshake {
    // --------------------- Data Structure --------------------- //

    struct MsgChannelOpenInit {
        string portId;
        Channel.Data channel;
    }

    struct MsgChannelOpenTry {
        string portId;
        Channel.Data channel;
        string counterpartyVersion;
        bytes proofInit;
        Height.Data proofHeight;
    }

    struct MsgChannelOpenAck {
        string portId;
        string channelId;
        string counterpartyVersion;
        string counterpartyChannelId;
        bytes proofTry;
        Height.Data proofHeight;
    }

    struct MsgChannelOpenConfirm {
        string portId;
        string channelId;
        bytes proofAck;
        Height.Data proofHeight;
    }

    struct MsgChannelCloseInit {
        string portId;
        string channelId;
    }

    struct MsgChannelCloseConfirm {
        string portId;
        string channelId;
        bytes proofInit;
        Height.Data proofHeight;
    }

    // --------------------- Events --------------------- //

    /// @param channelId channel identifier
    event GeneratedChannelIdentifier(string channelId);

    // --------------------- Functions --------------------- //

    /**
     * @dev channelOpenInit is called by a module to initiate a channel opening handshake with a module on another chain.
     */
    function channelOpenInit(MsgChannelOpenInit calldata msg_)
        external
        returns (string memory channelId, string memory version);

    /**
     * @dev channelOpenTry is called by a module to accept the first step of a channel opening handshake initiated by a module on another chain.
     */
    function channelOpenTry(MsgChannelOpenTry calldata msg_)
        external
        returns (string memory channelId, string memory version);

    /**
     * @dev channelOpenAck is called by the handshake-originating module to acknowledge the acceptance of the initial request by the counterparty module on the other chain.
     */
    function channelOpenAck(MsgChannelOpenAck calldata msg_) external;

    /**
     * @dev channelOpenConfirm is called by the counterparty module to close their end of the channel, since the other end has been closed.
     */
    function channelOpenConfirm(MsgChannelOpenConfirm calldata msg_) external;

    /**
     * @dev channelCloseInit is called by either module to close their end of the channel. Once closed, channels cannot be reopened.
     */
    function channelCloseInit(MsgChannelCloseInit calldata msg_) external;

    /**
     * @dev channelCloseConfirm is called by the counterparty module to close their end of the
     * channel, since the other end has been closed.
     */
    function channelCloseConfirm(MsgChannelCloseConfirm calldata msg_) external;
}

interface IICS04SendPacket {
    // --------------------- Events --------------------- //

    /// @notice event emitted upon sending a packet
    event SendPacket(
        uint64 sequence,
        string sourcePort,
        string sourceChannel,
        Height.Data timeoutHeight,
        uint64 timeoutTimestamp,
        bytes data
    );

    // --------------------- Functions --------------------- //

    /**
     * @dev sendPacket is called by a module in order to send an IBC packet on a channel.
     * The packet sequence generated for the packet to be sent is returned. An error
     * is returned if one occurs. Also, `timeoutTimestamp` is given in nanoseconds since unix epoch.
     */
    function sendPacket(
        string calldata sourcePort,
        string calldata sourceChannel,
        Height.Data calldata timeoutHeight,
        uint64 timeoutTimestamp,
        bytes calldata data
    ) external returns (uint64);
}

interface IICS04WriteAcknowledgement {
    // --------------------- Events --------------------- //

    /// @notice event emitted upon writing an acknowledgement
    /// @param destinationPortId destination port
    /// @param destinationChannel destination channel
    /// @param sequence packet sequence
    /// @param acknowledgement acknowledgement
    event WriteAcknowledgement(
        string destinationPortId, string destinationChannel, uint64 sequence, bytes acknowledgement
    );

    // --------------------- Functions --------------------- //

    /**
     * @dev writeAcknowledgement writes the packet execution acknowledgement to the state,
     * which will be verified by the counterparty chain using AcknowledgePacket.
     */
    function writeAcknowledgement(
        string calldata destinationPortId,
        string calldata destinationChannel,
        uint64 sequence,
        bytes calldata acknowledgement
    ) external;
}

interface IIBCChannelRecvPacket {
    // --------------------- Data Structure --------------------- //

    struct MsgPacketRecv {
        Packet packet;
        bytes proof;
        Height.Data proofHeight;
    }

    // --------------------- Events --------------------- //

    /// @notice event emitted upon receiving a packet
    event RecvPacket(Packet packet);

    // --------------------- Functions --------------------- //

    /**
     * @dev recvPacket is called by a module in order to receive & process an IBC packet
     * sent on the corresponding channel end on the counterparty chain.
     */
    function recvPacket(MsgPacketRecv calldata msg_) external;
}

interface IIBCChannelAcknowledgePacket {
    // --------------------- Data Structure --------------------- //

    struct MsgPacketAcknowledgement {
        Packet packet;
        bytes acknowledgement;
        bytes proof;
        Height.Data proofHeight;
    }

    // --------------------- Events --------------------- //

    /// @notice event emitted upon acknowledging a packet
    event AcknowledgePacket(Packet packet, bytes acknowledgement);

    // --------------------- Functions --------------------- //

    /**
     * @dev AcknowledgePacket is called by a module to process the acknowledgement of a
     * packet previously sent by the calling module on a channel to a counterparty
     * module on the counterparty chain. Its intended usage is within the ante
     * handler. AcknowledgePacket will clean up the packet commitment,
     * which is no longer necessary since the packet has been received and acted upon.
     * It will also increment NextSequenceAck in case of ORDERED channels.
     */
    function acknowledgePacket(MsgPacketAcknowledgement calldata msg_) external;
}

interface IIBCChannelPacketTimeout {
    // --------------------- Data Structure --------------------- //

    struct MsgTimeoutPacket {
        Packet packet;
        bytes proof;
        Height.Data proofHeight;
        uint64 nextSequenceRecv;
    }

    struct MsgTimeoutOnClose {
        Packet packet;
        bytes proofUnreceived;
        bytes proofClose;
        Height.Data proofHeight;
        uint64 nextSequenceRecv;
        uint64 counterpartyUpgradeSequence;
    }

    // --------------------- Events --------------------- //

    /// @notice event emitted upon timeout of a packet
    event TimeoutPacket(Packet packet);

    // --------------------- Functions --------------------- //

    /**
     * @dev TimeoutPacket is called by a module which originally attempted to send a
     * packet to a counterparty module, where the timeout height has passed on the
     * counterparty chain without the packet being committed, to prove that the
     * packet can no longer be executed and to allow the calling module to safely
     * perform appropriate state transitions. Its intended usage is within the
     * ante handler.
     */
    function timeoutPacket(MsgTimeoutPacket calldata msg_) external;

    /**
     * @dev TimeoutOnClose is called by a module in order to prove that the channel to
     * which an unreceived packet was addressed has been closed, so the packet will
     * never be received (even if the timeoutHeight has not yet been reached).
     */
    function timeoutOnClose(MsgTimeoutOnClose calldata msg_) external;
}

interface IICS04Wrapper is IICS04SendPacket, IICS04WriteAcknowledgement {}

interface IIBCChannelPacketSendRecv is IICS04Wrapper, IIBCChannelRecvPacket, IIBCChannelAcknowledgePacket {}

interface IIBCChannelPacket is IIBCChannelPacketSendRecv, IIBCChannelPacketTimeout {}

File 10 of 36 : IIBCChannelErrors.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {Channel} from "../../proto/Channel.sol";

interface IIBCChannelErrors {
    /// @param state channel state
    error IBCChannelUnexpectedChannelState(Channel.State state);

    /// @param portId port identifier
    /// @param channelId channel identifier
    error IBCChannelChannelNotFound(string portId, string channelId);

    /// @param ordering channel ordering
    error IBCChannelUnknownChannelOrder(Channel.Order ordering);

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param value value
    /// @param proof proof
    /// @param height proof height
    error IBCChannelFailedVerifyChannelState(string clientId, bytes path, bytes value, bytes proof, Height.Data height);

    /// @param connectionId connection identifier
    error IBCChannelConnectionNotOpened(string connectionId);

    /// @param counterpartyChannelId counterparty channel identifier
    error IBCChannelCounterpartyChannelIdNotEmpty(string counterpartyChannelId);

    /// @param length length of the connection hops
    error IBCChannelInvalidConnectionHopsLength(uint256 length);

    /// @param connectionId connection identifier
    /// @param length length of the connection hops
    error IBCChannelConnectionMultipleVersionsFound(string connectionId, uint256 length);

    /// @param ordering channel ordering
    error IBCChannelConnectionFeatureNotSupported(Channel.Order ordering);

    /// @notice timeout height and timestamp are both zero
    error IBCChannelZeroPacketTimeout();

    /// @notice receiving chain block height >= packet timeout height
    /// @param timeoutHeight packet timeout height
    /// @param latestHeight latest height of the receiving chain
    error IBCChannelPastPacketTimeoutHeight(Height.Data timeoutHeight, Height.Data latestHeight);

    /// @notice receiving chain block timestamp >= packet timeout timestamp
    /// @param timeoutTimestamp packet timeout timestamp
    /// @param latestTimestamp latest timestamp of the receiving chain
    error IBCChannelPastPacketTimeoutTimestamp(uint64 timeoutTimestamp, uint64 latestTimestamp);

    /// @notice packet timeout has not been reached for height or timestamp
    error IBCChannelTimeoutNotReached();

    /// @param commitment packet receipt commitment
    error IBCChannelUnknownPacketReceiptCommitment(bytes32 commitment);

    /// @param sourcePort source port
    /// @param sourceChannel source channel
    error IBCChannelUnexpectedPacketSource(string sourcePort, string sourceChannel);

    /// @param destinationPort destination port
    /// @param destinationChannel destination channel
    error IBCChannelUnexpectedPacketDestination(string destinationPort, string destinationChannel);

    error IBCChannelCannotRecvNextUpgradePacket(uint64 sequence, uint64 counterpartyNextSequenceSend);

    error IBCChannelPacketAlreadyProcessInPreviousUpgrade(uint64 sequence, uint64 recvStartSequence);

    error IBCChannelAckAlreadyProcessedInPreviousUpgrade(uint64 sequence, uint64 ackStartSequence);

    /// @param currentBlockNumber current block number
    /// @param timeoutHeight packet timeout height
    error IBCChannelTimeoutPacketHeight(uint256 currentBlockNumber, uint64 timeoutHeight);

    /// @param currentTimestamp current timestamp
    /// @param timeoutTimestamp packet timeout timestamp
    error IBCChannelTimeoutPacketTimestamp(uint256 currentTimestamp, uint64 timeoutTimestamp);

    /// @param destinationPort destination port
    /// @param destinationChannel destination channel
    /// @param sequence packet sequence
    error IBCChannelPacketReceiptAlreadyExists(string destinationPort, string destinationChannel, uint64 sequence);

    /// @param expected expected sequence
    error IBCChannelUnexpectedNextSequenceRecv(uint64 expected);

    /// @param portId port identifier
    /// @param channelId channel identifier
    /// @param sequence packet sequence
    error IBCChannelPacketCommitmentNotFound(string portId, string channelId, uint64 sequence);

    /// @param expected expected sequence
    error IBCChannelUnexpectedNextSequenceAck(uint64 expected);

    /// @param expected expected commitment
    /// @param actual actual commitment
    error IBCChannelPacketCommitmentMismatch(bytes32 expected, bytes32 actual);

    /// @param sequence packet sequence
    /// @param nextSequenceRecv next sequence received
    error IBCChannelPacketMaybeAlreadyReceived(uint64 sequence, uint64 nextSequenceRecv);

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param commitment packet commitment
    /// @param proof proof
    /// @param height proof height
    error IBCChannelFailedVerifyPacketCommitment(
        string clientId, bytes path, bytes32 commitment, bytes proof, Height.Data height
    );

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param commitment acknowledgement commitment
    /// @param proof proof
    /// @param height proof height
    error IBCChannelFailedVerifyPacketAcknowledgement(
        string clientId, bytes path, bytes32 commitment, bytes proof, Height.Data height
    );

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param nextSequenceRecv next sequence received
    /// @param proof proof
    /// @param height proof height
    error IBCChannelFailedVerifyNextSequenceRecv(
        string clientId, bytes path, uint64 nextSequenceRecv, bytes proof, Height.Data height
    );

    /// @param clientId client identifier
    /// @param path commitment path
    /// @param proof proof
    /// @param height proof height
    error IBCChannelFailedVerifyPacketReceiptAbsence(string clientId, bytes path, bytes proof, Height.Data height);

    /// @notice acknowledgement cannot be empty
    error IBCChannelEmptyAcknowledgement();

    /// @param destinationPort destination port
    /// @param destinationChannel destination channel
    /// @param sequence packet sequence
    error IBCChannelAcknowledgementAlreadyWritten(string destinationPort, string destinationChannel, uint64 sequence);
}

File 11 of 36 : IIBCChannelUpgrade.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {Channel, Upgrade, UpgradeFields, ErrorReceipt, Timeout} from "../../proto/Channel.sol";

interface IIBCChannelUpgradeBase {
    enum UpgradeHandshakeError {
        None,
        Overwritten,
        OutOfSync,
        Timeout,
        Cancel,
        IncompatibleProposal,
        AckCallbackFailed
    }

    struct MsgChannelUpgradeInit {
        string portId;
        string channelId;
        UpgradeFields.Data proposedUpgradeFields;
    }

    struct MsgChannelUpgradeTry {
        string portId;
        string channelId;
        uint64 counterpartyUpgradeSequence;
        UpgradeFields.Data counterpartyUpgradeFields;
        string[] proposedConnectionHops;
        ChannelUpgradeProofs proofs;
    }

    struct MsgChannelUpgradeAck {
        string portId;
        string channelId;
        Upgrade.Data counterpartyUpgrade;
        ChannelUpgradeProofs proofs;
    }

    struct MsgChannelUpgradeConfirm {
        string portId;
        string channelId;
        Channel.State counterpartyChannelState;
        Upgrade.Data counterpartyUpgrade;
        ChannelUpgradeProofs proofs;
    }

    struct MsgChannelUpgradeOpen {
        string portId;
        string channelId;
        Channel.State counterpartyChannelState;
        uint64 counterpartyUpgradeSequence;
        bytes proofChannel;
        Height.Data proofHeight;
    }

    struct MsgCancelChannelUpgrade {
        string portId;
        string channelId;
        ErrorReceipt.Data errorReceipt;
        bytes proofUpgradeError;
        Height.Data proofHeight;
    }

    struct MsgTimeoutChannelUpgrade {
        string portId;
        string channelId;
        Channel.Data counterpartyChannel;
        bytes proofChannel;
        Height.Data proofHeight;
    }

    struct ChannelUpgradeProofs {
        bytes proofChannel;
        bytes proofUpgrade;
        Height.Data proofHeight;
    }

    /// @notice error when the upgrade attempt fails
    /// @param portId port identifier
    /// @param channelId channel identifier
    /// @param upgradeSequence upgrade sequence
    event WriteErrorReceipt(string portId, string channelId, uint64 upgradeSequence, string message);
}

interface IIBCChannelUpgradeInitTryAck is IIBCChannelUpgradeBase {
    // --------------------- Events --------------------- //

    /// @notice emitted when channelUpgradeInit is successfully executed
    event ChannelUpgradeInit(
        string portId, string channelId, uint64 upgradeSequence, UpgradeFields.Data proposedUpgradeFields
    );

    /// @notice emitted when channelUpgradeTry is successfully executed
    event ChannelUpgradeTry(
        string portId,
        string channelId,
        uint64 upgradeSequence,
        UpgradeFields.Data upgradeFields,
        Timeout.Data timeout,
        uint64 nextSequenceSend
    );

    /// @notice emitted when channelUpgradeAck is successfully executed
    /// @param channelState post channel state (FLUSHING or FLUSHCOMPLETE)
    event ChannelUpgradeAck(
        string portId,
        string channelId,
        uint64 upgradeSequence,
        Channel.State channelState,
        UpgradeFields.Data upgradeFields,
        Timeout.Data timeout,
        uint64 nextSequenceSend
    );

    // --------------------- External Functions --------------------- //

    /**
     * @dev channelUpgradeInit is called by a module to initiate a channel upgrade handshake with
     * a module on another chain.
     * The current channel state must be OPEN. The post channel state is always OPEN.
     */
    function channelUpgradeInit(MsgChannelUpgradeInit calldata msg_) external returns (uint64 upgradeSequence);

    /**
     * @dev channelUpgradeTry is called by a module to accept the first step of a channel upgrade handshake initiated by
     * a module on another chain.
     * The current channel state must be OPEN. The post channel state will be OPEN or FLUSHING.
     * If this function is successful, the proposed upgrade will be emitted as event.
     * If the upgrade fails, the upgrade sequence will still be incremented but an error will be returned.
     */
    function channelUpgradeTry(MsgChannelUpgradeTry calldata msg_) external returns (bool ok, uint64 upgradeSequence);

    /**
     * @dev channelUpgradeAck is called by a module to accept the ACKUPGRADE handshake step of the channel upgrade protocol.
     * This method will verify that the counterparty has called the channelUpgradeTry handler.
     * and that its own upgrade is compatible with the selected counterparty version.
     *
     * NOTE: The current channel may be in either the OPEN or FLUSHING state.
     * The channel may be in OPEN if we are in the happy path.
     *   A -> Init (OPEN), B -> Try (FLUSHING), A -> Ack (begins in OPEN, ends in FLUSHING or FLUSHCOMPLETE)
     *
     * The channel may be in FLUSHING if we are in a crossing hellos situation.
     *   A -> Init (OPEN), B -> Init (OPEN) -> A -> Try (FLUSHING), B -> Try (FLUSHING), A -> Ack (begins in FLUSHING, ends in FLUSHING or FLUSHCOMPLETE)
     */
    function channelUpgradeAck(MsgChannelUpgradeAck calldata msg_) external returns (bool);
}

interface IIBCChannelUpgradeConfirmOpenTimeoutCancel is IIBCChannelUpgradeBase {
    // --------------------- Events --------------------- //

    /// @notice emitted when channelUpgradeConfirm is successfully executed
    /// @param channelState post channel state (FLUSHING or FLUSHCOMPLETE or OPEN)
    event ChannelUpgradeConfirm(string portId, string channelId, uint64 upgradeSequence, Channel.State channelState);

    /// @notice emitted when channelUpgradeOpen is successfully executed
    event ChannelUpgradeOpen(string portId, string channelId, uint64 upgradeSequence);

    // --------------------- External Functions --------------------- //

    /**
     * @dev channelUpgradeConfirm is called on the chain which is on FLUSHING after channelUpgradeAck is called on the counterparty.
     * This will inform the TRY chain of the timeout set on ACK by the counterparty. If the timeout has already exceeded,
     * we will write an error receipt and restore the channel to OPEN state.
     */
    function channelUpgradeConfirm(MsgChannelUpgradeConfirm calldata msg_) external returns (bool);

    /**
     * @dev channelUpgradeOpen is called by a module to complete the channel upgrade handshake and move the channel back to an OPEN state.
     * This method should only be called after both channels have flushed any in-flight packets.
     */
    function channelUpgradeOpen(MsgChannelUpgradeOpen calldata msg_) external;

    /**
     * @dev cancelChannelUpgrade proves that an error receipt was written on the counterparty
     * which constitutes a valid situation where the upgrade should be cancelled.
     * The tx reverts if sufficient evidence for cancelling the upgrade has not been provided.
     */
    function cancelChannelUpgrade(MsgCancelChannelUpgrade calldata msg_) external;

    /**
     * @dev timeoutChannelUpgrade times out an outstanding upgrade.
     * This should be used by the initialising chain when the counterparty chain has not responded to an upgrade proposal within the specified timeout period.
     */
    function timeoutChannelUpgrade(MsgTimeoutChannelUpgrade calldata msg_) external;
}

interface IIBCChannelUpgrade is IIBCChannelUpgradeInitTryAck, IIBCChannelUpgradeConfirmOpenTimeoutCancel {}

File 12 of 36 : IIBCChannelUpgradeErrors.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {Channel} from "../../proto/Channel.sol";
import {IIBCChannelErrors} from "./IIBCChannelErrors.sol";

interface IIBCChannelUpgradeErrors is IIBCChannelErrors {
    error IBCChannelUpgradeNoChanges();

    error IBCChannelUpgradeInvalidUpgradeFields();

    /// @notice proposal must be empty if upgrade exists
    error IBCChannelUpgradeTryProposalMustEmptyIfExist();

    /// @param upgrader address of the upgrader
    error IBCChannelUpgradeUnauthorizedChannelUpgrader(address upgrader);

    error IBCChannelUpgradeIncompatibleProposal();

    error IBCChannelUpgradeErrorReceiptEmpty();

    /// @param latestSequence latest upgrade sequence
    /// @param sequence upgrade sequence
    error IBCChannelUpgradeWriteOldErrorReceiptSequence(uint64 latestSequence, uint64 sequence);

    error IBCChannelUpgradeNoExistingUpgrade();

    /// @param state channel state
    error IBCChannelUpgradeNotFlushing(Channel.State state);

    /// @param state channel state
    error IBCChannelUpgradeNotOpenOrFlushing(Channel.State state);

    /// @param state channel state
    error IBCChannelUpgradeCounterpartyNotOpenOrFlushcomplete(Channel.State state);

    /// @notice counterparty channel not flushing or flushcomplete
    /// @param state channel state
    error IBCChannelUpgradeCounterpartyNotFlushingOrFlushcomplete(Channel.State state);

    /// @param state channel state
    error IBCChannelUpgradeNotFlushcomplete(Channel.State state);

    /// @param clientId client identifier
    /// @param path key path
    /// @param value key value
    /// @param proof proof of membership
    /// @param height proof height
    error IBCChannelUpgradeFailedVerifyMembership(
        string clientId, string path, bytes value, bytes proof, Height.Data height
    );

    error IBCChannelUpgradeTimeoutHeightNotReached();

    error IBCChannelUpgradeTimeoutTimestampNotReached();

    error IBCChannelUpgradeInvalidTimeout();

    error IBCChannelUpgradeCounterpartyAlreadyFlushCompleted();

    error IBCChannelUpgradeCounterpartyAlreadyUpgraded();

    error IBCChannelUpgradeTimeoutUnallowedState();

    error IBCChannelUpgradeOldErrorReceiptSequence();

    error IBCChannelUpgradeInvalidErrorReceiptSequence();

    error IBCChannelUpgradeOldCounterpartyUpgradeSequence();

    error IBCChannelUpgradeUnsupportedOrdering(Channel.Order ordering);
}

File 13 of 36 : IBCCommitment.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";

library IBCCommitment {
    // Commitment path generators that comply with https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements#path-space

    function clientStatePath(string memory clientId) internal pure returns (bytes memory) {
        return abi.encodePacked("clients/", clientId, "/clientState");
    }

    function consensusStatePath(string memory clientId, uint64 revisionNumber, uint64 revisionHeight)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked(
            "clients/",
            clientId,
            "/consensusStates/",
            Strings.toString(revisionNumber),
            "-",
            Strings.toString(revisionHeight)
        );
    }

    function connectionPath(string memory connectionId) internal pure returns (bytes memory) {
        return abi.encodePacked("connections/", connectionId);
    }

    function channelPath(string memory portId, string memory channelId) internal pure returns (bytes memory) {
        return abi.encodePacked("channelEnds/ports/", portId, "/channels/", channelId);
    }

    function packetCommitmentPathCalldata(string calldata portId, string calldata channelId, uint64 sequence)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked(
            "commitments/ports/", portId, "/channels/", channelId, "/sequences/", Strings.toString(sequence)
        );
    }

    function packetAcknowledgementCommitmentPathCalldata(
        string calldata portId,
        string calldata channelId,
        uint64 sequence
    ) internal pure returns (bytes memory) {
        return
            abi.encodePacked("acks/ports/", portId, "/channels/", channelId, "/sequences/", Strings.toString(sequence));
    }

    function packetReceiptCommitmentPathCalldata(string calldata portId, string calldata channelId, uint64 sequence)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked(
            "receipts/ports/", portId, "/channels/", channelId, "/sequences/", Strings.toString(sequence)
        );
    }

    function nextSequenceRecvCommitmentPath(string memory portId, string memory channelId)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked("nextSequenceRecv/ports/", portId, "/channels/", channelId);
    }

    function nextSequenceRecvCommitmentPathCalldata(string calldata portId, string calldata channelId)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked("nextSequenceRecv/ports/", portId, "/channels/", channelId);
    }

    function channelUpgradePath(string memory portId, string memory channelId) internal pure returns (bytes memory) {
        return abi.encodePacked("channelUpgrades/upgrades/ports/", portId, "/channels/", channelId);
    }

    function channelUpgradeErrorPath(string memory portId, string memory channelId)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked("channelUpgrades/upgradeError/ports/", portId, "/channels/", channelId);
    }

    // Key generators for Commitment mapping

    function clientStateCommitmentKey(string memory clientId) internal pure returns (bytes32) {
        return keccak256(clientStatePath(clientId));
    }

    function consensusStateCommitmentKey(string memory clientId, uint64 revisionNumber, uint64 revisionHeight)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(consensusStatePath(clientId, revisionNumber, revisionHeight));
    }

    function connectionCommitmentKey(string memory connectionId) internal pure returns (bytes32) {
        return keccak256(connectionPath(connectionId));
    }

    function channelCommitmentKey(string memory portId, string memory channelId) internal pure returns (bytes32) {
        return keccak256(channelPath(portId, channelId));
    }

    function nextSequenceRecvCommitmentKey(string memory portId, string memory channelId)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(nextSequenceRecvCommitmentPath(portId, channelId));
    }

    function packetCommitmentKeyCalldata(string calldata portId, string calldata channelId, uint64 sequence)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(packetCommitmentPathCalldata(portId, channelId, sequence));
    }

    function packetAcknowledgementCommitmentKeyCalldata(
        string calldata portId,
        string calldata channelId,
        uint64 sequence
    ) internal pure returns (bytes32) {
        return keccak256(packetAcknowledgementCommitmentPathCalldata(portId, channelId, sequence));
    }

    function packetReceiptCommitmentKeyCalldata(string calldata portId, string calldata channelId, uint64 sequence)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(packetReceiptCommitmentPathCalldata(portId, channelId, sequence));
    }

    function nextSequenceRecvCommitmentKeyCalldata(string calldata portId, string calldata channelId)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(nextSequenceRecvCommitmentPathCalldata(portId, channelId));
    }

    function channelUpgradeCommitmentKey(string memory portId, string memory channelId)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(channelUpgradePath(portId, channelId));
    }

    function channelUpgradeErrorCommitmentKey(string memory portId, string memory channelId)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(channelUpgradeErrorPath(portId, channelId));
    }
}

File 14 of 36 : IBCHost.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {ILightClient} from "../02-client/ILightClient.sol";
import {IBCStore} from "../24-host/IBCStore.sol";
import {IIBCHostErrors} from "./IIBCHostErrors.sol";

contract IBCHost is IIBCHostErrors, IBCStore {
    // It represents the prefix of the commitment proof(https://github.com/cosmos/ibc/tree/main/spec/core/ics-023-vector-commitments#prefix).
    // In ibc-solidity, the prefix is not required, but for compatibility with ibc-go this must be a non-empty value.
    bytes internal constant DEFAULT_COMMITMENT_PREFIX = bytes("ibc");

    /**
     * @dev _getCommitmentPrefix returns the prefix of the commitment proof.
     */
    function _getCommitmentPrefix() internal view virtual returns (bytes memory) {
        return DEFAULT_COMMITMENT_PREFIX;
    }

    /**
     * @dev checkAndGetClient returns the client implementation for the given client ID.
     */
    function checkAndGetClient(string memory clientId) internal view returns (ILightClient) {
        address clientImpl = clientImpls[clientId];
        if (clientImpl == address(0)) {
            revert IBCHostClientNotFound(clientId);
        }
        return ILightClient(clientImpl);
    }
}

File 15 of 36 : IBCHostConfigurator.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {IBCClientLib} from "../02-client/IBCClientLib.sol";
import {ILightClient} from "../02-client/ILightClient.sol";
import {IBCModuleManager} from "../26-router/IBCModuleManager.sol";
import {IIBCModule} from "../26-router/IIBCModule.sol";
import {IIBCHostConfigurator} from "./IIBCHostConfigurator.sol";

/**
 * @dev IBCHostConfigurator is a contract that provides the host configuration.
 */
abstract contract IBCHostConfigurator is IIBCHostConfigurator, IBCModuleManager {
    function _setExpectedTimePerBlock(uint64 expectedTimePerBlock_) internal virtual {
        expectedTimePerBlock = expectedTimePerBlock_;
    }

    function _registerClient(string calldata clientType, ILightClient client) internal virtual {
        if (!IBCClientLib.validateClientType(bytes(clientType))) {
            revert IBCHostInvalidClientType(clientType);
        } else if (address(clientRegistry[clientType]) != address(0)) {
            revert IBCHostClientTypeAlreadyExists(clientType);
        }
        if (address(client) == address(0) || address(client) == address(this)) {
            revert IBCHostInvalidLightClientAddress(address(client));
        }
        clientRegistry[clientType] = address(client);
    }

    function _bindPort(string calldata portId, IIBCModule moduleAddress) internal virtual {
        if (!validatePortIdentifier(bytes(portId))) {
            revert IBCHostInvalidPortIdentifier(portId);
        }
        if (address(moduleAddress) == address(0) || address(moduleAddress) == address(this)) {
            revert IBCHostInvalidModuleAddress(address(moduleAddress));
        }
        claimPortCapability(portId, address(moduleAddress));
    }
}

File 16 of 36 : IBCStore.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {ConnectionEnd} from "../../proto/Connection.sol";
import {Channel, Upgrade} from "../../proto/Channel.sol";

abstract contract IBCStore {
    struct RecvStartSequence {
        uint64 sequence;
        uint64 prevSequence;
    }

    // Commitments
    // keccak256(IBC-compatible-store-path) => keccak256(IBC-compatible-commitment)
    mapping(bytes32 => bytes32) internal commitments;

    // Store
    mapping(string => address) internal clientRegistry; // clientType => clientImpl
    mapping(string => string) internal clientTypes; // clientID => clientType
    mapping(string => address) internal clientImpls; // clientID => clientImpl
    mapping(string => ConnectionEnd.Data) internal connections;
    mapping(string => mapping(string => Channel.Data)) internal channels;
    mapping(string => mapping(string => uint64)) internal nextSequenceSends;
    mapping(string => mapping(string => uint64)) internal nextSequenceRecvs;
    mapping(string => mapping(string => uint64)) internal nextSequenceAcks;
    mapping(string => address) internal portCapabilities;
    mapping(string => mapping(string => address)) internal channelCapabilities;

    mapping(string => mapping(string => Upgrade.Data)) internal upgrades;
    mapping(string => mapping(string => uint64)) internal latestErrorReceiptSequences;
    mapping(string => mapping(string => RecvStartSequence)) internal recvStartSequences;
    mapping(string => mapping(string => uint64)) internal ackStartSequences;

    // Host parameters
    uint64 internal expectedTimePerBlock;

    // Sequences for identifier
    uint64 internal nextClientSequence;
    uint64 internal nextConnectionSequence;
    uint64 internal nextChannelSequence;
}

File 17 of 36 : IIBCHostConfigurator.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {ILightClient} from "../02-client/ILightClient.sol";
import {IIBCModule} from "../26-router/IIBCModule.sol";

interface IIBCHostConfigurator {
    /**
     * @dev setExpectedTimePerBlock sets expected time per block.
     */
    function setExpectedTimePerBlock(uint64 expectedTimePerBlock_) external;

    /**
     * @dev registerClient registers a new client type into the client registry
     */
    function registerClient(string calldata clientType, ILightClient client) external;

    /**
     * @dev bindPort binds to an unallocated port, failing if the port has already been allocated.
     */
    function bindPort(string calldata portId, IIBCModule moduleAddress) external;
}

File 18 of 36 : IIBCHostErrors.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

interface IIBCHostErrors {
    /// @param clientType client type
    error IBCHostInvalidClientType(string clientType);

    /// @param clientType client type
    error IBCHostClientTypeAlreadyExists(string clientType);

    /// @param clientId the client identifier
    error IBCHostClientNotFound(string clientId);

    /// @param portId port identifier
    error IBCHostInvalidPortIdentifier(string portId);

    /// @param lcAddress light client contract address
    error IBCHostInvalidLightClientAddress(address lcAddress);

    /// @param moduleAddress module contract address
    error IBCHostInvalidModuleAddress(address moduleAddress);

    /// @param portId port identifier
    error IBCHostModulePortNotFound(string portId);

    /// @param portId port identifier
    /// @param channelId channel identifier
    error IBCHostModuleChannelNotFound(string portId, string channelId);

    /// @param portId port identifier
    error IBCHostPortCapabilityAlreadyClaimed(string portId);

    /// @param portId port identifier
    /// @param channelId channel identifier
    error IBCHostChannelCapabilityAlreadyClaimed(string portId, string channelId);

    /// @param portId port identifier
    /// @param channelId channel identifier
    /// @param caller caller address
    error IBCHostFailedAuthenticateChannelCapability(string portId, string channelId, address caller);
}

File 19 of 36 : IBCClientConnectionChannelHandler.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {IIBCClient} from "../02-client/IIBCClient.sol";
import {IIBCConnection} from "../03-connection/IIBCConnection.sol";
import {
    IIBCChannelHandshake, IIBCChannelPacketSendRecv, IIBCChannelPacketTimeout
} from "../04-channel/IIBCChannel.sol";
import {
    IIBCChannelUpgrade,
    IIBCChannelUpgradeInitTryAck,
    IIBCChannelUpgradeConfirmOpenTimeoutCancel
} from "../04-channel/IIBCChannelUpgrade.sol";

interface IBCHandlerViewFunctionWrapper {
    function wrappedRouteUpdateClient(IIBCClient.MsgUpdateClient calldata msg_)
        external
        view
        returns (address, bytes4, bytes memory);
}

/**
 * @dev IBCClientConnectionChannelHandler is a handler implements ICS-02, ICS-03, and ICS-04
 */
abstract contract IBCClientConnectionChannelHandler is
    IIBCClient,
    IIBCConnection,
    IIBCChannelHandshake,
    IIBCChannelPacketSendRecv,
    IIBCChannelPacketTimeout,
    IIBCChannelUpgrade
{
    address internal immutable ibcClient;
    address internal immutable ibcConnection;
    address internal immutable ibcChannelHandshake;
    address internal immutable ibcChannelPacketSendRecv;
    address internal immutable ibcChannelPacketTimeout;
    address internal immutable ibcChannelUpgradeInitTryAck;
    address internal immutable ibcChannelUpgradeConfirmOpenTimeoutCancel;

    /**
     * @dev The arguments of constructor must satisfy the followings:
     * @param ibcClient_ is the address of a contract that implements `IIBCClient`.
     * @param ibcConnection_ is the address of a contract that implements `IIBCConnection`.
     * @param ibcChannelHandshake_ is the address of a contract that implements `IIBCChannelHandshake`.
     * @param ibcChannelPacketSendRecv_ is the address of a contract that implements `IICS04Wrapper + IIBCChannelPacketReceiver`.
     * @param ibcChannelPacketTimeout_ is the address of a contract that implements `IIBCChannelPacketTimeout`.
     * @param ibcChannelUpgradeInitTryAck_ is the address of a contract that implements `IIBCChannelUpgradeInitTryAck`.
     * @param ibcChannelUpgradeConfirmOpenTimeoutCancel_ is the address of a contract that implements `IIBCChannelUpgradeConfirmOpenTimeoutCancel`.
     */
    constructor(
        IIBCClient ibcClient_,
        IIBCConnection ibcConnection_,
        IIBCChannelHandshake ibcChannelHandshake_,
        IIBCChannelPacketSendRecv ibcChannelPacketSendRecv_,
        IIBCChannelPacketTimeout ibcChannelPacketTimeout_,
        IIBCChannelUpgradeInitTryAck ibcChannelUpgradeInitTryAck_,
        IIBCChannelUpgradeConfirmOpenTimeoutCancel ibcChannelUpgradeConfirmOpenTimeoutCancel_
    ) {
        ibcClient = address(ibcClient_);
        ibcConnection = address(ibcConnection_);
        ibcChannelHandshake = address(ibcChannelHandshake_);
        ibcChannelPacketSendRecv = address(ibcChannelPacketSendRecv_);
        ibcChannelPacketTimeout = address(ibcChannelPacketTimeout_);
        ibcChannelUpgradeInitTryAck = address(ibcChannelUpgradeInitTryAck_);
        ibcChannelUpgradeConfirmOpenTimeoutCancel = address(ibcChannelUpgradeConfirmOpenTimeoutCancel_);
    }

    function createClient(MsgCreateClient calldata) external returns (string memory) {
        doFallback(ibcClient);
    }

    function updateClient(MsgUpdateClient calldata) external {
        doFallback(ibcClient);
    }

    function updateClientCommitments(string calldata, Height.Data[] calldata) external {
        doFallback(ibcClient);
    }

    function routeUpdateClient(MsgUpdateClient calldata msg_) external view returns (address, bytes4, bytes memory) {
        return IBCHandlerViewFunctionWrapper(address(this)).wrappedRouteUpdateClient(msg_);
    }

    function wrappedRouteUpdateClient(MsgUpdateClient calldata msg_) public returns (address, bytes4, bytes memory) {
        (bool success, bytes memory returndata) =
            address(ibcClient).delegatecall(abi.encodeWithSelector(IIBCClient.routeUpdateClient.selector, msg_));
        if (!success) {
            if (returndata.length > 0) {
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert("routeUpdateClient failed");
            }
        }
        return abi.decode(returndata, (address, bytes4, bytes));
    }

    function connectionOpenInit(IIBCConnection.MsgConnectionOpenInit calldata) external returns (string memory) {
        doFallback(ibcConnection);
    }

    function connectionOpenTry(IIBCConnection.MsgConnectionOpenTry calldata) external returns (string memory) {
        doFallback(ibcConnection);
    }

    function connectionOpenAck(IIBCConnection.MsgConnectionOpenAck calldata) external {
        doFallback(ibcConnection);
    }

    function connectionOpenConfirm(IIBCConnection.MsgConnectionOpenConfirm calldata) external {
        doFallback(ibcConnection);
    }

    function channelOpenInit(IIBCChannelHandshake.MsgChannelOpenInit calldata)
        external
        returns (string memory, string memory)
    {
        doFallback(ibcChannelHandshake);
    }

    function channelOpenTry(IIBCChannelHandshake.MsgChannelOpenTry calldata)
        external
        returns (string memory, string memory)
    {
        doFallback(ibcChannelHandshake);
    }

    function channelOpenAck(IIBCChannelHandshake.MsgChannelOpenAck calldata) external {
        doFallback(ibcChannelHandshake);
    }

    function channelOpenConfirm(IIBCChannelHandshake.MsgChannelOpenConfirm calldata) external {
        doFallback(ibcChannelHandshake);
    }

    function channelCloseInit(IIBCChannelHandshake.MsgChannelCloseInit calldata) external {
        doFallback(ibcChannelHandshake);
    }

    function channelCloseConfirm(IIBCChannelHandshake.MsgChannelCloseConfirm calldata) external {
        doFallback(ibcChannelHandshake);
    }

    function sendPacket(string calldata, string calldata, Height.Data calldata, uint64, bytes calldata)
        external
        returns (uint64)
    {
        doFallback(ibcChannelPacketSendRecv);
    }

    function writeAcknowledgement(string calldata, string calldata, uint64, bytes calldata) external {
        doFallback(ibcChannelPacketSendRecv);
    }

    function recvPacket(MsgPacketRecv calldata) external {
        doFallback(ibcChannelPacketSendRecv);
    }

    function acknowledgePacket(MsgPacketAcknowledgement calldata) external {
        doFallback(ibcChannelPacketSendRecv);
    }

    function timeoutPacket(MsgTimeoutPacket calldata) external {
        doFallback(ibcChannelPacketTimeout);
    }

    function timeoutOnClose(MsgTimeoutOnClose calldata) external {
        doFallback(ibcChannelPacketTimeout);
    }

    function channelUpgradeInit(MsgChannelUpgradeInit calldata) external returns (uint64) {
        doFallback(ibcChannelUpgradeInitTryAck);
    }

    function channelUpgradeTry(MsgChannelUpgradeTry calldata) external returns (bool, uint64) {
        doFallback(ibcChannelUpgradeInitTryAck);
    }

    function channelUpgradeAck(MsgChannelUpgradeAck calldata) external returns (bool) {
        doFallback(ibcChannelUpgradeInitTryAck);
    }

    function channelUpgradeConfirm(MsgChannelUpgradeConfirm calldata) external returns (bool) {
        doFallback(ibcChannelUpgradeConfirmOpenTimeoutCancel);
    }

    function channelUpgradeOpen(MsgChannelUpgradeOpen calldata) external {
        doFallback(ibcChannelUpgradeConfirmOpenTimeoutCancel);
    }

    function cancelChannelUpgrade(MsgCancelChannelUpgrade calldata) external {
        doFallback(ibcChannelUpgradeConfirmOpenTimeoutCancel);
    }

    function timeoutChannelUpgrade(MsgTimeoutChannelUpgrade calldata) external {
        doFallback(ibcChannelUpgradeConfirmOpenTimeoutCancel);
    }

    function doFallback(address impl) internal virtual {
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }
}

File 20 of 36 : IBCHandler.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {IIBCClient} from "../02-client/IIBCClient.sol";
import {IIBCConnection} from "../03-connection/IIBCConnection.sol";
import {
    IIBCChannelHandshake, IIBCChannelPacketSendRecv, IIBCChannelPacketTimeout
} from "../04-channel/IIBCChannel.sol";
import {
    IIBCChannelUpgradeInitTryAck,
    IIBCChannelUpgradeConfirmOpenTimeoutCancel
} from "../04-channel/IIBCChannelUpgrade.sol";
import {IBCHostConfigurator} from "../24-host/IBCHostConfigurator.sol";
import {IBCClientConnectionChannelHandler} from "./IBCClientConnectionChannelHandler.sol";
import {IBCQuerier} from "./IBCQuerier.sol";
import {IIBCHandler} from "./IIBCHandler.sol";

abstract contract IBCHandler is IBCHostConfigurator, IBCClientConnectionChannelHandler, IBCQuerier, IIBCHandler {
    /**
     * @dev The arguments of constructor must satisfy the followings:
     * @param ibcClient_ is the address of a contract that implements `IIBCClient`.
     * @param ibcConnection_ is the address of a contract that implements `IIBCConnection`.
     * @param ibcChannelHandshake_ is the address of a contract that implements `IIBCChannelHandshake`.
     * @param ibcChannelPacketSendRecv_ is the address of a contract that implements `IIBCChannelPacketSendRecv`.
     * @param ibcChannelPacketTimeout_ is the address of a contract that implements `IIBCChannelPacketTimeout`.
     * @param ibcChannelUpgradeInitTryAck_ is the address of a contract that implements `IIBCChannelUpgrade`.
     * @param ibcChannelUpgradeConfirmOpenTimeoutCancel_ is the address of a contract that implements `IIBCChannelUpgrade`.
     */
    constructor(
        IIBCClient ibcClient_,
        IIBCConnection ibcConnection_,
        IIBCChannelHandshake ibcChannelHandshake_,
        IIBCChannelPacketSendRecv ibcChannelPacketSendRecv_,
        IIBCChannelPacketTimeout ibcChannelPacketTimeout_,
        IIBCChannelUpgradeInitTryAck ibcChannelUpgradeInitTryAck_,
        IIBCChannelUpgradeConfirmOpenTimeoutCancel ibcChannelUpgradeConfirmOpenTimeoutCancel_
    )
        IBCClientConnectionChannelHandler(
            ibcClient_,
            ibcConnection_,
            ibcChannelHandshake_,
            ibcChannelPacketSendRecv_,
            ibcChannelPacketTimeout_,
            ibcChannelUpgradeInitTryAck_,
            ibcChannelUpgradeConfirmOpenTimeoutCancel_
        )
    {}
}

File 21 of 36 : IBCQuerier.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {ConnectionEnd} from "../../proto/Connection.sol";
import {Channel, Upgrade} from "../../proto/Channel.sol";
import {IBCChannelLib} from "../04-channel/IBCChannelLib.sol";
import {IBCHost} from "../24-host/IBCHost.sol";
import {IBCCommitment} from "../24-host/IBCCommitment.sol";
import {IIBCQuerier} from "./IIBCQuerier.sol";

contract IBCQuerier is IBCHost, IIBCQuerier {
    function getClientByType(string calldata clientType) external view returns (address) {
        return clientRegistry[clientType];
    }

    function getClientType(string calldata clientId) external view returns (string memory) {
        return clientTypes[clientId];
    }

    function getClient(string calldata clientId) external view returns (address) {
        return clientImpls[clientId];
    }

    function getClientState(string calldata clientId) external view returns (bytes memory, bool) {
        return checkAndGetClient(clientId).getClientState(clientId);
    }

    function getConsensusState(string calldata clientId, Height.Data calldata height)
        external
        view
        returns (bytes memory consensusStateBytes, bool)
    {
        return checkAndGetClient(clientId).getConsensusState(clientId, height);
    }

    function getConnection(string calldata connectionId) external view returns (ConnectionEnd.Data memory, bool) {
        ConnectionEnd.Data storage connection = connections[connectionId];
        return (connection, connection.state != ConnectionEnd.State.STATE_UNINITIALIZED_UNSPECIFIED);
    }

    function getChannel(string calldata portId, string calldata channelId)
        external
        view
        returns (Channel.Data memory, bool)
    {
        Channel.Data storage channel = channels[portId][channelId];
        return (channel, channel.state != Channel.State.STATE_UNINITIALIZED_UNSPECIFIED);
    }

    function getNextSequenceSend(string calldata portId, string calldata channelId) external view returns (uint64) {
        return nextSequenceSends[portId][channelId];
    }

    function getNextSequenceRecv(string calldata portId, string calldata channelId) external view returns (uint64) {
        return nextSequenceRecvs[portId][channelId];
    }

    function getNextSequenceAck(string calldata portId, string calldata channelId) external view returns (uint64) {
        return nextSequenceAcks[portId][channelId];
    }

    function getPacketReceipt(string calldata portId, string calldata channelId, uint64 sequence)
        external
        view
        returns (IBCChannelLib.PacketReceipt)
    {
        return IBCChannelLib.receiptCommitmentToReceipt(
            commitments[IBCCommitment.packetReceiptCommitmentKeyCalldata(portId, channelId, sequence)]
        );
    }

    function getCommitmentPrefix() external view returns (bytes memory) {
        return _getCommitmentPrefix();
    }

    function getCommitment(bytes32 hashedPath) public view returns (bytes32) {
        return commitments[hashedPath];
    }

    function getExpectedTimePerBlock() external view returns (uint64) {
        return expectedTimePerBlock;
    }

    function getChannelUpgrade(string calldata portId, string calldata channelId)
        external
        view
        returns (Upgrade.Data memory, bool)
    {
        Upgrade.Data storage upgrade = upgrades[portId][channelId];
        return (upgrade, upgrade.fields.connection_hops.length != 0);
    }
}

File 22 of 36 : IIBCHandler.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {IIBCClient} from "../02-client/IIBCClient.sol";
import {IIBCClientErrors} from "../02-client/IIBCClientErrors.sol";
import {IIBCConnection} from "../03-connection/IIBCConnection.sol";
import {IIBCConnectionErrors} from "../03-connection/IIBCConnectionErrors.sol";
import {IIBCChannelHandshake, IIBCChannelPacket} from "../04-channel/IIBCChannel.sol";
import {IIBCChannelErrors} from "../04-channel/IIBCChannelErrors.sol";
import {IIBCChannelUpgrade} from "../04-channel/IIBCChannelUpgrade.sol";
import {IIBCChannelUpgradeErrors} from "../04-channel/IIBCChannelUpgradeErrors.sol";
import {IIBCHostConfigurator} from "../24-host/IIBCHostConfigurator.sol";
import {IIBCHostErrors} from "../24-host/IIBCHostErrors.sol";
import {IIBCQuerier} from "./IIBCQuerier.sol";

/**
 * @dev IIBCHandler is a handler interface supports [ICS-25](https://github.com/cosmos/ibc/tree/main/spec/core/ics-025-handler-interface),
 */
interface IIBCHandler is
    IIBCClient,
    IIBCClientErrors,
    IIBCConnection,
    IIBCConnectionErrors,
    IIBCChannelHandshake,
    IIBCChannelPacket,
    IIBCChannelErrors,
    IIBCChannelUpgrade,
    IIBCChannelUpgradeErrors,
    IIBCHostConfigurator,
    IIBCHostErrors,
    IIBCQuerier
{}

File 23 of 36 : IIBCQuerier.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Height} from "../../proto/Client.sol";
import {ConnectionEnd} from "../../proto/Connection.sol";
import {Channel, Upgrade} from "../../proto/Channel.sol";
import {IBCChannelLib} from "../04-channel/IBCChannelLib.sol";

interface IIBCQuerier {
    function getClientByType(string calldata clientType) external view returns (address);

    function getClientType(string calldata clientId) external view returns (string memory);

    function getClient(string calldata clientId) external view returns (address);

    function getClientState(string calldata clientId) external view returns (bytes memory, bool);

    function getConsensusState(string calldata clientId, Height.Data calldata height)
        external
        view
        returns (bytes memory, bool);

    function getConnection(string calldata connectionId) external view returns (ConnectionEnd.Data memory, bool);

    function getChannel(string calldata portId, string calldata channelId)
        external
        view
        returns (Channel.Data memory, bool);

    function getNextSequenceSend(string calldata portId, string calldata channelId) external view returns (uint64);

    function getNextSequenceRecv(string calldata portId, string calldata channelId) external view returns (uint64);

    function getNextSequenceAck(string calldata portId, string calldata channelId) external view returns (uint64);

    function getPacketReceipt(string calldata portId, string calldata channelId, uint64 sequence)
        external
        view
        returns (IBCChannelLib.PacketReceipt);

    function getCommitmentPrefix() external view returns (bytes memory);

    function getCommitment(bytes32 hashedPath) external view returns (bytes32);

    function getExpectedTimePerBlock() external view returns (uint64);

    function getChannelUpgrade(string calldata portId, string calldata channelId)
        external
        view
        returns (Upgrade.Data memory, bool);
}

File 24 of 36 : IBCModuleManager.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Context} from "@openzeppelin/contracts/utils/Context.sol";
import {IBCHost} from "../24-host/IBCHost.sol";
import {IIBCModule} from "./IIBCModule.sol";

/**
 * @dev IBCModuleManager is a contract that provides the functions defined in [ICS 5](https://github.com/cosmos/ibc/tree/main/spec/core/ics-005-port-allocation) and [ICS 26](https://github.com/cosmos/ibc/tree/main/spec/core/ics-026-routing-module).
 */
contract IBCModuleManager is IBCHost, Context {
    /**
     * @dev lookupModuleByPort will return the IBCModule along with the capability associated with a given portID
     */
    function lookupModuleByPort(string calldata portId) internal view virtual returns (IIBCModule) {
        address module = portCapabilities[portId];
        if (module == address(0)) {
            revert IBCHostModulePortNotFound(portId);
        }
        return IIBCModule(module);
    }

    /**
     * @dev lookupModuleByChannel will return the IBCModule along with the capability associated with a given channel defined by its portID and channelID
     */
    function lookupModuleByChannel(string calldata portId, string calldata channelId)
        internal
        view
        virtual
        returns (IIBCModule)
    {
        address module = channelCapabilities[portId][channelId];
        if (module == address(0)) {
            revert IBCHostModuleChannelNotFound(portId, channelId);
        }
        return IIBCModule(module);
    }

    function claimPortCapability(string calldata portId, address addr) internal {
        if (portCapabilities[portId] != address(0)) {
            revert IBCHostPortCapabilityAlreadyClaimed(portId);
        }
        portCapabilities[portId] = addr;
    }

    /**
     * @dev claimCapability allows the IBC app module to claim a capability that core IBC passes to it
     */
    function claimChannelCapability(string calldata portId, string memory channelId, address addr) internal {
        if (channelCapabilities[portId][channelId] != address(0)) {
            revert IBCHostChannelCapabilityAlreadyClaimed(portId, channelId);
        }
        channelCapabilities[portId][channelId] = addr;
    }

    /**
     * @dev authenticateChannelCapability attempts to authenticate a given name from a caller.
     * It allows for a caller to check that a capability does in fact correspond to a particular name.
     */
    function authenticateChannelCapability(string calldata portId, string calldata channelId) internal view {
        if (channelCapabilities[portId][channelId] != _msgSender()) {
            revert IBCHostFailedAuthenticateChannelCapability(portId, channelId, _msgSender());
        }
    }

    /**
     * @dev validatePortIdentifier validates a port identifier string
     *     check if the string consist of characters in one of the following categories only:
     *     - Alphanumeric
     *     - `.`, `_`, `+`, `-`, `#`
     *     - `[`, `]`, `<`, `>`
     */
    function validatePortIdentifier(bytes memory portId) internal pure returns (bool) {
        if (portId.length < 2 || portId.length > 128) {
            return false;
        }
        unchecked {
            for (uint256 i = 0; i < portId.length; i++) {
                uint256 c = uint256(uint8(portId[i]));
                if (
                    // a-z
                    (c >= 0x61 && c <= 0x7A)
                    // 0-9
                    || (c >= 0x30 && c <= 0x39)
                    // A-Z
                    || (c >= 0x41 && c <= 0x5A)
                    // ".", "_", "+", "-"
                    || (c == 0x2E || c == 0x5F || c == 0x2B || c == 0x2D)
                    // "#", "[", "]", "<", ">"
                    || (c == 0x23 || c == 0x5B || c == 0x5D || c == 0x3C || c == 0x3E)
                ) {
                    continue;
                }
            }
        }
        return true;
    }
}

File 25 of 36 : IIBCModule.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import {Channel, ChannelCounterparty} from "../../proto/Channel.sol";
import {Packet} from "../04-channel/IIBCChannel.sol";

// IIBCModule defines an interface that implements all the callbacks
// that modules must define as specified in ICS-26
interface IIBCModule {
    struct MsgOnChanOpenInit {
        Channel.Order order;
        string[] connectionHops;
        string portId;
        string channelId;
        ChannelCounterparty.Data counterparty;
        string version;
    }

    struct MsgOnChanOpenTry {
        Channel.Order order;
        string[] connectionHops;
        string portId;
        string channelId;
        ChannelCounterparty.Data counterparty;
        string counterpartyVersion;
    }

    struct MsgOnChanOpenAck {
        string portId;
        string channelId;
        string counterpartyVersion;
    }

    struct MsgOnChanOpenConfirm {
        string portId;
        string channelId;
    }

    struct MsgOnChanCloseInit {
        string portId;
        string channelId;
    }

    struct MsgOnChanCloseConfirm {
        string portId;
        string channelId;
    }

    /**
     * @dev onChanOpenInit will verify that the relayer-chosen parameters
     * are valid and perform any custom INIT logic.
     * It may return an error if the chosen parameters are invalid
     * in which case the handshake is aborted.
     * If the provided version string is non-empty, OnChanOpenInit should return
     * the version string if valid or an error if the provided version is invalid.
     * If the version string is empty, OnChanOpenInit is expected to
     * return a default version string representing the version(s) it supports.
     * If there is no default version string for the application,
     * it should return an error if provided version is empty string.
     */
    function onChanOpenInit(MsgOnChanOpenInit calldata msg_) external returns (string memory);

    /**
     * @dev onChanOpenTry will verify the relayer-chosen parameters along with the
     * counterparty-chosen version string and perform custom TRY logic.
     * If the relayer-chosen parameters are invalid, the callback must return
     * an error to abort the handshake. If the counterparty-chosen version is not
     * compatible with this modules supported versions, the callback must return
     * an error to abort the handshake. If the versions are compatible, the try callback
     * must select the final version string and return it to core IBC.
     * OnChanOpenTry may also perform custom initialization logic
     */
    function onChanOpenTry(MsgOnChanOpenTry calldata msg_) external returns (string memory);

    /**
     * @dev OnChanOpenAck will error if the counterparty selected version string
     * is invalid to abort the handshake. It may also perform custom ACK logic.
     */
    function onChanOpenAck(MsgOnChanOpenAck calldata msd_) external;

    /**
     * @dev OnChanOpenConfirm will perform custom CONFIRM logic and may error to abort the handshake.
     */
    function onChanOpenConfirm(MsgOnChanOpenConfirm calldata msg_) external;

    /**
     * @dev OnChanCloseInit will perform custom CLOSE_INIT logic and may error to abort the handshake.
     * NOTE: If the application does not allow the channel to be closed, this function must revert.
     */
    function onChanCloseInit(MsgOnChanCloseInit calldata msg_) external;

    /**
     * @dev OnChanCloseConfirm will perform custom CLOSE_CONFIRM logic and may error to abort the handshake.
     */
    function onChanCloseConfirm(MsgOnChanCloseConfirm calldata msg_) external;

    /**
     * @dev OnRecvPacket must return an acknowledgement that implements the Acknowledgement interface.
     * In the case of an asynchronous acknowledgement, nil should be returned.
     * If the acknowledgement returned is successful, the state changes on callback are written,
     * otherwise the application state changes are discarded. In either case the packet is received
     * and the acknowledgement is written (in synchronous cases).
     */
    function onRecvPacket(Packet calldata, address relayer) external returns (bytes memory);

    /**
     * @dev onAcknowledgementPacket is called when a packet sent by this module has been acknowledged.
     */
    function onAcknowledgementPacket(Packet calldata, bytes calldata acknowledgement, address relayer) external;

    /**
     * @dev onTimeoutPacket is called when a packet sent by this module has timed-out (such that it will not be received on the destination chain).
     */
    function onTimeoutPacket(Packet calldata, address relayer) external;
}

File 26 of 36 : Channel.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;
import "./ProtoBufRuntime.sol";
import "./GoogleProtobufAny.sol";
import "./Client.sol";

library Channel {

  //enum definition
  // Solidity enum definitions
  enum State {
    STATE_UNINITIALIZED_UNSPECIFIED,
    STATE_INIT,
    STATE_TRYOPEN,
    STATE_OPEN,
    STATE_CLOSED,
    STATE_FLUSHING,
    STATE_FLUSHCOMPLETE
  }


  // Solidity enum encoder
  function encode_State(State x) internal pure returns (int32) {
    
    if (x == State.STATE_UNINITIALIZED_UNSPECIFIED) {
      return 0;
    }

    if (x == State.STATE_INIT) {
      return 1;
    }

    if (x == State.STATE_TRYOPEN) {
      return 2;
    }

    if (x == State.STATE_OPEN) {
      return 3;
    }

    if (x == State.STATE_CLOSED) {
      return 4;
    }

    if (x == State.STATE_FLUSHING) {
      return 5;
    }

    if (x == State.STATE_FLUSHCOMPLETE) {
      return 6;
    }
    revert();
  }


  // Solidity enum decoder
  function decode_State(int64 x) internal pure returns (State) {
    
    if (x == 0) {
      return State.STATE_UNINITIALIZED_UNSPECIFIED;
    }

    if (x == 1) {
      return State.STATE_INIT;
    }

    if (x == 2) {
      return State.STATE_TRYOPEN;
    }

    if (x == 3) {
      return State.STATE_OPEN;
    }

    if (x == 4) {
      return State.STATE_CLOSED;
    }

    if (x == 5) {
      return State.STATE_FLUSHING;
    }

    if (x == 6) {
      return State.STATE_FLUSHCOMPLETE;
    }
    revert();
  }


  /**
   * @dev The estimator for an packed enum array
   * @return The number of bytes encoded
   */
  function estimate_packed_repeated_State(
    State[] memory a
  ) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += ProtoBufRuntime._sz_enum(encode_State(a[i]));
    }
    return e;
  }

  // Solidity enum definitions
  enum Order {
    ORDER_NONE_UNSPECIFIED,
    ORDER_UNORDERED,
    ORDER_ORDERED
  }


  // Solidity enum encoder
  function encode_Order(Order x) internal pure returns (int32) {
    
    if (x == Order.ORDER_NONE_UNSPECIFIED) {
      return 0;
    }

    if (x == Order.ORDER_UNORDERED) {
      return 1;
    }

    if (x == Order.ORDER_ORDERED) {
      return 2;
    }
    revert();
  }


  // Solidity enum decoder
  function decode_Order(int64 x) internal pure returns (Order) {
    
    if (x == 0) {
      return Order.ORDER_NONE_UNSPECIFIED;
    }

    if (x == 1) {
      return Order.ORDER_UNORDERED;
    }

    if (x == 2) {
      return Order.ORDER_ORDERED;
    }
    revert();
  }


  /**
   * @dev The estimator for an packed enum array
   * @return The number of bytes encoded
   */
  function estimate_packed_repeated_Order(
    Order[] memory a
  ) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += ProtoBufRuntime._sz_enum(encode_Order(a[i]));
    }
    return e;
  }

  //struct definition
  struct Data {
    Channel.State state;
    Channel.Order ordering;
    ChannelCounterparty.Data counterparty;
    string[] connection_hops;
    string version;
    uint64 upgrade_sequence;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint[7] memory counters;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_state(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_ordering(pointer, bs, r);
      } else
      if (fieldId == 3) {
        pointer += _read_counterparty(pointer, bs, r);
      } else
      if (fieldId == 4) {
        pointer += _read_unpacked_repeated_connection_hops(pointer, bs, nil(), counters);
      } else
      if (fieldId == 5) {
        pointer += _read_version(pointer, bs, r);
      } else
      if (fieldId == 6) {
        pointer += _read_upgrade_sequence(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    pointer = offset;
    if (counters[4] > 0) {
      require(r.connection_hops.length == 0);
      r.connection_hops = new string[](counters[4]);
    }

    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 4) {
        pointer += _read_unpacked_repeated_connection_hops(pointer, bs, r, counters);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }
    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_state(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (int64 tmp, uint256 sz) = ProtoBufRuntime._decode_enum(p, bs);
    Channel.State x = decode_State(tmp);
    r.state = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_ordering(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (int64 tmp, uint256 sz) = ProtoBufRuntime._decode_enum(p, bs);
    Channel.Order x = decode_Order(tmp);
    r.ordering = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_counterparty(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (ChannelCounterparty.Data memory x, uint256 sz) = _decode_ChannelCounterparty(p, bs);
    r.counterparty = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @param counters The counters for repeated fields
   * @return The number of bytes decoded
   */
  function _read_unpacked_repeated_connection_hops(
    uint256 p,
    bytes memory bs,
    Data memory r,
    uint[7] memory counters
  ) internal pure returns (uint) {
    /**
     * if `r` is NULL, then only counting the number of fields.
     */
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    if (isNil(r)) {
      counters[4] += 1;
    } else {
      r.connection_hops[r.connection_hops.length - counters[4]] = x;
      counters[4] -= 1;
    }
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_version(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.version = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_upgrade_sequence(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (uint64 x, uint256 sz) = ProtoBufRuntime._decode_uint64(p, bs);
    r.upgrade_sequence = x;
    return sz;
  }

  // struct decoder
  /**
   * @dev The decoder for reading a inner struct field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The decoded inner-struct
   * @return The number of bytes used to decode
   */
  function _decode_ChannelCounterparty(uint256 p, bytes memory bs)
    internal
    pure
    returns (ChannelCounterparty.Data memory, uint)
  {
    uint256 pointer = p;
    (uint256 sz, uint256 bytesRead) = ProtoBufRuntime._decode_varint(pointer, bs);
    pointer += bytesRead;
    (ChannelCounterparty.Data memory r, ) = ChannelCounterparty._decode(pointer, bs, sz);
    return (r, sz + bytesRead);
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    uint256 i;
    if (uint(r.state) != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    int32 _enum_state = encode_State(r.state);
    pointer += ProtoBufRuntime._encode_enum(_enum_state, pointer, bs);
    }
    if (uint(r.ordering) != 0) {
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    int32 _enum_ordering = encode_Order(r.ordering);
    pointer += ProtoBufRuntime._encode_enum(_enum_ordering, pointer, bs);
    }
    
    pointer += ProtoBufRuntime._encode_key(
      3,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ChannelCounterparty._encode_nested(r.counterparty, pointer, bs);
    
    if (r.connection_hops.length != 0) {
    for(i = 0; i < r.connection_hops.length; i++) {
      pointer += ProtoBufRuntime._encode_key(
        4,
        ProtoBufRuntime.WireType.LengthDelim,
        pointer,
        bs)
      ;
      pointer += ProtoBufRuntime._encode_string(r.connection_hops[i], pointer, bs);
    }
    }
    if (bytes(r.version).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      5,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.version, pointer, bs);
    }
    if (r.upgrade_sequence != 0) {
    pointer += ProtoBufRuntime._encode_key(
      6,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_uint64(r.upgrade_sequence, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;uint256 i;
    e += 1 + ProtoBufRuntime._sz_enum(encode_State(r.state));
    e += 1 + ProtoBufRuntime._sz_enum(encode_Order(r.ordering));
    e += 1 + ProtoBufRuntime._sz_lendelim(ChannelCounterparty._estimate(r.counterparty));
    for(i = 0; i < r.connection_hops.length; i++) {
      e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.connection_hops[i]).length);
    }
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.version).length);
    e += 1 + ProtoBufRuntime._sz_uint64(r.upgrade_sequence);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (uint(r.state) != 0) {
    return false;
  }

  if (uint(r.ordering) != 0) {
    return false;
  }

  if (r.connection_hops.length != 0) {
    return false;
  }

  if (bytes(r.version).length != 0) {
    return false;
  }

  if (r.upgrade_sequence != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.state = input.state;
    output.ordering = input.ordering;
    ChannelCounterparty.store(input.counterparty, output.counterparty);
    output.connection_hops = input.connection_hops;
    output.version = input.version;
    output.upgrade_sequence = input.upgrade_sequence;

  }


  //array helpers for ConnectionHops
  /**
   * @dev Add value to an array
   * @param self The in-memory struct
   * @param value The value to add
   */
  function addConnectionHops(Data memory self, string memory value) internal pure {
    /**
     * First resize the array. Then add the new element to the end.
     */
    string[] memory tmp = new string[](self.connection_hops.length + 1);
    for (uint256 i = 0; i < self.connection_hops.length; i++) {
      tmp[i] = self.connection_hops[i];
    }
    tmp[self.connection_hops.length] = value;
    self.connection_hops = tmp;
  }


  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library Channel

library ChannelCounterparty {


  //struct definition
  struct Data {
    string port_id;
    string channel_id;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_port_id(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_channel_id(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_port_id(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.port_id = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_channel_id(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.channel_id = x;
    return sz;
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    
    if (bytes(r.port_id).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.port_id, pointer, bs);
    }
    if (bytes(r.channel_id).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.channel_id, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.port_id).length);
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.channel_id).length);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (bytes(r.port_id).length != 0) {
    return false;
  }

  if (bytes(r.channel_id).length != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.port_id = input.port_id;
    output.channel_id = input.channel_id;

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library ChannelCounterparty

library Timeout {


  //struct definition
  struct Data {
    Height.Data height;
    uint64 timestamp;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_height(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_timestamp(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_height(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (Height.Data memory x, uint256 sz) = _decode_Height(p, bs);
    r.height = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_timestamp(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (uint64 x, uint256 sz) = ProtoBufRuntime._decode_uint64(p, bs);
    r.timestamp = x;
    return sz;
  }

  // struct decoder
  /**
   * @dev The decoder for reading a inner struct field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The decoded inner-struct
   * @return The number of bytes used to decode
   */
  function _decode_Height(uint256 p, bytes memory bs)
    internal
    pure
    returns (Height.Data memory, uint)
  {
    uint256 pointer = p;
    (uint256 sz, uint256 bytesRead) = ProtoBufRuntime._decode_varint(pointer, bs);
    pointer += bytesRead;
    (Height.Data memory r, ) = Height._decode(pointer, bs, sz);
    return (r, sz + bytesRead);
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    
    
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += Height._encode_nested(r.height, pointer, bs);
    
    if (r.timestamp != 0) {
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_uint64(r.timestamp, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_lendelim(Height._estimate(r.height));
    e += 1 + ProtoBufRuntime._sz_uint64(r.timestamp);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (r.timestamp != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    Height.store(input.height, output.height);
    output.timestamp = input.timestamp;

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library Timeout

library Upgrade {


  //struct definition
  struct Data {
    UpgradeFields.Data fields;
    Timeout.Data timeout;
    uint64 next_sequence_send;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_fields(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_timeout(pointer, bs, r);
      } else
      if (fieldId == 3) {
        pointer += _read_next_sequence_send(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_fields(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (UpgradeFields.Data memory x, uint256 sz) = _decode_UpgradeFields(p, bs);
    r.fields = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_timeout(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (Timeout.Data memory x, uint256 sz) = _decode_Timeout(p, bs);
    r.timeout = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_next_sequence_send(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (uint64 x, uint256 sz) = ProtoBufRuntime._decode_uint64(p, bs);
    r.next_sequence_send = x;
    return sz;
  }

  // struct decoder
  /**
   * @dev The decoder for reading a inner struct field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The decoded inner-struct
   * @return The number of bytes used to decode
   */
  function _decode_UpgradeFields(uint256 p, bytes memory bs)
    internal
    pure
    returns (UpgradeFields.Data memory, uint)
  {
    uint256 pointer = p;
    (uint256 sz, uint256 bytesRead) = ProtoBufRuntime._decode_varint(pointer, bs);
    pointer += bytesRead;
    (UpgradeFields.Data memory r, ) = UpgradeFields._decode(pointer, bs, sz);
    return (r, sz + bytesRead);
  }

  /**
   * @dev The decoder for reading a inner struct field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The decoded inner-struct
   * @return The number of bytes used to decode
   */
  function _decode_Timeout(uint256 p, bytes memory bs)
    internal
    pure
    returns (Timeout.Data memory, uint)
  {
    uint256 pointer = p;
    (uint256 sz, uint256 bytesRead) = ProtoBufRuntime._decode_varint(pointer, bs);
    pointer += bytesRead;
    (Timeout.Data memory r, ) = Timeout._decode(pointer, bs, sz);
    return (r, sz + bytesRead);
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    
    
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += UpgradeFields._encode_nested(r.fields, pointer, bs);
    
    
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += Timeout._encode_nested(r.timeout, pointer, bs);
    
    if (r.next_sequence_send != 0) {
    pointer += ProtoBufRuntime._encode_key(
      3,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_uint64(r.next_sequence_send, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_lendelim(UpgradeFields._estimate(r.fields));
    e += 1 + ProtoBufRuntime._sz_lendelim(Timeout._estimate(r.timeout));
    e += 1 + ProtoBufRuntime._sz_uint64(r.next_sequence_send);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (r.next_sequence_send != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    UpgradeFields.store(input.fields, output.fields);
    Timeout.store(input.timeout, output.timeout);
    output.next_sequence_send = input.next_sequence_send;

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library Upgrade

library UpgradeFields {


  //struct definition
  struct Data {
    Channel.Order ordering;
    string[] connection_hops;
    string version;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint[4] memory counters;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_ordering(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_unpacked_repeated_connection_hops(pointer, bs, nil(), counters);
      } else
      if (fieldId == 3) {
        pointer += _read_version(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    pointer = offset;
    if (counters[2] > 0) {
      require(r.connection_hops.length == 0);
      r.connection_hops = new string[](counters[2]);
    }

    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 2) {
        pointer += _read_unpacked_repeated_connection_hops(pointer, bs, r, counters);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }
    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_ordering(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (int64 tmp, uint256 sz) = ProtoBufRuntime._decode_enum(p, bs);
    Channel.Order x = Channel.decode_Order(tmp);
    r.ordering = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @param counters The counters for repeated fields
   * @return The number of bytes decoded
   */
  function _read_unpacked_repeated_connection_hops(
    uint256 p,
    bytes memory bs,
    Data memory r,
    uint[4] memory counters
  ) internal pure returns (uint) {
    /**
     * if `r` is NULL, then only counting the number of fields.
     */
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    if (isNil(r)) {
      counters[2] += 1;
    } else {
      r.connection_hops[r.connection_hops.length - counters[2]] = x;
      counters[2] -= 1;
    }
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_version(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.version = x;
    return sz;
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    uint256 i;
    if (uint(r.ordering) != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    int32 _enum_ordering = Channel.encode_Order(r.ordering);
    pointer += ProtoBufRuntime._encode_enum(_enum_ordering, pointer, bs);
    }
    if (r.connection_hops.length != 0) {
    for(i = 0; i < r.connection_hops.length; i++) {
      pointer += ProtoBufRuntime._encode_key(
        2,
        ProtoBufRuntime.WireType.LengthDelim,
        pointer,
        bs)
      ;
      pointer += ProtoBufRuntime._encode_string(r.connection_hops[i], pointer, bs);
    }
    }
    if (bytes(r.version).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      3,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.version, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;uint256 i;
    e += 1 + ProtoBufRuntime._sz_enum(Channel.encode_Order(r.ordering));
    for(i = 0; i < r.connection_hops.length; i++) {
      e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.connection_hops[i]).length);
    }
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.version).length);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (uint(r.ordering) != 0) {
    return false;
  }

  if (r.connection_hops.length != 0) {
    return false;
  }

  if (bytes(r.version).length != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.ordering = input.ordering;
    output.connection_hops = input.connection_hops;
    output.version = input.version;

  }


  //array helpers for ConnectionHops
  /**
   * @dev Add value to an array
   * @param self The in-memory struct
   * @param value The value to add
   */
  function addConnectionHops(Data memory self, string memory value) internal pure {
    /**
     * First resize the array. Then add the new element to the end.
     */
    string[] memory tmp = new string[](self.connection_hops.length + 1);
    for (uint256 i = 0; i < self.connection_hops.length; i++) {
      tmp[i] = self.connection_hops[i];
    }
    tmp[self.connection_hops.length] = value;
    self.connection_hops = tmp;
  }


  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library UpgradeFields

library ErrorReceipt {


  //struct definition
  struct Data {
    uint64 sequence;
    string message;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_sequence(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_message(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_sequence(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (uint64 x, uint256 sz) = ProtoBufRuntime._decode_uint64(p, bs);
    r.sequence = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_message(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.message = x;
    return sz;
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    
    if (r.sequence != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_uint64(r.sequence, pointer, bs);
    }
    if (bytes(r.message).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.message, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_uint64(r.sequence);
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.message).length);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (r.sequence != 0) {
    return false;
  }

  if (bytes(r.message).length != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.sequence = input.sequence;
    output.message = input.message;

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library ErrorReceipt

File 27 of 36 : Client.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;
import "./ProtoBufRuntime.sol";
import "./GoogleProtobufAny.sol";

library Height {


  //struct definition
  struct Data {
    uint64 revision_number;
    uint64 revision_height;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_revision_number(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_revision_height(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_revision_number(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (uint64 x, uint256 sz) = ProtoBufRuntime._decode_uint64(p, bs);
    r.revision_number = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_revision_height(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (uint64 x, uint256 sz) = ProtoBufRuntime._decode_uint64(p, bs);
    r.revision_height = x;
    return sz;
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    
    if (r.revision_number != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_uint64(r.revision_number, pointer, bs);
    }
    if (r.revision_height != 0) {
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_uint64(r.revision_height, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_uint64(r.revision_number);
    e += 1 + ProtoBufRuntime._sz_uint64(r.revision_height);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (r.revision_number != 0) {
    return false;
  }

  if (r.revision_height != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.revision_number = input.revision_number;
    output.revision_height = input.revision_height;

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library Height

File 28 of 36 : Commitment.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;
import "./ProtoBufRuntime.sol";
import "./GoogleProtobufAny.sol";

library MerklePrefix {


  //struct definition
  struct Data {
    bytes key_prefix;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_key_prefix(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_key_prefix(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (bytes memory x, uint256 sz) = ProtoBufRuntime._decode_bytes(p, bs);
    r.key_prefix = x;
    return sz;
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    
    if (r.key_prefix.length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_bytes(r.key_prefix, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_lendelim(r.key_prefix.length);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (r.key_prefix.length != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.key_prefix = input.key_prefix;

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library MerklePrefix

File 29 of 36 : Connection.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;
import "./ProtoBufRuntime.sol";
import "./GoogleProtobufAny.sol";
import "./Commitment.sol";

library ConnectionEnd {

  //enum definition
  // Solidity enum definitions
  enum State {
    STATE_UNINITIALIZED_UNSPECIFIED,
    STATE_INIT,
    STATE_TRYOPEN,
    STATE_OPEN
  }


  // Solidity enum encoder
  function encode_State(State x) internal pure returns (int32) {
    
    if (x == State.STATE_UNINITIALIZED_UNSPECIFIED) {
      return 0;
    }

    if (x == State.STATE_INIT) {
      return 1;
    }

    if (x == State.STATE_TRYOPEN) {
      return 2;
    }

    if (x == State.STATE_OPEN) {
      return 3;
    }
    revert();
  }


  // Solidity enum decoder
  function decode_State(int64 x) internal pure returns (State) {
    
    if (x == 0) {
      return State.STATE_UNINITIALIZED_UNSPECIFIED;
    }

    if (x == 1) {
      return State.STATE_INIT;
    }

    if (x == 2) {
      return State.STATE_TRYOPEN;
    }

    if (x == 3) {
      return State.STATE_OPEN;
    }
    revert();
  }


  /**
   * @dev The estimator for an packed enum array
   * @return The number of bytes encoded
   */
  function estimate_packed_repeated_State(
    State[] memory a
  ) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += ProtoBufRuntime._sz_enum(encode_State(a[i]));
    }
    return e;
  }

  //struct definition
  struct Data {
    string client_id;
    Version.Data[] versions;
    ConnectionEnd.State state;
    Counterparty.Data counterparty;
    uint64 delay_period;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint[6] memory counters;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_client_id(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_unpacked_repeated_versions(pointer, bs, nil(), counters);
      } else
      if (fieldId == 3) {
        pointer += _read_state(pointer, bs, r);
      } else
      if (fieldId == 4) {
        pointer += _read_counterparty(pointer, bs, r);
      } else
      if (fieldId == 5) {
        pointer += _read_delay_period(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    pointer = offset;
    if (counters[2] > 0) {
      require(r.versions.length == 0);
      r.versions = new Version.Data[](counters[2]);
    }

    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 2) {
        pointer += _read_unpacked_repeated_versions(pointer, bs, r, counters);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }
    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_client_id(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.client_id = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @param counters The counters for repeated fields
   * @return The number of bytes decoded
   */
  function _read_unpacked_repeated_versions(
    uint256 p,
    bytes memory bs,
    Data memory r,
    uint[6] memory counters
  ) internal pure returns (uint) {
    /**
     * if `r` is NULL, then only counting the number of fields.
     */
    (Version.Data memory x, uint256 sz) = _decode_Version(p, bs);
    if (isNil(r)) {
      counters[2] += 1;
    } else {
      r.versions[r.versions.length - counters[2]] = x;
      counters[2] -= 1;
    }
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_state(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (int64 tmp, uint256 sz) = ProtoBufRuntime._decode_enum(p, bs);
    ConnectionEnd.State x = decode_State(tmp);
    r.state = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_counterparty(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (Counterparty.Data memory x, uint256 sz) = _decode_Counterparty(p, bs);
    r.counterparty = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_delay_period(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (uint64 x, uint256 sz) = ProtoBufRuntime._decode_uint64(p, bs);
    r.delay_period = x;
    return sz;
  }

  // struct decoder
  /**
   * @dev The decoder for reading a inner struct field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The decoded inner-struct
   * @return The number of bytes used to decode
   */
  function _decode_Version(uint256 p, bytes memory bs)
    internal
    pure
    returns (Version.Data memory, uint)
  {
    uint256 pointer = p;
    (uint256 sz, uint256 bytesRead) = ProtoBufRuntime._decode_varint(pointer, bs);
    pointer += bytesRead;
    (Version.Data memory r, ) = Version._decode(pointer, bs, sz);
    return (r, sz + bytesRead);
  }

  /**
   * @dev The decoder for reading a inner struct field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The decoded inner-struct
   * @return The number of bytes used to decode
   */
  function _decode_Counterparty(uint256 p, bytes memory bs)
    internal
    pure
    returns (Counterparty.Data memory, uint)
  {
    uint256 pointer = p;
    (uint256 sz, uint256 bytesRead) = ProtoBufRuntime._decode_varint(pointer, bs);
    pointer += bytesRead;
    (Counterparty.Data memory r, ) = Counterparty._decode(pointer, bs, sz);
    return (r, sz + bytesRead);
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    uint256 i;
    if (bytes(r.client_id).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.client_id, pointer, bs);
    }
    if (r.versions.length != 0) {
    for(i = 0; i < r.versions.length; i++) {
      pointer += ProtoBufRuntime._encode_key(
        2,
        ProtoBufRuntime.WireType.LengthDelim,
        pointer,
        bs)
      ;
      pointer += Version._encode_nested(r.versions[i], pointer, bs);
    }
    }
    if (uint(r.state) != 0) {
    pointer += ProtoBufRuntime._encode_key(
      3,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    int32 _enum_state = encode_State(r.state);
    pointer += ProtoBufRuntime._encode_enum(_enum_state, pointer, bs);
    }
    
    pointer += ProtoBufRuntime._encode_key(
      4,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += Counterparty._encode_nested(r.counterparty, pointer, bs);
    
    if (r.delay_period != 0) {
    pointer += ProtoBufRuntime._encode_key(
      5,
      ProtoBufRuntime.WireType.Varint,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_uint64(r.delay_period, pointer, bs);
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;uint256 i;
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.client_id).length);
    for(i = 0; i < r.versions.length; i++) {
      e += 1 + ProtoBufRuntime._sz_lendelim(Version._estimate(r.versions[i]));
    }
    e += 1 + ProtoBufRuntime._sz_enum(encode_State(r.state));
    e += 1 + ProtoBufRuntime._sz_lendelim(Counterparty._estimate(r.counterparty));
    e += 1 + ProtoBufRuntime._sz_uint64(r.delay_period);
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (bytes(r.client_id).length != 0) {
    return false;
  }

  if (r.versions.length != 0) {
    return false;
  }

  if (uint(r.state) != 0) {
    return false;
  }

  if (r.delay_period != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.client_id = input.client_id;

    for(uint256 i2 = 0; i2 < input.versions.length; i2++) {
      output.versions.push(input.versions[i2]);
    }
    
    output.state = input.state;
    Counterparty.store(input.counterparty, output.counterparty);
    output.delay_period = input.delay_period;

  }


  //array helpers for Versions
  /**
   * @dev Add value to an array
   * @param self The in-memory struct
   * @param value The value to add
   */
  function addVersions(Data memory self, Version.Data memory value) internal pure {
    /**
     * First resize the array. Then add the new element to the end.
     */
    Version.Data[] memory tmp = new Version.Data[](self.versions.length + 1);
    for (uint256 i = 0; i < self.versions.length; i++) {
      tmp[i] = self.versions[i];
    }
    tmp[self.versions.length] = value;
    self.versions = tmp;
  }


  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library ConnectionEnd

library Counterparty {


  //struct definition
  struct Data {
    string client_id;
    string connection_id;
    MerklePrefix.Data prefix;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_client_id(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_connection_id(pointer, bs, r);
      } else
      if (fieldId == 3) {
        pointer += _read_prefix(pointer, bs, r);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_client_id(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.client_id = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_connection_id(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.connection_id = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_prefix(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (MerklePrefix.Data memory x, uint256 sz) = _decode_MerklePrefix(p, bs);
    r.prefix = x;
    return sz;
  }

  // struct decoder
  /**
   * @dev The decoder for reading a inner struct field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The decoded inner-struct
   * @return The number of bytes used to decode
   */
  function _decode_MerklePrefix(uint256 p, bytes memory bs)
    internal
    pure
    returns (MerklePrefix.Data memory, uint)
  {
    uint256 pointer = p;
    (uint256 sz, uint256 bytesRead) = ProtoBufRuntime._decode_varint(pointer, bs);
    pointer += bytesRead;
    (MerklePrefix.Data memory r, ) = MerklePrefix._decode(pointer, bs, sz);
    return (r, sz + bytesRead);
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    
    if (bytes(r.client_id).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.client_id, pointer, bs);
    }
    if (bytes(r.connection_id).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.connection_id, pointer, bs);
    }
    
    pointer += ProtoBufRuntime._encode_key(
      3,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += MerklePrefix._encode_nested(r.prefix, pointer, bs);
    
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.client_id).length);
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.connection_id).length);
    e += 1 + ProtoBufRuntime._sz_lendelim(MerklePrefix._estimate(r.prefix));
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (bytes(r.client_id).length != 0) {
    return false;
  }

  if (bytes(r.connection_id).length != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.client_id = input.client_id;
    output.connection_id = input.connection_id;
    MerklePrefix.store(input.prefix, output.prefix);

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library Counterparty

library Version {


  //struct definition
  struct Data {
    string identifier;
    string[] features;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint[3] memory counters;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_identifier(pointer, bs, r);
      } else
      if (fieldId == 2) {
        pointer += _read_unpacked_repeated_features(pointer, bs, nil(), counters);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }

    }
    pointer = offset;
    if (counters[2] > 0) {
      require(r.features.length == 0);
      r.features = new string[](counters[2]);
    }

    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 2) {
        pointer += _read_unpacked_repeated_features(pointer, bs, r, counters);
      } else
      {
        pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs);
      }
    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @return The number of bytes decoded
   */
  function _read_identifier(
    uint256 p,
    bytes memory bs,
    Data memory r
  ) internal pure returns (uint) {
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    r.identifier = x;
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @param counters The counters for repeated fields
   * @return The number of bytes decoded
   */
  function _read_unpacked_repeated_features(
    uint256 p,
    bytes memory bs,
    Data memory r,
    uint[3] memory counters
  ) internal pure returns (uint) {
    /**
     * if `r` is NULL, then only counting the number of fields.
     */
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    if (isNil(r)) {
      counters[2] += 1;
    } else {
      r.features[r.features.length - counters[2]] = x;
      counters[2] -= 1;
    }
    return sz;
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;
    uint256 i;
    if (bytes(r.identifier).length != 0) {
    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.identifier, pointer, bs);
    }
    if (r.features.length != 0) {
    for(i = 0; i < r.features.length; i++) {
      pointer += ProtoBufRuntime._encode_key(
        2,
        ProtoBufRuntime.WireType.LengthDelim,
        pointer,
        bs)
      ;
      pointer += ProtoBufRuntime._encode_string(r.features[i], pointer, bs);
    }
    }
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;uint256 i;
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.identifier).length);
    for(i = 0; i < r.features.length; i++) {
      e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.features[i]).length);
    }
    return e;
  }
  // empty checker

  function _empty(
    Data memory r
  ) internal pure returns (bool) {
    
  if (bytes(r.identifier).length != 0) {
    return false;
  }

  if (r.features.length != 0) {
    return false;
  }

    return true;
  }


  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.identifier = input.identifier;
    output.features = input.features;

  }


  //array helpers for Features
  /**
   * @dev Add value to an array
   * @param self The in-memory struct
   * @param value The value to add
   */
  function addFeatures(Data memory self, string memory value) internal pure {
    /**
     * First resize the array. Then add the new element to the end.
     */
    string[] memory tmp = new string[](self.features.length + 1);
    for (uint256 i = 0; i < self.features.length; i++) {
      tmp[i] = self.features[i];
    }
    tmp[self.features.length] = value;
    self.features = tmp;
  }


  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library Version

File 30 of 36 : GoogleProtobufAny.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;
import "./ProtoBufRuntime.sol";

library GoogleProtobufAny {


  //struct definition
  struct Data {
    string type_url;
    bytes value;
  }

  // Decoder section

  /**
   * @dev The main decoder for memory
   * @param bs The bytes array to be decoded
   * @return The decoded struct
   */
  function decode(bytes memory bs) internal pure returns (Data memory) {
    (Data memory x, ) = _decode(32, bs, bs.length);
    return x;
  }

  /**
   * @dev The main decoder for storage
   * @param self The in-storage struct
   * @param bs The bytes array to be decoded
   */
  function decode(Data storage self, bytes memory bs) internal {
    (Data memory x, ) = _decode(32, bs, bs.length);
    store(x, self);
  }
  // inner decoder

  /**
   * @dev The decoder for internal usage
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param sz The number of bytes expected
   * @return The decoded struct
   * @return The number of bytes decoded
   */
  function _decode(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (Data memory, uint)
  {
    Data memory r;
    uint[3] memory counters;
    uint256 fieldId;
    ProtoBufRuntime.WireType wireType;
    uint256 bytesRead;
    uint256 offset = p;
    uint256 pointer = p;
    while (pointer < offset + sz) {
      (fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
      pointer += bytesRead;
      if (fieldId == 1) {
        pointer += _read_type_url(pointer, bs, r, counters);
      }
      else if (fieldId == 2) {
        pointer += _read_value(pointer, bs, r, counters);
      }

      else {
        if (wireType == ProtoBufRuntime.WireType.Fixed64) {
          uint256 size;
          (, size) = ProtoBufRuntime._decode_fixed64(pointer, bs);
          pointer += size;
        }
        if (wireType == ProtoBufRuntime.WireType.Fixed32) {
          uint256 size;
          (, size) = ProtoBufRuntime._decode_fixed32(pointer, bs);
          pointer += size;
        }
        if (wireType == ProtoBufRuntime.WireType.Varint) {
          uint256 size;
          (, size) = ProtoBufRuntime._decode_varint(pointer, bs);
          pointer += size;
        }
        if (wireType == ProtoBufRuntime.WireType.LengthDelim) {
          uint256 size;
          (, size) = ProtoBufRuntime._decode_lendelim(pointer, bs);
          pointer += size;
        }
      }

    }
    return (r, sz);
  }

  // field readers

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @param counters The counters for repeated fields
   * @return The number of bytes decoded
   */
  function _read_type_url(
    uint256 p,
    bytes memory bs,
    Data memory r,
    uint[3] memory counters
  ) internal pure returns (uint) {
    /**
     * if `r` is NULL, then only counting the number of fields.
     */
    (string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
    if (isNil(r)) {
      counters[1] += 1;
    } else {
      r.type_url = x;
      if (counters[1] > 0) counters[1] -= 1;
    }
    return sz;
  }

  /**
   * @dev The decoder for reading a field
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @param r The in-memory struct
   * @param counters The counters for repeated fields
   * @return The number of bytes decoded
   */
  function _read_value(
    uint256 p,
    bytes memory bs,
    Data memory r,
    uint[3] memory counters
  ) internal pure returns (uint) {
    /**
     * if `r` is NULL, then only counting the number of fields.
     */
    (bytes memory x, uint256 sz) = ProtoBufRuntime._decode_bytes(p, bs);
    if (isNil(r)) {
      counters[2] += 1;
    } else {
      r.value = x;
      if (counters[2] > 0) counters[2] -= 1;
    }
    return sz;
  }


  // Encoder section

  /**
   * @dev The main encoder for memory
   * @param r The struct to be encoded
   * @return The encoded byte array
   */
  function encode(Data memory r) internal pure returns (bytes memory) {
    bytes memory bs = new bytes(_estimate(r));
    uint256 sz = _encode(r, 32, bs);
    assembly {
      mstore(bs, sz)
    }
    return bs;
  }
  // inner encoder

  /**
   * @dev The encoder for internal usage
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    uint256 offset = p;
    uint256 pointer = p;

    pointer += ProtoBufRuntime._encode_key(
      1,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_string(r.type_url, pointer, bs);
    pointer += ProtoBufRuntime._encode_key(
      2,
      ProtoBufRuntime.WireType.LengthDelim,
      pointer,
      bs
    );
    pointer += ProtoBufRuntime._encode_bytes(r.value, pointer, bs);
    return pointer - offset;
  }
  // nested encoder

  /**
   * @dev The encoder for inner struct
   * @param r The struct to be encoded
   * @param p The offset of bytes array to start decode
   * @param bs The bytes array to be decoded
   * @return The number of bytes encoded
   */
  function _encode_nested(Data memory r, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint)
  {
    /**
     * First encoded `r` into a temporary array, and encode the actual size used.
     * Then copy the temporary array into `bs`.
     */
    uint256 offset = p;
    uint256 pointer = p;
    bytes memory tmp = new bytes(_estimate(r));
    uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
    uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
    uint256 size = _encode(r, 32, tmp);
    pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
    ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
    pointer += size;
    delete tmp;
    return pointer - offset;
  }
  // estimator

  /**
   * @dev The estimator for a struct
   * @param r The struct to be encoded
   * @return The number of bytes encoded in estimation
   */
  function _estimate(
    Data memory r
  ) internal pure returns (uint) {
    uint256 e;
    e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.type_url).length);
    e += 1 + ProtoBufRuntime._sz_lendelim(r.value.length);
    return e;
  }

  //store function
  /**
   * @dev Store in-memory struct to storage
   * @param input The in-memory struct
   * @param output The in-storage struct
   */
  function store(Data memory input, Data storage output) internal {
    output.type_url = input.type_url;
    output.value = input.value;

  }



  //utility functions
  /**
   * @dev Return an empty struct
   * @return r The empty struct
   */
  function nil() internal pure returns (Data memory r) {
    assembly {
      r := 0
    }
  }

  /**
   * @dev Test whether a struct is empty
   * @param x The struct to be tested
   * @return r True if it is empty
   */
  function isNil(Data memory x) internal pure returns (bool r) {
    assembly {
      r := iszero(x)
    }
  }
}
//library Any

File 31 of 36 : ProtoBufRuntime.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;


/**
 * @title Runtime library for ProtoBuf serialization and/or deserialization.
 * All ProtoBuf generated code will use this library.
 */
library ProtoBufRuntime {
  // Types defined in ProtoBuf
  enum WireType { Varint, Fixed64, LengthDelim, StartGroup, EndGroup, Fixed32 }
  // Constants for bytes calculation
  uint256 constant WORD_LENGTH = 32;
  uint256 constant HEADER_SIZE_LENGTH_IN_BYTES = 4;
  uint256 constant BYTE_SIZE = 8;
  uint256 constant REMAINING_LENGTH = WORD_LENGTH - HEADER_SIZE_LENGTH_IN_BYTES;
  string constant OVERFLOW_MESSAGE = "length overflow";

  //Storages
  /**
   * @dev Encode to storage location using assembly to save storage space.
   * @param location The location of storage
   * @param encoded The encoded ProtoBuf bytes
   */
  function encodeStorage(bytes storage location, bytes memory encoded)
    internal
  {
    /**
     * This code use the first four bytes as size,
     * and then put the rest of `encoded` bytes.
     */
    uint256 length = encoded.length;
    uint256 firstWord;
    uint256 wordLength = WORD_LENGTH;
    uint256 remainingLength = REMAINING_LENGTH;

    assembly {
      firstWord := mload(add(encoded, wordLength))
    }
    firstWord =
      (firstWord >> (BYTE_SIZE * HEADER_SIZE_LENGTH_IN_BYTES)) |
      (length << (BYTE_SIZE * REMAINING_LENGTH));

    assembly {
      sstore(location.slot, firstWord)
    }

    if (length > REMAINING_LENGTH) {
      length -= REMAINING_LENGTH;
      for (uint256 i = 0; i < ceil(length, WORD_LENGTH); i++) {
        assembly {
          let offset := add(mul(i, wordLength), remainingLength)
          let slotIndex := add(i, 1)
          sstore(
            add(location.slot, slotIndex),
            mload(add(add(encoded, wordLength), offset))
          )
        }
      }
    }
  }

  /**
   * @dev Decode storage location using assembly using the format in `encodeStorage`.
   * @param location The location of storage
   * @return The encoded bytes
   */
  function decodeStorage(bytes storage location)
    internal
    view
    returns (bytes memory)
  {
    /**
     * This code is to decode the first four bytes as size,
     * and then decode the rest using the decoded size.
     */
    uint256 firstWord;
    uint256 remainingLength = REMAINING_LENGTH;
    uint256 wordLength = WORD_LENGTH;

    assembly {
      firstWord := sload(location.slot)
    }

    uint256 length = firstWord >> (BYTE_SIZE * REMAINING_LENGTH);
    bytes memory encoded = new bytes(length);

    assembly {
      mstore(add(encoded, remainingLength), firstWord)
    }

    if (length > REMAINING_LENGTH) {
      length -= REMAINING_LENGTH;
      for (uint256 i = 0; i < ceil(length, WORD_LENGTH); i++) {
        assembly {
          let offset := add(mul(i, wordLength), remainingLength)
          let slotIndex := add(i, 1)
          mstore(
            add(add(encoded, wordLength), offset),
            sload(add(location.slot, slotIndex))
          )
        }
      }
    }
    return encoded;
  }

  /**
   * @dev Fast memory copy of bytes using assembly.
   * @param src The source memory address
   * @param dest The destination memory address
   * @param len The length of bytes to copy
   */
  function copyBytes(uint256 src, uint256 dest, uint256 len) internal pure {
    if (len == 0) {
      return;
    }

    // Copy word-length chunks while possible
    for (; len > WORD_LENGTH; len -= WORD_LENGTH) {
      assembly {
        mstore(dest, mload(src))
      }
      dest += WORD_LENGTH;
      src += WORD_LENGTH;
    }

    // Copy remaining bytes
    uint256 mask = 256**(WORD_LENGTH - len) - 1;
    assembly {
      let srcpart := and(mload(src), not(mask))
      let destpart := and(mload(dest), mask)
      mstore(dest, or(destpart, srcpart))
    }
  }

  /**
   * @dev Use assembly to get memory address.
   * @param r The in-memory bytes array
   * @return The memory address of `r`
   */
  function getMemoryAddress(bytes memory r) internal pure returns (uint256) {
    uint256 addr;
    assembly {
      addr := r
    }
    return addr;
  }

  /**
   * @dev Implement Math function of ceil
   * @param a The denominator
   * @param m The numerator
   * @return r The result of ceil(a/m)
   */
  function ceil(uint256 a, uint256 m) internal pure returns (uint256 r) {
    return (a + m - 1) / m;
  }

  // Decoders
  /**
   * This section of code `_decode_(u)int(32|64)`, `_decode_enum` and `_decode_bool`
   * is to decode ProtoBuf native integers,
   * using the `varint` encoding.
   */

  /**
   * @dev Decode integers
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_uint32(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint32, uint256)
  {
    (uint256 varint, uint256 sz) = _decode_varint(p, bs);
    return (uint32(varint), sz);
  }

  /**
   * @dev Decode integers
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_uint64(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint64, uint256)
  {
    (uint256 varint, uint256 sz) = _decode_varint(p, bs);
    return (uint64(varint), sz);
  }

  /**
   * @dev Decode integers
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_int32(uint256 p, bytes memory bs)
    internal
    pure
    returns (int32, uint256)
  {
    (uint256 varint, uint256 sz) = _decode_varint(p, bs);
    int32 r;
    assembly {
      r := varint
    }
    return (r, sz);
  }

  /**
   * @dev Decode integers
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_int64(uint256 p, bytes memory bs)
    internal
    pure
    returns (int64, uint256)
  {
    (uint256 varint, uint256 sz) = _decode_varint(p, bs);
    int64 r;
    assembly {
      r := varint
    }
    return (r, sz);
  }

  /**
   * @dev Decode enum
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded enum's integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_enum(uint256 p, bytes memory bs)
    internal
    pure
    returns (int64, uint256)
  {
    return _decode_int64(p, bs);
  }

  /**
   * @dev Decode enum
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded boolean
   * @return The length of `bs` used to get decoded
   */
  function _decode_bool(uint256 p, bytes memory bs)
    internal
    pure
    returns (bool, uint256)
  {
    (uint256 varint, uint256 sz) = _decode_varint(p, bs);
    if (varint == 0) {
      return (false, sz);
    }
    return (true, sz);
  }

  /**
   * This section of code `_decode_sint(32|64)`
   * is to decode ProtoBuf native signed integers,
   * using the `zig-zag` encoding.
   */

  /**
   * @dev Decode signed integers
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_sint32(uint256 p, bytes memory bs)
    internal
    pure
    returns (int32, uint256)
  {
    (int256 varint, uint256 sz) = _decode_varints(p, bs);
    return (int32(varint), sz);
  }

  /**
   * @dev Decode signed integers
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_sint64(uint256 p, bytes memory bs)
    internal
    pure
    returns (int64, uint256)
  {
    (int256 varint, uint256 sz) = _decode_varints(p, bs);
    return (int64(varint), sz);
  }

  /**
   * @dev Decode string
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded string
   * @return The length of `bs` used to get decoded
   */
  function _decode_string(uint256 p, bytes memory bs)
    internal
    pure
    returns (string memory, uint256)
  {
    (bytes memory x, uint256 sz) = _decode_lendelim(p, bs);
    return (string(x), sz);
  }

  /**
   * @dev Decode bytes array
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded bytes array
   * @return The length of `bs` used to get decoded
   */
  function _decode_bytes(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes memory, uint256)
  {
    return _decode_lendelim(p, bs);
  }

  /**
   * @dev Decode ProtoBuf key
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded field ID
   * @return The decoded WireType specified in ProtoBuf
   * @return The length of `bs` used to get decoded
   */
  function _decode_key(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256, WireType, uint256)
  {
    (uint256 x, uint256 n) = _decode_varint(p, bs);
    WireType typeId = WireType(x & 7);
    uint256 fieldId = x / 8;
    return (fieldId, typeId, n);
  }

  /**
   * @dev Decode ProtoBuf varint
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded unsigned integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_varint(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256, uint256)
  {
    /**
     * Read a byte.
     * Use the lower 7 bits and shift it to the left,
     * until the most significant bit is 0.
     * Refer to https://developers.google.com/protocol-buffers/docs/encoding
     */
    uint256 x = 0;
    uint256 sz = 0;
    uint256 length = bs.length + WORD_LENGTH;
    assembly {
      let b := 0x80
      p := add(bs, p)
      for {

      } eq(0x80, and(b, 0x80)) {

      } {
        if eq(lt(sub(p, bs), length), 0) {
          mstore(
            0,
            0x08c379a000000000000000000000000000000000000000000000000000000000
          ) //error function selector
          mstore(4, 32)
          mstore(36, 15)
          mstore(
            68,
            0x6c656e677468206f766572666c6f770000000000000000000000000000000000
          ) // length overflow in hex
          revert(0, 83)
        }
        let tmp := mload(p)
        let pos := 0
        for {

        } and(eq(0x80, and(b, 0x80)), lt(pos, 32)) {

        } {
          if eq(lt(sub(p, bs), length), 0) {
            mstore(
              0,
              0x08c379a000000000000000000000000000000000000000000000000000000000
            ) //error function selector
            mstore(4, 32)
            mstore(36, 15)
            mstore(
              68,
              0x6c656e677468206f766572666c6f770000000000000000000000000000000000
            ) // length overflow in hex
            revert(0, 83)
          }
          b := byte(pos, tmp)
          x := or(x, shl(mul(7, sz), and(0x7f, b)))
          sz := add(sz, 1)
          pos := add(pos, 1)
          p := add(p, 0x01)
        }
      }
    }
    return (x, sz);
  }

  /**
   * @dev Decode ProtoBuf zig-zag encoding
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded signed integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_varints(uint256 p, bytes memory bs)
    internal
    pure
    returns (int256, uint256)
  {
    /**
     * Refer to https://developers.google.com/protocol-buffers/docs/encoding
     */
    (uint256 u, uint256 sz) = _decode_varint(p, bs);
    int256 s;
    assembly {
      s := xor(shr(1, u), add(not(and(u, 1)), 1))
    }
    return (s, sz);
  }

  /**
   * @dev Decode ProtoBuf fixed-length encoding
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded unsigned integer
   * @return The length of `bs` used to get decoded
   */
  function _decode_uintf(uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (uint256, uint256)
  {
    /**
     * Refer to https://developers.google.com/protocol-buffers/docs/encoding
     */
    uint256 x = 0;
    uint256 length = bs.length + WORD_LENGTH;
    assert(p + sz <= length);
    assembly {
      let i := 0
      p := add(bs, p)
      let tmp := mload(p)
      for {

      } lt(i, sz) {

      } {
        x := or(x, shl(mul(8, i), byte(i, tmp)))
        p := add(p, 0x01)
        i := add(i, 1)
      }
    }
    return (x, sz);
  }

  /**
   * `_decode_(s)fixed(32|64)` is the concrete implementation of `_decode_uintf`
   */
  function _decode_fixed32(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint32, uint256)
  {
    (uint256 x, uint256 sz) = _decode_uintf(p, bs, 4);
    return (uint32(x), sz);
  }

  function _decode_fixed64(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint64, uint256)
  {
    (uint256 x, uint256 sz) = _decode_uintf(p, bs, 8);
    return (uint64(x), sz);
  }

  function _decode_sfixed32(uint256 p, bytes memory bs)
    internal
    pure
    returns (int32, uint256)
  {
    (uint256 x, uint256 sz) = _decode_uintf(p, bs, 4);
    int256 r;
    assembly {
      r := x
    }
    return (int32(r), sz);
  }

  function _decode_sfixed64(uint256 p, bytes memory bs)
    internal
    pure
    returns (int64, uint256)
  {
    (uint256 x, uint256 sz) = _decode_uintf(p, bs, 8);
    int256 r;
    assembly {
      r := x
    }
    return (int64(r), sz);
  }

  /**
   * @dev Decode bytes array
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The decoded bytes array
   * @return The length of `bs` used to get decoded
   */
  function _decode_lendelim(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes memory, uint256)
  {
    /**
     * First read the size encoded in `varint`, then use the size to read bytes.
     */
    (uint256 len, uint256 sz) = _decode_varint(p, bs);
    bytes memory b = new bytes(len);
    uint256 length = bs.length + WORD_LENGTH;
    assert(p + sz + len <= length);
    uint256 sourcePtr;
    uint256 destPtr;
    assembly {
      destPtr := add(b, 32)
      sourcePtr := add(add(bs, p), sz)
    }
    copyBytes(sourcePtr, destPtr, len);
    return (b, sz + len);
  }

  /**
   * @dev Skip the decoding of a single field
   * @param wt The WireType of the field
   * @param p The memory offset of `bs`
   * @param bs The bytes array to be decoded
   * @return The length of `bs` to skipped
   */
  function _skip_field_decode(WireType wt, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    if (wt == ProtoBufRuntime.WireType.Fixed64) {
      return 8;
    } else if (wt == ProtoBufRuntime.WireType.Fixed32) {
      return 4;
    } else if (wt == ProtoBufRuntime.WireType.Varint) {
      (, uint256 size) = ProtoBufRuntime._decode_varint(p, bs);
      return size;
    } else {
      require(wt == ProtoBufRuntime.WireType.LengthDelim);
      (uint256 len, uint256 size) = ProtoBufRuntime._decode_varint(p, bs);
      return size + len;
    }
  }

  // Encoders
  /**
   * @dev Encode ProtoBuf key
   * @param x The field ID
   * @param wt The WireType specified in ProtoBuf
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The length of encoded bytes
   */
  function _encode_key(uint256 x, WireType wt, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint256 i;
    assembly {
      i := or(mul(x, 8), mod(wt, 8))
    }
    return _encode_varint(i, p, bs);
  }

  /**
   * @dev Encode ProtoBuf varint
   * @param x The unsigned integer to be encoded
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The length of encoded bytes
   */
  function _encode_varint(uint256 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    /**
     * Refer to https://developers.google.com/protocol-buffers/docs/encoding
     */
    uint256 sz = 0;
    assembly {
      let bsptr := add(bs, p)
      let byt := and(x, 0x7f)
      for {

      } gt(shr(7, x), 0) {

      } {
        mstore8(bsptr, or(0x80, byt))
        bsptr := add(bsptr, 1)
        sz := add(sz, 1)
        x := shr(7, x)
        byt := and(x, 0x7f)
      }
      mstore8(bsptr, byt)
      sz := add(sz, 1)
    }
    return sz;
  }

  /**
   * @dev Encode ProtoBuf zig-zag encoding
   * @param x The signed integer to be encoded
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The length of encoded bytes
   */
  function _encode_varints(int256 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    /**
     * Refer to https://developers.google.com/protocol-buffers/docs/encoding
     */
    uint256 encodedInt = _encode_zigzag(x);
    return _encode_varint(encodedInt, p, bs);
  }

  /**
   * @dev Encode ProtoBuf bytes
   * @param xs The bytes array to be encoded
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The length of encoded bytes
   */
  function _encode_bytes(bytes memory xs, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint256 xsLength = xs.length;
    uint256 sz = _encode_varint(xsLength, p, bs);
    uint256 count = 0;
    assembly {
      let bsptr := add(bs, add(p, sz))
      let xsptr := add(xs, 32)
      for {

      } lt(count, xsLength) {

      } {
        mstore8(bsptr, byte(0, mload(xsptr)))
        bsptr := add(bsptr, 1)
        xsptr := add(xsptr, 1)
        count := add(count, 1)
      }
    }
    return sz + count;
  }

  /**
   * @dev Encode ProtoBuf string
   * @param xs The string to be encoded
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The length of encoded bytes
   */
  function _encode_string(string memory xs, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_bytes(bytes(xs), p, bs);
  }

  /**
   * `_encode_(u)int(32|64)`, `_encode_enum` and `_encode_bool`
   * are concrete implementation of `_encode_varint`
   */
  function _encode_uint32(uint32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_varint(x, p, bs);
  }

  function _encode_uint64(uint64 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_varint(x, p, bs);
  }

  function _encode_int32(int32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint64 twosComplement;
    assembly {
      twosComplement := x
    }
    return _encode_varint(twosComplement, p, bs);
  }

  function _encode_int64(int64 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint64 twosComplement;
    assembly {
      twosComplement := x
    }
    return _encode_varint(twosComplement, p, bs);
  }

  function _encode_enum(int32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_int32(x, p, bs);
  }

  function _encode_bool(bool x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    if (x) {
      return _encode_varint(1, p, bs);
    } else return _encode_varint(0, p, bs);
  }

  /**
   * `_encode_sint(32|64)`, `_encode_enum` and `_encode_bool`
   * are the concrete implementation of `_encode_varints`
   */
  function _encode_sint32(int32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_varints(x, p, bs);
  }

  function _encode_sint64(int64 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_varints(x, p, bs);
  }

  /**
   * `_encode_(s)fixed(32|64)` is the concrete implementation of `_encode_uintf`
   */
  function _encode_fixed32(uint32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_uintf(x, p, bs, 4);
  }

  function _encode_fixed64(uint64 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_uintf(x, p, bs, 8);
  }

  function _encode_sfixed32(int32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint32 twosComplement;
    assembly {
      twosComplement := x
    }
    return _encode_uintf(twosComplement, p, bs, 4);
  }

  function _encode_sfixed64(int64 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint64 twosComplement;
    assembly {
      twosComplement := x
    }
    return _encode_uintf(twosComplement, p, bs, 8);
  }

  /**
   * @dev Encode ProtoBuf fixed-length integer
   * @param x The unsigned integer to be encoded
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The length of encoded bytes
   */
  function _encode_uintf(uint256 x, uint256 p, bytes memory bs, uint256 sz)
    internal
    pure
    returns (uint256)
  {
    assembly {
      let bsptr := add(sz, add(bs, p))
      let count := sz
      for {

      } gt(count, 0) {

      } {
        bsptr := sub(bsptr, 1)
        mstore8(bsptr, byte(sub(32, count), x))
        count := sub(count, 1)
      }
    }
    return sz;
  }

  /**
   * @dev Encode ProtoBuf zig-zag signed integer
   * @param i The unsigned integer to be encoded
   * @return The encoded unsigned integer
   */
  function _encode_zigzag(int256 i) internal pure returns (uint256) {
    if (i >= 0) {
      return uint256(i) * 2;
    } else return uint256(i * -2) - 1;
  }

  // Estimators
  /**
   * @dev Estimate the length of encoded LengthDelim
   * @param i The length of LengthDelim
   * @return The estimated encoded length
   */
  function _sz_lendelim(uint256 i) internal pure returns (uint256) {
    return i + _sz_varint(i);
  }

  /**
   * @dev Estimate the length of encoded ProtoBuf field ID
   * @param i The field ID
   * @return The estimated encoded length
   */
  function _sz_key(uint256 i) internal pure returns (uint256) {
    if (i < 16) {
      return 1;
    } else if (i < 2048) {
      return 2;
    } else if (i < 262144) {
      return 3;
    } else {
      revert("not supported");
    }
  }

  /**
   * @dev Estimate the length of encoded ProtoBuf varint
   * @param i The unsigned integer
   * @return The estimated encoded length
   */
  function _sz_varint(uint256 i) internal pure returns (uint256) {
    uint256 count = 1;
    assembly {
      i := shr(7, i)
      for {

      } gt(i, 0) {

      } {
        i := shr(7, i)
        count := add(count, 1)
      }
    }
    return count;
  }

  /**
   * `_sz_(u)int(32|64)` and `_sz_enum` are the concrete implementation of `_sz_varint`
   */
  function _sz_uint32(uint32 i) internal pure returns (uint256) {
    return _sz_varint(i);
  }

  function _sz_uint64(uint64 i) internal pure returns (uint256) {
    return _sz_varint(i);
  }

  function _sz_int32(int32 i) internal pure returns (uint256) {
    if (i < 0) {
      return 10;
    } else return _sz_varint(uint32(i));
  }

  function _sz_int64(int64 i) internal pure returns (uint256) {
    if (i < 0) {
      return 10;
    } else return _sz_varint(uint64(i));
  }

  function _sz_enum(int64 i) internal pure returns (uint256) {
    if (i < 0) {
      return 10;
    } else return _sz_varint(uint64(i));
  }

  /**
   * `_sz_sint(32|64)` and `_sz_enum` are the concrete implementation of zig-zag encoding
   */
  function _sz_sint32(int32 i) internal pure returns (uint256) {
    return _sz_varint(_encode_zigzag(i));
  }

  function _sz_sint64(int64 i) internal pure returns (uint256) {
    return _sz_varint(_encode_zigzag(i));
  }

  /**
   * `_estimate_packed_repeated_(uint32|uint64|int32|int64|sint32|sint64)`
   */
  function _estimate_packed_repeated_uint32(uint32[] memory a) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += _sz_uint32(a[i]);
    }
    return e;
  }

  function _estimate_packed_repeated_uint64(uint64[] memory a) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += _sz_uint64(a[i]);
    }
    return e;
  }

  function _estimate_packed_repeated_int32(int32[] memory a) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += _sz_int32(a[i]);
    }
    return e;
  }

  function _estimate_packed_repeated_int64(int64[] memory a) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += _sz_int64(a[i]);
    }
    return e;
  }

  function _estimate_packed_repeated_sint32(int32[] memory a) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += _sz_sint32(a[i]);
    }
    return e;
  }

  function _estimate_packed_repeated_sint64(int64[] memory a) internal pure returns (uint256) {
    uint256 e = 0;
    for (uint i = 0; i < a.length; i++) {
      e += _sz_sint64(a[i]);
    }
    return e;
  }

  // Element counters for packed repeated fields
  function _count_packed_repeated_varint(uint256 p, uint256 len, bytes memory bs) internal pure returns (uint256) {
    uint256 count = 0;
    uint256 end = p + len;
    while (p < end) {
      uint256 sz;
      (, sz) = _decode_varint(p, bs);
      p += sz;
      count += 1;
    }
    return count;
  }

  // Soltype extensions
  /**
   * @dev Decode Solidity integer and/or fixed-size bytes array, filling from lowest bit.
   * @param n The maximum number of bytes to read
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The bytes32 representation
   * @return The number of bytes used to decode
   */
  function _decode_sol_bytesN_lower(uint8 n, uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes32, uint256)
  {
    uint256 r;
    (uint256 len, uint256 sz) = _decode_varint(p, bs);
    if (len + sz > n + 3) {
      revert(OVERFLOW_MESSAGE);
    }
    p += 3;
    assert(p < bs.length + WORD_LENGTH);
    assembly {
      r := mload(add(p, bs))
    }
    for (uint256 i = len - 2; i < WORD_LENGTH; i++) {
      r /= 256;
    }
    return (bytes32(r), len + sz);
  }

  /**
   * @dev Decode Solidity integer and/or fixed-size bytes array, filling from highest bit.
   * @param n The maximum number of bytes to read
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The bytes32 representation
   * @return The number of bytes used to decode
   */
  function _decode_sol_bytesN(uint8 n, uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes32, uint256)
  {
    (uint256 len, uint256 sz) = _decode_varint(p, bs);
    uint256 wordLength = WORD_LENGTH;
    uint256 byteSize = BYTE_SIZE;
    if (len + sz > n + 3) {
      revert(OVERFLOW_MESSAGE);
    }
    p += 3;
    bytes32 acc;
    assert(p < bs.length + WORD_LENGTH);
    assembly {
      acc := mload(add(p, bs))
      let difference := sub(wordLength, sub(len, 2))
      let bits := mul(byteSize, difference)
      acc := shl(bits, shr(bits, acc))
    }
    return (acc, len + sz);
  }

  /*
   * `_decode_sol*` are the concrete implementation of decoding Solidity types
   */
  function _decode_sol_address(uint256 p, bytes memory bs)
    internal
    pure
    returns (address, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytesN(20, p, bs);
    return (address(bytes20(r)), sz);
  }

  function _decode_sol_bool(uint256 p, bytes memory bs)
    internal
    pure
    returns (bool, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(1, p, bs);
    if (r == 0) {
      return (false, sz);
    }
    return (true, sz);
  }

  function _decode_sol_uint(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256, uint256)
  {
    return _decode_sol_uint256(p, bs);
  }

  function _decode_sol_uintN(uint8 n, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256, uint256)
  {
    (bytes32 u, uint256 sz) = _decode_sol_bytesN_lower(n, p, bs);
    uint256 r;
    assembly {
      r := u
    }
    return (r, sz);
  }

  function _decode_sol_uint8(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint8, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(1, p, bs);
    return (uint8(r), sz);
  }

  function _decode_sol_uint16(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint16, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(2, p, bs);
    return (uint16(r), sz);
  }

  function _decode_sol_uint24(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint24, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(3, p, bs);
    return (uint24(r), sz);
  }

  function _decode_sol_uint32(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint32, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(4, p, bs);
    return (uint32(r), sz);
  }

  function _decode_sol_uint40(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint40, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(5, p, bs);
    return (uint40(r), sz);
  }

  function _decode_sol_uint48(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint48, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(6, p, bs);
    return (uint48(r), sz);
  }

  function _decode_sol_uint56(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint56, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(7, p, bs);
    return (uint56(r), sz);
  }

  function _decode_sol_uint64(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint64, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(8, p, bs);
    return (uint64(r), sz);
  }

  function _decode_sol_uint72(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint72, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(9, p, bs);
    return (uint72(r), sz);
  }

  function _decode_sol_uint80(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint80, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(10, p, bs);
    return (uint80(r), sz);
  }

  function _decode_sol_uint88(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint88, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(11, p, bs);
    return (uint88(r), sz);
  }

  function _decode_sol_uint96(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint96, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(12, p, bs);
    return (uint96(r), sz);
  }

  function _decode_sol_uint104(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint104, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(13, p, bs);
    return (uint104(r), sz);
  }

  function _decode_sol_uint112(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint112, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(14, p, bs);
    return (uint112(r), sz);
  }

  function _decode_sol_uint120(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint120, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(15, p, bs);
    return (uint120(r), sz);
  }

  function _decode_sol_uint128(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint128, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(16, p, bs);
    return (uint128(r), sz);
  }

  function _decode_sol_uint136(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint136, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(17, p, bs);
    return (uint136(r), sz);
  }

  function _decode_sol_uint144(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint144, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(18, p, bs);
    return (uint144(r), sz);
  }

  function _decode_sol_uint152(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint152, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(19, p, bs);
    return (uint152(r), sz);
  }

  function _decode_sol_uint160(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint160, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(20, p, bs);
    return (uint160(r), sz);
  }

  function _decode_sol_uint168(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint168, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(21, p, bs);
    return (uint168(r), sz);
  }

  function _decode_sol_uint176(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint176, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(22, p, bs);
    return (uint176(r), sz);
  }

  function _decode_sol_uint184(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint184, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(23, p, bs);
    return (uint184(r), sz);
  }

  function _decode_sol_uint192(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint192, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(24, p, bs);
    return (uint192(r), sz);
  }

  function _decode_sol_uint200(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint200, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(25, p, bs);
    return (uint200(r), sz);
  }

  function _decode_sol_uint208(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint208, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(26, p, bs);
    return (uint208(r), sz);
  }

  function _decode_sol_uint216(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint216, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(27, p, bs);
    return (uint216(r), sz);
  }

  function _decode_sol_uint224(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint224, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(28, p, bs);
    return (uint224(r), sz);
  }

  function _decode_sol_uint232(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint232, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(29, p, bs);
    return (uint232(r), sz);
  }

  function _decode_sol_uint240(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint240, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(30, p, bs);
    return (uint240(r), sz);
  }

  function _decode_sol_uint248(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint248, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(31, p, bs);
    return (uint248(r), sz);
  }

  function _decode_sol_uint256(uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256, uint256)
  {
    (uint256 r, uint256 sz) = _decode_sol_uintN(32, p, bs);
    return (uint256(r), sz);
  }

  function _decode_sol_int(uint256 p, bytes memory bs)
    internal
    pure
    returns (int256, uint256)
  {
    return _decode_sol_int256(p, bs);
  }

  function _decode_sol_intN(uint8 n, uint256 p, bytes memory bs)
    internal
    pure
    returns (int256, uint256)
  {
    (bytes32 u, uint256 sz) = _decode_sol_bytesN_lower(n, p, bs);
    int256 r;
    assembly {
      r := u
      r := signextend(sub(sz, 4), r)
    }
    return (r, sz);
  }

  function _decode_sol_bytes(uint8 n, uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes32, uint256)
  {
    (bytes32 u, uint256 sz) = _decode_sol_bytesN(n, p, bs);
    return (u, sz);
  }

  function _decode_sol_int8(uint256 p, bytes memory bs)
    internal
    pure
    returns (int8, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(1, p, bs);
    return (int8(r), sz);
  }

  function _decode_sol_int16(uint256 p, bytes memory bs)
    internal
    pure
    returns (int16, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(2, p, bs);
    return (int16(r), sz);
  }

  function _decode_sol_int24(uint256 p, bytes memory bs)
    internal
    pure
    returns (int24, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(3, p, bs);
    return (int24(r), sz);
  }

  function _decode_sol_int32(uint256 p, bytes memory bs)
    internal
    pure
    returns (int32, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(4, p, bs);
    return (int32(r), sz);
  }

  function _decode_sol_int40(uint256 p, bytes memory bs)
    internal
    pure
    returns (int40, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(5, p, bs);
    return (int40(r), sz);
  }

  function _decode_sol_int48(uint256 p, bytes memory bs)
    internal
    pure
    returns (int48, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(6, p, bs);
    return (int48(r), sz);
  }

  function _decode_sol_int56(uint256 p, bytes memory bs)
    internal
    pure
    returns (int56, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(7, p, bs);
    return (int56(r), sz);
  }

  function _decode_sol_int64(uint256 p, bytes memory bs)
    internal
    pure
    returns (int64, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(8, p, bs);
    return (int64(r), sz);
  }

  function _decode_sol_int72(uint256 p, bytes memory bs)
    internal
    pure
    returns (int72, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(9, p, bs);
    return (int72(r), sz);
  }

  function _decode_sol_int80(uint256 p, bytes memory bs)
    internal
    pure
    returns (int80, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(10, p, bs);
    return (int80(r), sz);
  }

  function _decode_sol_int88(uint256 p, bytes memory bs)
    internal
    pure
    returns (int88, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(11, p, bs);
    return (int88(r), sz);
  }

  function _decode_sol_int96(uint256 p, bytes memory bs)
    internal
    pure
    returns (int96, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(12, p, bs);
    return (int96(r), sz);
  }

  function _decode_sol_int104(uint256 p, bytes memory bs)
    internal
    pure
    returns (int104, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(13, p, bs);
    return (int104(r), sz);
  }

  function _decode_sol_int112(uint256 p, bytes memory bs)
    internal
    pure
    returns (int112, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(14, p, bs);
    return (int112(r), sz);
  }

  function _decode_sol_int120(uint256 p, bytes memory bs)
    internal
    pure
    returns (int120, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(15, p, bs);
    return (int120(r), sz);
  }

  function _decode_sol_int128(uint256 p, bytes memory bs)
    internal
    pure
    returns (int128, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(16, p, bs);
    return (int128(r), sz);
  }

  function _decode_sol_int136(uint256 p, bytes memory bs)
    internal
    pure
    returns (int136, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(17, p, bs);
    return (int136(r), sz);
  }

  function _decode_sol_int144(uint256 p, bytes memory bs)
    internal
    pure
    returns (int144, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(18, p, bs);
    return (int144(r), sz);
  }

  function _decode_sol_int152(uint256 p, bytes memory bs)
    internal
    pure
    returns (int152, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(19, p, bs);
    return (int152(r), sz);
  }

  function _decode_sol_int160(uint256 p, bytes memory bs)
    internal
    pure
    returns (int160, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(20, p, bs);
    return (int160(r), sz);
  }

  function _decode_sol_int168(uint256 p, bytes memory bs)
    internal
    pure
    returns (int168, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(21, p, bs);
    return (int168(r), sz);
  }

  function _decode_sol_int176(uint256 p, bytes memory bs)
    internal
    pure
    returns (int176, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(22, p, bs);
    return (int176(r), sz);
  }

  function _decode_sol_int184(uint256 p, bytes memory bs)
    internal
    pure
    returns (int184, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(23, p, bs);
    return (int184(r), sz);
  }

  function _decode_sol_int192(uint256 p, bytes memory bs)
    internal
    pure
    returns (int192, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(24, p, bs);
    return (int192(r), sz);
  }

  function _decode_sol_int200(uint256 p, bytes memory bs)
    internal
    pure
    returns (int200, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(25, p, bs);
    return (int200(r), sz);
  }

  function _decode_sol_int208(uint256 p, bytes memory bs)
    internal
    pure
    returns (int208, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(26, p, bs);
    return (int208(r), sz);
  }

  function _decode_sol_int216(uint256 p, bytes memory bs)
    internal
    pure
    returns (int216, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(27, p, bs);
    return (int216(r), sz);
  }

  function _decode_sol_int224(uint256 p, bytes memory bs)
    internal
    pure
    returns (int224, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(28, p, bs);
    return (int224(r), sz);
  }

  function _decode_sol_int232(uint256 p, bytes memory bs)
    internal
    pure
    returns (int232, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(29, p, bs);
    return (int232(r), sz);
  }

  function _decode_sol_int240(uint256 p, bytes memory bs)
    internal
    pure
    returns (int240, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(30, p, bs);
    return (int240(r), sz);
  }

  function _decode_sol_int248(uint256 p, bytes memory bs)
    internal
    pure
    returns (int248, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(31, p, bs);
    return (int248(r), sz);
  }

  function _decode_sol_int256(uint256 p, bytes memory bs)
    internal
    pure
    returns (int256, uint256)
  {
    (int256 r, uint256 sz) = _decode_sol_intN(32, p, bs);
    return (int256(r), sz);
  }

  function _decode_sol_bytes1(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes1, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(1, p, bs);
    return (bytes1(r), sz);
  }

  function _decode_sol_bytes2(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes2, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(2, p, bs);
    return (bytes2(r), sz);
  }

  function _decode_sol_bytes3(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes3, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(3, p, bs);
    return (bytes3(r), sz);
  }

  function _decode_sol_bytes4(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes4, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(4, p, bs);
    return (bytes4(r), sz);
  }

  function _decode_sol_bytes5(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes5, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(5, p, bs);
    return (bytes5(r), sz);
  }

  function _decode_sol_bytes6(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes6, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(6, p, bs);
    return (bytes6(r), sz);
  }

  function _decode_sol_bytes7(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes7, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(7, p, bs);
    return (bytes7(r), sz);
  }

  function _decode_sol_bytes8(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes8, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(8, p, bs);
    return (bytes8(r), sz);
  }

  function _decode_sol_bytes9(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes9, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(9, p, bs);
    return (bytes9(r), sz);
  }

  function _decode_sol_bytes10(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes10, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(10, p, bs);
    return (bytes10(r), sz);
  }

  function _decode_sol_bytes11(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes11, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(11, p, bs);
    return (bytes11(r), sz);
  }

  function _decode_sol_bytes12(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes12, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(12, p, bs);
    return (bytes12(r), sz);
  }

  function _decode_sol_bytes13(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes13, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(13, p, bs);
    return (bytes13(r), sz);
  }

  function _decode_sol_bytes14(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes14, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(14, p, bs);
    return (bytes14(r), sz);
  }

  function _decode_sol_bytes15(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes15, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(15, p, bs);
    return (bytes15(r), sz);
  }

  function _decode_sol_bytes16(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes16, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(16, p, bs);
    return (bytes16(r), sz);
  }

  function _decode_sol_bytes17(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes17, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(17, p, bs);
    return (bytes17(r), sz);
  }

  function _decode_sol_bytes18(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes18, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(18, p, bs);
    return (bytes18(r), sz);
  }

  function _decode_sol_bytes19(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes19, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(19, p, bs);
    return (bytes19(r), sz);
  }

  function _decode_sol_bytes20(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes20, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(20, p, bs);
    return (bytes20(r), sz);
  }

  function _decode_sol_bytes21(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes21, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(21, p, bs);
    return (bytes21(r), sz);
  }

  function _decode_sol_bytes22(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes22, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(22, p, bs);
    return (bytes22(r), sz);
  }

  function _decode_sol_bytes23(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes23, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(23, p, bs);
    return (bytes23(r), sz);
  }

  function _decode_sol_bytes24(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes24, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(24, p, bs);
    return (bytes24(r), sz);
  }

  function _decode_sol_bytes25(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes25, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(25, p, bs);
    return (bytes25(r), sz);
  }

  function _decode_sol_bytes26(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes26, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(26, p, bs);
    return (bytes26(r), sz);
  }

  function _decode_sol_bytes27(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes27, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(27, p, bs);
    return (bytes27(r), sz);
  }

  function _decode_sol_bytes28(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes28, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(28, p, bs);
    return (bytes28(r), sz);
  }

  function _decode_sol_bytes29(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes29, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(29, p, bs);
    return (bytes29(r), sz);
  }

  function _decode_sol_bytes30(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes30, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(30, p, bs);
    return (bytes30(r), sz);
  }

  function _decode_sol_bytes31(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes31, uint256)
  {
    (bytes32 r, uint256 sz) = _decode_sol_bytes(31, p, bs);
    return (bytes31(r), sz);
  }

  function _decode_sol_bytes32(uint256 p, bytes memory bs)
    internal
    pure
    returns (bytes32, uint256)
  {
    return _decode_sol_bytes(32, p, bs);
  }

  /*
   * `_encode_sol*` are the concrete implementation of encoding Solidity types
   */
  function _encode_sol_address(address x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(uint160(x)), 20, p, bs);
  }

  function _encode_sol_uint(uint256 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 32, p, bs);
  }

  function _encode_sol_uint8(uint8 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 1, p, bs);
  }

  function _encode_sol_uint16(uint16 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 2, p, bs);
  }

  function _encode_sol_uint24(uint24 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 3, p, bs);
  }

  function _encode_sol_uint32(uint32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 4, p, bs);
  }

  function _encode_sol_uint40(uint40 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 5, p, bs);
  }

  function _encode_sol_uint48(uint48 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 6, p, bs);
  }

  function _encode_sol_uint56(uint56 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 7, p, bs);
  }

  function _encode_sol_uint64(uint64 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 8, p, bs);
  }

  function _encode_sol_uint72(uint72 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 9, p, bs);
  }

  function _encode_sol_uint80(uint80 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 10, p, bs);
  }

  function _encode_sol_uint88(uint88 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 11, p, bs);
  }

  function _encode_sol_uint96(uint96 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 12, p, bs);
  }

  function _encode_sol_uint104(uint104 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 13, p, bs);
  }

  function _encode_sol_uint112(uint112 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 14, p, bs);
  }

  function _encode_sol_uint120(uint120 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 15, p, bs);
  }

  function _encode_sol_uint128(uint128 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 16, p, bs);
  }

  function _encode_sol_uint136(uint136 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 17, p, bs);
  }

  function _encode_sol_uint144(uint144 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 18, p, bs);
  }

  function _encode_sol_uint152(uint152 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 19, p, bs);
  }

  function _encode_sol_uint160(uint160 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 20, p, bs);
  }

  function _encode_sol_uint168(uint168 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 21, p, bs);
  }

  function _encode_sol_uint176(uint176 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 22, p, bs);
  }

  function _encode_sol_uint184(uint184 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 23, p, bs);
  }

  function _encode_sol_uint192(uint192 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 24, p, bs);
  }

  function _encode_sol_uint200(uint200 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 25, p, bs);
  }

  function _encode_sol_uint208(uint208 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 26, p, bs);
  }

  function _encode_sol_uint216(uint216 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 27, p, bs);
  }

  function _encode_sol_uint224(uint224 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 28, p, bs);
  }

  function _encode_sol_uint232(uint232 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 29, p, bs);
  }

  function _encode_sol_uint240(uint240 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 30, p, bs);
  }

  function _encode_sol_uint248(uint248 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 31, p, bs);
  }

  function _encode_sol_uint256(uint256 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(uint256(x), 32, p, bs);
  }

  function _encode_sol_int(int256 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(x, 32, p, bs);
  }

  function _encode_sol_int8(int8 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 1, p, bs);
  }

  function _encode_sol_int16(int16 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 2, p, bs);
  }

  function _encode_sol_int24(int24 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 3, p, bs);
  }

  function _encode_sol_int32(int32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 4, p, bs);
  }

  function _encode_sol_int40(int40 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 5, p, bs);
  }

  function _encode_sol_int48(int48 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 6, p, bs);
  }

  function _encode_sol_int56(int56 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 7, p, bs);
  }

  function _encode_sol_int64(int64 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 8, p, bs);
  }

  function _encode_sol_int72(int72 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 9, p, bs);
  }

  function _encode_sol_int80(int80 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 10, p, bs);
  }

  function _encode_sol_int88(int88 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 11, p, bs);
  }

  function _encode_sol_int96(int96 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 12, p, bs);
  }

  function _encode_sol_int104(int104 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 13, p, bs);
  }

  function _encode_sol_int112(int112 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 14, p, bs);
  }

  function _encode_sol_int120(int120 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 15, p, bs);
  }

  function _encode_sol_int128(int128 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 16, p, bs);
  }

  function _encode_sol_int136(int136 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 17, p, bs);
  }

  function _encode_sol_int144(int144 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 18, p, bs);
  }

  function _encode_sol_int152(int152 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 19, p, bs);
  }

  function _encode_sol_int160(int160 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 20, p, bs);
  }

  function _encode_sol_int168(int168 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 21, p, bs);
  }

  function _encode_sol_int176(int176 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 22, p, bs);
  }

  function _encode_sol_int184(int184 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 23, p, bs);
  }

  function _encode_sol_int192(int192 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 24, p, bs);
  }

  function _encode_sol_int200(int200 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 25, p, bs);
  }

  function _encode_sol_int208(int208 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 26, p, bs);
  }

  function _encode_sol_int216(int216 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 27, p, bs);
  }

  function _encode_sol_int224(int224 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 28, p, bs);
  }

  function _encode_sol_int232(int232 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 29, p, bs);
  }

  function _encode_sol_int240(int240 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 30, p, bs);
  }

  function _encode_sol_int248(int248 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(int256(x), 31, p, bs);
  }

  function _encode_sol_int256(int256 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol(x, 32, p, bs);
  }

  function _encode_sol_bytes1(bytes1 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 1, p, bs);
  }

  function _encode_sol_bytes2(bytes2 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 2, p, bs);
  }

  function _encode_sol_bytes3(bytes3 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 3, p, bs);
  }

  function _encode_sol_bytes4(bytes4 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 4, p, bs);
  }

  function _encode_sol_bytes5(bytes5 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 5, p, bs);
  }

  function _encode_sol_bytes6(bytes6 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 6, p, bs);
  }

  function _encode_sol_bytes7(bytes7 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 7, p, bs);
  }

  function _encode_sol_bytes8(bytes8 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 8, p, bs);
  }

  function _encode_sol_bytes9(bytes9 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 9, p, bs);
  }

  function _encode_sol_bytes10(bytes10 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 10, p, bs);
  }

  function _encode_sol_bytes11(bytes11 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 11, p, bs);
  }

  function _encode_sol_bytes12(bytes12 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 12, p, bs);
  }

  function _encode_sol_bytes13(bytes13 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 13, p, bs);
  }

  function _encode_sol_bytes14(bytes14 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 14, p, bs);
  }

  function _encode_sol_bytes15(bytes15 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 15, p, bs);
  }

  function _encode_sol_bytes16(bytes16 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 16, p, bs);
  }

  function _encode_sol_bytes17(bytes17 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 17, p, bs);
  }

  function _encode_sol_bytes18(bytes18 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 18, p, bs);
  }

  function _encode_sol_bytes19(bytes19 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 19, p, bs);
  }

  function _encode_sol_bytes20(bytes20 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 20, p, bs);
  }

  function _encode_sol_bytes21(bytes21 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 21, p, bs);
  }

  function _encode_sol_bytes22(bytes22 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 22, p, bs);
  }

  function _encode_sol_bytes23(bytes23 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 23, p, bs);
  }

  function _encode_sol_bytes24(bytes24 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 24, p, bs);
  }

  function _encode_sol_bytes25(bytes25 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 25, p, bs);
  }

  function _encode_sol_bytes26(bytes26 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 26, p, bs);
  }

  function _encode_sol_bytes27(bytes27 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 27, p, bs);
  }

  function _encode_sol_bytes28(bytes28 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 28, p, bs);
  }

  function _encode_sol_bytes29(bytes29 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 29, p, bs);
  }

  function _encode_sol_bytes30(bytes30 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 30, p, bs);
  }

  function _encode_sol_bytes31(bytes31 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(bytes32(x), 31, p, bs);
  }

  function _encode_sol_bytes32(bytes32 x, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    return _encode_sol_bytes(x, 32, p, bs);
  }

  /**
   * @dev Encode the key of Solidity integer and/or fixed-size bytes array.
   * @param sz The number of bytes used to encode Solidity types
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The number of bytes used to encode
   */
  function _encode_sol_header(uint256 sz, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint256 offset = p;
    p += _encode_varint(sz + 2, p, bs);
    p += _encode_key(1, WireType.LengthDelim, p, bs);
    p += _encode_varint(sz, p, bs);
    return p - offset;
  }

  /**
   * @dev Encode Solidity type
   * @param x The unsinged integer to be encoded
   * @param sz The number of bytes used to encode Solidity types
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The number of bytes used to encode
   */
  function _encode_sol(uint256 x, uint256 sz, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint256 offset = p;
    uint256 size;
    p += 3;
    size = _encode_sol_raw_other(x, p, bs, sz);
    p += size;
    _encode_sol_header(size, offset, bs);
    return p - offset;
  }

  /**
   * @dev Encode Solidity type
   * @param x The signed integer to be encoded
   * @param sz The number of bytes used to encode Solidity types
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The number of bytes used to encode
   */
  function _encode_sol(int256 x, uint256 sz, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint256 offset = p;
    uint256 size;
    p += 3;
    size = _encode_sol_raw_other(x, p, bs, sz);
    p += size;
    _encode_sol_header(size, offset, bs);
    return p - offset;
  }

  /**
   * @dev Encode Solidity type
   * @param x The fixed-size byte array to be encoded
   * @param sz The number of bytes used to encode Solidity types
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The number of bytes used to encode
   */
  function _encode_sol_bytes(bytes32 x, uint256 sz, uint256 p, bytes memory bs)
    internal
    pure
    returns (uint256)
  {
    uint256 offset = p;
    uint256 size;
    p += 3;
    size = _encode_sol_raw_bytes_array(x, p, bs, sz);
    p += size;
    _encode_sol_header(size, offset, bs);
    return p - offset;
  }

  /**
   * @dev Get the actual size needed to encoding an unsigned integer
   * @param x The unsigned integer to be encoded
   * @param sz The maximum number of bytes used to encode Solidity types
   * @return The number of bytes needed for encoding `x`
   */
  function _get_real_size(uint256 x, uint256 sz)
    internal
    pure
    returns (uint256)
  {
    uint256 base = 0xff;
    uint256 realSize = sz;
    while (
      x & (base << (realSize * BYTE_SIZE - BYTE_SIZE)) == 0 && realSize > 0
    ) {
      realSize -= 1;
    }
    if (realSize == 0) {
      realSize = 1;
    }
    return realSize;
  }

  /**
   * @dev Get the actual size needed to encoding an signed integer
   * @param x The signed integer to be encoded
   * @param sz The maximum number of bytes used to encode Solidity types
   * @return The number of bytes needed for encoding `x`
   */
  function _get_real_size(int256 x, uint256 sz)
    internal
    pure
    returns (uint256)
  {
    int256 base = 0xff;
    if (x >= 0) {
      uint256 tmp = _get_real_size(uint256(x), sz);
      int256 remainder = (x & (base << (tmp * BYTE_SIZE - BYTE_SIZE))) >>
        (tmp * BYTE_SIZE - BYTE_SIZE);
      if (remainder >= 128) {
        tmp += 1;
      }
      return tmp;
    }

    uint256 realSize = sz;
    while (
      x & (base << (realSize * BYTE_SIZE - BYTE_SIZE)) ==
      (base << (realSize * BYTE_SIZE - BYTE_SIZE)) &&
      realSize > 0
    ) {
      realSize -= 1;
    }
    {
      int256 remainder = (x & (base << (realSize * BYTE_SIZE - BYTE_SIZE))) >>
        (realSize * BYTE_SIZE - BYTE_SIZE);
      if (remainder < 128) {
        realSize += 1;
      }
    }
    return realSize;
  }

  /**
   * @dev Encode the fixed-bytes array
   * @param x The fixed-size byte array to be encoded
   * @param sz The maximum number of bytes used to encode Solidity types
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The number of bytes needed for encoding `x`
   */
  function _encode_sol_raw_bytes_array(
    bytes32 x,
    uint256 p,
    bytes memory bs,
    uint256 sz
  ) internal pure returns (uint256) {
    /**
     * The idea is to not encode the leading bytes of zero.
     */
    uint256 actualSize = sz;
    for (uint256 i = 0; i < sz; i++) {
      uint8 current = uint8(x[sz - 1 - i]);
      if (current == 0 && actualSize > 1) {
        actualSize--;
      } else {
        break;
      }
    }
    assembly {
      let bsptr := add(bs, p)
      let count := actualSize
      for {

      } gt(count, 0) {

      } {
        mstore8(bsptr, byte(sub(actualSize, count), x))
        bsptr := add(bsptr, 1)
        count := sub(count, 1)
      }
    }
    return actualSize;
  }

  /**
   * @dev Encode the signed integer
   * @param x The signed integer to be encoded
   * @param sz The maximum number of bytes used to encode Solidity types
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The number of bytes needed for encoding `x`
   */
  function _encode_sol_raw_other(
    int256 x,
    uint256 p,
    bytes memory bs,
    uint256 sz
  ) internal pure returns (uint256) {
    /**
     * The idea is to not encode the leading bytes of zero.or one,
     * depending on whether it is positive.
     */
    uint256 realSize = _get_real_size(x, sz);
    assembly {
      let bsptr := add(bs, p)
      let count := realSize
      for {

      } gt(count, 0) {

      } {
        mstore8(bsptr, byte(sub(32, count), x))
        bsptr := add(bsptr, 1)
        count := sub(count, 1)
      }
    }
    return realSize;
  }

  /**
   * @dev Encode the unsigned integer
   * @param x The unsigned integer to be encoded
   * @param sz The maximum number of bytes used to encode Solidity types
   * @param p The offset of bytes array `bs`
   * @param bs The bytes array to encode
   * @return The number of bytes needed for encoding `x`
   */
  function _encode_sol_raw_other(
    uint256 x,
    uint256 p,
    bytes memory bs,
    uint256 sz
  ) internal pure returns (uint256) {
    uint256 realSize = _get_real_size(x, sz);
    assembly {
      let bsptr := add(bs, p)
      let count := realSize
      for {

      } gt(count, 0) {

      } {
        mstore8(bsptr, byte(sub(32, count), x))
        bsptr := add(bsptr, 1)
        count := sub(count, 1)
      }
    }
    return realSize;
  }
}

File 32 of 36 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 33 of 36 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 34 of 36 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

File 35 of 36 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 36 of 36 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)

pragma solidity ^0.8.20;

import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant HEX_DIGITS = "0123456789abcdef";
    uint8 private constant ADDRESS_LENGTH = 20;

    /**
     * @dev The `value` string doesn't fit in the specified `length`.
     */
    error StringsInsufficientHexLength(uint256 value, uint256 length);

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toStringSigned(int256 value) internal pure returns (string memory) {
        return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        uint256 localValue = value;
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = HEX_DIGITS[localValue & 0xf];
            localValue >>= 4;
        }
        if (localValue != 0) {
            revert StringsInsufficientHexLength(value, length);
        }
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
     * representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 9999999
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"contract IIBCClient","name":"ibcClient_","type":"address"},{"internalType":"contract IIBCConnection","name":"ibcConnection_","type":"address"},{"internalType":"contract IIBCChannelHandshake","name":"ibcChannelHandshake_","type":"address"},{"internalType":"contract IIBCChannelPacketSendRecv","name":"ibcChannelPacketSendRecv_","type":"address"},{"internalType":"contract IIBCChannelPacketTimeout","name":"ibcChannelPacketTimeout_","type":"address"},{"internalType":"contract IIBCChannelUpgradeInitTryAck","name":"ibcChannelUpgradeInitTryAck_","type":"address"},{"internalType":"contract IIBCChannelUpgradeConfirmOpenTimeoutCancel","name":"ibcChannelUpgradeConfirmOpenTimeoutCancel_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint64","name":"ackStartSequence","type":"uint64"}],"name":"IBCChannelAckAlreadyProcessedInPreviousUpgrade","type":"error"},{"inputs":[{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"uint64","name":"sequence","type":"uint64"}],"name":"IBCChannelAcknowledgementAlreadyWritten","type":"error"},{"inputs":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint64","name":"counterpartyNextSequenceSend","type":"uint64"}],"name":"IBCChannelCannotRecvNextUpgradePacket","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"IBCChannelChannelNotFound","type":"error"},{"inputs":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"}],"name":"IBCChannelConnectionFeatureNotSupported","type":"error"},{"inputs":[{"internalType":"string","name":"connectionId","type":"string"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"IBCChannelConnectionMultipleVersionsFound","type":"error"},{"inputs":[{"internalType":"string","name":"connectionId","type":"string"}],"name":"IBCChannelConnectionNotOpened","type":"error"},{"inputs":[{"internalType":"string","name":"counterpartyChannelId","type":"string"}],"name":"IBCChannelCounterpartyChannelIdNotEmpty","type":"error"},{"inputs":[],"name":"IBCChannelEmptyAcknowledgement","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCChannelFailedVerifyChannelState","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint64","name":"nextSequenceRecv","type":"uint64"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCChannelFailedVerifyNextSequenceRecv","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes32","name":"commitment","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCChannelFailedVerifyPacketAcknowledgement","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes32","name":"commitment","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCChannelFailedVerifyPacketCommitment","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCChannelFailedVerifyPacketReceiptAbsence","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"IBCChannelInvalidConnectionHopsLength","type":"error"},{"inputs":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint64","name":"recvStartSequence","type":"uint64"}],"name":"IBCChannelPacketAlreadyProcessInPreviousUpgrade","type":"error"},{"inputs":[{"internalType":"bytes32","name":"expected","type":"bytes32"},{"internalType":"bytes32","name":"actual","type":"bytes32"}],"name":"IBCChannelPacketCommitmentMismatch","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"uint64","name":"sequence","type":"uint64"}],"name":"IBCChannelPacketCommitmentNotFound","type":"error"},{"inputs":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"uint64","name":"nextSequenceRecv","type":"uint64"}],"name":"IBCChannelPacketMaybeAlreadyReceived","type":"error"},{"inputs":[{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"uint64","name":"sequence","type":"uint64"}],"name":"IBCChannelPacketReceiptAlreadyExists","type":"error"},{"inputs":[{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"latestHeight","type":"tuple"}],"name":"IBCChannelPastPacketTimeoutHeight","type":"error"},{"inputs":[{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"},{"internalType":"uint64","name":"latestTimestamp","type":"uint64"}],"name":"IBCChannelPastPacketTimeoutTimestamp","type":"error"},{"inputs":[],"name":"IBCChannelTimeoutNotReached","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentBlockNumber","type":"uint256"},{"internalType":"uint64","name":"timeoutHeight","type":"uint64"}],"name":"IBCChannelTimeoutPacketHeight","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentTimestamp","type":"uint256"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"name":"IBCChannelTimeoutPacketTimestamp","type":"error"},{"inputs":[{"internalType":"enum Channel.State","name":"state","type":"uint8"}],"name":"IBCChannelUnexpectedChannelState","type":"error"},{"inputs":[{"internalType":"uint64","name":"expected","type":"uint64"}],"name":"IBCChannelUnexpectedNextSequenceAck","type":"error"},{"inputs":[{"internalType":"uint64","name":"expected","type":"uint64"}],"name":"IBCChannelUnexpectedNextSequenceRecv","type":"error"},{"inputs":[{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"}],"name":"IBCChannelUnexpectedPacketDestination","type":"error"},{"inputs":[{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"}],"name":"IBCChannelUnexpectedPacketSource","type":"error"},{"inputs":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"}],"name":"IBCChannelUnknownChannelOrder","type":"error"},{"inputs":[{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"IBCChannelUnknownPacketReceiptCommitment","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeCounterpartyAlreadyFlushCompleted","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeCounterpartyAlreadyUpgraded","type":"error"},{"inputs":[{"internalType":"enum Channel.State","name":"state","type":"uint8"}],"name":"IBCChannelUpgradeCounterpartyNotFlushingOrFlushcomplete","type":"error"},{"inputs":[{"internalType":"enum Channel.State","name":"state","type":"uint8"}],"name":"IBCChannelUpgradeCounterpartyNotOpenOrFlushcomplete","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeErrorReceiptEmpty","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"string","name":"path","type":"string"},{"internalType":"bytes","name":"value","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCChannelUpgradeFailedVerifyMembership","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeIncompatibleProposal","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeInvalidErrorReceiptSequence","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeInvalidTimeout","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeInvalidUpgradeFields","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeNoChanges","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeNoExistingUpgrade","type":"error"},{"inputs":[{"internalType":"enum Channel.State","name":"state","type":"uint8"}],"name":"IBCChannelUpgradeNotFlushcomplete","type":"error"},{"inputs":[{"internalType":"enum Channel.State","name":"state","type":"uint8"}],"name":"IBCChannelUpgradeNotFlushing","type":"error"},{"inputs":[{"internalType":"enum Channel.State","name":"state","type":"uint8"}],"name":"IBCChannelUpgradeNotOpenOrFlushing","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeOldCounterpartyUpgradeSequence","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeOldErrorReceiptSequence","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeTimeoutHeightNotReached","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeTimeoutTimestampNotReached","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeTimeoutUnallowedState","type":"error"},{"inputs":[],"name":"IBCChannelUpgradeTryProposalMustEmptyIfExist","type":"error"},{"inputs":[{"internalType":"address","name":"upgrader","type":"address"}],"name":"IBCChannelUpgradeUnauthorizedChannelUpgrader","type":"error"},{"inputs":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"}],"name":"IBCChannelUpgradeUnsupportedOrdering","type":"error"},{"inputs":[{"internalType":"uint64","name":"latestSequence","type":"uint64"},{"internalType":"uint64","name":"sequence","type":"uint64"}],"name":"IBCChannelUpgradeWriteOldErrorReceiptSequence","type":"error"},{"inputs":[],"name":"IBCChannelZeroPacketTimeout","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"}],"name":"IBCClientClientNotFound","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"consensusHeight","type":"tuple"}],"name":"IBCClientConsensusStateNotFound","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"bytes","name":"args","type":"bytes"}],"name":"IBCClientFailedUpdateClient","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"}],"name":"IBCClientNotActiveClient","type":"error"},{"inputs":[{"internalType":"string","name":"clientType","type":"string"}],"name":"IBCClientUnregisteredClientType","type":"error"},{"inputs":[],"name":"IBCConnectionAlreadyConnectionExists","type":"error"},{"inputs":[],"name":"IBCConnectionEmptyConnectionCounterpartyVersions","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCConnectionFailedVerifyClientConsensusState","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCConnectionFailedVerifyClientState","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"IBCConnectionFailedVerifyConnectionState","type":"error"},{"inputs":[],"name":"IBCConnectionIBCVersionNotSupported","type":"error"},{"inputs":[{"internalType":"string","name":"counterpartyConnectionId","type":"string"}],"name":"IBCConnectionInvalidCounterpartyConnectionIdentifier","type":"error"},{"inputs":[],"name":"IBCConnectionInvalidHostConsensusStateProof","type":"error"},{"inputs":[],"name":"IBCConnectionInvalidSelfClientState","type":"error"},{"inputs":[],"name":"IBCConnectionNoMatchingVersionFound","type":"error"},{"inputs":[{"internalType":"enum ConnectionEnd.State","name":"state","type":"uint8"}],"name":"IBCConnectionUnexpectedConnectionState","type":"error"},{"inputs":[],"name":"IBCConnectionVersionsAlreadySet","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"IBCHostChannelCapabilityAlreadyClaimed","type":"error"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"}],"name":"IBCHostClientNotFound","type":"error"},{"inputs":[{"internalType":"string","name":"clientType","type":"string"}],"name":"IBCHostClientTypeAlreadyExists","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"address","name":"caller","type":"address"}],"name":"IBCHostFailedAuthenticateChannelCapability","type":"error"},{"inputs":[{"internalType":"string","name":"clientType","type":"string"}],"name":"IBCHostInvalidClientType","type":"error"},{"inputs":[{"internalType":"address","name":"lcAddress","type":"address"}],"name":"IBCHostInvalidLightClientAddress","type":"error"},{"inputs":[{"internalType":"address","name":"moduleAddress","type":"address"}],"name":"IBCHostInvalidModuleAddress","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"}],"name":"IBCHostInvalidPortIdentifier","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"IBCHostModuleChannelNotFound","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"}],"name":"IBCHostModulePortNotFound","type":"error"},{"inputs":[{"internalType":"string","name":"portId","type":"string"}],"name":"IBCHostPortCapabilityAlreadyClaimed","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"},{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"indexed":false,"internalType":"struct Packet","name":"packet","type":"tuple"},{"indexed":false,"internalType":"bytes","name":"acknowledgement","type":"bytes"}],"name":"AcknowledgePacket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"portId","type":"string"},{"indexed":false,"internalType":"string","name":"channelId","type":"string"},{"indexed":false,"internalType":"uint64","name":"upgradeSequence","type":"uint64"},{"indexed":false,"internalType":"enum Channel.State","name":"channelState","type":"uint8"},{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"indexed":false,"internalType":"struct UpgradeFields.Data","name":"upgradeFields","type":"tuple"},{"components":[{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"indexed":false,"internalType":"struct Timeout.Data","name":"timeout","type":"tuple"},{"indexed":false,"internalType":"uint64","name":"nextSequenceSend","type":"uint64"}],"name":"ChannelUpgradeAck","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"portId","type":"string"},{"indexed":false,"internalType":"string","name":"channelId","type":"string"},{"indexed":false,"internalType":"uint64","name":"upgradeSequence","type":"uint64"},{"indexed":false,"internalType":"enum Channel.State","name":"channelState","type":"uint8"}],"name":"ChannelUpgradeConfirm","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"portId","type":"string"},{"indexed":false,"internalType":"string","name":"channelId","type":"string"},{"indexed":false,"internalType":"uint64","name":"upgradeSequence","type":"uint64"},{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"indexed":false,"internalType":"struct UpgradeFields.Data","name":"proposedUpgradeFields","type":"tuple"}],"name":"ChannelUpgradeInit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"portId","type":"string"},{"indexed":false,"internalType":"string","name":"channelId","type":"string"},{"indexed":false,"internalType":"uint64","name":"upgradeSequence","type":"uint64"}],"name":"ChannelUpgradeOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"portId","type":"string"},{"indexed":false,"internalType":"string","name":"channelId","type":"string"},{"indexed":false,"internalType":"uint64","name":"upgradeSequence","type":"uint64"},{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"indexed":false,"internalType":"struct UpgradeFields.Data","name":"upgradeFields","type":"tuple"},{"components":[{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"indexed":false,"internalType":"struct Timeout.Data","name":"timeout","type":"tuple"},{"indexed":false,"internalType":"uint64","name":"nextSequenceSend","type":"uint64"}],"name":"ChannelUpgradeTry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"channelId","type":"string"}],"name":"GeneratedChannelIdentifier","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"clientId","type":"string"}],"name":"GeneratedClientIdentifier","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"connectionId","type":"string"}],"name":"GeneratedConnectionIdentifier","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"},{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"indexed":false,"internalType":"struct Packet","name":"packet","type":"tuple"}],"name":"RecvPacket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":false,"internalType":"string","name":"sourcePort","type":"string"},{"indexed":false,"internalType":"string","name":"sourceChannel","type":"string"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"indexed":false,"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"indexed":false,"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"SendPacket","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"},{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"indexed":false,"internalType":"struct Packet","name":"packet","type":"tuple"}],"name":"TimeoutPacket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"destinationPortId","type":"string"},{"indexed":false,"internalType":"string","name":"destinationChannel","type":"string"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"acknowledgement","type":"bytes"}],"name":"WriteAcknowledgement","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"portId","type":"string"},{"indexed":false,"internalType":"string","name":"channelId","type":"string"},{"indexed":false,"internalType":"uint64","name":"upgradeSequence","type":"uint64"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"WriteErrorReceipt","type":"event"},{"inputs":[{"components":[{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"},{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"internalType":"struct Packet","name":"packet","type":"tuple"},{"internalType":"bytes","name":"acknowledgement","type":"bytes"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelAcknowledgePacket.MsgPacketAcknowledgement","name":"","type":"tuple"}],"name":"acknowledgePacket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"contract IIBCModule","name":"moduleAddress","type":"address"}],"name":"bindPort","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"message","type":"string"}],"internalType":"struct ErrorReceipt.Data","name":"errorReceipt","type":"tuple"},{"internalType":"bytes","name":"proofUpgradeError","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.MsgCancelChannelUpgrade","name":"","type":"tuple"}],"name":"cancelChannelUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"bytes","name":"proofInit","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelHandshake.MsgChannelCloseConfirm","name":"","type":"tuple"}],"name":"channelCloseConfirm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"internalType":"struct IIBCChannelHandshake.MsgChannelCloseInit","name":"","type":"tuple"}],"name":"channelCloseInit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"string","name":"counterpartyVersion","type":"string"},{"internalType":"string","name":"counterpartyChannelId","type":"string"},{"internalType":"bytes","name":"proofTry","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelHandshake.MsgChannelOpenAck","name":"","type":"tuple"}],"name":"channelOpenAck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"bytes","name":"proofAck","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelHandshake.MsgChannelOpenConfirm","name":"","type":"tuple"}],"name":"channelOpenConfirm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"components":[{"internalType":"enum Channel.State","name":"state","type":"uint8"},{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"components":[{"internalType":"string","name":"port_id","type":"string"},{"internalType":"string","name":"channel_id","type":"string"}],"internalType":"struct ChannelCounterparty.Data","name":"counterparty","type":"tuple"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint64","name":"upgrade_sequence","type":"uint64"}],"internalType":"struct Channel.Data","name":"channel","type":"tuple"}],"internalType":"struct IIBCChannelHandshake.MsgChannelOpenInit","name":"","type":"tuple"}],"name":"channelOpenInit","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"components":[{"internalType":"enum Channel.State","name":"state","type":"uint8"},{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"components":[{"internalType":"string","name":"port_id","type":"string"},{"internalType":"string","name":"channel_id","type":"string"}],"internalType":"struct ChannelCounterparty.Data","name":"counterparty","type":"tuple"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint64","name":"upgrade_sequence","type":"uint64"}],"internalType":"struct Channel.Data","name":"channel","type":"tuple"},{"internalType":"string","name":"counterpartyVersion","type":"string"},{"internalType":"bytes","name":"proofInit","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelHandshake.MsgChannelOpenTry","name":"","type":"tuple"}],"name":"channelOpenTry","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"components":[{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"internalType":"struct UpgradeFields.Data","name":"fields","type":"tuple"},{"components":[{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"internalType":"struct Timeout.Data","name":"timeout","type":"tuple"},{"internalType":"uint64","name":"next_sequence_send","type":"uint64"}],"internalType":"struct Upgrade.Data","name":"counterpartyUpgrade","type":"tuple"},{"components":[{"internalType":"bytes","name":"proofChannel","type":"bytes"},{"internalType":"bytes","name":"proofUpgrade","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.ChannelUpgradeProofs","name":"proofs","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.MsgChannelUpgradeAck","name":"","type":"tuple"}],"name":"channelUpgradeAck","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"enum Channel.State","name":"counterpartyChannelState","type":"uint8"},{"components":[{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"internalType":"struct UpgradeFields.Data","name":"fields","type":"tuple"},{"components":[{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"internalType":"struct Timeout.Data","name":"timeout","type":"tuple"},{"internalType":"uint64","name":"next_sequence_send","type":"uint64"}],"internalType":"struct Upgrade.Data","name":"counterpartyUpgrade","type":"tuple"},{"components":[{"internalType":"bytes","name":"proofChannel","type":"bytes"},{"internalType":"bytes","name":"proofUpgrade","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.ChannelUpgradeProofs","name":"proofs","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.MsgChannelUpgradeConfirm","name":"","type":"tuple"}],"name":"channelUpgradeConfirm","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"internalType":"struct UpgradeFields.Data","name":"proposedUpgradeFields","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.MsgChannelUpgradeInit","name":"","type":"tuple"}],"name":"channelUpgradeInit","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"enum Channel.State","name":"counterpartyChannelState","type":"uint8"},{"internalType":"uint64","name":"counterpartyUpgradeSequence","type":"uint64"},{"internalType":"bytes","name":"proofChannel","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.MsgChannelUpgradeOpen","name":"","type":"tuple"}],"name":"channelUpgradeOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"uint64","name":"counterpartyUpgradeSequence","type":"uint64"},{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"internalType":"struct UpgradeFields.Data","name":"counterpartyUpgradeFields","type":"tuple"},{"internalType":"string[]","name":"proposedConnectionHops","type":"string[]"},{"components":[{"internalType":"bytes","name":"proofChannel","type":"bytes"},{"internalType":"bytes","name":"proofUpgrade","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.ChannelUpgradeProofs","name":"proofs","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.MsgChannelUpgradeTry","name":"","type":"tuple"}],"name":"channelUpgradeTry","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"connectionId","type":"string"},{"internalType":"bytes","name":"clientStateBytes","type":"bytes"},{"components":[{"internalType":"string","name":"identifier","type":"string"},{"internalType":"string[]","name":"features","type":"string[]"}],"internalType":"struct Version.Data","name":"version","type":"tuple"},{"internalType":"string","name":"counterpartyConnectionId","type":"string"},{"internalType":"bytes","name":"proofTry","type":"bytes"},{"internalType":"bytes","name":"proofClient","type":"bytes"},{"internalType":"bytes","name":"proofConsensus","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"consensusHeight","type":"tuple"},{"internalType":"bytes","name":"hostConsensusStateProof","type":"bytes"}],"internalType":"struct IIBCConnection.MsgConnectionOpenAck","name":"","type":"tuple"}],"name":"connectionOpenAck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"connectionId","type":"string"},{"internalType":"bytes","name":"proofAck","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCConnection.MsgConnectionOpenConfirm","name":"","type":"tuple"}],"name":"connectionOpenConfirm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"clientId","type":"string"},{"components":[{"internalType":"string","name":"client_id","type":"string"},{"internalType":"string","name":"connection_id","type":"string"},{"components":[{"internalType":"bytes","name":"key_prefix","type":"bytes"}],"internalType":"struct MerklePrefix.Data","name":"prefix","type":"tuple"}],"internalType":"struct Counterparty.Data","name":"counterparty","type":"tuple"},{"components":[{"internalType":"string","name":"identifier","type":"string"},{"internalType":"string[]","name":"features","type":"string[]"}],"internalType":"struct Version.Data","name":"version","type":"tuple"},{"internalType":"uint64","name":"delayPeriod","type":"uint64"}],"internalType":"struct IIBCConnection.MsgConnectionOpenInit","name":"","type":"tuple"}],"name":"connectionOpenInit","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"client_id","type":"string"},{"internalType":"string","name":"connection_id","type":"string"},{"components":[{"internalType":"bytes","name":"key_prefix","type":"bytes"}],"internalType":"struct MerklePrefix.Data","name":"prefix","type":"tuple"}],"internalType":"struct Counterparty.Data","name":"counterparty","type":"tuple"},{"internalType":"uint64","name":"delayPeriod","type":"uint64"},{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"clientStateBytes","type":"bytes"},{"components":[{"internalType":"string","name":"identifier","type":"string"},{"internalType":"string[]","name":"features","type":"string[]"}],"internalType":"struct Version.Data[]","name":"counterpartyVersions","type":"tuple[]"},{"internalType":"bytes","name":"proofInit","type":"bytes"},{"internalType":"bytes","name":"proofClient","type":"bytes"},{"internalType":"bytes","name":"proofConsensus","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"consensusHeight","type":"tuple"},{"internalType":"bytes","name":"hostConsensusStateProof","type":"bytes"}],"internalType":"struct IIBCConnection.MsgConnectionOpenTry","name":"","type":"tuple"}],"name":"connectionOpenTry","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"clientType","type":"string"},{"internalType":"bytes","name":"protoClientState","type":"bytes"},{"internalType":"bytes","name":"protoConsensusState","type":"bytes"}],"internalType":"struct IIBCClient.MsgCreateClient","name":"","type":"tuple"}],"name":"createClient","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"getChannel","outputs":[{"components":[{"internalType":"enum Channel.State","name":"state","type":"uint8"},{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"components":[{"internalType":"string","name":"port_id","type":"string"},{"internalType":"string","name":"channel_id","type":"string"}],"internalType":"struct ChannelCounterparty.Data","name":"counterparty","type":"tuple"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint64","name":"upgrade_sequence","type":"uint64"}],"internalType":"struct Channel.Data","name":"","type":"tuple"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"getChannelUpgrade","outputs":[{"components":[{"components":[{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"}],"internalType":"struct UpgradeFields.Data","name":"fields","type":"tuple"},{"components":[{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"internalType":"struct Timeout.Data","name":"timeout","type":"tuple"},{"internalType":"uint64","name":"next_sequence_send","type":"uint64"}],"internalType":"struct Upgrade.Data","name":"","type":"tuple"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"}],"name":"getClient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"clientType","type":"string"}],"name":"getClientByType","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"}],"name":"getClientState","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"}],"name":"getClientType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hashedPath","type":"bytes32"}],"name":"getCommitment","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCommitmentPrefix","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"connectionId","type":"string"}],"name":"getConnection","outputs":[{"components":[{"internalType":"string","name":"client_id","type":"string"},{"components":[{"internalType":"string","name":"identifier","type":"string"},{"internalType":"string[]","name":"features","type":"string[]"}],"internalType":"struct Version.Data[]","name":"versions","type":"tuple[]"},{"internalType":"enum ConnectionEnd.State","name":"state","type":"uint8"},{"components":[{"internalType":"string","name":"client_id","type":"string"},{"internalType":"string","name":"connection_id","type":"string"},{"components":[{"internalType":"bytes","name":"key_prefix","type":"bytes"}],"internalType":"struct MerklePrefix.Data","name":"prefix","type":"tuple"}],"internalType":"struct Counterparty.Data","name":"counterparty","type":"tuple"},{"internalType":"uint64","name":"delay_period","type":"uint64"}],"internalType":"struct ConnectionEnd.Data","name":"","type":"tuple"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"clientId","type":"string"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"height","type":"tuple"}],"name":"getConsensusState","outputs":[{"internalType":"bytes","name":"consensusStateBytes","type":"bytes"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExpectedTimePerBlock","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"getNextSequenceAck","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"getNextSequenceRecv","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"}],"name":"getNextSequenceSend","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"internalType":"uint64","name":"sequence","type":"uint64"}],"name":"getPacketReceipt","outputs":[{"internalType":"enum IBCChannelLib.PacketReceipt","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"},{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"internalType":"struct Packet","name":"packet","type":"tuple"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelRecvPacket.MsgPacketRecv","name":"","type":"tuple"}],"name":"recvPacket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"clientType","type":"string"},{"internalType":"contract ILightClient","name":"client","type":"address"}],"name":"registerClient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"protoClientMessage","type":"bytes"}],"internalType":"struct IIBCClient.MsgUpdateClient","name":"msg_","type":"tuple"}],"name":"routeUpdateClient","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"","type":"tuple"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"sendPacket","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"expectedTimePerBlock_","type":"uint64"}],"name":"setExpectedTimePerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"portId","type":"string"},{"internalType":"string","name":"channelId","type":"string"},{"components":[{"internalType":"enum Channel.State","name":"state","type":"uint8"},{"internalType":"enum Channel.Order","name":"ordering","type":"uint8"},{"components":[{"internalType":"string","name":"port_id","type":"string"},{"internalType":"string","name":"channel_id","type":"string"}],"internalType":"struct ChannelCounterparty.Data","name":"counterparty","type":"tuple"},{"internalType":"string[]","name":"connection_hops","type":"string[]"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint64","name":"upgrade_sequence","type":"uint64"}],"internalType":"struct Channel.Data","name":"counterpartyChannel","type":"tuple"},{"internalType":"bytes","name":"proofChannel","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"}],"internalType":"struct IIBCChannelUpgradeBase.MsgTimeoutChannelUpgrade","name":"","type":"tuple"}],"name":"timeoutChannelUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"},{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"internalType":"struct Packet","name":"packet","type":"tuple"},{"internalType":"bytes","name":"proofUnreceived","type":"bytes"},{"internalType":"bytes","name":"proofClose","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"},{"internalType":"uint64","name":"nextSequenceRecv","type":"uint64"},{"internalType":"uint64","name":"counterpartyUpgradeSequence","type":"uint64"}],"internalType":"struct IIBCChannelPacketTimeout.MsgTimeoutOnClose","name":"","type":"tuple"}],"name":"timeoutOnClose","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"string","name":"sourcePort","type":"string"},{"internalType":"string","name":"sourceChannel","type":"string"},{"internalType":"string","name":"destinationPort","type":"string"},{"internalType":"string","name":"destinationChannel","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"timeoutHeight","type":"tuple"},{"internalType":"uint64","name":"timeoutTimestamp","type":"uint64"}],"internalType":"struct Packet","name":"packet","type":"tuple"},{"internalType":"bytes","name":"proof","type":"bytes"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data","name":"proofHeight","type":"tuple"},{"internalType":"uint64","name":"nextSequenceRecv","type":"uint64"}],"internalType":"struct IIBCChannelPacketTimeout.MsgTimeoutPacket","name":"","type":"tuple"}],"name":"timeoutPacket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"protoClientMessage","type":"bytes"}],"internalType":"struct IIBCClient.MsgUpdateClient","name":"","type":"tuple"}],"name":"updateClient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"components":[{"internalType":"uint64","name":"revision_number","type":"uint64"},{"internalType":"uint64","name":"revision_height","type":"uint64"}],"internalType":"struct Height.Data[]","name":"","type":"tuple[]"}],"name":"updateClientCommitments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"clientId","type":"string"},{"internalType":"bytes","name":"protoClientMessage","type":"bytes"}],"internalType":"struct IIBCClient.MsgUpdateClient","name":"msg_","type":"tuple"}],"name":"wrappedRouteUpdateClient","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"writeAcknowledgement","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061032b5760003560e01c8063715018a6116101b2578063ae4cd201116100f9578063d3c68ba0116100a2578063e211bb061161007c578063e211bb061461072d578063ec75d82914610740578063f2fde38b14610752578063fb6c93f71461076557600080fd5b8063d3c68ba0146106f9578063d5a2448114610707578063da6cea551461071a57600080fd5b8063b5ad7134116100d3578063b5ad7134146106de578063c2333903146104ae578063cc93aebf146106e657600080fd5b8063ae4cd20114610698578063b5226815146106ab578063b56e79de146106cb57600080fd5b80638c145a931161015b578063921e51d411610135578063921e51d41461066e578063a06cb3a21461067c578063aa18c8b11461068a57600080fd5b80638c145a931461062f5780638da5cb5b1461063d57806391f624341461065b57600080fd5b80637ad817541161018c5780637ad81754146105f65780637eb789321461060957806384515f5d1461061c57600080fd5b8063715018a6146105ad57806376c81c42146105b55780637795820c146105c857600080fd5b8063314c3c1c116102765780634e61055a1161021f5780635bd51b62116101f95780635bd51b62146103c75780636a728f2c146105795780636cf44bf41461058c57600080fd5b80634e61055a14610525578063582418b61461055857806359f379761461056b57600080fd5b8063382db38811610250578063382db388146104ae57806340d20d13146104c15780634e08c6f3146104f957600080fd5b8063314c3c1c1461045e578063314d55c31461046c57806332b5f86c1461048c57600080fd5b806325cbc3a6116102d85780632d5386df116102b25780632d5386df146104095780632e5e6d741461042a5780633000217a1461043d57600080fd5b806325cbc3a6146103c757806327184c13146103d557806327711a69146103e857600080fd5b806318c198701161030957806318c198701461038e578063236ebd70146103a1578063256c4199146103b457600080fd5b80630db24ed714610330578063117e886a1461035857806316fb38fd1461036d575b600080fd5b61034361033e3660046126a1565b610773565b60405190151581526020015b60405180910390f35b61036b610366366004612742565b6107a3565b005b61038061037b366004612799565b6107bb565b60405161034f92919061290b565b61036b61039c366004612742565b610a2a565b61036b6103af3660046129f5565b610a3d565b61036b6103c2366004612a3c565b610a69565b61036b6103c23660046126a1565b61036b6103e3366004612a89565b610a92565b6103fb6103f6366004612aa4565b610ad1565b60405161034f929190612b52565b61041c610417366004612ca8565b610fb9565b60405161034f929190612cdd565b61036b610438366004612a3c565b610fea565b61045061044b366004612799565b611013565b60405161034f929190612d02565b61041c610417366004612e1f565b61047f61047a366004612e54565b6113b3565b60405161034f9190612e90565b61049f61049a366004612ca8565b6113de565b60405161034f93929190612ea3565b61036b6104bc366004612e1f565b6115a3565b6104d46104cf366004612aa4565b6115cc565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161034f565b61050c610507366004612799565b61160e565b60405167ffffffffffffffff909116815260200161034f565b610538610533366004612e1f565b611664565b60408051921515835267ffffffffffffffff90911660208301520161034f565b61050c610566366004612799565b611690565b61036b6103af3660046126a1565b61036b6105873660046129f5565b6116a4565b61059f61059a366004612efa565b6116cd565b60405161034f929190612f4f565b61036b6117bb565b61059f6105c3366004612aa4565b6117cf565b6105e86105d6366004612f73565b60009081526020819052604090205490565b60405190815260200161034f565b61036b610604366004612f8c565b6118ba565b6104d4610617366004612aa4565b6118e9565b61047f61062a366004612aa4565b6118fd565b61036b610587366004613026565b60105473ffffffffffffffffffffffffffffffffffffffff166104d4565b61049f610669366004612ca8565b6119b0565b61036b6104bc366004612a3c565b61036b6103c2366004612ca8565b61036b6104383660046126a1565b61050c6106a6366004613062565b611a64565b6106be6106b9366004613121565b611a9b565b60405161034f91906131a2565b61036b6106d93660046131bc565b611ace565b61047f611b00565b61050c6106f436600461327c565b611b41565b61047f61047a3660046129f5565b61047f61071536600461327c565b611b6c565b61036b610728366004612ca8565b611b97565b61050c61073b366004612799565b611bc0565b600f5467ffffffffffffffff1661050c565b61036b6107603660046132b1565b611bd4565b6103436106f43660046129f5565b600061079e7f000000000000000000000000aaf39c1c8a76f077c0c6020f43d4f7ea235f9872611c35565b919050565b6107ab611c59565b6107b6838383611cac565b505050565b6107c3612580565b600080600b87876040516107d89291906132ce565b908152602001604051809103902085856040516107f69291906132ce565b90815260408051918290036020018220600181015460c084019092528054909350839291151591908390829060608201908390829060ff16600281111561083f5761083f612805565b600281111561085057610850612805565b815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610925578382906000526020600020018054610898906132de565b80601f01602080910402602001604051908101604052809291908181526020018280546108c4906132de565b80156109115780601f106108e657610100808354040283529160200191610911565b820191906000526020600020905b8154815290600101906020018083116108f457829003601f168201915b505050505081526020019060010190610879565b50505050815260200160028201805461093d906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054610969906132de565b80156109b65780601f1061098b576101008083540402835291602001916109b6565b820191906000526020600020905b81548152906001019060200180831161099957829003601f168201915b50505091909252505050815260408051608081018252600384015467ffffffffffffffff808216838501908152680100000000000000009092048116606084015290825260048501548116602080840191909152840191909152600590930154909216910152999098509650505050505050565b610a32611c59565b6107b6838383611db7565b610a667f00000000000000000000000097bc199b19190c71a05a46d245053aab9b3c0d66611c35565b50565b610a667f00000000000000000000000024759371124c35244e59c733ff8ef2b5a4fb6c93611c35565b610a9a611c59565b600f80547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff831617905550565b610ad96125bc565b60008060048585604051610aee9291906132ce565b9081526040519081900360200190209050806000600283015460ff166003811115610b1b57610b1b612805565b1415816040518060a0016040529081600082018054610b39906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054610b65906132de565b8015610bb25780601f10610b8757610100808354040283529160200191610bb2565b820191906000526020600020905b815481529060010190602001808311610b9557829003601f168201915b5050505050815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610d7d5783829060005260206000209060020201604051806040016040529081600082018054610c13906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3f906132de565b8015610c8c5780601f10610c6157610100808354040283529160200191610c8c565b820191906000526020600020905b815481529060010190602001808311610c6f57829003601f168201915b5050505050815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610d66578382906000526020600020018054610cd9906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054610d05906132de565b8015610d525780601f10610d2757610100808354040283529160200191610d52565b820191906000526020600020905b815481529060010190602001808311610d3557829003601f168201915b505050505081526020019060010190610cba565b505050508152505081526020019060010190610be0565b50505090825250600282015460209091019060ff166003811115610da357610da3612805565b6003811115610db457610db4612805565b815260200160038201604051806060016040529081600082018054610dd8906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054610e04906132de565b8015610e515780601f10610e2657610100808354040283529160200191610e51565b820191906000526020600020905b815481529060010190602001808311610e3457829003601f168201915b50505050508152602001600182018054610e6a906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054610e96906132de565b8015610ee35780601f10610eb857610100808354040283529160200191610ee3565b820191906000526020600020905b815481529060010190602001808311610ec657829003601f168201915b5050505050815260200160028201604051806020016040529081600082018054610f0c906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054610f38906132de565b8015610f855780601f10610f5a57610100808354040283529160200191610f85565b820191906000526020600020905b815481529060010190602001808311610f6857829003601f168201915b5050509190925250505090525081526006919091015467ffffffffffffffff166020909101529450925050505b9250929050565b606080610fe57f00000000000000000000000024759371124c35244e59c733ff8ef2b5a4fb6c93611c35565b915091565b610a667f0000000000000000000000009ef35a16c2201afaf653f6282ed561675f9a65f9611c35565b61101b6125e2565b600080600587876040516110309291906132ce565b9081526020016040518091039020858560405161104e9291906132ce565b9081526040519081900360200190209050806000825460ff16600681111561107857611078612805565b6040805160c0810190915283549290911415918390829060ff1660068111156110a3576110a3612805565b60068111156110b4576110b4612805565b81528154602090910190610100900460ff1660028111156110d7576110d7612805565b60028111156110e8576110e8612805565b81526020016001820160405180604001604052908160008201805461110c906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054611138906132de565b80156111855780601f1061115a57610100808354040283529160200191611185565b820191906000526020600020905b81548152906001019060200180831161116857829003601f168201915b5050505050815260200160018201805461119e906132de565b80601f01602080910402602001604051908101604052809291908181526020018280546111ca906132de565b80156112175780601f106111ec57610100808354040283529160200191611217565b820191906000526020600020905b8154815290600101906020018083116111fa57829003601f168201915b505050505081525050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156112f5578382906000526020600020018054611268906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054611294906132de565b80156112e15780601f106112b6576101008083540402835291602001916112e1565b820191906000526020600020905b8154815290600101906020018083116112c457829003601f168201915b505050505081526020019060010190611249565b50505050815260200160048201805461130d906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054611339906132de565b80156113865780601f1061135b57610100808354040283529160200191611386565b820191906000526020600020905b81548152906001019060200180831161136957829003601f168201915b50505091835250506005919091015467ffffffffffffffff16602090910152999098509650505050505050565b606061079e7f00000000000000000000000081dfd32d00f10995567d004163a82c8f05476dfc611c35565b60008060606000807f0000000000000000000000009961c74818e1bc6657cadd402f82aa5d125b7c7873ffffffffffffffffffffffffffffffffffffffff166391f6243460e01b8760405160240161143691906133d8565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516114bf9190613442565b600060405180830381855af49150503d80600081146114fa576040519150601f19603f3d011682016040523d82523d6000602084013e6114ff565b606091505b509150915081611580578051156115195780518082602001fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f726f757465557064617465436c69656e74206661696c6564000000000000000060448201526064015b60405180910390fd5b808060200190518101906115949190613559565b94509450945050509193909250565b610a667f000000000000000000000000aaf39c1c8a76f077c0c6020f43d4f7ea235f9872611c35565b6000600183836040516115e09291906132ce565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b6000600885856040516116229291906132ce565b908152602001604051809103902083836040516116409291906132ce565b9081526040519081900360200190205467ffffffffffffffff169050949350505050565b600080610fe57f000000000000000000000000d1b762d8a840193c7aae9207ed057680928a0706611c35565b6000600685856040516116229291906132ce565b610a667f00000000000000000000000081dfd32d00f10995567d004163a82c8f05476dfc611c35565b6060600061171085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611fae92505050565b73ffffffffffffffffffffffffffffffffffffffff16636cf44bf48686866040518463ffffffff1660e01b815260040161174c939291906135b9565b600060405180830381865afa158015611769573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526117af9190810190613604565b91509150935093915050565b6117c3611c59565b6117cd6000612028565b565b6060600061181284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611fae92505050565b73ffffffffffffffffffffffffffffffffffffffff166376c81c4285856040518363ffffffff1660e01b815260040161184c92919061365b565b600060405180830381865afa158015611869573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526118af9190810190613604565b915091509250929050565b6118e37f0000000000000000000000009961c74818e1bc6657cadd402f82aa5d125b7c78611c35565b50505050565b6000600383836040516115e09291906132ce565b6060600283836040516119119291906132ce565b9081526020016040518091039020805461192a906132de565b80601f0160208091040260200160405190810160405280929190818152602001828054611956906132de565b80156119a35780601f10611978576101008083540402835291602001916119a3565b820191906000526020600020905b81548152906001019060200180831161198657829003601f168201915b5050505050905092915050565b6040517f32b5f86c000000000000000000000000000000000000000000000000000000008152600090819060609030906332b5f86c906119f49087906004016133d8565b600060405180830381865afa158015611a11573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611a579190810190613559565b9250925092509193909250565b6000611a8f7f00000000000000000000000097bc199b19190c71a05a46d245053aab9b3c0d66611c35565b98975050505050505050565b6000611ac4600080611ab0898989898961209f565b8152602001908152602001600020546120c0565b9695505050505050565b611af77f00000000000000000000000097bc199b19190c71a05a46d245053aab9b3c0d66611c35565b50505050505050565b6060611b3c60408051808201909152600381527f6962630000000000000000000000000000000000000000000000000000000000602082015290565b905090565b600061079e7f000000000000000000000000d1b762d8a840193c7aae9207ed057680928a0706611c35565b606061079e7f0000000000000000000000009961c74818e1bc6657cadd402f82aa5d125b7c78611c35565b610a667f0000000000000000000000009961c74818e1bc6657cadd402f82aa5d125b7c78611c35565b6000600785856040516116229291906132ce565b611bdc611c59565b73ffffffffffffffffffffffffffffffffffffffff8116611c2c576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401611577565b610a6681612028565b3660008037600080366000845af43d6000803e808015611c54573d6000f35b3d6000fd5b60105473ffffffffffffffffffffffffffffffffffffffff1633146117cd576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401611577565b611ceb83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061213a92505050565b611d255782826040517f0b8a094700000000000000000000000000000000000000000000000000000000815260040161157792919061365b565b73ffffffffffffffffffffffffffffffffffffffff81161580611d5d575073ffffffffffffffffffffffffffffffffffffffff811630145b15611dac576040517f8b423a4c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401611577565b6107b6838383612245565b611df683838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122e392505050565b611e305782826040517f6171687500000000000000000000000000000000000000000000000000000000815260040161157792919061365b565b600073ffffffffffffffffffffffffffffffffffffffff1660018484604051611e5a9291906132ce565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1614611ebb5782826040517f6ada3f3100000000000000000000000000000000000000000000000000000000815260040161157792919061365b565b73ffffffffffffffffffffffffffffffffffffffff81161580611ef3575073ffffffffffffffffffffffffffffffffffffffff811630145b15611f42576040517fb995091900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401611577565b8060018484604051611f559291906132ce565b908152604051908190036020019020805473ffffffffffffffffffffffffffffffffffffffff929092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216919091179055505050565b600080600383604051611fc19190613442565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1690508061202257826040517f25a8dfe70000000000000000000000000000000000000000000000000000000081526004016115779190612e90565b92915050565b6010805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006120ae8686868686612399565b80519060200120905095945050505050565b6000816120cf57506000919050565b60016040516020016120e1919061366f565b60405160208183030381529060405280519060200120820361210557506001919050565b6040517f03f233f700000000000000000000000000000000000000000000000000000000815260048101839052602401611577565b600060028251108061214d575060808251115b1561215a57506000919050565b60005b825181101561223c57600083828151811061217a5761217a613690565b016020015160f81c9050606181108015906121965750607a8111155b806121ae5750603081101580156121ae575060398111155b806121c65750604181101580156121c65750605a8111155b806121f1575080602e14806121db575080605f145b806121e6575080602b145b806121f1575080602d145b8061222757508060231480612206575080605b145b80612211575080605d145b8061221c575080603c145b80612227575080603e145b156122325750612234565b505b60010161215d565b50600192915050565b600073ffffffffffffffffffffffffffffffffffffffff166009848460405161226f9291906132ce565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16146122d05782826040517fe8aed45c00000000000000000000000000000000000000000000000000000000815260040161157792919061365b565b8060098484604051611f559291906132ce565b600081516000036122f657506000919050565b60005b825181101561223c57600083828151811061231657612316613690565b016020015160f81c9050606181108015906123325750607a8111155b1561233d5750612391565b80602d0361236a578115806123555750600184510382145b15612364575060009392505050565b50612391565b8060301115801561237c575060398111155b156123875750612391565b5060009392505050565b6001016122f9565b6060858585856123b28667ffffffffffffffff166123e0565b6040516020016123c69594939291906136bf565b604051602081830303815290604052905095945050505050565b606060006123ed8361249e565b600101905060008167ffffffffffffffff81111561240d5761240d61348e565b6040519080825280601f01601f191660200182016040528015612437576020820181803683370190505b5090508181016020015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a850494508461244157509392505050565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106124e7577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310612513576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061253157662386f26fc10000830492506010015b6305f5e1008310612549576305f5e100830492506008015b612710831061255d57612710830492506004015b6064831061256f576064830492506002015b600a83106120225760010192915050565b6040805160c08101909152600060608083019182526080830181905260a08301528152602081016125af612633565b8152600060209091015290565b6040805160a08101825260608082526020820152908101600081526020016125af612655565b6040805160c08101909152806000815260200160008152602001612619604051806040016040528060608152602001606081525090565b815260606020820181905260408201819052600091015290565b60408051608081018252600091810182815260608201929092529081906125af565b604051806060016040528060608152602001606081526020016126846040518060200160405280606081525090565b905290565b600060a0828403121561269b57600080fd5b50919050565b6000602082840312156126b357600080fd5b813567ffffffffffffffff8111156126ca57600080fd5b6126d684828501612689565b949350505050565b60008083601f8401126126f057600080fd5b50813567ffffffffffffffff81111561270857600080fd5b602083019150836020828501011115610fb257600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610a6657600080fd5b60008060006040848603121561275757600080fd5b833567ffffffffffffffff81111561276e57600080fd5b61277a868287016126de565b909450925050602084013561278e81612720565b809150509250925092565b600080600080604085870312156127af57600080fd5b843567ffffffffffffffff808211156127c757600080fd5b6127d3888389016126de565b909650945060208701359150808211156127ec57600080fd5b506127f9878288016126de565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003811061284457612844612805565b9052565b60005b8381101561286357818101518382015260200161284b565b50506000910152565b60008151808452612884816020860160208601612848565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b858110156128fe5782840389526128ec84835161286c565b988501989350908401906001016128d4565b5091979650505050505050565b604081526000835160a0604084015261292860e084018251612834565b602081015160606101008501526129436101408501826128b6565b9050604082015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2084820301610120850152612981818361286c565b6020878101518051805167ffffffffffffffff90811660608a015290830151811660808901529101511660a0860152604087015190925090506129d060c085018267ffffffffffffffff169052565b50831515602084015290505b9392505050565b60006080828403121561269b57600080fd5b600060208284031215612a0757600080fd5b813567ffffffffffffffff811115612a1e57600080fd5b6126d6848285016129e3565b600060e0828403121561269b57600080fd5b600060208284031215612a4e57600080fd5b813567ffffffffffffffff811115612a6557600080fd5b6126d684828501612a2a565b803567ffffffffffffffff8116811461079e57600080fd5b600060208284031215612a9b57600080fd5b6129dc82612a71565b60008060208385031215612ab757600080fd5b823567ffffffffffffffff811115612ace57600080fd5b612ada858286016126de565b90969095509350505050565b6004811061284457612844612805565b6000815160608452612b0b606085018261286c565b905060208301518482036020860152612b24828261286c565b915050604083015184820360408601528051905060208252612b49602083018261286c565b95945050505050565b60006040808352845160a082850152612b6e60e085018261286c565b90506020808701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808785030160608801528382518086528486019150848160051b870101858501945060005b82811015612c2a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0888303018452855180518a8452612bfe8b85018261286c565b91890151848303858b0152919050612c1681836128b6565b978901979589019593505050600101612bbc565b50968b015196612c3d60808b0189612ae6565b60608c01519750838a82030160a08b0152612c588189612af6565b9750505050505060808701519150612c7c60c086018367ffffffffffffffff169052565b829350612c8c8186018715159052565b5050509392505050565b60006040828403121561269b57600080fd5b600060208284031215612cba57600080fd5b813567ffffffffffffffff811115612cd157600080fd5b6126d684828501612c96565b604081526000612cf0604083018561286c565b8281036020840152612b49818561286c565b604081526000835160078110612d1a57612d1a612805565b60408301526020840151612d316060840182612834565b50604084015160c0608084015280516040610100850152612d5661014085018261286c565b9050602082015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084820301610120850152612d94818361286c565b91505060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808584030160a0860152612dd183836128b6565b925060808701519150808584030160c086015250612def828261286c565b91505060a08501516129d060e085018267ffffffffffffffff169052565b600060c0828403121561269b57600080fd5b600060208284031215612e3157600080fd5b813567ffffffffffffffff811115612e4857600080fd5b6126d684828501612e0d565b600060208284031215612e6657600080fd5b813567ffffffffffffffff811115612e7d57600080fd5b82016101a081850312156129dc57600080fd5b6020815260006129dc602083018461286c565b73ffffffffffffffffffffffffffffffffffffffff841681527fffffffff0000000000000000000000000000000000000000000000000000000083166020820152606060408201526000612b49606083018461286c565b600080600060608486031215612f0f57600080fd5b833567ffffffffffffffff811115612f2657600080fd5b612f32868287016126de565b9094509250612f4690508560208601612c96565b90509250925092565b604081526000612f62604083018561286c565b905082151560208301529392505050565b600060208284031215612f8557600080fd5b5035919050565b60008060008060408587031215612fa257600080fd5b843567ffffffffffffffff80821115612fba57600080fd5b612fc6888389016126de565b90965094506020870135915080821115612fdf57600080fd5b818701915087601f830112612ff357600080fd5b81358181111561300257600080fd5b8860208260061b850101111561301757600080fd5b95989497505060200194505050565b60006020828403121561303857600080fd5b813567ffffffffffffffff81111561304f57600080fd5b820161018081850312156129dc57600080fd5b60008060008060008060008060c0898b03121561307e57600080fd5b883567ffffffffffffffff8082111561309657600080fd5b6130a28c838d016126de565b909a50985060208b01359150808211156130bb57600080fd5b6130c78c838d016126de565b90985096508691506130dc8c60408d01612c96565b95506130ea60808c01612a71565b945060a08b013591508082111561310057600080fd5b5061310d8b828c016126de565b999c989b5096995094979396929594505050565b60008060008060006060868803121561313957600080fd5b853567ffffffffffffffff8082111561315157600080fd5b61315d89838a016126de565b9097509550602088013591508082111561317657600080fd5b50613183888289016126de565b9094509250613196905060408701612a71565b90509295509295909350565b60208101600283106131b6576131b6612805565b91905290565b60008060008060008060006080888a0312156131d757600080fd5b873567ffffffffffffffff808211156131ef57600080fd5b6131fb8b838c016126de565b909950975060208a013591508082111561321457600080fd5b6132208b838c016126de565b909750955085915061323460408b01612a71565b945060608a013591508082111561324a57600080fd5b506132578a828b016126de565b989b979a50959850939692959293505050565b60006060828403121561269b57600080fd5b60006020828403121561328e57600080fd5b813567ffffffffffffffff8111156132a557600080fd5b6126d68482850161326a565b6000602082840312156132c357600080fd5b81356129dc81612720565b8183823760009101908152919050565b600181811c908216806132f257607f821691505b60208210810361269b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261336057600080fd5b830160208101925035905067ffffffffffffffff81111561338057600080fd5b803603821315610fb257600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006133e8838461332b565b604060208501526133fd60608501828461338f565b91505061340d602085018561332b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0858403016040860152611ac483828461338f565b60008251613454818460208701612848565b9190910192915050565b80517fffffffff000000000000000000000000000000000000000000000000000000008116811461079e57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126134ce57600080fd5b815167ffffffffffffffff808211156134e9576134e961348e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561352f5761352f61348e565b8160405283815286602085880101111561354857600080fd5b611ac4846020830160208901612848565b60008060006060848603121561356e57600080fd5b835161357981612720565b92506135876020850161345e565b9150604084015167ffffffffffffffff8111156135a357600080fd5b6135af868287016134bd565b9150509250925092565b6060815260006135cd60608301858761338f565b905067ffffffffffffffff806135e285612a71565b166020840152806135f560208601612a71565b16604084015250949350505050565b6000806040838503121561361757600080fd5b825167ffffffffffffffff81111561362e57600080fd5b61363a858286016134bd565b9250506020830151801515811461365057600080fd5b809150509250929050565b6020815260006126d660208301848661338f565b60006002831061368157613681612805565b5060f89190911b815260010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f72656365697074732f706f7274732f000000000000000000000000000000000081528486600f83013760008582017f2f6368616e6e656c732f00000000000000000000000000000000000000000000600f820152848660198301377f2f73657175656e6365732f0000000000000000000000000000000000000000006019918601918201528351613758816024840160208801612848565b0160240197965050505050505056fea2646970667358221220b960a5a4b5bf9994fba01cc4fb707493307962965adbb04ec45bd0212146e0b264736f6c63430008140033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.