From 7075f985a22003666c0d8f7559757dedc8390a6c Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 14:05:01 -0700 Subject: [PATCH 1/9] chore: add utoipa::ToSchema trait to request & response types for use in openapi spec --- Cargo.lock | 1 + lazer/sdk/rust/protocol/Cargo.toml | 3 +- lazer/sdk/rust/protocol/src/api.rs | 57 ++++++++++++++++-------------- lazer/sdk/rust/protocol/src/lib.rs | 3 +- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08375967ef..0b083b91e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5748,6 +5748,7 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.12", + "utoipa", ] [[package]] diff --git a/lazer/sdk/rust/protocol/Cargo.toml b/lazer/sdk/rust/protocol/Cargo.toml index 1f2999f139..5a42ff8df8 100644 --- a/lazer/sdk/rust/protocol/Cargo.toml +++ b/lazer/sdk/rust/protocol/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyth-lazer-protocol" -version = "0.20.0" +version = "0.21.0" edition = "2021" description = "Pyth Lazer SDK - protocol types." license = "Apache-2.0" @@ -21,6 +21,7 @@ chrono = "0.4.41" humantime = "2.2.0" hex = "0.4.3" thiserror = "2.0.12" +utoipa = "3.4.0" [dev-dependencies] bincode = "1.3.3" diff --git a/lazer/sdk/rust/protocol/src/api.rs b/lazer/sdk/rust/protocol/src/api.rs index 2f10d3c376..91933a65b1 100644 --- a/lazer/sdk/rust/protocol/src/api.rs +++ b/lazer/sdk/rust/protocol/src/api.rs @@ -7,6 +7,7 @@ use std::{ use derive_more::derive::From; use itertools::Itertools as _; use serde::{de::Error, Deserialize, Serialize}; +use utoipa::ToSchema; use crate::{ payload::AggregatedPriceFeedData, @@ -14,7 +15,7 @@ use crate::{ ChannelId, Price, PriceFeedId, PriceFeedProperty, Rate, }; -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct LatestPriceRequestRepr { // Either price feed ids or symbols must be specified. @@ -33,7 +34,7 @@ pub struct LatestPriceRequestRepr { pub channel: Channel, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct LatestPriceRequest(LatestPriceRequestRepr); @@ -79,7 +80,7 @@ impl DerefMut for LatestPriceRequest { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct PriceRequestRepr { pub timestamp: TimestampUs, @@ -97,7 +98,7 @@ pub struct PriceRequestRepr { pub channel: Channel, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct PriceRequest(PriceRequestRepr); @@ -143,7 +144,7 @@ impl DerefMut for PriceRequest { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct ReducePriceRequest { pub payload: JsonUpdate, @@ -158,7 +159,7 @@ pub fn default_parsed() -> bool { true } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub enum DeliveryFormat { /// Deliver stream updates as JSON text messages. @@ -168,7 +169,7 @@ pub enum DeliveryFormat { Binary, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub enum Format { Evm, @@ -177,7 +178,7 @@ pub enum Format { LeUnsigned, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub enum JsonBinaryEncoding { #[default] @@ -185,7 +186,7 @@ pub enum JsonBinaryEncoding { Hex, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, From)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, From, ToSchema)] pub enum Channel { FixedRate(FixedRate), RealTime, @@ -275,7 +276,7 @@ impl<'de> Deserialize<'de> for Channel { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct SubscriptionParamsRepr { // Either price feed ids or symbols must be specified. @@ -299,7 +300,7 @@ pub struct SubscriptionParamsRepr { pub ignore_invalid_feeds: bool, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct SubscriptionParams(SubscriptionParamsRepr); @@ -345,14 +346,14 @@ impl DerefMut for SubscriptionParams { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct JsonBinaryData { pub encoding: JsonBinaryEncoding, pub data: String, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct JsonUpdate { /// Present unless `parsed = false` is specified in subscription params. @@ -372,7 +373,7 @@ pub struct JsonUpdate { pub le_unsigned: Option, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct ParsedPayload { #[serde(with = "crate::serde_str::timestamp")] @@ -380,7 +381,7 @@ pub struct ParsedPayload { pub price_feeds: Vec, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct ParsedFeedPayload { pub price_feed_id: PriceFeedId, @@ -491,7 +492,7 @@ impl ParsedFeedPayload { } /// A request sent from the client to the server. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(tag = "type")] #[serde(rename_all = "camelCase")] pub enum WsRequest { @@ -499,10 +500,12 @@ pub enum WsRequest { Unsubscribe(UnsubscribeRequest), } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema, +)] pub struct SubscriptionId(pub u64); -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct SubscribeRequest { pub subscription_id: SubscriptionId, @@ -510,14 +513,14 @@ pub struct SubscribeRequest { pub params: SubscriptionParams, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct UnsubscribeRequest { pub subscription_id: SubscriptionId, } /// A JSON response sent from the server to the client. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, From)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, From, ToSchema)] #[serde(tag = "type")] #[serde(rename_all = "camelCase")] pub enum WsResponse { @@ -530,13 +533,13 @@ pub enum WsResponse { } /// Sent from the server after a successul subscription. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct SubscribedResponse { pub subscription_id: SubscriptionId, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct InvalidFeedSubscriptionDetails { pub unknown_ids: Vec, @@ -545,7 +548,7 @@ pub struct InvalidFeedSubscriptionDetails { pub unstable: Vec, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct SubscribedWithInvalidFeedIdsIgnoredResponse { pub subscription_id: SubscriptionId, @@ -553,7 +556,7 @@ pub struct SubscribedWithInvalidFeedIdsIgnoredResponse { pub ignored_invalid_feed_ids: InvalidFeedSubscriptionDetails, } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct UnsubscribedResponse { pub subscription_id: SubscriptionId, @@ -561,7 +564,7 @@ pub struct UnsubscribedResponse { /// Sent from the server if the requested subscription or unsubscription request /// could not be fulfilled. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct SubscriptionErrorResponse { pub subscription_id: SubscriptionId, @@ -570,7 +573,7 @@ pub struct SubscriptionErrorResponse { /// Sent from the server if an internal error occured while serving data for an existing subscription, /// or a client request sent a bad request. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct ErrorResponse { pub error: String, @@ -578,7 +581,7 @@ pub struct ErrorResponse { /// Sent from the server when new data is available for an existing subscription /// (only if `delivery_format == Json`). -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct StreamUpdatedResponse { pub subscription_id: SubscriptionId, diff --git a/lazer/sdk/rust/protocol/src/lib.rs b/lazer/sdk/rust/protocol/src/lib.rs index ff6f16da8f..a4db98389b 100644 --- a/lazer/sdk/rust/protocol/src/lib.rs +++ b/lazer/sdk/rust/protocol/src/lib.rs @@ -24,6 +24,7 @@ pub mod time; use derive_more::derive::{From, Into}; use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; pub use crate::{ dynamic_value::DynamicValue, @@ -55,7 +56,7 @@ impl ChannelId { pub const FIXED_RATE_1000: ChannelId = ChannelId(4); } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub enum PriceFeedProperty { Price, From 71b3f4fd001c7be35b6177b4eb88c15657882aa7 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 14:09:32 -0700 Subject: [PATCH 2/9] bump patch ver --- Cargo.lock | 30 +++++++++++++++--------------- lazer/sdk/rust/protocol/Cargo.toml | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b083b91e5..1a974b7d53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5674,7 +5674,7 @@ dependencies = [ "hyper 1.6.0", "hyper-util", "protobuf", - "pyth-lazer-protocol 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pyth-lazer-protocol 0.20.0", "pyth-lazer-publisher-sdk 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.12.23", "serde", @@ -5712,7 +5712,7 @@ dependencies = [ "hex", "humantime-serde", "libsecp256k1 0.7.2", - "pyth-lazer-protocol 0.20.0", + "pyth-lazer-protocol 0.20.1", "reqwest 0.12.23", "serde", "serde_json", @@ -5727,49 +5727,49 @@ dependencies = [ [[package]] name = "pyth-lazer-protocol" version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efd998c309b88c9f9790addb962cb20cb2528f3c1fe305160f998403306ba7d" dependencies = [ - "alloy-primitives 0.8.25", "anyhow", - "assert_float_eq", - "bincode 1.3.3", - "bs58", "byteorder", "chrono", "derive_more 1.0.0", - "ed25519-dalek 2.1.1", "hex", "humantime", "humantime-serde", "itertools 0.13.0", - "libsecp256k1 0.7.2", - "mry", "protobuf", "rust_decimal", "serde", "serde_json", "thiserror 2.0.12", - "utoipa", ] [[package]] name = "pyth-lazer-protocol" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efd998c309b88c9f9790addb962cb20cb2528f3c1fe305160f998403306ba7d" +version = "0.20.1" dependencies = [ + "alloy-primitives 0.8.25", "anyhow", + "assert_float_eq", + "bincode 1.3.3", + "bs58", "byteorder", "chrono", "derive_more 1.0.0", + "ed25519-dalek 2.1.1", "hex", "humantime", "humantime-serde", "itertools 0.13.0", + "libsecp256k1 0.7.2", + "mry", "protobuf", "rust_decimal", "serde", "serde_json", "thiserror 2.0.12", + "utoipa", ] [[package]] @@ -5780,7 +5780,7 @@ dependencies = [ "fs-err", "protobuf", "protobuf-codegen", - "pyth-lazer-protocol 0.20.0", + "pyth-lazer-protocol 0.20.1", "serde_json", ] @@ -5794,7 +5794,7 @@ dependencies = [ "fs-err", "protobuf", "protobuf-codegen", - "pyth-lazer-protocol 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pyth-lazer-protocol 0.20.0", "serde_json", ] diff --git a/lazer/sdk/rust/protocol/Cargo.toml b/lazer/sdk/rust/protocol/Cargo.toml index 5a42ff8df8..74189c2750 100644 --- a/lazer/sdk/rust/protocol/Cargo.toml +++ b/lazer/sdk/rust/protocol/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyth-lazer-protocol" -version = "0.21.0" +version = "0.20.1" edition = "2021" description = "Pyth Lazer SDK - protocol types." license = "Apache-2.0" From c84d1207edc6815050b00082c452d67053cffa13 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 14:19:40 -0700 Subject: [PATCH 3/9] chore: bump protocol dependents --- Cargo.lock | 14 +++++++------- lazer/publisher_sdk/rust/Cargo.toml | 4 ++-- lazer/sdk/rust/client/Cargo.toml | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a974b7d53..339c507cee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5675,7 +5675,7 @@ dependencies = [ "hyper-util", "protobuf", "pyth-lazer-protocol 0.20.0", - "pyth-lazer-publisher-sdk 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pyth-lazer-publisher-sdk 0.20.0", "reqwest 0.12.23", "serde", "serde_json", @@ -5694,7 +5694,7 @@ dependencies = [ [[package]] name = "pyth-lazer-client" -version = "8.6.0" +version = "8.6.1" dependencies = [ "alloy-primitives 0.8.25", "anyhow", @@ -5775,26 +5775,26 @@ dependencies = [ [[package]] name = "pyth-lazer-publisher-sdk" version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "988c6a2d6bc8d065a492d49915e803912b263e57ad5e300dc45c5a5471d609c8" dependencies = [ "anyhow", "fs-err", "protobuf", "protobuf-codegen", - "pyth-lazer-protocol 0.20.1", + "pyth-lazer-protocol 0.20.0", "serde_json", ] [[package]] name = "pyth-lazer-publisher-sdk" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "988c6a2d6bc8d065a492d49915e803912b263e57ad5e300dc45c5a5471d609c8" +version = "0.20.1" dependencies = [ "anyhow", "fs-err", "protobuf", "protobuf-codegen", - "pyth-lazer-protocol 0.20.0", + "pyth-lazer-protocol 0.20.1", "serde_json", ] diff --git a/lazer/publisher_sdk/rust/Cargo.toml b/lazer/publisher_sdk/rust/Cargo.toml index 08e08ed01c..1928a22bf0 100644 --- a/lazer/publisher_sdk/rust/Cargo.toml +++ b/lazer/publisher_sdk/rust/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "pyth-lazer-publisher-sdk" -version = "0.20.0" +version = "0.20.1" edition = "2021" description = "Pyth Lazer Publisher SDK types." license = "Apache-2.0" repository = "https://github.com/pyth-network/pyth-crosschain" [dependencies] -pyth-lazer-protocol = { version = "0.20.0", path = "../../sdk/rust/protocol" } +pyth-lazer-protocol = { version = "0.20.1", path = "../../sdk/rust/protocol" } anyhow = "1.0.98" protobuf = "3.7.2" serde_json = "1.0.140" diff --git a/lazer/sdk/rust/client/Cargo.toml b/lazer/sdk/rust/client/Cargo.toml index 4573081ee0..cbf2d1b198 100644 --- a/lazer/sdk/rust/client/Cargo.toml +++ b/lazer/sdk/rust/client/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "pyth-lazer-client" -version = "8.6.0" +version = "8.6.1" edition = "2021" description = "A Rust client for Pyth Lazer" license = "Apache-2.0" [dependencies] -pyth-lazer-protocol = { path = "../protocol", version = "0.20.0" } +pyth-lazer-protocol = { path = "../protocol", version = "0.20.1" } tokio = { version = "1", features = ["full"] } tokio-tungstenite = { version = "0.20", features = ["native-tls"] } futures-util = "0.3" From 0f3c5caa69cb93df37a472490aba616712a5ac35 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 14:27:40 -0700 Subject: [PATCH 4/9] unify utoipa version, add more ToSchema traits --- Cargo.lock | 31 ++++++++++++++++++++++++---- lazer/sdk/rust/protocol/Cargo.toml | 2 +- lazer/sdk/rust/protocol/src/lib.rs | 3 ++- lazer/sdk/rust/protocol/src/price.rs | 4 +++- lazer/sdk/rust/protocol/src/rate.rs | 4 +++- lazer/sdk/rust/protocol/src/time.rs | 13 +++++++++--- 6 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 339c507cee..bf74245225 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3132,7 +3132,7 @@ dependencies = [ "tracing", "tracing-subscriber", "url", - "utoipa", + "utoipa 3.5.0", "utoipa-swagger-ui", ] @@ -5769,7 +5769,7 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.12", - "utoipa", + "utoipa 5.4.0", ] [[package]] @@ -10555,7 +10555,19 @@ dependencies = [ "indexmap 2.10.0", "serde", "serde_json", - "utoipa-gen", + "utoipa-gen 3.5.0", +] + +[[package]] +name = "utoipa" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" +dependencies = [ + "indexmap 2.10.0", + "serde", + "serde_json", + "utoipa-gen 5.4.0", ] [[package]] @@ -10571,6 +10583,17 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "utoipa-gen" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "utoipa-swagger-ui" version = "3.1.5" @@ -10583,7 +10606,7 @@ dependencies = [ "rust-embed", "serde", "serde_json", - "utoipa", + "utoipa 3.5.0", "zip", ] diff --git a/lazer/sdk/rust/protocol/Cargo.toml b/lazer/sdk/rust/protocol/Cargo.toml index 74189c2750..0005dadc0d 100644 --- a/lazer/sdk/rust/protocol/Cargo.toml +++ b/lazer/sdk/rust/protocol/Cargo.toml @@ -21,7 +21,7 @@ chrono = "0.4.41" humantime = "2.2.0" hex = "0.4.3" thiserror = "2.0.12" -utoipa = "3.4.0" +utoipa = "5.3.1" [dev-dependencies] bincode = "1.3.3" diff --git a/lazer/sdk/rust/protocol/src/lib.rs b/lazer/sdk/rust/protocol/src/lib.rs index a4db98389b..fabccc856f 100644 --- a/lazer/sdk/rust/protocol/src/lib.rs +++ b/lazer/sdk/rust/protocol/src/lib.rs @@ -40,8 +40,9 @@ pub use crate::{ pub struct PublisherId(pub u16); #[derive( - Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into, + Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into, ToSchema, )] +#[schema(value_type = u32)] pub struct PriceFeedId(pub u32); #[derive( diff --git a/lazer/sdk/rust/protocol/src/price.rs b/lazer/sdk/rust/protocol/src/price.rs index 9bd706dc90..fb3998d860 100644 --- a/lazer/sdk/rust/protocol/src/price.rs +++ b/lazer/sdk/rust/protocol/src/price.rs @@ -7,6 +7,7 @@ use { serde::{Deserialize, Serialize}, std::num::NonZeroI64, thiserror::Error, + utoipa::ToSchema, }; #[derive(Debug, Error)] @@ -21,8 +22,9 @@ pub enum PriceError { Overflow, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema)] #[repr(transparent)] +#[schema(value_type = i64)] pub struct Price(NonZeroI64); impl Price { diff --git a/lazer/sdk/rust/protocol/src/rate.rs b/lazer/sdk/rust/protocol/src/rate.rs index 7c76de26b4..899cd6b282 100644 --- a/lazer/sdk/rust/protocol/src/rate.rs +++ b/lazer/sdk/rust/protocol/src/rate.rs @@ -6,6 +6,7 @@ use { rust_decimal::{prelude::FromPrimitive, Decimal}, serde::{Deserialize, Serialize}, thiserror::Error, + utoipa::ToSchema, }; #[derive(Debug, Error)] @@ -18,8 +19,9 @@ pub enum RateError { Overflow, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema)] #[repr(transparent)] +#[schema(value_type = i64)] pub struct Rate(i64); impl Rate { diff --git a/lazer/sdk/rust/protocol/src/time.rs b/lazer/sdk/rust/protocol/src/time.rs index 5f34a53c3c..8aa13609dd 100644 --- a/lazer/sdk/rust/protocol/src/time.rs +++ b/lazer/sdk/rust/protocol/src/time.rs @@ -11,11 +11,15 @@ use { }, serde::{Deserialize, Serialize}, std::time::{Duration, SystemTime}, + utoipa::ToSchema, }; /// Unix timestamp with microsecond resolution. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema, +)] #[repr(transparent)] +#[schema(value_type = u64)] pub struct TimestampUs(u64); #[cfg_attr(feature = "mry", mry::mry)] @@ -279,7 +283,10 @@ impl TryFrom for chrono::DateTime { } /// Non-negative duration with microsecond resolution. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema, +)] +#[schema(value_type = u64)] pub struct DurationUs(u64); impl DurationUs { @@ -487,7 +494,7 @@ pub mod duration_us_serde_humantime { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, ToSchema)] pub struct FixedRate { rate: DurationUs, } From cb3bdde8dc387ca17d89987aa1314897d8c85b5b Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 14:50:16 -0700 Subject: [PATCH 5/9] fix: treat Channel as a str in schema --- lazer/sdk/rust/protocol/src/api.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lazer/sdk/rust/protocol/src/api.rs b/lazer/sdk/rust/protocol/src/api.rs index 91933a65b1..30c3b637f1 100644 --- a/lazer/sdk/rust/protocol/src/api.rs +++ b/lazer/sdk/rust/protocol/src/api.rs @@ -20,6 +20,7 @@ use crate::{ pub struct LatestPriceRequestRepr { // Either price feed ids or symbols must be specified. pub price_feed_ids: Option>, + #[schema(default)] pub symbols: Option>, pub properties: Vec, // "chains" was renamed to "formats". "chains" is still supported for compatibility. @@ -86,6 +87,7 @@ pub struct PriceRequestRepr { pub timestamp: TimestampUs, // Either price feed ids or symbols must be specified. pub price_feed_ids: Option>, + #[schema(default)] pub symbols: Option>, pub properties: Vec, pub formats: Vec, @@ -187,6 +189,7 @@ pub enum JsonBinaryEncoding { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, From, ToSchema)] +#[schema(as = String)] pub enum Channel { FixedRate(FixedRate), RealTime, @@ -281,6 +284,7 @@ impl<'de> Deserialize<'de> for Channel { pub struct SubscriptionParamsRepr { // Either price feed ids or symbols must be specified. pub price_feed_ids: Option>, + #[schema(default)] pub symbols: Option>, pub properties: Vec, // "chains" was renamed to "formats". "chains" is still supported for compatibility. From 560d4e378830798c1bc3b59ee562dfb82bfb3e03 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 15:54:35 -0700 Subject: [PATCH 6/9] fix examples --- lazer/sdk/rust/protocol/src/api.rs | 14 ++++++++++++-- lazer/sdk/rust/protocol/src/time.rs | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lazer/sdk/rust/protocol/src/api.rs b/lazer/sdk/rust/protocol/src/api.rs index 30c3b637f1..7de20ddd57 100644 --- a/lazer/sdk/rust/protocol/src/api.rs +++ b/lazer/sdk/rust/protocol/src/api.rs @@ -7,6 +7,8 @@ use std::{ use derive_more::derive::From; use itertools::Itertools as _; use serde::{de::Error, Deserialize, Serialize}; +#[allow(unused_imports)] // used for schema examples +use serde_json::json; use utoipa::ToSchema; use crate::{ @@ -19,8 +21,9 @@ use crate::{ #[serde(rename_all = "camelCase")] pub struct LatestPriceRequestRepr { // Either price feed ids or symbols must be specified. + #[schema(example = json!([1]))] pub price_feed_ids: Option>, - #[schema(default)] + #[schema(default = schema_default_symbols)] pub symbols: Option>, pub properties: Vec, // "chains" was renamed to "formats". "chains" is still supported for compatibility. @@ -161,6 +164,13 @@ pub fn default_parsed() -> bool { true } +pub fn schema_default_symbols() -> Option> { + None +} +pub fn schema_default_price_feed_ids() -> Option> { + Some(vec![PriceFeedId(1)]) +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub enum DeliveryFormat { @@ -189,7 +199,7 @@ pub enum JsonBinaryEncoding { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, From, ToSchema)] -#[schema(as = String)] +#[schema(example = "fixed_rate@200ms")] pub enum Channel { FixedRate(FixedRate), RealTime, diff --git a/lazer/sdk/rust/protocol/src/time.rs b/lazer/sdk/rust/protocol/src/time.rs index 8aa13609dd..eb6cfcde7b 100644 --- a/lazer/sdk/rust/protocol/src/time.rs +++ b/lazer/sdk/rust/protocol/src/time.rs @@ -495,6 +495,7 @@ pub mod duration_us_serde_humantime { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, ToSchema)] +#[schema(as = String, example = "fixed_rate@200ms")] pub struct FixedRate { rate: DurationUs, } From 9bf39704a92d7a7a7016fcda7f0b3800fef5887f Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 16:05:16 -0700 Subject: [PATCH 7/9] examples --- lazer/sdk/rust/protocol/src/api.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lazer/sdk/rust/protocol/src/api.rs b/lazer/sdk/rust/protocol/src/api.rs index 7de20ddd57..fe81c4a1d1 100644 --- a/lazer/sdk/rust/protocol/src/api.rs +++ b/lazer/sdk/rust/protocol/src/api.rs @@ -23,7 +23,7 @@ pub struct LatestPriceRequestRepr { // Either price feed ids or symbols must be specified. #[schema(example = json!([1]))] pub price_feed_ids: Option>, - #[schema(default = schema_default_symbols)] + #[schema(example = schema_default_symbols)] pub symbols: Option>, pub properties: Vec, // "chains" was renamed to "formats". "chains" is still supported for compatibility. @@ -202,6 +202,7 @@ pub enum JsonBinaryEncoding { #[schema(example = "fixed_rate@200ms")] pub enum Channel { FixedRate(FixedRate), + #[schema(rename = "real_time")] RealTime, } From b710ea5503305a38c8e520102c30756817dfc742 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Thu, 30 Oct 2025 16:56:40 -0700 Subject: [PATCH 8/9] fmt --- lazer/sdk/rust/protocol/src/lib.rs | 14 +++++++++++++- lazer/sdk/rust/protocol/src/price.rs | 4 +++- lazer/sdk/rust/protocol/src/rate.rs | 4 +++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lazer/sdk/rust/protocol/src/lib.rs b/lazer/sdk/rust/protocol/src/lib.rs index fabccc856f..fc580b44ef 100644 --- a/lazer/sdk/rust/protocol/src/lib.rs +++ b/lazer/sdk/rust/protocol/src/lib.rs @@ -40,7 +40,19 @@ pub use crate::{ pub struct PublisherId(pub u16); #[derive( - Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into, ToSchema, + Debug, + Clone, + Copy, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Serialize, + Deserialize, + From, + Into, + ToSchema, )] #[schema(value_type = u32)] pub struct PriceFeedId(pub u32); diff --git a/lazer/sdk/rust/protocol/src/price.rs b/lazer/sdk/rust/protocol/src/price.rs index fb3998d860..d95ab1547c 100644 --- a/lazer/sdk/rust/protocol/src/price.rs +++ b/lazer/sdk/rust/protocol/src/price.rs @@ -22,7 +22,9 @@ pub enum PriceError { Overflow, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema, +)] #[repr(transparent)] #[schema(value_type = i64)] pub struct Price(NonZeroI64); diff --git a/lazer/sdk/rust/protocol/src/rate.rs b/lazer/sdk/rust/protocol/src/rate.rs index 899cd6b282..3f5113b173 100644 --- a/lazer/sdk/rust/protocol/src/rate.rs +++ b/lazer/sdk/rust/protocol/src/rate.rs @@ -19,7 +19,9 @@ pub enum RateError { Overflow, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, ToSchema, +)] #[repr(transparent)] #[schema(value_type = i64)] pub struct Rate(i64); From 11ffc14ca5f960d5cc4671d4bb8f1ec36ead3311 Mon Sep 17 00:00:00 2001 From: Tejas Badadare Date: Mon, 3 Nov 2025 20:33:46 -0500 Subject: [PATCH 9/9] remove unnecessary import --- lazer/sdk/rust/protocol/src/api.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/lazer/sdk/rust/protocol/src/api.rs b/lazer/sdk/rust/protocol/src/api.rs index fe81c4a1d1..12f995227c 100644 --- a/lazer/sdk/rust/protocol/src/api.rs +++ b/lazer/sdk/rust/protocol/src/api.rs @@ -7,8 +7,6 @@ use std::{ use derive_more::derive::From; use itertools::Itertools as _; use serde::{de::Error, Deserialize, Serialize}; -#[allow(unused_imports)] // used for schema examples -use serde_json::json; use utoipa::ToSchema; use crate::{