pmxt 1.4.0__py3-none-any.whl → 1.5.0__py3-none-any.whl

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.
pmxt/__init__.py CHANGED
@@ -33,7 +33,7 @@ from .models import (
33
33
  CreateOrderParams,
34
34
  )
35
35
 
36
- __version__ = "1.4.0"
36
+ __version__ = "1.5.0"
37
37
  __all__ = [
38
38
  # Exchanges
39
39
  "Polymarket",
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * PMXT Server Launcher
5
+ *
6
+ * This script ensures the PMXT sidecar server is running.
7
+ * It's designed to be called by SDKs in any language (Python, Java, C#, Go, etc.)
8
+ *
9
+ * Behavior:
10
+ * 1. Check if server is already running (via lock file)
11
+ * 2. If running, exit successfully
12
+ * 3. If not running, spawn the server and wait for health check
13
+ * 4. Exit with code 0 on success, 1 on failure
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const os = require('os');
19
+ const { spawn } = require('child_process');
20
+ const http = require('http');
21
+
22
+ const LOCK_FILE = path.join(os.homedir(), '.pmxt', 'server.lock');
23
+ const DEFAULT_PORT = 3847;
24
+ const HEALTH_CHECK_TIMEOUT = 10000; // 10 seconds
25
+ const HEALTH_CHECK_INTERVAL = 100; // 100ms
26
+
27
+ /**
28
+ * Check if the server is currently running
29
+ */
30
+ function isServerRunning() {
31
+ try {
32
+ if (!fs.existsSync(LOCK_FILE)) {
33
+ return false;
34
+ }
35
+
36
+ const lockData = JSON.parse(fs.readFileSync(LOCK_FILE, 'utf-8'));
37
+ const { pid, port } = lockData;
38
+
39
+ // Check if process exists
40
+ try {
41
+ process.kill(pid, 0); // Signal 0 checks existence without killing
42
+ return { running: true, port };
43
+ } catch (err) {
44
+ // Process doesn't exist, remove stale lock file
45
+ fs.unlinkSync(LOCK_FILE);
46
+ return false;
47
+ }
48
+ } catch (err) {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Wait for server to respond to health check
55
+ */
56
+ function waitForHealth(port, timeout = HEALTH_CHECK_TIMEOUT) {
57
+ return new Promise((resolve, reject) => {
58
+ const startTime = Date.now();
59
+
60
+ const checkHealth = () => {
61
+ const req = http.get(`http://localhost:${port}/health`, (res) => {
62
+ if (res.statusCode === 200) {
63
+ resolve(true);
64
+ } else {
65
+ scheduleNextCheck();
66
+ }
67
+ });
68
+
69
+ req.on('error', () => {
70
+ scheduleNextCheck();
71
+ });
72
+
73
+ req.setTimeout(1000);
74
+ };
75
+
76
+ const scheduleNextCheck = () => {
77
+ if (Date.now() - startTime > timeout) {
78
+ reject(new Error('Server health check timeout'));
79
+ } else {
80
+ setTimeout(checkHealth, HEALTH_CHECK_INTERVAL);
81
+ }
82
+ };
83
+
84
+ checkHealth();
85
+ });
86
+ }
87
+
88
+ /**
89
+ * Start the PMXT server
90
+ */
91
+ async function startServer() {
92
+ // 1. Try to find the server binary/script
93
+ let serverCmd = 'pmxt-server';
94
+ let args = [];
95
+
96
+ // Check for Python-bundled server (when bundled in pip package)
97
+ const pythonBundledServer = path.join(__dirname, '..', 'server', 'bundled.js');
98
+ // Check for local dev bundled server
99
+ const localBundledServer = path.join(__dirname, '..', 'dist', 'server', 'bundled.js');
100
+ const localDistServer = path.join(__dirname, '..', 'dist', 'server', 'index.js');
101
+ const localBinServer = path.join(__dirname, 'pmxt-server');
102
+
103
+ if (fs.existsSync(pythonBundledServer)) {
104
+ serverCmd = 'node';
105
+ args = [pythonBundledServer];
106
+ } else if (fs.existsSync(localBundledServer)) {
107
+ serverCmd = 'node';
108
+ args = [localBundledServer];
109
+ } else if (fs.existsSync(localDistServer)) {
110
+ serverCmd = 'node';
111
+ args = [localDistServer];
112
+ } else if (fs.existsSync(localBinServer)) {
113
+ serverCmd = localBinServer;
114
+ }
115
+
116
+ // Spawn server as detached process
117
+ const serverProcess = spawn(serverCmd, args, {
118
+ detached: true,
119
+ stdio: 'ignore',
120
+ env: process.env
121
+ });
122
+
123
+ // Detach from parent process
124
+ serverProcess.unref();
125
+
126
+ // Wait for server to be ready
127
+ await waitForHealth(DEFAULT_PORT);
128
+ }
129
+
130
+ /**
131
+ * Main entry point
132
+ */
133
+ async function main() {
134
+ try {
135
+ // Check if server is already running
136
+ const serverStatus = isServerRunning();
137
+
138
+ if (serverStatus && serverStatus.running) {
139
+ // Server is running, verify it's healthy
140
+ try {
141
+ await waitForHealth(serverStatus.port, 2000);
142
+ process.exit(0);
143
+ } catch (err) {
144
+ // Server process exists but not responding, try to start fresh
145
+ console.error('Server process exists but not responding, starting fresh...');
146
+ }
147
+ }
148
+
149
+ // Start the server
150
+ await startServer();
151
+ process.exit(0);
152
+ } catch (err) {
153
+ console.error('Failed to ensure server is running:', err.message);
154
+ process.exit(1);
155
+ }
156
+ }
157
+
158
+ main();
@@ -104839,6 +104839,798 @@ var require_polymarket = __commonJS({
104839
104839
  throw new Error("Price is required for limit orders");
104840
104840
  }
104841
104841
  const price = params.price || (side === clob_client_1.Side.BUY ? 0.99 : 0.01);
104842
+ let tickSize;
104843
+ if (params.tickSize) {
104844
+ tickSize = params.tickSize.toString();
104845
+ } else {
104846
+ try {
104847
+ const orderBook = await this.fetchOrderBook(params.outcomeId);
104848
+ tickSize = this.inferTickSize(orderBook);
104849
+ } catch (error) {
104850
+ tickSize = "0.01";
104851
+ }
104852
+ }
104853
+ try {
104854
+ const response = await client.createAndPostOrder({
104855
+ tokenID: params.outcomeId,
104856
+ price,
104857
+ side,
104858
+ size: params.amount,
104859
+ feeRateBps: 0
104860
+ }, {
104861
+ tickSize
104862
+ });
104863
+ if (!response || !response.success) {
104864
+ throw new Error(response?.errorMsg || "Order placement failed");
104865
+ }
104866
+ return {
104867
+ id: response.orderID,
104868
+ marketId: params.marketId,
104869
+ outcomeId: params.outcomeId,
104870
+ side: params.side,
104871
+ type: params.type,
104872
+ price,
104873
+ amount: params.amount,
104874
+ status: "open",
104875
+ filled: 0,
104876
+ remaining: params.amount,
104877
+ timestamp: Date.now()
104878
+ };
104879
+ } catch (error) {
104880
+ throw error;
104881
+ }
104882
+ }
104883
+ /**
104884
+ * Infer the tick size from order book price levels.
104885
+ * Analyzes the decimal precision of existing orders to determine the market's tick size.
104886
+ */
104887
+ inferTickSize(orderBook) {
104888
+ const allPrices = [
104889
+ ...orderBook.bids.map((b) => b.price),
104890
+ ...orderBook.asks.map((a) => a.price)
104891
+ ];
104892
+ if (allPrices.length === 0) {
104893
+ return "0.01";
104894
+ }
104895
+ let minIncrement = 1;
104896
+ for (const price of allPrices) {
104897
+ const priceStr = price.toString();
104898
+ const decimalPart = priceStr.split(".")[1];
104899
+ if (decimalPart) {
104900
+ const decimals = decimalPart.length;
104901
+ const increment = Math.pow(10, -decimals);
104902
+ if (increment < minIncrement) {
104903
+ minIncrement = increment;
104904
+ }
104905
+ }
104906
+ }
104907
+ if (minIncrement >= 0.1)
104908
+ return "0.1";
104909
+ if (minIncrement >= 0.01)
104910
+ return "0.01";
104911
+ if (minIncrement >= 1e-3)
104912
+ return "0.001";
104913
+ return "0.0001";
104914
+ }
104915
+ async cancelOrder(orderId) {
104916
+ const auth = this.ensureAuth();
104917
+ const client = await auth.getClobClient();
104918
+ try {
104919
+ await client.cancelOrder({ orderID: orderId });
104920
+ return {
104921
+ id: orderId,
104922
+ marketId: "unknown",
104923
+ outcomeId: "unknown",
104924
+ side: "buy",
104925
+ type: "limit",
104926
+ amount: 0,
104927
+ status: "cancelled",
104928
+ filled: 0,
104929
+ remaining: 0,
104930
+ timestamp: Date.now()
104931
+ };
104932
+ } catch (error) {
104933
+ throw error;
104934
+ }
104935
+ }
104936
+ async fetchOrder(orderId) {
104937
+ const auth = this.ensureAuth();
104938
+ const client = await auth.getClobClient();
104939
+ try {
104940
+ const order = await client.getOrder(orderId);
104941
+ return {
104942
+ id: order.id,
104943
+ marketId: order.market || "unknown",
104944
+ outcomeId: order.asset_id,
104945
+ side: order.side.toLowerCase(),
104946
+ type: order.order_type === "GTC" ? "limit" : "market",
104947
+ price: parseFloat(order.price),
104948
+ amount: parseFloat(order.original_size),
104949
+ status: order.status,
104950
+ // Needs precise mapping
104951
+ filled: parseFloat(order.size_matched),
104952
+ remaining: parseFloat(order.original_size) - parseFloat(order.size_matched),
104953
+ timestamp: order.created_at * 1e3
104954
+ };
104955
+ } catch (error) {
104956
+ throw error;
104957
+ }
104958
+ }
104959
+ async fetchOpenOrders(marketId) {
104960
+ const auth = this.ensureAuth();
104961
+ const client = await auth.getClobClient();
104962
+ try {
104963
+ const orders = await client.getOpenOrders({
104964
+ market: marketId
104965
+ });
104966
+ return orders.map((o) => ({
104967
+ id: o.id,
104968
+ marketId: o.market || "unknown",
104969
+ outcomeId: o.asset_id,
104970
+ side: o.side.toLowerCase(),
104971
+ type: "limit",
104972
+ price: parseFloat(o.price),
104973
+ amount: parseFloat(o.original_size),
104974
+ status: "open",
104975
+ filled: parseFloat(o.size_matched),
104976
+ remaining: parseFloat(o.size_left || parseFloat(o.original_size) - parseFloat(o.size_matched)),
104977
+ timestamp: o.created_at * 1e3
104978
+ }));
104979
+ } catch (error) {
104980
+ console.error("Error fetching Polymarket open orders:", error);
104981
+ return [];
104982
+ }
104983
+ }
104984
+ async fetchPositions() {
104985
+ const auth = this.ensureAuth();
104986
+ const address = auth.getAddress();
104987
+ return (0, fetchPositions_1.fetchPositions)(address);
104988
+ }
104989
+ async fetchBalance() {
104990
+ const auth = this.ensureAuth();
104991
+ const client = await auth.getClobClient();
104992
+ try {
104993
+ const USDC_DECIMALS = 6;
104994
+ const balRes = await client.getBalanceAllowance({
104995
+ asset_type: clob_client_1.AssetType.COLLATERAL
104996
+ });
104997
+ const rawBalance = parseFloat(balRes.balance);
104998
+ const total = rawBalance / Math.pow(10, USDC_DECIMALS);
104999
+ const openOrders = await client.getOpenOrders({});
105000
+ let locked = 0;
105001
+ if (openOrders && Array.isArray(openOrders)) {
105002
+ for (const order of openOrders) {
105003
+ if (order.side === clob_client_1.Side.BUY) {
105004
+ const remainingSize = parseFloat(order.original_size) - parseFloat(order.size_matched);
105005
+ const price = parseFloat(order.price);
105006
+ locked += remainingSize * price;
105007
+ }
105008
+ }
105009
+ }
105010
+ return [{
105011
+ currency: "USDC",
105012
+ total,
105013
+ available: total - locked,
105014
+ // Available for new trades
105015
+ locked
105016
+ }];
105017
+ } catch (error) {
105018
+ throw error;
105019
+ }
105020
+ }
105021
+ async watchOrderBook(id, limit) {
105022
+ if (!this.ws) {
105023
+ this.ws = new websocket_1.PolymarketWebSocket(this.wsConfig);
105024
+ }
105025
+ return this.ws.watchOrderBook(id);
105026
+ }
105027
+ async watchTrades(id, since, limit) {
105028
+ if (!this.ws) {
105029
+ this.ws = new websocket_1.PolymarketWebSocket(this.wsConfig);
105030
+ }
105031
+ return this.ws.watchTrades(id);
105032
+ }
105033
+ async close() {
105034
+ if (this.ws) {
105035
+ this.ws.close();
105036
+ this.ws = void 0;
105037
+ }
105038
+ }
105039
+ };
105040
+ exports2.PolymarketExchange = PolymarketExchange;
105041
+ }
105042
+ });
105043
+
105044
+ // dist/exchanges/limitless/utils.js
105045
+ var require_utils10 = __commonJS({
105046
+ "dist/exchanges/limitless/utils.js"(exports2) {
105047
+ "use strict";
105048
+ Object.defineProperty(exports2, "__esModule", { value: true });
105049
+ exports2.LIMITLESS_API_URL = void 0;
105050
+ exports2.mapMarketToUnified = mapMarketToUnified;
105051
+ exports2.mapIntervalToFidelity = mapIntervalToFidelity;
105052
+ var market_utils_1 = require_market_utils();
105053
+ exports2.LIMITLESS_API_URL = "https://api.limitless.exchange";
105054
+ function mapMarketToUnified(market) {
105055
+ if (!market)
105056
+ return null;
105057
+ const outcomes = [];
105058
+ if (market.tokens && market.prices) {
105059
+ const tokenEntries = Object.entries(market.tokens);
105060
+ tokenEntries.forEach(([label, tokenId], index) => {
105061
+ const outcomePrice = market.prices[index] || 0;
105062
+ outcomes.push({
105063
+ id: tokenId,
105064
+ label: label.charAt(0).toUpperCase() + label.slice(1),
105065
+ // Capitalize 'yes'/'no'
105066
+ price: outcomePrice,
105067
+ priceChange24h: 0,
105068
+ // Not directly available in this flat list, can be computed if needed
105069
+ metadata: {
105070
+ clobTokenId: tokenId
105071
+ }
105072
+ });
105073
+ });
105074
+ }
105075
+ const um = {
105076
+ id: market.slug,
105077
+ title: market.title || market.question,
105078
+ description: market.description,
105079
+ outcomes,
105080
+ resolutionDate: market.expirationTimestamp ? new Date(market.expirationTimestamp) : /* @__PURE__ */ new Date(),
105081
+ volume24h: Number(market.volumeFormatted || 0),
105082
+ volume: Number(market.volume || 0),
105083
+ liquidity: 0,
105084
+ // Not directly in the flat market list
105085
+ openInterest: 0,
105086
+ // Not directly in the flat market list
105087
+ url: `https://limitless.exchange/markets/${market.slug}`,
105088
+ image: market.logo || `https://limitless.exchange/api/og?slug=${market.slug}`,
105089
+ category: market.categories?.[0],
105090
+ tags: market.tags || []
105091
+ };
105092
+ (0, market_utils_1.addBinaryOutcomes)(um);
105093
+ return um;
105094
+ }
105095
+ function mapIntervalToFidelity(interval) {
105096
+ const mapping = {
105097
+ "1m": 1,
105098
+ "5m": 5,
105099
+ "15m": 15,
105100
+ "1h": 60,
105101
+ "6h": 360,
105102
+ "1d": 1440
105103
+ };
105104
+ return mapping[interval];
105105
+ }
105106
+ }
105107
+ });
105108
+
105109
+ // dist/exchanges/limitless/fetchMarkets.js
105110
+ var require_fetchMarkets2 = __commonJS({
105111
+ "dist/exchanges/limitless/fetchMarkets.js"(exports2) {
105112
+ "use strict";
105113
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105114
+ return mod && mod.__esModule ? mod : { "default": mod };
105115
+ };
105116
+ Object.defineProperty(exports2, "__esModule", { value: true });
105117
+ exports2.fetchMarkets = fetchMarkets;
105118
+ var axios_1 = __importDefault(require_axios());
105119
+ var utils_1 = require_utils10();
105120
+ async function fetchMarkets(params) {
105121
+ const limit = params?.limit || 200;
105122
+ const offset = params?.offset || 0;
105123
+ const url2 = `${utils_1.LIMITLESS_API_URL}/markets/active`;
105124
+ try {
105125
+ const response = await axios_1.default.get(url2);
105126
+ const markets = response.data?.data || response.data;
105127
+ if (!markets || !Array.isArray(markets)) {
105128
+ return [];
105129
+ }
105130
+ const unifiedMarkets = [];
105131
+ for (const market of markets) {
105132
+ const unifiedMarket = (0, utils_1.mapMarketToUnified)(market);
105133
+ if (unifiedMarket) {
105134
+ unifiedMarkets.push(unifiedMarket);
105135
+ }
105136
+ }
105137
+ if (params?.sort === "volume") {
105138
+ unifiedMarkets.sort((a, b) => (b.volume ?? 0) - (a.volume ?? 0));
105139
+ } else {
105140
+ unifiedMarkets.sort((a, b) => (b.volume ?? 0) - (a.volume ?? 0));
105141
+ }
105142
+ return unifiedMarkets.slice(offset, offset + limit);
105143
+ } catch (error) {
105144
+ console.error("Error fetching Limitless markets:", error.message);
105145
+ return [];
105146
+ }
105147
+ }
105148
+ }
105149
+ });
105150
+
105151
+ // dist/exchanges/limitless/searchMarkets.js
105152
+ var require_searchMarkets2 = __commonJS({
105153
+ "dist/exchanges/limitless/searchMarkets.js"(exports2) {
105154
+ "use strict";
105155
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105156
+ return mod && mod.__esModule ? mod : { "default": mod };
105157
+ };
105158
+ Object.defineProperty(exports2, "__esModule", { value: true });
105159
+ exports2.searchMarkets = searchMarkets;
105160
+ var axios_1 = __importDefault(require_axios());
105161
+ var utils_1 = require_utils10();
105162
+ async function searchMarkets(query, params) {
105163
+ try {
105164
+ const response = await axios_1.default.get(`${utils_1.LIMITLESS_API_URL}/markets/search`, {
105165
+ params: {
105166
+ query,
105167
+ limit: params?.limit || 20
105168
+ }
105169
+ });
105170
+ const markets = response.data?.markets || [];
105171
+ return markets.map((m) => (0, utils_1.mapMarketToUnified)(m)).filter((m) => m !== null).slice(0, params?.limit || 20);
105172
+ } catch (error) {
105173
+ console.error("Error searching Limitless data:", error.message);
105174
+ return [];
105175
+ }
105176
+ }
105177
+ }
105178
+ });
105179
+
105180
+ // dist/exchanges/limitless/searchEvents.js
105181
+ var require_searchEvents2 = __commonJS({
105182
+ "dist/exchanges/limitless/searchEvents.js"(exports2) {
105183
+ "use strict";
105184
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105185
+ return mod && mod.__esModule ? mod : { "default": mod };
105186
+ };
105187
+ Object.defineProperty(exports2, "__esModule", { value: true });
105188
+ exports2.searchEvents = searchEvents;
105189
+ var axios_1 = __importDefault(require_axios());
105190
+ var utils_1 = require_utils10();
105191
+ async function searchEvents(query, params) {
105192
+ try {
105193
+ const response = await axios_1.default.get(`${utils_1.LIMITLESS_API_URL}/markets/search`, {
105194
+ params: {
105195
+ query,
105196
+ limit: params?.limit || 20
105197
+ }
105198
+ });
105199
+ const markets = response.data?.markets || [];
105200
+ return markets.map((market) => {
105201
+ const unifiedMarket = (0, utils_1.mapMarketToUnified)(market);
105202
+ const marketsList = unifiedMarket ? [unifiedMarket] : [];
105203
+ return {
105204
+ id: market.slug,
105205
+ title: market.title || market.question,
105206
+ description: market.description || "",
105207
+ slug: market.slug,
105208
+ markets: marketsList,
105209
+ url: `https://limitless.exchange/markets/${market.slug}`,
105210
+ image: market.logo || `https://limitless.exchange/api/og?slug=${market.slug}`,
105211
+ category: market.categories?.[0],
105212
+ tags: market.tags || [],
105213
+ searchMarkets: function(marketQuery) {
105214
+ const lowerMarketQuery = marketQuery.toLowerCase();
105215
+ return this.markets.filter((m) => m.title.toLowerCase().includes(lowerMarketQuery) || m.description.toLowerCase().includes(lowerMarketQuery));
105216
+ }
105217
+ };
105218
+ });
105219
+ } catch (error) {
105220
+ console.error("Error searching Limitless events:", error.message);
105221
+ return [];
105222
+ }
105223
+ }
105224
+ }
105225
+ });
105226
+
105227
+ // dist/exchanges/limitless/getMarketsBySlug.js
105228
+ var require_getMarketsBySlug2 = __commonJS({
105229
+ "dist/exchanges/limitless/getMarketsBySlug.js"(exports2) {
105230
+ "use strict";
105231
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105232
+ return mod && mod.__esModule ? mod : { "default": mod };
105233
+ };
105234
+ Object.defineProperty(exports2, "__esModule", { value: true });
105235
+ exports2.getMarketsBySlug = getMarketsBySlug;
105236
+ var axios_1 = __importDefault(require_axios());
105237
+ var utils_1 = require_utils10();
105238
+ async function getMarketsBySlug(slug) {
105239
+ try {
105240
+ const response = await axios_1.default.get(`${utils_1.LIMITLESS_API_URL}/markets/${slug}`);
105241
+ const market = response.data;
105242
+ if (!market)
105243
+ return [];
105244
+ const unifiedMarket = (0, utils_1.mapMarketToUnified)(market);
105245
+ return unifiedMarket ? [unifiedMarket] : [];
105246
+ } catch (error) {
105247
+ console.error(`Error fetching Limitless slug ${slug}:`, error.message);
105248
+ return [];
105249
+ }
105250
+ }
105251
+ }
105252
+ });
105253
+
105254
+ // dist/exchanges/limitless/fetchOHLCV.js
105255
+ var require_fetchOHLCV2 = __commonJS({
105256
+ "dist/exchanges/limitless/fetchOHLCV.js"(exports2) {
105257
+ "use strict";
105258
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105259
+ return mod && mod.__esModule ? mod : { "default": mod };
105260
+ };
105261
+ Object.defineProperty(exports2, "__esModule", { value: true });
105262
+ exports2.fetchOHLCV = fetchOHLCV;
105263
+ var axios_1 = __importDefault(require_axios());
105264
+ var utils_1 = require_utils10();
105265
+ async function fetchOHLCV(id, params) {
105266
+ try {
105267
+ const fidelity = (0, utils_1.mapIntervalToFidelity)(params.resolution);
105268
+ const url2 = `${utils_1.LIMITLESS_API_URL}/markets/${id}/historical-price`;
105269
+ const response = await axios_1.default.get(url2, {
105270
+ params: { fidelity }
105271
+ });
105272
+ const data = response.data;
105273
+ const prices = data.prices || [];
105274
+ let candles = prices.map((p) => {
105275
+ const price = Number(p.price);
105276
+ const ts = Number(p.timestamp);
105277
+ return {
105278
+ timestamp: ts,
105279
+ open: price,
105280
+ high: price,
105281
+ low: price,
105282
+ close: price,
105283
+ volume: 0
105284
+ // Volume not provided in this specific endpoint
105285
+ };
105286
+ }).sort((a, b) => a.timestamp - b.timestamp);
105287
+ if (params.start) {
105288
+ candles = candles.filter((c) => c.timestamp >= params.start.getTime());
105289
+ }
105290
+ if (params.end) {
105291
+ candles = candles.filter((c) => c.timestamp <= params.end.getTime());
105292
+ }
105293
+ if (params.limit) {
105294
+ candles = candles.slice(0, params.limit);
105295
+ }
105296
+ return candles;
105297
+ } catch (error) {
105298
+ console.error(`Error fetching Limitless history for ${id}:`, error.message);
105299
+ return [];
105300
+ }
105301
+ }
105302
+ }
105303
+ });
105304
+
105305
+ // dist/exchanges/limitless/fetchOrderBook.js
105306
+ var require_fetchOrderBook2 = __commonJS({
105307
+ "dist/exchanges/limitless/fetchOrderBook.js"(exports2) {
105308
+ "use strict";
105309
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105310
+ return mod && mod.__esModule ? mod : { "default": mod };
105311
+ };
105312
+ Object.defineProperty(exports2, "__esModule", { value: true });
105313
+ exports2.fetchOrderBook = fetchOrderBook;
105314
+ var axios_1 = __importDefault(require_axios());
105315
+ var utils_1 = require_utils10();
105316
+ async function fetchOrderBook(id) {
105317
+ try {
105318
+ const url2 = `${utils_1.LIMITLESS_API_URL}/markets/${id}/orderbook`;
105319
+ const response = await axios_1.default.get(url2);
105320
+ const data = response.data;
105321
+ const bids = (data.bids || []).map((level) => ({
105322
+ price: parseFloat(level.price),
105323
+ size: parseFloat(level.size)
105324
+ })).sort((a, b) => b.price - a.price);
105325
+ const asks = (data.asks || []).map((level) => ({
105326
+ price: parseFloat(level.price),
105327
+ size: parseFloat(level.size)
105328
+ })).sort((a, b) => a.price - b.price);
105329
+ return {
105330
+ bids,
105331
+ asks,
105332
+ timestamp: Date.now()
105333
+ // API doesn't seem to return a specific timestamp in the root anymore
105334
+ };
105335
+ } catch (error) {
105336
+ console.error(`Error fetching Limitless orderbook for ${id}:`, error.message);
105337
+ return { bids: [], asks: [] };
105338
+ }
105339
+ }
105340
+ }
105341
+ });
105342
+
105343
+ // dist/exchanges/limitless/fetchTrades.js
105344
+ var require_fetchTrades2 = __commonJS({
105345
+ "dist/exchanges/limitless/fetchTrades.js"(exports2) {
105346
+ "use strict";
105347
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105348
+ return mod && mod.__esModule ? mod : { "default": mod };
105349
+ };
105350
+ Object.defineProperty(exports2, "__esModule", { value: true });
105351
+ exports2.fetchTrades = fetchTrades;
105352
+ var axios_1 = __importDefault(require_axios());
105353
+ var utils_1 = require_utils10();
105354
+ async function fetchTrades(id, params) {
105355
+ try {
105356
+ const url2 = `${utils_1.LIMITLESS_API_URL}/portfolio/trades`;
105357
+ const requestParams = {
105358
+ limit: params.limit || 100
105359
+ };
105360
+ if (params.start) {
105361
+ requestParams.after = Math.floor(params.start.getTime() / 1e3);
105362
+ }
105363
+ if (params.end) {
105364
+ requestParams.before = Math.floor(params.end.getTime() / 1e3);
105365
+ }
105366
+ const response = await axios_1.default.get(url2, {
105367
+ params: requestParams
105368
+ });
105369
+ const tradesData = response.data?.data || response.data || [];
105370
+ let trades = tradesData.map((trade) => {
105371
+ const price = parseFloat(trade.price);
105372
+ const timestamp = Number(trade.timestamp);
105373
+ let side = "unknown";
105374
+ const rawSide = trade.side?.toLowerCase();
105375
+ if (rawSide === "buy")
105376
+ side = "buy";
105377
+ else if (rawSide === "sell")
105378
+ side = "sell";
105379
+ return {
105380
+ id: trade.id || `${timestamp}-${price}`,
105381
+ timestamp: timestamp * 1e3,
105382
+ price,
105383
+ amount: parseFloat(trade.size || trade.amount || 0),
105384
+ side
105385
+ };
105386
+ });
105387
+ trades.sort((a, b) => b.timestamp - a.timestamp);
105388
+ if (params.limit) {
105389
+ trades = trades.slice(0, params.limit);
105390
+ }
105391
+ return trades;
105392
+ } catch (error) {
105393
+ console.error(`Error fetching Limitless trades for ${id}:`, error.message);
105394
+ return [];
105395
+ }
105396
+ }
105397
+ }
105398
+ });
105399
+
105400
+ // dist/exchanges/limitless/fetchPositions.js
105401
+ var require_fetchPositions2 = __commonJS({
105402
+ "dist/exchanges/limitless/fetchPositions.js"(exports2) {
105403
+ "use strict";
105404
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
105405
+ return mod && mod.__esModule ? mod : { "default": mod };
105406
+ };
105407
+ Object.defineProperty(exports2, "__esModule", { value: true });
105408
+ exports2.fetchPositions = fetchPositions;
105409
+ var axios_1 = __importDefault(require_axios());
105410
+ var utils_1 = require_utils10();
105411
+ async function fetchPositions(userAddress) {
105412
+ try {
105413
+ const url2 = `${utils_1.LIMITLESS_API_URL}/portfolio/${userAddress}/positions`;
105414
+ const response = await axios_1.default.get(url2);
105415
+ const data = response.data?.data || response.data || [];
105416
+ return data.map((p) => ({
105417
+ marketId: p.market?.slug || p.conditionId,
105418
+ outcomeId: p.asset,
105419
+ outcomeLabel: p.outcome || "Unknown",
105420
+ size: parseFloat(p.size || "0"),
105421
+ entryPrice: parseFloat(p.avgPrice || "0"),
105422
+ currentPrice: parseFloat(p.curPrice || "0"),
105423
+ unrealizedPnL: parseFloat(p.cashPnl || "0"),
105424
+ realizedPnL: parseFloat(p.realizedPnl || "0")
105425
+ }));
105426
+ } catch (error) {
105427
+ if (error.response?.status === 404) {
105428
+ return [];
105429
+ }
105430
+ console.error(`Error fetching Limitless positions: ${error.message}`);
105431
+ return [];
105432
+ }
105433
+ }
105434
+ }
105435
+ });
105436
+
105437
+ // dist/exchanges/limitless/auth.js
105438
+ var require_auth2 = __commonJS({
105439
+ "dist/exchanges/limitless/auth.js"(exports2) {
105440
+ "use strict";
105441
+ Object.defineProperty(exports2, "__esModule", { value: true });
105442
+ exports2.LimitlessAuth = void 0;
105443
+ var clob_client_1 = (init_dist2(), __toCommonJS(dist_exports));
105444
+ var ethers_1 = require_lib36();
105445
+ var LIMITLESS_HOST = "https://api.limitless.exchange";
105446
+ var BASE_CHAIN_ID = 8453;
105447
+ var LimitlessAuth = class {
105448
+ constructor(credentials) {
105449
+ this.credentials = credentials;
105450
+ if (!credentials.privateKey) {
105451
+ throw new Error("Limitless requires a privateKey for authentication");
105452
+ }
105453
+ this.signer = new ethers_1.Wallet(credentials.privateKey);
105454
+ }
105455
+ /**
105456
+ * Get or create API credentials using L1 authentication.
105457
+ * This uses the private key to derive/create API credentials.
105458
+ */
105459
+ async getApiCredentials() {
105460
+ if (this.apiCreds) {
105461
+ return this.apiCreds;
105462
+ }
105463
+ if (this.credentials.apiKey && this.credentials.apiSecret && this.credentials.passphrase) {
105464
+ this.apiCreds = {
105465
+ key: this.credentials.apiKey,
105466
+ secret: this.credentials.apiSecret,
105467
+ passphrase: this.credentials.passphrase
105468
+ };
105469
+ return this.apiCreds;
105470
+ }
105471
+ const l1Client = new clob_client_1.ClobClient(LIMITLESS_HOST, BASE_CHAIN_ID, this.signer);
105472
+ let creds;
105473
+ try {
105474
+ creds = await l1Client.deriveApiKey();
105475
+ } catch (deriveError) {
105476
+ try {
105477
+ creds = await l1Client.createApiKey();
105478
+ } catch (createError) {
105479
+ console.error("Failed to both derive and create API key:", createError?.message || createError);
105480
+ throw new Error("Authentication failed: Could not create or derive API key.");
105481
+ }
105482
+ }
105483
+ if (!creds) {
105484
+ throw new Error("Authentication failed: Credentials are empty.");
105485
+ }
105486
+ this.apiCreds = creds;
105487
+ return creds;
105488
+ }
105489
+ /**
105490
+ * Get an authenticated CLOB client for L2 operations (trading).
105491
+ * This client can place orders, cancel orders, query positions, etc.
105492
+ */
105493
+ async getClobClient() {
105494
+ if (this.clobClient) {
105495
+ return this.clobClient;
105496
+ }
105497
+ const apiCreds = await this.getApiCredentials();
105498
+ const signatureType = this.credentials.signatureType ?? 0;
105499
+ const funderAddress = this.credentials.funderAddress ?? this.signer.address;
105500
+ this.clobClient = new clob_client_1.ClobClient(LIMITLESS_HOST, BASE_CHAIN_ID, this.signer, apiCreds, signatureType, funderAddress);
105501
+ return this.clobClient;
105502
+ }
105503
+ /**
105504
+ * Get the signer's address.
105505
+ */
105506
+ getAddress() {
105507
+ return this.signer.address;
105508
+ }
105509
+ /**
105510
+ * Reset cached credentials and client (useful for testing or credential rotation).
105511
+ */
105512
+ reset() {
105513
+ this.apiCreds = void 0;
105514
+ this.clobClient = void 0;
105515
+ }
105516
+ };
105517
+ exports2.LimitlessAuth = LimitlessAuth;
105518
+ }
105519
+ });
105520
+
105521
+ // dist/exchanges/limitless/websocket.js
105522
+ var require_websocket4 = __commonJS({
105523
+ "dist/exchanges/limitless/websocket.js"(exports2) {
105524
+ "use strict";
105525
+ Object.defineProperty(exports2, "__esModule", { value: true });
105526
+ exports2.LimitlessWebSocket = void 0;
105527
+ var LimitlessWebSocket = class {
105528
+ constructor(_config = {}) {
105529
+ }
105530
+ async watchOrderBook(_id) {
105531
+ throw new Error("Limitless WebSocket (watchOrderBook) is currently unavailable. The Limitless API v1 does not provide a public WebSocket endpoint for real-time updates. Please use fetchOrderBook() for polling instead.");
105532
+ }
105533
+ async watchTrades(_id) {
105534
+ throw new Error("Limitless WebSocket (watchTrades) is currently unavailable. The Limitless API v1 does not provide a public WebSocket endpoint for real-time updates. Please use fetchOHLCV() or fetchOrderBook() for recent activity instead.");
105535
+ }
105536
+ async close() {
105537
+ }
105538
+ };
105539
+ exports2.LimitlessWebSocket = LimitlessWebSocket;
105540
+ }
105541
+ });
105542
+
105543
+ // dist/exchanges/limitless/index.js
105544
+ var require_limitless = __commonJS({
105545
+ "dist/exchanges/limitless/index.js"(exports2) {
105546
+ "use strict";
105547
+ Object.defineProperty(exports2, "__esModule", { value: true });
105548
+ exports2.LimitlessExchange = void 0;
105549
+ var BaseExchange_1 = require_BaseExchange();
105550
+ var fetchMarkets_1 = require_fetchMarkets2();
105551
+ var searchMarkets_1 = require_searchMarkets2();
105552
+ var searchEvents_1 = require_searchEvents2();
105553
+ var getMarketsBySlug_1 = require_getMarketsBySlug2();
105554
+ var fetchOHLCV_1 = require_fetchOHLCV2();
105555
+ var fetchOrderBook_1 = require_fetchOrderBook2();
105556
+ var fetchTrades_1 = require_fetchTrades2();
105557
+ var fetchPositions_1 = require_fetchPositions2();
105558
+ var auth_1 = require_auth2();
105559
+ var clob_client_1 = (init_dist2(), __toCommonJS(dist_exports));
105560
+ var websocket_1 = require_websocket4();
105561
+ var LimitlessExchange = class extends BaseExchange_1.PredictionMarketExchange {
105562
+ constructor(options) {
105563
+ let credentials;
105564
+ let wsConfig;
105565
+ if (options && "credentials" in options) {
105566
+ credentials = options.credentials;
105567
+ wsConfig = options.websocket;
105568
+ } else if (options && "privateKey" in options) {
105569
+ credentials = options;
105570
+ } else {
105571
+ credentials = options;
105572
+ }
105573
+ super(credentials);
105574
+ this.wsConfig = wsConfig;
105575
+ if (credentials?.privateKey) {
105576
+ this.auth = new auth_1.LimitlessAuth(credentials);
105577
+ }
105578
+ }
105579
+ get name() {
105580
+ return "Limitless";
105581
+ }
105582
+ async fetchMarkets(params) {
105583
+ return (0, fetchMarkets_1.fetchMarkets)(params);
105584
+ }
105585
+ async searchMarkets(query, params) {
105586
+ return (0, searchMarkets_1.searchMarkets)(query, params);
105587
+ }
105588
+ async searchEvents(query, params) {
105589
+ return (0, searchEvents_1.searchEvents)(query, params);
105590
+ }
105591
+ async getMarketsBySlug(slug) {
105592
+ return (0, getMarketsBySlug_1.getMarketsBySlug)(slug);
105593
+ }
105594
+ async fetchOHLCV(id, params) {
105595
+ return (0, fetchOHLCV_1.fetchOHLCV)(id, params);
105596
+ }
105597
+ async fetchOrderBook(id) {
105598
+ return (0, fetchOrderBook_1.fetchOrderBook)(id);
105599
+ }
105600
+ async fetchTrades(id, params) {
105601
+ return (0, fetchTrades_1.fetchTrades)(id, params);
105602
+ }
105603
+ // ----------------------------------------------------------------------------
105604
+ // Trading Methods
105605
+ // ----------------------------------------------------------------------------
105606
+ /**
105607
+ * Ensure authentication is initialized before trading operations.
105608
+ */
105609
+ ensureAuth() {
105610
+ if (!this.auth) {
105611
+ throw new Error('Trading operations require authentication. Initialize LimitlessExchange with credentials: new LimitlessExchange({ privateKey: "0x..." })');
105612
+ }
105613
+ return this.auth;
105614
+ }
105615
+ async createOrder(params) {
105616
+ const auth = this.ensureAuth();
105617
+ const client = await auth.getClobClient();
105618
+ const side = params.side.toUpperCase() === "BUY" ? clob_client_1.Side.BUY : clob_client_1.Side.SELL;
105619
+ if (params.type === "limit" && !params.price) {
105620
+ throw new Error("Price is required for limit orders");
105621
+ }
105622
+ const price = params.price || (side === clob_client_1.Side.BUY ? 0.99 : 0.01);
105623
+ let tickSize;
105624
+ if (params.tickSize) {
105625
+ tickSize = params.tickSize.toString();
105626
+ } else {
105627
+ try {
105628
+ const orderBook = await this.fetchOrderBook(params.outcomeId);
105629
+ tickSize = this.inferTickSize(orderBook);
105630
+ } catch (error) {
105631
+ tickSize = "0.001";
105632
+ }
105633
+ }
104842
105634
  try {
104843
105635
  const response = await client.createAndPostOrder({
104844
105636
  tokenID: params.outcomeId,
@@ -104847,7 +105639,7 @@ var require_polymarket = __commonJS({
104847
105639
  size: params.amount,
104848
105640
  feeRateBps: 0
104849
105641
  }, {
104850
- tickSize: "0.01"
105642
+ tickSize
104851
105643
  });
104852
105644
  if (!response || !response.success) {
104853
105645
  throw new Error(response?.errorMsg || "Order placement failed");
@@ -104869,6 +105661,38 @@ var require_polymarket = __commonJS({
104869
105661
  throw error;
104870
105662
  }
104871
105663
  }
105664
+ /**
105665
+ * Infer the tick size from order book price levels.
105666
+ * Analyzes the decimal precision of existing orders to determine the market's tick size.
105667
+ */
105668
+ inferTickSize(orderBook) {
105669
+ const allPrices = [
105670
+ ...orderBook.bids.map((b) => b.price),
105671
+ ...orderBook.asks.map((a) => a.price)
105672
+ ];
105673
+ if (allPrices.length === 0) {
105674
+ return "0.001";
105675
+ }
105676
+ let minIncrement = 1;
105677
+ for (const price of allPrices) {
105678
+ const priceStr = price.toString();
105679
+ const decimalPart = priceStr.split(".")[1];
105680
+ if (decimalPart) {
105681
+ const decimals = decimalPart.length;
105682
+ const increment = Math.pow(10, -decimals);
105683
+ if (increment < minIncrement) {
105684
+ minIncrement = increment;
105685
+ }
105686
+ }
105687
+ }
105688
+ if (minIncrement >= 0.1)
105689
+ return "0.1";
105690
+ if (minIncrement >= 0.01)
105691
+ return "0.01";
105692
+ if (minIncrement >= 1e-3)
105693
+ return "0.001";
105694
+ return "0.0001";
105695
+ }
104872
105696
  async cancelOrder(orderId) {
104873
105697
  const auth = this.ensureAuth();
104874
105698
  const client = await auth.getClobClient();
@@ -104934,7 +105758,7 @@ var require_polymarket = __commonJS({
104934
105758
  timestamp: o.created_at * 1e3
104935
105759
  }));
104936
105760
  } catch (error) {
104937
- console.error("Error fetching Polymarket open orders:", error);
105761
+ console.error("Error fetching Limitless open orders:", error.message);
104938
105762
  return [];
104939
105763
  }
104940
105764
  }
@@ -104977,13 +105801,13 @@ var require_polymarket = __commonJS({
104977
105801
  }
104978
105802
  async watchOrderBook(id, limit) {
104979
105803
  if (!this.ws) {
104980
- this.ws = new websocket_1.PolymarketWebSocket(this.wsConfig);
105804
+ this.ws = new websocket_1.LimitlessWebSocket(this.wsConfig);
104981
105805
  }
104982
105806
  return this.ws.watchOrderBook(id);
104983
105807
  }
104984
105808
  async watchTrades(id, since, limit) {
104985
105809
  if (!this.ws) {
104986
- this.ws = new websocket_1.PolymarketWebSocket(this.wsConfig);
105810
+ this.ws = new websocket_1.LimitlessWebSocket(this.wsConfig);
104987
105811
  }
104988
105812
  return this.ws.watchTrades(id);
104989
105813
  }
@@ -104994,12 +105818,12 @@ var require_polymarket = __commonJS({
104994
105818
  }
104995
105819
  }
104996
105820
  };
104997
- exports2.PolymarketExchange = PolymarketExchange;
105821
+ exports2.LimitlessExchange = LimitlessExchange;
104998
105822
  }
104999
105823
  });
105000
105824
 
105001
105825
  // dist/exchanges/kalshi/utils.js
105002
- var require_utils10 = __commonJS({
105826
+ var require_utils11 = __commonJS({
105003
105827
  "dist/exchanges/kalshi/utils.js"(exports2) {
105004
105828
  "use strict";
105005
105829
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -105089,7 +105913,7 @@ var require_utils10 = __commonJS({
105089
105913
  });
105090
105914
 
105091
105915
  // dist/exchanges/kalshi/fetchMarkets.js
105092
- var require_fetchMarkets2 = __commonJS({
105916
+ var require_fetchMarkets3 = __commonJS({
105093
105917
  "dist/exchanges/kalshi/fetchMarkets.js"(exports2) {
105094
105918
  "use strict";
105095
105919
  var __importDefault = exports2 && exports2.__importDefault || function(mod) {
@@ -105099,7 +105923,7 @@ var require_fetchMarkets2 = __commonJS({
105099
105923
  exports2.resetCache = resetCache;
105100
105924
  exports2.fetchMarkets = fetchMarkets;
105101
105925
  var axios_1 = __importDefault(require_axios());
105102
- var utils_1 = require_utils10();
105926
+ var utils_1 = require_utils11();
105103
105927
  async function fetchActiveEvents(targetMarketCount) {
105104
105928
  let allEvents = [];
105105
105929
  let totalMarketCount = 0;
@@ -105219,12 +106043,12 @@ var require_fetchMarkets2 = __commonJS({
105219
106043
  });
105220
106044
 
105221
106045
  // dist/exchanges/kalshi/searchMarkets.js
105222
- var require_searchMarkets2 = __commonJS({
106046
+ var require_searchMarkets3 = __commonJS({
105223
106047
  "dist/exchanges/kalshi/searchMarkets.js"(exports2) {
105224
106048
  "use strict";
105225
106049
  Object.defineProperty(exports2, "__esModule", { value: true });
105226
106050
  exports2.searchMarkets = searchMarkets;
105227
- var fetchMarkets_1 = require_fetchMarkets2();
106051
+ var fetchMarkets_1 = require_fetchMarkets3();
105228
106052
  async function searchMarkets(query, params) {
105229
106053
  const fetchLimit = 1e5;
105230
106054
  try {
@@ -105251,7 +106075,7 @@ var require_searchMarkets2 = __commonJS({
105251
106075
  });
105252
106076
 
105253
106077
  // dist/exchanges/kalshi/searchEvents.js
105254
- var require_searchEvents2 = __commonJS({
106078
+ var require_searchEvents3 = __commonJS({
105255
106079
  "dist/exchanges/kalshi/searchEvents.js"(exports2) {
105256
106080
  "use strict";
105257
106081
  var __importDefault = exports2 && exports2.__importDefault || function(mod) {
@@ -105260,7 +106084,7 @@ var require_searchEvents2 = __commonJS({
105260
106084
  Object.defineProperty(exports2, "__esModule", { value: true });
105261
106085
  exports2.searchEvents = searchEvents;
105262
106086
  var axios_1 = __importDefault(require_axios());
105263
- var utils_1 = require_utils10();
106087
+ var utils_1 = require_utils11();
105264
106088
  async function searchEvents(query, params) {
105265
106089
  try {
105266
106090
  const queryParams = {
@@ -105313,7 +106137,7 @@ var require_searchEvents2 = __commonJS({
105313
106137
  });
105314
106138
 
105315
106139
  // dist/exchanges/kalshi/getMarketsBySlug.js
105316
- var require_getMarketsBySlug2 = __commonJS({
106140
+ var require_getMarketsBySlug3 = __commonJS({
105317
106141
  "dist/exchanges/kalshi/getMarketsBySlug.js"(exports2) {
105318
106142
  "use strict";
105319
106143
  var __importDefault = exports2 && exports2.__importDefault || function(mod) {
@@ -105322,7 +106146,7 @@ var require_getMarketsBySlug2 = __commonJS({
105322
106146
  Object.defineProperty(exports2, "__esModule", { value: true });
105323
106147
  exports2.getMarketsBySlug = getMarketsBySlug;
105324
106148
  var axios_1 = __importDefault(require_axios());
105325
- var utils_1 = require_utils10();
106149
+ var utils_1 = require_utils11();
105326
106150
  async function getMarketsBySlug(eventTicker) {
105327
106151
  try {
105328
106152
  const normalizedTicker = eventTicker.toUpperCase();
@@ -105371,7 +106195,7 @@ var require_getMarketsBySlug2 = __commonJS({
105371
106195
  });
105372
106196
 
105373
106197
  // dist/exchanges/kalshi/fetchOHLCV.js
105374
- var require_fetchOHLCV2 = __commonJS({
106198
+ var require_fetchOHLCV3 = __commonJS({
105375
106199
  "dist/exchanges/kalshi/fetchOHLCV.js"(exports2) {
105376
106200
  "use strict";
105377
106201
  var __importDefault = exports2 && exports2.__importDefault || function(mod) {
@@ -105380,7 +106204,7 @@ var require_fetchOHLCV2 = __commonJS({
105380
106204
  Object.defineProperty(exports2, "__esModule", { value: true });
105381
106205
  exports2.fetchOHLCV = fetchOHLCV;
105382
106206
  var axios_1 = __importDefault(require_axios());
105383
- var utils_1 = require_utils10();
106207
+ var utils_1 = require_utils11();
105384
106208
  async function fetchOHLCV(id, params) {
105385
106209
  try {
105386
106210
  const cleanedId = id.replace(/-NO$/, "");
@@ -105458,7 +106282,7 @@ var require_fetchOHLCV2 = __commonJS({
105458
106282
  });
105459
106283
 
105460
106284
  // dist/exchanges/kalshi/fetchOrderBook.js
105461
- var require_fetchOrderBook2 = __commonJS({
106285
+ var require_fetchOrderBook3 = __commonJS({
105462
106286
  "dist/exchanges/kalshi/fetchOrderBook.js"(exports2) {
105463
106287
  "use strict";
105464
106288
  var __importDefault = exports2 && exports2.__importDefault || function(mod) {
@@ -105509,7 +106333,7 @@ var require_fetchOrderBook2 = __commonJS({
105509
106333
  });
105510
106334
 
105511
106335
  // dist/exchanges/kalshi/fetchTrades.js
105512
- var require_fetchTrades2 = __commonJS({
106336
+ var require_fetchTrades3 = __commonJS({
105513
106337
  "dist/exchanges/kalshi/fetchTrades.js"(exports2) {
105514
106338
  "use strict";
105515
106339
  var __importDefault = exports2 && exports2.__importDefault || function(mod) {
@@ -105545,7 +106369,7 @@ var require_fetchTrades2 = __commonJS({
105545
106369
  });
105546
106370
 
105547
106371
  // dist/exchanges/kalshi/auth.js
105548
- var require_auth2 = __commonJS({
106372
+ var require_auth3 = __commonJS({
105549
106373
  "dist/exchanges/kalshi/auth.js"(exports2) {
105550
106374
  "use strict";
105551
106375
  var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
@@ -105645,7 +106469,7 @@ var require_auth2 = __commonJS({
105645
106469
  });
105646
106470
 
105647
106471
  // dist/exchanges/kalshi/websocket.js
105648
- var require_websocket4 = __commonJS({
106472
+ var require_websocket5 = __commonJS({
105649
106473
  "dist/exchanges/kalshi/websocket.js"(exports2) {
105650
106474
  "use strict";
105651
106475
  var __importDefault = exports2 && exports2.__importDefault || function(mod) {
@@ -105939,15 +106763,15 @@ var require_kalshi = __commonJS({
105939
106763
  exports2.KalshiExchange = void 0;
105940
106764
  var axios_1 = __importDefault(require_axios());
105941
106765
  var BaseExchange_1 = require_BaseExchange();
105942
- var fetchMarkets_1 = require_fetchMarkets2();
105943
- var searchMarkets_1 = require_searchMarkets2();
105944
- var searchEvents_1 = require_searchEvents2();
105945
- var getMarketsBySlug_1 = require_getMarketsBySlug2();
105946
- var fetchOHLCV_1 = require_fetchOHLCV2();
105947
- var fetchOrderBook_1 = require_fetchOrderBook2();
105948
- var fetchTrades_1 = require_fetchTrades2();
105949
- var auth_1 = require_auth2();
105950
- var websocket_1 = require_websocket4();
106766
+ var fetchMarkets_1 = require_fetchMarkets3();
106767
+ var searchMarkets_1 = require_searchMarkets3();
106768
+ var searchEvents_1 = require_searchEvents3();
106769
+ var getMarketsBySlug_1 = require_getMarketsBySlug3();
106770
+ var fetchOHLCV_1 = require_fetchOHLCV3();
106771
+ var fetchOrderBook_1 = require_fetchOrderBook3();
106772
+ var fetchTrades_1 = require_fetchTrades3();
106773
+ var auth_1 = require_auth3();
106774
+ var websocket_1 = require_websocket5();
105951
106775
  var KalshiExchange = class extends BaseExchange_1.PredictionMarketExchange {
105952
106776
  constructor(options) {
105953
106777
  let credentials;
@@ -106233,9 +107057,11 @@ var require_app = __commonJS({
106233
107057
  var express_1 = __importDefault(require_express2());
106234
107058
  var cors_1 = __importDefault(require_lib3());
106235
107059
  var polymarket_1 = require_polymarket();
107060
+ var limitless_1 = require_limitless();
106236
107061
  var kalshi_1 = require_kalshi();
106237
107062
  var defaultExchanges = {
106238
107063
  polymarket: null,
107064
+ limitless: null,
106239
107065
  kalshi: null
106240
107066
  };
106241
107067
  async function startServer(port, accessToken) {
@@ -106299,6 +107125,13 @@ var require_app = __commonJS({
106299
107125
  apiSecret: credentials?.apiSecret || process.env.POLYMARKET_API_SECRET,
106300
107126
  passphrase: credentials?.passphrase || process.env.POLYMARKET_PASSPHRASE
106301
107127
  });
107128
+ case "limitless":
107129
+ return new limitless_1.LimitlessExchange({
107130
+ privateKey: credentials?.privateKey || process.env.LIMITLESS_PK || process.env.LIMITLESS_PRIVATE_KEY,
107131
+ apiKey: credentials?.apiKey || process.env.LIMITLESS_API_KEY,
107132
+ apiSecret: credentials?.apiSecret || process.env.LIMITLESS_API_SECRET,
107133
+ passphrase: credentials?.passphrase || process.env.LIMITLESS_PASSPHRASE
107134
+ });
106302
107135
  case "kalshi":
106303
107136
  return new kalshi_1.KalshiExchange({
106304
107137
  apiKey: credentials?.apiKey || process.env.KALSHI_API_KEY,
pmxt/server_manager.py CHANGED
@@ -209,15 +209,19 @@ class ServerManager:
209
209
  Start the server using the pmxt-ensure-server launcher.
210
210
  """
211
211
  # 1. Check for bundled server (PRODUCTION - installed via pip)
212
- bundled_launcher = Path(__file__).parent / '_server' / 'bin' / 'pmxt-ensure-server'
213
-
212
+ launcher_filename = 'pmxt-ensure-server'
213
+ if os.name == "nt": # Check if running Windows
214
+ launcher_filename += ".js"
215
+
216
+ bundled_launcher = Path(__file__).parent / '_server' / 'bin' / launcher_filename
217
+
214
218
  # 2. Check for monorepo structure (DEVELOPMENT)
215
219
  current_file = Path(__file__).resolve()
216
- local_launcher = current_file.parent.parent.parent.parent / 'core' / 'bin' / 'pmxt-ensure-server'
217
-
220
+ local_launcher = current_file.parent.parent.parent.parent / 'core' / 'bin' / launcher_filename
221
+
218
222
  # 3. Check PATH (GLOBAL INSTALL)
219
- path_launcher = shutil.which('pmxt-ensure-server')
220
-
223
+ path_launcher = shutil.which(launcher_filename)
224
+
221
225
  # Priority order: bundled > local dev > PATH
222
226
  if bundled_launcher.exists():
223
227
  launcher = str(bundled_launcher)
@@ -235,7 +239,7 @@ class ServerManager:
235
239
 
236
240
  # Call the launcher
237
241
  try:
238
- # If it's a JS file and we are calling it directly, might need node
242
+ # If it's a JS file, and we are calling it directly, might need node
239
243
  cmd = [launcher]
240
244
  if launcher.endswith('.js') or not os.access(launcher, os.X_OK):
241
245
  cmd = ['node', launcher]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pmxt
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: Unified prediction market data API - The ccxt for prediction markets
5
5
  Author: PMXT Contributors
6
6
  License: MIT
@@ -1,14 +1,15 @@
1
- pmxt/__init__.py,sha256=MAOqnWgwuaG-IN2JEPoGdUrp2DHARbZAFjHd-SmyEvs,1150
1
+ pmxt/__init__.py,sha256=ZPF_ko0cpffhd09VocB3qhkqlRaVOCmjuVkyZ6pkPU8,1150
2
2
  pmxt/client.py,sha256=1qa8ObZtf-tdzhDXQXvWWdeLvGbyxsiVHAgQvl8Z4Uk,32955
3
3
  pmxt/models.py,sha256=-jiQ9mmv_qnF6mzj3DrvNgEA77tE_Pl0RCblM1VbV7o,8581
4
- pmxt/server_manager.py,sha256=-G97dYEdKl7F3HK9bAOKYl-SGWP6HsvzZIx2QxiZm24,11494
4
+ pmxt/server_manager.py,sha256=6uS1LIZ2d5d_K-MtbMUAlCZvbvhZ_iyofKok55HEofc,11606
5
5
  pmxt/_server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pmxt/_server/bin/pmxt-ensure-server,sha256=kXIond0UbxS52FAVQD7kHmSBaL_s6cbIyapLRr4KZJw,4544
7
- pmxt/_server/server/bundled.js,sha256=ETpsJ6ZmRtO1gQmBZYwwHWTHJIEI8ooeeMhOwoeDJ84,4198184
8
- pmxt_internal/__init__.py,sha256=Kbxeq4WFfhIjcDkz72ZeXhWFpecUcOXCwUgqUzs6qsw,7578
9
- pmxt_internal/api_client.py,sha256=2XZZdrKh90kAA4P3bJ54IdzRfAFMawSUqwnp2pRZNYA,27889
7
+ pmxt/_server/bin/pmxt-ensure-server.js,sha256=kXIond0UbxS52FAVQD7kHmSBaL_s6cbIyapLRr4KZJw,4544
8
+ pmxt/_server/server/bundled.js,sha256=vq8SwFCZcuApDMUupQGMDDOlSv7dy62LXNTODCRHiZc,4228689
9
+ pmxt_internal/__init__.py,sha256=dyYj3OhFsjezgo0DTh1GPbUu9mIfKEHn-rHFI1awI4g,7578
10
+ pmxt_internal/api_client.py,sha256=terc7r4idrh8DbO-6iQ5A54bb_eJL7H6GkBOjFwCUqA,27889
10
11
  pmxt_internal/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
11
- pmxt_internal/configuration.py,sha256=evyyjQzPpYofXsIUdNKTMlMbpmq38l2ISokDuXJ0qJ0,18320
12
+ pmxt_internal/configuration.py,sha256=Qv9sYMIi_aut2V0cljQEWGDOrsjs5UcSZ_ipt3NAuSk,18320
12
13
  pmxt_internal/exceptions.py,sha256=txF8A7vlan57JS69kFPs-IZF-Qhp7IZobBTJVa4fOaM,6644
13
14
  pmxt_internal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
15
  pmxt_internal/rest.py,sha256=FMj4yaV6XLr842u_ScWHSzQsTFdk0jaUeuWLJoRbogQ,9760
@@ -64,7 +65,7 @@ pmxt_internal/models/unified_market.py,sha256=DoYhiH4HycYGlq858PEeB-CIA7haT6rxmJ
64
65
  pmxt_internal/models/watch_order_book_request.py,sha256=kavGUI-SLz2-Kam_jcJ_h0GDe0-9UkxqCmVsAi6Uios,3726
65
66
  pmxt_internal/models/watch_order_book_request_args_inner.py,sha256=ZHrjmFDGxRG5MXbuz4mUp9KFfo3XS7zuXWTyMNgi4xI,5464
66
67
  pmxt_internal/models/watch_trades_request.py,sha256=brrg8JbEe-aeg7mIe_Y2HzRPogp-IfRhkXChrxzqoLU,3722
67
- pmxt-1.4.0.dist-info/METADATA,sha256=6fTb2tiWCkPoyKkYSs16e6yzhUdp-s-NaE7NPY6VFhc,6449
68
- pmxt-1.4.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
69
- pmxt-1.4.0.dist-info/top_level.txt,sha256=J_jrcouJ-x-5lpcXMxeW0GOSi1HsBVR5_PdSfvigVrw,19
70
- pmxt-1.4.0.dist-info/RECORD,,
68
+ pmxt-1.5.0.dist-info/METADATA,sha256=Yj_I-KzPsqS3PERHSeeXCAbEwzYfLWW96ILbxUVa7dI,6449
69
+ pmxt-1.5.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
70
+ pmxt-1.5.0.dist-info/top_level.txt,sha256=J_jrcouJ-x-5lpcXMxeW0GOSi1HsBVR5_PdSfvigVrw,19
71
+ pmxt-1.5.0.dist-info/RECORD,,
pmxt_internal/__init__.py CHANGED
@@ -14,7 +14,7 @@
14
14
  """ # noqa: E501
15
15
 
16
16
 
17
- __version__ = "1.4.0"
17
+ __version__ = "1.5.0"
18
18
 
19
19
  # Define package exports
20
20
  __all__ = [
@@ -91,7 +91,7 @@ class ApiClient:
91
91
  self.default_headers[header_name] = header_value
92
92
  self.cookie = cookie
93
93
  # Set default User-Agent.
94
- self.user_agent = 'OpenAPI-Generator/1.4.0/python'
94
+ self.user_agent = 'OpenAPI-Generator/1.5.0/python'
95
95
  self.client_side_validation = configuration.client_side_validation
96
96
 
97
97
  def __enter__(self):
@@ -506,7 +506,7 @@ class Configuration:
506
506
  "OS: {env}\n"\
507
507
  "Python Version: {pyversion}\n"\
508
508
  "Version of the API: 0.4.4\n"\
509
- "SDK Package Version: 1.4.0".\
509
+ "SDK Package Version: 1.5.0".\
510
510
  format(env=sys.platform, pyversion=sys.version)
511
511
 
512
512
  def get_host_settings(self) -> List[HostSetting]:
File without changes