|
| 1 | +import { Callout, Steps } from "nextra/components"; |
| 2 | + |
| 3 | +# How to Fetch Price Updates from Pyth Lazer |
| 4 | + |
| 5 | +Pyth Lazer provides a [websocket API (TODO: Prod)](https://pyth-lazer-staging.dourolabs.app/docs) to fetch price updates. |
| 6 | + |
| 7 | + |
| 8 | +This guide explains how to **fetch** price updates, explore various **properties** of these updates, and configure the channel for **update frequency**. (TODO: Rewrite maybe) |
| 9 | + |
| 10 | +Fetching price updates is a three-step process: |
| 11 | + |
| 12 | +1. **Acquire** an access token. |
| 13 | +2. **Adjust** subscription parameters. |
| 14 | +3. **Subscribe** to the price updates via websocket API. |
| 15 | + |
| 16 | +The websocket server is available at `wss://pyth-lazer-staging.dourolabs.app/v1/stream`. |
| 17 | +TODO: Add the prod URL. |
| 18 | + |
| 19 | +<Steps> |
| 20 | + |
| 21 | +### 1. Acquire an access token |
| 22 | + |
| 23 | +Please fill out [this form](https://tally.so/r/nP2lG5) to contact the Pyth team and get the access token. |
| 24 | + |
| 25 | +Use the access token to authenticate the websocket connection as a `Bearer {token}{:bash}`. |
| 26 | + |
| 27 | + |
| 28 | +### 2. Adjust subscription parameters |
| 29 | + |
| 30 | +One can configure the request/subscription parameters to customize the received price updates. A sample request is shown below: |
| 31 | + |
| 32 | +```json |
| 33 | + client.send({ |
| 34 | + type: "subscribe", |
| 35 | + subscriptionId: 1, |
| 36 | + priceFeedIds: [1, 2], |
| 37 | + properties: ["price"], |
| 38 | + chains: ["solana"], |
| 39 | + channel: "fixed_rate@200ms", |
| 40 | + }); |
| 41 | +``` |
| 42 | +Here: |
| 43 | + |
| 44 | +- `subscriptionId` is an arbitrary numeric identifier one can choose for a subscription. It will eb returned back in response by the server. It doesn not affect the signed payload. |
| 45 | +- `priceFeedIds` is the list of price feeds one like to receive. Data for all price feeds will be present in the signed price updates generated. Refer to the [Price Feed IDs list](./price-feeds.mdx) for the supported price feeds. |
| 46 | +- `properties` is the list of properties one can request, such as **price**, **bestBidPrice**, **bestAskPrice**, etc. TODO: Find more properties. |
| 47 | +- `chains` is the list of chains for which one need a signed payload, such as **evm**, **solana**, etc. |
| 48 | +- `channel` allows to configure the update rate: updates in the **real_time** channel are sent as frequently as possible, while **fixed_rate@200ms** and **fixed_rate@50ms** channels are updated at fixed rates. |
| 49 | + |
| 50 | +There are also a few other parameters one may use. Refer to the [API documentation](https://pyth-lazer-staging.dourolabs.app/docs) for more details. |
| 51 | + |
| 52 | +### 3. Subscribe to the price updates |
| 53 | + |
| 54 | +To subscribe to the price updates, one needs to send the request to the websocket server. The server will respond with a signed price update. |
| 55 | + |
| 56 | +1. Pyth Lazer provides a [SDK](https://github.com/pyth-network/pyth-crosschain/tree/main/lazer/sdk/js) to seamlessly integrate the websocket API into your application. |
| 57 | +It can be installed using the following command: |
| 58 | + |
| 59 | +```bash |
| 60 | +npm install --save @pythnetwork/pyth-lazer-sdk |
| 61 | +``` |
| 62 | + |
| 63 | +2. Then create a [`PythLazerClient`](https://github.com/pyth-network/pyth-crosschain/blob/main/lazer/sdk/js/src/client.ts#L32) object using the URL and the access token requested from the Pyth team in the first step. |
| 64 | + |
| 65 | +```js |
| 66 | +import { PythLazerClient } from "@pythnetwork/pyth-lazer-sdk"; |
| 67 | + |
| 68 | +const client = new PythLazerClient("wss://pyth-lazer-staging.dourolabs.app/v1/stream", "ctoken1"); |
| 69 | +``` |
| 70 | + |
| 71 | +3. After the client is created, one can adjust the subscription parameters and subscribe to the price updates. |
| 72 | + |
| 73 | +```js |
| 74 | +client.ws.addEventListener("open", () => { |
| 75 | + client.send({ |
| 76 | + type: "subscribe", |
| 77 | + subscriptionId: 1, |
| 78 | + priceFeedIds: [1, 2], |
| 79 | + properties: ["price"], |
| 80 | + chains: ["solana"], |
| 81 | + channel: "fixed_rate@200ms", |
| 82 | + }); |
| 83 | +}); |
| 84 | +``` |
| 85 | + |
| 86 | +4. One the connection is established, the server will start sending the price updates to the client. |
| 87 | + |
| 88 | +```js |
| 89 | +client.addMessageListener((message) => { |
| 90 | + console.log(message); |
| 91 | +}); |
| 92 | +``` |
| 93 | + |
| 94 | +By default, price updates contain the `parsed` field that one can use to easily interpret the update in their backend or frontend, as well as evm and/or solana fields that contain data that one should include in the on-chain transaction: |
| 95 | + |
| 96 | +```json |
| 97 | +{ |
| 98 | + "type": "streamUpdated", |
| 99 | + "subscriptionId": 1, |
| 100 | + "parsed": { |
| 101 | + "timestampUs": "1730986152400000", |
| 102 | + "priceFeeds": [ |
| 103 | + { |
| 104 | + "priceFeedId": 1, |
| 105 | + "price": "1006900000000" |
| 106 | + }, |
| 107 | + { |
| 108 | + "priceFeedId": 2, |
| 109 | + "price": "2006900000000" |
| 110 | + } |
| 111 | + ] |
| 112 | + }, |
| 113 | + "solana": { |
| 114 | + "encoding": "hex", |
| 115 | + "data": "b9011a82d239c094c52016990d6ca2b261dbb1157ad503cbd3ea0679493316150cf3457624d19ec3f6e0a0e94373ab0971e39d939beda15cc02eb3c5454eb700f1f7310df65210bee4fcf5b1cee1e537fabcfd95010297653b94af04d454fc473e94834f2a0075d3c7938094b99e52260600030201000000010000b5ea6fea00000002000000010000c58f44d3010000" |
| 116 | + } |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | + |
| 121 | + |
| 122 | +</Steps> |
0 commit comments