predimarkets 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # predimarkets
2
2
 
3
- Official TypeScript client for the [Predimarkets](https://predimarkets.com) API — matching, oracle resolution and settlement for prediction markets.
3
+ Official TypeScript client for the [Predimarkets](https://predimarkets.com) API — markets, bets, settlement and webhooks for prediction markets.
4
4
 
5
5
  Zero runtime dependencies. Runs on Node 18+, Bun, Deno and Cloudflare Workers.
6
6
 
@@ -19,7 +19,7 @@ const { markets } = await client.markets.list({ status: 'open' });
19
19
  const market = markets[0];
20
20
 
21
21
  // Price the bet before you place it.
22
- const quote = await client.parimutuel.quote({
22
+ const quote = await client.quotes.get({
23
23
  marketId: market.id,
24
24
  outcomeId: market.outcomes[0].id,
25
25
  stake: 100,
@@ -43,21 +43,18 @@ user placing the bet. Keep the key server-side — it must never reach a browser
43
43
  await client.markets.list({ status: 'open', limit: 20 });
44
44
  await client.markets.get('will-france-win-the-world-cup-2026'); // id or slug
45
45
  await client.markets.priceHistory(market.id, { timeframe: '1D' });
46
- await client.markets.orderBook(market.id);
47
46
  ```
48
47
 
49
- Search is semantic, not just keyword — queries are ranked by embedding similarity
50
- fused with full-text, so a question finds the market that answers it even when
51
- they share no words:
48
+ Search is semantic, not just keyword — queries are ranked by meaning, so a
49
+ question finds the market that answers it even when they share no words:
52
50
 
53
51
  ```ts
54
52
  await client.markets.search('who wants to be president');
55
53
  ```
56
54
 
57
- ## Orders
55
+ ## Bets
58
56
 
59
- Parimutuel markets take an `amount` the money the user is staking, debited and
60
- staked 1:1, with no share price to reason about:
57
+ `amount` is the money the user is staking. That is all a market needs:
61
58
 
62
59
  ```ts
63
60
  await client.orders.create({
@@ -65,13 +62,12 @@ await client.orders.create({
65
62
  });
66
63
  ```
67
64
 
68
- Order-book markets take a `quantity`, plus a `price` for limit orders:
65
+ Quote first if you want to show the user what they stand to win:
69
66
 
70
67
  ```ts
71
- await client.orders.create({
72
- marketId, outcomeId, userId: 'user-123',
73
- side: 'buy', type: 'limit', quantity: 1000, price: 0.65,
74
- });
68
+ const quote = await client.quotes.get({ marketId, outcomeId, stake: 100 });
69
+ // quote.multiplier the return they lock in
70
+ // quote.estimated_payout what they take home if it hits
75
71
  ```
76
72
 
77
73
  ## Positions and trades
@@ -81,18 +77,19 @@ await client.positions.list({ userId: 'user-123' });
81
77
  await client.trades.list({ userId: 'user-123', limit: 50 });
82
78
  ```
83
79
 
84
- ## Multi-outcome markets
80
+ ## Markets with more than two outcomes
81
+
82
+ Pass `multiOutcome`:
85
83
 
86
84
  ```ts
87
- const state = await client.parimutuel.categorical.state(marketId);
88
- await client.parimutuel.categorical.quote({ marketId, outcomeId, stake: 50 });
85
+ const state = await client.marketState.get(marketId, { multiOutcome: true });
86
+ const quote = await client.quotes.get({ marketId, outcomeId, stake: 50, multiOutcome: true });
89
87
  ```
90
88
 
91
89
  An outcome that is out of the running (knocked out, lost) comes back with
92
90
  `eliminated: true` and takes no new bets — the API rejects them with
93
- `OUTCOME_ELIMINATED`. Render it as dead rather than hiding it: its share of the
94
- pool is real, so the remaining outcomes' percentages will not add to 100 without
95
- it.
91
+ `OUTCOME_ELIMINATED`. Render it as dead rather than hiding it, so the remaining
92
+ outcomes' percentages still add up for the user.
96
93
 
97
94
  ## Webhooks
98
95
 
@@ -148,7 +145,7 @@ try {
148
145
  handling already applied:
149
146
 
150
147
  ```ts
151
- await client.request('GET', '/markets/:id/milestone-live'.replace(':id', marketId));
148
+ await client.request('GET', `/markets/${marketId}/milestone-live`);
152
149
  ```
153
150
 
154
151
  ## License
package/dist/index.cjs CHANGED
@@ -22,7 +22,7 @@
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.Webhooks = exports.SIGNATURE_HEADER = exports.Predimarkets = exports.PredimarketsError = exports.VERSION = void 0;
25
- exports.VERSION = '0.1.0';
25
+ exports.VERSION = '0.2.0';
26
26
  const DEFAULT_BASE_URL = 'https://api.predimarkets.com';
27
27
  const DEFAULT_TIMEOUT_MS = 30_000;
28
28
  // ─────────────────────────────────────────────────────────────────────────────
@@ -58,7 +58,8 @@ class Predimarkets {
58
58
  orders;
59
59
  positions;
60
60
  trades;
61
- parimutuel;
61
+ quotes;
62
+ marketState;
62
63
  webhooks;
63
64
  apiKey;
64
65
  baseUrl;
@@ -80,7 +81,8 @@ class Predimarkets {
80
81
  this.orders = new Orders(this);
81
82
  this.positions = new Positions(this);
82
83
  this.trades = new Trades(this);
83
- this.parimutuel = new Parimutuel(this);
84
+ this.quotes = new Quotes(this);
85
+ this.marketState = new MarketState(this);
84
86
  this.webhooks = new Webhooks();
85
87
  }
86
88
  /** Escape hatch: call any endpoint the SDK doesn't wrap yet. */
@@ -187,10 +189,10 @@ class Orders {
187
189
  this.client = client;
188
190
  }
189
191
  /**
190
- * Place an order.
192
+ * Place a bet.
191
193
  *
192
- * For parimutuel markets pass `amount` (the money staked). For order-book
193
- * markets pass `quantity`, plus `price` when `type` is 'limit'.
194
+ * Pass `amount` the money the user is staking. That is all a live market
195
+ * needs; `quantity`/`price` exist only for legacy share-based markets.
194
196
  */
195
197
  create(params) {
196
198
  return this.client.request('POST', '/orders', {
@@ -239,44 +241,45 @@ class Trades {
239
241
  });
240
242
  }
241
243
  }
242
- class CategoricalParimutuel {
244
+ class Quotes {
243
245
  client;
244
246
  constructor(client) {
245
247
  this.client = client;
246
248
  }
247
- /** Price a stake on one outcome of a multi-outcome market, before placing it. */
248
- quote(params) {
249
- return this.client.request('GET', '/parimutuel-categorical/quote', {
250
- query: { market_id: params.marketId, outcome_id: params.outcomeId, stake: params.stake },
251
- });
252
- }
253
- /** Live pool state: per-outcome pool, probability and multiplier. */
254
- state(marketIdOrSlug) {
255
- return this.client.request('GET', `/parimutuel-categorical/markets/${encodeURIComponent(marketIdOrSlug)}`);
256
- }
257
- }
258
- class Parimutuel {
259
- client;
260
- categorical;
261
- constructor(client) {
262
- this.client = client;
263
- this.categorical = new CategoricalParimutuel(client);
264
- }
265
- /** Price a stake before placing it: fee, locked multiplier, estimated payout. */
266
- quote(params) {
267
- return this.client.request('GET', '/parimutuel/quote', {
249
+ /**
250
+ * Price a stake before it is placed: the fee, the return the user locks in, and
251
+ * what they would take home if the outcome hits.
252
+ *
253
+ * Set `multiOutcome` for markets with more than two runners.
254
+ */
255
+ get(params) {
256
+ const path = params.multiOutcome
257
+ ? '/parimutuel-categorical/quote'
258
+ : '/parimutuel/quote';
259
+ return this.client.request('GET', path, {
268
260
  query: {
269
261
  market_id: params.marketId,
270
262
  outcome_id: params.outcomeId,
271
263
  stake: params.stake,
272
- side: params.side,
273
264
  },
274
265
  });
275
266
  }
276
- /** Live pool state for a binary parimutuel market. */
277
- state(marketIdOrSlug) {
278
- return this.client.request('GET', `/parimutuel/markets/${encodeURIComponent(marketIdOrSlug)}`);
267
+ }
268
+ class MarketState {
269
+ client;
270
+ constructor(client) {
271
+ this.client = client;
272
+ }
273
+ /**
274
+ * Live state of a market: the current price and return on every outcome.
275
+ *
276
+ * Set `multiOutcome` for markets with more than two runners.
277
+ */
278
+ get(marketIdOrSlug, options = {}) {
279
+ const base = options.multiOutcome ? '/parimutuel-categorical' : '/parimutuel';
280
+ return this.client.request('GET', `${base}/markets/${encodeURIComponent(marketIdOrSlug)}`);
279
281
  }
282
+ /** What a user's open ticket is worth right now. */
280
283
  ticketValue(marketIdOrSlug, ticketId) {
281
284
  return this.client.request('GET', `/parimutuel/markets/${encodeURIComponent(marketIdOrSlug)}/tickets/${encodeURIComponent(ticketId)}/value`);
282
285
  }
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  * amount: 100,
20
20
  * });
21
21
  */
22
- export declare const VERSION = "0.1.0";
22
+ export declare const VERSION = "0.2.0";
23
23
  /**
24
24
  * Any non-2xx response from the API.
25
25
  *
@@ -97,13 +97,14 @@ export interface CreateOrderParams {
97
97
  side?: OrderSide;
98
98
  type?: OrderType;
99
99
  /**
100
- * Parimutuel: the amount of money the user is staking. Preferred it is
101
- * debited and staked 1:1, with no separate share price to reason about.
100
+ * The amount of money the user is staking. This is what you want for every
101
+ * live market: it is debited and staked 1:1, with no share price to reason
102
+ * about.
102
103
  */
103
104
  amount?: number;
104
- /** Order book: number of shares. */
105
+ /** Legacy share-based markets only. Prefer `amount`. */
105
106
  quantity?: number;
106
- /** Order book limit orders: price per share, 0–1. */
107
+ /** Legacy share-based limit orders only: price per share, 0–1. */
107
108
  price?: number;
108
109
  /** Hard cap on total spend including fees. Buy orders only. */
109
110
  maxSpend?: number;
@@ -111,16 +112,26 @@ export interface CreateOrderParams {
111
112
  export interface QuoteParams {
112
113
  marketId: string;
113
114
  outcomeId: string;
115
+ /** How much money the user wants to stake. */
114
116
  stake: number;
115
- /** Binary parimutuel only. */
116
- side?: 'yes' | 'no';
117
+ /** True for markets with more than two runners. */
118
+ multiOutcome?: boolean;
119
+ }
120
+ export interface Quote {
121
+ /** What the user takes home if this outcome hits. */
122
+ estimated_payout?: number;
123
+ /** The return locked in at the moment the bet is placed. */
124
+ multiplier?: number;
125
+ fee?: number;
126
+ [key: string]: unknown;
117
127
  }
118
128
  export declare class Predimarkets {
119
129
  readonly markets: Markets;
120
130
  readonly orders: Orders;
121
131
  readonly positions: Positions;
122
132
  readonly trades: Trades;
123
- readonly parimutuel: Parimutuel;
133
+ readonly quotes: Quotes;
134
+ readonly marketState: MarketState;
124
135
  readonly webhooks: Webhooks;
125
136
  private readonly apiKey;
126
137
  private readonly baseUrl;
@@ -164,10 +175,10 @@ declare class Orders {
164
175
  private readonly client;
165
176
  constructor(client: Predimarkets);
166
177
  /**
167
- * Place an order.
178
+ * Place a bet.
168
179
  *
169
- * For parimutuel markets pass `amount` (the money staked). For order-book
170
- * markets pass `quantity`, plus `price` when `type` is 'limit'.
180
+ * Pass `amount` the money the user is staking. That is all a live market
181
+ * needs; `quantity`/`price` exist only for legacy share-based markets.
171
182
  */
172
183
  create(params: CreateOrderParams): Promise<unknown>;
173
184
  }
@@ -190,22 +201,29 @@ declare class Trades {
190
201
  offset?: number;
191
202
  }): Promise<unknown>;
192
203
  }
193
- declare class CategoricalParimutuel {
204
+ declare class Quotes {
194
205
  private readonly client;
195
206
  constructor(client: Predimarkets);
196
- /** Price a stake on one outcome of a multi-outcome market, before placing it. */
197
- quote(params: QuoteParams): Promise<unknown>;
198
- /** Live pool state: per-outcome pool, probability and multiplier. */
199
- state(marketIdOrSlug: string): Promise<unknown>;
207
+ /**
208
+ * Price a stake before it is placed: the fee, the return the user locks in, and
209
+ * what they would take home if the outcome hits.
210
+ *
211
+ * Set `multiOutcome` for markets with more than two runners.
212
+ */
213
+ get(params: QuoteParams): Promise<Quote>;
200
214
  }
201
- declare class Parimutuel {
215
+ declare class MarketState {
202
216
  private readonly client;
203
- readonly categorical: CategoricalParimutuel;
204
217
  constructor(client: Predimarkets);
205
- /** Price a stake before placing it: fee, locked multiplier, estimated payout. */
206
- quote(params: QuoteParams): Promise<unknown>;
207
- /** Live pool state for a binary parimutuel market. */
208
- state(marketIdOrSlug: string): Promise<unknown>;
218
+ /**
219
+ * Live state of a market: the current price and return on every outcome.
220
+ *
221
+ * Set `multiOutcome` for markets with more than two runners.
222
+ */
223
+ get(marketIdOrSlug: string, options?: {
224
+ multiOutcome?: boolean;
225
+ }): Promise<unknown>;
226
+ /** What a user's open ticket is worth right now. */
209
227
  ticketValue(marketIdOrSlug: string, ticketId: string): Promise<unknown>;
210
228
  }
211
229
  /** Header Predimarkets signs every webhook with. */
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * amount: 100,
20
20
  * });
21
21
  */
22
- export const VERSION = '0.1.0';
22
+ export const VERSION = '0.2.0';
23
23
  const DEFAULT_BASE_URL = 'https://api.predimarkets.com';
24
24
  const DEFAULT_TIMEOUT_MS = 30_000;
25
25
  // ─────────────────────────────────────────────────────────────────────────────
@@ -54,7 +54,8 @@ export class Predimarkets {
54
54
  orders;
55
55
  positions;
56
56
  trades;
57
- parimutuel;
57
+ quotes;
58
+ marketState;
58
59
  webhooks;
59
60
  apiKey;
60
61
  baseUrl;
@@ -76,7 +77,8 @@ export class Predimarkets {
76
77
  this.orders = new Orders(this);
77
78
  this.positions = new Positions(this);
78
79
  this.trades = new Trades(this);
79
- this.parimutuel = new Parimutuel(this);
80
+ this.quotes = new Quotes(this);
81
+ this.marketState = new MarketState(this);
80
82
  this.webhooks = new Webhooks();
81
83
  }
82
84
  /** Escape hatch: call any endpoint the SDK doesn't wrap yet. */
@@ -182,10 +184,10 @@ class Orders {
182
184
  this.client = client;
183
185
  }
184
186
  /**
185
- * Place an order.
187
+ * Place a bet.
186
188
  *
187
- * For parimutuel markets pass `amount` (the money staked). For order-book
188
- * markets pass `quantity`, plus `price` when `type` is 'limit'.
189
+ * Pass `amount` the money the user is staking. That is all a live market
190
+ * needs; `quantity`/`price` exist only for legacy share-based markets.
189
191
  */
190
192
  create(params) {
191
193
  return this.client.request('POST', '/orders', {
@@ -234,44 +236,45 @@ class Trades {
234
236
  });
235
237
  }
236
238
  }
237
- class CategoricalParimutuel {
239
+ class Quotes {
238
240
  client;
239
241
  constructor(client) {
240
242
  this.client = client;
241
243
  }
242
- /** Price a stake on one outcome of a multi-outcome market, before placing it. */
243
- quote(params) {
244
- return this.client.request('GET', '/parimutuel-categorical/quote', {
245
- query: { market_id: params.marketId, outcome_id: params.outcomeId, stake: params.stake },
246
- });
247
- }
248
- /** Live pool state: per-outcome pool, probability and multiplier. */
249
- state(marketIdOrSlug) {
250
- return this.client.request('GET', `/parimutuel-categorical/markets/${encodeURIComponent(marketIdOrSlug)}`);
251
- }
252
- }
253
- class Parimutuel {
254
- client;
255
- categorical;
256
- constructor(client) {
257
- this.client = client;
258
- this.categorical = new CategoricalParimutuel(client);
259
- }
260
- /** Price a stake before placing it: fee, locked multiplier, estimated payout. */
261
- quote(params) {
262
- return this.client.request('GET', '/parimutuel/quote', {
244
+ /**
245
+ * Price a stake before it is placed: the fee, the return the user locks in, and
246
+ * what they would take home if the outcome hits.
247
+ *
248
+ * Set `multiOutcome` for markets with more than two runners.
249
+ */
250
+ get(params) {
251
+ const path = params.multiOutcome
252
+ ? '/parimutuel-categorical/quote'
253
+ : '/parimutuel/quote';
254
+ return this.client.request('GET', path, {
263
255
  query: {
264
256
  market_id: params.marketId,
265
257
  outcome_id: params.outcomeId,
266
258
  stake: params.stake,
267
- side: params.side,
268
259
  },
269
260
  });
270
261
  }
271
- /** Live pool state for a binary parimutuel market. */
272
- state(marketIdOrSlug) {
273
- return this.client.request('GET', `/parimutuel/markets/${encodeURIComponent(marketIdOrSlug)}`);
262
+ }
263
+ class MarketState {
264
+ client;
265
+ constructor(client) {
266
+ this.client = client;
267
+ }
268
+ /**
269
+ * Live state of a market: the current price and return on every outcome.
270
+ *
271
+ * Set `multiOutcome` for markets with more than two runners.
272
+ */
273
+ get(marketIdOrSlug, options = {}) {
274
+ const base = options.multiOutcome ? '/parimutuel-categorical' : '/parimutuel';
275
+ return this.client.request('GET', `${base}/markets/${encodeURIComponent(marketIdOrSlug)}`);
274
276
  }
277
+ /** What a user's open ticket is worth right now. */
275
278
  ticketValue(marketIdOrSlug, ticketId) {
276
279
  return this.client.request('GET', `/parimutuel/markets/${encodeURIComponent(marketIdOrSlug)}/tickets/${encodeURIComponent(ticketId)}/value`);
277
280
  }
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "predimarkets",
3
- "version": "0.1.0",
4
- "description": "Official TypeScript client for the Predimarkets API \u2014 matching, oracle resolution and settlement for prediction markets.",
3
+ "version": "0.2.0",
4
+ "description": "Official TypeScript client for the Predimarkets API \u2014 markets, bets, settlement and webhooks for prediction markets.",
5
5
  "keywords": [
6
6
  "predimarkets",
7
7
  "prediction-markets",
8
- "parimutuel",
9
8
  "betting",
9
+ "markets",
10
10
  "sdk",
11
- "api-client"
11
+ "api-client",
12
+ "typescript"
12
13
  ],
13
14
  "homepage": "https://predimarkets.com",
14
15
  "license": "MIT",