pmxt-core 2.23.0 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/exchanges/kalshi/api.d.ts +1 -1
  2. package/dist/exchanges/kalshi/api.js +1 -1
  3. package/dist/exchanges/limitless/api.d.ts +1 -1
  4. package/dist/exchanges/limitless/api.js +1 -1
  5. package/dist/exchanges/myriad/api.d.ts +1 -1
  6. package/dist/exchanges/myriad/api.js +1 -1
  7. package/dist/exchanges/opinion/api.d.ts +1 -1
  8. package/dist/exchanges/opinion/api.js +1 -1
  9. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  10. package/dist/exchanges/polymarket/api-clob.js +1 -1
  11. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  12. package/dist/exchanges/polymarket/api-data.js +1 -1
  13. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  14. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  15. package/dist/exchanges/polymarket/auth.js +42 -8
  16. package/dist/exchanges/polymarket/index.js +56 -19
  17. package/dist/exchanges/polymarket_us/config.d.ts +18 -0
  18. package/dist/exchanges/polymarket_us/config.js +22 -0
  19. package/dist/exchanges/polymarket_us/errors.d.ts +19 -0
  20. package/dist/exchanges/polymarket_us/errors.js +123 -0
  21. package/dist/exchanges/polymarket_us/errors.test.d.ts +1 -0
  22. package/dist/exchanges/polymarket_us/errors.test.js +54 -0
  23. package/dist/exchanges/polymarket_us/index.d.ts +90 -0
  24. package/dist/exchanges/polymarket_us/index.js +366 -0
  25. package/dist/exchanges/polymarket_us/index.test.d.ts +8 -0
  26. package/dist/exchanges/polymarket_us/index.test.js +237 -0
  27. package/dist/exchanges/polymarket_us/normalizer.d.ts +55 -0
  28. package/dist/exchanges/polymarket_us/normalizer.js +385 -0
  29. package/dist/exchanges/polymarket_us/normalizer.test.d.ts +1 -0
  30. package/dist/exchanges/polymarket_us/normalizer.test.js +224 -0
  31. package/dist/exchanges/polymarket_us/price.d.ts +94 -0
  32. package/dist/exchanges/polymarket_us/price.js +149 -0
  33. package/dist/exchanges/polymarket_us/price.test.d.ts +1 -0
  34. package/dist/exchanges/polymarket_us/price.test.js +131 -0
  35. package/dist/exchanges/polymarket_us/websocket.d.ts +39 -0
  36. package/dist/exchanges/polymarket_us/websocket.js +181 -0
  37. package/dist/exchanges/polymarket_us/websocket.test.d.ts +8 -0
  38. package/dist/exchanges/polymarket_us/websocket.test.js +162 -0
  39. package/dist/exchanges/probable/api.d.ts +1 -1
  40. package/dist/exchanges/probable/api.js +1 -1
  41. package/dist/exchanges/smarkets/api.d.ts +8067 -0
  42. package/dist/exchanges/smarkets/api.js +10698 -0
  43. package/dist/exchanges/smarkets/auth.d.ts +56 -0
  44. package/dist/exchanges/smarkets/auth.js +105 -0
  45. package/dist/exchanges/smarkets/config.d.ts +41 -0
  46. package/dist/exchanges/smarkets/config.js +47 -0
  47. package/dist/exchanges/smarkets/errors.d.ts +31 -0
  48. package/dist/exchanges/smarkets/errors.js +186 -0
  49. package/dist/exchanges/smarkets/fetcher.d.ts +177 -0
  50. package/dist/exchanges/smarkets/fetcher.js +342 -0
  51. package/dist/exchanges/smarkets/index.d.ts +54 -0
  52. package/dist/exchanges/smarkets/index.js +285 -0
  53. package/dist/exchanges/smarkets/normalizer.d.ts +18 -0
  54. package/dist/exchanges/smarkets/normalizer.js +267 -0
  55. package/dist/exchanges/smarkets/price.d.ts +26 -0
  56. package/dist/exchanges/smarkets/price.js +44 -0
  57. package/dist/exchanges/smarkets/price.test.d.ts +1 -0
  58. package/dist/exchanges/smarkets/price.test.js +50 -0
  59. package/dist/index.d.ts +8 -0
  60. package/dist/index.js +9 -1
  61. package/dist/server/app.js +18 -2
  62. package/package.json +4 -3
@@ -0,0 +1,56 @@
1
+ import { ExchangeCredentials } from '../../BaseExchange';
2
+ /**
3
+ * Manages Smarkets session-based authentication.
4
+ *
5
+ * Authentication flow:
6
+ * 1. POST /v3/sessions/ with username (email) and password to obtain a session token.
7
+ * 2. If the response `factor` is 'totp', POST /v3/sessions/verify/ with the TOTP code.
8
+ * 3. Once complete, use the token in the Authorization header as `Session-Token <token>`.
9
+ *
10
+ * This class does NOT make HTTP calls directly. The exchange index.ts handles the
11
+ * async login flow via callApi and calls `setToken()` with the result.
12
+ * `getHeaders()` returns the session token header synchronously.
13
+ */
14
+ export declare class SmarketsAuth {
15
+ private readonly credentials;
16
+ private sessionToken;
17
+ private tokenExpiry;
18
+ constructor(credentials: ExchangeCredentials);
19
+ private validateCredentials;
20
+ /**
21
+ * Returns the username (email) used for session creation.
22
+ */
23
+ getUsername(): string;
24
+ /**
25
+ * Returns the password used for session creation.
26
+ */
27
+ getPassword(): string;
28
+ /**
29
+ * Stores the session token and its expiry after a successful login.
30
+ *
31
+ * @param token The session token returned by /v3/sessions/.
32
+ * @param expiry The `stop` datetime string from the API response (ISO 8601).
33
+ */
34
+ setToken(token: string, expiry: string): void;
35
+ /**
36
+ * Returns true if the session token is present and has not expired.
37
+ */
38
+ isAuthenticated(): boolean;
39
+ /**
40
+ * Returns true if the token has expired or is about to expire.
41
+ */
42
+ isExpired(): boolean;
43
+ /**
44
+ * Generates the required headers for an authenticated request.
45
+ *
46
+ * @param _method The HTTP method (unused, kept for interface consistency with sign()).
47
+ * @param _path The request path (unused, kept for interface consistency with sign()).
48
+ * @returns An object containing the Authorization header with the session token.
49
+ * @throws Error if no valid session token is available.
50
+ */
51
+ getHeaders(_method: string, _path: string): Record<string, string>;
52
+ /**
53
+ * Clears the stored session token (e.g. after logout or for testing).
54
+ */
55
+ reset(): void;
56
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SmarketsAuth = void 0;
4
+ /** Default session TTL in milliseconds (30 minutes). */
5
+ const SESSION_TTL_MS = 30 * 60 * 1000;
6
+ /** Safety margin subtracted from TTL to avoid using an about-to-expire token. */
7
+ const EXPIRY_MARGIN_MS = 60 * 1000;
8
+ /**
9
+ * Manages Smarkets session-based authentication.
10
+ *
11
+ * Authentication flow:
12
+ * 1. POST /v3/sessions/ with username (email) and password to obtain a session token.
13
+ * 2. If the response `factor` is 'totp', POST /v3/sessions/verify/ with the TOTP code.
14
+ * 3. Once complete, use the token in the Authorization header as `Session-Token <token>`.
15
+ *
16
+ * This class does NOT make HTTP calls directly. The exchange index.ts handles the
17
+ * async login flow via callApi and calls `setToken()` with the result.
18
+ * `getHeaders()` returns the session token header synchronously.
19
+ */
20
+ class SmarketsAuth {
21
+ credentials;
22
+ sessionToken = null;
23
+ tokenExpiry = 0;
24
+ constructor(credentials) {
25
+ this.credentials = credentials;
26
+ this.validateCredentials();
27
+ }
28
+ validateCredentials() {
29
+ if (!this.credentials.apiKey) {
30
+ throw new Error('Smarkets requires an apiKey (email address) for authentication');
31
+ }
32
+ if (!this.credentials.privateKey) {
33
+ throw new Error('Smarkets requires a privateKey (account password) for authentication');
34
+ }
35
+ }
36
+ /**
37
+ * Returns the username (email) used for session creation.
38
+ */
39
+ getUsername() {
40
+ return this.credentials.apiKey;
41
+ }
42
+ /**
43
+ * Returns the password used for session creation.
44
+ */
45
+ getPassword() {
46
+ return this.credentials.privateKey;
47
+ }
48
+ /**
49
+ * Stores the session token and its expiry after a successful login.
50
+ *
51
+ * @param token The session token returned by /v3/sessions/.
52
+ * @param expiry The `stop` datetime string from the API response (ISO 8601).
53
+ */
54
+ setToken(token, expiry) {
55
+ this.sessionToken = token;
56
+ const expiryTime = new Date(expiry).getTime();
57
+ if (isNaN(expiryTime)) {
58
+ // Fall back to a 30-minute TTL from now if the expiry cannot be parsed.
59
+ this.tokenExpiry = Date.now() + SESSION_TTL_MS - EXPIRY_MARGIN_MS;
60
+ }
61
+ else {
62
+ this.tokenExpiry = expiryTime - EXPIRY_MARGIN_MS;
63
+ }
64
+ }
65
+ /**
66
+ * Returns true if the session token is present and has not expired.
67
+ */
68
+ isAuthenticated() {
69
+ return this.sessionToken !== null && Date.now() < this.tokenExpiry;
70
+ }
71
+ /**
72
+ * Returns true if the token has expired or is about to expire.
73
+ */
74
+ isExpired() {
75
+ if (this.sessionToken === null) {
76
+ return true;
77
+ }
78
+ return Date.now() >= this.tokenExpiry;
79
+ }
80
+ /**
81
+ * Generates the required headers for an authenticated request.
82
+ *
83
+ * @param _method The HTTP method (unused, kept for interface consistency with sign()).
84
+ * @param _path The request path (unused, kept for interface consistency with sign()).
85
+ * @returns An object containing the Authorization header with the session token.
86
+ * @throws Error if no valid session token is available.
87
+ */
88
+ getHeaders(_method, _path) {
89
+ if (!this.sessionToken) {
90
+ throw new Error('Smarkets session token is not set. Call the login endpoint first.');
91
+ }
92
+ return {
93
+ 'Authorization': `Session-Token ${this.sessionToken}`,
94
+ 'Content-Type': 'application/json',
95
+ };
96
+ }
97
+ /**
98
+ * Clears the stored session token (e.g. after logout or for testing).
99
+ */
100
+ reset() {
101
+ this.sessionToken = null;
102
+ this.tokenExpiry = 0;
103
+ }
104
+ }
105
+ exports.SmarketsAuth = SmarketsAuth;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Smarkets runtime configuration.
3
+ *
4
+ * This file is hand-authored and is the single source of truth for:
5
+ * - Base URL constant
6
+ * - API path constants (SMARKETS_PATHS)
7
+ * - Config interface and factory
8
+ *
9
+ * The OpenAPI spec lives in core/specs/smarkets/Smarkets.yaml and is compiled
10
+ * into core/src/exchanges/smarkets/api.ts by `npm run fetch:openapi`.
11
+ * Do NOT put runtime config into api.ts -- it will be overwritten.
12
+ */
13
+ export declare const SMARKETS_BASE_URL = "https://api.smarkets.com";
14
+ export declare const SMARKETS_PATHS: {
15
+ SESSIONS: string;
16
+ SESSIONS_VERIFY: string;
17
+ ACCOUNTS: string;
18
+ ACCOUNTS_ACTIVITY: string;
19
+ ACCOUNT_ACTIVITY_CSV: string;
20
+ CURRENCIES: string;
21
+ EVENTS: string;
22
+ EVENTS_COMPETITORS: string;
23
+ EVENTS_MARKETS: string;
24
+ EVENTS_MARKETS_COUNT: string;
25
+ EVENTS_STATES: string;
26
+ MARKETS_CONTRACTS: string;
27
+ MARKETS_LAST_EXECUTED_PRICES: string;
28
+ MARKETS_QUOTES: string;
29
+ MARKETS_VOLUMES: string;
30
+ ORDERS: string;
31
+ ORDERS_FULLCOVER: string;
32
+ ORDERS_BY_ID: string;
33
+ };
34
+ export interface SmarketsApiConfig {
35
+ /** Base REST API URL */
36
+ apiUrl: string;
37
+ }
38
+ /**
39
+ * Return a typed config object for the Smarkets API.
40
+ */
41
+ export declare function getSmarketsConfig(): SmarketsApiConfig;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * Smarkets runtime configuration.
4
+ *
5
+ * This file is hand-authored and is the single source of truth for:
6
+ * - Base URL constant
7
+ * - API path constants (SMARKETS_PATHS)
8
+ * - Config interface and factory
9
+ *
10
+ * The OpenAPI spec lives in core/specs/smarkets/Smarkets.yaml and is compiled
11
+ * into core/src/exchanges/smarkets/api.ts by `npm run fetch:openapi`.
12
+ * Do NOT put runtime config into api.ts -- it will be overwritten.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SMARKETS_PATHS = exports.SMARKETS_BASE_URL = void 0;
16
+ exports.getSmarketsConfig = getSmarketsConfig;
17
+ // -- Base URL constant --------------------------------------------------------
18
+ exports.SMARKETS_BASE_URL = "https://api.smarkets.com";
19
+ // -- Path constants -----------------------------------------------------------
20
+ exports.SMARKETS_PATHS = {
21
+ SESSIONS: "/v3/sessions/",
22
+ SESSIONS_VERIFY: "/v3/sessions/verify/",
23
+ ACCOUNTS: "/v3/accounts/",
24
+ ACCOUNTS_ACTIVITY: "/v3/accounts/activity/",
25
+ ACCOUNT_ACTIVITY_CSV: "/v3/account_activity_csv/{start_datetime}/{end_datetime}/",
26
+ CURRENCIES: "/v3/currencies/{code}/",
27
+ EVENTS: "/v3/events/",
28
+ EVENTS_COMPETITORS: "/v3/events/{event_ids}/competitors/",
29
+ EVENTS_MARKETS: "/v3/events/{event_ids}/markets/",
30
+ EVENTS_MARKETS_COUNT: "/v3/events/{event_ids}/markets_count/",
31
+ EVENTS_STATES: "/v3/events/{event_ids}/states/",
32
+ MARKETS_CONTRACTS: "/v3/markets/{market_ids}/contracts/",
33
+ MARKETS_LAST_EXECUTED_PRICES: "/v3/markets/{market_ids}/last_executed_prices/",
34
+ MARKETS_QUOTES: "/v3/markets/{market_ids}/quotes/",
35
+ MARKETS_VOLUMES: "/v3/markets/{market_ids}/volumes/",
36
+ ORDERS: "/v3/orders/",
37
+ ORDERS_FULLCOVER: "/v3/orders/fullcover/",
38
+ ORDERS_BY_ID: "/v3/orders/{order_id}/",
39
+ };
40
+ /**
41
+ * Return a typed config object for the Smarkets API.
42
+ */
43
+ function getSmarketsConfig() {
44
+ return {
45
+ apiUrl: exports.SMARKETS_BASE_URL,
46
+ };
47
+ }
@@ -0,0 +1,31 @@
1
+ import { ErrorMapper } from '../../utils/error-mapper';
2
+ import { BadRequest } from '../../errors';
3
+ /**
4
+ * Smarkets-specific error mapper
5
+ *
6
+ * Handles Smarkets API error patterns where errors use an error_type
7
+ * field to identify the error category.
8
+ */
9
+ export declare class SmarketsErrorMapper extends ErrorMapper {
10
+ constructor();
11
+ /**
12
+ * Override to handle the Smarkets { error_type, data } format
13
+ */
14
+ protected extractErrorMessage(error: any): string;
15
+ /**
16
+ * Override to map Smarkets error_type values before falling back
17
+ * to the default status-code-based mapping
18
+ */
19
+ mapError(error: any): ReturnType<ErrorMapper['mapError']>;
20
+ /**
21
+ * Override to detect order-specific errors within 400 responses
22
+ */
23
+ protected mapBadRequestError(message: string, data: any): BadRequest;
24
+ /**
25
+ * Maps a Smarkets error_type string to a PMXT error class.
26
+ * Returns undefined if the error_type is not recognized, allowing
27
+ * the base class to handle it via HTTP status code.
28
+ */
29
+ private mapByErrorType;
30
+ }
31
+ export declare const smarketsErrorMapper: SmarketsErrorMapper;
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.smarketsErrorMapper = exports.SmarketsErrorMapper = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const error_mapper_1 = require("../../utils/error-mapper");
9
+ const errors_1 = require("../../errors");
10
+ /**
11
+ * Maps Smarkets error_type values to PMXT error classes.
12
+ *
13
+ * Smarkets errors follow the format:
14
+ * { "error_type": "ERROR_CODE", "data": "message or object" }
15
+ */
16
+ const AUTHENTICATION_ERRORS = new Set([
17
+ 'INVALID_CREDENTIALS',
18
+ 'PASSWORD_RESET_NEEDED',
19
+ 'AUTH_REQUIRED',
20
+ ]);
21
+ const RATE_LIMIT_ERRORS = new Set([
22
+ 'RATE_LIMIT_EXCEEDED',
23
+ 'EVENTS_API_RATE_LIMIT',
24
+ ]);
25
+ const PERMISSION_DENIED_ERRORS = new Set([
26
+ 'USER_EXCLUDED',
27
+ 'USER_SUSPENDED',
28
+ 'SOURCE_BLOCKED',
29
+ 'IP_NOT_TRUSTED',
30
+ 'CLIENT_JURISDICTION_MISMATCH',
31
+ 'COUNTRY_BLOCKED',
32
+ 'FORBIDDEN',
33
+ 'ACCOUNT_UNVERIFIED',
34
+ ]);
35
+ const INSUFFICIENT_FUNDS_ERRORS = new Set([
36
+ 'ORDER_REJECTED_INSUFFICIENT_FUNDS',
37
+ ]);
38
+ const INVALID_ORDER_ERRORS = new Set([
39
+ 'ORDER_INVALID_INVALID_PRICE',
40
+ 'ORDER_INVALID_INVALID_QUANTITY',
41
+ 'ORDER_REJECTED_CROSSED_SELF',
42
+ 'ORDER_REJECTED_LIMIT_EXCEEDED',
43
+ 'ORDER_REJECTED_STAKE_LIMIT_EXCEEDED',
44
+ 'ORDER_REJECTED_CAPACITY_REACHED',
45
+ 'ORDER_REJECTED_CONTRACT_SETTLED',
46
+ 'ORDER_REJECTED_MARKET_SETTLED',
47
+ 'ORDER_REJECTED_MARKET_NOT_OPEN',
48
+ 'ORDER_REJECTED_MARKET_HALTED',
49
+ 'ORDER_CANCELLED_MARKET_HALTED',
50
+ 'ORDER_REJECTED_TRADING_SUSPENDED',
51
+ 'ORDER_CANCELLED_TRADING_SUSPENDED',
52
+ 'ORDER_REJECTED_ACCOUNT_SUSPENDED',
53
+ 'ORDER_REJECTED_THROTTLE_EXCEEDED',
54
+ ]);
55
+ const MARKET_NOT_FOUND_ERRORS = new Set([
56
+ 'ORDER_REJECTED_MARKET_NOT_FOUND',
57
+ 'ORDER_REJECTED_CONTRACT_NOT_FOUND',
58
+ ]);
59
+ const ORDER_NOT_FOUND_ERRORS = new Set([
60
+ 'ORDER_CANCEL_REJECTED_NOT_FOUND',
61
+ ]);
62
+ const UNAVAILABLE_ERRORS = new Set([
63
+ 'INTERNAL_ERROR',
64
+ 'FOREX_SERVICE_INTERNAL_ERROR',
65
+ 'KYC_SERVICE_INTERNAL_ERROR',
66
+ 'MDS_SERVICE_UNAVAILABLE',
67
+ 'RECKONATOR_UNAVAILABLE',
68
+ 'AUTH_UNAVAILABLE',
69
+ 'ZEUS_CONNECTION_ERROR',
70
+ 'ZEUS_TIMEOUT',
71
+ 'ORDER_REJECTED_SERVICE_TEMPORARILY_UNAVAILABLE',
72
+ ]);
73
+ /**
74
+ * Smarkets-specific error mapper
75
+ *
76
+ * Handles Smarkets API error patterns where errors use an error_type
77
+ * field to identify the error category.
78
+ */
79
+ class SmarketsErrorMapper extends error_mapper_1.ErrorMapper {
80
+ constructor() {
81
+ super('Smarkets');
82
+ }
83
+ /**
84
+ * Override to handle the Smarkets { error_type, data } format
85
+ */
86
+ extractErrorMessage(error) {
87
+ if (axios_1.default.isAxiosError(error) && error.response?.data) {
88
+ const body = error.response.data;
89
+ const errorType = body.error_type;
90
+ const data = body.data;
91
+ if (errorType) {
92
+ const status = error.response.status;
93
+ const detail = typeof data === 'string'
94
+ ? data
95
+ : data != null
96
+ ? JSON.stringify(data)
97
+ : '';
98
+ return detail
99
+ ? `[${status}] ${errorType}: ${detail}`
100
+ : `[${status}] ${errorType}`;
101
+ }
102
+ }
103
+ return super.extractErrorMessage(error);
104
+ }
105
+ /**
106
+ * Override to map Smarkets error_type values before falling back
107
+ * to the default status-code-based mapping
108
+ */
109
+ mapError(error) {
110
+ if (axios_1.default.isAxiosError(error) && error.response?.data) {
111
+ const errorType = error.response.data.error_type;
112
+ if (errorType) {
113
+ const message = this.extractErrorMessage(error);
114
+ const mapped = this.mapByErrorType(errorType, message, error.response);
115
+ if (mapped) {
116
+ return mapped;
117
+ }
118
+ }
119
+ }
120
+ return super.mapError(error);
121
+ }
122
+ /**
123
+ * Override to detect order-specific errors within 400 responses
124
+ */
125
+ mapBadRequestError(message, data) {
126
+ const errorType = data?.error_type;
127
+ if (errorType) {
128
+ if (INSUFFICIENT_FUNDS_ERRORS.has(errorType)) {
129
+ return new errors_1.InsufficientFunds(message, this.exchangeName);
130
+ }
131
+ if (INVALID_ORDER_ERRORS.has(errorType)) {
132
+ return new errors_1.InvalidOrder(message, this.exchangeName);
133
+ }
134
+ if (MARKET_NOT_FOUND_ERRORS.has(errorType)) {
135
+ return new errors_1.MarketNotFound(errorType, this.exchangeName);
136
+ }
137
+ if (ORDER_NOT_FOUND_ERRORS.has(errorType)) {
138
+ return new errors_1.OrderNotFound(errorType, this.exchangeName);
139
+ }
140
+ }
141
+ return super.mapBadRequestError(message, data);
142
+ }
143
+ /**
144
+ * Maps a Smarkets error_type string to a PMXT error class.
145
+ * Returns undefined if the error_type is not recognized, allowing
146
+ * the base class to handle it via HTTP status code.
147
+ */
148
+ mapByErrorType(errorType, message, response) {
149
+ if (AUTHENTICATION_ERRORS.has(errorType)) {
150
+ return new errors_1.AuthenticationError(message, this.exchangeName);
151
+ }
152
+ if (RATE_LIMIT_ERRORS.has(errorType)) {
153
+ const retryAfter = response?.headers?.['retry-after'];
154
+ const retryAfterSeconds = retryAfter
155
+ ? parseInt(retryAfter, 10)
156
+ : undefined;
157
+ return new errors_1.RateLimitExceeded(message, retryAfterSeconds, this.exchangeName);
158
+ }
159
+ if (PERMISSION_DENIED_ERRORS.has(errorType)) {
160
+ return new errors_1.PermissionDenied(message, this.exchangeName);
161
+ }
162
+ if (INSUFFICIENT_FUNDS_ERRORS.has(errorType)) {
163
+ return new errors_1.InsufficientFunds(message, this.exchangeName);
164
+ }
165
+ if (INVALID_ORDER_ERRORS.has(errorType)) {
166
+ return new errors_1.InvalidOrder(message, this.exchangeName);
167
+ }
168
+ if (MARKET_NOT_FOUND_ERRORS.has(errorType)) {
169
+ return new errors_1.MarketNotFound(errorType, this.exchangeName);
170
+ }
171
+ if (ORDER_NOT_FOUND_ERRORS.has(errorType)) {
172
+ return new errors_1.OrderNotFound(errorType, this.exchangeName);
173
+ }
174
+ if (UNAVAILABLE_ERRORS.has(errorType)) {
175
+ return new errors_1.ExchangeNotAvailable(message, this.exchangeName);
176
+ }
177
+ // Catch-all for any *_UNAVAILABLE or *_TIMEOUT patterns not in the set
178
+ if (errorType.endsWith('_UNAVAILABLE') || errorType.endsWith('_TIMEOUT')) {
179
+ return new errors_1.ExchangeNotAvailable(message, this.exchangeName);
180
+ }
181
+ return undefined;
182
+ }
183
+ }
184
+ exports.SmarketsErrorMapper = SmarketsErrorMapper;
185
+ // Export singleton instance for convenience
186
+ exports.smarketsErrorMapper = new SmarketsErrorMapper();
@@ -0,0 +1,177 @@
1
+ import { MarketFilterParams, EventFetchParams, TradesParams } from '../../BaseExchange';
2
+ import { IExchangeFetcher, FetcherContext } from '../interfaces';
3
+ export interface SmarketsRawEvent {
4
+ id: string;
5
+ name: string;
6
+ description: string | null;
7
+ slug: string;
8
+ full_slug: string;
9
+ state: string;
10
+ type: string | {
11
+ domain: string;
12
+ scope: string;
13
+ };
14
+ parent_id: string | null;
15
+ start_datetime: string | null;
16
+ start_date: string | null;
17
+ end_date: string | null;
18
+ created: string;
19
+ modified: string;
20
+ bettable?: boolean;
21
+ hidden?: boolean;
22
+ inplay_enabled?: boolean;
23
+ short_name?: string | null;
24
+ seo_description?: string | null;
25
+ special_rules?: string | null;
26
+ chart_time_period?: string | null;
27
+ [key: string]: unknown;
28
+ }
29
+ export interface SmarketsRawMarket {
30
+ id: string;
31
+ event_id: string;
32
+ name: string;
33
+ slug: string;
34
+ state: string;
35
+ description: string | null;
36
+ bet_delay: number;
37
+ complete: boolean;
38
+ winner_count: number;
39
+ hidden: boolean;
40
+ display_type: string;
41
+ display_order: number | null;
42
+ cashout_enabled: boolean;
43
+ inplay_enabled?: boolean;
44
+ created: string;
45
+ modified: string;
46
+ market_type: {
47
+ name: string;
48
+ param?: string;
49
+ params?: Record<string, string>;
50
+ } | null;
51
+ category?: string;
52
+ categories?: string[];
53
+ info?: Record<string, unknown> | null;
54
+ [key: string]: unknown;
55
+ }
56
+ export interface SmarketsRawContract {
57
+ id: string;
58
+ market_id: string;
59
+ name: string;
60
+ slug: string;
61
+ state_or_outcome: string;
62
+ created: string;
63
+ modified: string;
64
+ outcome_timestamp: string | null;
65
+ display_order: number | null;
66
+ hidden?: boolean;
67
+ competitor_id?: number | null;
68
+ contract_type?: {
69
+ name: string;
70
+ param?: string;
71
+ } | null;
72
+ reduction_factor?: string;
73
+ info?: {
74
+ color_primary?: string;
75
+ color_secondary?: string;
76
+ primary?: boolean;
77
+ } | null;
78
+ [key: string]: unknown;
79
+ }
80
+ export interface SmarketsRawQuote {
81
+ bids: Array<{
82
+ price: number;
83
+ quantity: number;
84
+ }>;
85
+ offers: Array<{
86
+ price: number;
87
+ quantity: number;
88
+ }>;
89
+ }
90
+ export interface SmarketsRawOrder {
91
+ id: string;
92
+ market_id: string;
93
+ contract_id: string;
94
+ side: string;
95
+ state: string;
96
+ type: string;
97
+ price: number;
98
+ quantity: number;
99
+ quantity_filled: number;
100
+ quantity_unfilled: number;
101
+ created_datetime: string;
102
+ last_modified_datetime: string;
103
+ average_price_matched?: number;
104
+ label?: string | null;
105
+ [key: string]: unknown;
106
+ }
107
+ export interface SmarketsRawVolume {
108
+ market_id: string;
109
+ volume: number;
110
+ double_stake_volume: number;
111
+ }
112
+ export interface SmarketsRawLastExecutedPrice {
113
+ contract_id: string;
114
+ last_executed_price: string | null;
115
+ timestamp: string | null;
116
+ }
117
+ export interface SmarketsRawBalance {
118
+ account_id: string;
119
+ balance: string;
120
+ available_balance: string;
121
+ exposure: string;
122
+ currency: string;
123
+ bonus_balance?: string;
124
+ commission_type?: string;
125
+ signup_date?: string;
126
+ }
127
+ export interface SmarketsRawActivityRow {
128
+ amount: string | null;
129
+ commission: string | null;
130
+ contract_id: string | null;
131
+ event_id: string | null;
132
+ market_id: string | null;
133
+ order_id: string | null;
134
+ price: number | null;
135
+ quantity: number | null;
136
+ quantity_change: number | null;
137
+ side: string | null;
138
+ source: string;
139
+ timestamp: string;
140
+ seq: number;
141
+ subseq: number;
142
+ money: string | null;
143
+ money_change: string | null;
144
+ exposure: string | null;
145
+ label: string | null;
146
+ [key: string]: unknown;
147
+ }
148
+ export interface SmarketsRawEventWithMarkets {
149
+ event: SmarketsRawEvent;
150
+ markets: SmarketsRawMarket[];
151
+ contracts: SmarketsRawContract[];
152
+ volumes: SmarketsRawVolume[];
153
+ }
154
+ export declare class SmarketsFetcher implements IExchangeFetcher<SmarketsRawEventWithMarkets, SmarketsRawEventWithMarkets> {
155
+ private readonly ctx;
156
+ constructor(ctx: FetcherContext);
157
+ fetchRawMarkets(params?: MarketFilterParams): Promise<SmarketsRawEventWithMarkets[]>;
158
+ fetchRawEvents(params: EventFetchParams): Promise<SmarketsRawEventWithMarkets[]>;
159
+ fetchRawOrderBook(id: string): Promise<Record<string, SmarketsRawQuote>>;
160
+ fetchRawTradeActivity(marketId: string, _params: TradesParams): Promise<SmarketsRawActivityRow[]>;
161
+ fetchRawMyTradeActivity(params?: Record<string, any>): Promise<SmarketsRawActivityRow[]>;
162
+ fetchRawBalance(): Promise<SmarketsRawBalance>;
163
+ fetchRawOrders(queryParams?: Record<string, any>): Promise<SmarketsRawOrder[]>;
164
+ fetchRawOrderById(orderId: string): Promise<SmarketsRawOrder>;
165
+ fetchRawPositions(): Promise<SmarketsRawOrder[]>;
166
+ fetchRawClosedOrders(params?: Record<string, any>): Promise<SmarketsRawOrder[]>;
167
+ private fetchEnrichedEventById;
168
+ private fetchEnrichedEventByMarketId;
169
+ private fetchAllEnrichedEvents;
170
+ private enrichEvents;
171
+ private fetchPaginatedEvents;
172
+ private fetchMarketsByEventIds;
173
+ private fetchContractsByMarketIds;
174
+ private fetchVolumesByMarketIds;
175
+ private mapEventStatus;
176
+ private batchArray;
177
+ }