pmxt-core 2.43.20 → 2.43.25
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/exchanges/baozi/errors.d.ts +1 -1
- package/dist/exchanges/baozi/errors.js +1 -1
- package/dist/exchanges/gemini-titan/errors.d.ts +3 -3
- package/dist/exchanges/gemini-titan/errors.js +1 -1
- package/dist/exchanges/gemini-titan/index.js +1 -1
- package/dist/exchanges/gemini-titan/normalizer.js +2 -2
- package/dist/exchanges/hyperliquid/errors.d.ts +3 -3
- package/dist/exchanges/hyperliquid/errors.js +1 -1
- package/dist/exchanges/hyperliquid/index.js +1 -1
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/kalshi/auth.js +3 -0
- package/dist/exchanges/kalshi/errors.d.ts +2 -2
- package/dist/exchanges/kalshi/fetcher.d.ts +1 -0
- package/dist/exchanges/kalshi/index.js +1 -1
- package/dist/exchanges/kalshi/normalizer.d.ts +1 -1
- package/dist/exchanges/kalshi/normalizer.js +4 -4
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/limitless/auth.js +3 -0
- package/dist/exchanges/limitless/errors.d.ts +2 -2
- package/dist/exchanges/limitless/index.js +1 -1
- package/dist/exchanges/metaculus/cancelOrder.d.ts +1 -1
- package/dist/exchanges/metaculus/cancelOrder.js +3 -3
- package/dist/exchanges/metaculus/errors.d.ts +3 -3
- package/dist/exchanges/mock/index.js +32 -15
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/myriad/errors.d.ts +2 -2
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/opinion/errors.d.ts +2 -2
- package/dist/exchanges/opinion/errors.js +4 -3
- package/dist/exchanges/opinion/index.js +1 -1
- package/dist/exchanges/opinion/utils.d.ts +1 -1
- package/dist/exchanges/opinion/utils.js +2 -2
- 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 +22 -3
- package/dist/exchanges/polymarket/errors.d.ts +3 -3
- package/dist/exchanges/polymarket/fetcher.js +3 -0
- package/dist/exchanges/polymarket/index.js +1 -1
- package/dist/exchanges/polymarket_us/normalizer.js +3 -3
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/probable/errors.d.ts +2 -2
- package/dist/exchanges/probable/errors.js +1 -1
- package/dist/exchanges/probable/index.js +2 -2
- package/dist/exchanges/smarkets/auth.js +6 -0
- package/dist/exchanges/smarkets/errors.d.ts +3 -3
- package/dist/exchanges/smarkets/errors.js +7 -2
- package/dist/feeds/binance/binance-feed.js +11 -2
- package/dist/feeds/chainlink/chainlink-feed.js +9 -3
- package/dist/router/Router.js +1 -3
- package/dist/router/client.d.ts +16 -8
- package/dist/router/client.js +7 -3
- package/dist/server/openapi.yaml +1 -1
- package/dist/subscriber/external/goldsky.d.ts +2 -1
- package/dist/subscriber/external/goldsky.js +33 -14
- package/dist/types.d.ts +1 -1
- package/dist/utils/error-mapper.d.ts +7 -7
- package/dist/utils/error-mapper.js +54 -47
- package/package.json +3 -3
|
@@ -125,13 +125,17 @@ class PolymarketAuth {
|
|
|
125
125
|
signatureType: this.discoveredSignatureType ?? SIG_TYPE_EOA
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
+
if (!this.signerAddress) {
|
|
129
|
+
throw new Error('[polymarket] Wallet not initialized — privateKey required before discoverProxy()');
|
|
130
|
+
}
|
|
128
131
|
const address = this.signerAddress;
|
|
129
132
|
try {
|
|
130
133
|
// Polymarket Data API / Profiles endpoint
|
|
131
134
|
// Path-based: https://data-api.polymarket.com/profiles/0x...
|
|
132
135
|
const dataApiUrl = process.env.POLYMARKET_DATA_URL || 'https://data-api.polymarket.com';
|
|
133
136
|
const response = await axios_1.default.get(`${dataApiUrl}/profiles/${address}`, {
|
|
134
|
-
headers: { 'User-Agent': 'pmxt (https://github.com/pmxt-dev/pmxt)' }
|
|
137
|
+
headers: { 'User-Agent': 'pmxt (https://github.com/pmxt-dev/pmxt)' },
|
|
138
|
+
timeout: 10_000,
|
|
135
139
|
});
|
|
136
140
|
const profile = response.data;
|
|
137
141
|
// console.log(`[PolymarketAuth] Profile for ${address}:`, JSON.stringify(profile));
|
|
@@ -142,6 +146,9 @@ class PolymarketAuth {
|
|
|
142
146
|
// If it's a proxy address but we don't know the type, 1 is a safe default for Polymarket.
|
|
143
147
|
this.discoveredSignatureType = profile.isGnosisSafe ? SIG_TYPE_GNOSIS_SAFE : SIG_TYPE_POLY_PROXY;
|
|
144
148
|
// console.log(`[PolymarketAuth] Auto-discovered proxy for ${address}: ${this.discoveredProxyAddress} (Type: ${this.discoveredSignatureType})`);
|
|
149
|
+
if (!this.discoveredProxyAddress || this.discoveredSignatureType === undefined) {
|
|
150
|
+
throw new Error('[polymarket] Proxy discovery incomplete — missing proxyAddress or signatureType');
|
|
151
|
+
}
|
|
145
152
|
return {
|
|
146
153
|
proxyAddress: this.discoveredProxyAddress,
|
|
147
154
|
signatureType: this.discoveredSignatureType
|
|
@@ -236,8 +243,11 @@ class PolymarketAuth {
|
|
|
236
243
|
// Get API credentials (L1 auth)
|
|
237
244
|
const apiCreds = await this.getApiCredentials();
|
|
238
245
|
// Final addresses
|
|
246
|
+
if (!this.signerAddress) {
|
|
247
|
+
throw new Error('[polymarket] Wallet not initialized — privateKey required before getClobClient()');
|
|
248
|
+
}
|
|
239
249
|
const signerAddress = this.signerAddress;
|
|
240
|
-
const finalProxyAddress =
|
|
250
|
+
const finalProxyAddress = proxyAddress || signerAddress;
|
|
241
251
|
const finalSignatureType = signatureType;
|
|
242
252
|
// Create L2-authenticated client
|
|
243
253
|
// console.log(`[PolymarketAuth] Initializing ClobClient | Signer: ${signerAddress} | Funder: ${finalProxyAddress} | SigType: ${finalSignatureType}`);
|
|
@@ -266,12 +276,21 @@ class PolymarketAuth {
|
|
|
266
276
|
* Synchronous getter for credentials funder address.
|
|
267
277
|
*/
|
|
268
278
|
getFunderAddress() {
|
|
269
|
-
|
|
279
|
+
if (this.credentials.funderAddress) {
|
|
280
|
+
return this.credentials.funderAddress;
|
|
281
|
+
}
|
|
282
|
+
if (!this.signerAddress) {
|
|
283
|
+
throw new Error('[polymarket] Wallet not initialized — no funderAddress or signerAddress available');
|
|
284
|
+
}
|
|
285
|
+
return this.signerAddress;
|
|
270
286
|
}
|
|
271
287
|
/**
|
|
272
288
|
* Get the signer's address.
|
|
273
289
|
*/
|
|
274
290
|
getAddress() {
|
|
291
|
+
if (!this.signerAddress) {
|
|
292
|
+
throw new Error('[polymarket] Wallet not initialized — privateKey required');
|
|
293
|
+
}
|
|
275
294
|
return this.signerAddress;
|
|
276
295
|
}
|
|
277
296
|
/**
|
|
@@ -21,14 +21,14 @@ export declare class PolymarketErrorMapper extends ErrorMapper {
|
|
|
21
21
|
* `errorMsg` path for any residual V1 responses (order submission still
|
|
22
22
|
* returns `errorMsg` in some batch flows).
|
|
23
23
|
*/
|
|
24
|
-
protected extractErrorMessage(error:
|
|
24
|
+
protected extractErrorMessage(error: unknown): string;
|
|
25
25
|
/**
|
|
26
26
|
* Override to handle V2 status code 425 (Too Early -- matching engine restarting)
|
|
27
27
|
*/
|
|
28
|
-
protected mapByStatusCode(status: number, message: string, data:
|
|
28
|
+
protected mapByStatusCode(status: number, message: string, data: unknown, response?: unknown): BaseError;
|
|
29
29
|
/**
|
|
30
30
|
* Override to detect Polymarket-specific error patterns in 400 responses
|
|
31
31
|
*/
|
|
32
|
-
protected mapBadRequestError(message: string, data:
|
|
32
|
+
protected mapBadRequestError(message: string, data: unknown): BadRequest;
|
|
33
33
|
}
|
|
34
34
|
export declare const polymarketErrorMapper: PolymarketErrorMapper;
|
|
@@ -376,6 +376,9 @@ class PolymarketFetcher {
|
|
|
376
376
|
const rawEvents = await fetchWithStatus('closed');
|
|
377
377
|
events = rawEvents.filter(filterClosed);
|
|
378
378
|
}
|
|
379
|
+
if (!params.query) {
|
|
380
|
+
throw new Error('params.query is required for event search');
|
|
381
|
+
}
|
|
379
382
|
const lowerQuery = params.query.toLowerCase();
|
|
380
383
|
const searchIn = params.searchIn || 'title';
|
|
381
384
|
return events.filter((event) => {
|
|
@@ -154,15 +154,15 @@ function intentToOutcomeId(intent, slug) {
|
|
|
154
154
|
function mapOrderType(type) {
|
|
155
155
|
return type === 'ORDER_TYPE_MARKET' ? 'market' : 'limit';
|
|
156
156
|
}
|
|
157
|
-
// PMXT Order.status values: 'pending' | 'open' | 'filled' | '
|
|
158
|
-
// Note: PMXT has no 'expired' status; expired orders are mapped to '
|
|
157
|
+
// PMXT Order.status values: 'pending' | 'open' | 'filled' | 'canceled' | 'rejected'
|
|
158
|
+
// Note: PMXT has no 'expired' status; expired orders are mapped to 'canceled'.
|
|
159
159
|
function mapOrderStatus(state) {
|
|
160
160
|
switch (state) {
|
|
161
161
|
case 'ORDER_STATE_FILLED':
|
|
162
162
|
return 'filled';
|
|
163
163
|
case 'ORDER_STATE_CANCELED':
|
|
164
164
|
case 'ORDER_STATE_EXPIRED':
|
|
165
|
-
return '
|
|
165
|
+
return 'canceled';
|
|
166
166
|
case 'ORDER_STATE_REJECTED':
|
|
167
167
|
return 'rejected';
|
|
168
168
|
case 'ORDER_STATE_NEW':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
3
|
-
* Generated at: 2026-05-
|
|
3
|
+
* Generated at: 2026-05-24T18:32:06.496Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const probableApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.probableApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
6
|
-
* Generated at: 2026-05-
|
|
6
|
+
* Generated at: 2026-05-24T18:32:06.496Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.probableApiSpec = {
|
|
@@ -2,7 +2,7 @@ import { ErrorMapper } from '../../utils/error-mapper';
|
|
|
2
2
|
import { BadRequest } from '../../errors';
|
|
3
3
|
export declare class ProbableErrorMapper extends ErrorMapper {
|
|
4
4
|
constructor();
|
|
5
|
-
protected extractErrorMessage(error:
|
|
6
|
-
protected mapBadRequestError(message: string, data:
|
|
5
|
+
protected extractErrorMessage(error: unknown): string;
|
|
6
|
+
protected mapBadRequestError(message: string, data: unknown): BadRequest;
|
|
7
7
|
}
|
|
8
8
|
export declare const probableErrorMapper: ProbableErrorMapper;
|
|
@@ -25,7 +25,7 @@ class ProbableErrorMapper extends error_mapper_1.ErrorMapper {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
// Handle @prob/clob SDK error objects
|
|
28
|
-
if (
|
|
28
|
+
if (typeof error === 'object' && error !== null && 'msg' in error) {
|
|
29
29
|
return String(error.msg);
|
|
30
30
|
}
|
|
31
31
|
return super.extractErrorMessage(error);
|
|
@@ -229,7 +229,7 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
229
229
|
side: 'buy',
|
|
230
230
|
type: 'limit',
|
|
231
231
|
amount: 0,
|
|
232
|
-
status: '
|
|
232
|
+
status: 'canceled',
|
|
233
233
|
filled: 0,
|
|
234
234
|
remaining: 0,
|
|
235
235
|
timestamp: Date.now(),
|
|
@@ -402,7 +402,7 @@ function mapOrderStatus(status) {
|
|
|
402
402
|
if (lower === 'filled' || lower === 'trade')
|
|
403
403
|
return 'filled';
|
|
404
404
|
if (lower === 'canceled' || lower === 'cancelled' || lower === 'expired')
|
|
405
|
-
return '
|
|
405
|
+
return 'canceled';
|
|
406
406
|
if (lower === 'rejected')
|
|
407
407
|
return 'rejected';
|
|
408
408
|
return 'open';
|
|
@@ -37,12 +37,18 @@ class SmarketsAuth {
|
|
|
37
37
|
* Returns the username (email) used for session creation.
|
|
38
38
|
*/
|
|
39
39
|
getUsername() {
|
|
40
|
+
if (!this.credentials.apiKey) {
|
|
41
|
+
throw new Error('[smarkets] apiKey (username) is required');
|
|
42
|
+
}
|
|
40
43
|
return this.credentials.apiKey;
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Returns the password used for session creation.
|
|
44
47
|
*/
|
|
45
48
|
getPassword() {
|
|
49
|
+
if (!this.credentials.privateKey) {
|
|
50
|
+
throw new Error('[smarkets] privateKey (password) is required');
|
|
51
|
+
}
|
|
46
52
|
return this.credentials.privateKey;
|
|
47
53
|
}
|
|
48
54
|
/**
|
|
@@ -11,16 +11,16 @@ export declare class SmarketsErrorMapper extends ErrorMapper {
|
|
|
11
11
|
/**
|
|
12
12
|
* Override to handle the Smarkets { error_type, data } format
|
|
13
13
|
*/
|
|
14
|
-
protected extractErrorMessage(error:
|
|
14
|
+
protected extractErrorMessage(error: unknown): string;
|
|
15
15
|
/**
|
|
16
16
|
* Override to map Smarkets error_type values before falling back
|
|
17
17
|
* to the default status-code-based mapping
|
|
18
18
|
*/
|
|
19
|
-
mapError(error:
|
|
19
|
+
mapError(error: unknown): ReturnType<ErrorMapper['mapError']>;
|
|
20
20
|
/**
|
|
21
21
|
* Override to detect order-specific errors within 400 responses
|
|
22
22
|
*/
|
|
23
|
-
protected mapBadRequestError(message: string, data:
|
|
23
|
+
protected mapBadRequestError(message: string, data: unknown): BadRequest;
|
|
24
24
|
/**
|
|
25
25
|
* Maps a Smarkets error_type string to a PMXT error class.
|
|
26
26
|
* Returns undefined if the error_type is not recognized, allowing
|
|
@@ -123,7 +123,9 @@ class SmarketsErrorMapper extends error_mapper_1.ErrorMapper {
|
|
|
123
123
|
* Override to detect order-specific errors within 400 responses
|
|
124
124
|
*/
|
|
125
125
|
mapBadRequestError(message, data) {
|
|
126
|
-
const errorType = data
|
|
126
|
+
const errorType = typeof data === 'object' && data !== null && 'error_type' in data
|
|
127
|
+
? String(data.error_type)
|
|
128
|
+
: undefined;
|
|
127
129
|
if (errorType) {
|
|
128
130
|
if (INSUFFICIENT_FUNDS_ERRORS.has(errorType)) {
|
|
129
131
|
return new errors_1.InsufficientFunds(message, this.exchangeName);
|
|
@@ -150,7 +152,10 @@ class SmarketsErrorMapper extends error_mapper_1.ErrorMapper {
|
|
|
150
152
|
return new errors_1.AuthenticationError(message, this.exchangeName);
|
|
151
153
|
}
|
|
152
154
|
if (RATE_LIMIT_ERRORS.has(errorType)) {
|
|
153
|
-
const
|
|
155
|
+
const headers = (typeof response === 'object' && response !== null && 'headers' in response
|
|
156
|
+
? response.headers
|
|
157
|
+
: undefined);
|
|
158
|
+
const retryAfter = headers?.['retry-after'];
|
|
154
159
|
const retryAfterSeconds = retryAfter
|
|
155
160
|
? parseInt(retryAfter, 10)
|
|
156
161
|
: undefined;
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.BinanceFeed = void 0;
|
|
7
7
|
const ws_1 = __importDefault(require("ws"));
|
|
8
|
+
const logger_1 = require("../../utils/logger");
|
|
8
9
|
const base_feed_1 = require("../base-feed");
|
|
9
10
|
const types_1 = require("./types");
|
|
10
11
|
const normalizer_1 = require("./normalizer");
|
|
@@ -106,7 +107,11 @@ class BinanceFeed extends base_feed_1.BaseDataFeed {
|
|
|
106
107
|
watchTickerImpl(symbol, callback) {
|
|
107
108
|
const sub = { symbol, callback };
|
|
108
109
|
this.subscriptions = [...this.subscriptions, sub];
|
|
109
|
-
this.ensureConnected()
|
|
110
|
+
this.ensureConnected().catch((err) => {
|
|
111
|
+
logger_1.logger.error('[BinanceFeed] initial connect failed in watchTickerImpl', {
|
|
112
|
+
error: err instanceof Error ? err.message : String(err),
|
|
113
|
+
});
|
|
114
|
+
});
|
|
110
115
|
return () => {
|
|
111
116
|
this.subscriptions = this.subscriptions.filter((s) => s !== sub);
|
|
112
117
|
};
|
|
@@ -190,7 +195,11 @@ class BinanceFeed extends base_feed_1.BaseDataFeed {
|
|
|
190
195
|
this.reconnectTimer = setTimeout(() => {
|
|
191
196
|
this.reconnectTimer = null;
|
|
192
197
|
if (!this.isTerminated) {
|
|
193
|
-
this.connect()
|
|
198
|
+
this.connect().catch((err) => {
|
|
199
|
+
logger_1.logger.error('[BinanceFeed] reconnect failed', {
|
|
200
|
+
error: err instanceof Error ? err.message : String(err),
|
|
201
|
+
});
|
|
202
|
+
});
|
|
194
203
|
}
|
|
195
204
|
}, this.reconnectIntervalMs);
|
|
196
205
|
}
|
|
@@ -7,6 +7,7 @@ exports.ChainlinkFeed = void 0;
|
|
|
7
7
|
const ws_1 = __importDefault(require("ws"));
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
9
|
const base_feed_1 = require("../base-feed");
|
|
10
|
+
const logger_1 = require("../../utils/logger");
|
|
10
11
|
const types_1 = require("./types");
|
|
11
12
|
const normalizer_1 = require("./normalizer");
|
|
12
13
|
class ChainlinkFeed extends base_feed_1.BaseDataFeed {
|
|
@@ -123,7 +124,9 @@ class ChainlinkFeed extends base_feed_1.BaseDataFeed {
|
|
|
123
124
|
watchTickerImpl(symbol, callback) {
|
|
124
125
|
const sub = { symbol: symbol.toUpperCase(), callback };
|
|
125
126
|
this.subscriptions = [...this.subscriptions, sub];
|
|
126
|
-
this.ensureConnected()
|
|
127
|
+
this.ensureConnected().catch((err) => {
|
|
128
|
+
logger_1.logger.error('[ChainlinkFeed] initial connect failed in watchTickerImpl', { error: err instanceof Error ? err.message : String(err) });
|
|
129
|
+
});
|
|
127
130
|
return () => {
|
|
128
131
|
this.subscriptions = this.subscriptions.filter((s) => s !== sub);
|
|
129
132
|
};
|
|
@@ -242,8 +245,11 @@ class ChainlinkFeed extends base_feed_1.BaseDataFeed {
|
|
|
242
245
|
return;
|
|
243
246
|
this.reconnectTimer = setTimeout(() => {
|
|
244
247
|
this.reconnectTimer = null;
|
|
245
|
-
if (!this.isTerminated)
|
|
246
|
-
this.connect()
|
|
248
|
+
if (!this.isTerminated) {
|
|
249
|
+
this.connect().catch((err) => {
|
|
250
|
+
logger_1.logger.error('[ChainlinkFeed] reconnect failed', { error: err instanceof Error ? err.message : String(err) });
|
|
251
|
+
});
|
|
252
|
+
}
|
|
247
253
|
}, this.reconnectIntervalMs);
|
|
248
254
|
}
|
|
249
255
|
}
|
package/dist/router/Router.js
CHANGED
|
@@ -308,9 +308,7 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
|
|
|
308
308
|
query.category = params.category;
|
|
309
309
|
if (params?.limit !== undefined)
|
|
310
310
|
query.limit = String(params.limit);
|
|
311
|
-
const
|
|
312
|
-
// getArbitrage already unwraps .data — res is the opportunities array.
|
|
313
|
-
const items = Array.isArray(res) ? res : (res?.data ?? []);
|
|
311
|
+
const items = await this.client.getArbitrage(query);
|
|
314
312
|
return items.map((r) => {
|
|
315
313
|
if (r.spread == null || r.buyPrice == null || r.sellPrice == null) {
|
|
316
314
|
throw new Error(`fetchArbitrageBulk: arbitrage record is missing required price fields ` +
|
package/dist/router/client.d.ts
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UnifiedMarket, UnifiedEvent } from '../types';
|
|
2
|
+
import type { FetchMatchesParams, FetchMarketMatchesParams, FetchEventMatchesParams, MatchResult, EventMatchResult, ArbitrageOpportunity, RouterMarketSearchParams, RouterEventSearchParams } from './types';
|
|
3
|
+
interface MarketMatchesResponse {
|
|
4
|
+
matches: MatchResult[];
|
|
5
|
+
}
|
|
6
|
+
interface EventMatchesResponse {
|
|
7
|
+
matches: EventMatchResult[];
|
|
8
|
+
}
|
|
2
9
|
export declare class PmxtApiClient {
|
|
3
10
|
private readonly http;
|
|
4
11
|
constructor(apiKey: string, baseUrl?: string);
|
|
5
|
-
getMarketMatches(params: FetchMatchesParams): Promise<
|
|
6
|
-
getEventMatches(params: FetchEventMatchesParams): Promise<
|
|
7
|
-
browseMarketMatches(params: FetchMarketMatchesParams): Promise<
|
|
8
|
-
browseEventMatches(params: FetchEventMatchesParams): Promise<
|
|
9
|
-
searchMarkets(params?: RouterMarketSearchParams): Promise<
|
|
10
|
-
searchEvents(params?: RouterEventSearchParams): Promise<
|
|
11
|
-
getArbitrage(query?: Record<string, string>): Promise<
|
|
12
|
+
getMarketMatches(params: FetchMatchesParams): Promise<MarketMatchesResponse>;
|
|
13
|
+
getEventMatches(params: FetchEventMatchesParams): Promise<EventMatchesResponse>;
|
|
14
|
+
browseMarketMatches(params: FetchMarketMatchesParams): Promise<MatchResult[]>;
|
|
15
|
+
browseEventMatches(params: FetchEventMatchesParams): Promise<EventMatchResult[]>;
|
|
16
|
+
searchMarkets(params?: RouterMarketSearchParams): Promise<UnifiedMarket[]>;
|
|
17
|
+
searchEvents(params?: RouterEventSearchParams): Promise<UnifiedEvent[]>;
|
|
18
|
+
getArbitrage(query?: Record<string, string>): Promise<ArbitrageOpportunity[]>;
|
|
12
19
|
private request;
|
|
13
20
|
private mapError;
|
|
14
21
|
}
|
|
22
|
+
export {};
|
package/dist/router/client.js
CHANGED
|
@@ -169,10 +169,14 @@ class PmxtApiClient {
|
|
|
169
169
|
return new errors_1.BadRequest(message, 'Router');
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
-
if (error
|
|
173
|
-
|
|
172
|
+
if (error instanceof Error) {
|
|
173
|
+
const code = error.code;
|
|
174
|
+
if (code === 'ECONNREFUSED' || code === 'ENOTFOUND' || code === 'ETIMEDOUT') {
|
|
175
|
+
return new errors_1.NetworkError(`Network error: ${error.message}`, 'Router');
|
|
176
|
+
}
|
|
177
|
+
return error;
|
|
174
178
|
}
|
|
175
|
-
return
|
|
179
|
+
return new Error(String(error));
|
|
176
180
|
}
|
|
177
181
|
}
|
|
178
182
|
exports.PmxtApiClient = PmxtApiClient;
|
package/dist/server/openapi.yaml
CHANGED
|
@@ -5,7 +5,7 @@ import { BaseSubscriber, SubscribedActivityBuilder, SubscriberConfig, Subscripti
|
|
|
5
5
|
export interface GoldSkyGraphQlQuery {
|
|
6
6
|
url: string;
|
|
7
7
|
query: string;
|
|
8
|
-
variables?: Record<string,
|
|
8
|
+
variables?: Record<string, string | number | boolean>;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Executes a single GraphQL query and returns the `data` object, or `null` on
|
|
@@ -76,6 +76,7 @@ export declare class GoldSkySubscriber implements BaseSubscriber {
|
|
|
76
76
|
private pollTimers;
|
|
77
77
|
private callbacks;
|
|
78
78
|
private addressQueryTypes;
|
|
79
|
+
private querying;
|
|
79
80
|
private closed;
|
|
80
81
|
constructor(config: GoldSkyConfig);
|
|
81
82
|
subscribe(address: string, types: SubscriptionOption[], onEvent: (data: unknown) => void): Promise<void>;
|
|
@@ -78,7 +78,9 @@ const POLYMARKET_DEFAULT_SUBSCRIPTION = async (address, types, goldSkyFetch, bas
|
|
|
78
78
|
]);
|
|
79
79
|
const seen = new Set();
|
|
80
80
|
const trades = [];
|
|
81
|
-
|
|
81
|
+
const makerEvents = (makerData?.orderFilledEvents ?? []);
|
|
82
|
+
const takerEvents = (takerData?.orderFilledEvents ?? []);
|
|
83
|
+
for (const row of [...makerEvents, ...takerEvents]) {
|
|
82
84
|
if (!seen.has(row.id)) {
|
|
83
85
|
seen.add(row.id);
|
|
84
86
|
trades.push(row);
|
|
@@ -128,7 +130,8 @@ exports.LIMITLESS_DEFAULT_SUBSCRIPTION = LIMITLESS_DEFAULT_SUBSCRIPTION;
|
|
|
128
130
|
const buildPolymarketTradesActivity = (data, address, types) => {
|
|
129
131
|
if (!types.includes('trades'))
|
|
130
132
|
return null;
|
|
131
|
-
const
|
|
133
|
+
const record = data;
|
|
134
|
+
const filled = record?.orderFilledEvents;
|
|
132
135
|
if (!Array.isArray(filled) || filled.length === 0)
|
|
133
136
|
return null;
|
|
134
137
|
const addr = address.toLowerCase();
|
|
@@ -189,7 +192,8 @@ exports.buildPolymarketActivity = buildPolymarketActivity;
|
|
|
189
192
|
const buildLimitlessBalanceActivity = (data, address, types, lastActivity) => {
|
|
190
193
|
if (!types.includes('balances'))
|
|
191
194
|
return null;
|
|
192
|
-
const
|
|
195
|
+
const record = data;
|
|
196
|
+
const transfers = record?.transfers;
|
|
193
197
|
if (!Array.isArray(transfers) || transfers.length === 0)
|
|
194
198
|
return null;
|
|
195
199
|
const prev = lastActivity?.balances?.find(b => b.currency === 'USDC');
|
|
@@ -226,6 +230,7 @@ class GoldSkySubscriber {
|
|
|
226
230
|
pollTimers = new Map();
|
|
227
231
|
callbacks = new Map();
|
|
228
232
|
addressQueryTypes = new Map();
|
|
233
|
+
querying = new Set();
|
|
229
234
|
closed = false;
|
|
230
235
|
constructor(config) {
|
|
231
236
|
this.config = config;
|
|
@@ -241,7 +246,11 @@ class GoldSkySubscriber {
|
|
|
241
246
|
clearInterval(existing);
|
|
242
247
|
this.pollTimers.delete(address);
|
|
243
248
|
}
|
|
244
|
-
const timer = setInterval(() =>
|
|
249
|
+
const timer = setInterval(() => {
|
|
250
|
+
this.query(address).catch((err) => {
|
|
251
|
+
logger_1.logger.error(`GoldSkySubscriber: query failed for ${address}`, { error: String(err) });
|
|
252
|
+
});
|
|
253
|
+
}, this.pollMs);
|
|
245
254
|
this.pollTimers.set(address, timer);
|
|
246
255
|
}
|
|
247
256
|
unsubscribe(address) {
|
|
@@ -254,6 +263,7 @@ class GoldSkySubscriber {
|
|
|
254
263
|
this.abortControllers.delete(address);
|
|
255
264
|
this.callbacks.delete(address);
|
|
256
265
|
this.addressQueryTypes.delete(address);
|
|
266
|
+
this.querying.delete(address);
|
|
257
267
|
}
|
|
258
268
|
close() {
|
|
259
269
|
this.closed = true;
|
|
@@ -266,14 +276,22 @@ class GoldSkySubscriber {
|
|
|
266
276
|
const types = this.addressQueryTypes.get(address);
|
|
267
277
|
if (!callback || !types)
|
|
268
278
|
return;
|
|
269
|
-
this.
|
|
270
|
-
const controller = new AbortController();
|
|
271
|
-
this.abortControllers.set(address, controller);
|
|
272
|
-
const goldSkyFetch = (q) => this.runQuery(q, controller.signal);
|
|
273
|
-
const data = await this.config.buildSubscription(address, types, goldSkyFetch, this.config.baseUrl);
|
|
274
|
-
if (!data)
|
|
279
|
+
if (this.querying.has(address))
|
|
275
280
|
return;
|
|
276
|
-
|
|
281
|
+
this.querying.add(address);
|
|
282
|
+
try {
|
|
283
|
+
this.abortControllers.get(address)?.abort();
|
|
284
|
+
const controller = new AbortController();
|
|
285
|
+
this.abortControllers.set(address, controller);
|
|
286
|
+
const goldSkyFetch = (q) => this.runQuery(q, controller.signal);
|
|
287
|
+
const data = await this.config.buildSubscription(address, types, goldSkyFetch, this.config.baseUrl);
|
|
288
|
+
if (!data)
|
|
289
|
+
return;
|
|
290
|
+
callback(data);
|
|
291
|
+
}
|
|
292
|
+
finally {
|
|
293
|
+
this.querying.delete(address);
|
|
294
|
+
}
|
|
277
295
|
}
|
|
278
296
|
async runQuery(q, signal) {
|
|
279
297
|
const headers = { 'Content-Type': 'application/json' };
|
|
@@ -297,14 +315,15 @@ class GoldSkySubscriber {
|
|
|
297
315
|
return null;
|
|
298
316
|
}
|
|
299
317
|
const json = await res.json();
|
|
300
|
-
if (json
|
|
318
|
+
if (json.errors) {
|
|
301
319
|
logger_1.logger.warn(`GoldSkySubscriber: GraphQL errors from ${q.url}`, { errors: JSON.stringify(json.errors) });
|
|
302
320
|
return null;
|
|
303
321
|
}
|
|
304
|
-
return json
|
|
322
|
+
return json.data ?? null;
|
|
305
323
|
}
|
|
306
324
|
catch (err) {
|
|
307
|
-
|
|
325
|
+
const name = err instanceof Error ? err.name : undefined;
|
|
326
|
+
if (name !== 'AbortError' && name !== 'TimeoutError') {
|
|
308
327
|
logger_1.logger.warn(`GoldSkySubscriber: Fetch failed for ${q.url}`, { error: String(err) });
|
|
309
328
|
}
|
|
310
329
|
return null;
|
package/dist/types.d.ts
CHANGED
|
@@ -160,7 +160,7 @@ export interface Order {
|
|
|
160
160
|
price?: number;
|
|
161
161
|
amount: number;
|
|
162
162
|
/** Lifecycle status of the order. */
|
|
163
|
-
status: 'pending' | 'open' | 'filled' | '
|
|
163
|
+
status: 'pending' | 'open' | 'filled' | 'canceled' | 'rejected';
|
|
164
164
|
filled: number;
|
|
165
165
|
/** Amount filled in shares/contracts (if different from USDC-denominated `filled`). */
|
|
166
166
|
filledShares?: number;
|
|
@@ -12,7 +12,7 @@ export declare class ErrorMapper {
|
|
|
12
12
|
/**
|
|
13
13
|
* Main entry point for error mapping
|
|
14
14
|
*/
|
|
15
|
-
mapError(error:
|
|
15
|
+
mapError(error: unknown): BaseError;
|
|
16
16
|
/**
|
|
17
17
|
* Maps axios HTTP errors to appropriate error classes
|
|
18
18
|
*/
|
|
@@ -20,25 +20,25 @@ export declare class ErrorMapper {
|
|
|
20
20
|
/**
|
|
21
21
|
* Maps an HTTP status code to the appropriate error class
|
|
22
22
|
*/
|
|
23
|
-
protected mapByStatusCode(status: number, message: string, data:
|
|
23
|
+
protected mapByStatusCode(status: number, message: string, data: unknown, response?: unknown): BaseError;
|
|
24
24
|
/**
|
|
25
25
|
* Maps 400 errors to specific bad request subtypes
|
|
26
26
|
*/
|
|
27
|
-
protected mapBadRequestError(message: string, data:
|
|
27
|
+
protected mapBadRequestError(message: string, data: unknown): BadRequest;
|
|
28
28
|
/**
|
|
29
29
|
* Maps 404 errors to specific not found subtypes
|
|
30
30
|
*/
|
|
31
|
-
protected mapNotFoundError(message: string, data:
|
|
31
|
+
protected mapNotFoundError(message: string, data: unknown): NotFound;
|
|
32
32
|
/**
|
|
33
33
|
* Maps rate limit errors
|
|
34
34
|
*/
|
|
35
|
-
protected mapRateLimitError(message: string, response:
|
|
35
|
+
protected mapRateLimitError(message: string, response: unknown): RateLimitExceeded;
|
|
36
36
|
/**
|
|
37
37
|
* Extracts error message from various error formats
|
|
38
38
|
*/
|
|
39
|
-
protected extractErrorMessage(error:
|
|
39
|
+
protected extractErrorMessage(error: unknown): string;
|
|
40
40
|
/**
|
|
41
41
|
* Extracts a message string from a response data payload
|
|
42
42
|
*/
|
|
43
|
-
protected extractFromData(data:
|
|
43
|
+
protected extractFromData(data: unknown): string | undefined;
|
|
44
44
|
}
|