@pythnetwork/pyth-lazer-sdk 5.0.0 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{client.js → client.cjs} +93 -98
- package/dist/cjs/constants.cjs +36 -0
- package/dist/cjs/emitter/index.cjs +53 -0
- package/dist/cjs/emitter/index.d.ts +29 -0
- package/dist/cjs/index.cjs +20 -0
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/protocol.cjs +33 -0
- package/dist/cjs/protocol.d.ts +1 -1
- package/dist/cjs/socket/{resilient-websocket.js → resilient-websocket.cjs} +47 -48
- package/dist/cjs/socket/websocket-pool.cjs +253 -0
- package/dist/cjs/socket/websocket-pool.d.ts +37 -3
- package/dist/cjs/util/{buffer-util.js → buffer-util.cjs} +14 -14
- package/dist/cjs/util/env-util.cjs +33 -0
- package/dist/cjs/util/index.cjs +20 -0
- package/dist/cjs/util/url-util.cjs +17 -0
- package/dist/esm/{client.js → client.mjs} +76 -88
- package/dist/esm/emitter/index.d.ts +29 -0
- package/dist/esm/emitter/index.mjs +43 -0
- package/dist/esm/index.mjs +3 -0
- package/dist/esm/package.json +1 -1
- package/dist/esm/protocol.d.ts +1 -1
- package/dist/esm/{protocol.js → protocol.mjs} +4 -4
- package/dist/esm/socket/{resilient-websocket.js → resilient-websocket.mjs} +27 -36
- package/dist/esm/socket/websocket-pool.d.ts +37 -3
- package/dist/esm/socket/websocket-pool.mjs +238 -0
- package/dist/esm/util/{buffer-util.js → buffer-util.mjs} +3 -6
- package/dist/esm/util/{env-util.js → env-util.mjs} +4 -8
- package/dist/esm/util/index.mjs +3 -0
- package/dist/esm/util/{url-util.js → url-util.mjs} +2 -4
- package/package.json +119 -15
- package/dist/cjs/constants.js +0 -9
- package/dist/cjs/index.js +0 -19
- package/dist/cjs/protocol.js +0 -15
- package/dist/cjs/socket/websocket-pool.js +0 -201
- package/dist/cjs/util/env-util.js +0 -32
- package/dist/cjs/util/index.js +0 -19
- package/dist/cjs/util/url-util.js +0 -18
- package/dist/esm/index.js +0 -3
- package/dist/esm/socket/websocket-pool.js +0 -195
- package/dist/esm/util/index.js +0 -3
- /package/dist/esm/{constants.js → constants.mjs} +0 -0
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "PythLazerClient", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return PythLazerClient;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _tslog = require("ts-log");
|
|
12
|
+
const _constants = require("./constants.cjs");
|
|
13
|
+
const _protocol = require("./protocol.cjs");
|
|
14
|
+
const _websocketpool = require("./socket/websocket-pool.cjs");
|
|
15
|
+
const _bufferutil = require("./util/buffer-util.cjs");
|
|
9
16
|
const UINT16_NUM_BYTES = 2;
|
|
10
17
|
const UINT32_NUM_BYTES = 4;
|
|
11
18
|
const UINT64_NUM_BYTES = 8;
|
|
@@ -15,7 +22,7 @@ class PythLazerClient {
|
|
|
15
22
|
priceServiceUrl;
|
|
16
23
|
logger;
|
|
17
24
|
wsp;
|
|
18
|
-
constructor(token, metadataServiceUrl, priceServiceUrl, logger, wsp)
|
|
25
|
+
constructor(token, metadataServiceUrl, priceServiceUrl, logger, wsp){
|
|
19
26
|
this.token = token;
|
|
20
27
|
this.metadataServiceUrl = metadataServiceUrl;
|
|
21
28
|
this.priceServiceUrl = priceServiceUrl;
|
|
@@ -23,91 +30,82 @@ class PythLazerClient {
|
|
|
23
30
|
this.wsp = wsp;
|
|
24
31
|
}
|
|
25
32
|
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
getWebSocketPool() {
|
|
33
|
+
* Gets the WebSocket pool. If the WebSocket pool is not configured, an error is thrown.
|
|
34
|
+
* @throws Error if WebSocket pool is not configured
|
|
35
|
+
* @returns The WebSocket pool
|
|
36
|
+
*/ getWebSocketPool() {
|
|
31
37
|
if (!this.wsp) {
|
|
32
38
|
throw new Error("WebSocket pool is not available. Make sure to provide webSocketPoolConfig when creating the client.");
|
|
33
39
|
}
|
|
34
40
|
return this.wsp;
|
|
35
41
|
}
|
|
36
42
|
/**
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
static async create(config) {
|
|
43
|
+
* Creates a new PythLazerClient instance.
|
|
44
|
+
* @param config - Configuration including token, metadata service URL, and price service URL, and WebSocket pool configuration
|
|
45
|
+
*/ static async create(config) {
|
|
41
46
|
const token = config.token;
|
|
42
47
|
// Collect and remove trailing slash from URLs
|
|
43
|
-
const metadataServiceUrl = (config.metadataServiceUrl ??
|
|
44
|
-
const priceServiceUrl = (config.priceServiceUrl ??
|
|
45
|
-
const logger = config.logger ??
|
|
48
|
+
const metadataServiceUrl = (config.metadataServiceUrl ?? _constants.DEFAULT_METADATA_SERVICE_URL).replace(/\/+$/, "");
|
|
49
|
+
const priceServiceUrl = (config.priceServiceUrl ?? _constants.DEFAULT_PRICE_SERVICE_URL).replace(/\/+$/, "");
|
|
50
|
+
const logger = config.logger ?? _tslog.dummyLogger;
|
|
46
51
|
// If webSocketPoolConfig is provided, create a WebSocket pool and block until at least one connection is established.
|
|
47
52
|
let wsp;
|
|
48
53
|
if (config.webSocketPoolConfig) {
|
|
49
|
-
wsp = await
|
|
54
|
+
wsp = await _websocketpool.WebSocketPool.create(config.webSocketPoolConfig, token, logger);
|
|
50
55
|
}
|
|
51
56
|
return new PythLazerClient(token, metadataServiceUrl, priceServiceUrl, logger, wsp);
|
|
52
57
|
}
|
|
53
58
|
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
addMessageListener(handler) {
|
|
59
|
+
* Adds a message listener that receives either JSON or binary responses from the WebSocket connections.
|
|
60
|
+
* The listener will be called for each message received, with deduplication across redundant connections.
|
|
61
|
+
* @param handler - Callback function that receives the parsed message. The message can be either a JSON response
|
|
62
|
+
* or a binary response containing EVM, Solana, or parsed payload data.
|
|
63
|
+
*/ addMessageListener(handler) {
|
|
60
64
|
const wsp = this.getWebSocketPool();
|
|
61
|
-
wsp.addMessageListener(async (data)
|
|
65
|
+
wsp.addMessageListener(async (data)=>{
|
|
62
66
|
if (typeof data == "string") {
|
|
63
67
|
handler({
|
|
64
68
|
type: "json",
|
|
65
|
-
value: JSON.parse(data)
|
|
69
|
+
value: JSON.parse(data)
|
|
66
70
|
});
|
|
67
71
|
return;
|
|
68
72
|
}
|
|
69
|
-
const buffData = await (0,
|
|
73
|
+
const buffData = await (0, _bufferutil.bufferFromWebsocketData)(data);
|
|
70
74
|
let pos = 0;
|
|
71
|
-
const magic = buffData
|
|
72
|
-
.subarray(pos, pos + UINT32_NUM_BYTES)
|
|
73
|
-
.readUint32LE();
|
|
75
|
+
const magic = buffData.subarray(pos, pos + UINT32_NUM_BYTES).readUint32LE();
|
|
74
76
|
pos += UINT32_NUM_BYTES;
|
|
75
|
-
if (magic !=
|
|
77
|
+
if (magic != _protocol.BINARY_UPDATE_FORMAT_MAGIC_LE) {
|
|
76
78
|
throw new Error("binary update format magic mismatch");
|
|
77
79
|
}
|
|
78
80
|
// TODO: some uint64 values may not be representable as Number.
|
|
79
81
|
const subscriptionId = Number(buffData.subarray(pos, pos + UINT64_NUM_BYTES).readBigInt64BE());
|
|
80
82
|
pos += UINT64_NUM_BYTES;
|
|
81
|
-
const value = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const value = {
|
|
84
|
+
subscriptionId
|
|
85
|
+
};
|
|
86
|
+
while(pos < buffData.length){
|
|
87
|
+
const len = buffData.subarray(pos, pos + UINT16_NUM_BYTES).readUint16BE();
|
|
86
88
|
pos += UINT16_NUM_BYTES;
|
|
87
|
-
const magic = buffData
|
|
88
|
-
|
|
89
|
-
.readUint32LE();
|
|
90
|
-
if (magic == protocol_js_1.FORMAT_MAGICS_LE.EVM) {
|
|
89
|
+
const magic = buffData.subarray(pos, pos + UINT32_NUM_BYTES).readUint32LE();
|
|
90
|
+
if (magic == _protocol.FORMAT_MAGICS_LE.EVM) {
|
|
91
91
|
value.evm = buffData.subarray(pos, pos + len);
|
|
92
|
-
}
|
|
93
|
-
else if (magic == protocol_js_1.FORMAT_MAGICS_LE.SOLANA) {
|
|
92
|
+
} else if (magic == _protocol.FORMAT_MAGICS_LE.SOLANA) {
|
|
94
93
|
value.solana = buffData.subarray(pos, pos + len);
|
|
95
|
-
}
|
|
96
|
-
else if (magic == protocol_js_1.FORMAT_MAGICS_LE.LE_ECDSA) {
|
|
94
|
+
} else if (magic == _protocol.FORMAT_MAGICS_LE.LE_ECDSA) {
|
|
97
95
|
value.leEcdsa = buffData.subarray(pos, pos + len);
|
|
98
|
-
}
|
|
99
|
-
else if (magic == protocol_js_1.FORMAT_MAGICS_LE.LE_UNSIGNED) {
|
|
96
|
+
} else if (magic == _protocol.FORMAT_MAGICS_LE.LE_UNSIGNED) {
|
|
100
97
|
value.leUnsigned = buffData.subarray(pos, pos + len);
|
|
101
|
-
}
|
|
102
|
-
else if (magic == protocol_js_1.FORMAT_MAGICS_LE.JSON) {
|
|
98
|
+
} else if (magic == _protocol.FORMAT_MAGICS_LE.JSON) {
|
|
103
99
|
value.parsed = JSON.parse(buffData.subarray(pos + UINT32_NUM_BYTES, pos + len).toString());
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
100
|
+
} else {
|
|
106
101
|
throw new Error(`unknown magic: ${magic.toString()}`);
|
|
107
102
|
}
|
|
108
103
|
pos += len;
|
|
109
104
|
}
|
|
110
|
-
handler({
|
|
105
|
+
handler({
|
|
106
|
+
type: "binary",
|
|
107
|
+
value
|
|
108
|
+
});
|
|
111
109
|
});
|
|
112
110
|
}
|
|
113
111
|
subscribe(request) {
|
|
@@ -126,11 +124,10 @@ class PythLazerClient {
|
|
|
126
124
|
wsp.sendRequest(request);
|
|
127
125
|
}
|
|
128
126
|
/**
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
addAllConnectionsDownListener(handler) {
|
|
127
|
+
* Registers a handler function that will be called whenever all WebSocket connections are down or attempting to reconnect.
|
|
128
|
+
* The connections may still try to reconnect in the background. To shut down the pool, call `shutdown()`.
|
|
129
|
+
* @param handler - Function to be called when all connections are down
|
|
130
|
+
*/ addAllConnectionsDownListener(handler) {
|
|
134
131
|
const wsp = this.getWebSocketPool();
|
|
135
132
|
wsp.addAllConnectionsDownListener(handler);
|
|
136
133
|
}
|
|
@@ -139,27 +136,25 @@ class PythLazerClient {
|
|
|
139
136
|
wsp.shutdown();
|
|
140
137
|
}
|
|
141
138
|
/**
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
async authenticatedFetch(url, options = {}) {
|
|
139
|
+
* Private helper method to make authenticated HTTP requests with Bearer token
|
|
140
|
+
* @param url - The URL to fetch
|
|
141
|
+
* @param options - Additional fetch options
|
|
142
|
+
* @returns Promise resolving to the fetch Response
|
|
143
|
+
*/ async authenticatedFetch(url, options = {}) {
|
|
148
144
|
const headers = {
|
|
149
145
|
Authorization: `Bearer ${this.token}`,
|
|
150
|
-
...options.headers
|
|
146
|
+
...options.headers
|
|
151
147
|
};
|
|
152
148
|
return fetch(url, {
|
|
153
149
|
...options,
|
|
154
|
-
headers
|
|
150
|
+
headers
|
|
155
151
|
});
|
|
156
152
|
}
|
|
157
153
|
/**
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
async getSymbols(params) {
|
|
154
|
+
* Queries the symbols endpoint to get available price feed symbols.
|
|
155
|
+
* @param params - Optional query parameters to filter symbols
|
|
156
|
+
* @returns Promise resolving to array of symbol information
|
|
157
|
+
*/ async getSymbols(params) {
|
|
163
158
|
const url = new URL(`${this.metadataServiceUrl}/v1/symbols`);
|
|
164
159
|
if (params?.query) {
|
|
165
160
|
url.searchParams.set("query", params.query);
|
|
@@ -172,63 +167,63 @@ class PythLazerClient {
|
|
|
172
167
|
if (!response.ok) {
|
|
173
168
|
throw new Error(`HTTP error! status: ${String(response.status)} - ${await response.text()}`);
|
|
174
169
|
}
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
170
|
+
return await response.json();
|
|
171
|
+
} catch (error) {
|
|
178
172
|
throw new Error(`Failed to fetch symbols: ${error instanceof Error ? error.message : String(error)}`);
|
|
179
173
|
}
|
|
180
174
|
}
|
|
181
175
|
/**
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
async getLatestPrice(params) {
|
|
176
|
+
* Queries the latest price endpoint to get current price data.
|
|
177
|
+
* @param params - Parameters for the latest price request
|
|
178
|
+
* @returns Promise resolving to JsonUpdate with current price data
|
|
179
|
+
*/ async getLatestPrice(params) {
|
|
187
180
|
const url = `${this.priceServiceUrl}/v1/latest_price`;
|
|
188
181
|
try {
|
|
189
182
|
const body = JSON.stringify(params);
|
|
190
|
-
this.logger.debug("getLatestPrice", {
|
|
183
|
+
this.logger.debug("getLatestPrice", {
|
|
184
|
+
url,
|
|
185
|
+
body
|
|
186
|
+
});
|
|
191
187
|
const response = await this.authenticatedFetch(url, {
|
|
192
188
|
method: "POST",
|
|
193
189
|
headers: {
|
|
194
|
-
"Content-Type": "application/json"
|
|
190
|
+
"Content-Type": "application/json"
|
|
195
191
|
},
|
|
196
|
-
body: body
|
|
192
|
+
body: body
|
|
197
193
|
});
|
|
198
194
|
if (!response.ok) {
|
|
199
195
|
throw new Error(`HTTP error! status: ${String(response.status)} - ${await response.text()}`);
|
|
200
196
|
}
|
|
201
|
-
return
|
|
202
|
-
}
|
|
203
|
-
catch (error) {
|
|
197
|
+
return await response.json();
|
|
198
|
+
} catch (error) {
|
|
204
199
|
throw new Error(`Failed to fetch latest price: ${error instanceof Error ? error.message : String(error)}`);
|
|
205
200
|
}
|
|
206
201
|
}
|
|
207
202
|
/**
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
async getPrice(params) {
|
|
203
|
+
* Queries the price endpoint to get historical price data at a specific timestamp.
|
|
204
|
+
* @param params - Parameters for the price request including timestamp
|
|
205
|
+
* @returns Promise resolving to JsonUpdate with price data at the specified time
|
|
206
|
+
*/ async getPrice(params) {
|
|
213
207
|
const url = `${this.priceServiceUrl}/v1/price`;
|
|
214
208
|
try {
|
|
215
209
|
const body = JSON.stringify(params);
|
|
216
|
-
this.logger.debug("getPrice", {
|
|
210
|
+
this.logger.debug("getPrice", {
|
|
211
|
+
url,
|
|
212
|
+
body
|
|
213
|
+
});
|
|
217
214
|
const response = await this.authenticatedFetch(url, {
|
|
218
215
|
method: "POST",
|
|
219
216
|
headers: {
|
|
220
|
-
"Content-Type": "application/json"
|
|
217
|
+
"Content-Type": "application/json"
|
|
221
218
|
},
|
|
222
|
-
body: body
|
|
219
|
+
body: body
|
|
223
220
|
});
|
|
224
221
|
if (!response.ok) {
|
|
225
222
|
throw new Error(`HTTP error! status: ${String(response.status)} - ${await response.text()}`);
|
|
226
223
|
}
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
catch (error) {
|
|
224
|
+
return await response.json();
|
|
225
|
+
} catch (error) {
|
|
230
226
|
throw new Error(`Failed to fetch price: ${error instanceof Error ? error.message : String(error)}`);
|
|
231
227
|
}
|
|
232
228
|
}
|
|
233
229
|
}
|
|
234
|
-
exports.PythLazerClient = PythLazerClient;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get DEFAULT_METADATA_SERVICE_URL () {
|
|
13
|
+
return DEFAULT_METADATA_SERVICE_URL;
|
|
14
|
+
},
|
|
15
|
+
get DEFAULT_PRICE_SERVICE_URL () {
|
|
16
|
+
return DEFAULT_PRICE_SERVICE_URL;
|
|
17
|
+
},
|
|
18
|
+
get DEFAULT_STREAM_SERVICE_0_URL () {
|
|
19
|
+
return DEFAULT_STREAM_SERVICE_0_URL;
|
|
20
|
+
},
|
|
21
|
+
get DEFAULT_STREAM_SERVICE_1_URL () {
|
|
22
|
+
return DEFAULT_STREAM_SERVICE_1_URL;
|
|
23
|
+
},
|
|
24
|
+
get SOLANA_LAZER_PROGRAM_ID () {
|
|
25
|
+
return SOLANA_LAZER_PROGRAM_ID;
|
|
26
|
+
},
|
|
27
|
+
get SOLANA_LAZER_STORAGE_ID () {
|
|
28
|
+
return SOLANA_LAZER_STORAGE_ID;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const SOLANA_LAZER_PROGRAM_ID = "pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt";
|
|
32
|
+
const SOLANA_LAZER_STORAGE_ID = "3rdJbqfnagQ4yx9HXJViD4zc4xpiSqmFsKpPuSCQVyQL";
|
|
33
|
+
const DEFAULT_METADATA_SERVICE_URL = "https://history.pyth-lazer.dourolabs.app/history";
|
|
34
|
+
const DEFAULT_PRICE_SERVICE_URL = "https://pyth-lazer-0.dourolabs.app";
|
|
35
|
+
const DEFAULT_STREAM_SERVICE_0_URL = "wss://pyth-lazer-0.dourolabs.app/v1/stream";
|
|
36
|
+
const DEFAULT_STREAM_SERVICE_1_URL = "wss://pyth-lazer-1.dourolabs.app/v1/stream";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T defines the "Event Map".
|
|
3
|
+
* Example: `{ 'data': (payload: string) => void; 'error': (err: Error) => void; }`
|
|
4
|
+
*/ "use strict";
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports, "IsomorphicEventEmitter", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function() {
|
|
11
|
+
return IsomorphicEventEmitter;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
class IsomorphicEventEmitter {
|
|
15
|
+
listeners = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* Register a callback for a specific event.
|
|
18
|
+
*/ on(eventName, callback) {
|
|
19
|
+
const currentListeners = this.listeners.get(eventName) ?? [];
|
|
20
|
+
this.listeners.set(eventName, [
|
|
21
|
+
...currentListeners,
|
|
22
|
+
callback
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Registers a callback for a specific event that
|
|
27
|
+
* will only be executed a single time i.e. the first occurence.
|
|
28
|
+
* After this, the handler will be automatically removed and cleaned up.
|
|
29
|
+
*/ once(eventName, callback) {
|
|
30
|
+
const wrappedCallback = (...args)=>{
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
32
|
+
callback(...args);
|
|
33
|
+
this.off(eventName, wrappedCallback);
|
|
34
|
+
};
|
|
35
|
+
this.on(eventName, wrappedCallback);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Remove a callback from a specific event.
|
|
39
|
+
* If no specific callback is specified when off() is called,
|
|
40
|
+
* ALL event handler callbacks for the given eventName will be removed
|
|
41
|
+
* at once.
|
|
42
|
+
*/ off(eventName, callback) {
|
|
43
|
+
const cbIsFunc = typeof callback === "function";
|
|
44
|
+
const currentListeners = this.listeners.get(eventName) ?? [];
|
|
45
|
+
this.listeners.set(eventName, currentListeners.filter((cb)=>cbIsFunc && cb !== callback));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Protected method to retrieve listeners for internal triggering.
|
|
49
|
+
* This allows the child class to decide how/when to execute them.
|
|
50
|
+
*/ getListeners(eventName) {
|
|
51
|
+
return this.listeners.get(eventName) ?? [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T defines the "Event Map".
|
|
3
|
+
* Example: `{ 'data': (payload: string) => void; 'error': (err: Error) => void; }`
|
|
4
|
+
*/
|
|
5
|
+
export declare abstract class IsomorphicEventEmitter<T extends Record<string, (...args: any[]) => void>> {
|
|
6
|
+
private listeners;
|
|
7
|
+
/**
|
|
8
|
+
* Register a callback for a specific event.
|
|
9
|
+
*/
|
|
10
|
+
on<K extends keyof T>(eventName: K, callback: T[K]): void;
|
|
11
|
+
/**
|
|
12
|
+
* Registers a callback for a specific event that
|
|
13
|
+
* will only be executed a single time i.e. the first occurence.
|
|
14
|
+
* After this, the handler will be automatically removed and cleaned up.
|
|
15
|
+
*/
|
|
16
|
+
once<K extends keyof T>(eventName: K, callback: T[K]): void;
|
|
17
|
+
/**
|
|
18
|
+
* Remove a callback from a specific event.
|
|
19
|
+
* If no specific callback is specified when off() is called,
|
|
20
|
+
* ALL event handler callbacks for the given eventName will be removed
|
|
21
|
+
* at once.
|
|
22
|
+
*/
|
|
23
|
+
off<K extends keyof T>(eventName: K, callback?: T[K]): void;
|
|
24
|
+
/**
|
|
25
|
+
* Protected method to retrieve listeners for internal triggering.
|
|
26
|
+
* This allows the child class to decide how/when to execute them.
|
|
27
|
+
*/
|
|
28
|
+
protected getListeners<K extends keyof T>(eventName: K): T[K][];
|
|
29
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./client.cjs"), exports);
|
|
6
|
+
_export_star(require("./protocol.cjs"), exports);
|
|
7
|
+
_export_star(require("./constants.cjs"), exports);
|
|
8
|
+
function _export_star(from, to) {
|
|
9
|
+
Object.keys(from).forEach(function(k) {
|
|
10
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
11
|
+
Object.defineProperty(to, k, {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function() {
|
|
14
|
+
return from[k];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return from;
|
|
20
|
+
}
|
package/dist/cjs/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"commonjs"}
|
|
1
|
+
{ "type": "commonjs" }
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get BINARY_UPDATE_FORMAT_MAGIC_LE () {
|
|
13
|
+
return BINARY_UPDATE_FORMAT_MAGIC_LE;
|
|
14
|
+
},
|
|
15
|
+
get CustomSocketClosureCodes () {
|
|
16
|
+
return CustomSocketClosureCodes;
|
|
17
|
+
},
|
|
18
|
+
get FORMAT_MAGICS_LE () {
|
|
19
|
+
return FORMAT_MAGICS_LE;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const BINARY_UPDATE_FORMAT_MAGIC_LE = 461_928_307;
|
|
23
|
+
const FORMAT_MAGICS_LE = {
|
|
24
|
+
JSON: 3_302_625_434,
|
|
25
|
+
EVM: 2_593_727_018,
|
|
26
|
+
SOLANA: 2_182_742_457,
|
|
27
|
+
LE_ECDSA: 1_296_547_300,
|
|
28
|
+
LE_UNSIGNED: 1_499_680_012
|
|
29
|
+
};
|
|
30
|
+
var CustomSocketClosureCodes = /*#__PURE__*/ function(CustomSocketClosureCodes) {
|
|
31
|
+
CustomSocketClosureCodes[CustomSocketClosureCodes["CLIENT_TIMEOUT_BUT_RECONNECTING"] = 4000] = "CLIENT_TIMEOUT_BUT_RECONNECTING";
|
|
32
|
+
return CustomSocketClosureCodes;
|
|
33
|
+
}({});
|
package/dist/cjs/protocol.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type Format = "evm" | "solana" | "leEcdsa" | "leUnsigned";
|
|
2
2
|
export type DeliveryFormat = "json" | "binary";
|
|
3
3
|
export type JsonBinaryEncoding = "base64" | "hex";
|
|
4
|
-
export type PriceFeedProperty = "price" | "bestBidPrice" | "bestAskPrice" | "exponent" | "publisherCount" | "confidence";
|
|
4
|
+
export type PriceFeedProperty = "price" | "bestBidPrice" | "bestAskPrice" | "exponent" | "publisherCount" | "confidence" | "fundingRate" | "fundingTimestamp" | "fundingRateInterval";
|
|
5
5
|
export type Channel = "real_time" | "fixed_rate@50ms" | "fixed_rate@200ms";
|
|
6
6
|
export type Request = {
|
|
7
7
|
type: "subscribe";
|