@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.
Files changed (2) hide show
  1. package/README.md +341 -16
  2. 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', // or 'baseSepolia' for testnet
23
+ chain: 'base',
19
24
  })
20
25
 
21
- // List open markets
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: '0x...',
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: '0x...',
46
+ market: markets[0].address,
34
47
  side: 'yes',
35
48
  usdcAmount: 10_000_000n,
36
- signer: walletClient,
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
- // Build raw call data for smart wallet batching
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
- Builders earn **0.25%** of every bet placed through their integration, carved from the existing 2% protocol fee. Register at [markit.market/builders](https://markit.market/builders).
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 stats |
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
- ### Namespaces
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
- - **`markit.markets`** `list()`, `get()`, `getPrice()`, `getQuote()`, `getLiveScores()`
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markit.market/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "TypeScript SDK for MarkIt prediction markets on Base",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",