pmxt-core 2.43.20 → 2.43.24

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.
Files changed (67) hide show
  1. package/dist/exchanges/baozi/errors.d.ts +1 -1
  2. package/dist/exchanges/baozi/errors.js +1 -1
  3. package/dist/exchanges/gemini-titan/errors.d.ts +3 -3
  4. package/dist/exchanges/gemini-titan/errors.js +1 -1
  5. package/dist/exchanges/gemini-titan/index.js +1 -1
  6. package/dist/exchanges/gemini-titan/normalizer.js +2 -2
  7. package/dist/exchanges/hyperliquid/errors.d.ts +3 -3
  8. package/dist/exchanges/hyperliquid/errors.js +1 -1
  9. package/dist/exchanges/hyperliquid/index.js +1 -1
  10. package/dist/exchanges/kalshi/api.d.ts +1 -1
  11. package/dist/exchanges/kalshi/api.js +1 -1
  12. package/dist/exchanges/kalshi/auth.js +3 -0
  13. package/dist/exchanges/kalshi/errors.d.ts +2 -2
  14. package/dist/exchanges/kalshi/fetcher.d.ts +1 -0
  15. package/dist/exchanges/kalshi/index.js +1 -1
  16. package/dist/exchanges/kalshi/normalizer.d.ts +1 -1
  17. package/dist/exchanges/kalshi/normalizer.js +4 -4
  18. package/dist/exchanges/limitless/api.d.ts +1 -1
  19. package/dist/exchanges/limitless/api.js +1 -1
  20. package/dist/exchanges/limitless/auth.js +3 -0
  21. package/dist/exchanges/limitless/errors.d.ts +2 -2
  22. package/dist/exchanges/limitless/index.js +1 -1
  23. package/dist/exchanges/metaculus/cancelOrder.d.ts +1 -1
  24. package/dist/exchanges/metaculus/cancelOrder.js +3 -3
  25. package/dist/exchanges/metaculus/errors.d.ts +3 -3
  26. package/dist/exchanges/mock/index.js +32 -15
  27. package/dist/exchanges/myriad/api.d.ts +1 -1
  28. package/dist/exchanges/myriad/api.js +1 -1
  29. package/dist/exchanges/myriad/errors.d.ts +2 -2
  30. package/dist/exchanges/opinion/api.d.ts +1 -1
  31. package/dist/exchanges/opinion/api.js +1 -1
  32. package/dist/exchanges/opinion/errors.d.ts +2 -2
  33. package/dist/exchanges/opinion/errors.js +4 -3
  34. package/dist/exchanges/opinion/index.js +1 -1
  35. package/dist/exchanges/opinion/utils.d.ts +1 -1
  36. package/dist/exchanges/opinion/utils.js +2 -2
  37. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  38. package/dist/exchanges/polymarket/api-clob.js +1 -1
  39. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  40. package/dist/exchanges/polymarket/api-data.js +1 -1
  41. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  42. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  43. package/dist/exchanges/polymarket/auth.js +22 -3
  44. package/dist/exchanges/polymarket/errors.d.ts +3 -3
  45. package/dist/exchanges/polymarket/fetcher.js +3 -0
  46. package/dist/exchanges/polymarket/index.js +1 -1
  47. package/dist/exchanges/polymarket_us/normalizer.js +3 -3
  48. package/dist/exchanges/probable/api.d.ts +1 -1
  49. package/dist/exchanges/probable/api.js +1 -1
  50. package/dist/exchanges/probable/errors.d.ts +2 -2
  51. package/dist/exchanges/probable/errors.js +1 -1
  52. package/dist/exchanges/probable/index.js +2 -2
  53. package/dist/exchanges/smarkets/auth.js +6 -0
  54. package/dist/exchanges/smarkets/errors.d.ts +3 -3
  55. package/dist/exchanges/smarkets/errors.js +7 -2
  56. package/dist/feeds/binance/binance-feed.js +11 -2
  57. package/dist/feeds/chainlink/chainlink-feed.js +9 -3
  58. package/dist/router/Router.js +1 -3
  59. package/dist/router/client.d.ts +16 -8
  60. package/dist/router/client.js +7 -3
  61. package/dist/server/openapi.yaml +1 -1
  62. package/dist/subscriber/external/goldsky.d.ts +2 -1
  63. package/dist/subscriber/external/goldsky.js +33 -14
  64. package/dist/types.d.ts +1 -1
  65. package/dist/utils/error-mapper.d.ts +7 -7
  66. package/dist/utils/error-mapper.js +54 -47
  67. 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 = (proxyAddress || signerAddress);
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
- return this.credentials.funderAddress || this.signerAddress;
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: any): string;
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: any, response?: any): BaseError;
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: any): BadRequest;
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) => {
@@ -263,7 +263,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
263
263
  side: 'buy',
264
264
  type: 'limit',
265
265
  amount: 0,
266
- status: 'cancelled',
266
+ status: 'canceled',
267
267
  filled: 0,
268
268
  remaining: 0,
269
269
  timestamp: Date.now(),
@@ -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' | 'cancelled' | 'rejected'
158
- // Note: PMXT has no 'expired' status; expired orders are mapped to 'cancelled'.
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 'cancelled';
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-24T16:58:16.178Z
3
+ * Generated at: 2026-05-24T18:05:59.975Z
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-24T16:58:16.178Z
6
+ * Generated at: 2026-05-24T18:05:59.975Z
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: any): string;
6
- protected mapBadRequestError(message: string, data: any): BadRequest;
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 (error && typeof error === 'object' && error.msg) {
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: 'cancelled',
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 'cancelled';
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: any): string;
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: any): ReturnType<ErrorMapper['mapError']>;
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: any): BadRequest;
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?.error_type;
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 retryAfter = response?.headers?.['retry-after'];
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
  }
@@ -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 res = await this.client.getArbitrage(query);
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 ` +
@@ -1,14 +1,22 @@
1
- import type { FetchMatchesParams, FetchMarketMatchesParams, FetchEventMatchesParams, RouterMarketSearchParams, RouterEventSearchParams } from './types';
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<any>;
6
- getEventMatches(params: FetchEventMatchesParams): Promise<any>;
7
- browseMarketMatches(params: FetchMarketMatchesParams): Promise<any>;
8
- browseEventMatches(params: FetchEventMatchesParams): Promise<any>;
9
- searchMarkets(params?: RouterMarketSearchParams): Promise<any>;
10
- searchEvents(params?: RouterEventSearchParams): Promise<any>;
11
- getArbitrage(query?: Record<string, string>): Promise<any>;
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 {};
@@ -169,10 +169,14 @@ class PmxtApiClient {
169
169
  return new errors_1.BadRequest(message, 'Router');
170
170
  }
171
171
  }
172
- if (error?.code === 'ECONNREFUSED' || error?.code === 'ENOTFOUND' || error?.code === 'ETIMEDOUT') {
173
- return new errors_1.NetworkError(`Network error: ${error.message}`, 'Router');
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 error instanceof Error ? error : new Error(String(error));
179
+ return new Error(String(error));
176
180
  }
177
181
  }
178
182
  exports.PmxtApiClient = PmxtApiClient;
@@ -2920,7 +2920,7 @@ components:
2920
2920
  - pending
2921
2921
  - open
2922
2922
  - filled
2923
- - cancelled
2923
+ - canceled
2924
2924
  - rejected
2925
2925
  description: Lifecycle status of the order.
2926
2926
  filled:
@@ -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, any>;
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
- for (const row of [...(makerData?.orderFilledEvents ?? []), ...(takerData?.orderFilledEvents ?? [])]) {
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 filled = data?.orderFilledEvents;
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 transfers = data?.transfers;
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(() => this.query(address), this.pollMs);
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.abortControllers.get(address)?.abort();
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
- callback(data);
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?.errors) {
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?.data ?? null;
322
+ return json.data ?? null;
305
323
  }
306
324
  catch (err) {
307
- if (err?.name !== 'AbortError' && err?.name !== 'TimeoutError') {
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' | 'cancelled' | 'rejected';
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: any): BaseError;
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: any, response?: any): BaseError;
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: any): BadRequest;
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: any): NotFound;
31
+ protected mapNotFoundError(message: string, data: unknown): NotFound;
32
32
  /**
33
33
  * Maps rate limit errors
34
34
  */
35
- protected mapRateLimitError(message: string, response: any): RateLimitExceeded;
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: any): string;
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: any): string | undefined;
43
+ protected extractFromData(data: unknown): string | undefined;
44
44
  }