@k256/sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/index.cjs +949 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +938 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.cjs +14 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +202 -0
- package/dist/types/index.d.ts +202 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.cjs +70 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +48 -0
- package/dist/utils/index.d.ts +48 -0
- package/dist/utils/index.js +66 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/ws/index.cjs +896 -0
- package/dist/ws/index.cjs.map +1 -0
- package/dist/ws/index.d.cts +516 -0
- package/dist/ws/index.d.ts +516 -0
- package/dist/ws/index.js +889 -0
- package/dist/ws/index.js.map +1 -0
- package/package.json +92 -0
- package/src/index.ts +34 -0
- package/src/types/index.ts +212 -0
- package/src/utils/base58.ts +123 -0
- package/src/utils/index.ts +7 -0
- package/src/ws/client.ts +786 -0
- package/src/ws/decoder.ts +490 -0
- package/src/ws/index.ts +55 -0
- package/src/ws/types.ts +227 -0
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket message types and interfaces
|
|
3
|
+
*
|
|
4
|
+
* Message type constants MUST match the K2 server values.
|
|
5
|
+
* See: https://github.com/k256-xyz for protocol documentation
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* WebSocket message type constants
|
|
9
|
+
*
|
|
10
|
+
* These are the byte prefixes used in the binary protocol.
|
|
11
|
+
* All SDKs across all languages MUST use these exact values.
|
|
12
|
+
*/
|
|
13
|
+
declare const MessageType: {
|
|
14
|
+
/** Single pool state update (bincode) */
|
|
15
|
+
readonly PoolUpdate: 1;
|
|
16
|
+
/** Subscribe request (JSON) - Client → Server */
|
|
17
|
+
readonly Subscribe: 2;
|
|
18
|
+
/** Subscription confirmed (JSON) - Server → Client */
|
|
19
|
+
readonly Subscribed: 3;
|
|
20
|
+
/** Unsubscribe all - Client → Server */
|
|
21
|
+
readonly Unsubscribe: 4;
|
|
22
|
+
/** Priority fee update (bincode) */
|
|
23
|
+
readonly PriorityFees: 5;
|
|
24
|
+
/** Recent blockhash (bincode) */
|
|
25
|
+
readonly Blockhash: 6;
|
|
26
|
+
/** Streaming quote update (bincode) */
|
|
27
|
+
readonly Quote: 7;
|
|
28
|
+
/** Quote subscription confirmed (JSON) */
|
|
29
|
+
readonly QuoteSubscribed: 8;
|
|
30
|
+
/** Subscribe to quote stream (JSON) - Client → Server */
|
|
31
|
+
readonly SubscribeQuote: 9;
|
|
32
|
+
/** Unsubscribe from quote (JSON) - Client → Server */
|
|
33
|
+
readonly UnsubscribeQuote: 10;
|
|
34
|
+
/** Ping keepalive - Client → Server */
|
|
35
|
+
readonly Ping: 11;
|
|
36
|
+
/** Pong response (bincode u64 timestamp) */
|
|
37
|
+
readonly Pong: 12;
|
|
38
|
+
/** Connection heartbeat with stats (JSON) */
|
|
39
|
+
readonly Heartbeat: 13;
|
|
40
|
+
/** Batched pool updates for high throughput */
|
|
41
|
+
readonly PoolUpdateBatch: 14;
|
|
42
|
+
/** Error message (UTF-8 string) */
|
|
43
|
+
readonly Error: 255;
|
|
44
|
+
};
|
|
45
|
+
type MessageTypeValue = typeof MessageType[keyof typeof MessageType];
|
|
46
|
+
/**
|
|
47
|
+
* Decoded pool update from binary message
|
|
48
|
+
*/
|
|
49
|
+
interface PoolUpdateMessage {
|
|
50
|
+
type: 'pool_update';
|
|
51
|
+
data: {
|
|
52
|
+
sequence: number;
|
|
53
|
+
slot: number;
|
|
54
|
+
writeVersion: number;
|
|
55
|
+
protocol: string;
|
|
56
|
+
poolAddress: string;
|
|
57
|
+
tokenMints: string[];
|
|
58
|
+
tokenBalances: string[];
|
|
59
|
+
tokenDecimals: number[];
|
|
60
|
+
isValid: boolean;
|
|
61
|
+
bestBid?: {
|
|
62
|
+
price: string;
|
|
63
|
+
size: string;
|
|
64
|
+
};
|
|
65
|
+
bestAsk?: {
|
|
66
|
+
price: string;
|
|
67
|
+
size: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Decoded priority fees from binary message
|
|
73
|
+
*
|
|
74
|
+
* All fields from K2 PriorityFeesWire
|
|
75
|
+
*/
|
|
76
|
+
interface PriorityFeesMessage {
|
|
77
|
+
type: 'priority_fees';
|
|
78
|
+
data: {
|
|
79
|
+
slot: number;
|
|
80
|
+
timestampMs: number;
|
|
81
|
+
/** Recommended priority fee in micro-lamports */
|
|
82
|
+
recommended: number;
|
|
83
|
+
/** Fee state: 0=low, 1=normal, 2=high, 3=extreme */
|
|
84
|
+
state: number;
|
|
85
|
+
/** True if data is stale (no recent samples) */
|
|
86
|
+
isStale: boolean;
|
|
87
|
+
swapP50: number;
|
|
88
|
+
swapP75: number;
|
|
89
|
+
swapP90: number;
|
|
90
|
+
swapP99: number;
|
|
91
|
+
/** Number of samples used for swap percentiles */
|
|
92
|
+
swapSamples: number;
|
|
93
|
+
landingP50Fee: number;
|
|
94
|
+
landingP75Fee: number;
|
|
95
|
+
landingP90Fee: number;
|
|
96
|
+
landingP99Fee: number;
|
|
97
|
+
top10Fee: number;
|
|
98
|
+
top25Fee: number;
|
|
99
|
+
spikeDetected: boolean;
|
|
100
|
+
spikeFee: number;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Decoded blockhash from binary message
|
|
105
|
+
*/
|
|
106
|
+
interface BlockhashMessage {
|
|
107
|
+
type: 'blockhash';
|
|
108
|
+
data: {
|
|
109
|
+
slot: number;
|
|
110
|
+
timestampMs: number;
|
|
111
|
+
blockhash: string;
|
|
112
|
+
blockHeight: number;
|
|
113
|
+
lastValidBlockHeight: number;
|
|
114
|
+
isStale: boolean;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Decoded quote from binary message
|
|
119
|
+
*/
|
|
120
|
+
interface QuoteMessage {
|
|
121
|
+
type: 'quote';
|
|
122
|
+
data: {
|
|
123
|
+
topicId: string;
|
|
124
|
+
timestampMs: number;
|
|
125
|
+
sequence: number;
|
|
126
|
+
inputMint: string;
|
|
127
|
+
outputMint: string;
|
|
128
|
+
inAmount: string;
|
|
129
|
+
outAmount: string;
|
|
130
|
+
priceImpactBps: number;
|
|
131
|
+
contextSlot: number;
|
|
132
|
+
algorithm: string;
|
|
133
|
+
isImprovement: boolean;
|
|
134
|
+
isCached: boolean;
|
|
135
|
+
isStale: boolean;
|
|
136
|
+
routePlan: unknown | null;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Decoded heartbeat from JSON message
|
|
141
|
+
*/
|
|
142
|
+
interface HeartbeatMessage {
|
|
143
|
+
type: 'heartbeat';
|
|
144
|
+
data: {
|
|
145
|
+
timestampMs: number;
|
|
146
|
+
uptimeSecs: number;
|
|
147
|
+
messagesSent: number;
|
|
148
|
+
poolUpdatesSent: number;
|
|
149
|
+
messagesDropped: number;
|
|
150
|
+
poolUpdatesEnabled: boolean;
|
|
151
|
+
subscribedChannels: string[];
|
|
152
|
+
serverSequence: number;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Subscription confirmed message
|
|
157
|
+
*/
|
|
158
|
+
interface SubscribedMessage {
|
|
159
|
+
type: 'subscribed';
|
|
160
|
+
data: {
|
|
161
|
+
channelCount: number;
|
|
162
|
+
channels: string[];
|
|
163
|
+
poolCount: number;
|
|
164
|
+
tokenPairCount: number;
|
|
165
|
+
protocolCount: number;
|
|
166
|
+
poolUpdatesEnabled: boolean;
|
|
167
|
+
timestampMs: number;
|
|
168
|
+
summary: string;
|
|
169
|
+
format?: 'binary' | 'json';
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Quote subscription confirmed message
|
|
174
|
+
*/
|
|
175
|
+
interface QuoteSubscribedMessage {
|
|
176
|
+
type: 'quote_subscribed';
|
|
177
|
+
data: {
|
|
178
|
+
topicId: string;
|
|
179
|
+
inputMint: string;
|
|
180
|
+
outputMint: string;
|
|
181
|
+
amount: string;
|
|
182
|
+
slippageBps: number;
|
|
183
|
+
refreshIntervalMs: number;
|
|
184
|
+
timestampMs: number;
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Error message from server
|
|
189
|
+
*/
|
|
190
|
+
interface ErrorMessage {
|
|
191
|
+
type: 'error';
|
|
192
|
+
data: {
|
|
193
|
+
message: string;
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Pong response message
|
|
198
|
+
*/
|
|
199
|
+
interface PongMessage {
|
|
200
|
+
type: 'pong';
|
|
201
|
+
data: {
|
|
202
|
+
timestampMs: number;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Union of all decoded message types
|
|
207
|
+
*/
|
|
208
|
+
type DecodedMessage = PoolUpdateMessage | PriorityFeesMessage | BlockhashMessage | QuoteMessage | HeartbeatMessage | SubscribedMessage | QuoteSubscribedMessage | ErrorMessage | PongMessage;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* K256 WebSocket Client
|
|
212
|
+
*
|
|
213
|
+
* Production-grade WebSocket client with:
|
|
214
|
+
* - Automatic reconnection with exponential backoff
|
|
215
|
+
* - Binary and JSON mode support
|
|
216
|
+
* - Ping/pong keepalive
|
|
217
|
+
* - Heartbeat monitoring
|
|
218
|
+
* - Full error handling with RFC 6455 close codes
|
|
219
|
+
* - Type-safe event emitters
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* const client = new K256WebSocketClient({
|
|
224
|
+
* apiKey: 'your-api-key',
|
|
225
|
+
* mode: 'binary', // or 'json'
|
|
226
|
+
* onPoolUpdate: (update) => console.log(update),
|
|
227
|
+
* onError: (error) => console.error(error),
|
|
228
|
+
* });
|
|
229
|
+
*
|
|
230
|
+
* await client.connect();
|
|
231
|
+
* client.subscribe({ channels: ['pools', 'priority_fees'] });
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* RFC 6455 WebSocket Close Codes
|
|
237
|
+
* @see https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1
|
|
238
|
+
*/
|
|
239
|
+
declare const CloseCode: {
|
|
240
|
+
/** 1000: Normal closure - connection completed successfully */
|
|
241
|
+
readonly NORMAL: 1000;
|
|
242
|
+
/** 1001: Going away - server/client shutting down. Client: reconnect immediately */
|
|
243
|
+
readonly GOING_AWAY: 1001;
|
|
244
|
+
/** 1002: Protocol error - invalid frame format. Client: fix client code */
|
|
245
|
+
readonly PROTOCOL_ERROR: 1002;
|
|
246
|
+
/** 1003: Unsupported data - message type not supported */
|
|
247
|
+
readonly UNSUPPORTED_DATA: 1003;
|
|
248
|
+
/** 1005: No status received (reserved, not sent over wire) */
|
|
249
|
+
readonly NO_STATUS: 1005;
|
|
250
|
+
/** 1006: Abnormal closure - connection dropped without close frame */
|
|
251
|
+
readonly ABNORMAL: 1006;
|
|
252
|
+
/** 1007: Invalid payload - malformed UTF-8 or data. Client: fix message format */
|
|
253
|
+
readonly INVALID_PAYLOAD: 1007;
|
|
254
|
+
/** 1008: Policy violation - rate limit exceeded, auth failed. Client: check credentials/limits */
|
|
255
|
+
readonly POLICY_VIOLATION: 1008;
|
|
256
|
+
/** 1009: Message too big - message exceeds size limits */
|
|
257
|
+
readonly MESSAGE_TOO_BIG: 1009;
|
|
258
|
+
/** 1010: Missing extension - required extension not negotiated */
|
|
259
|
+
readonly MISSING_EXTENSION: 1010;
|
|
260
|
+
/** 1011: Internal error - unexpected server error. Client: retry with backoff */
|
|
261
|
+
readonly INTERNAL_ERROR: 1011;
|
|
262
|
+
/** 1012: Service restart - server is restarting. Client: reconnect after brief delay */
|
|
263
|
+
readonly SERVICE_RESTART: 1012;
|
|
264
|
+
/** 1013: Try again later - server overloaded. Client: retry with backoff */
|
|
265
|
+
readonly TRY_AGAIN_LATER: 1013;
|
|
266
|
+
/** 1014: Bad gateway - upstream connection failed */
|
|
267
|
+
readonly BAD_GATEWAY: 1014;
|
|
268
|
+
/** 1015: TLS handshake failed (reserved, not sent over wire) */
|
|
269
|
+
readonly TLS_HANDSHAKE: 1015;
|
|
270
|
+
};
|
|
271
|
+
type CloseCodeValue = typeof CloseCode[keyof typeof CloseCode];
|
|
272
|
+
/**
|
|
273
|
+
* Connection state
|
|
274
|
+
*/
|
|
275
|
+
type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'closed';
|
|
276
|
+
/**
|
|
277
|
+
* Subscribe request options
|
|
278
|
+
*/
|
|
279
|
+
interface SubscribeOptions {
|
|
280
|
+
/** Channels to subscribe to: 'pools', 'priority_fees', 'blockhash' */
|
|
281
|
+
channels: string[];
|
|
282
|
+
/** Pool address filters (optional) */
|
|
283
|
+
pools?: string[];
|
|
284
|
+
/** Protocol filters (optional): 'Raydium AMM', 'Orca Whirlpool', etc. */
|
|
285
|
+
protocols?: string[];
|
|
286
|
+
/** Token pair filters (optional): [['mint1', 'mint2'], ...] */
|
|
287
|
+
tokenPairs?: string[][];
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Quote subscription options
|
|
291
|
+
*/
|
|
292
|
+
interface SubscribeQuoteOptions {
|
|
293
|
+
/** Input token mint address */
|
|
294
|
+
inputMint: string;
|
|
295
|
+
/** Output token mint address */
|
|
296
|
+
outputMint: string;
|
|
297
|
+
/** Amount in base units (lamports/smallest unit) */
|
|
298
|
+
amount: number | string;
|
|
299
|
+
/** Slippage tolerance in basis points */
|
|
300
|
+
slippageBps: number;
|
|
301
|
+
/** How often to refresh the quote (ms) */
|
|
302
|
+
refreshIntervalMs?: number;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* WebSocket client configuration
|
|
306
|
+
*/
|
|
307
|
+
interface K256WebSocketClientConfig {
|
|
308
|
+
/** API key for authentication */
|
|
309
|
+
apiKey: string;
|
|
310
|
+
/** Gateway URL (default: wss://gateway.k256.xyz/v1/ws) */
|
|
311
|
+
url?: string;
|
|
312
|
+
/** Message format: 'binary' (default, efficient) or 'json' (debugging) */
|
|
313
|
+
mode?: 'binary' | 'json';
|
|
314
|
+
/** Enable automatic reconnection (default: true) */
|
|
315
|
+
autoReconnect?: boolean;
|
|
316
|
+
/** Initial reconnect delay in ms (default: 1000) */
|
|
317
|
+
reconnectDelayMs?: number;
|
|
318
|
+
/** Max reconnect delay in ms (default: 30000) */
|
|
319
|
+
maxReconnectDelayMs?: number;
|
|
320
|
+
/** Max reconnect attempts (default: Infinity) */
|
|
321
|
+
maxReconnectAttempts?: number;
|
|
322
|
+
/** Ping interval in ms (default: 30000) */
|
|
323
|
+
pingIntervalMs?: number;
|
|
324
|
+
/** Pong timeout in ms - disconnect if no pong (default: 10000) */
|
|
325
|
+
pongTimeoutMs?: number;
|
|
326
|
+
/** Heartbeat timeout in ms - warn if no heartbeat (default: 15000) */
|
|
327
|
+
heartbeatTimeoutMs?: number;
|
|
328
|
+
/** Called when connection state changes */
|
|
329
|
+
onStateChange?: (state: ConnectionState, prevState: ConnectionState) => void;
|
|
330
|
+
/** Called on successful connection */
|
|
331
|
+
onConnect?: () => void;
|
|
332
|
+
/** Called on disconnection */
|
|
333
|
+
onDisconnect?: (code: number, reason: string, wasClean: boolean) => void;
|
|
334
|
+
/** Called on reconnection attempt */
|
|
335
|
+
onReconnecting?: (attempt: number, delayMs: number) => void;
|
|
336
|
+
/** Called on any error */
|
|
337
|
+
onError?: (error: K256WebSocketError) => void;
|
|
338
|
+
/** Called on subscription confirmed */
|
|
339
|
+
onSubscribed?: (data: DecodedMessage & {
|
|
340
|
+
type: 'subscribed';
|
|
341
|
+
}) => void;
|
|
342
|
+
/** Called on pool update */
|
|
343
|
+
onPoolUpdate?: (update: PoolUpdateMessage) => void;
|
|
344
|
+
/** Called on batched pool updates (for efficiency) */
|
|
345
|
+
onPoolUpdateBatch?: (updates: PoolUpdateMessage[]) => void;
|
|
346
|
+
/** Called on priority fees update */
|
|
347
|
+
onPriorityFees?: (data: DecodedMessage & {
|
|
348
|
+
type: 'priority_fees';
|
|
349
|
+
}) => void;
|
|
350
|
+
/** Called on blockhash update */
|
|
351
|
+
onBlockhash?: (data: DecodedMessage & {
|
|
352
|
+
type: 'blockhash';
|
|
353
|
+
}) => void;
|
|
354
|
+
/** Called on quote update */
|
|
355
|
+
onQuote?: (data: DecodedMessage & {
|
|
356
|
+
type: 'quote';
|
|
357
|
+
}) => void;
|
|
358
|
+
/** Called on quote subscription confirmed */
|
|
359
|
+
onQuoteSubscribed?: (data: DecodedMessage & {
|
|
360
|
+
type: 'quote_subscribed';
|
|
361
|
+
}) => void;
|
|
362
|
+
/** Called on heartbeat */
|
|
363
|
+
onHeartbeat?: (data: DecodedMessage & {
|
|
364
|
+
type: 'heartbeat';
|
|
365
|
+
}) => void;
|
|
366
|
+
/** Called on pong response (with round-trip latency) */
|
|
367
|
+
onPong?: (latencyMs: number) => void;
|
|
368
|
+
/** Called on any message (raw) */
|
|
369
|
+
onMessage?: (message: DecodedMessage) => void;
|
|
370
|
+
/** Called on raw binary message (for debugging) */
|
|
371
|
+
onRawMessage?: (data: ArrayBuffer | string) => void;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Error types for K256 WebSocket
|
|
375
|
+
*/
|
|
376
|
+
type K256ErrorCode = 'CONNECTION_FAILED' | 'CONNECTION_LOST' | 'PROTOCOL_ERROR' | 'AUTH_FAILED' | 'RATE_LIMITED' | 'SERVER_ERROR' | 'PING_TIMEOUT' | 'HEARTBEAT_TIMEOUT' | 'INVALID_MESSAGE' | 'RECONNECT_FAILED';
|
|
377
|
+
/**
|
|
378
|
+
* WebSocket error with context
|
|
379
|
+
*/
|
|
380
|
+
declare class K256WebSocketError extends Error {
|
|
381
|
+
readonly code: K256ErrorCode;
|
|
382
|
+
readonly closeCode?: number | undefined;
|
|
383
|
+
readonly closeReason?: string | undefined;
|
|
384
|
+
readonly cause?: unknown | undefined;
|
|
385
|
+
constructor(code: K256ErrorCode, message: string, closeCode?: number | undefined, closeReason?: string | undefined, cause?: unknown | undefined);
|
|
386
|
+
/** Check if error is recoverable (should trigger reconnect) */
|
|
387
|
+
get isRecoverable(): boolean;
|
|
388
|
+
/** Check if error is an auth failure */
|
|
389
|
+
get isAuthError(): boolean;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Production-grade K256 WebSocket Client
|
|
393
|
+
*/
|
|
394
|
+
declare class K256WebSocketClient {
|
|
395
|
+
private ws;
|
|
396
|
+
private config;
|
|
397
|
+
private _state;
|
|
398
|
+
private reconnectAttempts;
|
|
399
|
+
private reconnectTimer;
|
|
400
|
+
private pingTimer;
|
|
401
|
+
private pongTimer;
|
|
402
|
+
private heartbeatTimer;
|
|
403
|
+
private lastPingTime;
|
|
404
|
+
private lastHeartbeatTime;
|
|
405
|
+
private pendingSubscription;
|
|
406
|
+
private pendingQuoteSubscription;
|
|
407
|
+
private isIntentionallyClosed;
|
|
408
|
+
/** Current connection state */
|
|
409
|
+
get state(): ConnectionState;
|
|
410
|
+
/** Whether currently connected */
|
|
411
|
+
get isConnected(): boolean;
|
|
412
|
+
/** Time since last heartbeat (ms) or null if no heartbeat received */
|
|
413
|
+
get timeSinceHeartbeat(): number | null;
|
|
414
|
+
/** Current reconnect attempt number */
|
|
415
|
+
get currentReconnectAttempt(): number;
|
|
416
|
+
constructor(config: K256WebSocketClientConfig);
|
|
417
|
+
/**
|
|
418
|
+
* Connect to the WebSocket server
|
|
419
|
+
* @returns Promise that resolves when connected
|
|
420
|
+
*/
|
|
421
|
+
connect(): Promise<void>;
|
|
422
|
+
/**
|
|
423
|
+
* Disconnect from the WebSocket server
|
|
424
|
+
* @param code - Close code (default: 1000 NORMAL)
|
|
425
|
+
* @param reason - Close reason
|
|
426
|
+
*/
|
|
427
|
+
disconnect(code?: number, reason?: string): void;
|
|
428
|
+
/**
|
|
429
|
+
* Subscribe to channels
|
|
430
|
+
*/
|
|
431
|
+
subscribe(options: SubscribeOptions): void;
|
|
432
|
+
/**
|
|
433
|
+
* Subscribe to a quote stream
|
|
434
|
+
*/
|
|
435
|
+
subscribeQuote(options: SubscribeQuoteOptions): void;
|
|
436
|
+
/**
|
|
437
|
+
* Unsubscribe from a quote stream
|
|
438
|
+
* @param topicId - Topic ID from quote_subscribed response
|
|
439
|
+
*/
|
|
440
|
+
unsubscribeQuote(topicId: string): void;
|
|
441
|
+
/**
|
|
442
|
+
* Unsubscribe from all channels
|
|
443
|
+
*/
|
|
444
|
+
unsubscribe(): void;
|
|
445
|
+
/**
|
|
446
|
+
* Send a ping to measure latency
|
|
447
|
+
*/
|
|
448
|
+
ping(): void;
|
|
449
|
+
private doConnect;
|
|
450
|
+
private handleMessage;
|
|
451
|
+
private sendSubscription;
|
|
452
|
+
private sendQuoteSubscription;
|
|
453
|
+
private setState;
|
|
454
|
+
private handleError;
|
|
455
|
+
private cleanup;
|
|
456
|
+
private startPingInterval;
|
|
457
|
+
private startPongTimeout;
|
|
458
|
+
private clearPongTimeout;
|
|
459
|
+
private startHeartbeatTimeout;
|
|
460
|
+
private resetHeartbeatTimeout;
|
|
461
|
+
private shouldReconnect;
|
|
462
|
+
private scheduleReconnect;
|
|
463
|
+
private getCloseReason;
|
|
464
|
+
private getErrorCodeFromClose;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Binary message decoder for K256 WebSocket protocol
|
|
469
|
+
*
|
|
470
|
+
* Decodes binary messages from K2 server into typed JavaScript objects.
|
|
471
|
+
* Supports both single messages and batched pool updates.
|
|
472
|
+
*
|
|
473
|
+
* Wire format: [1 byte MessageType][N bytes Payload]
|
|
474
|
+
*/
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Decode a binary WebSocket message from K2
|
|
478
|
+
*
|
|
479
|
+
* @param data - Raw binary data from WebSocket
|
|
480
|
+
* @returns Decoded message or null if unrecognized type
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```typescript
|
|
484
|
+
* ws.onmessage = (event) => {
|
|
485
|
+
* if (event.data instanceof ArrayBuffer) {
|
|
486
|
+
* const message = decodeMessage(event.data);
|
|
487
|
+
* if (message?.type === 'pool_update') {
|
|
488
|
+
* console.log(message.data.poolAddress);
|
|
489
|
+
* }
|
|
490
|
+
* }
|
|
491
|
+
* };
|
|
492
|
+
* ```
|
|
493
|
+
*/
|
|
494
|
+
declare function decodeMessage(data: ArrayBuffer): DecodedMessage | null;
|
|
495
|
+
/**
|
|
496
|
+
* Decode a batch of pool updates
|
|
497
|
+
*
|
|
498
|
+
* Use this when you need to process all updates in a batch.
|
|
499
|
+
* For high-throughput scenarios, batches can contain 50-200 updates.
|
|
500
|
+
*
|
|
501
|
+
* @param data - Raw payload (without the 0x0E type prefix)
|
|
502
|
+
* @returns Array of decoded pool updates
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```typescript
|
|
506
|
+
* if (msgType === MessageType.PoolUpdateBatch) {
|
|
507
|
+
* const updates = decodePoolUpdateBatch(payload);
|
|
508
|
+
* for (const update of updates) {
|
|
509
|
+
* console.log(update.data.poolAddress);
|
|
510
|
+
* }
|
|
511
|
+
* }
|
|
512
|
+
* ```
|
|
513
|
+
*/
|
|
514
|
+
declare function decodePoolUpdateBatch(payload: ArrayBuffer): PoolUpdateMessage[];
|
|
515
|
+
|
|
516
|
+
export { type BlockhashMessage, CloseCode, type CloseCodeValue, type ConnectionState, type DecodedMessage, type ErrorMessage, type HeartbeatMessage, type K256ErrorCode, K256WebSocketClient, type K256WebSocketClientConfig, K256WebSocketError, MessageType, type MessageTypeValue, type PongMessage, type PoolUpdateMessage, type PriorityFeesMessage, type QuoteMessage, type QuoteSubscribedMessage, type SubscribeOptions, type SubscribeQuoteOptions, type SubscribedMessage, decodeMessage, decodePoolUpdateBatch };
|