syntax = "proto3";
package band.bandtss.v1beta1;

import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";

option go_package            = "github.com/bandprotocol/chain/v3/x/bandtss/types";
option (gogoproto.equal_all) = true;

// Member maintains member information for monitoring their liveness activity.
message Member {
  option (gogoproto.equal) = true;

  // address is the address of the member.
  string address = 1;
  // group_id is the group ID that the member belongs to.
  uint64 group_id = 2
      [(gogoproto.customname) = "GroupID", (gogoproto.casttype) = "github.com/bandprotocol/chain/v3/pkg/tss.GroupID"];
  // is_active is a flag to indicate whether a member is active or not.
  bool is_active = 3;
  // since is a block timestamp when a member status is changed (from active to inactive or vice versa).
  google.protobuf.Timestamp since = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

// CurrentGroup is a bandtss current group information.
message CurrentGroup {
  // group_id is the ID of the current group.
  uint64 group_id = 1
      [(gogoproto.customname) = "GroupID", (gogoproto.casttype) = "github.com/bandprotocol/chain/v3/pkg/tss.GroupID"];
  // active_time is the timestamp at which the group becomes the current group of the module.
  google.protobuf.Timestamp active_time = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

// Signing is a bandtss signing information.
message Signing {
  option (gogoproto.equal) = true;

  // id is the unique identifier of the bandtss signing.
  uint64 id = 1 [(gogoproto.customname) = "ID", (gogoproto.casttype) = "SigningID"];
  // fee_per_signer is the tokens that will be paid per signer for this bandtss signing.
  repeated cosmos.base.v1beta1.Coin fee_per_signer = 2
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
  // requester is the address who pays the bandtss signing.
  string requester = 3;
  // current_group_signing_id is a tss signing ID of a current group.
  uint64 current_group_signing_id = 4 [
    (gogoproto.customname) = "CurrentGroupSigningID",
    (gogoproto.casttype)   = "github.com/bandprotocol/chain/v3/pkg/tss.SigningID"
  ];
  // incoming_group_signing_id is a tss signing ID of an incoming group, if any.
  uint64 incoming_group_signing_id = 5 [
    (gogoproto.customname) = "IncomingGroupSigningID",
    (gogoproto.casttype)   = "github.com/bandprotocol/chain/v3/pkg/tss.SigningID"
  ];
}

// GroupTransition defines the group transition information of the current group and incoming group.
message GroupTransition {
  // signing_id is a tss signing ID of group transition signing request.
  uint64 signing_id = 1 [
    (gogoproto.customname) = "SigningID",
    (gogoproto.casttype)   = "github.com/bandprotocol/chain/v3/pkg/tss.SigningID"
  ];
  // current_group_id is the ID of the group that will be replaced.
  uint64 current_group_id = 2 [
    (gogoproto.customname) = "CurrentGroupID",
    (gogoproto.casttype)   = "github.com/bandprotocol/chain/v3/pkg/tss.GroupID"
  ];
  // current_group_pub_key is the public key pair that used for sign & verify transition group msg.
  bytes current_group_pub_key = 3 [(gogoproto.casttype) = "github.com/bandprotocol/chain/v3/pkg/tss.Point"];
  // new_group_id is the ID of the new group that be a new key candidate.
  uint64 incoming_group_id = 4 [
    (gogoproto.customname) = "IncomingGroupID",
    (gogoproto.casttype)   = "github.com/bandprotocol/chain/v3/pkg/tss.GroupID"
  ];
  // incoming_group_pub_key is the public key of the group that will be the next key of this group
  bytes incoming_group_pub_key = 5 [(gogoproto.casttype) = "github.com/bandprotocol/chain/v3/pkg/tss.Point"];
  // status is an enumeration of the possible statuses of a group transition process.
  TransitionStatus status = 6;
  // exec_time is the time when the transition will be executed.
  google.protobuf.Timestamp exec_time = 7 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
  // is_force_transition is a flag to indicate whether the current group signs the transition message
  // before the transition is executed or not.
  bool is_force_transition = 8;
}

// TransitionStatus is an enumeration of the possible statuses of a group transition process.
enum TransitionStatus {
  option (gogoproto.goproto_enum_prefix) = false;

  // TRANSITION_STATUS_UNSPECIFIED is the status of a group transition that has not been specified.
  TRANSITION_STATUS_UNSPECIFIED = 0;
  // TRANSITION_STATUS_CREATING_GROUP is the status of a group transition that a new group
  // is being created.
  TRANSITION_STATUS_CREATING_GROUP = 1;
  // TRANSITION_STATUS_WAITING_SIGN is the status of a group transition that waits members in
  // a current group to sign the transition message.
  TRANSITION_STATUS_WAITING_SIGN = 2;
  // TRANSITION_STATUS_WAITING_EXECUTION is the status of a group transition that
  // a transition process is completed, either from a forceTransition or having a current-group
  // signature on a transition message, but waits for the execution time.
  TRANSITION_STATUS_WAITING_EXECUTION = 3;
}

// GroupTransitionSignatureOrder defines a general signature order for group transition.
message GroupTransitionSignatureOrder {
  option (cosmos_proto.implements_interface) = "Content";

  // pub_key is the public key of new group that the current group needs to be signed.
  bytes pub_key = 1 [(gogoproto.casttype) = "github.com/cometbft/cometbft/libs/bytes.HexBytes"];
  // transition_time is the timestamp at which the transition is executed and the public key is active.
  google.protobuf.Timestamp transition_time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
}
