pmxtjs 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.
@@ -123,7 +123,7 @@ export declare const OrderStatusEnum: {
123
123
  readonly Pending: "pending";
124
124
  readonly Open: "open";
125
125
  readonly Filled: "filled";
126
- readonly Cancelled: "cancelled";
126
+ readonly Canceled: "canceled";
127
127
  readonly Rejected: "rejected";
128
128
  };
129
129
  export type OrderStatusEnum = typeof OrderStatusEnum[keyof typeof OrderStatusEnum];
@@ -32,7 +32,7 @@ export const OrderStatusEnum = {
32
32
  Pending: 'pending',
33
33
  Open: 'open',
34
34
  Filled: 'filled',
35
- Cancelled: 'cancelled',
35
+ Canceled: 'canceled',
36
36
  Rejected: 'rejected'
37
37
  };
38
38
  /**
@@ -57,7 +57,7 @@ export declare const server: {
57
57
  readonly logs: (n?: number) => string[];
58
58
  };
59
59
  declare const pmxt: {
60
- fromServerError(errorData: any): errors.PmxtError;
60
+ fromServerError(errorData: unknown): errors.PmxtError;
61
61
  PmxtError: typeof errors.PmxtError;
62
62
  BadRequest: typeof errors.BadRequest;
63
63
  AuthenticationError: typeof errors.AuthenticationError;
@@ -1 +1 @@
1
- export declare function buildArgsWithOptionalOptions(primary?: any): any[];
1
+ export declare function buildArgsWithOptionalOptions<T>(primary?: T): T[];
@@ -150,9 +150,16 @@ export declare abstract class Exchange {
150
150
  * @internal — shared transport used by every generated read method.
151
151
  */
152
152
  protected sidecarReadRequest(methodName: string, query: Record<string, unknown>, args: unknown[]): Promise<any>;
153
+ /**
154
+ * Dispatch a sidecar POST method with positional args and credentials.
155
+ *
156
+ * @internal - shared transport for hand-maintained methods that should
157
+ * never use the GET read path.
158
+ */
159
+ protected sidecarPostRequest(methodName: string, args: unknown[]): Promise<any>;
153
160
  loadMarkets(reload?: boolean): Promise<Record<string, UnifiedMarket>>;
154
161
  fetchMarkets(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
155
- fetchMarketsPaginated(params?: MarketFetchParams): Promise<PaginatedMarketsResult>;
162
+ fetchMarketsPaginated(params?: any): Promise<PaginatedMarketsResult>;
156
163
  fetchEvents(params?: EventFetchParams): Promise<UnifiedEvent[]>;
157
164
  fetchMarket(params?: MarketFetchParams): Promise<UnifiedMarket>;
158
165
  fetchEvent(params?: EventFetchParams): Promise<UnifiedEvent>;
@@ -480,6 +487,13 @@ export interface PolymarketOptions {
480
487
  }
481
488
  export declare class Polymarket extends Exchange {
482
489
  constructor(options?: PolymarketOptions);
490
+ /**
491
+ * Initialize Polymarket L2 API credentials for implicit API signing.
492
+ *
493
+ * Call this before private Polymarket implicit-API endpoints when the
494
+ * underlying CLOB credentials have not been created yet.
495
+ */
496
+ initAuth(): Promise<void>;
483
497
  }
484
498
  /**
485
499
  * Kalshi exchange client.
@@ -270,7 +270,10 @@ export class Exchange {
270
270
  let lastError;
271
271
  for (let attempt = 0; attempt <= delays.length; attempt++) {
272
272
  try {
273
- return await fetch(input, init);
273
+ return await fetch(input, {
274
+ ...init,
275
+ signal: AbortSignal.timeout(30_000),
276
+ });
274
277
  }
275
278
  catch (error) {
276
279
  lastError = error;
@@ -460,6 +463,27 @@ export class Exchange {
460
463
  }
461
464
  return response.json();
462
465
  }
466
+ /**
467
+ * Dispatch a sidecar POST method with positional args and credentials.
468
+ *
469
+ * @internal - shared transport for hand-maintained methods that should
470
+ * never use the GET read path.
471
+ */
472
+ async sidecarPostRequest(methodName, args) {
473
+ const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/${methodName}`, {
474
+ method: 'POST',
475
+ headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
476
+ body: JSON.stringify({ args, credentials: this.getCredentials() }),
477
+ });
478
+ if (!response.ok) {
479
+ const body = await response.json().catch(() => ({}));
480
+ if (body.error && typeof body.error === "object") {
481
+ throw fromServerError(body.error);
482
+ }
483
+ throw new PmxtError(body.error?.message || response.statusText);
484
+ }
485
+ return response.json();
486
+ }
463
487
  // BEGIN GENERATED METHODS
464
488
  async loadMarkets(reload = false) {
465
489
  await this.initPromise;
@@ -2216,6 +2240,24 @@ export class Polymarket extends Exchange {
2216
2240
  };
2217
2241
  super("polymarket", polyOptions);
2218
2242
  }
2243
+ /**
2244
+ * Initialize Polymarket L2 API credentials for implicit API signing.
2245
+ *
2246
+ * Call this before private Polymarket implicit-API endpoints when the
2247
+ * underlying CLOB credentials have not been created yet.
2248
+ */
2249
+ async initAuth() {
2250
+ await this.initPromise;
2251
+ try {
2252
+ const json = await this.sidecarPostRequest('initAuth', []);
2253
+ this.handleResponse(json);
2254
+ }
2255
+ catch (error) {
2256
+ if (error instanceof PmxtError)
2257
+ throw error;
2258
+ throw new PmxtError(`Failed to initAuth: ${error}`);
2259
+ }
2260
+ }
2219
2261
  }
2220
2262
  /**
2221
2263
  * Kalshi exchange client.
@@ -20,7 +20,7 @@ export declare class PermissionDenied extends PmxtError {
20
20
  constructor(message: string, exchange?: string);
21
21
  }
22
22
  export declare class NotFoundError extends PmxtError {
23
- constructor(message: string, exchange?: string);
23
+ constructor(message: string, exchange?: string, code?: string);
24
24
  }
25
25
  export declare class OrderNotFound extends NotFoundError {
26
26
  constructor(orderId: string, exchange?: string);
@@ -52,4 +52,4 @@ export declare class ExchangeNotAvailable extends PmxtError {
52
52
  constructor(message: string, exchange?: string);
53
53
  }
54
54
  /** Convert a server error response object into a typed PmxtError. */
55
- export declare function fromServerError(errorData: any): PmxtError;
55
+ export declare function fromServerError(errorData: unknown): PmxtError;
@@ -36,26 +36,23 @@ export class PermissionDenied extends PmxtError {
36
36
  }
37
37
  }
38
38
  export class NotFoundError extends PmxtError {
39
- constructor(message, exchange) {
40
- super(message, "NOT_FOUND", false, exchange);
39
+ constructor(message, exchange, code = "NOT_FOUND") {
40
+ super(message, code, false, exchange);
41
41
  }
42
42
  }
43
43
  export class OrderNotFound extends NotFoundError {
44
44
  constructor(orderId, exchange) {
45
- super(`Order not found: ${orderId}`, exchange);
46
- this.code = "ORDER_NOT_FOUND";
45
+ super(`Order not found: ${orderId}`, exchange, "ORDER_NOT_FOUND");
47
46
  }
48
47
  }
49
48
  export class MarketNotFound extends NotFoundError {
50
49
  constructor(marketId, exchange) {
51
- super(`Market not found: ${marketId}`, exchange);
52
- this.code = "MARKET_NOT_FOUND";
50
+ super(`Market not found: ${marketId}`, exchange, "MARKET_NOT_FOUND");
53
51
  }
54
52
  }
55
53
  export class EventNotFound extends NotFoundError {
56
54
  constructor(identifier, exchange) {
57
- super(`Event not found: ${identifier}`, exchange);
58
- this.code = "EVENT_NOT_FOUND";
55
+ super(`Event not found: ${identifier}`, exchange, "EVENT_NOT_FOUND");
59
56
  }
60
57
  }
61
58
  export class RateLimitExceeded extends PmxtError {
@@ -114,16 +111,19 @@ export function fromServerError(errorData) {
114
111
  if (typeof errorData === "string") {
115
112
  return new PmxtError(errorData);
116
113
  }
117
- const message = errorData.message || "Unknown error";
118
- const code = errorData.code || "UNKNOWN_ERROR";
119
- const retryable = errorData.retryable || false;
120
- const exchange = errorData.exchange;
114
+ const data = errorData;
115
+ const message = (typeof data.message === "string" ? data.message : undefined) || "Unknown error";
116
+ const code = (typeof data.code === "string" ? data.code : undefined) || "UNKNOWN_ERROR";
117
+ const retryable = typeof data.retryable === "boolean" ? data.retryable : false;
118
+ const exchange = typeof data.exchange === "string" ? data.exchange : undefined;
121
119
  const ErrorClass = ERROR_CODE_MAP[code];
122
120
  if (ErrorClass === RateLimitExceeded) {
123
- return new RateLimitExceeded(message, errorData.retryAfter, exchange);
121
+ const retryAfter = typeof data.retryAfter === "number" ? data.retryAfter : undefined;
122
+ return new RateLimitExceeded(message, retryAfter, exchange);
124
123
  }
125
124
  if (ErrorClass === ValidationError) {
126
- return new ValidationError(message, errorData.field, exchange);
125
+ const field = typeof data.field === "string" ? data.field : undefined;
126
+ return new ValidationError(message, field, exchange);
127
127
  }
128
128
  if (ErrorClass) {
129
129
  return new ErrorClass(message, exchange);
@@ -7,7 +7,7 @@
7
7
  */
8
8
  export interface Ticker {
9
9
  symbol: string;
10
- info: any;
10
+ info: Record<string, unknown>;
11
11
  timestamp: number | undefined;
12
12
  datetime: string | undefined;
13
13
  high: number | undefined;
@@ -38,7 +38,7 @@ export interface Market {
38
38
  quote: string;
39
39
  active: boolean;
40
40
  type: string;
41
- info: any;
41
+ info: Record<string, unknown>;
42
42
  }
43
43
  export interface OracleRound {
44
44
  feed: string;
@@ -34,7 +34,7 @@ export class FeedClient {
34
34
  params.symbols = symbols.join(',');
35
35
  return this.get('fetchTickers', params);
36
36
  }
37
- async fetchOHLCV(symbol, timeframe, since, limit) {
37
+ async fetchOHLCV(symbol, timeframe = '1h', since, limit) {
38
38
  return this.get('fetchOHLCV', { symbol, timeframe, since, limit });
39
39
  }
40
40
  async fetchOracleRound(feed) {
@@ -55,7 +55,10 @@ export class FeedClient {
55
55
  .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
56
56
  .join('&');
57
57
  const url = `${this.baseUrl}/api/feeds/${this.feedName}/${method}${qs ? '?' + qs : ''}`;
58
- const response = await fetch(url, { headers: this.headers });
58
+ const response = await fetch(url, {
59
+ headers: this.headers,
60
+ signal: AbortSignal.timeout(30_000),
61
+ });
59
62
  if (!response.ok) {
60
63
  const body = await response.json().catch(() => ({}));
61
64
  throw new PmxtError(body.error || response.statusText);
@@ -22,7 +22,7 @@ export interface MarketOutcome {
22
22
  /** 24-hour price change */
23
23
  priceChange24h?: number;
24
24
  /** Exchange-specific metadata */
25
- metadata?: Record<string, any>;
25
+ metadata?: Record<string, unknown>;
26
26
  /** Best bid price from the order book (when includePrices=True) */
27
27
  bestBid?: number;
28
28
  /** Best ask price from the order book (when includePrices=True) */
@@ -201,7 +201,7 @@ export interface Trade {
201
201
  side: "buy" | "sell" | "unknown";
202
202
  }
203
203
  /**
204
- * An order (open, filled, or cancelled).
204
+ * An order (open, filled, or canceled).
205
205
  */
206
206
  export interface Order {
207
207
  /** Order ID */
@@ -85,7 +85,9 @@ export class ServerManager {
85
85
  try {
86
86
  // Use native fetch to check health on the actual running port
87
87
  // This avoids issues where this.api is configured with the wrong port
88
- const response = await fetch(`http://localhost:${port}/health`);
88
+ const response = await fetch(`http://localhost:${port}/health`, {
89
+ signal: AbortSignal.timeout(5_000),
90
+ });
89
91
  if (response.ok) {
90
92
  const data = await response.json();
91
93
  return data.status === "ok";
@@ -106,7 +108,9 @@ export class ServerManager {
106
108
  const info = this.getServerInfo();
107
109
  if (info) {
108
110
  try {
109
- const response = await fetch(`http://localhost:${info.port}/health`);
111
+ const response = await fetch(`http://localhost:${info.port}/health`, {
112
+ signal: AbortSignal.timeout(5_000),
113
+ });
110
114
  if (response.ok) {
111
115
  const data = await response.json();
112
116
  if (data.status === "ok")
@@ -101,8 +101,21 @@ export class SidecarWsClient {
101
101
  const raw = typeof event.data === "string"
102
102
  ? event.data
103
103
  : event.data.toString();
104
- const msg = JSON.parse(raw);
105
- this.dispatch(msg);
104
+ let msg;
105
+ try {
106
+ msg = JSON.parse(raw);
107
+ }
108
+ catch {
109
+ // Non-JSON control frame -- ignore.
110
+ return;
111
+ }
112
+ try {
113
+ this.dispatch(msg);
114
+ }
115
+ catch (err) {
116
+ // Dispatch bug -- log and continue; don't kill the connection.
117
+ console.error('[SidecarWsClient] dispatch error:', err);
118
+ }
106
119
  };
107
120
  });
108
121
  }
@@ -123,7 +123,7 @@ export declare const OrderStatusEnum: {
123
123
  readonly Pending: "pending";
124
124
  readonly Open: "open";
125
125
  readonly Filled: "filled";
126
- readonly Cancelled: "cancelled";
126
+ readonly Canceled: "canceled";
127
127
  readonly Rejected: "rejected";
128
128
  };
129
129
  export type OrderStatusEnum = typeof OrderStatusEnum[keyof typeof OrderStatusEnum];
@@ -40,7 +40,7 @@ exports.OrderStatusEnum = {
40
40
  Pending: 'pending',
41
41
  Open: 'open',
42
42
  Filled: 'filled',
43
- Cancelled: 'cancelled',
43
+ Canceled: 'canceled',
44
44
  Rejected: 'rejected'
45
45
  };
46
46
  /**
package/dist/index.d.ts CHANGED
@@ -57,7 +57,7 @@ export declare const server: {
57
57
  readonly logs: (n?: number) => string[];
58
58
  };
59
59
  declare const pmxt: {
60
- fromServerError(errorData: any): errors.PmxtError;
60
+ fromServerError(errorData: unknown): errors.PmxtError;
61
61
  PmxtError: typeof errors.PmxtError;
62
62
  BadRequest: typeof errors.BadRequest;
63
63
  AuthenticationError: typeof errors.AuthenticationError;
@@ -1 +1 @@
1
- export declare function buildArgsWithOptionalOptions(primary?: any): any[];
1
+ export declare function buildArgsWithOptionalOptions<T>(primary?: T): T[];
@@ -150,9 +150,16 @@ export declare abstract class Exchange {
150
150
  * @internal — shared transport used by every generated read method.
151
151
  */
152
152
  protected sidecarReadRequest(methodName: string, query: Record<string, unknown>, args: unknown[]): Promise<any>;
153
+ /**
154
+ * Dispatch a sidecar POST method with positional args and credentials.
155
+ *
156
+ * @internal - shared transport for hand-maintained methods that should
157
+ * never use the GET read path.
158
+ */
159
+ protected sidecarPostRequest(methodName: string, args: unknown[]): Promise<any>;
153
160
  loadMarkets(reload?: boolean): Promise<Record<string, UnifiedMarket>>;
154
161
  fetchMarkets(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
155
- fetchMarketsPaginated(params?: MarketFetchParams): Promise<PaginatedMarketsResult>;
162
+ fetchMarketsPaginated(params?: any): Promise<PaginatedMarketsResult>;
156
163
  fetchEvents(params?: EventFetchParams): Promise<UnifiedEvent[]>;
157
164
  fetchMarket(params?: MarketFetchParams): Promise<UnifiedMarket>;
158
165
  fetchEvent(params?: EventFetchParams): Promise<UnifiedEvent>;
@@ -480,6 +487,13 @@ export interface PolymarketOptions {
480
487
  }
481
488
  export declare class Polymarket extends Exchange {
482
489
  constructor(options?: PolymarketOptions);
490
+ /**
491
+ * Initialize Polymarket L2 API credentials for implicit API signing.
492
+ *
493
+ * Call this before private Polymarket implicit-API endpoints when the
494
+ * underlying CLOB credentials have not been created yet.
495
+ */
496
+ initAuth(): Promise<void>;
483
497
  }
484
498
  /**
485
499
  * Kalshi exchange client.
@@ -273,7 +273,10 @@ class Exchange {
273
273
  let lastError;
274
274
  for (let attempt = 0; attempt <= delays.length; attempt++) {
275
275
  try {
276
- return await fetch(input, init);
276
+ return await fetch(input, {
277
+ ...init,
278
+ signal: AbortSignal.timeout(30_000),
279
+ });
277
280
  }
278
281
  catch (error) {
279
282
  lastError = error;
@@ -463,6 +466,27 @@ class Exchange {
463
466
  }
464
467
  return response.json();
465
468
  }
469
+ /**
470
+ * Dispatch a sidecar POST method with positional args and credentials.
471
+ *
472
+ * @internal - shared transport for hand-maintained methods that should
473
+ * never use the GET read path.
474
+ */
475
+ async sidecarPostRequest(methodName, args) {
476
+ const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/${methodName}`, {
477
+ method: 'POST',
478
+ headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
479
+ body: JSON.stringify({ args, credentials: this.getCredentials() }),
480
+ });
481
+ if (!response.ok) {
482
+ const body = await response.json().catch(() => ({}));
483
+ if (body.error && typeof body.error === "object") {
484
+ throw (0, errors_js_1.fromServerError)(body.error);
485
+ }
486
+ throw new errors_js_1.PmxtError(body.error?.message || response.statusText);
487
+ }
488
+ return response.json();
489
+ }
466
490
  // BEGIN GENERATED METHODS
467
491
  async loadMarkets(reload = false) {
468
492
  await this.initPromise;
@@ -2220,6 +2244,24 @@ class Polymarket extends Exchange {
2220
2244
  };
2221
2245
  super("polymarket", polyOptions);
2222
2246
  }
2247
+ /**
2248
+ * Initialize Polymarket L2 API credentials for implicit API signing.
2249
+ *
2250
+ * Call this before private Polymarket implicit-API endpoints when the
2251
+ * underlying CLOB credentials have not been created yet.
2252
+ */
2253
+ async initAuth() {
2254
+ await this.initPromise;
2255
+ try {
2256
+ const json = await this.sidecarPostRequest('initAuth', []);
2257
+ this.handleResponse(json);
2258
+ }
2259
+ catch (error) {
2260
+ if (error instanceof errors_js_1.PmxtError)
2261
+ throw error;
2262
+ throw new errors_js_1.PmxtError(`Failed to initAuth: ${error}`);
2263
+ }
2264
+ }
2223
2265
  }
2224
2266
  exports.Polymarket = Polymarket;
2225
2267
  /**
@@ -20,7 +20,7 @@ export declare class PermissionDenied extends PmxtError {
20
20
  constructor(message: string, exchange?: string);
21
21
  }
22
22
  export declare class NotFoundError extends PmxtError {
23
- constructor(message: string, exchange?: string);
23
+ constructor(message: string, exchange?: string, code?: string);
24
24
  }
25
25
  export declare class OrderNotFound extends NotFoundError {
26
26
  constructor(orderId: string, exchange?: string);
@@ -52,4 +52,4 @@ export declare class ExchangeNotAvailable extends PmxtError {
52
52
  constructor(message: string, exchange?: string);
53
53
  }
54
54
  /** Convert a server error response object into a typed PmxtError. */
55
- export declare function fromServerError(errorData: any): PmxtError;
55
+ export declare function fromServerError(errorData: unknown): PmxtError;
@@ -44,29 +44,26 @@ class PermissionDenied extends PmxtError {
44
44
  }
45
45
  exports.PermissionDenied = PermissionDenied;
46
46
  class NotFoundError extends PmxtError {
47
- constructor(message, exchange) {
48
- super(message, "NOT_FOUND", false, exchange);
47
+ constructor(message, exchange, code = "NOT_FOUND") {
48
+ super(message, code, false, exchange);
49
49
  }
50
50
  }
51
51
  exports.NotFoundError = NotFoundError;
52
52
  class OrderNotFound extends NotFoundError {
53
53
  constructor(orderId, exchange) {
54
- super(`Order not found: ${orderId}`, exchange);
55
- this.code = "ORDER_NOT_FOUND";
54
+ super(`Order not found: ${orderId}`, exchange, "ORDER_NOT_FOUND");
56
55
  }
57
56
  }
58
57
  exports.OrderNotFound = OrderNotFound;
59
58
  class MarketNotFound extends NotFoundError {
60
59
  constructor(marketId, exchange) {
61
- super(`Market not found: ${marketId}`, exchange);
62
- this.code = "MARKET_NOT_FOUND";
60
+ super(`Market not found: ${marketId}`, exchange, "MARKET_NOT_FOUND");
63
61
  }
64
62
  }
65
63
  exports.MarketNotFound = MarketNotFound;
66
64
  class EventNotFound extends NotFoundError {
67
65
  constructor(identifier, exchange) {
68
- super(`Event not found: ${identifier}`, exchange);
69
- this.code = "EVENT_NOT_FOUND";
66
+ super(`Event not found: ${identifier}`, exchange, "EVENT_NOT_FOUND");
70
67
  }
71
68
  }
72
69
  exports.EventNotFound = EventNotFound;
@@ -132,16 +129,19 @@ function fromServerError(errorData) {
132
129
  if (typeof errorData === "string") {
133
130
  return new PmxtError(errorData);
134
131
  }
135
- const message = errorData.message || "Unknown error";
136
- const code = errorData.code || "UNKNOWN_ERROR";
137
- const retryable = errorData.retryable || false;
138
- const exchange = errorData.exchange;
132
+ const data = errorData;
133
+ const message = (typeof data.message === "string" ? data.message : undefined) || "Unknown error";
134
+ const code = (typeof data.code === "string" ? data.code : undefined) || "UNKNOWN_ERROR";
135
+ const retryable = typeof data.retryable === "boolean" ? data.retryable : false;
136
+ const exchange = typeof data.exchange === "string" ? data.exchange : undefined;
139
137
  const ErrorClass = ERROR_CODE_MAP[code];
140
138
  if (ErrorClass === RateLimitExceeded) {
141
- return new RateLimitExceeded(message, errorData.retryAfter, exchange);
139
+ const retryAfter = typeof data.retryAfter === "number" ? data.retryAfter : undefined;
140
+ return new RateLimitExceeded(message, retryAfter, exchange);
142
141
  }
143
142
  if (ErrorClass === ValidationError) {
144
- return new ValidationError(message, errorData.field, exchange);
143
+ const field = typeof data.field === "string" ? data.field : undefined;
144
+ return new ValidationError(message, field, exchange);
145
145
  }
146
146
  if (ErrorClass) {
147
147
  return new ErrorClass(message, exchange);
@@ -7,7 +7,7 @@
7
7
  */
8
8
  export interface Ticker {
9
9
  symbol: string;
10
- info: any;
10
+ info: Record<string, unknown>;
11
11
  timestamp: number | undefined;
12
12
  datetime: string | undefined;
13
13
  high: number | undefined;
@@ -38,7 +38,7 @@ export interface Market {
38
38
  quote: string;
39
39
  active: boolean;
40
40
  type: string;
41
- info: any;
41
+ info: Record<string, unknown>;
42
42
  }
43
43
  export interface OracleRound {
44
44
  feed: string;
@@ -37,7 +37,7 @@ class FeedClient {
37
37
  params.symbols = symbols.join(',');
38
38
  return this.get('fetchTickers', params);
39
39
  }
40
- async fetchOHLCV(symbol, timeframe, since, limit) {
40
+ async fetchOHLCV(symbol, timeframe = '1h', since, limit) {
41
41
  return this.get('fetchOHLCV', { symbol, timeframe, since, limit });
42
42
  }
43
43
  async fetchOracleRound(feed) {
@@ -58,7 +58,10 @@ class FeedClient {
58
58
  .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
59
59
  .join('&');
60
60
  const url = `${this.baseUrl}/api/feeds/${this.feedName}/${method}${qs ? '?' + qs : ''}`;
61
- const response = await fetch(url, { headers: this.headers });
61
+ const response = await fetch(url, {
62
+ headers: this.headers,
63
+ signal: AbortSignal.timeout(30_000),
64
+ });
62
65
  if (!response.ok) {
63
66
  const body = await response.json().catch(() => ({}));
64
67
  throw new errors_js_1.PmxtError(body.error || response.statusText);
@@ -22,7 +22,7 @@ export interface MarketOutcome {
22
22
  /** 24-hour price change */
23
23
  priceChange24h?: number;
24
24
  /** Exchange-specific metadata */
25
- metadata?: Record<string, any>;
25
+ metadata?: Record<string, unknown>;
26
26
  /** Best bid price from the order book (when includePrices=True) */
27
27
  bestBid?: number;
28
28
  /** Best ask price from the order book (when includePrices=True) */
@@ -201,7 +201,7 @@ export interface Trade {
201
201
  side: "buy" | "sell" | "unknown";
202
202
  }
203
203
  /**
204
- * An order (open, filled, or cancelled).
204
+ * An order (open, filled, or canceled).
205
205
  */
206
206
  export interface Order {
207
207
  /** Order ID */
@@ -121,7 +121,9 @@ class ServerManager {
121
121
  try {
122
122
  // Use native fetch to check health on the actual running port
123
123
  // This avoids issues where this.api is configured with the wrong port
124
- const response = await fetch(`http://localhost:${port}/health`);
124
+ const response = await fetch(`http://localhost:${port}/health`, {
125
+ signal: AbortSignal.timeout(5_000),
126
+ });
125
127
  if (response.ok) {
126
128
  const data = await response.json();
127
129
  return data.status === "ok";
@@ -142,7 +144,9 @@ class ServerManager {
142
144
  const info = this.getServerInfo();
143
145
  if (info) {
144
146
  try {
145
- const response = await fetch(`http://localhost:${info.port}/health`);
147
+ const response = await fetch(`http://localhost:${info.port}/health`, {
148
+ signal: AbortSignal.timeout(5_000),
149
+ });
146
150
  if (response.ok) {
147
151
  const data = await response.json();
148
152
  if (data.status === "ok")
@@ -104,8 +104,21 @@ class SidecarWsClient {
104
104
  const raw = typeof event.data === "string"
105
105
  ? event.data
106
106
  : event.data.toString();
107
- const msg = JSON.parse(raw);
108
- this.dispatch(msg);
107
+ let msg;
108
+ try {
109
+ msg = JSON.parse(raw);
110
+ }
111
+ catch {
112
+ // Non-JSON control frame -- ignore.
113
+ return;
114
+ }
115
+ try {
116
+ this.dispatch(msg);
117
+ }
118
+ catch (err) {
119
+ // Dispatch bug -- log and continue; don't kill the connection.
120
+ console.error('[SidecarWsClient] dispatch error:', err);
121
+ }
109
122
  };
110
123
  });
111
124
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxtjs",
3
- "version": "2.43.20",
3
+ "version": "2.43.25",
4
4
  "description": "OpenAPI client for pmxtjs",
5
5
  "author": "OpenAPI-Generator",
6
6
  "repository": {
@@ -131,7 +131,7 @@ export const OrderStatusEnum = {
131
131
  Pending: 'pending',
132
132
  Open: 'open',
133
133
  Filled: 'filled',
134
- Cancelled: 'cancelled',
134
+ Canceled: 'canceled',
135
135
  Rejected: 'rejected'
136
136
  } as const;
137
137
  export type OrderStatusEnum = typeof OrderStatusEnum[keyof typeof OrderStatusEnum];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxtjs",
3
- "version": "2.43.20",
3
+ "version": "2.43.25",
4
4
  "description": "Unified prediction market data API - The ccxt for prediction markets",
5
5
  "author": "PMXT Contributors",
6
6
  "repository": {
@@ -43,7 +43,7 @@
43
43
  "unified"
44
44
  ],
45
45
  "dependencies": {
46
- "pmxt-core": "2.43.20",
46
+ "pmxt-core": "2.43.25",
47
47
  "ws": "^8.18.0"
48
48
  },
49
49
  "devDependencies": {
package/pmxt/args.ts CHANGED
@@ -1,3 +1,3 @@
1
- export function buildArgsWithOptionalOptions(primary?: any): any[] {
1
+ export function buildArgsWithOptionalOptions<T>(primary?: T): T[] {
2
2
  return primary !== undefined ? [primary] : [];
3
3
  }
package/pmxt/client.ts CHANGED
@@ -392,7 +392,10 @@ export abstract class Exchange {
392
392
 
393
393
  for (let attempt = 0; attempt <= delays.length; attempt++) {
394
394
  try {
395
- return await fetch(input, init);
395
+ return await fetch(input, {
396
+ ...init,
397
+ signal: AbortSignal.timeout(30_000),
398
+ });
396
399
  } catch (error) {
397
400
  lastError = error;
398
401
  if (attempt >= delays.length) break;
@@ -607,6 +610,28 @@ export abstract class Exchange {
607
610
  return response.json();
608
611
  }
609
612
 
613
+ /**
614
+ * Dispatch a sidecar POST method with positional args and credentials.
615
+ *
616
+ * @internal - shared transport for hand-maintained methods that should
617
+ * never use the GET read path.
618
+ */
619
+ protected async sidecarPostRequest(methodName: string, args: unknown[]): Promise<any> {
620
+ const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/${methodName}`, {
621
+ method: 'POST',
622
+ headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
623
+ body: JSON.stringify({ args, credentials: this.getCredentials() }),
624
+ });
625
+ if (!response.ok) {
626
+ const body = await response.json().catch(() => ({}));
627
+ if (body.error && typeof body.error === "object") {
628
+ throw fromServerError(body.error);
629
+ }
630
+ throw new PmxtError(body.error?.message || response.statusText);
631
+ }
632
+ return response.json();
633
+ }
634
+
610
635
  // BEGIN GENERATED METHODS
611
636
 
612
637
  async loadMarkets(reload: boolean = false): Promise<Record<string, UnifiedMarket>> {
@@ -665,7 +690,7 @@ export abstract class Exchange {
665
690
  }
666
691
  }
667
692
 
668
- async fetchMarketsPaginated(params?: MarketFetchParams): Promise<PaginatedMarketsResult> {
693
+ async fetchMarketsPaginated(params?: any): Promise<PaginatedMarketsResult> {
669
694
  await this.initPromise;
670
695
  try {
671
696
  const args: any[] = [];
@@ -2446,6 +2471,23 @@ export class Polymarket extends Exchange {
2446
2471
  };
2447
2472
  super("polymarket", polyOptions as ExchangeOptions);
2448
2473
  }
2474
+
2475
+ /**
2476
+ * Initialize Polymarket L2 API credentials for implicit API signing.
2477
+ *
2478
+ * Call this before private Polymarket implicit-API endpoints when the
2479
+ * underlying CLOB credentials have not been created yet.
2480
+ */
2481
+ async initAuth(): Promise<void> {
2482
+ await this.initPromise;
2483
+ try {
2484
+ const json = await this.sidecarPostRequest('initAuth', []);
2485
+ this.handleResponse(json);
2486
+ } catch (error) {
2487
+ if (error instanceof PmxtError) throw error;
2488
+ throw new PmxtError(`Failed to initAuth: ${error}`);
2489
+ }
2490
+ }
2449
2491
  }
2450
2492
 
2451
2493
  /**
package/pmxt/errors.ts CHANGED
@@ -49,29 +49,26 @@ export class PermissionDenied extends PmxtError {
49
49
  }
50
50
 
51
51
  export class NotFoundError extends PmxtError {
52
- constructor(message: string, exchange?: string) {
53
- super(message, "NOT_FOUND", false, exchange);
52
+ constructor(message: string, exchange?: string, code: string = "NOT_FOUND") {
53
+ super(message, code, false, exchange);
54
54
  }
55
55
  }
56
56
 
57
57
  export class OrderNotFound extends NotFoundError {
58
58
  constructor(orderId: string, exchange?: string) {
59
- super(`Order not found: ${orderId}`, exchange);
60
- (this as any).code = "ORDER_NOT_FOUND";
59
+ super(`Order not found: ${orderId}`, exchange, "ORDER_NOT_FOUND");
61
60
  }
62
61
  }
63
62
 
64
63
  export class MarketNotFound extends NotFoundError {
65
64
  constructor(marketId: string, exchange?: string) {
66
- super(`Market not found: ${marketId}`, exchange);
67
- (this as any).code = "MARKET_NOT_FOUND";
65
+ super(`Market not found: ${marketId}`, exchange, "MARKET_NOT_FOUND");
68
66
  }
69
67
  }
70
68
 
71
69
  export class EventNotFound extends NotFoundError {
72
70
  constructor(identifier: string, exchange?: string) {
73
- super(`Event not found: ${identifier}`, exchange);
74
- (this as any).code = "EVENT_NOT_FOUND";
71
+ super(`Event not found: ${identifier}`, exchange, "EVENT_NOT_FOUND");
75
72
  }
76
73
  }
77
74
 
@@ -137,23 +134,27 @@ const ERROR_CODE_MAP: Record<string, new (...args: any[]) => PmxtError> = {
137
134
  };
138
135
 
139
136
  /** Convert a server error response object into a typed PmxtError. */
140
- export function fromServerError(errorData: any): PmxtError {
137
+ export function fromServerError(errorData: unknown): PmxtError {
141
138
  if (typeof errorData === "string") {
142
139
  return new PmxtError(errorData);
143
140
  }
144
141
 
145
- const message = errorData.message || "Unknown error";
146
- const code = errorData.code || "UNKNOWN_ERROR";
147
- const retryable = errorData.retryable || false;
148
- const exchange = errorData.exchange;
142
+ const data = errorData as Record<string, unknown>;
143
+
144
+ const message = (typeof data.message === "string" ? data.message : undefined) || "Unknown error";
145
+ const code = (typeof data.code === "string" ? data.code : undefined) || "UNKNOWN_ERROR";
146
+ const retryable = typeof data.retryable === "boolean" ? data.retryable : false;
147
+ const exchange = typeof data.exchange === "string" ? data.exchange : undefined;
149
148
 
150
149
  const ErrorClass = ERROR_CODE_MAP[code];
151
150
 
152
151
  if (ErrorClass === RateLimitExceeded) {
153
- return new RateLimitExceeded(message, errorData.retryAfter, exchange);
152
+ const retryAfter = typeof data.retryAfter === "number" ? data.retryAfter : undefined;
153
+ return new RateLimitExceeded(message, retryAfter, exchange);
154
154
  }
155
155
  if (ErrorClass === ValidationError) {
156
- return new ValidationError(message, errorData.field, exchange);
156
+ const field = typeof data.field === "string" ? data.field : undefined;
157
+ return new ValidationError(message, field, exchange);
157
158
  }
158
159
  if (ErrorClass) {
159
160
  return new ErrorClass(message, exchange);
@@ -11,7 +11,7 @@ import { PmxtError } from "./errors.js";
11
11
 
12
12
  export interface Ticker {
13
13
  symbol: string;
14
- info: any;
14
+ info: Record<string, unknown>;
15
15
  timestamp: number | undefined;
16
16
  datetime: string | undefined;
17
17
  high: number | undefined;
@@ -44,7 +44,7 @@ export interface Market {
44
44
  quote: string;
45
45
  active: boolean;
46
46
  type: string;
47
- info: any;
47
+ info: Record<string, unknown>;
48
48
  }
49
49
 
50
50
  export interface OracleRound {
@@ -94,7 +94,7 @@ export class FeedClient {
94
94
  return this.get<Tickers>('fetchTickers', params);
95
95
  }
96
96
 
97
- async fetchOHLCV(symbol: string, timeframe?: string, since?: number, limit?: number): Promise<OHLCV[]> {
97
+ async fetchOHLCV(symbol: string, timeframe: string = '1h', since?: number, limit?: number): Promise<OHLCV[]> {
98
98
  return this.get<OHLCV[]>('fetchOHLCV', { symbol, timeframe, since, limit });
99
99
  }
100
100
 
@@ -125,7 +125,10 @@ export class FeedClient {
125
125
 
126
126
  const url = `${this.baseUrl}/api/feeds/${this.feedName}/${method}${qs ? '?' + qs : ''}`;
127
127
 
128
- const response = await fetch(url, { headers: this.headers });
128
+ const response = await fetch(url, {
129
+ headers: this.headers,
130
+ signal: AbortSignal.timeout(30_000),
131
+ });
129
132
 
130
133
  if (!response.ok) {
131
134
  const body = await response.json().catch(() => ({}));
package/pmxt/models.ts CHANGED
@@ -28,7 +28,7 @@ export interface MarketOutcome {
28
28
  priceChange24h?: number;
29
29
 
30
30
  /** Exchange-specific metadata */
31
- metadata?: Record<string, any>;
31
+ metadata?: Record<string, unknown>;
32
32
 
33
33
  /** Best bid price from the order book (when includePrices=True) */
34
34
  bestBid?: number;
@@ -271,7 +271,7 @@ export interface Trade {
271
271
  }
272
272
 
273
273
  /**
274
- * An order (open, filled, or cancelled).
274
+ * An order (open, filled, or canceled).
275
275
  */
276
276
  export interface Order {
277
277
  /** Order ID */
@@ -108,7 +108,9 @@ export class ServerManager {
108
108
  try {
109
109
  // Use native fetch to check health on the actual running port
110
110
  // This avoids issues where this.api is configured with the wrong port
111
- const response = await fetch(`http://localhost:${port}/health`);
111
+ const response = await fetch(`http://localhost:${port}/health`, {
112
+ signal: AbortSignal.timeout(5_000),
113
+ });
112
114
  if (response.ok) {
113
115
  const data = await response.json();
114
116
  return (data as any).status === "ok";
@@ -129,7 +131,9 @@ export class ServerManager {
129
131
  const info = this.getServerInfo();
130
132
  if (info) {
131
133
  try {
132
- const response = await fetch(`http://localhost:${info.port}/health`);
134
+ const response = await fetch(`http://localhost:${info.port}/health`, {
135
+ signal: AbortSignal.timeout(5_000),
136
+ });
133
137
  if (response.ok) {
134
138
  const data = await response.json() as any;
135
139
  if (data.status === "ok") return;
package/pmxt/ws-client.ts CHANGED
@@ -129,8 +129,19 @@ export class SidecarWsClient {
129
129
  const raw = typeof event.data === "string"
130
130
  ? event.data
131
131
  : event.data.toString();
132
- const msg: WsMessage = JSON.parse(raw);
133
- this.dispatch(msg);
132
+ let msg: WsMessage;
133
+ try {
134
+ msg = JSON.parse(raw);
135
+ } catch {
136
+ // Non-JSON control frame -- ignore.
137
+ return;
138
+ }
139
+ try {
140
+ this.dispatch(msg);
141
+ } catch (err) {
142
+ // Dispatch bug -- log and continue; don't kill the connection.
143
+ console.error('[SidecarWsClient] dispatch error:', err);
144
+ }
134
145
  };
135
146
  });
136
147
  }