pmxt-core 2.9.2 → 2.9.3
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/BaseExchange.d.ts +118 -4
- package/dist/BaseExchange.js +160 -7
- package/dist/exchanges/baozi/fetchEvents.js +16 -11
- package/dist/exchanges/baozi/index.d.ts +5 -0
- package/dist/exchanges/baozi/index.js +6 -0
- package/dist/exchanges/kalshi/api.d.ts +7 -1
- package/dist/exchanges/kalshi/api.js +11 -2
- package/dist/exchanges/kalshi/config.d.ts +103 -0
- package/dist/exchanges/kalshi/config.js +144 -0
- package/dist/exchanges/kalshi/fetchEvents.d.ts +2 -2
- package/dist/exchanges/kalshi/fetchEvents.js +138 -67
- package/dist/exchanges/kalshi/fetchMarkets.d.ts +2 -2
- package/dist/exchanges/kalshi/fetchMarkets.js +36 -25
- package/dist/exchanges/kalshi/fetchOHLCV.d.ts +3 -3
- package/dist/exchanges/kalshi/fetchOHLCV.js +20 -17
- package/dist/exchanges/kalshi/fetchOrderBook.d.ts +2 -0
- package/dist/exchanges/kalshi/fetchOrderBook.js +60 -0
- package/dist/exchanges/kalshi/fetchTrades.d.ts +3 -0
- package/dist/exchanges/kalshi/fetchTrades.js +32 -0
- package/dist/exchanges/kalshi/index.d.ts +20 -4
- package/dist/exchanges/kalshi/index.js +171 -90
- package/dist/exchanges/kalshi/kalshi.test.js +440 -157
- package/dist/exchanges/kalshi/utils.d.ts +1 -3
- package/dist/exchanges/kalshi/utils.js +15 -16
- package/dist/exchanges/kalshi/websocket.d.ts +4 -3
- package/dist/exchanges/kalshi/websocket.js +87 -61
- package/dist/exchanges/kalshi-demo/index.d.ts +10 -0
- package/dist/exchanges/kalshi-demo/index.js +23 -0
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/limitless/fetchEvents.d.ts +2 -1
- package/dist/exchanges/limitless/fetchEvents.js +95 -49
- package/dist/exchanges/limitless/fetchOHLCV.d.ts +2 -2
- package/dist/exchanges/limitless/index.d.ts +11 -3
- package/dist/exchanges/limitless/index.js +69 -1
- package/dist/exchanges/limitless/utils.js +1 -0
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/myriad/fetchOHLCV.d.ts +2 -2
- package/dist/exchanges/myriad/index.d.ts +9 -3
- package/dist/exchanges/myriad/index.js +34 -0
- package/dist/exchanges/myriad/utils.js +5 -1
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/polymarket/auth.js +3 -1
- package/dist/exchanges/polymarket/fetchEvents.js +116 -80
- package/dist/exchanges/polymarket/fetchOHLCV.d.ts +2 -2
- package/dist/exchanges/polymarket/index.d.ts +30 -6
- package/dist/exchanges/polymarket/index.js +101 -31
- package/dist/exchanges/polymarket/utils.js +1 -0
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/probable/index.d.ts +45 -3
- package/dist/exchanges/probable/index.js +61 -0
- package/dist/exchanges/probable/utils.js +5 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -1
- package/dist/server/app.js +56 -48
- package/dist/server/utils/port-manager.js +1 -1
- package/dist/types.d.ts +29 -0
- package/dist/utils/throttler.d.ts +17 -0
- package/dist/utils/throttler.js +50 -0
- package/package.json +7 -4
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { UnifiedMarket, CandleInterval } from
|
|
2
|
-
export declare const KALSHI_API_URL = "https://api.elections.kalshi.com/trade-api/v2/events";
|
|
3
|
-
export declare const KALSHI_SERIES_URL = "https://api.elections.kalshi.com/trade-api/v2/series";
|
|
1
|
+
import { UnifiedMarket, CandleInterval } from "../../types";
|
|
4
2
|
export declare function mapMarketToUnified(event: any, market: any): UnifiedMarket | null;
|
|
5
3
|
export declare function mapIntervalToKalshi(interval: CandleInterval): number;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.KALSHI_SERIES_URL = exports.KALSHI_API_URL = void 0;
|
|
4
3
|
exports.mapMarketToUnified = mapMarketToUnified;
|
|
5
4
|
exports.mapIntervalToKalshi = mapIntervalToKalshi;
|
|
6
5
|
const market_utils_1 = require("../../utils/market-utils");
|
|
7
|
-
exports.KALSHI_API_URL = "https://api.elections.kalshi.com/trade-api/v2/events";
|
|
8
|
-
exports.KALSHI_SERIES_URL = "https://api.elections.kalshi.com/trade-api/v2/series";
|
|
9
6
|
function mapMarketToUnified(event, market) {
|
|
10
7
|
if (!market)
|
|
11
8
|
return null;
|
|
@@ -27,24 +24,25 @@ function mapMarketToUnified(event, market) {
|
|
|
27
24
|
}
|
|
28
25
|
// Calculate 24h change
|
|
29
26
|
let priceChange = 0;
|
|
30
|
-
if (market.previous_price_dollars !== undefined &&
|
|
27
|
+
if (market.previous_price_dollars !== undefined &&
|
|
28
|
+
market.last_price_dollars !== undefined) {
|
|
31
29
|
priceChange = market.last_price_dollars - market.previous_price_dollars;
|
|
32
30
|
}
|
|
33
31
|
const outcomes = [
|
|
34
32
|
{
|
|
35
33
|
outcomeId: market.ticker,
|
|
36
34
|
marketId: market.ticker,
|
|
37
|
-
label: candidateName ||
|
|
35
|
+
label: candidateName || "Yes",
|
|
38
36
|
price: price,
|
|
39
|
-
priceChange24h: priceChange
|
|
37
|
+
priceChange24h: priceChange,
|
|
40
38
|
},
|
|
41
39
|
{
|
|
42
40
|
outcomeId: `${market.ticker}-NO`,
|
|
43
41
|
marketId: market.ticker,
|
|
44
|
-
label: candidateName ? `Not ${candidateName}` :
|
|
42
|
+
label: candidateName ? `Not ${candidateName}` : "No",
|
|
45
43
|
price: 1 - price,
|
|
46
|
-
priceChange24h: -priceChange // Inverse change for No? simplified assumption
|
|
47
|
-
}
|
|
44
|
+
priceChange24h: -priceChange, // Inverse change for No? simplified assumption
|
|
45
|
+
},
|
|
48
46
|
];
|
|
49
47
|
// Combine category and tags into a unified tags array
|
|
50
48
|
const unifiedTags = [];
|
|
@@ -63,6 +61,7 @@ function mapMarketToUnified(event, market) {
|
|
|
63
61
|
const um = {
|
|
64
62
|
id: market.ticker,
|
|
65
63
|
marketId: market.ticker,
|
|
64
|
+
eventId: event.event_ticker,
|
|
66
65
|
title: event.title,
|
|
67
66
|
description: market.rules_primary || market.rules_secondary || "",
|
|
68
67
|
outcomes: outcomes,
|
|
@@ -73,19 +72,19 @@ function mapMarketToUnified(event, market) {
|
|
|
73
72
|
openInterest: Number(market.open_interest || 0),
|
|
74
73
|
url: `https://kalshi.com/events/${event.event_ticker}`,
|
|
75
74
|
category: event.category,
|
|
76
|
-
tags: unifiedTags
|
|
75
|
+
tags: unifiedTags,
|
|
77
76
|
};
|
|
78
77
|
(0, market_utils_1.addBinaryOutcomes)(um);
|
|
79
78
|
return um;
|
|
80
79
|
}
|
|
81
80
|
function mapIntervalToKalshi(interval) {
|
|
82
81
|
const mapping = {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
"1m": 1,
|
|
83
|
+
"5m": 1,
|
|
84
|
+
"15m": 1,
|
|
85
|
+
"1h": 60,
|
|
86
|
+
"6h": 60,
|
|
87
|
+
"1d": 1440,
|
|
89
88
|
};
|
|
90
89
|
return mapping[interval];
|
|
91
90
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { OrderBook, Trade } from
|
|
2
|
-
import { KalshiAuth } from
|
|
1
|
+
import { OrderBook, Trade } from "../../types";
|
|
2
|
+
import { KalshiAuth } from "./auth";
|
|
3
3
|
export interface KalshiWebSocketConfig {
|
|
4
|
-
/** WebSocket URL
|
|
4
|
+
/** WebSocket URL - will be set based on demoMode if not provided */
|
|
5
5
|
wsUrl?: string;
|
|
6
6
|
/** Reconnection interval in milliseconds (default: 5000) */
|
|
7
7
|
reconnectIntervalMs?: number;
|
|
@@ -14,6 +14,7 @@ export declare class KalshiWebSocket {
|
|
|
14
14
|
private ws?;
|
|
15
15
|
private auth;
|
|
16
16
|
private config;
|
|
17
|
+
private wsUrl;
|
|
17
18
|
private orderBookResolvers;
|
|
18
19
|
private tradeResolvers;
|
|
19
20
|
private orderBooks;
|
|
@@ -13,6 +13,7 @@ class KalshiWebSocket {
|
|
|
13
13
|
ws;
|
|
14
14
|
auth;
|
|
15
15
|
config;
|
|
16
|
+
wsUrl;
|
|
16
17
|
orderBookResolvers = new Map();
|
|
17
18
|
tradeResolvers = new Map();
|
|
18
19
|
orderBooks = new Map();
|
|
@@ -26,10 +27,8 @@ class KalshiWebSocket {
|
|
|
26
27
|
isTerminated = false;
|
|
27
28
|
constructor(auth, config = {}) {
|
|
28
29
|
this.auth = auth;
|
|
29
|
-
this.config =
|
|
30
|
-
|
|
31
|
-
reconnectIntervalMs: config.reconnectIntervalMs || 5000
|
|
32
|
-
};
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.wsUrl = config.wsUrl; // wsUrl must be provided by caller (from KalshiExchange)
|
|
33
32
|
}
|
|
34
33
|
async connect() {
|
|
35
34
|
if (this.isConnected) {
|
|
@@ -45,17 +44,17 @@ class KalshiWebSocket {
|
|
|
45
44
|
this.connectionPromise = new Promise((resolve, reject) => {
|
|
46
45
|
try {
|
|
47
46
|
// Extract path from URL for signature
|
|
48
|
-
const url = new URL(this.
|
|
47
|
+
const url = new URL(this.wsUrl);
|
|
49
48
|
const path = url.pathname;
|
|
50
|
-
console.log(`Kalshi WS: Connecting to ${this.
|
|
49
|
+
console.log(`Kalshi WS: Connecting to ${this.wsUrl} (using path ${path} for signature)`);
|
|
51
50
|
// Get authentication headers
|
|
52
|
-
const headers = this.auth.getHeaders(
|
|
53
|
-
this.ws = new ws_1.default(this.
|
|
54
|
-
this.ws.on(
|
|
51
|
+
const headers = this.auth.getHeaders("GET", path);
|
|
52
|
+
this.ws = new ws_1.default(this.wsUrl, { headers });
|
|
53
|
+
this.ws.on("open", () => {
|
|
55
54
|
this.isConnected = true;
|
|
56
55
|
this.isConnecting = false;
|
|
57
56
|
this.connectionPromise = undefined;
|
|
58
|
-
console.log(
|
|
57
|
+
console.log("Kalshi WebSocket connected");
|
|
59
58
|
// Resubscribe to all tickers if reconnecting
|
|
60
59
|
if (this.subscribedOrderBookTickers.size > 0) {
|
|
61
60
|
this.subscribeToOrderbook(Array.from(this.subscribedOrderBookTickers));
|
|
@@ -65,24 +64,24 @@ class KalshiWebSocket {
|
|
|
65
64
|
}
|
|
66
65
|
resolve();
|
|
67
66
|
});
|
|
68
|
-
this.ws.on(
|
|
67
|
+
this.ws.on("message", (data) => {
|
|
69
68
|
try {
|
|
70
69
|
const message = JSON.parse(data.toString());
|
|
71
70
|
this.handleMessage(message);
|
|
72
71
|
}
|
|
73
72
|
catch (error) {
|
|
74
|
-
console.error(
|
|
73
|
+
console.error("Error parsing Kalshi WebSocket message:", error);
|
|
75
74
|
}
|
|
76
75
|
});
|
|
77
|
-
this.ws.on(
|
|
78
|
-
console.error(
|
|
76
|
+
this.ws.on("error", (error) => {
|
|
77
|
+
console.error("Kalshi WebSocket error:", error);
|
|
79
78
|
this.isConnecting = false;
|
|
80
79
|
this.connectionPromise = undefined;
|
|
81
80
|
reject(error);
|
|
82
81
|
});
|
|
83
|
-
this.ws.on(
|
|
82
|
+
this.ws.on("close", () => {
|
|
84
83
|
if (!this.isTerminated) {
|
|
85
|
-
console.log(
|
|
84
|
+
console.log("Kalshi WebSocket closed");
|
|
86
85
|
this.scheduleReconnect();
|
|
87
86
|
}
|
|
88
87
|
this.isConnected = false;
|
|
@@ -106,9 +105,9 @@ class KalshiWebSocket {
|
|
|
106
105
|
clearTimeout(this.reconnectTimer);
|
|
107
106
|
}
|
|
108
107
|
this.reconnectTimer = setTimeout(() => {
|
|
109
|
-
console.log(
|
|
108
|
+
console.log("Attempting to reconnect Kalshi WebSocket...");
|
|
110
109
|
this.connect().catch(console.error);
|
|
111
|
-
}, this.config.reconnectIntervalMs);
|
|
110
|
+
}, this.config.reconnectIntervalMs || 5000);
|
|
112
111
|
}
|
|
113
112
|
subscribeToOrderbook(marketTickers) {
|
|
114
113
|
if (!this.ws || !this.isConnected) {
|
|
@@ -116,11 +115,11 @@ class KalshiWebSocket {
|
|
|
116
115
|
}
|
|
117
116
|
const subscription = {
|
|
118
117
|
id: this.messageIdCounter++,
|
|
119
|
-
cmd:
|
|
118
|
+
cmd: "subscribe",
|
|
120
119
|
params: {
|
|
121
|
-
channels: [
|
|
122
|
-
market_tickers: marketTickers
|
|
123
|
-
}
|
|
120
|
+
channels: ["orderbook_delta"],
|
|
121
|
+
market_tickers: marketTickers,
|
|
122
|
+
},
|
|
124
123
|
};
|
|
125
124
|
this.ws.send(JSON.stringify(subscription));
|
|
126
125
|
}
|
|
@@ -130,11 +129,11 @@ class KalshiWebSocket {
|
|
|
130
129
|
}
|
|
131
130
|
const subscription = {
|
|
132
131
|
id: this.messageIdCounter++,
|
|
133
|
-
cmd:
|
|
132
|
+
cmd: "subscribe",
|
|
134
133
|
params: {
|
|
135
|
-
channels: [
|
|
136
|
-
market_tickers: marketTickers
|
|
137
|
-
}
|
|
134
|
+
channels: ["trade"],
|
|
135
|
+
market_tickers: marketTickers,
|
|
136
|
+
},
|
|
138
137
|
};
|
|
139
138
|
this.ws.send(JSON.stringify(subscription));
|
|
140
139
|
}
|
|
@@ -142,31 +141,31 @@ class KalshiWebSocket {
|
|
|
142
141
|
const msgType = message.type;
|
|
143
142
|
// Kalshi V2 uses 'data' field for payloads
|
|
144
143
|
const data = message.data || message.msg;
|
|
145
|
-
if (!data && msgType !==
|
|
144
|
+
if (!data && msgType !== "subscribed" && msgType !== "pong") {
|
|
146
145
|
return;
|
|
147
146
|
}
|
|
148
147
|
// Add message-level timestamp as a fallback for handlers
|
|
149
|
-
if (data && typeof data ===
|
|
148
|
+
if (data && typeof data === "object" && !data.ts && !data.created_time) {
|
|
150
149
|
data.message_ts = message.ts || message.time;
|
|
151
150
|
}
|
|
152
151
|
switch (msgType) {
|
|
153
|
-
case
|
|
152
|
+
case "orderbook_snapshot":
|
|
154
153
|
this.handleOrderbookSnapshot(data);
|
|
155
154
|
break;
|
|
156
|
-
case
|
|
157
|
-
case
|
|
155
|
+
case "orderbook_delta":
|
|
156
|
+
case "orderbook_update": // Some versions use update
|
|
158
157
|
this.handleOrderbookDelta(data);
|
|
159
158
|
break;
|
|
160
|
-
case
|
|
159
|
+
case "trade":
|
|
161
160
|
this.handleTrade(data);
|
|
162
161
|
break;
|
|
163
|
-
case
|
|
164
|
-
console.error(
|
|
162
|
+
case "error":
|
|
163
|
+
console.error("Kalshi WebSocket error:", message.msg || message.error || message.data);
|
|
165
164
|
break;
|
|
166
|
-
case
|
|
167
|
-
console.log(
|
|
165
|
+
case "subscribed":
|
|
166
|
+
console.log("Kalshi subscription confirmed:", JSON.stringify(message));
|
|
168
167
|
break;
|
|
169
|
-
case
|
|
168
|
+
case "pong":
|
|
170
169
|
// Ignore keep-alive
|
|
171
170
|
break;
|
|
172
171
|
default:
|
|
@@ -179,20 +178,32 @@ class KalshiWebSocket {
|
|
|
179
178
|
// Kalshi orderbook structure:
|
|
180
179
|
// yes: [{ price: number (cents), quantity: number }, ...]
|
|
181
180
|
// no: [{ price: number (cents), quantity: number }, ...]
|
|
182
|
-
const bids = (data.yes || [])
|
|
181
|
+
const bids = (data.yes || [])
|
|
182
|
+
.map((level) => {
|
|
183
183
|
const price = (level.price || level[0]) / 100;
|
|
184
|
-
const size = (level.quantity !== undefined
|
|
184
|
+
const size = (level.quantity !== undefined
|
|
185
|
+
? level.quantity
|
|
186
|
+
: level.size !== undefined
|
|
187
|
+
? level.size
|
|
188
|
+
: level[1]) || 0;
|
|
185
189
|
return { price, size };
|
|
186
|
-
})
|
|
187
|
-
|
|
190
|
+
})
|
|
191
|
+
.sort((a, b) => b.price - a.price);
|
|
192
|
+
const asks = (data.no || [])
|
|
193
|
+
.map((level) => {
|
|
188
194
|
const price = (100 - (level.price || level[0])) / 100;
|
|
189
|
-
const size = (level.quantity !== undefined
|
|
195
|
+
const size = (level.quantity !== undefined
|
|
196
|
+
? level.quantity
|
|
197
|
+
: level.size !== undefined
|
|
198
|
+
? level.size
|
|
199
|
+
: level[1]) || 0;
|
|
190
200
|
return { price, size };
|
|
191
|
-
})
|
|
201
|
+
})
|
|
202
|
+
.sort((a, b) => a.price - b.price);
|
|
192
203
|
const orderBook = {
|
|
193
204
|
bids,
|
|
194
205
|
asks,
|
|
195
|
-
timestamp: Date.now()
|
|
206
|
+
timestamp: Date.now(),
|
|
196
207
|
};
|
|
197
208
|
this.orderBooks.set(ticker, orderBook);
|
|
198
209
|
this.resolveOrderBook(ticker, orderBook);
|
|
@@ -206,21 +217,25 @@ class KalshiWebSocket {
|
|
|
206
217
|
}
|
|
207
218
|
// Apply delta updates
|
|
208
219
|
// Kalshi sends: { price: number, delta: number, side: 'yes' | 'no' }
|
|
209
|
-
const price =
|
|
210
|
-
const delta = data.delta !== undefined
|
|
220
|
+
const price = data.price / 100;
|
|
221
|
+
const delta = data.delta !== undefined
|
|
222
|
+
? data.delta
|
|
223
|
+
: data.quantity !== undefined
|
|
224
|
+
? data.quantity
|
|
225
|
+
: 0;
|
|
211
226
|
const side = data.side;
|
|
212
|
-
if (side ===
|
|
213
|
-
this.applyDelta(existing.bids, price, delta,
|
|
227
|
+
if (side === "yes") {
|
|
228
|
+
this.applyDelta(existing.bids, price, delta, "desc");
|
|
214
229
|
}
|
|
215
230
|
else {
|
|
216
231
|
const yesPrice = (100 - data.price) / 100;
|
|
217
|
-
this.applyDelta(existing.asks, yesPrice, delta,
|
|
232
|
+
this.applyDelta(existing.asks, yesPrice, delta, "asc");
|
|
218
233
|
}
|
|
219
234
|
existing.timestamp = Date.now();
|
|
220
235
|
this.resolveOrderBook(ticker, existing);
|
|
221
236
|
}
|
|
222
237
|
applyDelta(levels, price, delta, sortOrder) {
|
|
223
|
-
const existingIndex = levels.findIndex(l => Math.abs(l.price - price) < 0.001);
|
|
238
|
+
const existingIndex = levels.findIndex((l) => Math.abs(l.price - price) < 0.001);
|
|
224
239
|
if (delta === 0) {
|
|
225
240
|
// Remove level
|
|
226
241
|
if (existingIndex !== -1) {
|
|
@@ -238,7 +253,7 @@ class KalshiWebSocket {
|
|
|
238
253
|
else {
|
|
239
254
|
levels.push({ price, size: delta });
|
|
240
255
|
// Re-sort
|
|
241
|
-
if (sortOrder ===
|
|
256
|
+
if (sortOrder === "desc") {
|
|
242
257
|
levels.sort((a, b) => b.price - a.price);
|
|
243
258
|
}
|
|
244
259
|
else {
|
|
@@ -253,7 +268,11 @@ class KalshiWebSocket {
|
|
|
253
268
|
// { trade_id, market_ticker, yes_price, no_price, count, created_time, taker_side }
|
|
254
269
|
// The timestamp could be in created_time, created_at, or ts.
|
|
255
270
|
let timestamp = Date.now();
|
|
256
|
-
const rawTime = data.created_time ||
|
|
271
|
+
const rawTime = data.created_time ||
|
|
272
|
+
data.created_at ||
|
|
273
|
+
data.ts ||
|
|
274
|
+
data.time ||
|
|
275
|
+
data.message_ts;
|
|
257
276
|
if (rawTime) {
|
|
258
277
|
const parsed = new Date(rawTime).getTime();
|
|
259
278
|
if (!isNaN(parsed)) {
|
|
@@ -263,7 +282,7 @@ class KalshiWebSocket {
|
|
|
263
282
|
timestamp *= 1000;
|
|
264
283
|
}
|
|
265
284
|
}
|
|
266
|
-
else if (typeof rawTime ===
|
|
285
|
+
else if (typeof rawTime === "number") {
|
|
267
286
|
// If it's already a number but new Date() failed (maybe it's a large timestamp)
|
|
268
287
|
timestamp = rawTime;
|
|
269
288
|
if (timestamp < 10000000000) {
|
|
@@ -274,20 +293,26 @@ class KalshiWebSocket {
|
|
|
274
293
|
const trade = {
|
|
275
294
|
id: data.trade_id || `${timestamp}-${Math.random()}`,
|
|
276
295
|
timestamp,
|
|
277
|
-
price:
|
|
296
|
+
price: data.yes_price || data.price
|
|
297
|
+
? (data.yes_price || data.price) / 100
|
|
298
|
+
: 0.5,
|
|
278
299
|
amount: data.count || data.size || 0,
|
|
279
|
-
side: data.taker_side ===
|
|
300
|
+
side: data.taker_side === "yes" || data.side === "buy"
|
|
301
|
+
? "buy"
|
|
302
|
+
: data.taker_side === "no" || data.side === "sell"
|
|
303
|
+
? "sell"
|
|
304
|
+
: "unknown",
|
|
280
305
|
};
|
|
281
306
|
const resolvers = this.tradeResolvers.get(ticker);
|
|
282
307
|
if (resolvers && resolvers.length > 0) {
|
|
283
|
-
resolvers.forEach(r => r.resolve([trade]));
|
|
308
|
+
resolvers.forEach((r) => r.resolve([trade]));
|
|
284
309
|
this.tradeResolvers.set(ticker, []);
|
|
285
310
|
}
|
|
286
311
|
}
|
|
287
312
|
resolveOrderBook(ticker, orderBook) {
|
|
288
313
|
const resolvers = this.orderBookResolvers.get(ticker);
|
|
289
314
|
if (resolvers && resolvers.length > 0) {
|
|
290
|
-
resolvers.forEach(r => r.resolve(orderBook));
|
|
315
|
+
resolvers.forEach((r) => r.resolve(orderBook));
|
|
291
316
|
this.orderBookResolvers.set(ticker, []);
|
|
292
317
|
}
|
|
293
318
|
}
|
|
@@ -335,19 +360,20 @@ class KalshiWebSocket {
|
|
|
335
360
|
}
|
|
336
361
|
// Reject all pending resolvers
|
|
337
362
|
this.orderBookResolvers.forEach((resolvers, ticker) => {
|
|
338
|
-
resolvers.forEach(r => r.reject(new Error(`WebSocket closed for ${ticker}`)));
|
|
363
|
+
resolvers.forEach((r) => r.reject(new Error(`WebSocket closed for ${ticker}`)));
|
|
339
364
|
});
|
|
340
365
|
this.orderBookResolvers.clear();
|
|
341
366
|
this.tradeResolvers.forEach((resolvers, ticker) => {
|
|
342
|
-
resolvers.forEach(r => r.reject(new Error(`WebSocket closed for ${ticker}`)));
|
|
367
|
+
resolvers.forEach((r) => r.reject(new Error(`WebSocket closed for ${ticker}`)));
|
|
343
368
|
});
|
|
344
369
|
this.tradeResolvers.clear();
|
|
345
370
|
if (this.ws) {
|
|
346
371
|
const ws = this.ws;
|
|
347
372
|
this.ws = undefined;
|
|
348
|
-
if (ws.readyState !== ws_1.default.CLOSED &&
|
|
373
|
+
if (ws.readyState !== ws_1.default.CLOSED &&
|
|
374
|
+
ws.readyState !== ws_1.default.CLOSING) {
|
|
349
375
|
return new Promise((resolve) => {
|
|
350
|
-
ws.once(
|
|
376
|
+
ws.once("close", () => {
|
|
351
377
|
this.isConnected = false;
|
|
352
378
|
this.isConnecting = false;
|
|
353
379
|
resolve();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ExchangeCredentials } from "../../BaseExchange";
|
|
2
|
+
import { KalshiExchange, KalshiWebSocketConfig } from "../kalshi";
|
|
3
|
+
export interface KalshiDemoExchangeOptions {
|
|
4
|
+
credentials?: ExchangeCredentials;
|
|
5
|
+
websocket?: KalshiWebSocketConfig;
|
|
6
|
+
}
|
|
7
|
+
export declare class KalshiDemoExchange extends KalshiExchange {
|
|
8
|
+
constructor(options?: ExchangeCredentials | KalshiDemoExchangeOptions);
|
|
9
|
+
get name(): string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KalshiDemoExchange = void 0;
|
|
4
|
+
const kalshi_1 = require("../kalshi");
|
|
5
|
+
class KalshiDemoExchange extends kalshi_1.KalshiExchange {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
// Normalise: accept either plain credentials or the options-object form,
|
|
8
|
+
// then force demoMode: true.
|
|
9
|
+
if (options && "credentials" in options) {
|
|
10
|
+
super({ ...options, demoMode: true });
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
super({
|
|
14
|
+
credentials: options,
|
|
15
|
+
demoMode: true,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
get name() {
|
|
20
|
+
return "KalshiDemo";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.KalshiDemoExchange = KalshiDemoExchange;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
3
|
-
* Generated at: 2026-
|
|
3
|
+
* Generated at: 2026-03-04T17:45:20.621Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const limitlessApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.limitlessApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
6
|
-
* Generated at: 2026-
|
|
6
|
+
* Generated at: 2026-03-04T17:45:20.621Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.limitlessApiSpec = {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { EventFetchParams } from '../../BaseExchange';
|
|
2
2
|
import { UnifiedEvent } from '../../types';
|
|
3
|
-
|
|
3
|
+
import { AxiosInstance } from 'axios';
|
|
4
|
+
export declare function fetchEvents(params: EventFetchParams, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>, http?: AxiosInstance): Promise<UnifiedEvent[]>;
|