syntax = "proto3";

package searcher;
option go_package = "generated/types";

import "dto.proto";

message AddressSubscriptionV0 {
  repeated string address = 1; // List of events to subscribe to.
}

message WorkchainSubscriptionV0 {
  int32 workchain_id = 1; // workchain id
}

message WorkchainShardSubscriptionV0 {
  int32 workchain_id = 1; // workchain id
  bytes shard = 2; // shard id
}

message ExternalOutMessageBodyOpcodeSubscriptionV0 {
  int32 workchain_id = 1; // workchain id
  optional bytes shard = 2; // shard id
  int32 opcode = 3; // opcode
}

message InternalMessageBodyOpcodeSubscriptionV0 {
  int32 workchain_id = 1; // workchain id
  optional bytes shard = 2; // shard id
  int32 opcode = 3; // opcode
}

// Mempool subscription message, allowing subscriptions by package, object, or address.
message MempoolSubscription {
  oneof subscription {
    AddressSubscriptionV0 addresses = 1; // Subscribe to mempool messages involving specific addresses.
    WorkchainSubscriptionV0 workchain = 2; // Subscribe to mempool messages happened in specific workchain.
    WorkchainShardSubscriptionV0 workchainShard = 3; // Subscribe to mempool messages happened in specific shard of workchain.
    ExternalOutMessageBodyOpcodeSubscriptionV0 externalOutMessageBodyOpcode = 4; // Subscribe to mempool outging internal messages matching opcode.
    InternalMessageBodyOpcodeSubscriptionV0 internalMessageBodyOpcode = 5; // Subscribe to mempool outging internal messages matching opcode.
  }
}

// Response message for sending a bundle.
message SendBundleResponse {
  string id = 1; // ID of the sent bundle.
}

// Request message to get the tip address.
message GetTipAddressesRequest {}

// Response message containing the tip addresses.
message GetTipAddressesResponse {
  repeated string address = 1; // List of tip addresses.
}

// Request message for subscribing to bundle results.
message SubscribeBundleResultsRequest {}

// Message indicating a bundle won an auction.
message BundleResultAuctionWin {
  string auction_id = 1; // ID of the auction.
  uint64 estimated_nanoton_tip = 2; // Estimated tip amount.
}

// Message indicating a bundle lost an auction.
message BundleResultAuctionLoose {
  string auction_id = 1; // ID of the auction.
}

// Message indicating a bundle was partially processed.
message BundleResultPartiallyProcessed {
  string auction_id = 1; // ID of the auction.
  repeated bytes digest = 2; // Digests of the processed messages.
}

// Message indicating a bundle partially expired.
message BundleResultPartiallyExpired {
  string auction_id = 1; // ID of the auction.
  repeated bytes digest = 2; // Digests of the expired messages.
}

// Message indicating a bundle was interrupted.
message BundleResultInterrupted {
  bool on_auction = 1; // Whether the bundle was on auction.
  oneof reason {
    BundleResultPartiallyProcessed partially_processed = 2; // Partially processed bundle result.
    BundleResultPartiallyExpired expired = 3; // Partially expired bundle result.
  }
}

// Message indicating a bundle auction failed due to an estimate error.
message BundleResultAuctionFailedEstimate {
  string auction_id = 1; // ID of the auction.
  bytes digest = 2; // Digest of the failed message.
  string message = 3; // Error message.
}

// Message indicating a bundle auction failed due to an internal error.
message BundleResultInternalError {
  string auction_id = 1; // ID of the auction.
  repeated bytes digest = 2; // Digests of the messages involved.
  string message = 3; // Error message.
}

// Message indicating a bundle auction failure.
message BundleResultAuctionFailed {
  oneof reason {
    BundleResultAuctionFailedEstimate estimate_error = 1; // Auction failed due to estimate error.
    BundleResultInternalError internal_error = 2; // Auction failed due to internal error.
  }
}

// Message representing the result of a bundle submission.
message BundleResult {
  string id = 1; // ID of the bundle.
  oneof result {
    BundleResultAuctionWin win = 2; // Bundle won the auction.
    BundleResultAuctionLoose loose = 3; // Bundle lost the auction.
    BundleResultInterrupted drop = 4; // Bundle was interrupted.
    BundleResultAuctionFailed failure = 5; // Bundle auction failed.
  }
}

// Service definition for MEV searchers on the TON blockchain.
service SearcherService {
  // Subscribe to bundle results.
  rpc SubscribeBundleResults (SubscribeBundleResultsRequest) returns (stream BundleResult) {}

  // Subscribe to mempool messages based on specific criteria.
  rpc SubscribeMempool (MempoolSubscription) returns (stream dto.MempoolPacket) {}

  // Send a bundle of messages.
  rpc SendBundle (dto.Bundle) returns (SendBundleResponse) {}

  // Get the tip address for message inclusion.
  rpc GetTipAddresses (GetTipAddressesRequest) returns (GetTipAddressesResponse) {}
}