|
| 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> |
0 commit comments