Skip to content

Commit 1101ad2

Browse files
authored
feat(lazer): improve protocol types and modules (#2934)
* refactor(lazer): add some Price tests and error types * refactor(lazer): make Price operations more explicit * refactor(lazer): move Price and Rate out from router module, update Rate API and add tests * refactor(lazer): restructure protocol modules * fix(lazer): use non-inverted exponent values in Price and Rate * test(lazer): add more Price and Rate tests
1 parent b011aee commit 1101ad2

File tree

26 files changed

+1176
-795
lines changed

26 files changed

+1176
-795
lines changed

Cargo.lock

Lines changed: 13 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lazer/contracts/solana/programs/pyth-lazer-solana-contract/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyth-lazer-solana-contract"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
edition = "2021"
55
description = "Pyth Lazer Solana contract and SDK."
66
license = "Apache-2.0"
@@ -19,7 +19,7 @@ no-log-ix-name = []
1919
idl-build = ["anchor-lang/idl-build"]
2020

2121
[dependencies]
22-
pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.10.1" }
22+
pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.11.0" }
2323

2424
anchor-lang = "0.31.1"
2525
bytemuck = { version = "1.20.0", features = ["derive"] }

lazer/publisher_sdk/rust/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[package]
22
name = "pyth-lazer-publisher-sdk"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
edition = "2021"
55
description = "Pyth Lazer Publisher SDK types."
66
license = "Apache-2.0"
77
repository = "https://github.com/pyth-network/pyth-crosschain"
88

99
[dependencies]
10-
pyth-lazer-protocol = { version = "0.10.2", path = "../../sdk/rust/protocol" }
10+
pyth-lazer-protocol = { version = "0.11.0", path = "../../sdk/rust/protocol" }
1111
anyhow = "1.0.98"
1212
protobuf = "3.7.2"
1313
serde_json = "1.0.140"

lazer/publisher_sdk/rust/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use crate::publisher_update::{FeedUpdate, FundingRateUpdate, PriceUpdate};
33
use crate::state::FeedState;
44
use ::protobuf::MessageField;
55
use pyth_lazer_protocol::jrpc::{FeedUpdateParams, UpdateParams};
6-
use pyth_lazer_protocol::symbol_state::SymbolState;
76
use pyth_lazer_protocol::FeedKind;
7+
use pyth_lazer_protocol::SymbolState;
88

99
pub mod transaction_envelope {
1010
pub use crate::protobuf::transaction_envelope::*;
@@ -56,18 +56,18 @@ impl From<UpdateParams> for Update {
5656
best_bid_price,
5757
best_ask_price,
5858
} => Update::PriceUpdate(PriceUpdate {
59-
price: Some(price.0.into()),
60-
best_bid_price: best_bid_price.map(|p| p.0.into()),
61-
best_ask_price: best_ask_price.map(|p| p.0.into()),
59+
price: Some(price.mantissa_i64()),
60+
best_bid_price: best_bid_price.map(|p| p.mantissa_i64()),
61+
best_ask_price: best_ask_price.map(|p| p.mantissa_i64()),
6262
special_fields: Default::default(),
6363
}),
6464
UpdateParams::FundingRateUpdate {
6565
price,
6666
rate,
6767
funding_rate_interval,
6868
} => Update::FundingRateUpdate(FundingRateUpdate {
69-
price: price.map(|p| p.0.into()),
70-
rate: Some(rate.0),
69+
price: price.map(|p| p.mantissa_i64()),
70+
rate: Some(rate.mantissa()),
7171
funding_rate_interval: MessageField::from_option(
7272
funding_rate_interval.map(|i| i.into()),
7373
),

lazer/sdk/rust/client/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[package]
22
name = "pyth-lazer-client"
3-
version = "2.0.1"
3+
version = "3.0.0"
44
edition = "2021"
55
description = "A Rust client for Pyth Lazer"
66
license = "Apache-2.0"
77

88
[dependencies]
9-
pyth-lazer-protocol = { path = "../protocol", version = "0.10.2" }
9+
pyth-lazer-protocol = { path = "../protocol", version = "0.11.0" }
1010
tokio = { version = "1", features = ["full"] }
1111
tokio-tungstenite = { version = "0.20", features = ["native-tls"] }
1212
futures-util = "0.3"

lazer/sdk/rust/client/examples/subscribe_price_feeds.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ use base64::Engine;
44
use pyth_lazer_client::backoff::PythLazerExponentialBackoffBuilder;
55
use pyth_lazer_client::client::PythLazerClientBuilder;
66
use pyth_lazer_client::ws_connection::AnyResponse;
7+
use pyth_lazer_protocol::api::{
8+
Channel, DeliveryFormat, Format, JsonBinaryEncoding, SubscriptionParams, SubscriptionParamsRepr,
9+
};
10+
use pyth_lazer_protocol::api::{SubscribeRequest, SubscriptionId, WsResponse};
711
use pyth_lazer_protocol::message::{
812
EvmMessage, LeEcdsaMessage, LeUnsignedMessage, Message, SolanaMessage,
913
};
1014
use pyth_lazer_protocol::payload::PayloadData;
11-
use pyth_lazer_protocol::router::{
12-
Channel, DeliveryFormat, FixedRate, Format, JsonBinaryEncoding, PriceFeedId, PriceFeedProperty,
13-
SubscriptionParams, SubscriptionParamsRepr,
14-
};
15-
use pyth_lazer_protocol::subscription::{Response, SubscribeRequest, SubscriptionId};
15+
use pyth_lazer_protocol::time::FixedRate;
16+
use pyth_lazer_protocol::{PriceFeedId, PriceFeedProperty};
1617
use tokio::pin;
1718
use tracing::level_filters::LevelFilter;
1819
use tracing_subscriber::EnvFilter;
@@ -109,7 +110,7 @@ async fn main() -> anyhow::Result<()> {
109110
// The stream gives us base64-encoded binary messages. We need to decode, parse, and verify them.
110111
match msg {
111112
AnyResponse::Json(msg) => match msg {
112-
Response::StreamUpdated(update) => {
113+
WsResponse::StreamUpdated(update) => {
113114
println!("Received a JSON update for {:?}", update.subscription_id);
114115
if let Some(evm_data) = update.payload.evm {
115116
// Decode binary data

lazer/sdk/rust/client/src/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use crate::{
5151
};
5252
use anyhow::{bail, Result};
5353
use backoff::ExponentialBackoff;
54-
use pyth_lazer_protocol::subscription::{SubscribeRequest, SubscriptionId};
54+
use pyth_lazer_protocol::api::{SubscribeRequest, SubscriptionId};
5555
use tokio::sync::mpsc::{self, error::TrySendError};
5656
use tracing::{error, warn};
5757
use ttl_cache::TtlCache;

lazer/sdk/rust/client/src/resilient_ws_connection.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ use std::time::Duration;
22

33
use backoff::{backoff::Backoff, ExponentialBackoff};
44
use futures_util::StreamExt;
5-
use pyth_lazer_protocol::subscription::{
6-
Request, SubscribeRequest, SubscriptionId, UnsubscribeRequest,
7-
};
5+
use pyth_lazer_protocol::api::{SubscribeRequest, SubscriptionId, UnsubscribeRequest, WsRequest};
86
use tokio::{pin, select, sync::mpsc, time::Instant};
97
use tracing::{error, info, warn};
108
use url::Url;
@@ -18,7 +16,7 @@ use anyhow::{bail, Context, Result};
1816
const BACKOFF_RESET_DURATION: Duration = Duration::from_secs(10);
1917

2018
pub struct PythLazerResilientWSConnection {
21-
request_sender: mpsc::Sender<Request>,
19+
request_sender: mpsc::Sender<WsRequest>,
2220
}
2321

2422
impl PythLazerResilientWSConnection {
@@ -53,15 +51,17 @@ impl PythLazerResilientWSConnection {
5351

5452
pub async fn subscribe(&mut self, request: SubscribeRequest) -> Result<()> {
5553
self.request_sender
56-
.send(Request::Subscribe(request))
54+
.send(WsRequest::Subscribe(request))
5755
.await
5856
.context("Failed to send subscribe request")?;
5957
Ok(())
6058
}
6159

6260
pub async fn unsubscribe(&mut self, subscription_id: SubscriptionId) -> Result<()> {
6361
self.request_sender
64-
.send(Request::Unsubscribe(UnsubscribeRequest { subscription_id }))
62+
.send(WsRequest::Unsubscribe(UnsubscribeRequest {
63+
subscription_id,
64+
}))
6565
.await
6666
.context("Failed to send unsubscribe request")?;
6767
Ok(())
@@ -95,7 +95,7 @@ impl PythLazerResilientWSConnectionTask {
9595
pub async fn run(
9696
&mut self,
9797
response_sender: mpsc::Sender<AnyResponse>,
98-
request_receiver: &mut mpsc::Receiver<Request>,
98+
request_receiver: &mut mpsc::Receiver<WsRequest>,
9999
) -> Result<()> {
100100
loop {
101101
let start_time = Instant::now();
@@ -128,7 +128,7 @@ impl PythLazerResilientWSConnectionTask {
128128
pub async fn start(
129129
&mut self,
130130
sender: mpsc::Sender<AnyResponse>,
131-
request_receiver: &mut mpsc::Receiver<Request>,
131+
request_receiver: &mut mpsc::Receiver<WsRequest>,
132132
) -> Result<()> {
133133
let mut ws_connection =
134134
PythLazerWSConnection::new(self.endpoint.clone(), self.access_token.clone())?;
@@ -137,7 +137,7 @@ impl PythLazerResilientWSConnectionTask {
137137

138138
for subscription in self.subscriptions.clone() {
139139
ws_connection
140-
.send_request(Request::Subscribe(subscription))
140+
.send_request(WsRequest::Subscribe(subscription))
141141
.await?;
142142
}
143143
loop {
@@ -167,10 +167,10 @@ impl PythLazerResilientWSConnectionTask {
167167
}
168168
Some(request) = request_receiver.recv() => {
169169
match request {
170-
Request::Subscribe(request) => {
170+
WsRequest::Subscribe(request) => {
171171
self.subscribe(&mut ws_connection, request).await?;
172172
}
173-
Request::Unsubscribe(request) => {
173+
WsRequest::Unsubscribe(request) => {
174174
self.unsubscribe(&mut ws_connection, request).await?;
175175
}
176176
}

lazer/sdk/rust/client/src/ws_connection.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use anyhow::Result;
44
use derive_more::From;
55
use futures_util::{SinkExt, StreamExt, TryStreamExt};
66
use pyth_lazer_protocol::{
7+
api::{ErrorResponse, SubscribeRequest, UnsubscribeRequest, WsRequest, WsResponse},
78
binary_update::BinaryWsUpdate,
8-
subscription::{ErrorResponse, Request, Response, SubscribeRequest, UnsubscribeRequest},
99
};
1010
use tokio_tungstenite::{connect_async, tungstenite::Message};
1111
use url::Url;
@@ -32,7 +32,7 @@ pub struct PythLazerWSConnection {
3232

3333
#[derive(Debug, Clone, PartialEq, Eq, Hash, From)]
3434
pub enum AnyResponse {
35-
Json(Response),
35+
Json(WsResponse),
3636
Binary(BinaryWsUpdate),
3737
}
3838

@@ -84,13 +84,13 @@ impl PythLazerWSConnection {
8484
.try_filter_map(|msg| async {
8585
let r: Result<Option<AnyResponse>> = match msg {
8686
Message::Text(text) => {
87-
Ok(Some(serde_json::from_str::<Response>(&text)?.into()))
87+
Ok(Some(serde_json::from_str::<WsResponse>(&text)?.into()))
8888
}
8989
Message::Binary(data) => {
9090
Ok(Some(BinaryWsUpdate::deserialize_slice(&data)?.into()))
9191
}
9292
Message::Close(_) => Ok(Some(
93-
Response::Error(ErrorResponse {
93+
WsResponse::Error(ErrorResponse {
9494
error: "WebSocket connection closed".to_string(),
9595
})
9696
.into(),
@@ -103,7 +103,7 @@ impl PythLazerWSConnection {
103103
Ok(response_stream)
104104
}
105105

106-
pub async fn send_request(&mut self, request: Request) -> Result<()> {
106+
pub async fn send_request(&mut self, request: WsRequest) -> Result<()> {
107107
if let Some(sender) = &mut self.ws_sender {
108108
let msg = serde_json::to_string(&request)?;
109109
sender.send(Message::Text(msg)).await?;
@@ -118,7 +118,7 @@ impl PythLazerWSConnection {
118118
/// # Arguments
119119
/// * `request` - A subscription request containing feed IDs and parameters
120120
pub async fn subscribe(&mut self, request: SubscribeRequest) -> Result<()> {
121-
let request = Request::Subscribe(request);
121+
let request = WsRequest::Subscribe(request);
122122
self.send_request(request).await
123123
}
124124

@@ -127,7 +127,7 @@ impl PythLazerWSConnection {
127127
/// # Arguments
128128
/// * `subscription_id` - The ID of the subscription to cancel
129129
pub async fn unsubscribe(&mut self, request: UnsubscribeRequest) -> Result<()> {
130-
let request = Request::Unsubscribe(request);
130+
let request = WsRequest::Unsubscribe(request);
131131
self.send_request(request).await
132132
}
133133

lazer/sdk/rust/protocol/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyth-lazer-protocol"
3-
version = "0.10.2"
3+
version = "0.11.0"
44
edition = "2021"
55
description = "Pyth Lazer SDK - protocol types."
66
license = "Apache-2.0"
@@ -20,6 +20,7 @@ mry = { version = "0.13.0", features = ["serde"], optional = true }
2020
chrono = "0.4.41"
2121
humantime = "2.2.0"
2222
hex = "0.4.3"
23+
thiserror = "2.0.12"
2324

2425
[dev-dependencies]
2526
bincode = "1.3.3"
@@ -28,3 +29,4 @@ hex = "0.4.3"
2829
libsecp256k1 = "0.7.1"
2930
bs58 = "0.5.1"
3031
alloy-primitives = "0.8.19"
32+
assert_float_eq = "1.1.4"

0 commit comments

Comments
 (0)