Skip to content

Commit b8ae225

Browse files
feat(pyth-lazer-stk): correctly handle connection drops + other improvements (#2737)
* fix: pyth lazer js sdk * increase version * make resilient websocket configurable * fix: config types * handle onError * fix * fix example * fix * fix format * fix typo * fix format
1 parent cac91dd commit b8ae225

File tree

5 files changed

+202
-199
lines changed

5 files changed

+202
-199
lines changed

lazer/sdk/js/examples/index.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,24 @@ import { PythLazerClient } from "../src/index.js";
66
// Ignore debug messages
77
console.debug = () => {};
88

9-
const client = await PythLazerClient.create(
10-
["wss://pyth-lazer.dourolabs.app/v1/stream"],
11-
"access_token",
12-
3, // Optionally specify number of parallel redundant connections to reduce the chance of dropped messages. The connections will round-robin across the provided URLs. Default is 3.
13-
console, // Optionally log socket operations (to the console in this case.)
14-
);
9+
const client = await PythLazerClient.create({
10+
urls: [
11+
"wss://pyth-lazer-0.dourolabs.app/v1/stream",
12+
"wss://pyth-lazer-1.dourolabs.app/v1/stream",
13+
],
14+
token: "you-access-token-here", // Replace with your actual access token
15+
numConnections: 4, // Optionally specify number of parallel redundant connections to reduce the chance of dropped messages. The connections will round-robin across the provided URLs. Default is 4.
16+
logger: console, // Optionally log socket operations (to the console in this case.)
17+
onError: (error) => {
18+
console.error("WebSocket error:", error);
19+
},
20+
// Optional configuration for resilient WebSocket connections
21+
rwsConfig: {
22+
heartbeatTimeoutDurationMs: 5000, // Optional heartbeat timeout duration in milliseconds
23+
maxRetryDelayMs: 1000, // Optional maximum retry delay in milliseconds
24+
logAfterRetryCount: 10, // Optional log after how many retries
25+
},
26+
});
1527

1628
// Read and process messages from the Lazer stream
1729
client.addMessageListener((message) => {
@@ -47,7 +59,7 @@ client.addAllConnectionsDownListener(() => {
4759
});
4860

4961
// Create and remove one or more subscriptions on the fly
50-
await client.subscribe({
62+
client.subscribe({
5163
type: "subscribe",
5264
subscriptionId: 1,
5365
priceFeedIds: [1, 2],
@@ -58,7 +70,7 @@ await client.subscribe({
5870
parsed: false,
5971
jsonBinaryEncoding: "base64",
6072
});
61-
await client.subscribe({
73+
client.subscribe({
6274
type: "subscribe",
6375
subscriptionId: 2,
6476
priceFeedIds: [1, 2, 3, 4, 5],
@@ -72,6 +84,6 @@ await client.subscribe({
7284

7385
await new Promise((resolve) => setTimeout(resolve, 10_000));
7486

75-
await client.unsubscribe(1);
76-
await client.unsubscribe(2);
87+
client.unsubscribe(1);
88+
client.unsubscribe(2);
7789
client.shutdown();

lazer/sdk/js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pythnetwork/pyth-lazer-sdk",
3-
"version": "0.5.1",
3+
"version": "1.0.0",
44
"description": "Pyth Lazer SDK",
55
"publishConfig": {
66
"access": "public"

lazer/sdk/js/src/client.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import WebSocket from "isomorphic-ws";
2-
import type { Logger } from "ts-log";
3-
import { dummyLogger } from "ts-log";
42

53
import type { ParsedPayload, Request, Response } from "./protocol.js";
64
import { BINARY_UPDATE_FORMAT_MAGIC_LE, FORMAT_MAGICS_LE } from "./protocol.js";
5+
import type { WebSocketPoolConfig } from "./socket/websocket-pool.js";
76
import { WebSocketPool } from "./socket/websocket-pool.js";
87

98
export type BinaryResponse = {
@@ -35,13 +34,8 @@ export class PythLazerClient {
3534
* @param numConnections - The number of parallel WebSocket connections to establish (default: 3). A higher number gives a more reliable stream. The connections will round-robin across the provided URLs.
3635
* @param logger - Optional logger to get socket level logs. Compatible with most loggers such as the built-in console and `bunyan`.
3736
*/
38-
static async create(
39-
urls: string[],
40-
token: string,
41-
numConnections = 3,
42-
logger: Logger = dummyLogger,
43-
): Promise<PythLazerClient> {
44-
const wsp = await WebSocketPool.create(urls, token, numConnections, logger);
37+
static async create(config: WebSocketPoolConfig): Promise<PythLazerClient> {
38+
const wsp = await WebSocketPool.create(config);
4539
return new PythLazerClient(wsp);
4640
}
4741

@@ -102,19 +96,19 @@ export class PythLazerClient {
10296
});
10397
}
10498

105-
async subscribe(request: Request): Promise<void> {
99+
subscribe(request: Request) {
106100
if (request.type !== "subscribe") {
107101
throw new Error("Request must be a subscribe request");
108102
}
109-
await this.wsp.addSubscription(request);
103+
this.wsp.addSubscription(request);
110104
}
111105

112-
async unsubscribe(subscriptionId: number): Promise<void> {
113-
await this.wsp.removeSubscription(subscriptionId);
106+
unsubscribe(subscriptionId: number) {
107+
this.wsp.removeSubscription(subscriptionId);
114108
}
115109

116-
async send(request: Request): Promise<void> {
117-
await this.wsp.sendRequest(request);
110+
send(request: Request) {
111+
this.wsp.sendRequest(request);
118112
}
119113

120114
/**

0 commit comments

Comments
 (0)