Skip to content

Commit 21ee8d9

Browse files
feat(lazer): Payload reference details (#854)
* redirect from subscribe updates page * add exponent in the properties * cleanup * do not require price feed structure * update unsigned usecase * update algorithm * add 1s channel and other comments * identation in callout
1 parent a0709f9 commit 21ee8d9

File tree

3 files changed

+288
-0
lines changed

3 files changed

+288
-0
lines changed

pages/lazer/_meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"title": "Reference Material",
2626
"type": "separator"
2727
},
28+
"payload-reference": "Payload Reference",
2829
"price-feed-ids": "Price Feed IDs",
2930

3031
"websocket-api-reference": {

pages/lazer/payload-reference.mdx

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
import { Callout, Steps } from "nextra/components";
2+
3+
# Lazer Payload Reference
4+
5+
This page provides a comprehensive reference for understanding Pyth Lazer payload structure, field specifications, and available data formats. This information is essential for integrating with Lazer as a consumer and understanding the data you receive.
6+
7+
<Callout type="info">
8+
This reference is designed for both technical and non-technical stakeholders
9+
to understand Pyth Lazer's data offering. For implementation details, see our
10+
[integration guides](/lazer/integrate-as-consumer).
11+
</Callout>
12+
13+
## What is a Lazer Payload?
14+
15+
A Lazer payload is a real-time data update containing financial market information with cryptographic signatures for verification. When you subscribe to Lazer price feeds, you receive `StreamUpdated` messages containing this structured data.
16+
17+
## Stream Response Structure
18+
19+
<Callout type="info">
20+
**Customizable Payload**: The payload structure is customizable based on the
21+
properties you request in your subscription. Only the fields you specify will
22+
be included in the response. See [Available Properties by Feed
23+
Types](#available-properties-by-feed-types) for details on what you can
24+
request.
25+
</Callout>
26+
27+
When you receive a `StreamUpdated` message from Lazer, it contains the following structure:
28+
29+
### Top-Level Response Fields
30+
31+
| Field | Type | Description |
32+
| ---------------- | --------------- | ------------------------------------------------------ |
33+
| `type` | `string` | Always `"streamUpdated"` for price updates |
34+
| `subscriptionId` | `number` | Your subscription identifier, provided by the user |
35+
| `parsed` | `ParsedPayload` | Human-readable price data (when `parsed: true`) |
36+
| `evm` | `BinaryData` | EVM-compatible binary payload (when requested) |
37+
| `solana` | `BinaryData` | Solana-compatible binary payload (when requested) |
38+
| `leEcdsa` | `BinaryData` | Little-endian ECDSA binary payload (when requested) |
39+
| `leUnsigned` | `BinaryData` | Little-endian unsigned binary payload (when requested) |
40+
41+
### Parsed Payload Structure
42+
43+
The `parsed` object contains human-readable price data (if `parsed` is requested):
44+
45+
| Field | Type | Description |
46+
| ------------- | ------------------ | ---------------------------------------------------------- |
47+
| `timestampUs` | `string` | Unix timestamp in microseconds when the data was generated |
48+
| `priceFeeds` | `Array<PriceFeed>` | Array of price feed data objects |
49+
50+
## What does a price feed update look like?
51+
52+
Each price feed in the `priceFeeds` array represents real-time market data for a specific trading pair (e.g., BTC/USD, ETH/USD). Think of a price feed as a comprehensive snapshot of market conditions for that asset.
53+
54+
Here's what a typical StreamUpdated response that contains a PriceFeed looks like::
55+
56+
```json
57+
{
58+
"type": "streamUpdated",
59+
"subscriptionId": 1,
60+
"parsed": {
61+
"timestampUs": "1758690761750000",
62+
"priceFeeds": [
63+
{
64+
"priceFeedId": 1,
65+
"price": "11223872331053",
66+
"bestBidPrice": "11222498842767",
67+
"bestAskPrice": "11224513591935",
68+
"publisherCount": 9,
69+
"exponent": -8,
70+
"confidence": 1373488286
71+
},
72+
{
73+
"priceFeedId": 2,
74+
"price": "448480908040",
75+
"bestBidPrice": "448475995765",
76+
"bestAskPrice": "448508987987",
77+
"publisherCount": 12,
78+
"exponent": -8,
79+
"confidence": 106965585
80+
}
81+
]
82+
},
83+
"evm": {
84+
"encoding": "base64",
85+
"data": "..."
86+
}
87+
}
88+
```
89+
90+
<Callout type="warning">
91+
**Important**: The price is stored in two parts: an integer mantissa value
92+
(the `price` field) and a power-of-ten `exponent`.
93+
<br /> The actual decimal representation of the price is given by: `decimal_price
94+
= price × 10^exponent`.
95+
<br /> For example: `1006900000000 × 10^(-8) = $10,069.00`
96+
</Callout>
97+
98+
## Property Specifications
99+
100+
Based on the protocol specification, here are the technical details for each property in a price feed:
101+
102+
### Feed Structure
103+
104+
- **Feed ID**: `u32` - Unique identifier for the price feed
105+
- **Properties**: Fields included based on your subscription request parameters
106+
107+
### Core Price Properties
108+
109+
#### Aggregate Market Price - `price`
110+
111+
Main aggregate price calculated from all contributing publishers
112+
113+
- **Type**: `optional non-zero i64` (mantissa representation)
114+
- **Availability**: Only included if requested in subscription properties
115+
- **Algorithm**: Refer to [price aggregation](../../price-feeds/how-pyth-works/price-aggregation) for the current algorithm
116+
- **Invariants**: Non-zero when present (null values filtered out)
117+
118+
#### Data Publisher Count - `publisher_count`
119+
120+
Number of data publishers contributing to this price feed
121+
122+
- **Type**: `u16`
123+
- **Availability**: Always included when any price properties are present
124+
- **Invariants**: Always positive for valid price feeds
125+
126+
#### Decimal Exponent - `exponent`
127+
128+
Decimal exponent for price conversion
129+
130+
- **Type**: `i16`
131+
- **Availability**: Always included when price properties are present
132+
- **Invariants**: Typically negative (e.g., -8 for USD prices, -18 for token prices)
133+
- **Usage**: Convert mantissa to actual price: `actual_price = mantissa × 10^exponent`
134+
- **Example**: With exponent `-8`, mantissa `1006900000000` becomes `$10,069.00`
135+
136+
#### Price Confidence Interval - `confidence`
137+
138+
Confidence interval representing price uncertainty
139+
140+
- **Type**: `optional i64` (mantissa representation)
141+
- **Availability**: Only included if requested in subscription properties
142+
- **Algorithm**: Refer to [price aggregation](../../price-feeds/how-pyth-works/price-aggregation) for the current algorithm
143+
- **Invariants**: Positive when present
144+
- **Usage**: Risk management and price quality assessment
145+
146+
### Market Depth Properties
147+
148+
#### Highest Market Bid - `best_bid_price`
149+
150+
Highest bid price across all contributing publishers
151+
152+
- **Type**: `optional non-zero i64` (mantissa representation)
153+
- **Availability**: Only included if requested in subscription properties
154+
- **Algorithm**: Refer to [price aggregation](../../price-feeds/how-pyth-works/price-aggregation) for the current algorithm
155+
- **Invariants**: Non-zero when present, typically ≤ current price
156+
157+
#### Lowest Market Ask - `best_ask_price`
158+
159+
Lowest ask price across all contributing publishers
160+
161+
- **Type**: `optional non-zero i64` (mantissa representation)
162+
- **Availability**: Only included if requested in subscription properties
163+
- **Algorithm**: Refer to [price aggregation](../../price-feeds/how-pyth-works/price-aggregation) for the current algorithm
164+
- **Invariants**: Non-zero when present, typically ≥ current price
165+
166+
### Derivatives Properties (FundingRate Feed Type Only)
167+
168+
#### Perpetual Futures Funding Rate - `funding_rate`
169+
170+
Current funding rate for perpetual futures contracts
171+
172+
- **Type**: `optional i64` (mantissa representation)
173+
- **Availability**: Only for FeedKind::FundingRate feeds, only if requested in subscription
174+
- **Invariants**: Can be positive (longs pay shorts) or negative (shorts pay longs)
175+
176+
#### Funding Payment Timestamp - `funding_timestamp`
177+
178+
Timestamp when funding rate was last calculated or applied
179+
180+
- **Type**: `optional u64` (microseconds)
181+
- **Availability**: Only for FeedKind::FundingRate feeds, only if requested in subscription
182+
- **Invariants**: Valid Unix timestamp in microseconds when present
183+
184+
#### Funding Update Interval - `funding_interval`
185+
186+
Duration between consecutive funding rate calculations
187+
188+
- **Type**: `optional u64` (microseconds)
189+
- **Availability**: Only for FeedKind::FundingRate feeds, only if requested in subscription
190+
- **Invariants**: Positive value when present
191+
- **Typical Values**: 28,800,000,000 microseconds (8 hours) for major exchanges
192+
193+
## Available Properties by Feed Types
194+
195+
Based on the [API documentation](https://pyth-lazer.dourolabs.app/docs), you can request specific properties when subscribing:
196+
197+
### Common Properties (All Feed Types)
198+
199+
- `publisherCount` - Number of contributing data publishers
200+
- `exponent` - Decimal exponent for proper price representation
201+
202+
### Spot Trading Properties
203+
204+
- `price` - Primary aggregate price for the asset
205+
- `confidence` - Price confidence interval for risk assessment
206+
- `bestBidPrice` - Highest bid across all publishers (market depth)
207+
- `bestAskPrice` - Lowest ask across all publishers (market depth)
208+
209+
### Derivatives Properties
210+
211+
- `fundingRate` - Current funding rate for perpetual futures
212+
- `fundingTimestamp` - Most recent funding rate timestamp
213+
- `fundingRateInterval` - Duration between funding updates
214+
215+
## Subscription Channels
216+
217+
Lazer offers multiple delivery channels to match your latency and frequency requirements:
218+
219+
| Channel | Description | Use Cases |
220+
| ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------------- |
221+
| `real_time` | Updates sent immediately when new price is available (no faster than 1ms, no slower than 50ms) | High-frequency trading, real-time analytics |
222+
| `fixed_rate@1ms` | Updates every 1 millisecond | Ultra-low latency applications |
223+
| `fixed_rate@50ms` | Updates every 50 milliseconds | Low-latency trading systems |
224+
| `fixed_rate@200ms` | Updates every 200 milliseconds | Standard trading applications |
225+
| `fixed_rate@1s` | Updates every 1 second | General applications, dashboards |
226+
227+
## Signature Schemes and Binary Formats
228+
229+
Lazer provides multiple cryptographic formats to support different blockchain ecosystems. When you subscribe, you can request specific binary formats in the `chains` parameter:
230+
231+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">
232+
233+
<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
234+
#### EVM Format (`evm`)
235+
236+
- **Algorithm**: secp256k1 ECDSA
237+
- **Hash Function**: Keccak-256
238+
- **Signature Size**: 65 bytes
239+
- **Verification**: Recoverable ECDSA with Ethereum address derivation
240+
241+
</div>
242+
243+
<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
244+
#### Solana Format (`solana`)
245+
246+
- **Algorithm**: Ed25519 EdDSA
247+
- **Signature Size**: 64 bytes
248+
- **Public Key Size**: 32 bytes
249+
- **Verification**: Direct Ed25519 signature verification
250+
251+
</div>
252+
253+
<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
254+
#### Little-Endian ECDSA (`leEcdsa`)
255+
256+
- **Algorithm**: secp256k1 ECDSA (little-endian)
257+
- **Hash Function**: Keccak-256
258+
- **Byte Order**: Little-endian encoding
259+
260+
**Perfect for**: Custom implementations requiring specific byte ordering
261+
262+
</div>
263+
264+
<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
265+
#### Unsigned Format (`leUnsigned`)
266+
267+
- **Signature**: None (raw payload)
268+
- **Use Cases**: Off-chain use, testing and development
269+
270+
</div>
271+
272+
</div>
273+
274+
<Callout type="info">
275+
**How to Choose**: Select the optimal signing algorithm for your use case.
276+
These formats are not blockchain-specific - for example, the `solana` format
277+
(Ed25519) has been used on non-SVM blockchains when Ed25519 was the most
278+
efficient algorithm for that specific chain. Choose `evm` for secp256k1 ECDSA,
279+
`solana` for Ed25519, `leEcdsa` for little-endian secp256k1, and `leUnsigned`
280+
for off-chain use.
281+
</Callout>

pages/lazer/subscribe-price-updates.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ Determine the most suitable values for your application -- they will be used in
5151

5252
### 3. Subscribe to the price updates
5353

54+
<Callout type="info">
55+
**Complete Payload Reference**: For understanding all fields and data types of
56+
Lazer payloads, see our [**Payload Reference**](/lazer/payload-reference)
57+
page.
58+
</Callout>
59+
5460
To subscribe to the price updates, send a request to the websocket server. The server will respond with a signed price update.
5561

5662
1. Pyth Lazer provides an [SDK](https://github.com/pyth-network/pyth-crosschain/tree/main/lazer/sdk/js) to seamlessly integrate the websocket API into your application.

0 commit comments

Comments
 (0)