@newyorkcompute/kalshi-core 0.2.0 → 0.4.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 +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mm/index.d.ts +10 -0
- package/dist/mm/index.d.ts.map +1 -0
- package/dist/mm/index.js +12 -0
- package/dist/mm/index.js.map +1 -0
- package/dist/mm/inventory.d.ts +70 -0
- package/dist/mm/inventory.d.ts.map +1 -0
- package/dist/mm/inventory.js +171 -0
- package/dist/mm/inventory.js.map +1 -0
- package/dist/mm/inventory.test.d.ts +2 -0
- package/dist/mm/inventory.test.d.ts.map +1 -0
- package/dist/mm/inventory.test.js +358 -0
- package/dist/mm/inventory.test.js.map +1 -0
- package/dist/mm/order-manager.d.ts +81 -0
- package/dist/mm/order-manager.d.ts.map +1 -0
- package/dist/mm/order-manager.js +216 -0
- package/dist/mm/order-manager.js.map +1 -0
- package/dist/mm/order-manager.test.d.ts +2 -0
- package/dist/mm/order-manager.test.d.ts.map +1 -0
- package/dist/mm/order-manager.test.js +333 -0
- package/dist/mm/order-manager.test.js.map +1 -0
- package/dist/mm/risk.d.ts +77 -0
- package/dist/mm/risk.d.ts.map +1 -0
- package/dist/mm/risk.js +179 -0
- package/dist/mm/risk.js.map +1 -0
- package/dist/mm/risk.test.d.ts +2 -0
- package/dist/mm/risk.test.d.ts.map +1 -0
- package/dist/mm/risk.test.js +297 -0
- package/dist/mm/risk.test.js.map +1 -0
- package/dist/mm/types.d.ts +128 -0
- package/dist/mm/types.d.ts.map +1 -0
- package/dist/mm/types.js +7 -0
- package/dist/mm/types.js.map +1 -0
- package/dist/websocket/auth.d.ts +35 -0
- package/dist/websocket/auth.d.ts.map +1 -0
- package/dist/websocket/auth.js +60 -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 +65 -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 +358 -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 +172 -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,95 @@
|
|
|
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 { type KalshiWsConfig, type KalshiWsEventHandlers, type SubscriptionChannel, type ConnectionState } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Kalshi WebSocket Client
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const client = new KalshiWsClient({
|
|
18
|
+
* apiKeyId: 'your-api-key',
|
|
19
|
+
* privateKey: 'your-private-key',
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* client.on('ticker', (data) => {
|
|
23
|
+
* console.log('Price update:', data.market_ticker, data.yes_bid);
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* await client.connect();
|
|
27
|
+
* client.subscribe(['ticker'], ['KXBTC-25JAN03']);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare class KalshiWsClient {
|
|
31
|
+
private config;
|
|
32
|
+
private ws;
|
|
33
|
+
private handlers;
|
|
34
|
+
private state;
|
|
35
|
+
private reconnectAttempts;
|
|
36
|
+
private commandId;
|
|
37
|
+
private pingTimer;
|
|
38
|
+
private pongTimer;
|
|
39
|
+
private subscriptions;
|
|
40
|
+
constructor(config: KalshiWsConfig);
|
|
41
|
+
/**
|
|
42
|
+
* Get current connection state
|
|
43
|
+
*/
|
|
44
|
+
get connectionState(): ConnectionState;
|
|
45
|
+
/**
|
|
46
|
+
* Check if connected
|
|
47
|
+
*/
|
|
48
|
+
get isConnected(): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Register event handlers
|
|
51
|
+
*/
|
|
52
|
+
on<K extends keyof KalshiWsEventHandlers>(event: K, handler: KalshiWsEventHandlers[K]): void;
|
|
53
|
+
/**
|
|
54
|
+
* Connect to WebSocket server
|
|
55
|
+
*/
|
|
56
|
+
connect(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Disconnect from WebSocket server
|
|
59
|
+
*/
|
|
60
|
+
disconnect(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Subscribe to channels for specific market tickers
|
|
63
|
+
*
|
|
64
|
+
* @param channels - Channels to subscribe to
|
|
65
|
+
* @param marketTickers - Market tickers (not needed for 'fill' channel)
|
|
66
|
+
*/
|
|
67
|
+
subscribe(channels: SubscriptionChannel[], marketTickers?: string[]): void;
|
|
68
|
+
/**
|
|
69
|
+
* Unsubscribe from channels
|
|
70
|
+
*/
|
|
71
|
+
unsubscribe(channels: SubscriptionChannel[], marketTickers?: string[]): void;
|
|
72
|
+
/**
|
|
73
|
+
* Add markets to existing subscription
|
|
74
|
+
*/
|
|
75
|
+
addMarkets(channels: SubscriptionChannel[], marketTickers: string[]): void;
|
|
76
|
+
/**
|
|
77
|
+
* Remove markets from existing subscription
|
|
78
|
+
*/
|
|
79
|
+
removeMarkets(channels: SubscriptionChannel[], marketTickers: string[]): void;
|
|
80
|
+
/**
|
|
81
|
+
* Get currently subscribed tickers for a channel
|
|
82
|
+
*/
|
|
83
|
+
getSubscribedTickers(channel: SubscriptionChannel): string[];
|
|
84
|
+
private send;
|
|
85
|
+
private handleMessage;
|
|
86
|
+
private handleClose;
|
|
87
|
+
private scheduleReconnect;
|
|
88
|
+
private resubscribeAll;
|
|
89
|
+
private updateLocalSubscriptions;
|
|
90
|
+
private startPingPong;
|
|
91
|
+
private stopPingPong;
|
|
92
|
+
private setPongTimeout;
|
|
93
|
+
private clearPongTimeout;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/websocket/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAG1B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EAGrB,MAAM,YAAY,CAAC;AAYpB;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,aAAa,CAKnB;gBAEU,MAAM,EAAE,cAAc;IAclC;;OAEG;IACH,IAAI,eAAe,IAAI,eAAe,CAErC;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,qBAAqB,EACtC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAChC,IAAI;IAIP;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAUlB;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,mBAAmB,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAoB1E;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,mBAAmB,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAmB5E;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,mBAAmB,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI;IAoB1E;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,mBAAmB,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI;IAoB7E;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,EAAE;IAS5D,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,aAAa;IAiDrB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,gBAAgB;CAMzB"}
|
|
@@ -0,0 +1,358 @@
|
|
|
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_snapshot':
|
|
244
|
+
this.handlers.onOrderbookSnapshot?.(message.msg);
|
|
245
|
+
break;
|
|
246
|
+
case 'orderbook_delta':
|
|
247
|
+
this.handlers.onOrderbookDelta?.(message.msg);
|
|
248
|
+
break;
|
|
249
|
+
case 'ticker':
|
|
250
|
+
this.handlers.onTicker?.(message.msg);
|
|
251
|
+
break;
|
|
252
|
+
case 'trade':
|
|
253
|
+
this.handlers.onTrade?.(message.msg);
|
|
254
|
+
break;
|
|
255
|
+
case 'fill':
|
|
256
|
+
this.handlers.onFill?.(message.msg);
|
|
257
|
+
break;
|
|
258
|
+
// Ignore ok, unsubscribed, and other operational messages
|
|
259
|
+
default:
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
this.handlers.onError?.(error instanceof Error ? error : new Error('Failed to parse message'));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
handleClose(code, reason) {
|
|
268
|
+
this.stopPingPong();
|
|
269
|
+
this.handlers.onDisconnect?.(code, reason);
|
|
270
|
+
if (this.config.autoReconnect &&
|
|
271
|
+
this.state !== 'disconnected' &&
|
|
272
|
+
this.reconnectAttempts < this.config.maxReconnectAttempts) {
|
|
273
|
+
this.scheduleReconnect();
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
this.state = 'disconnected';
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
scheduleReconnect() {
|
|
280
|
+
this.state = 'reconnecting';
|
|
281
|
+
this.reconnectAttempts++;
|
|
282
|
+
// Exponential backoff
|
|
283
|
+
const delay = this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
|
284
|
+
setTimeout(() => {
|
|
285
|
+
if (this.state === 'reconnecting') {
|
|
286
|
+
this.connect().catch((error) => {
|
|
287
|
+
this.handlers.onError?.(error);
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}, delay);
|
|
291
|
+
}
|
|
292
|
+
resubscribeAll() {
|
|
293
|
+
// Resubscribe to all previously active subscriptions
|
|
294
|
+
const channels = [];
|
|
295
|
+
const tickers = [];
|
|
296
|
+
for (const [channel, data] of Object.entries(this.subscriptions)) {
|
|
297
|
+
if (channel === 'fill') {
|
|
298
|
+
if (data === true) {
|
|
299
|
+
this.subscribe(['fill']);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else if (data instanceof Set && data.size > 0) {
|
|
303
|
+
channels.push(channel);
|
|
304
|
+
tickers.push(...data);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (channels.length > 0 && tickers.length > 0) {
|
|
308
|
+
const uniqueTickers = [...new Set(tickers)];
|
|
309
|
+
this.subscribe(channels, uniqueTickers);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
updateLocalSubscriptions(channels, tickers, action) {
|
|
313
|
+
for (const channel of channels) {
|
|
314
|
+
if (channel === 'fill') {
|
|
315
|
+
this.subscriptions.fill = action === 'add';
|
|
316
|
+
}
|
|
317
|
+
else if (tickers) {
|
|
318
|
+
for (const ticker of tickers) {
|
|
319
|
+
if (action === 'add') {
|
|
320
|
+
this.subscriptions[channel].add(ticker);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
this.subscriptions[channel].delete(ticker);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
startPingPong() {
|
|
330
|
+
this.pingTimer = setInterval(() => {
|
|
331
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
332
|
+
this.ws.ping();
|
|
333
|
+
this.setPongTimeout();
|
|
334
|
+
}
|
|
335
|
+
}, DEFAULTS.pingInterval);
|
|
336
|
+
}
|
|
337
|
+
stopPingPong() {
|
|
338
|
+
if (this.pingTimer) {
|
|
339
|
+
clearInterval(this.pingTimer);
|
|
340
|
+
this.pingTimer = null;
|
|
341
|
+
}
|
|
342
|
+
this.clearPongTimeout();
|
|
343
|
+
}
|
|
344
|
+
setPongTimeout() {
|
|
345
|
+
this.pongTimer = setTimeout(() => {
|
|
346
|
+
// No pong received, connection might be dead
|
|
347
|
+
this.handlers.onError?.(new Error('Pong timeout - connection may be dead'));
|
|
348
|
+
this.ws?.terminate();
|
|
349
|
+
}, DEFAULTS.pongTimeout);
|
|
350
|
+
}
|
|
351
|
+
clearPongTimeout() {
|
|
352
|
+
if (this.pongTimer) {
|
|
353
|
+
clearTimeout(this.pongTimer);
|
|
354
|
+
this.pongTimer = null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
//# 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,172 @@
|
|
|
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
|
+
/** Orderbook snapshot (full state) */
|
|
90
|
+
export interface OrderbookSnapshotMessage extends BaseMessage {
|
|
91
|
+
type: 'orderbook_snapshot';
|
|
92
|
+
msg: {
|
|
93
|
+
market_ticker: string;
|
|
94
|
+
market_id: string;
|
|
95
|
+
yes: [number, number][];
|
|
96
|
+
no: [number, number][];
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/** Ticker update (market price change) */
|
|
100
|
+
export interface TickerMessage extends BaseMessage {
|
|
101
|
+
type: 'ticker';
|
|
102
|
+
msg: {
|
|
103
|
+
market_ticker: string;
|
|
104
|
+
yes_bid: number;
|
|
105
|
+
yes_ask: number;
|
|
106
|
+
no_bid: number;
|
|
107
|
+
no_ask: number;
|
|
108
|
+
last_price: number;
|
|
109
|
+
volume: number;
|
|
110
|
+
open_interest: number;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Trade execution */
|
|
114
|
+
export interface TradeMessage extends BaseMessage {
|
|
115
|
+
type: 'trade';
|
|
116
|
+
msg: {
|
|
117
|
+
market_ticker: string;
|
|
118
|
+
trade_id: string;
|
|
119
|
+
price: number;
|
|
120
|
+
count: number;
|
|
121
|
+
taker_side: 'yes' | 'no';
|
|
122
|
+
created_time: string;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** User fill notification (authenticated) */
|
|
126
|
+
export interface FillMessage extends BaseMessage {
|
|
127
|
+
type: 'fill';
|
|
128
|
+
msg: {
|
|
129
|
+
trade_id: string;
|
|
130
|
+
order_id: string;
|
|
131
|
+
market_ticker: string;
|
|
132
|
+
side: 'yes' | 'no';
|
|
133
|
+
action: 'buy' | 'sell';
|
|
134
|
+
count: number;
|
|
135
|
+
price: number;
|
|
136
|
+
created_time: string;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/** All possible server messages */
|
|
140
|
+
export type WsMessage = SubscribedMessage | ErrorMessage | OrderbookDeltaMessage | OrderbookSnapshotMessage | TickerMessage | TradeMessage | FillMessage;
|
|
141
|
+
/** WebSocket event handlers */
|
|
142
|
+
export interface KalshiWsEventHandlers {
|
|
143
|
+
/** Called when connection is established */
|
|
144
|
+
onConnect?: () => void;
|
|
145
|
+
/** Called when connection is closed */
|
|
146
|
+
onDisconnect?: (code: number, reason: string) => void;
|
|
147
|
+
/** Called on any error */
|
|
148
|
+
onError?: (error: Error) => void;
|
|
149
|
+
/** Called when subscription is confirmed */
|
|
150
|
+
onSubscribed?: (channel: SubscriptionChannel, tickers?: string[]) => void;
|
|
151
|
+
/** Called on orderbook snapshot (initial state) */
|
|
152
|
+
onOrderbookSnapshot?: (data: OrderbookSnapshotMessage['msg']) => void;
|
|
153
|
+
/** Called on orderbook update */
|
|
154
|
+
onOrderbookDelta?: (data: OrderbookDeltaMessage['msg']) => void;
|
|
155
|
+
/** Called on ticker update */
|
|
156
|
+
onTicker?: (data: TickerMessage['msg']) => void;
|
|
157
|
+
/** Called on trade */
|
|
158
|
+
onTrade?: (data: TradeMessage['msg']) => void;
|
|
159
|
+
/** Called on fill (user's order filled) */
|
|
160
|
+
onFill?: (data: FillMessage['msg']) => void;
|
|
161
|
+
}
|
|
162
|
+
/** WebSocket connection state */
|
|
163
|
+
export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
|
|
164
|
+
/** Active subscriptions */
|
|
165
|
+
export interface ActiveSubscriptions {
|
|
166
|
+
orderbook_delta: Set<string>;
|
|
167
|
+
ticker: Set<string>;
|
|
168
|
+
trade: Set<string>;
|
|
169
|
+
fill: boolean;
|
|
170
|
+
}
|
|
171
|
+
export {};
|
|
172
|
+
//# 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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"}
|