syntax = "proto3";

package alloy.mesh.v1;

import "google/api/annotations.proto";

option go_package = "github.com/alloybuilder/context/alloy/mesh/v1;meshv1";
option java_multiple_files = true;
option java_outer_classname = "MpcWalletProto";
option java_package = "build.alloy.mesh.v1";

// The MpcWalletService provides gRPC endpoints for M0 mock DKG, signing, and resumability.
service MpcWalletService {
  // Initiates a new Distributed Key Generation (DKG) session across mock 3-of-5 nodes.
  rpc InitiateDkg(InitiateDkgRequest) returns (InitiateDkgResponse) {
    option (google.api.http) = {
      post: "/v1/dkg/initiate"
      body: "*"
    };
  }

  // Executes a round of polynomial commitment / share exchange during DKG.
  rpc ExchangeDkgShares(DkgShareExchangeRequest) returns (DkgShareExchangeResponse) {
    option (google.api.http) = {
      post: "/v1/dkg/shares"
      body: "*"
    };
  }

  // Initiates a threshold signature ceremony for a transaction intent.
  rpc InitiateSigning(InitiateSigningRequest) returns (InitiateSigningResponse) {
    option (google.api.http) = {
      post: "/v1/signing/initiate"
      body: "*"
    };
  }

  // Submits partial signature shares to reconstruct the final signature.
  rpc SubmitSignatureShare(SignatureShareRequest) returns (SignatureShareResponse) {
    option (google.api.http) = {
      post: "/v1/signing/share"
      body: "*"
    };
  }

  // Resumes a previously paused or escalated session using a checkpoint token.
  rpc ResumeSession(ResumeSessionRequest) returns (ResumeSessionResponse) {
    option (google.api.http) = {
      post: "/v1/sessions/resume"
      body: "*"
    };
  }
}

enum ApprovalMode {
  APPROVAL_MODE_UNSPECIFIED = 0;
  DIRECT_ALLOWED = 1;
  HUMAN_REQUIRED = 2;
}

enum ReceiptState {
  RECEIPT_STATE_UNSPECIFIED = 0;
  RECEIPT_STATE_ACCEPTED = 1;
  RECEIPT_STATE_DENIED = 2;
  RECEIPT_STATE_PENDING_HUMAN_APPROVAL = 3;
  RECEIPT_STATE_RESUMED = 4;
  RECEIPT_STATE_EXPIRED = 5;
  RECEIPT_STATE_REPLAY_REJECTED = 6;
  RECEIPT_STATE_REVOKED = 7;
  RECEIPT_STATE_BACKEND_COMPLETED = 8;
  RECEIPT_STATE_BACKEND_FAILED = 9;
  RECEIPT_STATE_UNSUPPORTED_CLIENT_CONTRACT_VERSION = 10;
}

enum KeystoreType {
  KEYSTORE_TYPE_UNSPECIFIED = 0;
  KEYSTORE_TYPE_MOCK_THRESHOLD = 1;
  KEYSTORE_TYPE_MULTISIG_EVM_SAFE = 2;
  KEYSTORE_TYPE_MPC_SEPIOR = 3;
  KEYSTORE_TYPE_MPC_FROST = 4;
  KEYSTORE_TYPE_HSM_PKCS11 = 5;
}

enum MockDirective {
  MOCK_DIRECTIVE_UNSPECIFIED = 0;
  MOCK_DIRECTIVE_FORCE_DENIED = 1;
  MOCK_DIRECTIVE_FORCE_REVOKED = 2;
  MOCK_DIRECTIVE_FORCE_EXPIRED = 3;
  MOCK_DIRECTIVE_FORCE_BACKEND_FAILED = 4;
}

message ClientVersionInfo {
  string client_name = 1;
  string client_version = 2;
  string contract_version = 3;
}

message OrchestrationContext {
  // Opaque payload from WalletKit/PolicyKit (e.g., serialized policy approval token or intent ID).
  bytes payload = 1;
  // W3C traceparent header string for WORM audit traceability.
  string traceparent = 2;
  // Correlation ID across the entire transaction lifecycle.
  string correlation_id = 3;
  // Client/runtime identity used for contract version traceability.
  ClientVersionInfo client = 4;
}

message ThresholdDerivation {
  // BIP-32/44 derivation path (e.g., "m/44'/60'/0'/0/0").
  string derivation_path = 1;
  // Curve type ("secp256k1" or "ed25519").
  string curve = 2;
  // Optional chain ID or network identifier.
  string network_id = 3;
}

message DiagnosticReceipt {
  string receipt_id = 1;
  ReceiptState state = 2;
  ApprovalMode approval_mode = 3;
  string reason_code = 4;
  string message = 5;
  string correlation_id = 6;
  string session_id = 7;
  string contract_version = 8;
  string client_name = 9;
  string client_version = 10;
  int64 epoch = 11;
  string checkpoint_id = 12;
  bool resumable = 13;
  KeystoreType keystore_type = 14;
  string backend_route = 15;
}

message SessionCheckpoint {
  string checkpoint_id = 1;
  int64 epoch = 2;
  int64 created_at_epoch_ms = 3;
  ReceiptState state = 4;
  string resume_token = 5;
}

message InitiateDkgRequest {
  string session_id = 1;
  int32 threshold = 2;
  int32 total_nodes = 3;
  ThresholdDerivation derivation = 4;
  OrchestrationContext context = 5;
}

message InitiateDkgResponse {
  string session_id = 1;
  ReceiptState state = 2;
  int64 epoch = 3;
  DiagnosticReceipt receipt = 4;
  SessionCheckpoint checkpoint = 5;
}

message DkgShareExchangeRequest {
  string session_id = 1;
  int32 sender_node_id = 2;
  int32 recipient_node_id = 3;
  // In M0 mock mode this can carry the raw mock share bytes.
  bytes encrypted_share = 4;
  // Mock Feldman VSS commitments.
  repeated bytes commitments = 5;
  OrchestrationContext context = 6;
}

message DkgShareExchangeResponse {
  string session_id = 1;
  bool verified = 2;
  string error_message = 3;
  DiagnosticReceipt receipt = 4;
  SessionCheckpoint checkpoint = 5;
}

message InitiateSigningRequest {
  string transaction_intent_id = 1;
  string wallet_id = 2;
  ThresholdDerivation derivation = 3;
  bytes message_hash = 4;
  // Opaque policy evidence from PolicyKit. M0 does not interpret business semantics from this payload.
  bytes policy_approval_token = 5;
  bytes human_approval_witness = 6;
  ApprovalMode approval_mode = 7;
  OrchestrationContext context = 8;
  KeystoreType keystore_type = 9;
  // Explicit M0-only override for deterministic local testing. Must not carry business-policy semantics.
  MockDirective mock_directive = 10;
}

message InitiateSigningResponse {
  string signing_session_id = 1;
  ReceiptState state = 2;
  int64 epoch = 3;
  DiagnosticReceipt receipt = 4;
  SessionCheckpoint checkpoint = 5;
}

message SignatureShareRequest {
  string signing_session_id = 1;
  int32 node_id = 2;
  bytes partial_signature = 3;
  bytes ephemeral_public_key = 4;
  OrchestrationContext context = 5;
}

message SignatureShareResponse {
  string signing_session_id = 1;
  bool is_complete = 2;
  bytes full_signature = 3;
  bytes recovery_id = 4;
  DiagnosticReceipt receipt = 5;
  SessionCheckpoint checkpoint = 6;
}

message ResumeSessionRequest {
  string session_id = 1;
  string resume_token = 2;
  OrchestrationContext context = 3;
  bytes human_approval_witness = 4;
}

message ResumeSessionResponse {
  string session_id = 1;
  ReceiptState state = 2;
  int64 epoch = 3;
  DiagnosticReceipt receipt = 4;
  SessionCheckpoint checkpoint = 5;
}
