pmxt-core 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BaseExchange.js +1 -0
- package/dist/errors.js +11 -0
- package/dist/exchanges/kalshi/auth.js +1 -0
- package/dist/exchanges/kalshi/index.js +6 -0
- package/dist/exchanges/kalshi/websocket.js +14 -9
- package/dist/exchanges/limitless/auth.js +4 -0
- package/dist/exchanges/limitless/client.js +5 -1
- package/dist/exchanges/limitless/index.js +8 -1
- package/dist/exchanges/limitless/websocket.js +7 -5
- package/dist/exchanges/polymarket/auth.js +6 -0
- package/dist/exchanges/polymarket/index.js +6 -0
- package/dist/exchanges/polymarket/websocket.js +6 -3
- package/dist/exchanges/probable/auth.d.ts +14 -0
- package/dist/exchanges/probable/auth.js +67 -0
- package/dist/exchanges/probable/errors.d.ts +8 -0
- package/dist/exchanges/probable/errors.js +61 -0
- package/dist/exchanges/probable/fetchEvents.d.ts +5 -0
- package/dist/exchanges/probable/fetchEvents.js +138 -0
- package/dist/exchanges/probable/fetchMarkets.d.ts +3 -0
- package/dist/exchanges/probable/fetchMarkets.js +205 -0
- package/dist/exchanges/probable/fetchOHLCV.d.ts +3 -0
- package/dist/exchanges/probable/fetchOHLCV.js +83 -0
- package/dist/exchanges/probable/fetchOrderBook.d.ts +2 -0
- package/dist/exchanges/probable/fetchOrderBook.js +37 -0
- package/dist/exchanges/probable/fetchPositions.d.ts +2 -0
- package/dist/exchanges/probable/fetchPositions.js +33 -0
- package/dist/exchanges/probable/fetchTrades.d.ts +10 -0
- package/dist/exchanges/probable/fetchTrades.js +36 -0
- package/dist/exchanges/probable/index.d.ts +35 -0
- package/dist/exchanges/probable/index.js +317 -0
- package/dist/exchanges/probable/utils.d.ts +9 -0
- package/dist/exchanges/probable/utils.js +106 -0
- package/dist/exchanges/probable/websocket.d.ts +27 -0
- package/dist/exchanges/probable/websocket.js +102 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -2
- package/dist/server/app.js +10 -1
- package/dist/server/utils/lock-file.js +1 -0
- package/dist/utils/error-mapper.js +1 -0
- package/package.json +4 -3
package/dist/BaseExchange.js
CHANGED
package/dist/errors.js
CHANGED
|
@@ -8,6 +8,14 @@ exports.ExchangeNotAvailable = exports.NetworkError = exports.ValidationError =
|
|
|
8
8
|
* across exchanges with HTTP status codes and retry semantics.
|
|
9
9
|
*/
|
|
10
10
|
class BaseError extends Error {
|
|
11
|
+
/** HTTP status code */
|
|
12
|
+
status;
|
|
13
|
+
/** Machine-readable error code */
|
|
14
|
+
code;
|
|
15
|
+
/** Whether the operation can be retried */
|
|
16
|
+
retryable;
|
|
17
|
+
/** Which exchange threw the error */
|
|
18
|
+
exchange;
|
|
11
19
|
constructor(message, status, code, retryable = false, exchange) {
|
|
12
20
|
super(message);
|
|
13
21
|
this.name = this.constructor.name;
|
|
@@ -83,6 +91,8 @@ exports.MarketNotFound = MarketNotFound;
|
|
|
83
91
|
* 429 Too Many Requests - Rate limit exceeded
|
|
84
92
|
*/
|
|
85
93
|
class RateLimitExceeded extends BaseError {
|
|
94
|
+
/** Number of seconds to wait before retrying */
|
|
95
|
+
retryAfter;
|
|
86
96
|
constructor(message, retryAfter, exchange) {
|
|
87
97
|
super(message, 429, 'RATE_LIMIT_EXCEEDED', true, exchange);
|
|
88
98
|
this.retryAfter = retryAfter;
|
|
@@ -111,6 +121,7 @@ exports.InsufficientFunds = InsufficientFunds;
|
|
|
111
121
|
* 400 Bad Request - Input validation failed
|
|
112
122
|
*/
|
|
113
123
|
class ValidationError extends BaseError {
|
|
124
|
+
field;
|
|
114
125
|
constructor(message, field, exchange) {
|
|
115
126
|
super(message, 400, 'VALIDATION_ERROR', false, exchange);
|
|
116
127
|
this.field = field;
|
|
@@ -41,6 +41,7 @@ const errors_1 = require("./errors");
|
|
|
41
41
|
* Reference: https://docs.kalshi.com/getting_started/quick_start_authenticated_requests
|
|
42
42
|
*/
|
|
43
43
|
class KalshiAuth {
|
|
44
|
+
credentials;
|
|
44
45
|
constructor(credentials) {
|
|
45
46
|
this.credentials = credentials;
|
|
46
47
|
this.validateCredentials();
|
|
@@ -16,6 +16,8 @@ const websocket_1 = require("./websocket");
|
|
|
16
16
|
const errors_1 = require("./errors");
|
|
17
17
|
const errors_2 = require("../../errors");
|
|
18
18
|
class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
19
|
+
auth;
|
|
20
|
+
wsConfig;
|
|
19
21
|
constructor(options) {
|
|
20
22
|
// Support both old signature (credentials only) and new signature (options object)
|
|
21
23
|
let credentials;
|
|
@@ -283,6 +285,10 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
283
285
|
return 'open';
|
|
284
286
|
}
|
|
285
287
|
}
|
|
288
|
+
// ----------------------------------------------------------------------------
|
|
289
|
+
// WebSocket Methods
|
|
290
|
+
// ----------------------------------------------------------------------------
|
|
291
|
+
ws;
|
|
286
292
|
async watchOrderBook(id, limit) {
|
|
287
293
|
const auth = this.ensureAuth();
|
|
288
294
|
if (!this.ws) {
|
|
@@ -10,16 +10,21 @@ const ws_1 = __importDefault(require("ws"));
|
|
|
10
10
|
* Follows CCXT Pro-style async iterator pattern.
|
|
11
11
|
*/
|
|
12
12
|
class KalshiWebSocket {
|
|
13
|
+
ws;
|
|
14
|
+
auth;
|
|
15
|
+
config;
|
|
16
|
+
orderBookResolvers = new Map();
|
|
17
|
+
tradeResolvers = new Map();
|
|
18
|
+
orderBooks = new Map();
|
|
19
|
+
subscribedOrderBookTickers = new Set();
|
|
20
|
+
subscribedTradeTickers = new Set();
|
|
21
|
+
messageIdCounter = 1;
|
|
22
|
+
isConnecting = false;
|
|
23
|
+
isConnected = false;
|
|
24
|
+
reconnectTimer;
|
|
25
|
+
connectionPromise;
|
|
26
|
+
isTerminated = false;
|
|
13
27
|
constructor(auth, config = {}) {
|
|
14
|
-
this.orderBookResolvers = new Map();
|
|
15
|
-
this.tradeResolvers = new Map();
|
|
16
|
-
this.orderBooks = new Map();
|
|
17
|
-
this.subscribedOrderBookTickers = new Set();
|
|
18
|
-
this.subscribedTradeTickers = new Set();
|
|
19
|
-
this.messageIdCounter = 1;
|
|
20
|
-
this.isConnecting = false;
|
|
21
|
-
this.isConnected = false;
|
|
22
|
-
this.isTerminated = false;
|
|
23
28
|
this.auth = auth;
|
|
24
29
|
this.config = {
|
|
25
30
|
wsUrl: config.wsUrl || 'wss://api.elections.kalshi.com/trade-api/ws/v2',
|
|
@@ -9,6 +9,10 @@ const LIMITLESS_HOST = 'https://api.limitless.exchange';
|
|
|
9
9
|
* Simplified from cookie-based to API key authentication.
|
|
10
10
|
*/
|
|
11
11
|
class LimitlessAuth {
|
|
12
|
+
credentials;
|
|
13
|
+
signer;
|
|
14
|
+
httpClient;
|
|
15
|
+
apiKey;
|
|
12
16
|
constructor(credentials) {
|
|
13
17
|
this.credentials = credentials;
|
|
14
18
|
// API key is required for authenticated endpoints
|
|
@@ -9,8 +9,12 @@ const LIMITLESS_API_URL = 'https://api.limitless.exchange';
|
|
|
9
9
|
* Provides a simplified interface for market data and order operations.
|
|
10
10
|
*/
|
|
11
11
|
class LimitlessClient {
|
|
12
|
+
httpClient;
|
|
13
|
+
orderClient;
|
|
14
|
+
marketFetcher;
|
|
15
|
+
signer;
|
|
16
|
+
marketCache = {};
|
|
12
17
|
constructor(privateKey, apiKey) {
|
|
13
|
-
this.marketCache = {};
|
|
14
18
|
// Fix for common .env issue where newlines are escaped
|
|
15
19
|
if (privateKey.includes('\\n')) {
|
|
16
20
|
privateKey = privateKey.replace(/\\n/g, '\n');
|
|
@@ -16,6 +16,9 @@ const errors_2 = require("../../errors");
|
|
|
16
16
|
const sdk_1 = require("@limitless-exchange/sdk");
|
|
17
17
|
const ethers_1 = require("ethers");
|
|
18
18
|
class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
19
|
+
auth;
|
|
20
|
+
client;
|
|
21
|
+
wsConfig;
|
|
19
22
|
constructor(options) {
|
|
20
23
|
// Support both old signature (credentials only) and new signature (options object)
|
|
21
24
|
let credentials;
|
|
@@ -112,7 +115,7 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
112
115
|
throw new Error('Limit orders require a price');
|
|
113
116
|
}
|
|
114
117
|
// Limitless (USDC on Base) supports 6 decimals max.
|
|
115
|
-
const price = Math.round(params.price *
|
|
118
|
+
const price = Math.round(params.price * 1_000_000) / 1_000_000;
|
|
116
119
|
const response = await client.createOrder({
|
|
117
120
|
marketSlug: marketSlug,
|
|
118
121
|
outcomeId: params.outcomeId,
|
|
@@ -231,6 +234,10 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
231
234
|
throw errors_1.limitlessErrorMapper.mapError(error);
|
|
232
235
|
}
|
|
233
236
|
}
|
|
237
|
+
// ----------------------------------------------------------------------------
|
|
238
|
+
// WebSocket Methods
|
|
239
|
+
// ----------------------------------------------------------------------------
|
|
240
|
+
ws;
|
|
234
241
|
/**
|
|
235
242
|
* Initialize WebSocket with API key if available.
|
|
236
243
|
*/
|
|
@@ -21,12 +21,14 @@ function convertSize(rawSize) {
|
|
|
21
21
|
* - User transactions (requires API key)
|
|
22
22
|
*/
|
|
23
23
|
class LimitlessWebSocket {
|
|
24
|
+
client;
|
|
25
|
+
config;
|
|
26
|
+
orderbookCallbacks = new Map();
|
|
27
|
+
priceCallbacks = new Map();
|
|
28
|
+
orderbookResolvers = new Map();
|
|
29
|
+
orderbookBuffers = new Map();
|
|
30
|
+
lastOrderbookTimestamps = new Map();
|
|
24
31
|
constructor(config = {}) {
|
|
25
|
-
this.orderbookCallbacks = new Map();
|
|
26
|
-
this.priceCallbacks = new Map();
|
|
27
|
-
this.orderbookResolvers = new Map();
|
|
28
|
-
this.orderbookBuffers = new Map();
|
|
29
|
-
this.lastOrderbookTimestamps = new Map();
|
|
30
32
|
this.config = config;
|
|
31
33
|
// Initialize SDK WebSocket client
|
|
32
34
|
const wsConfig = {
|
|
@@ -15,6 +15,12 @@ const POLYGON_CHAIN_ID = 137;
|
|
|
15
15
|
* Handles both L1 (wallet-based) and L2 (API credentials) authentication.
|
|
16
16
|
*/
|
|
17
17
|
class PolymarketAuth {
|
|
18
|
+
credentials;
|
|
19
|
+
signer;
|
|
20
|
+
clobClient;
|
|
21
|
+
apiCreds;
|
|
22
|
+
discoveredProxyAddress;
|
|
23
|
+
discoveredSignatureType;
|
|
18
24
|
constructor(credentials) {
|
|
19
25
|
this.credentials = credentials;
|
|
20
26
|
if (!credentials.privateKey) {
|
|
@@ -14,6 +14,8 @@ const websocket_1 = require("./websocket");
|
|
|
14
14
|
const errors_1 = require("./errors");
|
|
15
15
|
const errors_2 = require("../../errors");
|
|
16
16
|
class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
17
|
+
auth;
|
|
18
|
+
wsConfig;
|
|
17
19
|
constructor(options) {
|
|
18
20
|
// Support both old signature (credentials only) and new signature (options object)
|
|
19
21
|
let credentials;
|
|
@@ -293,6 +295,10 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
293
295
|
throw errors_1.polymarketErrorMapper.mapError(error);
|
|
294
296
|
}
|
|
295
297
|
}
|
|
298
|
+
// ----------------------------------------------------------------------------
|
|
299
|
+
// WebSocket Methods
|
|
300
|
+
// ----------------------------------------------------------------------------
|
|
301
|
+
ws;
|
|
296
302
|
async watchOrderBook(id, limit) {
|
|
297
303
|
if (!this.ws) {
|
|
298
304
|
this.ws = new websocket_1.PolymarketWebSocket(this.wsConfig);
|
|
@@ -46,10 +46,13 @@ exports.PolymarketWebSocket = void 0;
|
|
|
46
46
|
* watchOrderBook() and watchTrades() methods.
|
|
47
47
|
*/
|
|
48
48
|
class PolymarketWebSocket {
|
|
49
|
+
manager;
|
|
50
|
+
orderBookResolvers = new Map();
|
|
51
|
+
tradeResolvers = new Map();
|
|
52
|
+
orderBooks = new Map();
|
|
53
|
+
config;
|
|
54
|
+
initializationPromise;
|
|
49
55
|
constructor(config = {}) {
|
|
50
|
-
this.orderBookResolvers = new Map();
|
|
51
|
-
this.tradeResolvers = new Map();
|
|
52
|
-
this.orderBooks = new Map();
|
|
53
56
|
this.config = config;
|
|
54
57
|
}
|
|
55
58
|
async ensureInitialized() {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createClobClient } from '@prob/clob';
|
|
2
|
+
import { ExchangeCredentials } from '../../BaseExchange';
|
|
3
|
+
/**
|
|
4
|
+
* Manages Probable authentication and CLOB client initialization.
|
|
5
|
+
* Requires a privateKey and pre-generated API key triplet (apiKey, apiSecret, passphrase).
|
|
6
|
+
*/
|
|
7
|
+
export declare class ProbableAuth {
|
|
8
|
+
private credentials;
|
|
9
|
+
private clobClient?;
|
|
10
|
+
private walletAddress;
|
|
11
|
+
constructor(credentials: ExchangeCredentials);
|
|
12
|
+
getClobClient(): ReturnType<typeof createClobClient>;
|
|
13
|
+
getAddress(): string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProbableAuth = void 0;
|
|
4
|
+
const clob_1 = require("@prob/clob");
|
|
5
|
+
const accounts_1 = require("viem/accounts");
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
const chains_1 = require("viem/chains");
|
|
8
|
+
/**
|
|
9
|
+
* Manages Probable authentication and CLOB client initialization.
|
|
10
|
+
* Requires a privateKey and pre-generated API key triplet (apiKey, apiSecret, passphrase).
|
|
11
|
+
*/
|
|
12
|
+
class ProbableAuth {
|
|
13
|
+
credentials;
|
|
14
|
+
clobClient;
|
|
15
|
+
walletAddress;
|
|
16
|
+
constructor(credentials) {
|
|
17
|
+
this.credentials = credentials;
|
|
18
|
+
if (!credentials.privateKey) {
|
|
19
|
+
throw new Error('Probable requires a privateKey for authentication');
|
|
20
|
+
}
|
|
21
|
+
if (!credentials.apiKey || !credentials.apiSecret || !credentials.passphrase) {
|
|
22
|
+
throw new Error('Probable requires pre-generated API credentials (apiKey, apiSecret, passphrase). ' +
|
|
23
|
+
'Generate them at https://probable.markets or via the SDK.');
|
|
24
|
+
}
|
|
25
|
+
const account = (0, accounts_1.privateKeyToAccount)(credentials.privateKey);
|
|
26
|
+
this.walletAddress = account.address;
|
|
27
|
+
}
|
|
28
|
+
getClobClient() {
|
|
29
|
+
if (this.clobClient) {
|
|
30
|
+
return this.clobClient;
|
|
31
|
+
}
|
|
32
|
+
const chainId = parseInt(process.env.PROBABLE_CHAIN_ID || '56', 10);
|
|
33
|
+
const chain = chainId === 97 ? chains_1.bscTestnet : chains_1.bsc;
|
|
34
|
+
const account = (0, accounts_1.privateKeyToAccount)(this.credentials.privateKey);
|
|
35
|
+
const wallet = (0, viem_1.createWalletClient)({
|
|
36
|
+
account,
|
|
37
|
+
chain,
|
|
38
|
+
transport: (0, viem_1.http)(),
|
|
39
|
+
});
|
|
40
|
+
const credential = {
|
|
41
|
+
key: this.credentials.apiKey,
|
|
42
|
+
secret: this.credentials.apiSecret,
|
|
43
|
+
passphrase: this.credentials.passphrase,
|
|
44
|
+
};
|
|
45
|
+
if (chainId === 56) {
|
|
46
|
+
this.clobClient = (0, clob_1.createClobClient)({
|
|
47
|
+
chainId: 56,
|
|
48
|
+
wallet,
|
|
49
|
+
credential,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const baseUrl = process.env.PROBABLE_BASE_URL || 'https://api.probable.markets/public/api/v1';
|
|
54
|
+
this.clobClient = (0, clob_1.createClobClient)({
|
|
55
|
+
chainId,
|
|
56
|
+
baseUrl,
|
|
57
|
+
wallet,
|
|
58
|
+
credential,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return this.clobClient;
|
|
62
|
+
}
|
|
63
|
+
getAddress() {
|
|
64
|
+
return this.walletAddress;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.ProbableAuth = ProbableAuth;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ErrorMapper } from '../../utils/error-mapper';
|
|
2
|
+
import { BadRequest } from '../../errors';
|
|
3
|
+
export declare class ProbableErrorMapper extends ErrorMapper {
|
|
4
|
+
constructor();
|
|
5
|
+
protected extractErrorMessage(error: any): string;
|
|
6
|
+
protected mapBadRequestError(message: string, data: any): BadRequest;
|
|
7
|
+
}
|
|
8
|
+
export declare const probableErrorMapper: ProbableErrorMapper;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.probableErrorMapper = exports.ProbableErrorMapper = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const error_mapper_1 = require("../../utils/error-mapper");
|
|
9
|
+
const errors_1 = require("../../errors");
|
|
10
|
+
class ProbableErrorMapper extends error_mapper_1.ErrorMapper {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('Probable');
|
|
13
|
+
}
|
|
14
|
+
extractErrorMessage(error) {
|
|
15
|
+
if (axios_1.default.isAxiosError(error) && error.response?.data) {
|
|
16
|
+
const data = error.response.data;
|
|
17
|
+
if (data.detail) {
|
|
18
|
+
return typeof data.detail === 'string' ? data.detail : JSON.stringify(data.detail);
|
|
19
|
+
}
|
|
20
|
+
if (data.message) {
|
|
21
|
+
return String(data.message);
|
|
22
|
+
}
|
|
23
|
+
if (data.error) {
|
|
24
|
+
return typeof data.error === 'string' ? data.error : JSON.stringify(data.error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Handle @prob/clob SDK error objects
|
|
28
|
+
if (error && typeof error === 'object' && error.msg) {
|
|
29
|
+
return String(error.msg);
|
|
30
|
+
}
|
|
31
|
+
return super.extractErrorMessage(error);
|
|
32
|
+
}
|
|
33
|
+
mapBadRequestError(message, data) {
|
|
34
|
+
const lowerMessage = message.toLowerCase();
|
|
35
|
+
// SDK auth failures
|
|
36
|
+
if (lowerMessage.includes('l1 auth') ||
|
|
37
|
+
lowerMessage.includes('l2 auth') ||
|
|
38
|
+
lowerMessage.includes('invalid api key') ||
|
|
39
|
+
lowerMessage.includes('invalid signature') ||
|
|
40
|
+
lowerMessage.includes('api key')) {
|
|
41
|
+
return new errors_1.AuthenticationError(message, this.exchangeName);
|
|
42
|
+
}
|
|
43
|
+
// Insufficient funds
|
|
44
|
+
if (lowerMessage.includes('insufficient') ||
|
|
45
|
+
lowerMessage.includes('balance') ||
|
|
46
|
+
lowerMessage.includes('not enough')) {
|
|
47
|
+
return new errors_1.InsufficientFunds(message, this.exchangeName);
|
|
48
|
+
}
|
|
49
|
+
// Invalid order params
|
|
50
|
+
if (lowerMessage.includes('invalid order') ||
|
|
51
|
+
lowerMessage.includes('tick size') ||
|
|
52
|
+
lowerMessage.includes('price must') ||
|
|
53
|
+
lowerMessage.includes('size must') ||
|
|
54
|
+
lowerMessage.includes('amount must')) {
|
|
55
|
+
return new errors_1.InvalidOrder(message, this.exchangeName);
|
|
56
|
+
}
|
|
57
|
+
return super.mapBadRequestError(message, data);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.ProbableErrorMapper = ProbableErrorMapper;
|
|
61
|
+
exports.probableErrorMapper = new ProbableErrorMapper();
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { EventFetchParams } from '../../BaseExchange';
|
|
2
|
+
import { UnifiedEvent } from '../../types';
|
|
3
|
+
export declare function fetchEvents(params: EventFetchParams): Promise<UnifiedEvent[]>;
|
|
4
|
+
export declare function fetchEventById(id: string): Promise<UnifiedEvent | null>;
|
|
5
|
+
export declare function fetchEventBySlug(slug: string): Promise<UnifiedEvent | null>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.fetchEvents = fetchEvents;
|
|
7
|
+
exports.fetchEventById = fetchEventById;
|
|
8
|
+
exports.fetchEventBySlug = fetchEventBySlug;
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
const errors_1 = require("./errors");
|
|
12
|
+
async function fetchEvents(params) {
|
|
13
|
+
try {
|
|
14
|
+
// Query-based search: use the search endpoint (only endpoint with text search)
|
|
15
|
+
if (params.query) {
|
|
16
|
+
return await searchEvents(params);
|
|
17
|
+
}
|
|
18
|
+
// Default: use the dedicated events API for listing
|
|
19
|
+
return await fetchEventsList(params);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw errors_1.probableErrorMapper.mapError(error);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function fetchEventById(id) {
|
|
26
|
+
try {
|
|
27
|
+
const numericId = Number(id);
|
|
28
|
+
if (isNaN(numericId))
|
|
29
|
+
return null;
|
|
30
|
+
const response = await axios_1.default.get(`${utils_1.BASE_URL}${utils_1.EVENTS_PATH}${numericId}`);
|
|
31
|
+
const event = (0, utils_1.mapEventToUnified)(response.data);
|
|
32
|
+
if (event)
|
|
33
|
+
await (0, utils_1.enrichMarketsWithPrices)(event.markets);
|
|
34
|
+
return event;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (isNotFoundError(error))
|
|
38
|
+
return null;
|
|
39
|
+
throw errors_1.probableErrorMapper.mapError(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function fetchEventBySlug(slug) {
|
|
43
|
+
try {
|
|
44
|
+
const response = await axios_1.default.get(`${utils_1.BASE_URL}${utils_1.EVENTS_PATH}slug/${slug}`);
|
|
45
|
+
const event = (0, utils_1.mapEventToUnified)(response.data);
|
|
46
|
+
if (event)
|
|
47
|
+
await (0, utils_1.enrichMarketsWithPrices)(event.markets);
|
|
48
|
+
return event;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (isNotFoundError(error))
|
|
52
|
+
return null;
|
|
53
|
+
throw errors_1.probableErrorMapper.mapError(error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function fetchEventsList(params) {
|
|
57
|
+
const limit = params.limit || 20;
|
|
58
|
+
const page = params.offset ? Math.floor(params.offset / limit) + 1 : 1;
|
|
59
|
+
const queryParams = {
|
|
60
|
+
page,
|
|
61
|
+
limit,
|
|
62
|
+
};
|
|
63
|
+
// Map status
|
|
64
|
+
if (params.status) {
|
|
65
|
+
switch (params.status) {
|
|
66
|
+
case 'active':
|
|
67
|
+
queryParams.status = 'active';
|
|
68
|
+
break;
|
|
69
|
+
case 'inactive':
|
|
70
|
+
case 'closed':
|
|
71
|
+
queryParams.status = 'closed';
|
|
72
|
+
break;
|
|
73
|
+
case 'all':
|
|
74
|
+
queryParams.status = 'all';
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
queryParams.status = 'active';
|
|
80
|
+
}
|
|
81
|
+
// Default sort by volume
|
|
82
|
+
queryParams.sort = 'volume';
|
|
83
|
+
queryParams.ascending = false;
|
|
84
|
+
const response = await axios_1.default.get(`${utils_1.BASE_URL}${utils_1.EVENTS_PATH}`, {
|
|
85
|
+
params: queryParams,
|
|
86
|
+
});
|
|
87
|
+
const events = response.data?.events || [];
|
|
88
|
+
const result = events
|
|
89
|
+
.map((event) => (0, utils_1.mapEventToUnified)(event))
|
|
90
|
+
.filter((e) => e !== null);
|
|
91
|
+
const allMarkets = result.flatMap((e) => e.markets);
|
|
92
|
+
await (0, utils_1.enrichMarketsWithPrices)(allMarkets);
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
async function searchEvents(params) {
|
|
96
|
+
const limit = params.limit || 20;
|
|
97
|
+
const page = params.offset ? Math.floor(params.offset / limit) + 1 : 1;
|
|
98
|
+
const response = await axios_1.default.get(`${utils_1.BASE_URL}${utils_1.SEARCH_PATH}`, {
|
|
99
|
+
params: {
|
|
100
|
+
q: params.query,
|
|
101
|
+
page,
|
|
102
|
+
limit,
|
|
103
|
+
events_status: mapStatus(params.status),
|
|
104
|
+
keep_closed_markets: params.status === 'all' || params.status === 'inactive' || params.status === 'closed' ? 1 : 0,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
const events = response.data?.events || [];
|
|
108
|
+
const result = events
|
|
109
|
+
.map((event) => (0, utils_1.mapEventToUnified)(event))
|
|
110
|
+
.filter((e) => e !== null);
|
|
111
|
+
const allMarkets = result.flatMap((e) => e.markets);
|
|
112
|
+
await (0, utils_1.enrichMarketsWithPrices)(allMarkets);
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
function isNotFoundError(error) {
|
|
116
|
+
const status = error.response?.status;
|
|
117
|
+
if (status === 404 || status === 400)
|
|
118
|
+
return true;
|
|
119
|
+
// API returns 500 with plain-text "not found" message for missing resources
|
|
120
|
+
if (status === 500) {
|
|
121
|
+
const data = error.response?.data;
|
|
122
|
+
const msg = typeof data === 'string' ? data : (data?.detail || data?.message || '');
|
|
123
|
+
return /not found/i.test(String(msg));
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
function mapStatus(status) {
|
|
128
|
+
switch (status) {
|
|
129
|
+
case 'inactive':
|
|
130
|
+
case 'closed':
|
|
131
|
+
return 'closed';
|
|
132
|
+
case 'all':
|
|
133
|
+
return 'all';
|
|
134
|
+
case 'active':
|
|
135
|
+
default:
|
|
136
|
+
return 'active';
|
|
137
|
+
}
|
|
138
|
+
}
|