pyth_lazer_protocol/
lib.rs

1//! Lazer type definitions and utilities.
2
3/// Types describing Lazer HTTP and WebSocket APIs.
4pub mod api;
5/// Binary delivery format for WebSocket.
6pub mod binary_update;
7mod dynamic_value;
8mod feed_kind;
9/// Lazer Agent JSON-RPC API.
10pub mod jrpc;
11/// Types describing Lazer's verifiable messages containing signature and payload.
12pub mod message;
13/// Types describing Lazer's message payload.
14pub mod payload;
15mod price;
16/// Legacy Websocket API for publishers.
17pub mod publisher;
18mod rate;
19mod serde_price_as_i64;
20mod serde_str;
21mod symbol_state;
22/// Lazer's types for time representation.
23pub mod time;
24
25use derive_more::derive::{From, Into};
26use serde::{Deserialize, Serialize};
27use utoipa::ToSchema;
28
29pub use crate::{
30    dynamic_value::DynamicValue,
31    feed_kind::FeedKind,
32    price::{Price, PriceError},
33    rate::{Rate, RateError},
34    symbol_state::SymbolState,
35};
36
37#[derive(
38    Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
39)]
40pub struct PublisherId(pub u16);
41
42#[derive(
43    Debug,
44    Clone,
45    Copy,
46    PartialEq,
47    Eq,
48    Hash,
49    PartialOrd,
50    Ord,
51    Serialize,
52    Deserialize,
53    From,
54    Into,
55    ToSchema,
56)]
57#[schema(value_type = u32)]
58pub struct PriceFeedId(pub u32);
59
60#[derive(
61    Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
62)]
63pub struct ChannelId(pub u8);
64
65impl ChannelId {
66    pub const REAL_TIME: ChannelId = ChannelId(1);
67    pub const FIXED_RATE_50: ChannelId = ChannelId(2);
68    pub const FIXED_RATE_200: ChannelId = ChannelId(3);
69    pub const FIXED_RATE_1000: ChannelId = ChannelId(4);
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)]
73#[serde(rename_all = "camelCase")]
74pub enum PriceFeedProperty {
75    Price,
76    BestBidPrice,
77    BestAskPrice,
78    PublisherCount,
79    Exponent,
80    Confidence,
81    FundingRate,
82    FundingTimestamp,
83    FundingRateInterval,
84    // More fields may be added later.
85}
86
87// Operation and coefficient for converting value to mantissa.
88enum ExponentFactor {
89    // mantissa = value * factor
90    Mul(i64),
91    // mantissa = value / factor
92    Div(i64),
93}
94
95impl ExponentFactor {
96    fn get(exponent: i16) -> Option<Self> {
97        if exponent >= 0 {
98            let exponent: u32 = exponent.try_into().ok()?;
99            Some(ExponentFactor::Div(10_i64.checked_pow(exponent)?))
100        } else {
101            let minus_exponent: u32 = exponent.checked_neg()?.try_into().ok()?;
102            Some(ExponentFactor::Mul(10_i64.checked_pow(minus_exponent)?))
103        }
104    }
105}
106
107#[test]
108fn magics_in_big_endian() {
109    use crate::{
110        binary_update::BINARY_UPDATE_FORMAT_MAGIC,
111        message::format_magics_le::{
112            EVM_FORMAT_MAGIC, JSON_FORMAT_MAGIC, LE_ECDSA_FORMAT_MAGIC, LE_UNSIGNED_FORMAT_MAGIC,
113            SOLANA_FORMAT_MAGIC,
114        },
115        payload::PAYLOAD_FORMAT_MAGIC,
116    };
117
118    // The values listed in this test can be used when reading the magic headers in BE format
119    // (e.g., on EVM).
120
121    assert_eq!(u32::swap_bytes(BINARY_UPDATE_FORMAT_MAGIC), 1937213467);
122    assert_eq!(u32::swap_bytes(PAYLOAD_FORMAT_MAGIC), 1976813459);
123
124    assert_eq!(u32::swap_bytes(SOLANA_FORMAT_MAGIC), 3103857282);
125    assert_eq!(u32::swap_bytes(JSON_FORMAT_MAGIC), 2584795844);
126    assert_eq!(u32::swap_bytes(EVM_FORMAT_MAGIC), 706910618);
127    assert_eq!(u32::swap_bytes(LE_ECDSA_FORMAT_MAGIC), 3837609805);
128    assert_eq!(u32::swap_bytes(LE_UNSIGNED_FORMAT_MAGIC), 206398297);
129
130    for magic in [
131        BINARY_UPDATE_FORMAT_MAGIC,
132        PAYLOAD_FORMAT_MAGIC,
133        SOLANA_FORMAT_MAGIC,
134        JSON_FORMAT_MAGIC,
135        EVM_FORMAT_MAGIC,
136        LE_ECDSA_FORMAT_MAGIC,
137        LE_UNSIGNED_FORMAT_MAGIC,
138    ] {
139        // Required to distinguish between byte orders.
140        assert_ne!(u32::swap_bytes(magic), magic);
141    }
142}