@newyorkcompute/kalshi-core 0.2.0 → 0.3.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/dist/config.d.ts +61 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +56 -5
- package/dist/config.js.map +1 -1
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +94 -0
- package/dist/config.test.js.map +1 -0
- package/dist/format.d.ts +71 -2
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +71 -2
- package/dist/format.js.map +1 -1
- package/dist/format.test.js +42 -1
- package/dist/format.test.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/websocket/auth.d.ts +28 -0
- package/dist/websocket/auth.d.ts.map +1 -0
- package/dist/websocket/auth.js +55 -0
- package/dist/websocket/auth.js.map +1 -0
- package/dist/websocket/auth.test.d.ts +2 -0
- package/dist/websocket/auth.test.d.ts.map +1 -0
- package/dist/websocket/auth.test.js +56 -0
- package/dist/websocket/auth.test.js.map +1 -0
- package/dist/websocket/client.d.ts +95 -0
- package/dist/websocket/client.d.ts.map +1 -0
- package/dist/websocket/client.js +352 -0
- package/dist/websocket/client.js.map +1 -0
- package/dist/websocket/index.d.ts +9 -0
- package/dist/websocket/index.d.ts.map +1 -0
- package/dist/websocket/index.js +9 -0
- package/dist/websocket/index.js.map +1 -0
- package/dist/websocket/types.d.ts +160 -0
- package/dist/websocket/types.d.ts.map +1 -0
- package/dist/websocket/types.js +12 -0
- package/dist/websocket/types.js.map +1 -0
- package/dist/websocket/types.test.d.ts +2 -0
- package/dist/websocket/types.test.d.ts.map +1 -0
- package/dist/websocket/types.test.js +17 -0
- package/dist/websocket/types.test.js.map +1 -0
- package/package.json +8 -4
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kalshi WebSocket Client
|
|
3
|
+
*
|
|
4
|
+
* Provides real-time market data streaming from Kalshi.
|
|
5
|
+
* Features:
|
|
6
|
+
* - Automatic reconnection with exponential backoff
|
|
7
|
+
* - Subscription management
|
|
8
|
+
* - Event-based message handling
|
|
9
|
+
* - Connection health monitoring
|
|
10
|
+
*/
|
|
11
|
+
import WebSocket from 'ws';
|
|
12
|
+
import { WS_ENDPOINTS, } from './types.js';
|
|
13
|
+
import { generateWsAuthHeaders } from './auth.js';
|
|
14
|
+
/** Default configuration values */
|
|
15
|
+
const DEFAULTS = {
|
|
16
|
+
autoReconnect: true,
|
|
17
|
+
reconnectDelay: 1000,
|
|
18
|
+
maxReconnectAttempts: 10,
|
|
19
|
+
pingInterval: 30000, // 30 seconds
|
|
20
|
+
pongTimeout: 10000, // 10 seconds
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Kalshi WebSocket Client
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const client = new KalshiWsClient({
|
|
28
|
+
* apiKeyId: 'your-api-key',
|
|
29
|
+
* privateKey: 'your-private-key',
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* client.on('ticker', (data) => {
|
|
33
|
+
* console.log('Price update:', data.market_ticker, data.yes_bid);
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* await client.connect();
|
|
37
|
+
* client.subscribe(['ticker'], ['KXBTC-25JAN03']);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export class KalshiWsClient {
|
|
41
|
+
config;
|
|
42
|
+
ws = null;
|
|
43
|
+
handlers = {};
|
|
44
|
+
state = 'disconnected';
|
|
45
|
+
reconnectAttempts = 0;
|
|
46
|
+
commandId = 0;
|
|
47
|
+
pingTimer = null;
|
|
48
|
+
pongTimer = null;
|
|
49
|
+
subscriptions = {
|
|
50
|
+
orderbook_delta: new Set(),
|
|
51
|
+
ticker: new Set(),
|
|
52
|
+
trade: new Set(),
|
|
53
|
+
fill: false,
|
|
54
|
+
};
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.config = {
|
|
57
|
+
...config,
|
|
58
|
+
demo: config.demo ?? false,
|
|
59
|
+
autoReconnect: config.autoReconnect ?? DEFAULTS.autoReconnect,
|
|
60
|
+
reconnectDelay: config.reconnectDelay ?? DEFAULTS.reconnectDelay,
|
|
61
|
+
maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULTS.maxReconnectAttempts,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// ===========================================================================
|
|
65
|
+
// Public API
|
|
66
|
+
// ===========================================================================
|
|
67
|
+
/**
|
|
68
|
+
* Get current connection state
|
|
69
|
+
*/
|
|
70
|
+
get connectionState() {
|
|
71
|
+
return this.state;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if connected
|
|
75
|
+
*/
|
|
76
|
+
get isConnected() {
|
|
77
|
+
return this.state === 'connected';
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Register event handlers
|
|
81
|
+
*/
|
|
82
|
+
on(event, handler) {
|
|
83
|
+
this.handlers[event] = handler;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Connect to WebSocket server
|
|
87
|
+
*/
|
|
88
|
+
async connect() {
|
|
89
|
+
if (this.state === 'connected' || this.state === 'connecting') {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.state = 'connecting';
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
const endpoint = this.config.demo
|
|
95
|
+
? WS_ENDPOINTS.demo
|
|
96
|
+
: WS_ENDPOINTS.production;
|
|
97
|
+
const headers = generateWsAuthHeaders(this.config.apiKeyId, this.config.privateKey);
|
|
98
|
+
this.ws = new WebSocket(endpoint, { headers });
|
|
99
|
+
this.ws.on('open', () => {
|
|
100
|
+
this.state = 'connected';
|
|
101
|
+
this.reconnectAttempts = 0;
|
|
102
|
+
this.startPingPong();
|
|
103
|
+
this.handlers.onConnect?.();
|
|
104
|
+
this.resubscribeAll();
|
|
105
|
+
resolve();
|
|
106
|
+
});
|
|
107
|
+
this.ws.on('message', (data) => {
|
|
108
|
+
this.handleMessage(data);
|
|
109
|
+
});
|
|
110
|
+
this.ws.on('close', (code, reason) => {
|
|
111
|
+
this.handleClose(code, reason.toString());
|
|
112
|
+
});
|
|
113
|
+
this.ws.on('error', (error) => {
|
|
114
|
+
this.handlers.onError?.(error);
|
|
115
|
+
if (this.state === 'connecting') {
|
|
116
|
+
reject(error);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
this.ws.on('pong', () => {
|
|
120
|
+
this.clearPongTimeout();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Disconnect from WebSocket server
|
|
126
|
+
*/
|
|
127
|
+
disconnect() {
|
|
128
|
+
this.state = 'disconnected';
|
|
129
|
+
this.stopPingPong();
|
|
130
|
+
if (this.ws) {
|
|
131
|
+
this.ws.close(1000, 'Client disconnect');
|
|
132
|
+
this.ws = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Subscribe to channels for specific market tickers
|
|
137
|
+
*
|
|
138
|
+
* @param channels - Channels to subscribe to
|
|
139
|
+
* @param marketTickers - Market tickers (not needed for 'fill' channel)
|
|
140
|
+
*/
|
|
141
|
+
subscribe(channels, marketTickers) {
|
|
142
|
+
if (!this.ws || this.state !== 'connected') {
|
|
143
|
+
// Store for later subscription when connected
|
|
144
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'add');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const command = {
|
|
148
|
+
id: ++this.commandId,
|
|
149
|
+
cmd: 'subscribe',
|
|
150
|
+
params: {
|
|
151
|
+
channels,
|
|
152
|
+
...(marketTickers && { market_tickers: marketTickers }),
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
this.send(command);
|
|
156
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'add');
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Unsubscribe from channels
|
|
160
|
+
*/
|
|
161
|
+
unsubscribe(channels, marketTickers) {
|
|
162
|
+
if (!this.ws || this.state !== 'connected') {
|
|
163
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'remove');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const command = {
|
|
167
|
+
id: ++this.commandId,
|
|
168
|
+
cmd: 'unsubscribe',
|
|
169
|
+
params: {
|
|
170
|
+
channels,
|
|
171
|
+
...(marketTickers && { market_tickers: marketTickers }),
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
this.send(command);
|
|
175
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'remove');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Add markets to existing subscription
|
|
179
|
+
*/
|
|
180
|
+
addMarkets(channels, marketTickers) {
|
|
181
|
+
if (!this.ws || this.state !== 'connected') {
|
|
182
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'add');
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const command = {
|
|
186
|
+
id: ++this.commandId,
|
|
187
|
+
cmd: 'update_subscription',
|
|
188
|
+
params: {
|
|
189
|
+
channels,
|
|
190
|
+
market_tickers: marketTickers,
|
|
191
|
+
action: 'add_markets',
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
this.send(command);
|
|
195
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'add');
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Remove markets from existing subscription
|
|
199
|
+
*/
|
|
200
|
+
removeMarkets(channels, marketTickers) {
|
|
201
|
+
if (!this.ws || this.state !== 'connected') {
|
|
202
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'remove');
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const command = {
|
|
206
|
+
id: ++this.commandId,
|
|
207
|
+
cmd: 'update_subscription',
|
|
208
|
+
params: {
|
|
209
|
+
channels,
|
|
210
|
+
market_tickers: marketTickers,
|
|
211
|
+
action: 'remove_markets',
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
this.send(command);
|
|
215
|
+
this.updateLocalSubscriptions(channels, marketTickers, 'remove');
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get currently subscribed tickers for a channel
|
|
219
|
+
*/
|
|
220
|
+
getSubscribedTickers(channel) {
|
|
221
|
+
if (channel === 'fill')
|
|
222
|
+
return [];
|
|
223
|
+
return Array.from(this.subscriptions[channel]);
|
|
224
|
+
}
|
|
225
|
+
// ===========================================================================
|
|
226
|
+
// Private Methods
|
|
227
|
+
// ===========================================================================
|
|
228
|
+
send(data) {
|
|
229
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
230
|
+
this.ws.send(JSON.stringify(data));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
handleMessage(data) {
|
|
234
|
+
try {
|
|
235
|
+
const message = JSON.parse(data.toString());
|
|
236
|
+
switch (message.type) {
|
|
237
|
+
case 'subscribed':
|
|
238
|
+
this.handlers.onSubscribed?.(message.msg.channel, message.msg.market_tickers);
|
|
239
|
+
break;
|
|
240
|
+
case 'error':
|
|
241
|
+
this.handlers.onError?.(new Error(`WebSocket error ${message.msg.code}: ${message.msg.message}`));
|
|
242
|
+
break;
|
|
243
|
+
case 'orderbook_delta':
|
|
244
|
+
this.handlers.onOrderbookDelta?.(message.msg);
|
|
245
|
+
break;
|
|
246
|
+
case 'ticker':
|
|
247
|
+
this.handlers.onTicker?.(message.msg);
|
|
248
|
+
break;
|
|
249
|
+
case 'trade':
|
|
250
|
+
this.handlers.onTrade?.(message.msg);
|
|
251
|
+
break;
|
|
252
|
+
case 'fill':
|
|
253
|
+
this.handlers.onFill?.(message.msg);
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
this.handlers.onError?.(error instanceof Error ? error : new Error('Failed to parse message'));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
handleClose(code, reason) {
|
|
262
|
+
this.stopPingPong();
|
|
263
|
+
this.handlers.onDisconnect?.(code, reason);
|
|
264
|
+
if (this.config.autoReconnect &&
|
|
265
|
+
this.state !== 'disconnected' &&
|
|
266
|
+
this.reconnectAttempts < this.config.maxReconnectAttempts) {
|
|
267
|
+
this.scheduleReconnect();
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
this.state = 'disconnected';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
scheduleReconnect() {
|
|
274
|
+
this.state = 'reconnecting';
|
|
275
|
+
this.reconnectAttempts++;
|
|
276
|
+
// Exponential backoff
|
|
277
|
+
const delay = this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
|
278
|
+
setTimeout(() => {
|
|
279
|
+
if (this.state === 'reconnecting') {
|
|
280
|
+
this.connect().catch((error) => {
|
|
281
|
+
this.handlers.onError?.(error);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}, delay);
|
|
285
|
+
}
|
|
286
|
+
resubscribeAll() {
|
|
287
|
+
// Resubscribe to all previously active subscriptions
|
|
288
|
+
const channels = [];
|
|
289
|
+
const tickers = [];
|
|
290
|
+
for (const [channel, data] of Object.entries(this.subscriptions)) {
|
|
291
|
+
if (channel === 'fill') {
|
|
292
|
+
if (data === true) {
|
|
293
|
+
this.subscribe(['fill']);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (data instanceof Set && data.size > 0) {
|
|
297
|
+
channels.push(channel);
|
|
298
|
+
tickers.push(...data);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (channels.length > 0 && tickers.length > 0) {
|
|
302
|
+
const uniqueTickers = [...new Set(tickers)];
|
|
303
|
+
this.subscribe(channels, uniqueTickers);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
updateLocalSubscriptions(channels, tickers, action) {
|
|
307
|
+
for (const channel of channels) {
|
|
308
|
+
if (channel === 'fill') {
|
|
309
|
+
this.subscriptions.fill = action === 'add';
|
|
310
|
+
}
|
|
311
|
+
else if (tickers) {
|
|
312
|
+
for (const ticker of tickers) {
|
|
313
|
+
if (action === 'add') {
|
|
314
|
+
this.subscriptions[channel].add(ticker);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
this.subscriptions[channel].delete(ticker);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
startPingPong() {
|
|
324
|
+
this.pingTimer = setInterval(() => {
|
|
325
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
326
|
+
this.ws.ping();
|
|
327
|
+
this.setPongTimeout();
|
|
328
|
+
}
|
|
329
|
+
}, DEFAULTS.pingInterval);
|
|
330
|
+
}
|
|
331
|
+
stopPingPong() {
|
|
332
|
+
if (this.pingTimer) {
|
|
333
|
+
clearInterval(this.pingTimer);
|
|
334
|
+
this.pingTimer = null;
|
|
335
|
+
}
|
|
336
|
+
this.clearPongTimeout();
|
|
337
|
+
}
|
|
338
|
+
setPongTimeout() {
|
|
339
|
+
this.pongTimer = setTimeout(() => {
|
|
340
|
+
// No pong received, connection might be dead
|
|
341
|
+
this.handlers.onError?.(new Error('Pong timeout - connection may be dead'));
|
|
342
|
+
this.ws?.terminate();
|
|
343
|
+
}, DEFAULTS.pongTimeout);
|
|
344
|
+
}
|
|
345
|
+
clearPongTimeout() {
|
|
346
|
+
if (this.pongTimer) {
|
|
347
|
+
clearTimeout(this.pongTimer);
|
|
348
|
+
this.pongTimer = null;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/websocket/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kalshi WebSocket Module
|
|
3
|
+
*
|
|
4
|
+
* Real-time market data streaming from Kalshi.
|
|
5
|
+
*/
|
|
6
|
+
export { KalshiWsClient } from './client.js';
|
|
7
|
+
export { generateWsAuthHeaders, generateSignedWsUrl } from './auth.js';
|
|
8
|
+
export { type KalshiWsConfig, type KalshiWsEventHandlers, type SubscriptionChannel, type ConnectionState, type ActiveSubscriptions, type OrderbookDeltaMessage, type TickerMessage, type TradeMessage, type FillMessage, type WsMessage, WS_ENDPOINTS, } from './types.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kalshi WebSocket Module
|
|
3
|
+
*
|
|
4
|
+
* Real-time market data streaming from Kalshi.
|
|
5
|
+
*/
|
|
6
|
+
export { KalshiWsClient } from './client.js';
|
|
7
|
+
export { generateWsAuthHeaders, generateSignedWsUrl } from './auth.js';
|
|
8
|
+
export { WS_ENDPOINTS, } from './types.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAWL,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kalshi WebSocket Types
|
|
3
|
+
*
|
|
4
|
+
* Message formats for Kalshi's WebSocket API
|
|
5
|
+
* Based on: https://docs.kalshi.com/websockets
|
|
6
|
+
*/
|
|
7
|
+
/** WebSocket connection configuration */
|
|
8
|
+
export interface KalshiWsConfig {
|
|
9
|
+
/** API Key ID */
|
|
10
|
+
apiKeyId: string;
|
|
11
|
+
/** API Private Key (PEM format) */
|
|
12
|
+
privateKey: string;
|
|
13
|
+
/** Use demo environment (default: false) */
|
|
14
|
+
demo?: boolean;
|
|
15
|
+
/** Auto-reconnect on disconnect (default: true) */
|
|
16
|
+
autoReconnect?: boolean;
|
|
17
|
+
/** Reconnect delay in ms (default: 1000) */
|
|
18
|
+
reconnectDelay?: number;
|
|
19
|
+
/** Max reconnect attempts (default: 10) */
|
|
20
|
+
maxReconnectAttempts?: number;
|
|
21
|
+
}
|
|
22
|
+
/** WebSocket endpoints */
|
|
23
|
+
export declare const WS_ENDPOINTS: {
|
|
24
|
+
readonly production: "wss://api.elections.kalshi.com/trade-api/ws/v2";
|
|
25
|
+
readonly demo: "wss://demo-api.kalshi.co/trade-api/ws/v2";
|
|
26
|
+
};
|
|
27
|
+
/** Available subscription channels */
|
|
28
|
+
export type SubscriptionChannel = 'orderbook_delta' | 'ticker' | 'trade' | 'fill';
|
|
29
|
+
/** Subscription command */
|
|
30
|
+
export interface SubscribeCommand {
|
|
31
|
+
id: number;
|
|
32
|
+
cmd: 'subscribe';
|
|
33
|
+
params: {
|
|
34
|
+
channels: SubscriptionChannel[];
|
|
35
|
+
market_tickers?: string[];
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Unsubscribe command */
|
|
39
|
+
export interface UnsubscribeCommand {
|
|
40
|
+
id: number;
|
|
41
|
+
cmd: 'unsubscribe';
|
|
42
|
+
params: {
|
|
43
|
+
channels: SubscriptionChannel[];
|
|
44
|
+
market_tickers?: string[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Update subscription command */
|
|
48
|
+
export interface UpdateSubscriptionCommand {
|
|
49
|
+
id: number;
|
|
50
|
+
cmd: 'update_subscription';
|
|
51
|
+
params: {
|
|
52
|
+
channels: SubscriptionChannel[];
|
|
53
|
+
market_tickers: string[];
|
|
54
|
+
action: 'add_markets' | 'remove_markets';
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export type WsCommand = SubscribeCommand | UnsubscribeCommand | UpdateSubscriptionCommand;
|
|
58
|
+
/** Base message structure */
|
|
59
|
+
interface BaseMessage {
|
|
60
|
+
type: string;
|
|
61
|
+
sid?: number;
|
|
62
|
+
}
|
|
63
|
+
/** Subscription confirmation */
|
|
64
|
+
export interface SubscribedMessage extends BaseMessage {
|
|
65
|
+
type: 'subscribed';
|
|
66
|
+
msg: {
|
|
67
|
+
channel: SubscriptionChannel;
|
|
68
|
+
market_tickers?: string[];
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Error message */
|
|
72
|
+
export interface ErrorMessage extends BaseMessage {
|
|
73
|
+
type: 'error';
|
|
74
|
+
msg: {
|
|
75
|
+
code: number;
|
|
76
|
+
message: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** Orderbook delta update */
|
|
80
|
+
export interface OrderbookDeltaMessage extends BaseMessage {
|
|
81
|
+
type: 'orderbook_delta';
|
|
82
|
+
msg: {
|
|
83
|
+
market_ticker: string;
|
|
84
|
+
price: number;
|
|
85
|
+
delta: number;
|
|
86
|
+
side: 'yes' | 'no';
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Ticker update (market price change) */
|
|
90
|
+
export interface TickerMessage extends BaseMessage {
|
|
91
|
+
type: 'ticker';
|
|
92
|
+
msg: {
|
|
93
|
+
market_ticker: string;
|
|
94
|
+
yes_bid: number;
|
|
95
|
+
yes_ask: number;
|
|
96
|
+
no_bid: number;
|
|
97
|
+
no_ask: number;
|
|
98
|
+
last_price: number;
|
|
99
|
+
volume: number;
|
|
100
|
+
open_interest: number;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Trade execution */
|
|
104
|
+
export interface TradeMessage extends BaseMessage {
|
|
105
|
+
type: 'trade';
|
|
106
|
+
msg: {
|
|
107
|
+
market_ticker: string;
|
|
108
|
+
trade_id: string;
|
|
109
|
+
price: number;
|
|
110
|
+
count: number;
|
|
111
|
+
taker_side: 'yes' | 'no';
|
|
112
|
+
created_time: string;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** User fill notification (authenticated) */
|
|
116
|
+
export interface FillMessage extends BaseMessage {
|
|
117
|
+
type: 'fill';
|
|
118
|
+
msg: {
|
|
119
|
+
trade_id: string;
|
|
120
|
+
order_id: string;
|
|
121
|
+
market_ticker: string;
|
|
122
|
+
side: 'yes' | 'no';
|
|
123
|
+
action: 'buy' | 'sell';
|
|
124
|
+
count: number;
|
|
125
|
+
price: number;
|
|
126
|
+
created_time: string;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** All possible server messages */
|
|
130
|
+
export type WsMessage = SubscribedMessage | ErrorMessage | OrderbookDeltaMessage | TickerMessage | TradeMessage | FillMessage;
|
|
131
|
+
/** WebSocket event handlers */
|
|
132
|
+
export interface KalshiWsEventHandlers {
|
|
133
|
+
/** Called when connection is established */
|
|
134
|
+
onConnect?: () => void;
|
|
135
|
+
/** Called when connection is closed */
|
|
136
|
+
onDisconnect?: (code: number, reason: string) => void;
|
|
137
|
+
/** Called on any error */
|
|
138
|
+
onError?: (error: Error) => void;
|
|
139
|
+
/** Called when subscription is confirmed */
|
|
140
|
+
onSubscribed?: (channel: SubscriptionChannel, tickers?: string[]) => void;
|
|
141
|
+
/** Called on orderbook update */
|
|
142
|
+
onOrderbookDelta?: (data: OrderbookDeltaMessage['msg']) => void;
|
|
143
|
+
/** Called on ticker update */
|
|
144
|
+
onTicker?: (data: TickerMessage['msg']) => void;
|
|
145
|
+
/** Called on trade */
|
|
146
|
+
onTrade?: (data: TradeMessage['msg']) => void;
|
|
147
|
+
/** Called on fill (user's order filled) */
|
|
148
|
+
onFill?: (data: FillMessage['msg']) => void;
|
|
149
|
+
}
|
|
150
|
+
/** WebSocket connection state */
|
|
151
|
+
export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
|
|
152
|
+
/** Active subscriptions */
|
|
153
|
+
export interface ActiveSubscriptions {
|
|
154
|
+
orderbook_delta: Set<string>;
|
|
155
|
+
ticker: Set<string>;
|
|
156
|
+
trade: Set<string>;
|
|
157
|
+
fill: boolean;
|
|
158
|
+
}
|
|
159
|
+
export {};
|
|
160
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/websocket/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kalshi WebSocket Types
|
|
3
|
+
*
|
|
4
|
+
* Message formats for Kalshi's WebSocket API
|
|
5
|
+
* Based on: https://docs.kalshi.com/websockets
|
|
6
|
+
*/
|
|
7
|
+
/** WebSocket endpoints */
|
|
8
|
+
export const WS_ENDPOINTS = {
|
|
9
|
+
production: 'wss://api.elections.kalshi.com/trade-api/ws/v2',
|
|
10
|
+
demo: 'wss://demo-api.kalshi.co/trade-api/ws/v2',
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/websocket/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH,0BAA0B;AAC1B,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,UAAU,EAAE,gDAAgD;IAC5D,IAAI,EAAE,0CAA0C;CACxC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../src/websocket/types.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { WS_ENDPOINTS } from './types.js';
|
|
3
|
+
describe('WebSocket Types', () => {
|
|
4
|
+
describe('WS_ENDPOINTS', () => {
|
|
5
|
+
it('has production endpoint', () => {
|
|
6
|
+
expect(WS_ENDPOINTS.production).toBe('wss://api.elections.kalshi.com/trade-api/ws/v2');
|
|
7
|
+
});
|
|
8
|
+
it('has demo endpoint', () => {
|
|
9
|
+
expect(WS_ENDPOINTS.demo).toBe('wss://demo-api.kalshi.co/trade-api/ws/v2');
|
|
10
|
+
});
|
|
11
|
+
it('endpoints use secure WebSocket protocol', () => {
|
|
12
|
+
expect(WS_ENDPOINTS.production.startsWith('wss://')).toBe(true);
|
|
13
|
+
expect(WS_ENDPOINTS.demo.startsWith('wss://')).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=types.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/websocket/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;YACjC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;YAC3B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newyorkcompute/kalshi-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared utilities for Kalshi prediction market tools — SDK configuration, formatting, and types",
|
|
5
5
|
"author": "NewYorkCompute",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,15 +39,19 @@
|
|
|
39
39
|
"lint": "eslint src/",
|
|
40
40
|
"lint:fix": "eslint src/ --fix",
|
|
41
41
|
"test": "vitest run",
|
|
42
|
-
"test:watch": "vitest"
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"test:coverage": "vitest run --coverage"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
|
-
"kalshi-typescript": "^3.3.0"
|
|
46
|
+
"kalshi-typescript": "^3.3.0",
|
|
47
|
+
"ws": "^8.18.0"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
50
|
+
"@eslint/js": "^9.28.0",
|
|
48
51
|
"@types/node": "^22.15.29",
|
|
52
|
+
"@types/ws": "^8.5.13",
|
|
53
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
49
54
|
"eslint": "^9.28.0",
|
|
50
|
-
"@eslint/js": "^9.28.0",
|
|
51
55
|
"typescript-eslint": "^8.33.1",
|
|
52
56
|
"vitest": "^3.2.3"
|
|
53
57
|
}
|