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
|
@@ -47,12 +47,18 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
47
47
|
fetchBalance: true,
|
|
48
48
|
watchOrderBook: true,
|
|
49
49
|
watchTrades: false,
|
|
50
|
+
fetchMyTrades: true,
|
|
51
|
+
fetchClosedOrders: false,
|
|
52
|
+
fetchAllOrders: false,
|
|
53
|
+
buildOrder: false,
|
|
54
|
+
submitOrder: false,
|
|
50
55
|
};
|
|
51
56
|
auth;
|
|
52
57
|
ws;
|
|
53
58
|
wsConfig;
|
|
54
59
|
constructor(credentials, wsConfig) {
|
|
55
60
|
super(credentials);
|
|
61
|
+
this.rateLimit = 500;
|
|
56
62
|
this.wsConfig = wsConfig;
|
|
57
63
|
if (credentials?.privateKey && credentials?.apiKey && credentials?.apiSecret && credentials?.passphrase) {
|
|
58
64
|
this.auth = new auth_1.ProbableAuth(credentials);
|
|
@@ -82,9 +88,45 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
82
88
|
async fetchEventsImpl(params) {
|
|
83
89
|
return (0, fetchEvents_1.fetchEvents)(params, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }), (queryParams) => this.callApi('getPublicApiV1PublicSearch', queryParams));
|
|
84
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Fetch a single event by its numeric ID (Probable only).
|
|
93
|
+
*
|
|
94
|
+
* @param id - The numeric event ID
|
|
95
|
+
* @returns The UnifiedEvent, or null if not found
|
|
96
|
+
*
|
|
97
|
+
* @example-ts Get event by ID
|
|
98
|
+
* const event = await exchange.getEventById('42');
|
|
99
|
+
* if (event) {
|
|
100
|
+
* console.log(event.title);
|
|
101
|
+
* console.log(event.markets.length, 'markets');
|
|
102
|
+
* }
|
|
103
|
+
*
|
|
104
|
+
* @example-python Get event by ID
|
|
105
|
+
* event = exchange.get_event_by_id('42')
|
|
106
|
+
* if event:
|
|
107
|
+
* print(event.title)
|
|
108
|
+
* print(len(event.markets), 'markets')
|
|
109
|
+
*/
|
|
85
110
|
async getEventById(id) {
|
|
86
111
|
return (0, fetchEvents_1.fetchEventById)(id, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
|
|
87
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Fetch a single event by its URL slug (Probable only).
|
|
115
|
+
*
|
|
116
|
+
* @param slug - The event's URL slug (e.g. `"trump-2024-election"`)
|
|
117
|
+
* @returns The UnifiedEvent, or null if not found
|
|
118
|
+
*
|
|
119
|
+
* @example-ts Get event by slug
|
|
120
|
+
* const event = await exchange.getEventBySlug('trump-2024-election');
|
|
121
|
+
* if (event) {
|
|
122
|
+
* console.log(event.title);
|
|
123
|
+
* }
|
|
124
|
+
*
|
|
125
|
+
* @example-python Get event by slug
|
|
126
|
+
* event = exchange.get_event_by_slug('trump-2024-election')
|
|
127
|
+
* if event:
|
|
128
|
+
* print(event.title)
|
|
129
|
+
*/
|
|
88
130
|
async getEventBySlug(slug) {
|
|
89
131
|
return (0, fetchEvents_1.fetchEventBySlug)(slug, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
|
|
90
132
|
}
|
|
@@ -142,6 +184,25 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
142
184
|
}
|
|
143
185
|
return candles;
|
|
144
186
|
}
|
|
187
|
+
async fetchMyTrades(params) {
|
|
188
|
+
const auth = this.ensureAuth();
|
|
189
|
+
const address = auth.getAddress();
|
|
190
|
+
const queryParams = { user: address };
|
|
191
|
+
if (params?.limit)
|
|
192
|
+
queryParams.limit = params.limit;
|
|
193
|
+
const data = await this.callApi('getPublicApiV1Trades', queryParams);
|
|
194
|
+
const trades = Array.isArray(data) ? data : (data.data || []);
|
|
195
|
+
return trades.map((t) => ({
|
|
196
|
+
id: String(t.tradeId || t.id || t.timestamp),
|
|
197
|
+
timestamp: typeof t.time === 'number'
|
|
198
|
+
? (t.time > 1e12 ? t.time : t.time * 1000)
|
|
199
|
+
: Date.now(),
|
|
200
|
+
price: parseFloat(t.price || '0'),
|
|
201
|
+
amount: parseFloat(t.qty || t.size || t.amount || '0'),
|
|
202
|
+
side: (t.side || '').toLowerCase() === 'buy' ? 'buy' : 'sell',
|
|
203
|
+
orderId: t.orderId,
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
145
206
|
// --------------------------------------------------------------------------
|
|
146
207
|
// Trading Methods
|
|
147
208
|
// --------------------------------------------------------------------------
|
|
@@ -29,6 +29,7 @@ function mapMarketToUnified(market, event) {
|
|
|
29
29
|
}
|
|
30
30
|
const um = {
|
|
31
31
|
marketId: String(market.id),
|
|
32
|
+
eventId: event ? String(event.id) : (market.event_id ? String(market.event_id) : undefined),
|
|
32
33
|
title: market.question || market.title || '',
|
|
33
34
|
description: market.description || '',
|
|
34
35
|
outcomes,
|
|
@@ -56,17 +57,20 @@ function mapEventToUnified(event) {
|
|
|
56
57
|
markets.push(mapped);
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
const unifiedEvent = {
|
|
60
61
|
id: String(event.id),
|
|
61
62
|
title: event.title || '',
|
|
62
63
|
description: event.description || '',
|
|
63
64
|
slug: event.slug || '',
|
|
64
65
|
markets,
|
|
66
|
+
volume24h: markets.reduce((sum, m) => sum + m.volume24h, 0),
|
|
67
|
+
volume: markets.some(m => m.volume !== undefined) ? markets.reduce((sum, m) => sum + (m.volume ?? 0), 0) : undefined,
|
|
65
68
|
url: `https://probable.markets/events/${event.slug || event.id}`,
|
|
66
69
|
image: event.icon || event.image || undefined,
|
|
67
70
|
category: event.category || undefined,
|
|
68
71
|
tags: event.tags || [],
|
|
69
72
|
};
|
|
73
|
+
return unifiedEvent;
|
|
70
74
|
}
|
|
71
75
|
async function enrichMarketsWithPrices(markets, callMidpoint) {
|
|
72
76
|
const outcomes = [];
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './errors';
|
|
|
6
6
|
export * from './exchanges/polymarket';
|
|
7
7
|
export * from './exchanges/limitless';
|
|
8
8
|
export * from './exchanges/kalshi';
|
|
9
|
+
export * from './exchanges/kalshi-demo';
|
|
9
10
|
export * from './exchanges/probable';
|
|
10
11
|
export * from './exchanges/baozi';
|
|
11
12
|
export * from './exchanges/myriad';
|
|
@@ -15,6 +16,7 @@ export * from './server/utils/lock-file';
|
|
|
15
16
|
import { PolymarketExchange } from './exchanges/polymarket';
|
|
16
17
|
import { LimitlessExchange } from './exchanges/limitless';
|
|
17
18
|
import { KalshiExchange } from './exchanges/kalshi';
|
|
19
|
+
import { KalshiDemoExchange } from './exchanges/kalshi-demo';
|
|
18
20
|
import { ProbableExchange } from './exchanges/probable';
|
|
19
21
|
import { BaoziExchange } from './exchanges/baozi';
|
|
20
22
|
import { MyriadExchange } from './exchanges/myriad';
|
|
@@ -22,6 +24,7 @@ declare const pmxt: {
|
|
|
22
24
|
Polymarket: typeof PolymarketExchange;
|
|
23
25
|
Limitless: typeof LimitlessExchange;
|
|
24
26
|
Kalshi: typeof KalshiExchange;
|
|
27
|
+
KalshiDemo: typeof KalshiDemoExchange;
|
|
25
28
|
Probable: typeof ProbableExchange;
|
|
26
29
|
Baozi: typeof BaoziExchange;
|
|
27
30
|
Myriad: typeof MyriadExchange;
|
|
@@ -29,6 +32,7 @@ declare const pmxt: {
|
|
|
29
32
|
export declare const Polymarket: typeof PolymarketExchange;
|
|
30
33
|
export declare const Limitless: typeof LimitlessExchange;
|
|
31
34
|
export declare const Kalshi: typeof KalshiExchange;
|
|
35
|
+
export declare const KalshiDemo: typeof KalshiDemoExchange;
|
|
32
36
|
export declare const Probable: typeof ProbableExchange;
|
|
33
37
|
export declare const Baozi: typeof BaoziExchange;
|
|
34
38
|
export declare const Myriad: typeof MyriadExchange;
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.Myriad = exports.Baozi = exports.Probable = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.parseOpenApiSpec = void 0;
|
|
17
|
+
exports.Myriad = exports.Baozi = exports.Probable = exports.KalshiDemo = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.parseOpenApiSpec = void 0;
|
|
18
18
|
__exportStar(require("./BaseExchange"), exports);
|
|
19
19
|
__exportStar(require("./types"), exports);
|
|
20
20
|
__exportStar(require("./utils/math"), exports);
|
|
@@ -24,6 +24,7 @@ __exportStar(require("./errors"), exports);
|
|
|
24
24
|
__exportStar(require("./exchanges/polymarket"), exports);
|
|
25
25
|
__exportStar(require("./exchanges/limitless"), exports);
|
|
26
26
|
__exportStar(require("./exchanges/kalshi"), exports);
|
|
27
|
+
__exportStar(require("./exchanges/kalshi-demo"), exports);
|
|
27
28
|
__exportStar(require("./exchanges/probable"), exports);
|
|
28
29
|
__exportStar(require("./exchanges/baozi"), exports);
|
|
29
30
|
__exportStar(require("./exchanges/myriad"), exports);
|
|
@@ -33,6 +34,7 @@ __exportStar(require("./server/utils/lock-file"), exports);
|
|
|
33
34
|
const polymarket_1 = require("./exchanges/polymarket");
|
|
34
35
|
const limitless_1 = require("./exchanges/limitless");
|
|
35
36
|
const kalshi_1 = require("./exchanges/kalshi");
|
|
37
|
+
const kalshi_demo_1 = require("./exchanges/kalshi-demo");
|
|
36
38
|
const probable_1 = require("./exchanges/probable");
|
|
37
39
|
const baozi_1 = require("./exchanges/baozi");
|
|
38
40
|
const myriad_1 = require("./exchanges/myriad");
|
|
@@ -40,6 +42,7 @@ const pmxt = {
|
|
|
40
42
|
Polymarket: polymarket_1.PolymarketExchange,
|
|
41
43
|
Limitless: limitless_1.LimitlessExchange,
|
|
42
44
|
Kalshi: kalshi_1.KalshiExchange,
|
|
45
|
+
KalshiDemo: kalshi_demo_1.KalshiDemoExchange,
|
|
43
46
|
Probable: probable_1.ProbableExchange,
|
|
44
47
|
Baozi: baozi_1.BaoziExchange,
|
|
45
48
|
Myriad: myriad_1.MyriadExchange
|
|
@@ -47,6 +50,7 @@ const pmxt = {
|
|
|
47
50
|
exports.Polymarket = polymarket_1.PolymarketExchange;
|
|
48
51
|
exports.Limitless = limitless_1.LimitlessExchange;
|
|
49
52
|
exports.Kalshi = kalshi_1.KalshiExchange;
|
|
53
|
+
exports.KalshiDemo = kalshi_demo_1.KalshiDemoExchange;
|
|
50
54
|
exports.Probable = probable_1.ProbableExchange;
|
|
51
55
|
exports.Baozi = baozi_1.BaoziExchange;
|
|
52
56
|
exports.Myriad = myriad_1.MyriadExchange;
|
package/dist/server/app.js
CHANGED
|
@@ -9,6 +9,7 @@ const cors_1 = __importDefault(require("cors"));
|
|
|
9
9
|
const polymarket_1 = require("../exchanges/polymarket");
|
|
10
10
|
const limitless_1 = require("../exchanges/limitless");
|
|
11
11
|
const kalshi_1 = require("../exchanges/kalshi");
|
|
12
|
+
const kalshi_demo_1 = require("../exchanges/kalshi-demo");
|
|
12
13
|
const probable_1 = require("../exchanges/probable");
|
|
13
14
|
const baozi_1 = require("../exchanges/baozi");
|
|
14
15
|
const myriad_1 = require("../exchanges/myriad");
|
|
@@ -18,44 +19,34 @@ const defaultExchanges = {
|
|
|
18
19
|
polymarket: null,
|
|
19
20
|
limitless: null,
|
|
20
21
|
kalshi: null,
|
|
22
|
+
"kalshi-demo": null,
|
|
21
23
|
probable: null,
|
|
22
24
|
baozi: null,
|
|
23
|
-
myriad: null
|
|
25
|
+
myriad: null,
|
|
24
26
|
};
|
|
25
27
|
async function startServer(port, accessToken) {
|
|
26
28
|
const app = (0, express_1.default)();
|
|
27
29
|
app.use((0, cors_1.default)());
|
|
28
30
|
app.use(express_1.default.json());
|
|
29
31
|
// Health check (public)
|
|
30
|
-
app.get(
|
|
31
|
-
res.json({ status:
|
|
32
|
+
app.get("/health", (req, res) => {
|
|
33
|
+
res.json({ status: "ok", timestamp: Date.now() });
|
|
32
34
|
});
|
|
33
35
|
// Auth Middleware
|
|
34
36
|
app.use((req, res, next) => {
|
|
35
|
-
const token = req.headers[
|
|
37
|
+
const token = req.headers["x-pmxt-access-token"];
|
|
36
38
|
if (!token || token !== accessToken) {
|
|
37
|
-
res.status(401).json({
|
|
39
|
+
res.status(401).json({
|
|
40
|
+
success: false,
|
|
41
|
+
error: "Unauthorized: Invalid or missing access token",
|
|
42
|
+
});
|
|
38
43
|
return;
|
|
39
44
|
}
|
|
40
45
|
next();
|
|
41
46
|
});
|
|
42
|
-
// Capability map endpoint: GET /api/:exchange/has
|
|
43
|
-
app.get('/api/:exchange/has', (req, res, next) => {
|
|
44
|
-
try {
|
|
45
|
-
const exchangeName = req.params.exchange.toLowerCase();
|
|
46
|
-
if (!defaultExchanges[exchangeName]) {
|
|
47
|
-
defaultExchanges[exchangeName] = createExchange(exchangeName);
|
|
48
|
-
}
|
|
49
|
-
const exchange = defaultExchanges[exchangeName];
|
|
50
|
-
res.json({ success: true, data: exchange.has });
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
next(error);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
47
|
// API endpoint: POST /api/:exchange/:method
|
|
57
48
|
// Body: { args: any[], credentials?: ExchangeCredentials }
|
|
58
|
-
app.post(
|
|
49
|
+
app.post("/api/:exchange/:method", async (req, res, next) => {
|
|
59
50
|
try {
|
|
60
51
|
const exchangeName = req.params.exchange.toLowerCase();
|
|
61
52
|
const methodName = req.params.method;
|
|
@@ -74,18 +65,20 @@ async function startServer(port, accessToken) {
|
|
|
74
65
|
}
|
|
75
66
|
exchange = defaultExchanges[exchangeName];
|
|
76
67
|
}
|
|
77
|
-
//
|
|
78
|
-
if (req.
|
|
68
|
+
// Apply verbose logging if requested via header
|
|
69
|
+
if (req.headers["x-pmxt-verbose"] === "true") {
|
|
79
70
|
exchange.verbose = true;
|
|
80
71
|
}
|
|
81
72
|
else {
|
|
82
73
|
// Reset to false for singleton instances to avoid leaking state between requests
|
|
83
|
-
// For new instances it defaults to false anyway
|
|
84
74
|
exchange.verbose = false;
|
|
85
75
|
}
|
|
86
76
|
// 2. Validate Method
|
|
87
|
-
if (typeof exchange[methodName] !==
|
|
88
|
-
res.status(404).json({
|
|
77
|
+
if (typeof exchange[methodName] !== "function") {
|
|
78
|
+
res.status(404).json({
|
|
79
|
+
success: false,
|
|
80
|
+
error: `Method '${methodName}' not found on ${exchangeName}`,
|
|
81
|
+
});
|
|
89
82
|
return;
|
|
90
83
|
}
|
|
91
84
|
// 3. Execute with direct argument spreading
|
|
@@ -98,7 +91,7 @@ async function startServer(port, accessToken) {
|
|
|
98
91
|
});
|
|
99
92
|
// Error handler
|
|
100
93
|
app.use((error, req, res, next) => {
|
|
101
|
-
console.error(
|
|
94
|
+
console.error("API Error:", error);
|
|
102
95
|
if (error.stack) {
|
|
103
96
|
console.error(error.stack);
|
|
104
97
|
}
|
|
@@ -109,72 +102,87 @@ async function startServer(port, accessToken) {
|
|
|
109
102
|
error: {
|
|
110
103
|
message: error.message,
|
|
111
104
|
code: error.code,
|
|
112
|
-
retryable: error.retryable
|
|
113
|
-
}
|
|
105
|
+
retryable: error.retryable,
|
|
106
|
+
},
|
|
114
107
|
};
|
|
115
108
|
// Add exchange context if available
|
|
116
109
|
if (error.exchange) {
|
|
117
110
|
errorResponse.error.exchange = error.exchange;
|
|
118
111
|
}
|
|
119
112
|
// Add retryAfter for rate limit errors
|
|
120
|
-
if (
|
|
113
|
+
if ("retryAfter" in error && error.retryAfter !== undefined) {
|
|
121
114
|
errorResponse.error.retryAfter = error.retryAfter;
|
|
122
115
|
}
|
|
123
116
|
// Add stack trace in development
|
|
124
|
-
if (process.env.NODE_ENV ===
|
|
117
|
+
if (process.env.NODE_ENV === "development") {
|
|
125
118
|
errorResponse.error.stack = error.stack;
|
|
126
119
|
}
|
|
127
|
-
res.status(error.status).json(errorResponse);
|
|
120
|
+
res.status(error.status || 500).json(errorResponse);
|
|
128
121
|
return;
|
|
129
122
|
}
|
|
130
123
|
// Handle generic errors
|
|
131
124
|
res.status(error.status || 500).json({
|
|
132
125
|
success: false,
|
|
133
126
|
error: {
|
|
134
|
-
message: error.message ||
|
|
135
|
-
stack: process.env.NODE_ENV ===
|
|
136
|
-
}
|
|
127
|
+
message: error.message || "Internal server error",
|
|
128
|
+
stack: process.env.NODE_ENV === "development" ? error.stack : undefined,
|
|
129
|
+
},
|
|
137
130
|
});
|
|
138
131
|
});
|
|
139
|
-
return app.listen(port,
|
|
132
|
+
return app.listen(port, "127.0.0.1");
|
|
140
133
|
}
|
|
141
134
|
function createExchange(name, credentials) {
|
|
142
135
|
switch (name) {
|
|
143
|
-
case
|
|
136
|
+
case "polymarket":
|
|
144
137
|
return new polymarket_1.PolymarketExchange({
|
|
145
|
-
privateKey: credentials?.privateKey ||
|
|
138
|
+
privateKey: credentials?.privateKey ||
|
|
139
|
+
process.env.POLYMARKET_PK ||
|
|
140
|
+
process.env.POLYMARKET_PRIVATE_KEY,
|
|
146
141
|
apiKey: credentials?.apiKey || process.env.POLYMARKET_API_KEY,
|
|
147
142
|
apiSecret: credentials?.apiSecret || process.env.POLYMARKET_API_SECRET,
|
|
148
143
|
passphrase: credentials?.passphrase || process.env.POLYMARKET_PASSPHRASE,
|
|
149
144
|
funderAddress: credentials?.funderAddress,
|
|
150
|
-
signatureType: credentials?.signatureType
|
|
145
|
+
signatureType: credentials?.signatureType,
|
|
151
146
|
});
|
|
152
|
-
case
|
|
147
|
+
case "limitless":
|
|
153
148
|
return new limitless_1.LimitlessExchange({
|
|
154
|
-
privateKey: credentials?.privateKey ||
|
|
149
|
+
privateKey: credentials?.privateKey ||
|
|
150
|
+
process.env.LIMITLESS_PK ||
|
|
151
|
+
process.env.LIMITLESS_PRIVATE_KEY,
|
|
155
152
|
apiKey: credentials?.apiKey || process.env.LIMITLESS_API_KEY,
|
|
156
153
|
apiSecret: credentials?.apiSecret || process.env.LIMITLESS_API_SECRET,
|
|
157
|
-
passphrase: credentials?.passphrase || process.env.LIMITLESS_PASSPHRASE
|
|
154
|
+
passphrase: credentials?.passphrase || process.env.LIMITLESS_PASSPHRASE,
|
|
158
155
|
});
|
|
159
|
-
case
|
|
156
|
+
case "kalshi":
|
|
160
157
|
return new kalshi_1.KalshiExchange({
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
credentials: {
|
|
159
|
+
apiKey: credentials?.apiKey || process.env.KALSHI_API_KEY,
|
|
160
|
+
privateKey: credentials?.privateKey || process.env.KALSHI_PRIVATE_KEY,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
case "kalshi-demo":
|
|
164
|
+
return new kalshi_demo_1.KalshiDemoExchange({
|
|
165
|
+
credentials: {
|
|
166
|
+
apiKey: credentials?.apiKey || process.env.KALSHI_API_KEY,
|
|
167
|
+
privateKey: credentials?.privateKey || process.env.KALSHI_PRIVATE_KEY,
|
|
168
|
+
},
|
|
163
169
|
});
|
|
164
|
-
case
|
|
170
|
+
case "probable":
|
|
165
171
|
return new probable_1.ProbableExchange({
|
|
166
172
|
apiKey: credentials?.apiKey || process.env.PROBABLE_API_KEY,
|
|
167
173
|
apiSecret: credentials?.apiSecret || process.env.PROBABLE_API_SECRET,
|
|
168
174
|
passphrase: credentials?.passphrase || process.env.PROBABLE_PASSPHRASE,
|
|
169
175
|
privateKey: credentials?.privateKey || process.env.PROBABLE_PRIVATE_KEY,
|
|
170
176
|
});
|
|
171
|
-
case
|
|
177
|
+
case "baozi":
|
|
172
178
|
return new baozi_1.BaoziExchange({
|
|
173
179
|
privateKey: credentials?.privateKey || process.env.BAOZI_PRIVATE_KEY,
|
|
174
180
|
});
|
|
175
|
-
case
|
|
181
|
+
case "myriad":
|
|
176
182
|
return new myriad_1.MyriadExchange({
|
|
177
|
-
apiKey: credentials?.apiKey ||
|
|
183
|
+
apiKey: credentials?.apiKey ||
|
|
184
|
+
process.env.MYRIAD_API_KEY ||
|
|
185
|
+
process.env.MYRIAD_PROD,
|
|
178
186
|
privateKey: credentials?.privateKey || process.env.MYRIAD_WALLET_ADDRESS,
|
|
179
187
|
});
|
|
180
188
|
default:
|
package/dist/types.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface UnifiedEvent {
|
|
|
14
14
|
description: string;
|
|
15
15
|
slug: string;
|
|
16
16
|
markets: UnifiedMarket[];
|
|
17
|
+
volume24h: number;
|
|
18
|
+
volume?: number;
|
|
17
19
|
url: string;
|
|
18
20
|
image?: string;
|
|
19
21
|
category?: string;
|
|
@@ -22,6 +24,7 @@ export interface UnifiedEvent {
|
|
|
22
24
|
export interface UnifiedMarket {
|
|
23
25
|
/** The unique identifier for this market */
|
|
24
26
|
marketId: string;
|
|
27
|
+
eventId?: string;
|
|
25
28
|
title: string;
|
|
26
29
|
description: string;
|
|
27
30
|
slug?: string;
|
|
@@ -66,6 +69,9 @@ export interface Trade {
|
|
|
66
69
|
amount: number;
|
|
67
70
|
side: 'buy' | 'sell' | 'unknown';
|
|
68
71
|
}
|
|
72
|
+
export interface UserTrade extends Trade {
|
|
73
|
+
orderId?: string;
|
|
74
|
+
}
|
|
69
75
|
export interface Order {
|
|
70
76
|
id: string;
|
|
71
77
|
marketId: string;
|
|
@@ -107,3 +113,26 @@ export interface CreateOrderParams {
|
|
|
107
113
|
tickSize?: number;
|
|
108
114
|
negRisk?: boolean;
|
|
109
115
|
}
|
|
116
|
+
export interface BuiltOrder {
|
|
117
|
+
/** The exchange name this order was built for. */
|
|
118
|
+
exchange: string;
|
|
119
|
+
/** The original params used to build this order. */
|
|
120
|
+
params: CreateOrderParams;
|
|
121
|
+
/**
|
|
122
|
+
* For CLOB exchanges (Polymarket): the EIP-712 signed order
|
|
123
|
+
* ready to POST to the exchange's order endpoint.
|
|
124
|
+
*/
|
|
125
|
+
signedOrder?: Record<string, unknown>;
|
|
126
|
+
/**
|
|
127
|
+
* For on-chain AMM exchanges: the EVM transaction payload.
|
|
128
|
+
* Reserved for future exchanges; no current exchange populates this.
|
|
129
|
+
*/
|
|
130
|
+
tx?: {
|
|
131
|
+
to: string;
|
|
132
|
+
data: string;
|
|
133
|
+
value: string;
|
|
134
|
+
chainId: number;
|
|
135
|
+
};
|
|
136
|
+
/** The raw, exchange-native payload. Always present. */
|
|
137
|
+
raw: unknown;
|
|
138
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class Throttler {
|
|
2
|
+
private tokens;
|
|
3
|
+
private queue;
|
|
4
|
+
private running;
|
|
5
|
+
private lastTimestamp;
|
|
6
|
+
private refillRate;
|
|
7
|
+
private capacity;
|
|
8
|
+
private delay;
|
|
9
|
+
constructor(config: {
|
|
10
|
+
refillRate: number;
|
|
11
|
+
capacity: number;
|
|
12
|
+
delay: number;
|
|
13
|
+
});
|
|
14
|
+
throttle(cost?: number): Promise<void>;
|
|
15
|
+
private loop;
|
|
16
|
+
private sleep;
|
|
17
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Throttler = void 0;
|
|
4
|
+
class Throttler {
|
|
5
|
+
tokens = 0;
|
|
6
|
+
queue = [];
|
|
7
|
+
running = false;
|
|
8
|
+
lastTimestamp = 0;
|
|
9
|
+
refillRate;
|
|
10
|
+
capacity;
|
|
11
|
+
delay;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.refillRate = config.refillRate;
|
|
14
|
+
this.capacity = config.capacity;
|
|
15
|
+
this.delay = config.delay;
|
|
16
|
+
}
|
|
17
|
+
async throttle(cost = 1) {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
this.queue.push({ resolve, cost });
|
|
20
|
+
if (!this.running) {
|
|
21
|
+
this.running = true;
|
|
22
|
+
this.loop();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async loop() {
|
|
27
|
+
while (this.queue.length > 0) {
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
if (this.lastTimestamp > 0) {
|
|
30
|
+
const elapsed = now - this.lastTimestamp;
|
|
31
|
+
this.tokens = Math.min(this.tokens + elapsed * this.refillRate, this.capacity);
|
|
32
|
+
}
|
|
33
|
+
this.lastTimestamp = now;
|
|
34
|
+
const head = this.queue[0];
|
|
35
|
+
if (this.tokens >= 0) {
|
|
36
|
+
this.tokens -= head.cost;
|
|
37
|
+
head.resolve();
|
|
38
|
+
this.queue.shift();
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
await this.sleep(this.delay);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
this.running = false;
|
|
45
|
+
}
|
|
46
|
+
sleep(ms) {
|
|
47
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.Throttler = Throttler;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.3",
|
|
4
4
|
"description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,12 +29,15 @@
|
|
|
29
29
|
"test": "jest -c jest.config.js",
|
|
30
30
|
"server": "tsx watch src/server/index.ts",
|
|
31
31
|
"server:prod": "node dist/server/index.js",
|
|
32
|
-
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.9.
|
|
33
|
-
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.9.
|
|
32
|
+
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.9.3,library=urllib3",
|
|
33
|
+
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.9.3,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
|
|
34
34
|
"fetch:openapi": "node scripts/fetch-openapi-specs.js",
|
|
35
35
|
"extract:jsdoc": "node ../scripts/extract-jsdoc.js",
|
|
36
36
|
"generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",
|
|
37
|
-
"generate:
|
|
37
|
+
"generate:openapi": "node scripts/generate-openapi.js",
|
|
38
|
+
"generate:python-exchanges": "node scripts/generate-python-exchanges.js",
|
|
39
|
+
"generate:compliance": "node scripts/generate-compliance.js",
|
|
40
|
+
"generate:sdk:all": "npm run generate:openapi && npm run generate:sdk:python && npm run generate:python-exchanges && npm run generate:sdk:typescript && npm run generate:docs && npm run generate:compliance"
|
|
38
41
|
},
|
|
39
42
|
"keywords": [],
|
|
40
43
|
"author": "",
|