syntax = "proto3"; package oracle.v1; option go_package = "github.com/tech/sendico/pkg/proto/oracle/v1;oraclev1"; import "google/protobuf/timestamp.proto"; import "api/proto/common/money/v1/money.proto"; import "api/proto/common/fx/v1/fx.proto"; import "api/proto/common/trace/v1/trace.proto"; // RateSnapshot holds a point-in-time rate observation from a provider. 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; } // RequestMeta carries caller identity and tracing context for oracle requests. message RequestMeta { reserved 1, 4, 5; reserved "request_ref", "idempotency_key", "trace_ref"; string tenant_ref = 2; string organization_ref = 3; common.trace.v1.TraceContext trace = 6; } // ResponseMeta carries tracing context for oracle responses. message ResponseMeta { reserved 1, 2; reserved "request_ref", "trace_ref"; common.trace.v1.TraceContext trace = 3; } // Quote represents a priced FX quote with an expiry window. 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; google.protobuf.Timestamp priced_at = 11; } // GetQuoteRequest is the request to obtain an FX quote. 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; } // GetQuoteResponse is the response for GetQuote. message GetQuoteResponse { ResponseMeta meta = 1; Quote quote = 2; } // ValidateQuoteRequest is the request to check whether a quote is still valid. message ValidateQuoteRequest { RequestMeta meta = 1; string quote_ref = 2; } // ValidateQuoteResponse is the response for ValidateQuote. message ValidateQuoteResponse { ResponseMeta meta = 1; Quote quote = 2; bool valid = 3; string reason = 4; } // ConsumeQuoteRequest marks a quote as used, linking it to a ledger transaction. message ConsumeQuoteRequest { RequestMeta meta = 1; string quote_ref = 2; string ledger_txn_ref = 3; } // ConsumeQuoteResponse is the response for ConsumeQuote. message ConsumeQuoteResponse { ResponseMeta meta = 1; bool consumed = 2; string reason = 3; } // LatestRateRequest is the request to fetch the most recent rate for a pair. message LatestRateRequest { RequestMeta meta = 1; common.fx.v1.CurrencyPair pair = 2; string provider = 3; } // LatestRateResponse is the response for LatestRate. message LatestRateResponse { ResponseMeta meta = 1; RateSnapshot rate = 2; } // ListPairsRequest is the request to list all supported currency pairs. message ListPairsRequest { RequestMeta meta = 1; } // PairMeta holds metadata for a supported currency pair. message PairMeta { common.fx.v1.CurrencyPair pair = 1; common.money.v1.CurrencyMeta base_meta = 2; common.money.v1.CurrencyMeta quote_meta = 3; } // ListPairsResponse is the response for ListPairs. message ListPairsResponse { ResponseMeta meta = 1; repeated PairMeta pairs = 2; } // Oracle provides FX rate quoting, validation, and consumption. service Oracle { // GetQuote returns a priced FX quote for a currency pair. rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse); // ValidateQuote checks whether an existing quote is still valid. rpc ValidateQuote(ValidateQuoteRequest) returns (ValidateQuoteResponse); // ConsumeQuote marks a quote as consumed and links it to a ledger transaction. rpc ConsumeQuote(ConsumeQuoteRequest) returns (ConsumeQuoteResponse); // LatestRate returns the most recent rate snapshot for a currency pair. rpc LatestRate(LatestRateRequest) returns (LatestRateResponse); // ListPairs returns all supported currency pairs. rpc ListPairs(ListPairsRequest) returns (ListPairsResponse); }