Skip to content

Commit 438a206

Browse files
committed
feat(lazer-protocol): add metadata v3 response types
1 parent 6248709 commit 438a206

File tree

7 files changed

+153
-12
lines changed

7 files changed

+153
-12
lines changed

Cargo.lock

Lines changed: 5 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.7.1"
3+
version = "0.7.2"
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.16.0" }
22+
pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.17.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.14.0"
3+
version = "0.15.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.16.0", path = "../../sdk/rust/protocol" }
10+
pyth-lazer-protocol = { version = "0.17.0", path = "../../sdk/rust/protocol" }
1111
anyhow = "1.0.98"
1212
protobuf = "3.7.2"
1313
serde_json = "1.0.140"

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 = "8.2.2"
3+
version = "8.2.3"
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.16.0" }
9+
pyth-lazer-protocol = { path = "../protocol", version = "0.17.0" }
1010
tokio = { version = "1", features = ["full"] }
1111
tokio-tungstenite = { version = "0.20", features = ["native-tls"] }
1212
futures-util = "0.3"

lazer/sdk/rust/protocol/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyth-lazer-protocol"
3-
version = "0.16.0"
3+
version = "0.17.0"
44
edition = "2021"
55
description = "Pyth Lazer SDK - protocol types."
66
license = "Apache-2.0"

lazer/sdk/rust/protocol/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ mod feed_kind;
1010
pub mod jrpc;
1111
/// Types describing Lazer's verifiable messages containing signature and payload.
1212
pub mod message;
13+
/// Types describing Lazer's feed & asset metadata catalog APIs.
14+
pub mod metadata;
1315
/// Types describing Lazer's message payload.
1416
pub mod payload;
1517
mod price;
@@ -28,6 +30,7 @@ use serde::{Deserialize, Serialize};
2830
pub use crate::{
2931
dynamic_value::DynamicValue,
3032
feed_kind::FeedKind,
33+
metadata::{AssetClass, AssetResponseV3, FeedResponseV3, InstrumentType},
3134
price::{Price, PriceError},
3235
rate::{Rate, RateError},
3336
symbol_state::SymbolState,
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//! Types describing Lazer's metadata APIs.
2+
3+
use crate::FeedKind;
4+
use crate::{symbol_state::SymbolState, PriceFeedId};
5+
use serde::{Deserialize, Serialize};
6+
7+
/// The pricing context or type of instrument for a feed.
8+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9+
#[serde(rename_all = "lowercase")]
10+
pub enum InstrumentType {
11+
/// Spot price
12+
Spot,
13+
/// Redemption rate
14+
#[serde(rename = "redemptionrate")]
15+
RedemptionRate,
16+
/// Funding rate
17+
#[serde(rename = "fundingrate")]
18+
FundingRate,
19+
/// Future price
20+
Future,
21+
/// Net Asset Value
22+
Nav,
23+
/// Time-weighted average price
24+
Twap,
25+
}
26+
27+
/// High-level asset class.
28+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
29+
#[serde(rename_all = "kebab-case")]
30+
pub enum AssetClass {
31+
/// Cryptocurrency
32+
Crypto,
33+
/// Foreign exchange
34+
Fx,
35+
/// Equity
36+
Equity,
37+
/// Metal
38+
Metal,
39+
/// Rates
40+
Rates,
41+
/// Net Asset Value
42+
Nav,
43+
/// Commodity
44+
Commodity,
45+
/// Funding rate
46+
FundingRate,
47+
}
48+
49+
/// Feed metadata as returned by the v3 metadata API.
50+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
51+
pub struct FeedResponseV3 {
52+
/// Unique integer identifier for a feed. Known as `pyth_lazer_id` in V1 API.
53+
/// Example: `1`
54+
pub id: PriceFeedId,
55+
/// Short feed name.
56+
/// Example: `"Bitcoin / US Dollar"`
57+
pub name: String,
58+
/// Unique human-readable identifier for a feed.
59+
/// Format: `source.instrument_type.base/quote`
60+
/// Examples: `"pyth.spot.btc/usd"`, `"pyth.redemptionrate.alp/usd"`, `"binance.fundingrate.btc/usdt"`, `"pyth.future.emz5/usd"`
61+
pub symbol: String,
62+
/// Description of the feed pair.
63+
/// Example: `"Pyth Network Aggregate Price for spot BTC/USD"`
64+
pub description: String,
65+
/// The Asset ID of the base asset.
66+
/// Example: `"BTC"`
67+
pub base_asset_id: String,
68+
/// The Asset ID of the quote asset.
69+
/// Example: `"USD"`
70+
pub quote_asset_id: String,
71+
/// The pricing context.
72+
/// Example: `InstrumentType::Spot`
73+
pub instrument_type: InstrumentType,
74+
/// Aggregator or producer of the prices.
75+
/// Examples: `"pyth"` for our aggregations, `"binance"` for their funding rates
76+
pub source: String,
77+
/// The trading schedule of the feed's market, in Pythnet format.
78+
/// Example: `"America/New_York;O,O,O,O,O,O,O;"`
79+
pub schedule: String,
80+
/// Power-of-ten exponent. Scale the `price` mantissa value by `10^exponent` to get the decimal representation.
81+
/// Example: `-8`
82+
pub exponent: i32,
83+
/// Funding rate interval. Only applies to feeds with instrument type `funding_rate`.
84+
/// Example: `10`
85+
pub update_interval_seconds: i32,
86+
/// The minimum number of publishers contributing component prices to the aggregate price.
87+
/// Example: `3`
88+
pub min_publishers: i32,
89+
/// Status of the feed.
90+
/// Example: `SymbolState::Active`
91+
pub state: SymbolState,
92+
/// High-level asset class. One of crypto, fx, equity, metal, rates, nav, commodity, funding-rate.
93+
/// Example: `AssetClass::Crypto`
94+
pub asset_type: AssetClass,
95+
/// CoinMarketCap asset identifier.
96+
/// Example: `"123"`
97+
#[serde(skip_serializing_if = "Option::is_none")]
98+
pub cmc_id: Option<String>,
99+
/// Pythnet feed identifier. 32 bytes, represented in hex.
100+
/// Example: `"e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43"`
101+
pub pythnet_id: String,
102+
/// Nasdaq symbol identifier.
103+
/// Example: `"ADSK"`
104+
#[serde(skip_serializing_if = "Option::is_none")]
105+
pub nasdaq_symbol: Option<String>,
106+
/// ISO datetime after which the feed will no longer produce prices because the underlying market has expired.
107+
/// Example: `"2025-10-03T11:08:10.089998603Z"`
108+
#[serde(skip_serializing_if = "Option::is_none")]
109+
pub feed_expiry: Option<String>,
110+
/// The nature of the data produced by the feed.
111+
/// Examples: `"price"`, `"fundingRate"`
112+
pub feed_kind: FeedKind,
113+
}
114+
115+
/// Asset metadata as returned by the v3 metadata API.
116+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
117+
pub struct AssetResponseV3 {
118+
/// Unique identifier for an asset.
119+
/// Example: `"BTC"`
120+
pub id: String,
121+
/// A short, human-readable code that identifies an asset. Not guaranteed to be unique.
122+
/// Example: `"BTC"`
123+
pub ticker: String,
124+
/// Full human-readable name of the asset.
125+
/// Example: `"Bitcoin"`
126+
pub full_name: String,
127+
/// High-level asset class.
128+
/// Example: `AssetClass::Crypto`
129+
pub class: AssetClass,
130+
/// More granular categorization within class.
131+
/// Example: `"stablecoin"`
132+
#[serde(skip_serializing_if = "Option::is_none")]
133+
pub subclass: Option<String>,
134+
/// Primary or canonical listing exchange, when applicable.
135+
/// Example: `"NASDAQ"`
136+
#[serde(skip_serializing_if = "Option::is_none")]
137+
pub listing_exchange: Option<String>,
138+
}

0 commit comments

Comments
 (0)