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 +18 -21
- package/dist/index.cjs +35 -32
- package/dist/index.d.ts +40 -22
- package/dist/index.js +35 -32
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# predimarkets
|
|
2
2
|
|
|
3
|
-
Official TypeScript client for the [Predimarkets](https://predimarkets.com) API —
|
|
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.
|
|
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
|
|
50
|
-
|
|
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
|
-
##
|
|
55
|
+
## Bets
|
|
58
56
|
|
|
59
|
-
|
|
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
|
-
|
|
65
|
+
Quote first if you want to show the user what they stand to win:
|
|
69
66
|
|
|
70
67
|
```ts
|
|
71
|
-
await client.
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
##
|
|
80
|
+
## Markets with more than two outcomes
|
|
81
|
+
|
|
82
|
+
Pass `multiOutcome`:
|
|
85
83
|
|
|
86
84
|
```ts
|
|
87
|
-
const state = await client.
|
|
88
|
-
await client.
|
|
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
|
|
94
|
-
|
|
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',
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
|
192
|
+
* Place a bet.
|
|
191
193
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
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
|
|
244
|
+
class Quotes {
|
|
243
245
|
client;
|
|
244
246
|
constructor(client) {
|
|
245
247
|
this.client = client;
|
|
246
248
|
}
|
|
247
|
-
/**
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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.
|
|
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
|
-
*
|
|
101
|
-
* debited and staked 1:1, with no
|
|
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
|
-
/**
|
|
105
|
+
/** Legacy share-based markets only. Prefer `amount`. */
|
|
105
106
|
quantity?: number;
|
|
106
|
-
/**
|
|
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
|
-
/**
|
|
116
|
-
|
|
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
|
|
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
|
|
178
|
+
* Place a bet.
|
|
168
179
|
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
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
|
|
204
|
+
declare class Quotes {
|
|
194
205
|
private readonly client;
|
|
195
206
|
constructor(client: Predimarkets);
|
|
196
|
-
/**
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
|
215
|
+
declare class MarketState {
|
|
202
216
|
private readonly client;
|
|
203
|
-
readonly categorical: CategoricalParimutuel;
|
|
204
217
|
constructor(client: Predimarkets);
|
|
205
|
-
/**
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
|
187
|
+
* Place a bet.
|
|
186
188
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
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
|
|
239
|
+
class Quotes {
|
|
238
240
|
client;
|
|
239
241
|
constructor(client) {
|
|
240
242
|
this.client = client;
|
|
241
243
|
}
|
|
242
|
-
/**
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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.
|
|
4
|
-
"description": "Official TypeScript client for the Predimarkets API \u2014
|
|
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",
|