pmxtjs 0.2.1 → 0.3.1

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/API_REFERENCE.md CHANGED
@@ -1,88 +1,254 @@
1
1
  # Prediction Market API Reference
2
2
 
3
- This project implements a **Unified Interface** for interacting with multiple prediction market exchanges (Kalshi, Polymarket) identically.
3
+ A unified interface for interacting with multiple prediction market exchanges (Kalshi, Polymarket) identically.
4
4
 
5
- ## Usage
5
+ ## Installation & Usage
6
6
 
7
- All components are available directly from the `pmxt` library.
7
+ ```bash
8
+ npm install pmxtjs
9
+ ```
8
10
 
9
11
  ```typescript
10
- import {
11
- PolymarketExchange,
12
- KalshiExchange
13
- } from './pmxt';
12
+ import pmxt from 'pmxtjs';
14
13
 
15
- const polymarket = new PolymarketExchange();
16
- const kalshi = new KalshiExchange();
14
+ const polymarket = new pmxt.polymarket();
15
+ const kalshi = new pmxt.kalshi();
17
16
  ```
18
17
 
19
- ## 1. Unified Interface (`PredictionMarketExchange`)
18
+ ---
20
19
 
21
- All exchanges implement this core interface for discovery.
20
+ ## Core Methods
22
21
 
23
22
  ### `fetchMarkets(params?)`
24
- Retrieves active markets normalized into a standard format.
25
- - **Input**: `limit`, `sort` ('volume' | 'liquidity' | 'newest')
26
- - **Output**: `Promise<UnifiedMarket[]>`
23
+ Get active markets from an exchange.
24
+
25
+ ```typescript
26
+ const markets = await polymarket.fetchMarkets({
27
+ limit: 20,
28
+ offset: 0,
29
+ sort: 'volume' // 'volume' | 'liquidity' | 'newest'
30
+ });
31
+ ```
27
32
 
28
33
  ### `searchMarkets(query, params?)`
29
- Search markets by title/description across the exchange(s).
30
- - **Input**: `query` (string), `limit`
31
- - **Output**: `Promise<UnifiedMarket[]>`
34
+ Search markets by keyword. By default, searches only in titles.
35
+
36
+ ```typescript
37
+ const results = await kalshi.searchMarkets('Fed rates', {
38
+ limit: 10,
39
+ searchIn: 'title' // 'title' (default) | 'description' | 'both'
40
+ });
41
+ ```
42
+
43
+ ### `getMarketsBySlug(slug)`
44
+ Fetch markets by URL slug/ticker.
45
+
46
+ ```typescript
47
+ // Polymarket: use URL slug
48
+ const polyMarkets = await polymarket.getMarketsBySlug('who-will-trump-nominate-as-fed-chair');
49
+
50
+ // Kalshi: use event ticker (auto-uppercased)
51
+ const kalshiMarkets = await kalshi.getMarketsBySlug('FED-25JAN');
52
+ ```
32
53
 
33
54
  ---
34
55
 
35
- ## 2. Deep-Dive Interface (Exchange Only)
56
+ ## Deep-Dive Methods
57
+
58
+ ### `fetchOHLCV(outcomeId, params)`
59
+ Get historical price candles.
60
+
61
+ **CRITICAL**: Use `outcome.id`, not `market.id`.
62
+ - **Polymarket**: `outcome.id` is the CLOB Token ID
63
+ - **Kalshi**: `outcome.id` is the Market Ticker
64
+
65
+ ```typescript
66
+ const markets = await polymarket.searchMarkets('Trump');
67
+ const outcomeId = markets[0].outcomes[0].id; // Get the outcome ID
68
+
69
+ const candles = await polymarket.fetchOHLCV(outcomeId, {
70
+ resolution: '1h', // '1m' | '5m' | '15m' | '1h' | '6h' | '1d'
71
+ start: new Date('2024-01-01'),
72
+ end: new Date('2024-01-31'),
73
+ limit: 100
74
+ });
75
+ ```
76
+
77
+ ### `fetchOrderBook(outcomeId)`
78
+ Get current bids/asks.
36
79
 
37
- Methods available on specific exchange instances (`KalshiExchange`, `PolymarketExchange`) for detailed data.
80
+ ```typescript
81
+ const orderBook = await kalshi.fetchOrderBook('FED-25JAN');
82
+ console.log('Best bid:', orderBook.bids[0].price);
83
+ console.log('Best ask:', orderBook.asks[0].price);
84
+ ```
38
85
 
39
- ### `getMarketHistory(id, params)`
40
- Fetches OHLCV candlesticks.
41
- - **Input**: `id`, `resolution` (1m, 1h, 1d), `start`, `end`.
42
- - **Output**: `Promise<PriceCandle[]>`
43
- - **Important**:
44
- - **Kalshi**: Uses the Market Ticker (e.g., `FED-25DEC`). Returns **native OHLCV** (Open/High/Low/Close data is distinct).
45
- - **Polymarket**: Uses the **CLOB Token ID** found in `outcome.metadata.clobTokenId`. Returns **synthetic candles** (Open=High=Low=Close) derived from raw price points.
86
+ ### `fetchTrades(outcomeId, params)`
87
+ Get trade history.
46
88
 
47
- ### `getOrderBook(id)`
48
- Fetches live Bids/Asks.
49
- - **Input**: `id` (Ticker for Kalshi, Token ID for Polymarket).
50
- - **Output**: `Promise<OrderBook>` (Normalized: "No" bids becomes "Yes" asks).
89
+ **Note**: Polymarket requires API key. Use `fetchOHLCV` for public historical data.
51
90
 
52
- ### `getTradeHistory(id, params)`
53
- Fetches the "Tape" (raw transaction history).
54
- - **Input**: `id`, `limit`.
55
- - **Output**: `Promise<Trade[]>`
56
- - **Note**:
57
- - **Kalshi**: Publicly accessible for all tickers.
58
- - **Polymarket**: Requires L2 Authentication (API Key). Without a key, this method will throw an unauthorized error. Use `getMarketHistory` for public historical data.
91
+ ```typescript
92
+ const trades = await kalshi.fetchTrades('FED-25JAN', {
93
+ resolution: '1h',
94
+ limit: 100
95
+ });
96
+ ```
59
97
 
60
98
  ---
61
99
 
62
- ## 3. Data Models
100
+ ## Data Models
63
101
 
64
- ### `UnifiedMarket` (The Standard Atom)
102
+ ### `UnifiedMarket`
65
103
  ```typescript
66
104
  {
67
- id: string; // Exchange-specific ID
68
- title: string; // "Who will win the election?"
69
- description: string; // Detailed context/rules of the market
70
- outcomes: [
71
- {
72
- id: string,
73
- label: "Trump",
74
- price: 0.52,
75
- priceChange24h: 0.05, // Optional: Change in price over last 24h
76
- metadata: { ... } // Exchange-specific keys (clobTokenId)
77
- }
78
- ];
105
+ id: string; // Market ID
106
+ title: string;
107
+ description: string;
108
+ outcomes: MarketOutcome[]; // All tradeable outcomes
109
+
79
110
  resolutionDate: Date;
80
- volume24h: number;
81
- liquidity: number;
111
+ volume24h: number; // USD
112
+ volume?: number; // Total volume (USD)
113
+ liquidity: number; // USD
114
+ openInterest?: number; // USD
115
+
82
116
  url: string;
83
- image?: string; // Optional: Thumbnail URL
84
- category?: string; // Optional: Primary category (e.g., "Politics")
85
- tags?: string[]; // Optional: Searchable tags
117
+ image?: string;
118
+ category?: string;
119
+ tags?: string[];
86
120
  }
87
121
  ```
88
122
 
123
+ ### `MarketOutcome`
124
+ ```typescript
125
+ {
126
+ id: string; // ⚠️ Use this for fetchOHLCV/fetchOrderBook/fetchTrades
127
+ // Polymarket: CLOB Token ID
128
+ // Kalshi: Market Ticker
129
+ label: string; // "Trump", "Yes", etc.
130
+ price: number; // 0.0 to 1.0 (probability)
131
+ priceChange24h?: number;
132
+ metadata?: {
133
+ clobTokenId?: string; // Polymarket only
134
+ }
135
+ }
136
+ ```
137
+
138
+ ### Other Types
139
+ ```typescript
140
+ interface PriceCandle {
141
+ timestamp: number; // Unix ms
142
+ open: number; // 0.0 to 1.0
143
+ high: number;
144
+ low: number;
145
+ close: number;
146
+ volume?: number;
147
+ }
148
+
149
+ interface OrderBook {
150
+ bids: OrderLevel[]; // Sorted high to low
151
+ asks: OrderLevel[]; // Sorted low to high
152
+ timestamp?: number;
153
+ }
154
+
155
+ interface OrderLevel {
156
+ price: number; // 0.0 to 1.0
157
+ size: number; // Contracts
158
+ }
159
+
160
+ interface Trade {
161
+ id: string;
162
+ timestamp: number; // Unix ms
163
+ price: number; // 0.0 to 1.0
164
+ amount: number;
165
+ side: 'buy' | 'sell' | 'unknown';
166
+ }
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Complete Workflow Example
172
+
173
+ ```typescript
174
+ // 1. Search for markets
175
+ const markets = await polymarket.searchMarkets('Fed Chair');
176
+ const market = markets[0];
177
+
178
+ // 2. Get outcome details
179
+ const outcome = market.outcomes[0];
180
+ console.log(`${outcome.label}: ${(outcome.price * 100).toFixed(1)}%`);
181
+
182
+ // 3. Fetch historical data (use outcome.id!)
183
+ const candles = await polymarket.fetchOHLCV(outcome.id, {
184
+ resolution: '1d',
185
+ limit: 30
186
+ });
187
+
188
+ // 4. Get current order book
189
+ const orderBook = await polymarket.fetchOrderBook(outcome.id);
190
+ const spread = orderBook.asks[0].price - orderBook.bids[0].price;
191
+ console.log(`Spread: ${(spread * 100).toFixed(2)}%`);
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Exchange Differences
197
+
198
+ | Feature | Polymarket | Kalshi |
199
+ |---------|-----------|--------|
200
+ | **Sorting** | Server-side | Client-side (slower for large sets) |
201
+ | **Market ID** | UUID | Event Ticker (e.g., "PRES-2024") |
202
+ | **Outcome ID** | CLOB Token ID | Market Ticker (e.g., "FED-25JAN") |
203
+ | **OHLCV Quality** | Synthetic (O=H=L=C) | Native (distinct values) |
204
+ | **Auth Required** | Only for `fetchTrades()` | No (all public) |
205
+ | **Slug Format** | lowercase-with-hyphens | UPPERCASE (auto-normalized) |
206
+
207
+ ---
208
+
209
+ ## Error Handling
210
+
211
+ ```typescript
212
+ try {
213
+ const markets = await kalshi.getMarketsBySlug('INVALID-TICKER');
214
+ } catch (error) {
215
+ // Kalshi: "Event not found: INVALID-TICKER"
216
+ // Polymarket: Returns empty array []
217
+ console.error(error.message);
218
+ }
219
+ ```
220
+
221
+ **Common Errors**:
222
+ - `404`: Market/event doesn't exist
223
+ - `401`: Missing API key (Polymarket `fetchTrades`)
224
+ - `429`: Rate limited
225
+ - `500`: Exchange API issue
226
+
227
+ ---
228
+
229
+ ## Type Exports
230
+
231
+ ```typescript
232
+ import pmxt, {
233
+ UnifiedMarket,
234
+ MarketOutcome,
235
+ PriceCandle,
236
+ OrderBook,
237
+ Trade,
238
+ CandleInterval,
239
+ MarketFilterParams,
240
+ HistoryFilterParams
241
+ } from 'pmxtjs';
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Quick Reference
247
+
248
+ - **Prices**: Always 0.0-1.0 (multiply by 100 for %)
249
+ - **Timestamps**: Unix milliseconds
250
+ - **Volumes**: USD
251
+ - **IDs**: Use `outcome.id` for deep-dive methods, not `market.id`
252
+
253
+ For more examples, see [`examples/`](examples/).
254
+
@@ -3,6 +3,7 @@ export interface MarketFilterParams {
3
3
  limit?: number;
4
4
  offset?: number;
5
5
  sort?: 'volume' | 'liquidity' | 'newest';
6
+ searchIn?: 'title' | 'description' | 'both';
6
7
  }
7
8
  export interface HistoryFilterParams {
8
9
  resolution: CandleInterval;
@@ -18,22 +19,22 @@ export declare abstract class PredictionMarketExchange {
18
19
  abstract fetchMarkets(params?: MarketFilterParams): Promise<UnifiedMarket[]>;
19
20
  /**
20
21
  * Search for markets matching a keyword query.
21
- * Searches across title and description fields.
22
+ * By default, searches only in market titles. Use params.searchIn to search descriptions or both.
22
23
  */
23
24
  abstract searchMarkets(query: string, params?: MarketFilterParams): Promise<UnifiedMarket[]>;
24
25
  /**
25
26
  * Fetch historical price data for a specific market outcome.
26
27
  * @param id - The Outcome ID (MarketOutcome.id). This should be the ID of the specific tradeable asset.
27
28
  */
28
- getMarketHistory(id: string, params: HistoryFilterParams): Promise<PriceCandle[]>;
29
+ fetchOHLCV(id: string, params: HistoryFilterParams): Promise<PriceCandle[]>;
29
30
  /**
30
31
  * Fetch the current order book (bids/asks) for a specific outcome.
31
32
  * Essential for calculating localized spread and depth.
32
33
  */
33
- getOrderBook(id: string): Promise<OrderBook>;
34
+ fetchOrderBook(id: string): Promise<OrderBook>;
34
35
  /**
35
36
  * Fetch raw trade history.
36
37
  * Useful for generating synthetic OHLCV candles if the exchange doesn't provide them natively.
37
38
  */
38
- getTradeHistory(id: string, params: HistoryFilterParams): Promise<Trade[]>;
39
+ fetchTrades(id: string, params: HistoryFilterParams): Promise<Trade[]>;
39
40
  }
@@ -9,22 +9,22 @@ class PredictionMarketExchange {
9
9
  * Fetch historical price data for a specific market outcome.
10
10
  * @param id - The Outcome ID (MarketOutcome.id). This should be the ID of the specific tradeable asset.
11
11
  */
12
- async getMarketHistory(id, params) {
13
- throw new Error("Method getMarketHistory not implemented.");
12
+ async fetchOHLCV(id, params) {
13
+ throw new Error("Method fetchOHLCV not implemented.");
14
14
  }
15
15
  /**
16
16
  * Fetch the current order book (bids/asks) for a specific outcome.
17
17
  * Essential for calculating localized spread and depth.
18
18
  */
19
- async getOrderBook(id) {
20
- throw new Error("Method getOrderBook not implemented.");
19
+ async fetchOrderBook(id) {
20
+ throw new Error("Method fetchOrderBook not implemented.");
21
21
  }
22
22
  /**
23
23
  * Fetch raw trade history.
24
24
  * Useful for generating synthetic OHLCV candles if the exchange doesn't provide them natively.
25
25
  */
26
- async getTradeHistory(id, params) {
27
- throw new Error("Method getTradeHistory not implemented.");
26
+ async fetchTrades(id, params) {
27
+ throw new Error("Method fetchTrades not implemented.");
28
28
  }
29
29
  }
30
30
  exports.PredictionMarketExchange = PredictionMarketExchange;
@@ -14,7 +14,7 @@ export declare class KalshiExchange extends PredictionMarketExchange {
14
14
  */
15
15
  getMarketsBySlug(eventTicker: string): Promise<UnifiedMarket[]>;
16
16
  private mapIntervalToKalshi;
17
- getMarketHistory(id: string, params: HistoryFilterParams): Promise<PriceCandle[]>;
18
- getOrderBook(id: string): Promise<OrderBook>;
19
- getTradeHistory(id: string, params: HistoryFilterParams): Promise<Trade[]>;
17
+ fetchOHLCV(id: string, params: HistoryFilterParams): Promise<PriceCandle[]>;
18
+ fetchOrderBook(id: string): Promise<OrderBook>;
19
+ fetchTrades(id: string, params: HistoryFilterParams): Promise<Trade[]>;
20
20
  }
@@ -149,8 +149,16 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
149
149
  try {
150
150
  const markets = await this.fetchMarkets({ ...params, limit: fetchLimit });
151
151
  const lowerQuery = query.toLowerCase();
152
- const filtered = markets.filter(market => market.title.toLowerCase().includes(lowerQuery) ||
153
- market.description.toLowerCase().includes(lowerQuery));
152
+ const searchIn = params?.searchIn || 'title'; // Default to title-only search
153
+ const filtered = markets.filter(market => {
154
+ const titleMatch = (market.title || '').toLowerCase().includes(lowerQuery);
155
+ const descMatch = (market.description || '').toLowerCase().includes(lowerQuery);
156
+ if (searchIn === 'title')
157
+ return titleMatch;
158
+ if (searchIn === 'description')
159
+ return descMatch;
160
+ return titleMatch || descMatch; // 'both'
161
+ });
154
162
  const limit = params?.limit || 20;
155
163
  return filtered.slice(0, limit);
156
164
  }
@@ -208,7 +216,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
208
216
  };
209
217
  return mapping[interval];
210
218
  }
211
- async getMarketHistory(id, params) {
219
+ async fetchOHLCV(id, params) {
212
220
  try {
213
221
  // Kalshi API expects uppercase tickers
214
222
  // Handle virtual "-NO" suffix by stripping it (fetching the underlying market history)
@@ -239,14 +247,31 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
239
247
  queryParams.end_ts = endTs;
240
248
  const response = await axios_1.default.get(url, { params: queryParams });
241
249
  const candles = response.data.candlesticks || [];
242
- const mappedCandles = candles.map((c) => ({
243
- timestamp: c.end_period_ts * 1000,
244
- open: (c.price.open || 0) / 100,
245
- high: (c.price.high || 0) / 100,
246
- low: (c.price.low || 0) / 100,
247
- close: (c.price.close || 0) / 100,
248
- volume: c.volume
249
- }));
250
+ const mappedCandles = candles.map((c) => {
251
+ // Priority:
252
+ // 1. Transaction price (close)
253
+ // 2. Mid price (average of yes_ask and yes_bid close)
254
+ // 3. Fallback to 0 if everything is missing
255
+ const p = c.price || {};
256
+ const ask = c.yes_ask || {};
257
+ const bid = c.yes_bid || {};
258
+ const getVal = (field) => {
259
+ if (p[field] !== null && p[field] !== undefined)
260
+ return p[field];
261
+ if (ask[field] !== null && bid[field] !== null && ask[field] !== undefined && bid[field] !== undefined) {
262
+ return (ask[field] + bid[field]) / 2;
263
+ }
264
+ return p.previous || 0;
265
+ };
266
+ return {
267
+ timestamp: c.end_period_ts * 1000,
268
+ open: getVal('open') / 100,
269
+ high: getVal('high') / 100,
270
+ low: getVal('low') / 100,
271
+ close: getVal('close') / 100,
272
+ volume: c.volume || 0
273
+ };
274
+ });
250
275
  if (params.limit && mappedCandles.length > params.limit) {
251
276
  return mappedCandles.slice(-params.limit);
252
277
  }
@@ -261,7 +286,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
261
286
  throw error;
262
287
  }
263
288
  }
264
- async getOrderBook(id) {
289
+ async fetchOrderBook(id) {
265
290
  try {
266
291
  const ticker = id.replace(/-NO$/, '');
267
292
  const url = `https://api.elections.kalshi.com/trade-api/v2/markets/${ticker}/orderbook`;
@@ -286,7 +311,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
286
311
  return { bids: [], asks: [] };
287
312
  }
288
313
  }
289
- async getTradeHistory(id, params) {
314
+ async fetchTrades(id, params) {
290
315
  try {
291
316
  const ticker = id.replace(/-NO$/, '');
292
317
  const url = `https://api.elections.kalshi.com/trade-api/v2/markets/trades`;
@@ -20,19 +20,19 @@ export declare class PolymarketExchange extends PredictionMarketExchange {
20
20
  * Fetch historical price data (OHLCV candles) for a specific token.
21
21
  * @param id - The CLOB token ID (e.g., outcome token ID)
22
22
  */
23
- getMarketHistory(id: string, params: HistoryFilterParams): Promise<PriceCandle[]>;
23
+ fetchOHLCV(id: string, params: HistoryFilterParams): Promise<PriceCandle[]>;
24
24
  /**
25
25
  * Fetch the current order book for a specific token.
26
26
  * @param id - The CLOB token ID
27
27
  */
28
- getOrderBook(id: string): Promise<OrderBook>;
28
+ fetchOrderBook(id: string): Promise<OrderBook>;
29
29
  /**
30
30
  * Fetch raw trade history for a specific token.
31
31
  * @param id - The CLOB token ID
32
32
  *
33
33
  * NOTE: Polymarket's /trades endpoint currently requires L2 Authentication (API Key).
34
34
  * This method will return an empty array if an API key is not provided in headers.
35
- * Use getMarketHistory for public historical price data instead.
35
+ * Use fetchOHLCV for public historical price data instead.
36
36
  */
37
- getTradeHistory(id: string, params: HistoryFilterParams): Promise<Trade[]>;
37
+ fetchTrades(id: string, params: HistoryFilterParams): Promise<Trade[]>;
38
38
  }
@@ -64,6 +64,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
64
64
  outcomePrices = typeof market.outcomePrices === 'string' ? JSON.parse(market.outcomePrices) : (market.outcomePrices || []);
65
65
  }
66
66
  catch (e) {
67
+ console.warn(`Error parsing outcomes for market ${market.id}:`, e);
67
68
  }
68
69
  // Extract CLOB token IDs for granular operations
69
70
  let clobTokenIds = [];
@@ -148,8 +149,8 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
148
149
  }
149
150
  async searchMarkets(query, params) {
150
151
  // Polymarket Gamma API doesn't support native search
151
- // Fetch a larger batch and filter client-side
152
- const searchLimit = 100; // Fetch more markets to search through
152
+ // Fetch all active markets and filter client-side
153
+ const searchLimit = 100000; // Fetch all markets for comprehensive search
153
154
  try {
154
155
  // Fetch markets with a higher limit
155
156
  const markets = await this.fetchMarkets({
@@ -158,8 +159,16 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
158
159
  });
159
160
  // Client-side text filtering
160
161
  const lowerQuery = query.toLowerCase();
161
- const filtered = markets.filter(market => market.title.toLowerCase().includes(lowerQuery) ||
162
- market.description.toLowerCase().includes(lowerQuery));
162
+ const searchIn = params?.searchIn || 'title'; // Default to title-only search
163
+ const filtered = markets.filter(market => {
164
+ const titleMatch = (market.title || '').toLowerCase().includes(lowerQuery);
165
+ const descMatch = (market.description || '').toLowerCase().includes(lowerQuery);
166
+ if (searchIn === 'title')
167
+ return titleMatch;
168
+ if (searchIn === 'description')
169
+ return descMatch;
170
+ return titleMatch || descMatch; // 'both'
171
+ });
163
172
  // Apply limit to filtered results
164
173
  const limit = params?.limit || 20;
165
174
  return filtered.slice(0, limit);
@@ -201,7 +210,9 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
201
210
  outcomePrices = typeof market.outcomePrices === 'string' ? JSON.parse(market.outcomePrices) : (market.outcomePrices || []);
202
211
  clobTokenIds = typeof market.clobTokenIds === 'string' ? JSON.parse(market.clobTokenIds) : (market.clobTokenIds || []);
203
212
  }
204
- catch (e) { /* ignore */ }
213
+ catch (e) {
214
+ console.warn(`Error parsing outcomes for market ${market.id}:`, e);
215
+ }
205
216
  let candidateName = market.groupItemTitle;
206
217
  if (!candidateName && market.question)
207
218
  candidateName = market.question;
@@ -271,7 +282,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
271
282
  * Fetch historical price data (OHLCV candles) for a specific token.
272
283
  * @param id - The CLOB token ID (e.g., outcome token ID)
273
284
  */
274
- async getMarketHistory(id, params) {
285
+ async fetchOHLCV(id, params) {
275
286
  // ID Validation: Polymarket CLOB requires a Token ID (long numeric string) not a Market ID
276
287
  if (id.length < 10 && /^\d+$/.test(id)) {
277
288
  throw new Error(`Invalid ID for Polymarket history: "${id}". You provided a Market ID, but Polymarket's CLOB API requires a Token ID. Ensure you are using 'outcome.id'.`);
@@ -336,7 +347,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
336
347
  * Fetch the current order book for a specific token.
337
348
  * @param id - The CLOB token ID
338
349
  */
339
- async getOrderBook(id) {
350
+ async fetchOrderBook(id) {
340
351
  try {
341
352
  const response = await axios_1.default.get(`${this.clobUrl}/book`, {
342
353
  params: { token_id: id }
@@ -368,9 +379,9 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
368
379
  *
369
380
  * NOTE: Polymarket's /trades endpoint currently requires L2 Authentication (API Key).
370
381
  * This method will return an empty array if an API key is not provided in headers.
371
- * Use getMarketHistory for public historical price data instead.
382
+ * Use fetchOHLCV for public historical price data instead.
372
383
  */
373
- async getTradeHistory(id, params) {
384
+ async fetchTrades(id, params) {
374
385
  // ID Validation
375
386
  if (id.length < 10 && /^\d+$/.test(id)) {
376
387
  throw new Error(`Invalid ID for Polymarket trades: "${id}". You provided a Market ID, but Polymarket's CLOB API requires a Token ID.`);
package/dist/index.d.ts CHANGED
@@ -2,3 +2,12 @@ export * from './BaseExchange';
2
2
  export * from './types';
3
3
  export * from './exchanges/Polymarket';
4
4
  export * from './exchanges/Kalshi';
5
+ import { PolymarketExchange } from './exchanges/Polymarket';
6
+ import { KalshiExchange } from './exchanges/Kalshi';
7
+ declare const pmxt: {
8
+ polymarket: typeof PolymarketExchange;
9
+ kalshi: typeof KalshiExchange;
10
+ Polymarket: typeof PolymarketExchange;
11
+ Kalshi: typeof KalshiExchange;
12
+ };
13
+ export default pmxt;
package/dist/index.js CHANGED
@@ -18,3 +18,12 @@ __exportStar(require("./BaseExchange"), exports);
18
18
  __exportStar(require("./types"), exports);
19
19
  __exportStar(require("./exchanges/Polymarket"), exports);
20
20
  __exportStar(require("./exchanges/Kalshi"), exports);
21
+ const Polymarket_1 = require("./exchanges/Polymarket");
22
+ const Kalshi_1 = require("./exchanges/Kalshi");
23
+ const pmxt = {
24
+ polymarket: Polymarket_1.PolymarketExchange,
25
+ kalshi: Kalshi_1.KalshiExchange,
26
+ Polymarket: Polymarket_1.PolymarketExchange,
27
+ Kalshi: Kalshi_1.KalshiExchange
28
+ };
29
+ exports.default = pmxt;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxtjs",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/readme.md CHANGED
@@ -54,33 +54,19 @@ Different prediction market platforms have different APIs, data formats, and con
54
54
 
55
55
  ## Quick Example
56
56
 
57
- Search for markets across Polymarket and Kalshi using the same API:
57
+ Get the current price for any market in seconds:
58
58
 
59
59
  ```typescript
60
- import { PolymarketExchange, KalshiExchange } from 'pmxtjs';
61
-
62
- const query = process.argv[2] || 'Who will Trump nominate as Fed Chair?';
63
- console.log(`Searching for "${query}"...\n`);
64
-
65
- // Polymarket
66
- const polymarket = new PolymarketExchange();
67
- const polyResults = await polymarket.searchMarkets(query, { sort: 'volume' });
68
-
69
- console.log(`--- Polymarket Found ${polyResults.length} ---`);
70
- polyResults.slice(0, 10).forEach(m => {
71
- const label = m.outcomes[0]?.label || 'Unknown';
72
- console.log(`[${m.id}] ${m.title} - ${label} (Vol24h: $${m.volume24h.toLocaleString()})`);
73
- });
74
-
75
- // Kalshi
76
- const kalshi = new KalshiExchange();
77
- const kalshiResults = await kalshi.searchMarkets(query);
78
-
79
- console.log(`\n--- Kalshi Found ${kalshiResults.length} ---`);
80
- kalshiResults.slice(0, 10).forEach(m => {
81
- const label = m.outcomes[0]?.label || 'Unknown';
82
- console.log(`[${m.id}] ${m.title} - ${label} (Vol24h: $${m.volume24h.toLocaleString()})`);
83
- });
60
+ import pmxt from 'pmxtjs';
61
+
62
+ async function main() {
63
+ const poly = new pmxt.polymarket();
64
+ const [market] = await poly.searchMarkets('Trump');
65
+
66
+ console.log(`${market.title} - ${market.outcomes[0].label}: ${marketoutcomes[0].price * 100}%`);
67
+ }
68
+
69
+ main();
84
70
  ```
85
71
 
86
72
  ## Installation