syntax = "proto3";
package shredo.decoded.v1;

service DecodedTransactions {
  rpc Subscribe(SubscribeRequest) returns (stream StreamEvent);
}

// Supply the secret API key as authorization: Bearer shredo_dt_... metadata.
// Filters here may only narrow the service's server-side configuration.
message SubscribeRequest {
  repeated string program_ids = 1;
  repeated string account_keys = 2;
}

message StreamEvent {
  uint32 schema_version = 1;
  string stream_id = 2;
  // Per-connection delivery ordinal. Not block execution order.
  uint64 delivery_sequence = 3;
  oneof event {
    Transaction transaction = 4;
    Gap gap = 5;
    Heartbeat heartbeat = 6;
  }
}

message Transaction {
  uint64 slot = 1;
  uint32 entry_range_start = 2;
  uint32 entry_range_end = 3;
  uint64 entry_ordinal = 4;
  uint64 transaction_ordinal = 5;
  bytes signature = 6;
  bytes signed_transaction_bytes = 7;
  string message_version = 8;
  repeated bytes static_account_keys = 9;
  repeated AddressTableLookup address_table_lookups = 10;
  repeated bytes resolved_account_keys = 11;
  string account_resolution_status = 12;
  repeated bytes program_ids = 13;
  uint64 observed_at_unix_ns = 14;
  repeated Instruction instructions = 15;
  // Combined accounts: static, all loaded writables, all loaded readonlys.
  repeated bytes account_keys = 16;
  // Complete signer verification happened before delivery.
  repeated bytes signatures = 17;
}

message AddressTableLookup {
  bytes account_key = 1;
  bytes writable_indexes = 2;
  bytes readonly_indexes = 3;
}
message Instruction {
  uint32 program_id_index = 1;
  bytes account_indexes = 2;
  bytes data = 3;
}
message Gap { string reason = 1; bool replay_available = 2; }
message Heartbeat { uint64 observed_at_unix_ns = 1; bool input_healthy = 2; }
