Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pages/lazer/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"title": "Reference Material",
"type": "separator"
},
"payload-reference": "Payload Reference",
"price-feed-ids": "Price Feed IDs",

"websocket-api-reference": {
Expand Down
265 changes: 265 additions & 0 deletions pages/lazer/payload-reference.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
import { Callout, Steps } from "nextra/components";

# Lazer Payload Reference

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.

<Callout type="info">
This reference is designed for both technical and non-technical stakeholders
to understand Pyth Lazer's data offering. For implementation details, see our
[integration guides](/lazer/integrate-as-consumer).
</Callout>

## What is a Lazer Payload?

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.

## Stream Response Structure

When you receive a `StreamUpdated` message from Lazer, it contains the following structure:

### Top-Level Response Fields

| Field | Type | Description |
| ---------------- | --------------- | ------------------------------------------------------ |
| `type` | `string` | Always `"streamUpdated"` for price updates |
| `subscriptionId` | `number` | Your subscription identifier |
| `parsed` | `ParsedPayload` | Human-readable price data (when `parsed: true`) |
| `evm` | `BinaryData` | EVM-compatible binary payload (when requested) |
| `solana` | `BinaryData` | Solana-compatible binary payload (when requested) |
| `leEcdsa` | `BinaryData` | Little-endian ECDSA binary payload (when requested) |
| `leUnsigned` | `BinaryData` | Little-endian unsigned binary payload (when requested) |

### Parsed Payload Structure

The `parsed` object contains human-readable price data:

| Field | Type | Description |
| ------------- | ------------------ | ---------------------------------------------------------- |
| `timestampUs` | `string` | Unix timestamp in microseconds when the data was generated |
| `priceFeeds` | `Array<PriceFeed>` | Array of price feed data objects |

## How Does a Price Feed Look?

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.

Here's what a typical price feed looks like in a Lazer response:

```json
{
"type": "streamUpdated",
"subscriptionId": 1,
"parsed": {
"timestampUs": "1758690761750000",
"priceFeeds": [
{
"priceFeedId": 1,
"price": "11223872331053",
"bestBidPrice": "11222498842767",
"bestAskPrice": "11224513591935",
"publisherCount": 9,
"exponent": -8,
"confidence": 1373488286
}
]
},
"evm": {
"encoding": "base64",
"data": "..."
}
}
```

<Callout type="warning">
**Important**: Price values are in mantissa format. To get the actual price,
use: `actual_price = mantissa × 10^exponent`. For example: `1006900000000 ×
10^(-8) = $10,069.00`
</Callout>

## Property Specifications

Based on the protocol specification, here are the technical details for each property in a price feed:

### Feed Structure

- **Feed ID**: `u32` - Unique identifier for the price feed
- **Properties**: Fields included based on your subscription request parameters

### Core Price Properties

#### Aggregate Market Price - `price`

Main aggregate price calculated from all contributing publishers

- **Type**: `optional non-zero i64` (mantissa representation)
- **Availability**: Only included if requested in subscription properties
- **Algorithm**: Robust statistical aggregation using median-based methods with outlier detection
- **Invariants**: Non-zero when present (null values filtered out)

#### Data Publisher Count - `publisher_count`

Number of data publishers contributing to this price feed

- **Type**: `u16`
- **Availability**: Always included when any price properties are present
- **Algorithm**: Count of publishers whose data passed validation and quality checks
- **Invariants**: Always positive for valid price feeds

#### Decimal Exponent - `exponent`

Decimal exponent for price conversion

- **Type**: `i16`
- **Availability**: Always included when price properties are present
- **Algorithm**: Determines decimal placement for all price values in the feed
- **Invariants**: Typically negative (e.g., -8 for USD prices, -18 for token prices)
- **Usage**: Convert mantissa to actual price: `actual_price = mantissa × 10^exponent`
- **Example**: With exponent `-8`, mantissa `1006900000000` becomes `$10,069.00`

#### Price Confidence Interval - `confidence`

Confidence interval representing price uncertainty

- **Type**: `optional i64` (mantissa representation)
- **Availability**: Only included if requested in subscription properties
- **Algorithm**: Statistical measure derived from publisher price variance and market volatility
- **Invariants**: Positive when present
- **Usage**: Risk management and price quality assessment

### Market Depth Properties

#### Highest Market Bid - `best_bid_price`

Highest bid price across all contributing publishers

- **Type**: `optional non-zero i64` (mantissa representation)
- **Availability**: Only included if requested in subscription properties
- **Algorithm**: Maximum bid price from all publishers with active order book data
- **Invariants**: Non-zero when present, typically ≤ current price

#### Lowest Market Ask - `best_ask_price`

Lowest ask price across all contributing publishers

- **Type**: `optional non-zero i64` (mantissa representation)
- **Availability**: Only included if requested in subscription properties
- **Algorithm**: Minimum ask price from all publishers with active order book data
- **Invariants**: Non-zero when present, typically ≥ current price

### Derivatives Properties (FundingRate Feed Type Only)

#### Perpetual Futures Funding Rate - `funding_rate`

Current funding rate for perpetual futures contracts

- **Type**: `optional i64` (mantissa representation)
- **Availability**: Only for FeedKind::FundingRate feeds, only if requested in subscription
- **Algorithm**: Interest rate differential: `(PerpetualsPrice - IndexPrice) / IndexPrice`
- **Invariants**: Can be positive (longs pay shorts) or negative (shorts pay longs)

#### Funding Payment Timestamp - `funding_timestamp`

Timestamp when funding rate was last calculated or applied

- **Type**: `optional u64` (microseconds)
- **Availability**: Only for FeedKind::FundingRate feeds, only if requested in subscription
- **Invariants**: Valid Unix timestamp in microseconds when present

#### Funding Update Interval - `funding_interval`

Duration between consecutive funding rate calculations

- **Type**: `optional u64` (microseconds)
- **Availability**: Only for FeedKind::FundingRate feeds, only if requested in subscription
- **Invariants**: Positive value when present
- **Typical Values**: 28,800,000,000 microseconds (8 hours) for major exchanges

## Available Properties by Feed Types

Based on the [API documentation](https://pyth-lazer.dourolabs.app/docs), you can request specific properties when subscribing:

### Common Properties (All Feed Types)

- `publisherCount` - Number of contributing data publishers
- `exponent` - Decimal exponent for proper price representation

### Spot Trading Properties

- `price` - Primary aggregate price for the asset
- `confidence` - Price confidence interval for risk assessment
- `bestBidPrice` - Highest bid across all publishers (market depth)
- `bestAskPrice` - Lowest ask across all publishers (market depth)

### Derivatives Properties

- `fundingRate` - Current funding rate for perpetual futures
- `fundingTimestamp` - Most recent funding rate timestamp
- `fundingRateInterval` - Duration between funding updates

<Callout type="info">
**Subscription Flexibility**: You only receive the properties you request in
your subscription, optimizing bandwidth and processing.
</Callout>

## Subscription Channels

Lazer offers multiple delivery channels to match your latency and frequency requirements:

| Channel | Description | Use Cases |
| ------------------ | --------------------------------------- | ------------------------------------------- |
| `real_time` | Updates sent immediately when available | High-frequency trading, real-time analytics |
| `fixed_rate@1ms` | Updates every 1 millisecond | Ultra-low latency applications |
| `fixed_rate@50ms` | Updates every 50 milliseconds | Low-latency trading systems |
| `fixed_rate@200ms` | Updates every 200 milliseconds | Standard trading applications |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a 1s channel now too

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also real_time updates immediately when a new price is available, no faster than 1ms and no slower than 50ms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, 1s channel got added.

I have added 1s and the description in real_time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open to change the use case for real_time if it doesn't go well. @tejasbadadare


## Signature Schemes and Binary Formats

Lazer provides multiple cryptographic formats to support different blockchain ecosystems. When you subscribe, you can request specific binary formats in the `chains` parameter:

<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">

<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
#### EVM Format (`evm`)

- **Algorithm**: secp256k1 ECDSA
- **Hash Function**: Keccak-256
- **Signature Size**: 65 bytes
- **Verification**: Recoverable ECDSA with Ethereum address derivation

</div>

<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
#### Solana Format (`solana`)

- **Algorithm**: Ed25519 EdDSA
- **Signature Size**: 64 bytes
- **Public Key Size**: 32 bytes
- **Verification**: Direct Ed25519 signature verification

</div>

<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
#### Little-Endian ECDSA (`leEcdsa`)

- **Algorithm**: secp256k1 ECDSA (little-endian)
- **Hash Function**: Keccak-256
- **Byte Order**: Little-endian encoding

**Perfect for**: Custom implementations requiring specific byte ordering

</div>

<div className="p-6 bg-gray-50 dark:bg-darkGray rounded-lg border border-gray-200 dark:border-gray-700">
#### Unsigned Format (`leUnsigned`)

- **Signature**: None (raw payload)
- **Use Cases**: Off-chain use, testing and development

</div>

</div>

<Callout type="info">
**How to Choose**: Use `evm` for Ethereum-compatible chains, `solana` for
Solana, `leEcdsa` for custom implementations, and `leUnsigned` for off-chain.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mention to choose the optimal signing algorithm for your use case. The formats are not blockchain specific. (We should have named this field better from the start and not mentioned specific chains.)

For example, we've used the solana format in non-SVM blockchains since Ed25519 was the most efficient algo for that specific chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh got it, can you provide details to be added to How to Choose as in how they can decide on the basis of their use case ? so this section can be useful to the folks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the How to Choose section specifying the details provided above, hoping that will help the users.

</Callout>
6 changes: 6 additions & 0 deletions pages/lazer/subscribe-price-updates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ Determine the most suitable values for your application -- they will be used in

### 3. Subscribe to the price updates

<Callout type="info">
**Complete Payload Reference**: For understanding all fields and data types of
Lazer payloads, see our [**Payload Reference**](/lazer/payload-reference)
page.
</Callout>

To subscribe to the price updates, send a request to the websocket server. The server will respond with a signed price update.

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.
Expand Down
Loading