syntax = "proto3";

import "google/protobuf/empty.proto";
import "sdk/model/model.proto";
import "sdk/transaction/transaction.proto";
import "sdk/rbac.proto";
import "sdk/document.proto";

package m10.sdk;

/// Service for creating transactions.
service M10TxService {
  /// Create a single transaction.
  rpc CreateTransaction(RequestEnvelope)
      returns (m10.sdk.transaction.TransactionResponse) {}
  /// Create multiple transactions.
  rpc BulkCreateTransactions(BulkTransactions)
      returns (BulkTransactionsResponse);
}

/// A batch of transactions to be created.
message BulkTransactions {
/// List of transaction requests.
  repeated RequestEnvelope transactions = 1; 
}

/// Responses for a bulk transaction creation request.
message BulkTransactionsResponse {
/// List of transaction responses.
  repeated m10.sdk.transaction.TransactionResponse responses = 1; 
}

/// Service for querying the ledger.
service M10QueryService {
  // Transfers
  /// Retrieves a specific transfer by ID.
  rpc GetTransfer(RequestEnvelope)
      returns (m10.sdk.transaction.FinalizedTransfer) {}
  /// Retrieves a list of transfers.
  rpc ListTransfers(RequestEnvelope)
      returns (m10.sdk.transaction.FinalizedTransfers) {}
  /// Observes transfers.
  /// Param: RequestEnvelope should contain ObserveAccountsRequest
  rpc ObserveTransfers(RequestEnvelope) returns (stream FinalizedTransactions);

  // Accounts
  /// Retrieves an indexed account by ID.
  rpc GetIndexedAccount(RequestEnvelope)
      returns (m10.sdk.transaction.IndexedAccount) {}
  /// Retrieve account metadata.
  rpc GetAccountMetadata(RequestEnvelope) returns (m10.sdk.model.AccountMetadata);
  /// Retrieve account information.
  rpc GetAccountInfo(RequestEnvelope) returns (m10.sdk.model.AccountInfo);
  /// Lists AccountMetadata.
  rpc ListAccountMetadata(RequestEnvelope) returns (m10.sdk.ListAccountMetadataResponse);
  /// Observes account changes.
  /// Param: RequestEnvelope should contain ObserveAccountsRequest
  rpc ObserveAccounts(RequestEnvelope) returns (stream FinalizedTransactions);


  /// Actions
  /// Retrieves a specific action by ID.
  rpc GetAction(RequestEnvelope) returns (m10.sdk.transaction.Action) {}
  /// Retrieves a list of actions.
  rpc ListActions(RequestEnvelope) returns (m10.sdk.transaction.Actions) {}
  /// Observe actions.
  /// Param: RequestEnvelope should contain ObserveActionsRequest
  rpc ObserveActions(RequestEnvelope) returns (stream FinalizedTransactions) {}

  /// Retrieves chain information.
  rpc GetChainInfo(google.protobuf.Empty) returns (ChainInfo) {}

  /// Transactions
  /// Request a specific transaction by ID
  /// Param: RequestEnvelope should contain GetTransactionRequest
  rpc GetTransaction(RequestEnvelope) returns (FinalizedTransaction) {}
  /// List transactions.
  // Param: RequestEnvelope should contain ListTransactionsRequest
  rpc ListTransactions(RequestEnvelope) returns (FinalizedTransactions) {}
  /// Group transactions.
  /// ID Param: RequestEnvelope should contain GroupTransactionsRequest
  rpc GroupTransactions(RequestEnvelope)
      returns (GroupedFinalizedTransactions) {}

  /// AccountSet
  /// Retrieve an AccountSet.
  rpc GetAccountSet(RequestEnvelope) returns (m10.sdk.model.AccountSet);
  /// List AccountSets.
  rpc ListAccountSets(RequestEnvelope)
      returns (m10.sdk.ListAccountSetsResponse);

  /// RoleBinding
  /// Retrieve role binding.
  rpc GetRoleBinding(RequestEnvelope) returns (m10.sdk.RoleBinding);
  /// List role bindings.
  rpc ListRoleBindings(RequestEnvelope)
      returns (m10.sdk.ListRoleBindingsResponse);

  // RoleBinding
   /// Retrieve a role.
   rpc GetRole(RequestEnvelope) returns (m10.sdk.Role);
  /// List roles.
  rpc ListRoles(RequestEnvelope) returns (m10.sdk.ListRolesResponse);

  // Resources
  // Request to observe all resources processed by the ledger
  /// Observes resources.
  /// Param: RequestEnvelope should contain ObserveResourcesRequest
  rpc ObserveResources(RequestEnvelope) returns (stream FinalizedTransactions);

  // Metrics
  // Request to observe metrics data processed by the ledger
  /// Observes metrics.
  /// Param: RequestEnvelope should contain ObserveAccountsRequest
  rpc ObserveMetrics(RequestEnvelope) returns (stream TransactionMetrics);

  // Banks
  /// Lists banks.
  /// Param: RequestEnvelope should contain ListBanksRequest
  rpc  ListBanks(RequestEnvelope) returns (m10.sdk.ListBanksResponse);
  /// Retrieves a bank.
  /// Param: RequestEnvelope should contain Bank
  rpc  GetBank(RequestEnvelope) returns (m10.sdk.model.Bank);

  // Offline
  /// Retrieves an offline key.
  rpc GetOfflineKey(google.protobuf.Empty) returns (OfflineKey);
}

// Wraps a payload with a signature for authentication and authorization.
message RequestEnvelope {
  /// Payload data.
  bytes payload = 2; 
  /// Signature for the payload.
  m10.sdk.transaction.Signature signature = 3;
}

// A page of results for paginated queries.
message Page {
  /// Limit of results per page.
  uint32 limit = 1; 
  /// Last ID from previous page.
  bytes last_id = 2; 
}

// Retrieve a specific AccountSet.
message GetAccountSetRequest { 
  /// ID of the AccountSet.
  bytes id = 1;  
}

// ListAccountSetsRequest is the request message for listing account sets.
message ListAccountSetsRequest {
  oneof filter {
    /// Filter by owner.
    bytes owner = 1;  
    /// Filter by name.
    string name = 2; 
  }
  /// Pagination options.
  Page page = 4;  
}


// The response message for listing account sets.
message ListAccountSetsResponse {
  /// List of account sets.
  repeated m10.sdk.model.AccountSet account_sets = 1;  
  /// Request for next page of results.
  ListAccountSetsRequest next_request = 2; 
}

// The request message for listing account metadata.
message ListAccountMetadataRequest {
  oneof filter {
    /// Filter by owner.
    bytes owner = 1; 
    /// Filter by name.
    string name = 2; 
    /// Filter by public name.
    string public_name = 3;
    /// Filter by ISIN.
    string isin = 5;
    /// Filter by DTI.
    string dti = 6;
    /// Filter by Issuer Bank ID.
    string issuer_bank_id = 7;
  }
  /// Pagination options.
  Page page = 4;
}

// The response message for listing account metadata.
message ListAccountMetadataResponse {
  /// List of account metadata.
  repeated m10.sdk.model.AccountMetadata accounts = 1; 
  /// Request for the next page.
  ListAccountMetadataRequest next_request = 2; 
}

// The request message for retrieving a specific role binding.
message GetRoleBindingRequest { 
  /// ID of the role binding.
  bytes id = 1; 
}

// The request message for listing role bindings.
message ListRoleBindingsRequest {
  oneof filter { 
    /// Filter by name.
    string name = 1; 
    /// Filter by subject (public key).
    bytes subject = 2;
    /// Filter by description.
    string description = 3;
    /// Filter by labels.
    MapWrapper labels = 4;
  }
  /// Pagination options.
  Page page = 5;
}

// The response message for listing role bindings.
message ListRoleBindingsResponse {
  /// List of role bindings.
  repeated m10.sdk.RoleBinding role_bindings = 1;  
  /// Request for next page of results.
  ListRoleBindingsRequest next_request = 2; 
}

// The request message for retrieving a specific role.
message GetRoleRequest { 
  /// ID of the role.
  bytes id = 1; 
}

// The request message for listing roles.
message ListRolesRequest {
  oneof filter { 
    /// Filter by name.
    string name = 1; 
    /// Filter by instance id (bytes).
    bytes instance_id = 2;
    /// Filter by description.
    string description = 3;
    /// Filter by labels.
    MapWrapper labels = 4;
  }
  /// Pagination options.
  Page page = 5;
}

// The response message for listing roles.
message ListRolesResponse {
  /// List of roles.
  repeated m10.sdk.Role roles = 1; 
  /// Request for next page of results.
  ListRolesRequest next_request = 2; 
}

// The request message for retrieving a specific transaction.
message GetTransactionRequest { 
  /// ID of the transaction.
  uint64 tx_id = 1; 
}

// The request message for listing transactions.
message ListTransactionsRequest {
  /// Context ID to filter by.
  bytes context_id = 1; 
  /// Maximum number of transactions to return.
  uint64 limit = 3; 
  /// Minimum transaction ID.
  uint64 min_tx_id = 4; 
  /// Maximum transaction ID.
  uint64 max_tx_id = 5; 
}

// The request message for grouping transactions by context ID.
message GroupTransactionsRequest {
  /// Account ID to filter by.
  bytes account_id = 1; 
  /// Maximum number of groups to return.
  uint64 limit_groups = 2; 
  /// Minimum transaction ID.
  uint64 min_tx_id = 3; 
  /// Maximum transaction ID.
  uint64 max_tx_id = 4; 
}

// The request message for observing account changes.
message ObserveAccountsRequest {
  /// Starting transaction ID for observation.
  TxId starting_from = 1; 
  /// Account IDs to observe.
  repeated bytes involved_accounts = 2; 
}

// ObserveResourcesRequest is the request message for observing resource changes.
message ObserveResourcesRequest {
  /// Expression to filter resources.
  m10.sdk.Exp expression = 1;  
  /// Collection to observe.
  string collection = 2;  
  /// Starting transaction ID for observation.
  TxId starting_from = 3;  
}

// TxId represents a transaction ID.
message TxId { 
  /// ID of the transaction.
  uint64 tx_id = 1; 
}

// Request message to observe actions.
message ObserveActionsRequest {
  /// Starting transaction ID for observation.
  TxId starting_from = 1;  
  /// Name of the action to observe.
  string name = 2; 
  /// Account IDs involved in the action.
  repeated bytes involves_accounts = 3; 
}

// A finalized transaction.
message FinalizedTransaction {
  /// Transaction request.
  m10.sdk.transaction.TransactionRequestPayload request = 1; 
  /// Transaction response.
  m10.sdk.transaction.TransactionResponse response = 2;  
}

// A list of finalized transactions.
message FinalizedTransactions {
  /// List of finalized transactions.
  repeated FinalizedTransaction transactions = 1;  
}

// A list of grouped finalized transactions.
message GroupedFinalizedTransactions {
  /// List of grouped transactions.
  repeated FinalizedTransactions groups = 1; 
}

// Information about the blockchain.
message ChainInfo { 
  /// Current block height.
  uint64 block_height = 1; 
}

/// Transaction metrics.
message TransactionMetrics {
  /// Total transfer volume.
  uint64 transfer_volume = 1; 
  /// Number of transfers.
  uint64 transfer_count = 2; 
  /// Number of transfer errors.
  uint64 transfer_errors = 3;  
  /// Number of accounts created.
  uint64 accounts_created = 4;  
}

/// Request list of banks.
message ListBanksRequest {
  /// Pagination options.
  Page page = 1; 
}

/// Receive list of banks.
message ListBanksResponse {
  /// List of banks.
  repeated m10.sdk.model.Bank banks = 1; 
}

// Retrieve a specific bank.
message GetBankRequest {
  /// ID of the bank to retrieve.
  bytes id = 1; 
}

/// Offline key.
message OfflineKey {
  // The offline public key.
  bytes offline_pk = 1; 
}
