diff --git a/Cargo.lock b/Cargo.lock index 674827bd62..7d6e0fb75c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5693,7 +5693,7 @@ dependencies = [ [[package]] name = "pyth-lazer-client" -version = "8.2.2" +version = "8.3.0" dependencies = [ "alloy-primitives 0.8.25", "anyhow", @@ -5711,7 +5711,7 @@ dependencies = [ "hex", "humantime-serde", "libsecp256k1 0.7.2", - "pyth-lazer-protocol 0.16.0", + "pyth-lazer-protocol 0.17.0", "reqwest 0.12.23", "serde", "serde_json", @@ -5746,7 +5746,7 @@ dependencies = [ [[package]] name = "pyth-lazer-protocol" -version = "0.16.0" +version = "0.17.0" dependencies = [ "alloy-primitives 0.8.25", "anyhow", @@ -5786,13 +5786,13 @@ dependencies = [ [[package]] name = "pyth-lazer-publisher-sdk" -version = "0.14.0" +version = "0.15.0" dependencies = [ "anyhow", "fs-err", "protobuf", "protobuf-codegen", - "pyth-lazer-protocol 0.16.0", + "pyth-lazer-protocol 0.17.0", "serde_json", ] diff --git a/lazer/contracts/solana/programs/pyth-lazer-solana-contract/Cargo.toml b/lazer/contracts/solana/programs/pyth-lazer-solana-contract/Cargo.toml index 18504df77f..38a0f6b1b5 100644 --- a/lazer/contracts/solana/programs/pyth-lazer-solana-contract/Cargo.toml +++ b/lazer/contracts/solana/programs/pyth-lazer-solana-contract/Cargo.toml @@ -19,7 +19,7 @@ no-log-ix-name = [] idl-build = ["anchor-lang/idl-build"] [dependencies] -pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.16.0" } +pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.17.0" } anchor-lang = "0.31.1" bytemuck = { version = "1.20.0", features = ["derive"] } diff --git a/lazer/publisher_sdk/rust/Cargo.toml b/lazer/publisher_sdk/rust/Cargo.toml index 3e9b852275..b90e1e8a19 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.14.0" +version = "0.15.0" 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.16.0", path = "../../sdk/rust/protocol" } +pyth-lazer-protocol = { version = "0.17.0", 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 56ca1aea89..ff6be20f1b 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.2.2" +version = "8.3.0" edition = "2021" description = "A Rust client for Pyth Lazer" license = "Apache-2.0" [dependencies] -pyth-lazer-protocol = { path = "../protocol", version = "0.16.0" } +pyth-lazer-protocol = { path = "../protocol", version = "0.17.0" } tokio = { version = "1", features = ["full"] } tokio-tungstenite = { version = "0.20", features = ["native-tls"] } futures-util = "0.3" diff --git a/lazer/sdk/rust/protocol/Cargo.toml b/lazer/sdk/rust/protocol/Cargo.toml index be3dd81682..bc05f638c6 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.16.0" +version = "0.17.0" edition = "2021" description = "Pyth Lazer SDK - protocol types." license = "Apache-2.0" diff --git a/lazer/sdk/rust/protocol/src/jrpc.rs b/lazer/sdk/rust/protocol/src/jrpc.rs index c14c22f12b..3da0e45907 100644 --- a/lazer/sdk/rust/protocol/src/jrpc.rs +++ b/lazer/sdk/rust/protocol/src/jrpc.rs @@ -6,12 +6,22 @@ use crate::{api::Channel, price::Price}; use serde::{Deserialize, Serialize}; use std::time::Duration; +#[derive(Serialize, Deserialize, Debug, Default, Eq, PartialEq)] +#[serde(untagged)] +pub enum JrpcId { + String(String), + Int(i64), + #[default] + Null, +} + #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] pub struct PythLazerAgentJrpcV1 { pub jsonrpc: JsonRpcVersion, #[serde(flatten)] pub params: JrpcCall, - pub id: Option, + #[serde(default)] + pub id: JrpcId, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] @@ -184,7 +194,89 @@ mod tests { best_ask_price: Some(Price::from_integer(1234567892, 0).unwrap()), }, }), - id: Some(1), + id: JrpcId::Int(1), + }; + + assert_eq!( + serde_json::from_str::(json).unwrap(), + expected + ); + } + + #[test] + fn test_push_update_price_string_id() { + let json = r#" + { + "jsonrpc": "2.0", + "method": "push_update", + "params": { + "feed_id": 1, + "source_timestamp": 124214124124, + + "update": { + "type": "price", + "price": 1234567890, + "best_bid_price": 1234567891, + "best_ask_price": 1234567892 + } + }, + "id": "b6bb54a0-ea8d-439d-97a7-3b06befa0e76" + } + "#; + + let expected = PythLazerAgentJrpcV1 { + jsonrpc: JsonRpcVersion::V2, + params: PushUpdate(FeedUpdateParams { + feed_id: PriceFeedId(1), + source_timestamp: TimestampUs::from_micros(124214124124), + update: UpdateParams::PriceUpdate { + price: Price::from_integer(1234567890, 0).unwrap(), + best_bid_price: Some(Price::from_integer(1234567891, 0).unwrap()), + best_ask_price: Some(Price::from_integer(1234567892, 0).unwrap()), + }, + }), + id: JrpcId::String("b6bb54a0-ea8d-439d-97a7-3b06befa0e76".to_string()), + }; + + assert_eq!( + serde_json::from_str::(json).unwrap(), + expected + ); + } + + #[test] + fn test_push_update_price_null_id() { + let json = r#" + { + "jsonrpc": "2.0", + "method": "push_update", + "params": { + "feed_id": 1, + "source_timestamp": 124214124124, + + "update": { + "type": "price", + "price": 1234567890, + "best_bid_price": 1234567891, + "best_ask_price": 1234567892 + } + }, + "id": null + } + "#; + + let expected = PythLazerAgentJrpcV1 { + jsonrpc: JsonRpcVersion::V2, + params: PushUpdate(FeedUpdateParams { + feed_id: PriceFeedId(1), + source_timestamp: TimestampUs::from_micros(124214124124), + update: UpdateParams::PriceUpdate { + price: Price::from_integer(1234567890, 0).unwrap(), + best_bid_price: Some(Price::from_integer(1234567891, 0).unwrap()), + best_ask_price: Some(Price::from_integer(1234567892, 0).unwrap()), + }, + }), + id: JrpcId::Null, }; assert_eq!( @@ -224,7 +316,7 @@ mod tests { best_ask_price: Some(Price::from_integer(5432, 0).unwrap()), }, }), - id: None, + id: JrpcId::Null, }; assert_eq!( @@ -263,7 +355,7 @@ mod tests { best_ask_price: None, }, }), - id: Some(1), + id: JrpcId::Int(1), }; assert_eq!( @@ -304,7 +396,7 @@ mod tests { funding_rate_interval: Duration::from_secs(28800).into(), }, }), - id: Some(1), + id: JrpcId::Int(1), }; assert_eq!( @@ -342,7 +434,7 @@ mod tests { funding_rate_interval: None, }, }), - id: Some(1), + id: JrpcId::Int(1), }; assert_eq!( @@ -371,7 +463,7 @@ mod tests { names: Some(vec!["BTC/USD".to_string()]), asset_types: Some(vec!["crypto".to_string()]), }), - id: Some(1), + id: JrpcId::Int(1), }; assert_eq!( @@ -397,7 +489,7 @@ mod tests { names: None, asset_types: None, }), - id: Some(1), + id: JrpcId::Int(1), }; assert_eq!(