pmxtjs 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.
@@ -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[];
@@ -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;
@@ -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[];
@@ -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;
@@ -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.24",
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.24",
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.24",
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;
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
  }