syntax = "proto3";
package ibc.core.channel.v1;

option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types";

import "gogoproto/gogo.proto";
import "ibc/core/client/v1/client.proto";

// Msg defines the ibc/channel Msg service.
service Msg {
  // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit.
  rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse);

  // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry.
  rpc ChannelOpenTry(MsgChannelOpenTry) returns (MsgChannelOpenTryResponse);

  // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck.
  rpc ChannelOpenAck(MsgChannelOpenAck) returns (MsgChannelOpenAckResponse);

  // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm.
  rpc ChannelOpenConfirm(MsgChannelOpenConfirm) returns (MsgChannelOpenConfirmResponse);

  // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit.
  rpc ChannelCloseInit(MsgChannelCloseInit) returns (MsgChannelCloseInitResponse);

  // ChannelCloseConfirm defines a rpc handler method for MsgChannelCloseConfirm.
  rpc ChannelCloseConfirm(MsgChannelCloseConfirm) returns (MsgChannelCloseConfirmResponse);

  // RecvPacket defines a rpc handler method for MsgRecvPacket.
  rpc RecvPacket(MsgRecvPacket) returns (MsgRecvPacketResponse);

  // Timeout defines a rpc handler method for MsgTimeout.
  rpc Timeout(MsgTimeout) returns (MsgTimeoutResponse);

  // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose.
  rpc TimeoutOnClose(MsgTimeoutOnClose) returns (MsgTimeoutOnCloseResponse);

  // Acknowledgement defines a rpc handler method for MsgAcknowledgement.
  rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse);
}

// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It
// is called by a relayer on Chain A.
message MsgChannelOpenInit {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string  port_id    = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  string  channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
  Channel channel    = 3 [(gogoproto.nullable) = false];
  string  signer     = 4;
}

// MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type.
message MsgChannelOpenInitResponse {}

// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel
// on Chain B.
message MsgChannelOpenTry {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string  port_id                        = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  string  desired_channel_id             = 2 [(gogoproto.moretags) = "yaml:\"desired_channel_id\""];
  string  counterparty_chosen_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_channel_id\""];
  Channel channel                        = 4 [(gogoproto.nullable) = false];
  string  counterparty_version           = 5 [(gogoproto.moretags) = "yaml:\"counterparty_version\""];
  bytes   proof_init                     = 6 [(gogoproto.moretags) = "yaml:\"proof_init\""];
  ibc.core.client.v1.Height proof_height = 7
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  string signer = 8;
}

// MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type.
message MsgChannelOpenTryResponse {}

// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge
// the change of channel state to TRYOPEN on Chain B.
message MsgChannelOpenAck {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string                    port_id                 = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  string                    channel_id              = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
  string                    counterparty_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_channel_id\""];
  string                    counterparty_version    = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""];
  bytes                     proof_try               = 5 [(gogoproto.moretags) = "yaml:\"proof_try\""];
  ibc.core.client.v1.Height proof_height            = 6
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  string signer = 7;
}

// MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type.
message MsgChannelOpenAckResponse {}

// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to
// acknowledge the change of channel state to OPEN on Chain A.
message MsgChannelOpenConfirm {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string                    port_id      = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  string                    channel_id   = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
  bytes                     proof_ack    = 3 [(gogoproto.moretags) = "yaml:\"proof_ack\""];
  ibc.core.client.v1.Height proof_height = 4
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  string signer = 5;
}

// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response type.
message MsgChannelOpenConfirmResponse {}

// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A
// to close a channel with Chain B.
message MsgChannelCloseInit {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string port_id    = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
  string signer     = 3;
}

// MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type.
message MsgChannelCloseInitResponse {}

// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B
// to acknowledge the change of channel state to CLOSED on Chain A.
message MsgChannelCloseConfirm {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string                    port_id      = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  string                    channel_id   = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
  bytes                     proof_init   = 3 [(gogoproto.moretags) = "yaml:\"proof_init\""];
  ibc.core.client.v1.Height proof_height = 4
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  string signer = 5;
}

// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response type.
message MsgChannelCloseConfirmResponse {}

// MsgRecvPacket receives incoming IBC packet
message MsgRecvPacket {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  Packet                    packet       = 1 [(gogoproto.nullable) = false];
  bytes                     proof        = 2;
  ibc.core.client.v1.Height proof_height = 3
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  string signer = 4;
}

// MsgRecvPacketResponse defines the Msg/RecvPacket response type.
message MsgRecvPacketResponse {}

// MsgTimeout receives timed-out packet
message MsgTimeout {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  Packet                    packet       = 1 [(gogoproto.nullable) = false];
  bytes                     proof        = 2;
  ibc.core.client.v1.Height proof_height = 3
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""];
  string signer             = 5;
}

// MsgTimeoutResponse defines the Msg/Timeout response type.
message MsgTimeoutResponse {}

// MsgTimeoutOnClose timed-out packet upon counterparty channel closure.
message MsgTimeoutOnClose {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  Packet                    packet       = 1 [(gogoproto.nullable) = false];
  bytes                     proof        = 2;
  bytes                     proof_close  = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""];
  ibc.core.client.v1.Height proof_height = 4
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""];
  string signer             = 6;
}

// MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type.
message MsgTimeoutOnCloseResponse {}

// MsgAcknowledgement receives incoming IBC acknowledgement
message MsgAcknowledgement {
  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  Packet                    packet          = 1 [(gogoproto.nullable) = false];
  bytes                     acknowledgement = 2;
  bytes                     proof           = 3;
  ibc.core.client.v1.Height proof_height    = 4
      [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
  string signer = 5;
}

// MsgAcknowledgementResponse defines the Msg/Acknowledgement response type.
message MsgAcknowledgementResponse {}

// Channel defines pipeline for exactly-once packet delivery between specific
// modules on separate blockchains, which has at least one end capable of
// sending packets and one end capable of receiving packets.
message Channel {
  option (gogoproto.goproto_getters) = false;

  // current state of the channel end
  State state = 1;
  // whether the channel is ordered or unordered
  Order ordering = 2;
  // counterparty channel end
  Counterparty counterparty = 3 [(gogoproto.nullable) = false];
  // list of connection identifiers, in order, along which packets sent on
  // this channel will travel
  repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""];
  // opaque channel version, which is agreed upon during the handshake
  string version = 5;
}

// IdentifiedChannel defines a channel with additional port and channel
// identifier fields.
message IdentifiedChannel {
  option (gogoproto.goproto_getters) = false;

  // current state of the channel end
  State state = 1;
  // whether the channel is ordered or unordered
  Order ordering = 2;
  // counterparty channel end
  Counterparty counterparty = 3 [(gogoproto.nullable) = false];
  // list of connection identifiers, in order, along which packets sent on
  // this channel will travel
  repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""];
  // opaque channel version, which is agreed upon during the handshake
  string version = 5;
  // port identifier
  string port_id = 6;
  // channel identifier
  string channel_id = 7;
}

// State defines if a channel is in one of the following states:
// CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED.
enum State {
  option (gogoproto.goproto_enum_prefix) = false;

  // Default State
  STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"];
  // A channel has just started the opening handshake.
  STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"];
  // A channel has acknowledged the handshake step on the counterparty chain.
  STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"];
  // A channel has completed the handshake. Open channels are
  // ready to send and receive packets.
  STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"];
  // A channel has been closed and can no longer be used to send or receive
  // packets.
  STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"];
}

// Order defines if a channel is ORDERED or UNORDERED
enum Order {
  option (gogoproto.goproto_enum_prefix) = false;

  // zero-value for channel ordering
  ORDER_NONE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "NONE"];
  // packets can be delivered in any order, which may differ from the order in
  // which they were sent.
  ORDER_UNORDERED = 1 [(gogoproto.enumvalue_customname) = "UNORDERED"];
  // packets are delivered exactly in the order which they were sent
  ORDER_ORDERED = 2 [(gogoproto.enumvalue_customname) = "ORDERED"];
}

// Counterparty defines a channel end counterparty
message Counterparty {
  option (gogoproto.goproto_getters) = false;

  // port on the counterparty chain which owns the other end of the channel.
  string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  // channel end on the counterparty chain
  string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
}

// Packet defines a type that carries data across different chains through IBC
message Packet {
  option (gogoproto.goproto_getters) = false;

  // number 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.
  uint64 sequence = 1;
  // identifies the port on the sending chain.
  string source_port = 2 [(gogoproto.moretags) = "yaml:\"source_port\""];
  // identifies the channel end on the sending chain.
  string source_channel = 3 [(gogoproto.moretags) = "yaml:\"source_channel\""];
  // identifies the port on the receiving chain.
  string destination_port = 4 [(gogoproto.moretags) = "yaml:\"destination_port\""];
  // identifies the channel end on the receiving chain.
  string destination_channel = 5 [(gogoproto.moretags) = "yaml:\"destination_channel\""];
  // actual opaque bytes transferred directly to the application module
  bytes data = 6;
  // block height after which the packet times out
  ibc.core.client.v1.Height timeout_height = 7
      [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false];
  // block timestamp (in nanoseconds) after which the packet times out
  uint64 timeout_timestamp = 8 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""];
}

// PacketAckCommitment defines the genesis type necessary to retrieve and store
// acknowlegements.
message PacketAckCommitment {
  option (gogoproto.goproto_getters) = false;

  // channel port identifier.
  string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
  // channel unique identifier.
  string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
  // packet sequence.
  uint64 sequence = 3;
  // packet commitment hash.
  bytes hash = 4;
}

// Acknowledgement is the recommended acknowledgement format to be used by
// app-specific protocols.
// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental
// conflicts with other protobuf message formats used for acknowledgements.
// The first byte of any message with this format will be the non-ASCII values
// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS:
// https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#acknowledgement-envelope
message Acknowledgement {
  // response contains either a result or an error and must be non-empty
  oneof response {
    bytes  result = 21;
    string error  = 22;
  }
}