syntax = "proto3";

package oracle.v1;

option go_package = "github.com/tech/sendico/pkg/proto/oracle/v1;oraclev1";

import "common/money/v1/money.proto";
import "common/fx/v1/fx.proto";
import "common/trace/v1/trace.proto";

message RateSnapshot {
  common.fx.v1.CurrencyPair pair = 1;
  common.money.v1.Decimal mid = 2;
  common.money.v1.Decimal bid = 3;
  common.money.v1.Decimal ask = 4;
  int64 asof_unix_ms = 5;
  string provider = 6;
  string rate_ref = 7;
  common.money.v1.Decimal spread_bps = 8;
}

message RequestMeta {
  string request_ref = 1 [deprecated = true];
  string tenant_ref = 2;
  string organization_ref = 3;
  string idempotency_key = 4 [deprecated = true];
  string trace_ref = 5 [deprecated = true];
  common.trace.v1.TraceContext trace = 6;
}

message ResponseMeta {
  string request_ref = 1 [deprecated = true];
  string trace_ref = 2 [deprecated = true];
  common.trace.v1.TraceContext trace = 3;
}

message Quote {
  string quote_ref = 1;
  common.fx.v1.CurrencyPair pair = 2;
  common.fx.v1.Side side = 3;
  common.money.v1.Decimal price = 4;
  common.money.v1.Money base_amount = 5;
  common.money.v1.Money quote_amount = 6;
  int64 expires_at_unix_ms = 7;
  string provider = 8;
  string rate_ref = 9;
  bool firm = 10;
}

message GetQuoteRequest {
  RequestMeta meta = 1;
  common.fx.v1.CurrencyPair pair = 2;
  common.fx.v1.Side side = 3;
  oneof amount_input {
    common.money.v1.Money base_amount = 4;
    common.money.v1.Money quote_amount = 5;
  }
  bool firm = 6;
  int64 ttl_ms = 7;
  string preferred_provider = 8;
  int32 max_age_ms = 9;
}

message GetQuoteResponse {
  ResponseMeta meta = 1;
  Quote quote = 2;
}

message ValidateQuoteRequest {
  RequestMeta meta = 1;
  string quote_ref = 2;
}

message ValidateQuoteResponse {
  ResponseMeta meta = 1;
  Quote quote = 2;
  bool valid = 3;
  string reason = 4;
}

message ConsumeQuoteRequest {
  RequestMeta meta = 1;
  string quote_ref = 2;
  string ledger_txn_ref = 3;
}

message ConsumeQuoteResponse {
  ResponseMeta meta = 1;
  bool consumed = 2;
  string reason = 3;
}

message LatestRateRequest {
  RequestMeta meta = 1;
  common.fx.v1.CurrencyPair pair = 2;
  string provider = 3;
}

message LatestRateResponse {
  ResponseMeta meta = 1;
  RateSnapshot rate = 2;
}

message ListPairsRequest {
  RequestMeta meta = 1;
}

message PairMeta {
  common.fx.v1.CurrencyPair pair = 1;
  common.money.v1.CurrencyMeta base_meta = 2;
  common.money.v1.CurrencyMeta quote_meta = 3;
}

message ListPairsResponse {
  ResponseMeta meta = 1;
  repeated PairMeta pairs = 2;
}

service Oracle {
  rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse);
  rpc ValidateQuote(ValidateQuoteRequest) returns (ValidateQuoteResponse);
  rpc ConsumeQuote(ConsumeQuoteRequest) returns (ConsumeQuoteResponse);
  rpc LatestRate(LatestRateRequest) returns (LatestRateResponse);
  rpc ListPairs(ListPairsRequest) returns (ListPairsResponse);
}
