syntax = "proto3";

package mpc.coordinator.v1;

option go_package = "github.com/rwadurian/mpc-system/api/grpc/coordinator/v1;coordinator";

// SessionCoordinator service manages MPC sessions
service SessionCoordinator {
  // Session management
  rpc CreateSession(CreateSessionRequest) returns (CreateSessionResponse);
  rpc JoinSession(JoinSessionRequest) returns (JoinSessionResponse);
  rpc GetSessionStatus(GetSessionStatusRequest) returns (GetSessionStatusResponse);
  rpc MarkPartyReady(MarkPartyReadyRequest) returns (MarkPartyReadyResponse);
  rpc StartSession(StartSessionRequest) returns (StartSessionResponse);
  rpc ReportCompletion(ReportCompletionRequest) returns (ReportCompletionResponse);
  rpc CloseSession(CloseSessionRequest) returns (CloseSessionResponse);

  // Delegate party share submission (delegate party submits user's share after keygen)
  rpc SubmitDelegateShare(SubmitDelegateShareRequest) returns (SubmitDelegateShareResponse);
}

// CreateSessionRequest creates a new MPC session
message CreateSessionRequest {
  string session_type = 1;               // "keygen", "sign", or "co_managed_keygen"
  int32 threshold_n = 2;                 // Total number of parties
  int32 threshold_t = 3;                 // Minimum required parties
  repeated ParticipantInfo participants = 4;  // Optional: if empty, coordinator selects automatically
  bytes message_hash = 5;                // Required for sign sessions
  int64 expires_in_seconds = 6;          // Session expiration time
  PartyComposition party_composition = 7; // Optional: party composition requirements for auto-selection
  // For sign sessions with delegate party: user must provide their encrypted share
  DelegateUserShare delegate_user_share = 8;
  // For sign sessions: which keygen session's shares to use
  string keygen_session_id = 9;
  // For co_managed_keygen sessions: wallet name and invite code
  string wallet_name = 10;               // Wallet name (for co_managed_keygen)
  string invite_code = 11;               // Invite code for participants to join (for co_managed_keygen)
}

// DelegateUserShare contains user's share for delegate party to use in signing
message DelegateUserShare {
  string delegate_party_id = 1;          // The delegate party that will use this share
  bytes encrypted_share = 2;             // User's encrypted share (same as received from keygen)
  int32 party_index = 3;                 // Party index for this share
}

// PartyComposition specifies requirements for automatic party selection
message PartyComposition {
  int32 persistent_count = 1;            // Number of persistent parties (store shares in DB)
  int32 delegate_count = 2;              // Number of delegate parties (return shares to user)
  int32 temporary_count = 3;             // Number of temporary parties
}

// ParticipantInfo contains information about a participant
message ParticipantInfo {
  string party_id = 1;
  DeviceInfo device_info = 2;
  int32 party_index = 3;                 // Original party index from keygen (required for signing)
}

// DeviceInfo contains device information
message DeviceInfo {
  string device_type = 1;                // android, ios, pc, server, recovery
  string device_id = 2;
  string platform = 3;
  string app_version = 4;
}

// CreateSessionResponse contains the created session info
message CreateSessionResponse {
  string session_id = 1;
  map<string, string> join_tokens = 2;   // party_id -> join_token
  int64 expires_at = 3;                  // Unix timestamp milliseconds
  repeated string selected_parties = 4;  // List of selected party IDs
  string delegate_party_id = 5;          // The delegate party ID (if any)
}

// JoinSessionRequest allows a participant to join a session
message JoinSessionRequest {
  string session_id = 1;
  string party_id = 2;
  string join_token = 3;
  DeviceInfo device_info = 4;
}

// JoinSessionResponse contains session information for the joining party
message JoinSessionResponse {
  bool success = 1;
  SessionInfo session_info = 2;
  repeated PartyInfo other_parties = 3;
  int32 party_index = 4;                   // This party's assigned index
}

// SessionInfo contains session information
message SessionInfo {
  string session_id = 1;
  string session_type = 2;
  int32 threshold_n = 3;
  int32 threshold_t = 4;
  bytes message_hash = 5;
  string status = 6;
  // For sign sessions: which keygen session's shares to use
  string keygen_session_id = 7;
  // For co_managed_keygen sessions
  string wallet_name = 8;                // Wallet name (for co_managed_keygen)
  string invite_code = 9;                // Invite code (for co_managed_keygen)
}

// PartyInfo contains party information
message PartyInfo {
  string party_id = 1;
  int32 party_index = 2;
  DeviceInfo device_info = 3;
}

// GetSessionStatusRequest queries session status
message GetSessionStatusRequest {
  string session_id = 1;
}

// GetSessionStatusResponse contains session status
message GetSessionStatusResponse {
  string status = 1;
  int32 completed_parties = 2;
  int32 total_parties = 3;
  string session_type = 4;               // "keygen" or "sign"
  bytes public_key = 5;                  // For completed keygen
  bytes signature = 6;                   // For completed sign
  // has_delegate indicates whether this keygen session has a delegate party
  // Only meaningful for keygen sessions. Always false for sign sessions.
  bool has_delegate = 7;
  // Delegate share info (returned when keygen session completed and delegate party submitted share)
  // Only populated if session_type="keygen" AND has_delegate=true AND session is completed
  DelegateShareInfo delegate_share = 8;
  // participants contains detailed participant information including party_index
  // Used by service-party-app for co_managed_keygen sessions
  repeated ParticipantStatus participants = 9;
  // threshold_n and threshold_t - actual threshold values from session config
  // Used for co_managed_keygen sessions where total_parties may differ from threshold_n during joining
  int32 threshold_n = 10;                // Total number of parties required (e.g., 3 in 2-of-3)
  int32 threshold_t = 11;                // Minimum parties needed to sign (e.g., 2 in 2-of-3)
}

// ParticipantStatus contains participant status information
message ParticipantStatus {
  string party_id = 1;
  int32 party_index = 2;
  string status = 3;                     // pending, joined, ready, completed
}

// DelegateShareInfo contains the delegate party's share for user
message DelegateShareInfo {
  bytes encrypted_share = 1;             // Encrypted share for user
  int32 party_index = 2;                 // Party's index in the session
  string party_id = 3;                   // Delegate party ID
}

// ReportCompletionRequest reports that a participant has completed
message ReportCompletionRequest {
  string session_id = 1;
  string party_id = 2;
  bytes public_key = 3;                  // For keygen completion
  bytes signature = 4;                   // For sign completion
}

// ReportCompletionResponse contains the result of completion report
message ReportCompletionResponse {
  bool success = 1;
  bool all_completed = 2;
}

// CloseSessionRequest closes a session
message CloseSessionRequest {
  string session_id = 1;
}

// CloseSessionResponse contains the result of session closure
message CloseSessionResponse {
  bool success = 1;
}

// MarkPartyReadyRequest marks a party as ready to start the protocol
message MarkPartyReadyRequest {
  string session_id = 1;
  string party_id = 2;
}

// MarkPartyReadyResponse contains the result of marking party ready
message MarkPartyReadyResponse {
  bool success = 1;
  bool all_ready = 2;                    // True if all parties are ready
  int32 ready_count = 3;
  int32 total_parties = 4;
}

// StartSessionRequest starts the MPC protocol execution
message StartSessionRequest {
  string session_id = 1;
}

// StartSessionResponse contains the result of starting the session
message StartSessionResponse {
  bool success = 1;
  string status = 2;                     // New session status
}

// SubmitDelegateShareRequest submits user's share from delegate party
message SubmitDelegateShareRequest {
  string session_id = 1;
  string party_id = 2;
  bytes encrypted_share = 3;             // Encrypted share for user
  bytes public_key = 4;                  // Public key from keygen
  int32 party_index = 5;                 // Party's index in the session
}

// SubmitDelegateShareResponse contains result of share submission
message SubmitDelegateShareResponse {
  bool success = 1;
}
