pmxtjs 1.3.2 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/pmxt/client.d.ts +16 -2
- package/dist/esm/pmxt/client.js +82 -4
- package/dist/esm/pmxt/models.d.ts +31 -0
- package/dist/pmxt/client.d.ts +16 -2
- package/dist/pmxt/client.js +82 -4
- package/dist/pmxt/models.d.ts +31 -0
- package/generated/package.json +1 -1
- package/package.json +2 -2
- package/pmxt/client.ts +94 -4
- package/pmxt/models.ts +40 -0
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This module provides clean, TypeScript-friendly wrappers around the auto-generated
|
|
5
5
|
* OpenAPI client, matching the Python API exactly.
|
|
6
6
|
*/
|
|
7
|
-
import { DefaultApi, ExchangeCredentials } from "../generated/src/index.js";
|
|
8
|
-
import { UnifiedMarket, PriceCandle, OrderBook, Trade, Order, Position, Balance, MarketFilterParams, HistoryFilterParams, CreateOrderParams } from "./models.js";
|
|
7
|
+
import { DefaultApi, Configuration, ExchangeCredentials } from "../generated/src/index.js";
|
|
8
|
+
import { UnifiedMarket, PriceCandle, OrderBook, Trade, Order, Position, Balance, MarketFilterParams, HistoryFilterParams, CreateOrderParams, UnifiedEvent } from "./models.js";
|
|
9
9
|
import { ServerManager } from "./server-manager.js";
|
|
10
10
|
/**
|
|
11
11
|
* Base exchange client options.
|
|
@@ -31,6 +31,7 @@ export declare abstract class Exchange {
|
|
|
31
31
|
protected apiKey?: string;
|
|
32
32
|
protected privateKey?: string;
|
|
33
33
|
protected api: DefaultApi;
|
|
34
|
+
protected config: Configuration;
|
|
34
35
|
protected serverManager: ServerManager;
|
|
35
36
|
protected initPromise: Promise<void>;
|
|
36
37
|
constructor(exchangeName: string, options?: ExchangeOptions);
|
|
@@ -62,6 +63,19 @@ export declare abstract class Exchange {
|
|
|
62
63
|
* ```
|
|
63
64
|
*/
|
|
64
65
|
searchMarkets(query: string, params?: MarketFilterParams): Promise<UnifiedMarket[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Search events (groups of related markets) by keyword.
|
|
68
|
+
*
|
|
69
|
+
* @param query - Search query
|
|
70
|
+
* @param params - Optional filter parameters
|
|
71
|
+
* @returns List of matching events
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const events = await exchange.searchEvents("Trump");
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
searchEvents(query: string, params?: MarketFilterParams): Promise<UnifiedEvent[]>;
|
|
65
79
|
/**
|
|
66
80
|
* Fetch markets by URL slug/ticker.
|
|
67
81
|
*
|
package/dist/esm/pmxt/client.js
CHANGED
|
@@ -112,6 +112,37 @@ function convertBalance(raw) {
|
|
|
112
112
|
locked: raw.locked,
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
|
+
function convertEvent(raw) {
|
|
116
|
+
const markets = (raw.markets || []).map(convertMarket);
|
|
117
|
+
return {
|
|
118
|
+
id: raw.id,
|
|
119
|
+
title: raw.title,
|
|
120
|
+
description: raw.description,
|
|
121
|
+
slug: raw.slug,
|
|
122
|
+
markets,
|
|
123
|
+
url: raw.url,
|
|
124
|
+
image: raw.image,
|
|
125
|
+
category: raw.category,
|
|
126
|
+
tags: raw.tags,
|
|
127
|
+
searchMarkets(query, searchIn = "both") {
|
|
128
|
+
const queryLower = query.toLowerCase();
|
|
129
|
+
return this.markets.filter(market => {
|
|
130
|
+
let match = false;
|
|
131
|
+
if (searchIn === "title" || searchIn === "both") {
|
|
132
|
+
if (market.title.toLowerCase().includes(queryLower)) {
|
|
133
|
+
match = true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (searchIn === "description" || searchIn === "both") {
|
|
137
|
+
if (market.description?.toLowerCase().includes(queryLower)) {
|
|
138
|
+
match = true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return match;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
115
146
|
/**
|
|
116
147
|
* Base class for prediction market exchanges.
|
|
117
148
|
*
|
|
@@ -123,6 +154,7 @@ export class Exchange {
|
|
|
123
154
|
apiKey;
|
|
124
155
|
privateKey;
|
|
125
156
|
api;
|
|
157
|
+
config;
|
|
126
158
|
serverManager;
|
|
127
159
|
initPromise;
|
|
128
160
|
constructor(exchangeName, options = {}) {
|
|
@@ -134,8 +166,8 @@ export class Exchange {
|
|
|
134
166
|
// Initialize server manager
|
|
135
167
|
this.serverManager = new ServerManager({ baseUrl });
|
|
136
168
|
// Configure the API client with the initial base URL (will be updated if port changes)
|
|
137
|
-
|
|
138
|
-
this.api = new DefaultApi(config);
|
|
169
|
+
this.config = new Configuration({ basePath: baseUrl });
|
|
170
|
+
this.api = new DefaultApi(this.config);
|
|
139
171
|
// Initialize the server connection asynchronously
|
|
140
172
|
this.initPromise = this.initializeServer(autoStartServer);
|
|
141
173
|
}
|
|
@@ -153,11 +185,11 @@ export class Exchange {
|
|
|
153
185
|
headers['x-pmxt-access-token'] = accessToken;
|
|
154
186
|
}
|
|
155
187
|
// Update API client with actual base URL
|
|
156
|
-
|
|
188
|
+
this.config = new Configuration({
|
|
157
189
|
basePath: newBaseUrl,
|
|
158
190
|
headers
|
|
159
191
|
});
|
|
160
|
-
this.api = new DefaultApi(
|
|
192
|
+
this.api = new DefaultApi(this.config);
|
|
161
193
|
}
|
|
162
194
|
catch (error) {
|
|
163
195
|
throw new Error(`Failed to start PMXT server: ${error}\n\n` +
|
|
@@ -250,6 +282,52 @@ export class Exchange {
|
|
|
250
282
|
throw new Error(`Failed to search markets: ${error}`);
|
|
251
283
|
}
|
|
252
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Search events (groups of related markets) by keyword.
|
|
287
|
+
*
|
|
288
|
+
* @param query - Search query
|
|
289
|
+
* @param params - Optional filter parameters
|
|
290
|
+
* @returns List of matching events
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* ```typescript
|
|
294
|
+
* const events = await exchange.searchEvents("Trump");
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
async searchEvents(query, params) {
|
|
298
|
+
await this.initPromise;
|
|
299
|
+
try {
|
|
300
|
+
const args = [query];
|
|
301
|
+
if (params) {
|
|
302
|
+
args.push(params);
|
|
303
|
+
}
|
|
304
|
+
const body = { args };
|
|
305
|
+
const credentials = this.getCredentials();
|
|
306
|
+
if (credentials) {
|
|
307
|
+
body.credentials = credentials;
|
|
308
|
+
}
|
|
309
|
+
// Manual implementation since generated client is missing this
|
|
310
|
+
const url = `${this.config.basePath}/api/${this.exchangeName}/searchEvents`;
|
|
311
|
+
const response = await fetch(url, {
|
|
312
|
+
method: 'POST',
|
|
313
|
+
headers: {
|
|
314
|
+
'Content-Type': 'application/json',
|
|
315
|
+
...this.config.headers
|
|
316
|
+
},
|
|
317
|
+
body: JSON.stringify(body)
|
|
318
|
+
});
|
|
319
|
+
if (!response.ok) {
|
|
320
|
+
const error = await response.json().catch(() => ({}));
|
|
321
|
+
throw new Error(error.error?.message || response.statusText);
|
|
322
|
+
}
|
|
323
|
+
const json = await response.json();
|
|
324
|
+
const data = this.handleResponse(json);
|
|
325
|
+
return data.map(convertEvent);
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
throw new Error(`Failed to search events: ${error}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
253
331
|
/**
|
|
254
332
|
* Fetch markets by URL slug/ticker.
|
|
255
333
|
*
|
|
@@ -224,3 +224,34 @@ export interface CreateOrderParams {
|
|
|
224
224
|
/** Limit price (required for limit orders, 0.0-1.0) */
|
|
225
225
|
price?: number;
|
|
226
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* A grouped collection of related markets (e.g., "Who will be Fed Chair?" contains multiple candidate markets)
|
|
229
|
+
*/
|
|
230
|
+
export interface UnifiedEvent {
|
|
231
|
+
/** Event ID */
|
|
232
|
+
id: string;
|
|
233
|
+
/** Event title */
|
|
234
|
+
title: string;
|
|
235
|
+
/** Event description */
|
|
236
|
+
description: string;
|
|
237
|
+
/** Event slug */
|
|
238
|
+
slug: string;
|
|
239
|
+
/** Related markets in this event */
|
|
240
|
+
markets: UnifiedMarket[];
|
|
241
|
+
/** Event URL */
|
|
242
|
+
url: string;
|
|
243
|
+
/** Event image URL */
|
|
244
|
+
image?: string;
|
|
245
|
+
/** Event category */
|
|
246
|
+
category?: string;
|
|
247
|
+
/** Event tags */
|
|
248
|
+
tags?: string[];
|
|
249
|
+
/**
|
|
250
|
+
* Search for markets within this event by keyword.
|
|
251
|
+
*
|
|
252
|
+
* @param query - Search query (case-insensitive)
|
|
253
|
+
* @param searchIn - Where to search - "title", "description", or "both"
|
|
254
|
+
* @returns List of matching markets
|
|
255
|
+
*/
|
|
256
|
+
searchMarkets(query: string, searchIn?: SearchIn): UnifiedMarket[];
|
|
257
|
+
}
|
package/dist/pmxt/client.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This module provides clean, TypeScript-friendly wrappers around the auto-generated
|
|
5
5
|
* OpenAPI client, matching the Python API exactly.
|
|
6
6
|
*/
|
|
7
|
-
import { DefaultApi, ExchangeCredentials } from "../generated/src/index.js";
|
|
8
|
-
import { UnifiedMarket, PriceCandle, OrderBook, Trade, Order, Position, Balance, MarketFilterParams, HistoryFilterParams, CreateOrderParams } from "./models.js";
|
|
7
|
+
import { DefaultApi, Configuration, ExchangeCredentials } from "../generated/src/index.js";
|
|
8
|
+
import { UnifiedMarket, PriceCandle, OrderBook, Trade, Order, Position, Balance, MarketFilterParams, HistoryFilterParams, CreateOrderParams, UnifiedEvent } from "./models.js";
|
|
9
9
|
import { ServerManager } from "./server-manager.js";
|
|
10
10
|
/**
|
|
11
11
|
* Base exchange client options.
|
|
@@ -31,6 +31,7 @@ export declare abstract class Exchange {
|
|
|
31
31
|
protected apiKey?: string;
|
|
32
32
|
protected privateKey?: string;
|
|
33
33
|
protected api: DefaultApi;
|
|
34
|
+
protected config: Configuration;
|
|
34
35
|
protected serverManager: ServerManager;
|
|
35
36
|
protected initPromise: Promise<void>;
|
|
36
37
|
constructor(exchangeName: string, options?: ExchangeOptions);
|
|
@@ -62,6 +63,19 @@ export declare abstract class Exchange {
|
|
|
62
63
|
* ```
|
|
63
64
|
*/
|
|
64
65
|
searchMarkets(query: string, params?: MarketFilterParams): Promise<UnifiedMarket[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Search events (groups of related markets) by keyword.
|
|
68
|
+
*
|
|
69
|
+
* @param query - Search query
|
|
70
|
+
* @param params - Optional filter parameters
|
|
71
|
+
* @returns List of matching events
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const events = await exchange.searchEvents("Trump");
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
searchEvents(query: string, params?: MarketFilterParams): Promise<UnifiedEvent[]>;
|
|
65
79
|
/**
|
|
66
80
|
* Fetch markets by URL slug/ticker.
|
|
67
81
|
*
|
package/dist/pmxt/client.js
CHANGED
|
@@ -115,6 +115,37 @@ function convertBalance(raw) {
|
|
|
115
115
|
locked: raw.locked,
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
+
function convertEvent(raw) {
|
|
119
|
+
const markets = (raw.markets || []).map(convertMarket);
|
|
120
|
+
return {
|
|
121
|
+
id: raw.id,
|
|
122
|
+
title: raw.title,
|
|
123
|
+
description: raw.description,
|
|
124
|
+
slug: raw.slug,
|
|
125
|
+
markets,
|
|
126
|
+
url: raw.url,
|
|
127
|
+
image: raw.image,
|
|
128
|
+
category: raw.category,
|
|
129
|
+
tags: raw.tags,
|
|
130
|
+
searchMarkets(query, searchIn = "both") {
|
|
131
|
+
const queryLower = query.toLowerCase();
|
|
132
|
+
return this.markets.filter(market => {
|
|
133
|
+
let match = false;
|
|
134
|
+
if (searchIn === "title" || searchIn === "both") {
|
|
135
|
+
if (market.title.toLowerCase().includes(queryLower)) {
|
|
136
|
+
match = true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (searchIn === "description" || searchIn === "both") {
|
|
140
|
+
if (market.description?.toLowerCase().includes(queryLower)) {
|
|
141
|
+
match = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return match;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
118
149
|
/**
|
|
119
150
|
* Base class for prediction market exchanges.
|
|
120
151
|
*
|
|
@@ -126,6 +157,7 @@ class Exchange {
|
|
|
126
157
|
apiKey;
|
|
127
158
|
privateKey;
|
|
128
159
|
api;
|
|
160
|
+
config;
|
|
129
161
|
serverManager;
|
|
130
162
|
initPromise;
|
|
131
163
|
constructor(exchangeName, options = {}) {
|
|
@@ -137,8 +169,8 @@ class Exchange {
|
|
|
137
169
|
// Initialize server manager
|
|
138
170
|
this.serverManager = new server_manager_js_1.ServerManager({ baseUrl });
|
|
139
171
|
// Configure the API client with the initial base URL (will be updated if port changes)
|
|
140
|
-
|
|
141
|
-
this.api = new index_js_1.DefaultApi(config);
|
|
172
|
+
this.config = new index_js_1.Configuration({ basePath: baseUrl });
|
|
173
|
+
this.api = new index_js_1.DefaultApi(this.config);
|
|
142
174
|
// Initialize the server connection asynchronously
|
|
143
175
|
this.initPromise = this.initializeServer(autoStartServer);
|
|
144
176
|
}
|
|
@@ -156,11 +188,11 @@ class Exchange {
|
|
|
156
188
|
headers['x-pmxt-access-token'] = accessToken;
|
|
157
189
|
}
|
|
158
190
|
// Update API client with actual base URL
|
|
159
|
-
|
|
191
|
+
this.config = new index_js_1.Configuration({
|
|
160
192
|
basePath: newBaseUrl,
|
|
161
193
|
headers
|
|
162
194
|
});
|
|
163
|
-
this.api = new index_js_1.DefaultApi(
|
|
195
|
+
this.api = new index_js_1.DefaultApi(this.config);
|
|
164
196
|
}
|
|
165
197
|
catch (error) {
|
|
166
198
|
throw new Error(`Failed to start PMXT server: ${error}\n\n` +
|
|
@@ -253,6 +285,52 @@ class Exchange {
|
|
|
253
285
|
throw new Error(`Failed to search markets: ${error}`);
|
|
254
286
|
}
|
|
255
287
|
}
|
|
288
|
+
/**
|
|
289
|
+
* Search events (groups of related markets) by keyword.
|
|
290
|
+
*
|
|
291
|
+
* @param query - Search query
|
|
292
|
+
* @param params - Optional filter parameters
|
|
293
|
+
* @returns List of matching events
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* const events = await exchange.searchEvents("Trump");
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
async searchEvents(query, params) {
|
|
301
|
+
await this.initPromise;
|
|
302
|
+
try {
|
|
303
|
+
const args = [query];
|
|
304
|
+
if (params) {
|
|
305
|
+
args.push(params);
|
|
306
|
+
}
|
|
307
|
+
const body = { args };
|
|
308
|
+
const credentials = this.getCredentials();
|
|
309
|
+
if (credentials) {
|
|
310
|
+
body.credentials = credentials;
|
|
311
|
+
}
|
|
312
|
+
// Manual implementation since generated client is missing this
|
|
313
|
+
const url = `${this.config.basePath}/api/${this.exchangeName}/searchEvents`;
|
|
314
|
+
const response = await fetch(url, {
|
|
315
|
+
method: 'POST',
|
|
316
|
+
headers: {
|
|
317
|
+
'Content-Type': 'application/json',
|
|
318
|
+
...this.config.headers
|
|
319
|
+
},
|
|
320
|
+
body: JSON.stringify(body)
|
|
321
|
+
});
|
|
322
|
+
if (!response.ok) {
|
|
323
|
+
const error = await response.json().catch(() => ({}));
|
|
324
|
+
throw new Error(error.error?.message || response.statusText);
|
|
325
|
+
}
|
|
326
|
+
const json = await response.json();
|
|
327
|
+
const data = this.handleResponse(json);
|
|
328
|
+
return data.map(convertEvent);
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
throw new Error(`Failed to search events: ${error}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
256
334
|
/**
|
|
257
335
|
* Fetch markets by URL slug/ticker.
|
|
258
336
|
*
|
package/dist/pmxt/models.d.ts
CHANGED
|
@@ -224,3 +224,34 @@ export interface CreateOrderParams {
|
|
|
224
224
|
/** Limit price (required for limit orders, 0.0-1.0) */
|
|
225
225
|
price?: number;
|
|
226
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* A grouped collection of related markets (e.g., "Who will be Fed Chair?" contains multiple candidate markets)
|
|
229
|
+
*/
|
|
230
|
+
export interface UnifiedEvent {
|
|
231
|
+
/** Event ID */
|
|
232
|
+
id: string;
|
|
233
|
+
/** Event title */
|
|
234
|
+
title: string;
|
|
235
|
+
/** Event description */
|
|
236
|
+
description: string;
|
|
237
|
+
/** Event slug */
|
|
238
|
+
slug: string;
|
|
239
|
+
/** Related markets in this event */
|
|
240
|
+
markets: UnifiedMarket[];
|
|
241
|
+
/** Event URL */
|
|
242
|
+
url: string;
|
|
243
|
+
/** Event image URL */
|
|
244
|
+
image?: string;
|
|
245
|
+
/** Event category */
|
|
246
|
+
category?: string;
|
|
247
|
+
/** Event tags */
|
|
248
|
+
tags?: string[];
|
|
249
|
+
/**
|
|
250
|
+
* Search for markets within this event by keyword.
|
|
251
|
+
*
|
|
252
|
+
* @param query - Search query (case-insensitive)
|
|
253
|
+
* @param searchIn - Where to search - "title", "description", or "both"
|
|
254
|
+
* @returns List of matching markets
|
|
255
|
+
*/
|
|
256
|
+
searchMarkets(query: string, searchIn?: SearchIn): UnifiedMarket[];
|
|
257
|
+
}
|
package/generated/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxtjs",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Unified prediction market data API - The ccxt for prediction markets",
|
|
5
5
|
"author": "PMXT Contributors",
|
|
6
6
|
"repository": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"unified"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"pmxt-core": "1.3.
|
|
45
|
+
"pmxt-core": "1.3.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/jest": "^30.0.0",
|
package/pmxt/client.ts
CHANGED
|
@@ -34,6 +34,8 @@ import {
|
|
|
34
34
|
MarketFilterParams,
|
|
35
35
|
HistoryFilterParams,
|
|
36
36
|
CreateOrderParams,
|
|
37
|
+
SearchIn,
|
|
38
|
+
UnifiedEvent,
|
|
37
39
|
} from "./models.js";
|
|
38
40
|
|
|
39
41
|
import { ServerManager } from "./server-manager.js";
|
|
@@ -156,6 +158,39 @@ function convertBalance(raw: any): Balance {
|
|
|
156
158
|
};
|
|
157
159
|
}
|
|
158
160
|
|
|
161
|
+
function convertEvent(raw: any): UnifiedEvent {
|
|
162
|
+
const markets = (raw.markets || []).map(convertMarket);
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
id: raw.id,
|
|
166
|
+
title: raw.title,
|
|
167
|
+
description: raw.description,
|
|
168
|
+
slug: raw.slug,
|
|
169
|
+
markets,
|
|
170
|
+
url: raw.url,
|
|
171
|
+
image: raw.image,
|
|
172
|
+
category: raw.category,
|
|
173
|
+
tags: raw.tags,
|
|
174
|
+
searchMarkets(query: string, searchIn: SearchIn = "both"): UnifiedMarket[] {
|
|
175
|
+
const queryLower = query.toLowerCase();
|
|
176
|
+
return this.markets.filter(market => {
|
|
177
|
+
let match = false;
|
|
178
|
+
if (searchIn === "title" || searchIn === "both") {
|
|
179
|
+
if (market.title.toLowerCase().includes(queryLower)) {
|
|
180
|
+
match = true;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (searchIn === "description" || searchIn === "both") {
|
|
184
|
+
if (market.description?.toLowerCase().includes(queryLower)) {
|
|
185
|
+
match = true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return match;
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
159
194
|
/**
|
|
160
195
|
* Base exchange client options.
|
|
161
196
|
*/
|
|
@@ -184,6 +219,7 @@ export abstract class Exchange {
|
|
|
184
219
|
protected apiKey?: string;
|
|
185
220
|
protected privateKey?: string;
|
|
186
221
|
protected api: DefaultApi;
|
|
222
|
+
protected config: Configuration;
|
|
187
223
|
protected serverManager: ServerManager;
|
|
188
224
|
protected initPromise: Promise<void>;
|
|
189
225
|
|
|
@@ -199,8 +235,8 @@ export abstract class Exchange {
|
|
|
199
235
|
this.serverManager = new ServerManager({ baseUrl });
|
|
200
236
|
|
|
201
237
|
// Configure the API client with the initial base URL (will be updated if port changes)
|
|
202
|
-
|
|
203
|
-
this.api = new DefaultApi(config);
|
|
238
|
+
this.config = new Configuration({ basePath: baseUrl });
|
|
239
|
+
this.api = new DefaultApi(this.config);
|
|
204
240
|
|
|
205
241
|
// Initialize the server connection asynchronously
|
|
206
242
|
this.initPromise = this.initializeServer(autoStartServer);
|
|
@@ -223,11 +259,11 @@ export abstract class Exchange {
|
|
|
223
259
|
}
|
|
224
260
|
|
|
225
261
|
// Update API client with actual base URL
|
|
226
|
-
|
|
262
|
+
this.config = new Configuration({
|
|
227
263
|
basePath: newBaseUrl,
|
|
228
264
|
headers
|
|
229
265
|
});
|
|
230
|
-
this.api = new DefaultApi(
|
|
266
|
+
this.api = new DefaultApi(this.config);
|
|
231
267
|
} catch (error) {
|
|
232
268
|
throw new Error(
|
|
233
269
|
`Failed to start PMXT server: ${error}\n\n` +
|
|
@@ -334,6 +370,60 @@ export abstract class Exchange {
|
|
|
334
370
|
}
|
|
335
371
|
}
|
|
336
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Search events (groups of related markets) by keyword.
|
|
375
|
+
*
|
|
376
|
+
* @param query - Search query
|
|
377
|
+
* @param params - Optional filter parameters
|
|
378
|
+
* @returns List of matching events
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```typescript
|
|
382
|
+
* const events = await exchange.searchEvents("Trump");
|
|
383
|
+
* ```
|
|
384
|
+
*/
|
|
385
|
+
async searchEvents(
|
|
386
|
+
query: string,
|
|
387
|
+
params?: MarketFilterParams
|
|
388
|
+
): Promise<UnifiedEvent[]> {
|
|
389
|
+
await this.initPromise;
|
|
390
|
+
try {
|
|
391
|
+
const args: any[] = [query];
|
|
392
|
+
if (params) {
|
|
393
|
+
args.push(params);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const body: any = { args };
|
|
397
|
+
const credentials = this.getCredentials();
|
|
398
|
+
if (credentials) {
|
|
399
|
+
body.credentials = credentials;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Manual implementation since generated client is missing this
|
|
403
|
+
const url = `${this.config.basePath}/api/${this.exchangeName}/searchEvents`;
|
|
404
|
+
|
|
405
|
+
const response = await fetch(url, {
|
|
406
|
+
method: 'POST',
|
|
407
|
+
headers: {
|
|
408
|
+
'Content-Type': 'application/json',
|
|
409
|
+
...this.config.headers
|
|
410
|
+
},
|
|
411
|
+
body: JSON.stringify(body)
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
if (!response.ok) {
|
|
415
|
+
const error = await response.json().catch(() => ({}));
|
|
416
|
+
throw new Error(error.error?.message || response.statusText);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const json = await response.json();
|
|
420
|
+
const data = this.handleResponse(json);
|
|
421
|
+
return data.map(convertEvent);
|
|
422
|
+
} catch (error) {
|
|
423
|
+
throw new Error(`Failed to search events: ${error}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
337
427
|
/**
|
|
338
428
|
* Fetch markets by URL slug/ticker.
|
|
339
429
|
*
|
package/pmxt/models.ts
CHANGED
|
@@ -302,3 +302,43 @@ export interface CreateOrderParams {
|
|
|
302
302
|
/** Limit price (required for limit orders, 0.0-1.0) */
|
|
303
303
|
price?: number;
|
|
304
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* A grouped collection of related markets (e.g., "Who will be Fed Chair?" contains multiple candidate markets)
|
|
307
|
+
*/
|
|
308
|
+
export interface UnifiedEvent {
|
|
309
|
+
/** Event ID */
|
|
310
|
+
id: string;
|
|
311
|
+
|
|
312
|
+
/** Event title */
|
|
313
|
+
title: string;
|
|
314
|
+
|
|
315
|
+
/** Event description */
|
|
316
|
+
description: string;
|
|
317
|
+
|
|
318
|
+
/** Event slug */
|
|
319
|
+
slug: string;
|
|
320
|
+
|
|
321
|
+
/** Related markets in this event */
|
|
322
|
+
markets: UnifiedMarket[];
|
|
323
|
+
|
|
324
|
+
/** Event URL */
|
|
325
|
+
url: string;
|
|
326
|
+
|
|
327
|
+
/** Event image URL */
|
|
328
|
+
image?: string;
|
|
329
|
+
|
|
330
|
+
/** Event category */
|
|
331
|
+
category?: string;
|
|
332
|
+
|
|
333
|
+
/** Event tags */
|
|
334
|
+
tags?: string[];
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Search for markets within this event by keyword.
|
|
338
|
+
*
|
|
339
|
+
* @param query - Search query (case-insensitive)
|
|
340
|
+
* @param searchIn - Where to search - "title", "description", or "both"
|
|
341
|
+
* @returns List of matching markets
|
|
342
|
+
*/
|
|
343
|
+
searchMarkets(query: string, searchIn?: SearchIn): UnifiedMarket[];
|
|
344
|
+
}
|