@markit.market/sdk 0.1.0 → 0.1.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/README.md +341 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
# @markit/sdk
|
|
1
|
+
# @markit.market/sdk
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for [MarkIt](https://markit.market) prediction markets on Base.
|
|
4
4
|
|
|
5
|
+
Builders earn **0.25%** of every bet placed through their integration, carved from the existing 2% protocol fee. Zero cost to users.
|
|
6
|
+
|
|
5
7
|
## Install
|
|
6
8
|
|
|
7
9
|
```bash
|
|
@@ -12,41 +14,90 @@ npm install @markit.market/sdk viem
|
|
|
12
14
|
|
|
13
15
|
```ts
|
|
14
16
|
import { createMarkitClient } from '@markit.market/sdk'
|
|
17
|
+
import { createWalletClient, http } from 'viem'
|
|
18
|
+
import { base } from 'viem/chains'
|
|
19
|
+
import { privateKeyToAccount } from 'viem/accounts'
|
|
15
20
|
|
|
16
21
|
const markit = createMarkitClient({
|
|
17
22
|
builderCode: 'your-builder-code',
|
|
18
|
-
chain: 'base',
|
|
23
|
+
chain: 'base',
|
|
19
24
|
})
|
|
20
25
|
|
|
21
|
-
//
|
|
26
|
+
// Browse open markets
|
|
22
27
|
const markets = await markit.markets.list({ state: 'open' })
|
|
28
|
+
console.log(markets[0].question) // "Will the Lakers beat the Celtics?"
|
|
29
|
+
console.log(markets[0].yesPrice) // "0.65" (65 cents)
|
|
23
30
|
|
|
24
|
-
// Get a quote
|
|
31
|
+
// Get a quote before betting
|
|
25
32
|
const quote = await markit.markets.getQuote({
|
|
26
|
-
market:
|
|
33
|
+
market: markets[0].address,
|
|
27
34
|
side: 'yes',
|
|
28
35
|
usdcAmount: 10_000_000n, // $10 USDC (6 decimals)
|
|
29
36
|
})
|
|
37
|
+
console.log(quote.sharesOut) // shares you'd receive
|
|
38
|
+
console.log(quote.effectivePrice) // effective price per share
|
|
39
|
+
console.log(quote.totalFee) // total fees in USDC
|
|
40
|
+
|
|
41
|
+
// Place the bet
|
|
42
|
+
const account = privateKeyToAccount('0x...')
|
|
43
|
+
const signer = createWalletClient({ account, chain: base, transport: http() })
|
|
30
44
|
|
|
31
|
-
// Place a bet (requires a viem wallet client)
|
|
32
45
|
const result = await markit.trade.placeBet({
|
|
33
|
-
market:
|
|
46
|
+
market: markets[0].address,
|
|
34
47
|
side: 'yes',
|
|
35
48
|
usdcAmount: 10_000_000n,
|
|
36
|
-
signer
|
|
49
|
+
signer,
|
|
37
50
|
})
|
|
51
|
+
console.log(result.txHash) // transaction hash
|
|
52
|
+
console.log(result.attributed) // true if builder fee was credited
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Smart Wallet Integration
|
|
56
|
+
|
|
57
|
+
For Coinbase Smart Wallet, Safe, or other batching wallets, use `buildPlaceBetCalls()` to get raw calldata:
|
|
38
58
|
|
|
39
|
-
|
|
59
|
+
```ts
|
|
40
60
|
const calls = markit.trade.buildPlaceBetCalls({
|
|
41
61
|
market: '0x...',
|
|
42
62
|
side: 'yes',
|
|
43
63
|
usdcAmount: 10_000_000n,
|
|
44
64
|
})
|
|
65
|
+
// calls = [
|
|
66
|
+
// { to: USDC_ADDRESS, data: '0x...' }, // approve
|
|
67
|
+
// { to: MARKET_ADDRESS, data: '0x...' }, // placeBet
|
|
68
|
+
// ]
|
|
69
|
+
|
|
70
|
+
// Send via your smart wallet's batch method
|
|
71
|
+
await smartWallet.sendCalls(calls)
|
|
72
|
+
|
|
73
|
+
// Then report attribution separately so you earn the builder fee
|
|
74
|
+
await markit.trade.reportAttribution({
|
|
75
|
+
market: '0x...',
|
|
76
|
+
txHash: '0x...',
|
|
77
|
+
bettor: '0x...',
|
|
78
|
+
})
|
|
45
79
|
```
|
|
46
80
|
|
|
47
81
|
## Builder Codes
|
|
48
82
|
|
|
49
|
-
|
|
83
|
+
Register at [markit.market/builders](https://markit.market/builders) to get your builder code and API key.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
const markit = createMarkitClient({
|
|
87
|
+
builderCode: 'your-code',
|
|
88
|
+
apiKey: 'mk_live_...', // from registration — needed for stats
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// View your earnings
|
|
92
|
+
const stats = await markit.builder.getStats()
|
|
93
|
+
console.log(stats.totalVolume) // total bet volume through your integration
|
|
94
|
+
console.log(stats.totalFees) // total fees earned (USD)
|
|
95
|
+
console.log(stats.unpaidFees) // fees pending payout
|
|
96
|
+
console.log(stats.uniqueUsers) // unique bettors
|
|
97
|
+
|
|
98
|
+
// Per-bet fee history
|
|
99
|
+
const fees = await markit.builder.getFeeHistory({ limit: 20 })
|
|
100
|
+
```
|
|
50
101
|
|
|
51
102
|
## API Reference
|
|
52
103
|
|
|
@@ -57,14 +108,288 @@ Builders earn **0.25%** of every bet placed through their integration, carved fr
|
|
|
57
108
|
| `builderCode` | `string` | *required* | Your registered builder code |
|
|
58
109
|
| `chain` | `'base' \| 'baseSepolia'` | `'base'` | Target chain |
|
|
59
110
|
| `rpcUrl` | `string` | Public RPC | Custom RPC endpoint |
|
|
60
|
-
| `apiKey` | `string` | — | API key for builder
|
|
111
|
+
| `apiKey` | `string` | — | API key for `builder.getStats()` and `builder.getFeeHistory()` |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### `markit.markets`
|
|
116
|
+
|
|
117
|
+
#### `list(options?)`
|
|
118
|
+
|
|
119
|
+
List markets from the MarkIt indexer.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
const markets = await markit.markets.list({
|
|
123
|
+
state: 'open', // 'open' | 'closeOnly' | 'resolved' | 'all'
|
|
124
|
+
sport: 'nba', // 'nba' | 'ncaab' | 'all'
|
|
125
|
+
limit: 20,
|
|
126
|
+
})
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Returns `MarketSummary[]`:
|
|
130
|
+
|
|
131
|
+
| Field | Type | Description |
|
|
132
|
+
|-------|------|-------------|
|
|
133
|
+
| `address` | `Address` | Market contract address |
|
|
134
|
+
| `question` | `string` | e.g. "Will the Lakers beat the Celtics?" |
|
|
135
|
+
| `slug` | `string \| null` | URL slug, e.g. `lakers-at-celtics-mar-17` |
|
|
136
|
+
| `state` | `number` | 0=Created, 1=Funded, 2=Open, 3=CloseOnly, 4=Resolved, 5=Withdrawable |
|
|
137
|
+
| `outcome` | `number` | 0=None, 1=Yes, 2=No |
|
|
138
|
+
| `sport` | `string` | `'nba'` or `'ncaab'` |
|
|
139
|
+
| `yesPrice` | `string` | Current YES price (0-1) |
|
|
140
|
+
| `noPrice` | `string` | Current NO price (0-1) |
|
|
141
|
+
| `yesLiability` | `string` | Total YES payouts owed (WAD) |
|
|
142
|
+
| `noLiability` | `string` | Total NO payouts owed (WAD) |
|
|
143
|
+
| `engineUsdc` | `string` | USDC balance in contract (6 decimals) |
|
|
144
|
+
| `bettingCloseTime` | `number` | Unix timestamp when betting closes |
|
|
145
|
+
| `resolveTime` | `number` | Unix timestamp when market resolves |
|
|
146
|
+
| `homeLogoUrl` | `string \| null` | ESPN team logo URL |
|
|
147
|
+
| `awayLogoUrl` | `string \| null` | ESPN team logo URL |
|
|
148
|
+
|
|
149
|
+
#### `get(slugOrAddress)`
|
|
150
|
+
|
|
151
|
+
Get full market details by address or slug.
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const market = await markit.markets.get('lakers-at-celtics-mar-17')
|
|
155
|
+
// or
|
|
156
|
+
const market = await markit.markets.get('0x1234...')
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Returns `MarketDetail` (extends `MarketSummary` with LP parameters, fees, seed imbalance).
|
|
160
|
+
|
|
161
|
+
#### `getPrice(market)`
|
|
61
162
|
|
|
62
|
-
|
|
163
|
+
Get live on-chain mark prices (reads directly from the contract via RPC).
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
const price = await markit.markets.getPrice('0x...')
|
|
167
|
+
console.log(price.yes) // 0.65
|
|
168
|
+
console.log(price.no) // 0.35
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### `getQuote({ market, side, usdcAmount })`
|
|
172
|
+
|
|
173
|
+
Simulate a bet and get a detailed fee breakdown.
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const quote = await markit.markets.getQuote({
|
|
177
|
+
market: '0x...',
|
|
178
|
+
side: 'yes',
|
|
179
|
+
usdcAmount: 50_000_000n, // $50
|
|
180
|
+
})
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Returns `BetQuote`:
|
|
184
|
+
|
|
185
|
+
| Field | Type | Description |
|
|
186
|
+
|-------|------|-------------|
|
|
187
|
+
| `sharesOut` | `string` | Shares you'd receive (WAD, 18 decimals) |
|
|
188
|
+
| `avgPrice` | `string` | Average price per share |
|
|
189
|
+
| `priceImpact` | `string` | Price impact as a decimal (0.01 = 1%) |
|
|
190
|
+
| `lpFee` | `string` | LP fee in USDC (6 decimals) |
|
|
191
|
+
| `protocolFee` | `string` | Protocol fee in USDC (6 decimals) |
|
|
192
|
+
| `builderFee` | `string` | Builder fee in USDC (6 decimals) |
|
|
193
|
+
| `totalFee` | `string` | Total fees in USDC (6 decimals) |
|
|
194
|
+
| `effectivePrice` | `string` | Effective price per share after fees |
|
|
195
|
+
|
|
196
|
+
#### `getLiveScores()`
|
|
197
|
+
|
|
198
|
+
Get ESPN live scores matched to MarkIt markets.
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
const scores = await markit.markets.getLiveScores()
|
|
202
|
+
// [{ homeTeam: "Lakers", awayTeam: "Celtics", homeScore: 98, awayScore: 95, status: "in_progress", period: "4th", clock: "2:15" }]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
### `markit.trade`
|
|
208
|
+
|
|
209
|
+
#### `placeBet({ market, side, usdcAmount, signer, minSharesOut? })`
|
|
210
|
+
|
|
211
|
+
Full flow: checks USDC allowance, approves if needed, places the bet, reports builder attribution.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
const result = await markit.trade.placeBet({
|
|
215
|
+
market: '0x...',
|
|
216
|
+
side: 'yes',
|
|
217
|
+
usdcAmount: 10_000_000n, // $10 USDC
|
|
218
|
+
minSharesOut: 9_000_000_000n, // optional: slippage protection
|
|
219
|
+
signer: walletClient,
|
|
220
|
+
})
|
|
221
|
+
// { txHash: '0x...', attributed: true }
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
- `signer` must be a [viem WalletClient](https://viem.sh/docs/clients/wallet) with an `account`
|
|
225
|
+
- Attribution is fire-and-forget — the bet succeeds even if attribution fails
|
|
226
|
+
- USDC uses 6 decimals: `$1 = 1_000_000n`, `$10 = 10_000_000n`, `$100 = 100_000_000n`
|
|
227
|
+
|
|
228
|
+
#### `buildPlaceBetCalls({ market, side, usdcAmount, minSharesOut? })`
|
|
229
|
+
|
|
230
|
+
Returns raw `{ to, data }` call objects for smart wallet batching. Does not send any transactions.
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
const calls = markit.trade.buildPlaceBetCalls({
|
|
234
|
+
market: '0x...',
|
|
235
|
+
side: 'no',
|
|
236
|
+
usdcAmount: 25_000_000n,
|
|
237
|
+
})
|
|
238
|
+
// Returns: [approveCall, placeBetCall]
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
After sending via your smart wallet, call `reportAttribution()` to credit the builder fee.
|
|
242
|
+
|
|
243
|
+
#### `reportAttribution({ market, txHash, bettor })`
|
|
244
|
+
|
|
245
|
+
Report a bet for builder fee attribution. Called automatically by `placeBet()`, but must be called manually when using `buildPlaceBetCalls()`.
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
const ok = await markit.trade.reportAttribution({
|
|
249
|
+
market: '0x...',
|
|
250
|
+
txHash: '0x...',
|
|
251
|
+
bettor: '0x...',
|
|
252
|
+
})
|
|
253
|
+
// true if attribution was accepted
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
#### `getPositions(user)`
|
|
257
|
+
|
|
258
|
+
Get a user's open positions across all markets.
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
const positions = await markit.trade.getPositions('0x...')
|
|
262
|
+
// [{ market: '0x...', yesShares: 15000000000000000000n, noShares: 0n }]
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### `markit.vault`
|
|
268
|
+
|
|
269
|
+
The LP vault underwrites all markets. Depositors earn fees from every bet.
|
|
270
|
+
|
|
271
|
+
#### `getState()`
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
const vault = await markit.vault.getState()
|
|
275
|
+
console.log(vault.nav) // total NAV in USDC (6 decimals)
|
|
276
|
+
console.log(vault.sharePrice) // price per share (WAD)
|
|
277
|
+
console.log(vault.float) // undeployed USDC (6 decimals)
|
|
278
|
+
console.log(vault.activeMarketCount) // number of live markets
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### `getUserPosition(user)`
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
const pos = await markit.vault.getUserPosition('0x...')
|
|
285
|
+
console.log(pos.shares) // vault shares (WAD)
|
|
286
|
+
console.log(pos.value) // current USDC value (6 decimals)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
#### `deposit({ usdcAmount, signer })`
|
|
290
|
+
|
|
291
|
+
Deposit USDC into the vault. Handles approval automatically.
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
const txHash = await markit.vault.deposit({
|
|
295
|
+
usdcAmount: 1_000_000_000n, // $1,000
|
|
296
|
+
signer: walletClient,
|
|
297
|
+
})
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
#### `requestWithdrawal({ shares, signer })`
|
|
301
|
+
|
|
302
|
+
Request a withdrawal from the vault (enters FIFO queue).
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
const txHash = await markit.vault.requestWithdrawal({
|
|
306
|
+
shares: 500_000_000_000_000_000_000n, // 500 shares (WAD)
|
|
307
|
+
signer: walletClient,
|
|
308
|
+
})
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
### `markit.builder`
|
|
314
|
+
|
|
315
|
+
Requires `apiKey` in client config (received during registration at `/builders`).
|
|
316
|
+
|
|
317
|
+
#### `getStats()`
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
const stats = await markit.builder.getStats()
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Returns `BuilderStats`:
|
|
324
|
+
|
|
325
|
+
| Field | Type | Description |
|
|
326
|
+
|-------|------|-------------|
|
|
327
|
+
| `totalVolume` | `number` | All-time bet volume (USD) |
|
|
328
|
+
| `totalFees` | `number` | All-time builder fees earned (USD) |
|
|
329
|
+
| `totalBets` | `number` | Total bets attributed |
|
|
330
|
+
| `uniqueUsers` | `number` | Unique bettors |
|
|
331
|
+
| `unpaidFees` | `number` | Fees pending payout (USD) |
|
|
332
|
+
| `last30dVolume` | `number` | 30-day rolling volume |
|
|
333
|
+
| `last30dFees` | `number` | 30-day rolling fees |
|
|
334
|
+
|
|
335
|
+
#### `getFeeHistory({ limit? })`
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
const fees = await markit.builder.getFeeHistory({ limit: 50 })
|
|
339
|
+
// [{ market, bettor, usdcBet, builderFee, txHash, createdAt, paidAt }]
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Error Handling
|
|
345
|
+
|
|
346
|
+
All SDK errors throw `MarkitError` with a typed `code`:
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
import { MarkitError, ErrorCode } from '@markit.market/sdk'
|
|
350
|
+
|
|
351
|
+
try {
|
|
352
|
+
await markit.trade.placeBet({ ... })
|
|
353
|
+
} catch (err) {
|
|
354
|
+
if (err instanceof MarkitError) {
|
|
355
|
+
switch (err.code) {
|
|
356
|
+
case ErrorCode.TX_REJECTED: // user rejected in wallet
|
|
357
|
+
case ErrorCode.INSUFFICIENT_USDC: // not enough USDC balance
|
|
358
|
+
case ErrorCode.BET_TOO_SMALL: // below minimum bet
|
|
359
|
+
case ErrorCode.SKEW_CAP_EXCEEDED: // market too skewed
|
|
360
|
+
case ErrorCode.MARKET_NOT_OPEN: // market not accepting bets
|
|
361
|
+
case ErrorCode.TX_REVERTED: // on-chain revert
|
|
362
|
+
case ErrorCode.NETWORK_ERROR: // RPC/fetch failure
|
|
363
|
+
case ErrorCode.INVALID_PARAMS: // bad input
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## USDC Amounts
|
|
370
|
+
|
|
371
|
+
USDC uses 6 decimals. Common values:
|
|
372
|
+
|
|
373
|
+
| Amount | BigInt |
|
|
374
|
+
|--------|--------|
|
|
375
|
+
| $0.01 | `10_000n` |
|
|
376
|
+
| $1 | `1_000_000n` |
|
|
377
|
+
| $10 | `10_000_000n` |
|
|
378
|
+
| $100 | `100_000_000n` |
|
|
379
|
+
| $1,000 | `1_000_000_000n` |
|
|
380
|
+
|
|
381
|
+
## Testnet
|
|
382
|
+
|
|
383
|
+
Use Base Sepolia for development:
|
|
384
|
+
|
|
385
|
+
```ts
|
|
386
|
+
const markit = createMarkitClient({
|
|
387
|
+
builderCode: 'your-code',
|
|
388
|
+
chain: 'baseSepolia',
|
|
389
|
+
})
|
|
390
|
+
```
|
|
63
391
|
|
|
64
|
-
|
|
65
|
-
- **`markit.trade`** — `placeBet()`, `buildPlaceBetCalls()`, `reportAttribution()`, `getPositions()`
|
|
66
|
-
- **`markit.vault`** — `getState()`, `getUserPosition()`, `deposit()`, `requestWithdrawal()`
|
|
67
|
-
- **`markit.builder`** — `getStats()`, `getFeeHistory()`
|
|
392
|
+
Testnet USDC can be minted freely via the MockUSDC contract.
|
|
68
393
|
|
|
69
394
|
## Requirements
|
|
70
395
|
|