@totalis/hip4-client 0.0.0-stage → 0.65.2

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 (74) hide show
  1. package/CHANGELOG.md +1541 -0
  2. package/LICENSE +202 -0
  3. package/README.md +143 -2
  4. package/dist/api-keys.d.ts +118 -0
  5. package/dist/api-keys.js +104 -0
  6. package/dist/audience-contract.d.ts +52 -0
  7. package/dist/audience-contract.js +1 -0
  8. package/dist/base.d.ts +41 -0
  9. package/dist/base.js +60 -0
  10. package/dist/client.d.ts +16 -0
  11. package/dist/client.js +15 -0
  12. package/dist/controller.d.ts +50 -0
  13. package/dist/controller.js +60 -0
  14. package/dist/errors.d.ts +3 -0
  15. package/dist/errors.js +3 -0
  16. package/dist/flow-errors.d.ts +61 -0
  17. package/dist/flow-errors.js +70 -0
  18. package/dist/generated/account-read.d.ts +2009 -0
  19. package/dist/generated/account-read.js +1 -0
  20. package/dist/generated/api-keys.d.ts +1303 -0
  21. package/dist/generated/api-keys.js +1 -0
  22. package/dist/generated/browse.d.ts +938 -0
  23. package/dist/generated/browse.js +1 -0
  24. package/dist/generated/client.d.ts +73 -0
  25. package/dist/generated/client.js +1 -0
  26. package/dist/generated/errors.d.ts +404 -0
  27. package/dist/generated/errors.js +1342 -0
  28. package/dist/generated/maker.d.ts +47 -0
  29. package/dist/generated/maker.js +1 -0
  30. package/dist/generated/openapi.d.ts +8044 -0
  31. package/dist/generated/openapi.js +1 -0
  32. package/dist/generated/operator.d.ts +7 -0
  33. package/dist/generated/operator.js +1 -0
  34. package/dist/generated/realtime.d.ts +1416 -0
  35. package/dist/generated/realtime.js +1 -0
  36. package/dist/generated/vault-abi.d.ts +39 -0
  37. package/dist/generated/vault-abi.js +56 -0
  38. package/dist/generated/version.d.ts +23 -0
  39. package/dist/generated/version.js +143 -0
  40. package/dist/hypercore.d.ts +111 -0
  41. package/dist/hypercore.js +132 -0
  42. package/dist/maker.d.ts +205 -0
  43. package/dist/maker.js +608 -0
  44. package/dist/money.d.ts +59 -0
  45. package/dist/money.js +66 -0
  46. package/dist/operator.d.ts +4 -0
  47. package/dist/operator.js +4 -0
  48. package/dist/pagination.d.ts +20 -0
  49. package/dist/pagination.js +27 -0
  50. package/dist/partner.d.ts +59 -0
  51. package/dist/partner.js +57 -0
  52. package/dist/realtime.d.ts +19 -0
  53. package/dist/realtime.js +10 -0
  54. package/dist/request.d.ts +112 -0
  55. package/dist/request.js +187 -0
  56. package/dist/signer.d.ts +51 -0
  57. package/dist/signer.js +90 -0
  58. package/dist/stream.d.ts +133 -0
  59. package/dist/stream.js +318 -0
  60. package/dist/totalis.d.ts +656 -0
  61. package/dist/totalis.js +1160 -0
  62. package/dist/typed-data.d.ts +330 -0
  63. package/dist/typed-data.js +340 -0
  64. package/dist/ui.d.ts +54 -0
  65. package/dist/ui.js +77 -0
  66. package/dist/wallet-session.d.ts +45 -0
  67. package/dist/wallet-session.js +61 -0
  68. package/examples/browser-wallet.html +69 -0
  69. package/examples/browser-wallet.mjs +57 -0
  70. package/examples/node-bot.mjs +57 -0
  71. package/examples/onboard.mjs +132 -0
  72. package/examples/partner-frontend.mjs +44 -0
  73. package/examples/partner-server.mjs +22 -0
  74. package/package.json +104 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,1541 @@
1
+ # Changelog
2
+
3
+ `@totalis/hip4-client` follows [semantic versioning](https://semver.org).
4
+ The contract version the generated types come from is `sdkVersion` in `./version`.
5
+
6
+ ## 0.65.2
7
+
8
+ The package is now `@totalis/hip4-client`, published to public npm. Install
9
+ it under the new name and change your imports from
10
+ `@totalistrading/hip4-client` to `@totalis/hip4-client`; nothing else
11
+ changes. 0.65.1 was tagged under the old name but never published.
12
+
13
+ ## 0.65.1
14
+
15
+ The first release on public npm (`registry.npmjs.org`), under Apache-2.0, with
16
+ no registry configuration or token needed. Remove any
17
+ `@totalistrading:registry=https://npm.pkg.github.com` line from your `.npmrc`.
18
+ The code is the same as 0.65.0; 0.65.0 and earlier stay on GitHub Packages.
19
+ The README is now a short overview; the full guide is at
20
+ [docs.totalis.trade/hyperliquid/sdk](https://docs.totalis.trade/hyperliquid/sdk).
21
+
22
+ ## 0.65.0
23
+
24
+ A failed operation says why (TT-2261). Additive: 0.64 code runs unchanged.
25
+
26
+ ### Added
27
+
28
+ - `Operation` and the `OPERATION_UPDATED` payload carry an optional
29
+ `failure_reason`: `INSUFFICIENT_CASH` when an accept ended
30
+ `EXPIRED_UNEXECUTED` because the taker's Cash did not cover the stake, and
31
+ absent otherwise. `waitForOperation` resolves with it, so you no longer need
32
+ the RFQ's `terminal_reason`.
33
+ - `entryFailure(record, operation)` names why an entry did not trade, for the
34
+ message to show: `INSUFFICIENT_CASH` (not enough Cash, including when the
35
+ planned Core cash landed) or `CORE_MOVE_MISSED` (the record planned Core
36
+ cash that Hyperliquid never confirmed moving before `fund_by`, so the user
37
+ may still have enough on HyperCore). It is `undefined` for any other
38
+ outcome. Pass the latest record, as `onRecord` last handed it back.
39
+ - `openPosition` returns the entry `record`, which follows each bridge update
40
+ `onSigned` gets.
41
+ - The `createRfq` error list includes `RFQ_GENERATION_STALE`,
42
+ `RFQ_GENERATION_IN_FLIGHT` and `COMBO_AUTOMATIC_DISABLED`, which the route
43
+ already returned.
44
+
45
+ ```ts
46
+ const opened = await totalis.openPosition({ legs, stake, core });
47
+ if (opened.operationId) {
48
+ const operation = await totalis.waitForOperation(opened.operationId);
49
+ if (operation.status !== "COMMITTED") {
50
+ const failure = entryFailure(opened.record, operation); // "INSUFFICIENT_CASH" | "CORE_MOVE_MISSED" | undefined
51
+ }
52
+ }
53
+ ```
54
+
55
+ Needs a venue with contract `163.0.0-operation-failure-reason`; against an
56
+ older venue `failure_reason` is absent and `entryFailure` returns `undefined`.
57
+
58
+ ## 0.64.0
59
+
60
+ A Combo entry posts its accept at once and moves Core cash only after the
61
+ maker takes it (TT-2125). The accept no longer waits up to 1.5 s for
62
+ Hyperliquid's answer to the bridge, and a declined, timed-out or not-admitted
63
+ entry never sends its bridge. Needs a venue that publishes `accept_before` on entry
64
+ quotes and `fund_by` and `server_time` on acceptances.
65
+
66
+ ### Changed
67
+
68
+ - `sendAcceptance` posts the accept first. The Core to HyperEVM bridge goes
69
+ only when the acceptance is `ACCEPTED` with a `fund_by` still ahead, and is
70
+ resent while unanswered until `fund_by`; an accept answered any other way
71
+ discards it. The result does not wait for Hyperliquid: its new `bridging`
72
+ promise carries the answer, and `bridge` (the answer) is gone.
73
+ - `signEntry` asks the signer for the quote, the bridge and the wallet
74
+ authorization at once. Pass `cash` (the `{ vault, wallet }` of a
75
+ `spendableCash` read) to plan without a balances read on the press; a plan
76
+ that fails then throws before the wallet is asked for anything. Without
77
+ `cash` it still reads the balances. `openPosition` takes `cash` too, and
78
+ otherwise reads the balances while the quotes arrive.
79
+ - `recoverAcceptance` now finishes the bridge: it sends a never-sent bridge
80
+ if the acceptance is `ACCEPTED` before its `fund_by` and discards it
81
+ otherwise, and resends a sent but unanswered one, the same bytes, within
82
+ that window. It takes `transport` and `onRecord`. A bridge moves only for
83
+ the record's own acceptance: when another record's acceptance took the
84
+ quote, the result reports it and this record's bridge is discarded.
85
+ While a never-sent bridge waits on a `PENDING_CONFIRM` acceptance, it and
86
+ a lost accept answer are read every 250 ms until 2 s past the maker's
87
+ deadline, so an early `ACCEPTED` still moves cash before `fund_by`.
88
+ - `fund_by` is judged by the latest the venue clock can read: a response's
89
+ new `server_time`, read from the database clock that sets `fund_by`, plus
90
+ the time since its request left. A skewed local clock or a delayed
91
+ response never sends late, and a bridge with no stamp to judge by is
92
+ discarded. An entry with a bridge reads its RFQ's quotes alongside the
93
+ accept for a tight stamp, since the held accept's own runs late by the
94
+ maker's wait. A first send whose `fund_by` passed while
95
+ `onRecord` saved `SENT` is not sent and records `DISCARDED`.
96
+ - Entry records carry `version: 2` and a `bridgeState` (`SENT`, `LANDED`,
97
+ `PROCESSED`, `REFUSED`, `DISCARDED`). `onRecord` on `sendAcceptance` and
98
+ `recoverAcceptance` (and `openPosition`'s `onSigned`) is awaited with the
99
+ record before the first send and gets it again with each new state:
100
+ persist it over the stored one. A record without `version`
101
+ (`LegacySignedEntry`, from 0.63 or older) is only read by
102
+ `recoverAcceptance`; `sendAcceptance` refuses it.
103
+ - `bridged` is set only once a bridge was sent: never for one never sent,
104
+ discarded or refused. A refused bridge after `ACCEPTED` leaves the result
105
+ `ACCEPTED`.
106
+ - `settleHypercore` checks its `deadline` before every send, not only by
107
+ timer, on its new `now` clock (epoch ms by default).
108
+ - `bestQuote()` and the quote book cut entry quotes off at their
109
+ `accept_before` instead of fixed margins; `bestQuote` takes no argument,
110
+ and the UI adapter's `minLifeSeconds` applies to cash-out quotes only. An
111
+ entry quote without `accept_before` is never offered.
112
+
113
+ ### Removed
114
+
115
+ - `EntryError` codes `QUOTE_SHORT`, `BRIDGE_LATE` and `BRIDGE_REFUSED`, with
116
+ its `hyperliquidError` and `bridged`, and `bridged` on `ApiError` and
117
+ `normalizeError`'s result: nothing is bridged before the accept any more.
118
+
119
+ ## 0.63.0
120
+
121
+ Fixes from a partner integration (TT-2258).
122
+
123
+ ### Changed
124
+
125
+ - `openPosition` and `cashOut` take `collectMs` (default 1,000): once `choose`
126
+ would take a quote, more quotes may arrive for that long, and `choose` picks
127
+ when the window ends, whether or not any did. The window ends sooner when
128
+ waiting would leave `choose` nothing. `collectMs: 0` takes the first quote
129
+ as before. A `Chooser` may be asked about a later time, so it must
130
+ depend only on its arguments.
131
+ - `signEntry` and `openPosition` without `core` throw `EntryError`
132
+ `INSUFFICIENT_FUNDS`, naming the shortfall, when the wallet is known to fall
133
+ short, instead of signing an entry the venue refuses.
134
+ - `issueApiKey` refuses a challenge whose `urn:totalis:scope:` resources differ
135
+ from the requested scopes. Key challenges now list the scopes they grant and
136
+ `urn:totalis:expires-in-days:<days>`.
137
+ - A transfer bid its buyer's free vault balance cannot pay is refused at
138
+ publish (`INVALID_REQUEST`, `transfer.price`) instead of timing out after the
139
+ owner accepts it.
140
+
141
+ ## 0.62.0
142
+
143
+ Hourly reference closes, so charts can show a market's trend past one day
144
+ (TT-2230). Generated from contract 161.
145
+
146
+ ### Added
147
+
148
+ - `GET /v1/markets/{outcome_id}/reference-closes` takes `bucket=HOUR`: each
149
+ UTC hour carries the close of its last observed minute, over a window of up
150
+ to 90 days (the default with no `from`/`to`), `limit` up to 2,184. Every
151
+ response now carries `bucket_seconds` (60 or 3600), and runs read
152
+ `[bucket, close, buckets]`. Minute closes are unchanged.
153
+
154
+ ## 0.61.0
155
+
156
+ Makers onboard and run headless (TT-2257): the /mm dashboard becomes read-only,
157
+ so every maker write goes through the SDK or the API. No API change.
158
+
159
+ ### Added
160
+
161
+ - `listApiKeys(client, { maker? })` reads every page of an account's or a
162
+ maker's keys; `revokeApiKey(client, keyId, { maker? })` revokes one and throws
163
+ the venue's `ApiError` otherwise.
164
+ - `QUOTING_BOT_SCOPES` (the maker scopes for a quoting bot, none of which move
165
+ vault money) and `COLLATERAL_SCOPES` (for `reduceCollateral`), with the
166
+ `KeyScope` and `KeyMetadata` types.
167
+ - `examples/onboard.mjs`: headless maker onboarding from the exported Totalis
168
+ wallet key: sign in, open and admit the maker, issue the quoting bot's key,
169
+ make the first deposit into the maker vault (only while it is empty on
170
+ chain) and start quoting. A rerun resumes and never deposits twice.
171
+
172
+ ### Changed
173
+
174
+ - `signInWithWallet`'s `origin` documentation: outside a browser a maker passes
175
+ the Totalis app's origin (`https://hip4.totalis.trade`, or
176
+ `https://hip4-staging.totalis.trade` on staging) and sends it as the Origin
177
+ header with every request on the session.
178
+
179
+ ## 0.60.1
180
+
181
+ The venue now refuses, with 409 `STATE_CONFLICT`, to replace or cancel a quote
182
+ while a taker's acceptance of it awaits the maker's answer, instead of
183
+ withdrawing the acceptance (TT-2254). That closes the window 0.60.0 left: an
184
+ acceptance recorded while a replacing quote was on its way. Generated from the
185
+ contract with the new 409 descriptions; no API change.
186
+
187
+ ### Changed
188
+
189
+ - `quote`, `bid` and `cancelQuote` can answer `ApiError` `STATE_CONFLICT`
190
+ (`retry: "REFRESH"`) when an acceptance of the quote awaits this maker's
191
+ answer: answer it (`confirm`, or `onAcceptance`) first. The documentation of
192
+ `AcceptancePendingError` and `cancelQuote` says so.
193
+
194
+ ## 0.60.0
195
+
196
+ A maker no longer withdraws the acceptances it knows of by quoting again
197
+ (TT-2253). An acceptance the venue records while a quote is already on its way
198
+ can still be withdrawn by it: the SDK checks what the stream and the
199
+ acceptances read have delivered, not the venue's state at publication.
200
+ Generated from contract 160; no API change.
201
+
202
+ ### Changed
203
+
204
+ - Maker (`createMaker`): replacing or cancelling a quote while a taker's
205
+ acceptance of it awaits the maker's answer makes the venue withdraw that
206
+ acceptance. `quote` and `bid` now throw `AcceptancePendingError` (`code`
207
+ `ACCEPTANCE_PENDING`, with `rfqId`, `quoteId` and `deadline`), publishing
208
+ nothing, on an RFQ where this maker holds an unanswered acceptance, and
209
+ `onRfq` holds such an RFQ back until the acceptance is answered or its
210
+ deadline passes. A restarted maker that quotes every RFQ `onRfq` hands it no
211
+ longer withdraws the acceptances its snapshot carries.
212
+ - `quote` and `bid` start the maker stream if needed and wait until it is live,
213
+ so the pending acceptances are known, and check again just before publishing.
214
+ After a snapshot that truncated `acceptances`, or a stream resumed from a
215
+ cursor (its replay has no end marker, and an acceptance delivered before the
216
+ saved cursor is not replayed), they and `onRfq` also wait until
217
+ `GET /v1/makers/{maker_id}/acceptances` has been read in full. While that
218
+ read fails, `quote` and `bid` throw its error and `onRfq` offers nothing,
219
+ retrying every second. That read needs `quote:read`, one of the maker
220
+ scopes. Acceptance deadlines are compared on the venue clock.
221
+ - `cancelQuote`: `ACCEPTED` means this maker already confirmed the quote.
222
+ Cancelling a quote whose acceptance awaits an answer withdraws the
223
+ acceptance; prefer `confirm(acceptance, "DECLINE")`.
224
+ ### Added
225
+
226
+ - `reduceCollateral` returns the job's `idempotencyKey`. Without
227
+ `signTransaction`, sign the returned `transaction` yourself and submit it to
228
+ `POST /v1/makers/{maker_id}/operations/{operation_id}/self-funded-transaction`
229
+ under that same `Idempotency-Key`, the only one the route admits for the job.
230
+ Before, a job returned without `signTransaction` could not be finished.
231
+
232
+ ### Changed (example)
233
+
234
+ - `examples/node-bot.mjs` bids on cash-outs only to buy back its own positions
235
+ (a transfer is paid from the maker wallet's own account balance, which it
236
+ does not fund) and confirms only while its `willing(acceptance)` check holds.
237
+
238
+ ## 0.59.0
239
+
240
+ Say where the cash is after a bridged entry that did not trade (TT-2219).
241
+ Generated from contract 160; no API change.
242
+
243
+ ### Added
244
+
245
+ - `AcceptanceResult.bridged` (`BridgedCash`: `{ amount, landed }`, amount in
246
+ USDC base units) for an entry that bridged from HyperCore, whatever its
247
+ status. Unless the entry's operation `COMMITTED`, that cash is in the
248
+ HyperEVM wallet, not on HyperCore: the next entry spends it first, or
249
+ `returnToCore` moves it back. `landed` is `"yes"` only on Hyperliquid's
250
+ `ok`; with no answer, a `processed` nonce (a lost refusal spends it too) or
251
+ after `recoverAcceptance` it is `"unknown"`.
252
+ - An accept refused after the bridge (an `ApiError` that cannot still run,
253
+ such as `QUOTE_EXPIRED`) and a `BRIDGE_LATE` `EntryError` carry the same
254
+ `bridged`; `normalizeError` copies it to `NormalizedError.bridged`.
255
+
256
+ ## 0.58.0
257
+
258
+ An opt-in maker quote lease, so takers stop spending their quote window on a
259
+ maker that has gone quiet (TT-2229). Generated from contract 160.
260
+
261
+ ### Added
262
+
263
+ - Maker (`createMaker`): `keepQuoteLease(leaseMs, onError?)` renews the lease
264
+ now and every third of `leaseMs` until the returned stop function, `close()`
265
+ or another `keepQuoteLease` call. `renewQuoteLease(leaseMs)`
266
+ (`PUT /v1/makers/{maker_id}/quote-lease`, 1000 to 60000 ms) arms or renews it
267
+ once and answers `{ lease_ms, expires_at }`; `releaseQuoteLease()`
268
+ (`DELETE`) disarms it and answers `{ released }`.
269
+ - Once a lease lapses, the venue cancels each open quote of the maker that no
270
+ taker is accepting, and each one it publishes after, until it renews or
271
+ releases the lease. Takers see `QUOTE_REMOVED` with `CANCELLED`, which
272
+ `watchQuotes` and `bestQuote` already honour. An acceptance already under way
273
+ runs to its confirm deadline as before. A maker without a lease sees no change.
274
+
275
+ ## 0.57.0
276
+
277
+ Partner helpers from the Liquid dogfood run (TT-2224). Generated from contract
278
+ 159; no API change.
279
+
280
+ ### Changed
281
+
282
+ - `stream.status === "live"` after a resumed account stream means the replay
283
+ has been applied. With publication freshness (the account default) the
284
+ stream stays `connecting` through the replayed events and goes live at the
285
+ first publication checkpoint, which the venue sends only after them. A
286
+ stream without publication freshness (the maker default) has no such marker
287
+ and is still live once subscribed. `stream.live()` and the flows wait the
288
+ same way, up to one 1 s heartbeat longer on a resume.
289
+ - A withdrawal or return to HyperCore with an unread balance throws
290
+ `BalanceUnknownError` (`component`: `VAULT_FREE` or `WALLET_USDC`), and a
291
+ deployment without exits to HyperCore (staging) throws
292
+ `ExitUnavailableError` from `signCoreExit`, `exitToCore`, `signReturnToCore`
293
+ and `returnToCore`, before anything is signed. Both used to be plain
294
+ `Error`s. `sendCoreExit` turns the venue's 503 `CORE_EXIT_UNAVAILABLE`,
295
+ which it answers only where no exit runs, into `ExitUnavailableError` (the
296
+ refusal as `cause`). `signReturnToCore` reads the exit route before it signs
297
+ the deposit leg. Entries still throw `EntryError` `BALANCE_UNKNOWN`.
298
+
299
+ ### Added
300
+
301
+ - `spendableCash(balance)` and `totalis.spendableCash()`: `{ vault, wallet,
302
+ total }` from `GET /v1/me/balances`, the reservation-aware figures the SDK
303
+ plans with. Each is `null` while unknown, never 0.
304
+ - `netPayout(quote)`, `netCashout(bid, position)`, `netOfProfitFee` and
305
+ `netStake`: what the user actually receives, by the vault's fee rules. The
306
+ profit fee is `floor((amount - net_stake) * fee_bps / 10000)` on a settlement
307
+ payout or sell-back price above the net stake; a transfer pays its price in
308
+ full. A quote with payout 9.18 USDC on a 3 USDC stake nets 9.118140 USDC.
309
+ - `normalizeError(error)`: any SDK failure as `{ code, message, retryable,
310
+ retry, requestId, status, mayStillRun, resend, cause }`. `mayStillRun` is
311
+ true when the command may have reached the venue (a lost response, an abort
312
+ or timeout in flight, `BACKOFF` after the resends, a proxy 5xx). Also on
313
+ `/errors`, with the error classes.
314
+ - `createUiAdapter(totalis, { onInvalidate, onCatalogStale })`: quotes with the
315
+ best one (`watchQuotes`), the venue clock (`serverNow`, `secondsLeft`),
316
+ `readInvalidated` revisions (and every resource each time the stream goes
317
+ live) for a query cache, and a catalog refresh only for a newer
318
+ `catalog_generation` than `catalogLoaded`. No framework dependency.
319
+ - `/maker`: `makerReadiness(client)` reads `GET /v1/me/maker`, admits an
320
+ indexed or self-service `PENDING` maker with `POST /v1/me/maker`, and
321
+ answers `NOT_INDEXED` instead of a 404 while the open transaction is not
322
+ indexed yet; `waitForMaker(client)` reads again until it is.
323
+
324
+ ## 0.56.0
325
+
326
+ An eligibility filter on the market list (TT-2226). Generated from contract
327
+ 158.
328
+
329
+ ### Added
330
+
331
+ - `eligibility` on `GET /v1/markets` (`ENABLED` or `DISABLED`) keeps only
332
+ markets in that state. A page can be short or empty while `has_more` is
333
+ true, and the cursor is bound to the filter.
334
+
335
+ ## 0.55.0
336
+
337
+ Cash-out RFQs carry the position's stake and payout (TT-2228). Generated from
338
+ contract 157.
339
+
340
+ ### Added
341
+
342
+ - `CashoutRfq` and the cash-out `RFQ_CREATED` payload require `net_stake` and
343
+ `payout`, atomic USDC strings: the position's `tickets(position_id).stake`
344
+ (after the taker fee) and `.payout`. The vault fixes both when the position
345
+ opens, so they hold at `decision_block`. A maker can price a transfer
346
+ without reading the ticket.
347
+
348
+ ## 0.54.0
349
+
350
+ Anonymous reads refuse query parameters they do not take (TT-2223).
351
+ Generated from contract 155. No code change for callers.
352
+
353
+ ### Changed
354
+
355
+ - A malformed query, a repeated parameter or one the operation does not list
356
+ is 400 `INVALID_QUERY` on every anonymous read. `field_violations` names an
357
+ unlisted parameter as `UNEXPECTED`, and a repeated one or a malformed value
358
+ (`limit=%GG`) as `INVALID`; a key that does not decode names nothing. This
359
+ covers markets, questions, series, history, recurring rounds, discovery,
360
+ search, taxonomy, market stats, config, definitions, deployment, suggested
361
+ Combo, RFQs and the market stream handshake. `/v1/markets?search=BTC` used to
362
+ answer an unfiltered page.
363
+ - `getDeployment`, `getSuggestedCombo`, `getMarketStats`, `getMarketDataConfig`
364
+ and `getMarketDefinitions` gain a 400 response; the rest list
365
+ `INVALID_QUERY` in `operationErrors`.
366
+
367
+ ## 0.53.1
368
+
369
+ The package ships its examples, and the README matches what the SDK does
370
+ (TT-2222). Generated from contract 154. No code change for callers.
371
+
372
+ ### Changed
373
+
374
+ - `examples/` is in the package. The README keeps the partner guide; the
375
+ repository's development and release notes moved to `CONTRIBUTING.md`,
376
+ which is not published.
377
+ - A withdrawal kept across a restart stores the whole `signWithdrawal`
378
+ record, `{ idempotencyKey, account, body }`; without `account`,
379
+ `sendWithdrawal` posts it and then throws "different terms".
380
+ - `waitForOperation` resolves at `REVERTED` and `EXPIRED_UNEXECUTED` as well
381
+ as `COMMITTED`; the README checks `status`.
382
+ - `onRfq` delivers each open RFQ once per subscription; another subscription
383
+ or a restart delivers the still-open ones again, and quoting again replaces
384
+ the earlier quote.
385
+ - `examples/browser-wallet.html` runs from a checkout of the SDK, not from an
386
+ installed copy; an app imports `browser-wallet.mjs` through its bundler.
387
+ - The `tpk_` server-key guards throw at runtime only; they cannot keep a key
388
+ out of a bundle.
389
+ - The README names staging's stream host, `wss://hip4-ws-staging.totalis.trade`.
390
+
391
+ ## 0.53.0
392
+
393
+ Markets say whether a Combo can take them and who deployed them; Esports is
394
+ its own category (TT-2196). Generated from contract 154.
395
+
396
+ - `Market.combo`: `{ state: "OPEN" }`, or `CLOSED` with `reason`
397
+ (`EXCLUDED`, `UNLISTED_DEPLOYER`, `OUTSIDE_WINDOW`) and `opens_at`, when an
398
+ `OUTSIDE_WINDOW` market joins Combos. RFQs refuse legs that are not `OPEN`.
399
+ - `Market.deployer`: `{ name, address }`; Hyperliquid's own markets have no
400
+ address, deployers Totalis does not list have no name and stay out of browse.
401
+ - `Category` adds `Esports`; `lol` moves there from Sports. Switches over
402
+ categories need the new case.
403
+
404
+ ## 0.52.0
405
+
406
+ `getProfitLeaderboard` reads the top 10 traders by profit, each as their
407
+ Portfolio Profit/Loss card shows it, with the same `range` and `kind` as
408
+ `getVolumeLeaderboard` and the same signed-in caller (TT-2157). Each trader
409
+ carries `profit` in atomic USDC. Generated from contract 153. Additive.
410
+
411
+ ## 0.51.1
412
+
413
+ Staging streams connect to their own host (TT-2204). Generated from contract
414
+ 152. No code change for callers.
415
+
416
+ ### Changed
417
+
418
+ - `publicStreamServers.staging` is `wss://hip4-ws-staging.totalis.trade`, so
419
+ `realtimeUrl("staging")` and `marketStreamUrl("staging")` open there. The API
420
+ host still serves both paths.
421
+
422
+ ## 0.51.0
423
+
424
+ Maker withdrawals from the dashboard or a bot (TT-2189). Generated from
425
+ contract 152. Additive.
426
+
427
+ - `GET /v1/makers/{maker_id}/withdrawal` and `maker.withdrawal()`: the
428
+ pending vault withdrawal (`amount`, `destination`, `ready_at`), whether
429
+ `executeMakerWithdraw` would succeed now, and its `blockers`
430
+ (`WITHDRAW_NOT_READY`, `VAULT_PAUSED`, `MAKER_SHORT`, `INSUFFICIENT_FREE`).
431
+ `pending` is null when none is live.
432
+ - `GET /v1/makers/{maker_id}/capital` now reports `MAKER_WITHDRAW` as
433
+ available: the amount a new request may ask for (`free_after_pending`), or
434
+ null with `MAKER_WITHDRAW_PENDING` while a request is live.
435
+ - The maker wallet still sends `requestWithdraw`, `executeWithdraw` and
436
+ `cancelWithdraw` from `maker.controller()` itself and pays the gas in HYPE.
437
+
438
+ ## 0.50.0
439
+
440
+ Breaking: `getVolumeLeaderboard` needs a signed-in participant session;
441
+ anonymous calls and API keys are refused. It returns up to 10 traders and
442
+ takes `kind`: `ALL` (the default), `SINGLES` for HyperCore fills alone or
443
+ `COMBOS` for Combo stakes alone, each with its own top 10, and the answer
444
+ names its `kind`. Each trader carries `avatar_seed`, so a client can draw the
445
+ same generated avatar as for `GET /v1/me`. Both are optional in the answer, so
446
+ servers before contract 151 may omit them. Generated from contract 151.
447
+
448
+ ## 0.49.0
449
+
450
+ Maker dashboard reads (TT-2188). Generated from contract 150. Additive.
451
+
452
+ ### Added
453
+
454
+ - `GET /v1/makers/{maker_id}/quote-history` (`listMakerQuoteHistory`): every
455
+ quote the maker published in `[from, through)`, newest first, with its
456
+ status (`OPEN`, `AWAITING_CONFIRMATION`, `ACCEPTED`, `FILLED`, `FAILED`,
457
+ `DECLINED`, `TIMED_OUT`, `CANCELLED`, `REPLACED`, `EXPIRED`, `NOT_SELECTED`,
458
+ `RFQ_CANCELLED`), stake, net stake, payout, maker risk or cash-out price,
459
+ submitted/accepted/resolved times and the period's `fill_rate`. Filters
460
+ `status` and `kind`; cursor paged.
461
+ - `GET /v1/makers/{maker_id}/exposure` (`getMakerExposure`): the maker's open
462
+ book by outcome: YES/NO, gross, net and worst-case exposure, netting
463
+ savings, and what awaits settlement.
464
+ - Positions carry `maker_pnl`, `maker_result` (`WON`, `LOST`, `EVEN`) and
465
+ `protocol_fees`; position lists filter on `maker_result`.
466
+ - Performance carries `history_from` (the earliest complete `from`),
467
+ `won_ticket_count`, `lost_ticket_count`, `even_ticket_count`,
468
+ `gross_winning_pnl` and `gross_losing_pnl`; each `series` point carries
469
+ `closed_ticket_count` and `net_trading_pnl_change` since the previous point.
470
+
471
+ ## 0.48.0
472
+
473
+ A stream closes `STREAM_REPLACED` when its owner opens a fifth live stream,
474
+ which replaces the owner's oldest (TT-2185). `TotalisStream` does not
475
+ reconnect; it emits a `StreamClosedError` with that reason, since reconnecting
476
+ would replace the owner's oldest stream in turn. Generated from contract 149,
477
+ whose error schema gains the reason.
478
+
479
+ ## 0.47.0
480
+
481
+ A maker is one wallet, its controller and its quote signer (TT-2181).
482
+ Breaking: `maker.controller()` / `controllerTransactions` no longer build
483
+ `setQuoteSigner`. Open a maker with `openMakerVaultTransaction(deployment,
484
+ wallet)` sent from that same wallet; nothing fills without its confirmation
485
+ signature, so stop confirming to stop filling. Generated from contract 148.
486
+
487
+ ## 0.46.0
488
+
489
+ `getMarketDefinitions` reads the native names and descriptions of every
490
+ question and outcome in the current catalog, with the network's reviewed
491
+ outcome templates. Generated from contract 148. Additive.
492
+
493
+ ## 0.45.0
494
+
495
+ Fund a Combo from HyperCore and resume every money flow after a reload or a
496
+ killed app (TT-2174). Generated from contract 147. Breaking: the native
497
+ HyperCore withdrawal routes (`/v1/hypercore/withdrawals*`) and their types are
498
+ gone; sign a `sendAsset` and submit it to Hyperliquid (or a relay) yourself,
499
+ since Hyperliquid's first answer settles it.
500
+
501
+ ### Added
502
+
503
+ - `signEntry({ quote, core?, sourceDex?, acceptanceId?, hypercoreNonce? })`:
504
+ signs a Combo entry as a plain JSON record. Funding is planned from current
505
+ balances: free vault cash, then the wallet, then a Core to HyperEVM bridge.
506
+ A vault balance the venue marks `STALE` or `UNKNOWN` throws `EntryError`
507
+ `BALANCE_UNKNOWN`; a wallet without a current read is authorized for the
508
+ whole shortfall and the venue checks it.
509
+ `core: null` means your Core read failed: an entry that needs the bridge
510
+ throws `EntryError` `BALANCE_UNKNOWN`. Without `core` it funds from the
511
+ wallet alone.
512
+ - `signCashout({ quote, acceptanceId? })`, and `sendAcceptance(signed,
513
+ { transport?, signal? })` / `recoverAcceptance(signed, { wait? })` for either
514
+ record. A refused bridge throws `EntryError` and posts nothing. Only
515
+ `sendAcceptance` sends the bridge, within the quote's life; recovery never
516
+ sends it or signs again, and only reads and fences the acceptance. An accept answer
517
+ that does not echo the record's acceptance, RFQ and quote IDs throws.
518
+ `recoverAcceptance(signed, { wait: false })` returns a `PENDING_CONFIRM`
519
+ acceptance at once instead of reading it again after the maker's deadline.
520
+ - `signCoreExit` / `sendCoreExit`, `signDeposit` / `sendDeposit` (sponsored
521
+ `POST /v1/me/deposits`), and `returnToCore` with `signReturnToCore` /
522
+ `sendReturnToCore`: deposit the wallet USDC, wait for it to commit, then exit
523
+ it with the free vault cash. External wallets only: an embedded wallet's
524
+ vault cash is already swept to HyperCore, so it throws there.
525
+ - `wallet_kind` (`EMBEDDED` or `EXTERNAL`) on `GET /v1/me`.
526
+ - `openPosition` takes `core`, `sourceDex`, `transport` and `onSigned`;
527
+ `cashOut` takes `onSigned`. Both return the record's IDs as before.
528
+ - Hyperliquid bridge helpers: `hyperliquidNetwork`, `bridgeAction`,
529
+ `sendAssetTypedData`, `signSendAsset`, `hypercoreSignature`,
530
+ `hypercoreNonce`, `usdcText`, `hyperliquidExchange`, `submitHypercore`,
531
+ `settleHypercore`, `classifyHypercoreAnswer`, `hyperevmUsdcBridge`,
532
+ `bridgeGasBuffer`.
533
+
534
+ ### Fixed
535
+
536
+ - A retried Core exit resends the same signed body under its exit ID. Before,
537
+ `exitToCore` signed again, which the venue refused as
538
+ `IDEMPOTENCY_KEY_REUSED`.
539
+
540
+ ### Changed
541
+
542
+ - `openPosition` and `cashOut` cancel their RFQ when signing fails, or when an
543
+ entry stops before its accept is posted.
544
+ - The lost-answer fence also holds when the cancel answers `NOT_FOUND`, and
545
+ holds on 409 only for `RFQ_NOT_CANCELLABLE`. After `STATE_CONFLICT` the RFQ
546
+ is still open, so a still-absent acceptance throws instead of ending
547
+ `NOT_ADMITTED`.
548
+
549
+ ## 0.44.0
550
+
551
+ New subcategory filters: Champions League (`ucl`) and Europa League (`uel`)
552
+ under Sports, HYPE (`hype`) under Crypto. Generated from contract 146.
553
+ Additive.
554
+
555
+ ## 0.43.0
556
+
557
+ High-frequency template rounds, like BTC every 15 minutes, read as recurring
558
+ rounds. Generated from contract 145. Additive.
559
+
560
+ ### Added
561
+
562
+ - `RecurringSeries.stream`: the deployer template stream (`stream_id`, `venue`,
563
+ `template`, `price_description`, `seconds`) behind a recurring round, or
564
+ `null` for a native recurring series.
565
+
566
+ ### Changed
567
+
568
+ - `recurring_round` on market detail, and the market recurring-round route,
569
+ also describe a qualified stream round. Its `target_price` is the template
570
+ threshold, and it settles YES only strictly above it. Such a market has no
571
+ `series_id`.
572
+
573
+ ## 0.42.0
574
+
575
+ The public volume leaderboard (TT-2157). Generated from contract 144.
576
+ Additive.
577
+
578
+ ### Added
579
+
580
+ - `GET /v1/leaderboard/volume` (`getVolumeLeaderboard`): up to 100 traders by
581
+ username and volume in 10^-8 USDC, for `range` `1W` (default) or `ALL`.
582
+
583
+ ## 0.41.0
584
+
585
+ Streams connect to a stream host apart from the API host (TT-2113). Still
586
+ contract 143. Additive, with one default change.
587
+
588
+ ### Added
589
+
590
+ - `streamBaseUrl` on `createTotalis`, `createMaker` and `TotalisStream`: the
591
+ WebSocket origin, apart from `baseUrl` (the REST origin).
592
+ - `publicStreamServers`, `streamServerUrl()`, `marketStreamUrl()` (joins
593
+ `fallback_stream` from `/v1/market-data/config` to the stream origin) and
594
+ `marketStreamProtocol` (`totalis.market.v2`).
595
+ - `realtimeUrl()` takes an optional third argument, `streamBaseUrl`.
596
+
597
+ ### Changed
598
+
599
+ - In production, streams connect to `wss://hip4-ws.totalis.trade` by default.
600
+ REST stays on `https://hip4-api.totalis.trade`, which still serves both stream
601
+ paths during the migration. A `baseUrl` without `streamBaseUrl` keeps
602
+ deriving the stream from `baseUrl`, as before; to go back to the API host,
603
+ pass `streamBaseUrl: "wss://hip4-api.totalis.trade"`.
604
+ - A `drain` frame's `retry_after_ms` is a floor: the stream reconnects after
605
+ between one and two times the hint, so the sockets one drain closes do not
606
+ all return at once.
607
+
608
+ ## 0.40.0
609
+
610
+ A first exit to a HyperCore account that does not exist yet can pay its
611
+ activation fee. Generated from contract 143.
612
+
613
+ ### Added
614
+
615
+ - `activation_fee_accepted` on the `POST /v1/core-exits` command and on every
616
+ `CoreExit`.
617
+ - The `CORE_ACCOUNT_ACTIVATION_REQUIRED` error code.
618
+ - `exitToCore({ activationFeeAccepted: true })` sends that consent.
619
+
620
+ ## 0.39.0
621
+
622
+ The Core funding float is dropped. Generated from contract 142. Breaking.
623
+
624
+ ### Removed
625
+
626
+ - The `PENDING_FUNDING` acceptance status. Only Core funding reached it.
627
+ - The retired `CORE_FUNDING_UNAVAILABLE`, `CORE_FUNDING_CONFLICT` and
628
+ `CORE_VAULT_RESERVATION` error codes.
629
+
630
+ ## 0.38.0
631
+
632
+ Core funding is retired. Generated from contract 141. Breaking.
633
+
634
+ ### Removed
635
+
636
+ - `GET /v1/me/core-fundings` (`activeCoreFundings`) and
637
+ `GET /v1/quotes/{quote_id}/acceptance/funding` (`getCoreFunding`), with the
638
+ `core-funding` schemas.
639
+ - `CORE` and `COMBINED` accept funding. `funding` on an accept is a `WALLET`
640
+ authorization only; any other kind is `INVALID_REQUEST`. To spend Core USDC,
641
+ bridge it to the wallet first.
642
+ - The `CORE_FUNDING_UPDATED` stream event.
643
+
644
+ ### Changed
645
+
646
+ - `CORE_FUNDING_UNAVAILABLE`, `CORE_FUNDING_CONFLICT` and
647
+ `CORE_VAULT_RESERVATION` stay registered but are retired; no route returns
648
+ them.
649
+
650
+ ## 0.37.0
651
+
652
+ Usernames are optional, changeable, and name each account's /r/ link. Generated
653
+ from contract 140. Additive, with one behaviour change.
654
+
655
+ ### Added
656
+
657
+ - `POST /v1/me/username` (`generateUsername`): an account that skipped choosing
658
+ a username takes a generated one (`trader_` and six characters), returned as
659
+ `GeneratedUsername`. An account with a username gets its own back. If every
660
+ generated name it tries is taken, it answers `USERNAME_TAKEN`; try again.
661
+
662
+ ### Changed
663
+
664
+ - `PUT /v1/me/username` (`setUsername`) also changes an existing username, so it
665
+ no longer answers `USERNAME_ALREADY_SET`. A Totalis campaign link, a reserved
666
+ platform name or another account's earlier link name is `USERNAME_TAKEN`.
667
+ - `getUsernameAvailability` reports a name Totalis keeps for its own links,
668
+ such as `instagram`, as `TAKEN`.
669
+ - `setUsername` and `generateUsername` answer `INVALID_REQUEST` to an
670
+ `Idempotency-Key` stamped more than 5 minutes ahead of server time, since the
671
+ keys put username changes in order.
672
+
673
+ ## 0.36.0
674
+
675
+ Profit/Loss series for Portfolio and backend-owned Chance and Value (TT-2004).
676
+ Generated from contract 139. Additive.
677
+
678
+ ### Added
679
+
680
+ - Available market references carry nullable `chance`, `chance_basis`,
681
+ `mark`, `last_trade` and `last_trade_at`. `chance` is the crowd view (mid
682
+ within 10c, last trade inside a 10-50c spread, else null), and
683
+ `chance_basis` says which (`MID` or `LAST_TRADE`); `mark` is what a held
684
+ share is worth (chance, else best bid). Read them instead of deriving them
685
+ from the book.
686
+ - `GET /v1/me/pnl` (`getAccountPnl`): the cumulative trading P&L of the
687
+ account Portfolio shows, for `range` `1D`, `1W`, `1M` (default) or `ALL`.
688
+ `points` are `{at, pnl}` in atomic USDC, cumulative since `tracked_since`;
689
+ a window's change is its last point minus its first. A `pnl` of `null` is
690
+ unknown, never zero.
691
+
692
+ ## 0.35.0
693
+
694
+ Onboarding picks a username and an avatar (TT-1986). Generated from contract
695
+ 138. Additive.
696
+
697
+ ### Added
698
+
699
+ - `getUsernameAvailability` (`GET /v1/me/username/availability?username=`)
700
+ answers `UsernameAvailability` `{available, reason}`, where `reason` is
701
+ `INVALID`, `NOT_ALLOWED`, `TAKEN` or `null`. The account's own username is
702
+ available.
703
+ - `setAvatar` (`PUT /v1/me/avatar`) with `AvatarRequest` `{avatar_seed}` sets
704
+ the seed the account's generated avatar is drawn from.
705
+
706
+ ## 0.34.0
707
+
708
+ Followers survive a failed recovery read (TT-1902). Additive.
709
+
710
+ ### Fixed
711
+
712
+ - `withdraw`, `sendWithdrawal`, `waitForWithdrawal`, `waitForOperation`,
713
+ `waitForCoreExit`, `reduceCollateral`, and the quotes read after a truncated
714
+ snapshot no longer reject when a recovery read fails. Each recovery read is
715
+ sent once, and the follower alone decides when to read again. A lost read
716
+ (including a body cut off mid-response), a `BACKOFF` error, or a 500, 502,
717
+ 503 or 504 without the venue's error envelope is read again, one read at a
718
+ time, after the client's `retry` backoff and jitter, or the response's
719
+ `Retry-After` capped at `maxDelayMs` when that is longer. A `Retry-After` of
720
+ zero or a past date never skips the backoff. The backoff restarts after any
721
+ successful read. A stream update or reconnect during the backoff, or during
722
+ a read that then fails, reads at once; during a `Retry-After` wait it reads
723
+ when the wait ends. Settling, the
724
+ caller's abort and `close()` stop it and abort the read in flight. A `NEVER`
725
+ or `REFRESH` refusal (such as 404 or 401), any other 5xx without the
726
+ envelope (such as 501), or an error thrown by your own code (a chooser or
727
+ token provider) still rejects.
728
+ - `retry: false` turns off the request layer's resends; followers still read
729
+ again, with the default backoff.
730
+ - Resent requests keep the client's `mode`, `integrity`, `referrer`,
731
+ `referrerPolicy` and `keepalive` instead of falling back to fetch defaults.
732
+
733
+ ### Added
734
+
735
+ - `follow(stream, read, done, wake, signal, retry)`: `read` receives an
736
+ `AbortSignal` that aborts when the follow ends, and `retry` sets the
737
+ recovery backoff.
738
+
739
+ ## 0.33.0
740
+
741
+ Wallet USDC deposits are back (TT-1788). Generated from contract 137. Additive.
742
+
743
+ ### Added
744
+
745
+ - `POST /v1/me/deposits` (`createDeposit`): a browser session moves USDC
746
+ from its Privy embedded wallet into its Totalis balance. Send a
747
+ `DepositEnvelope` whose command is the wallet's signed USDC
748
+ `ReceiveWithAuthorization` with the vault as payee
749
+ (`receiveWithAuthorizationTypedData`); Totalis relays it and pays the gas.
750
+ The 202 `DepositAccepted` carries the queued `operation_id`. A deposit moves
751
+ at least 1 USDC; an account gets at most 5 an hour (`RATE_LIMITED` with
752
+ `Retry-After`). API keys cannot call it.
753
+
754
+ ## 0.32.1
755
+
756
+ Market stats cache lifetime (TT-1993). Generated from contract 136. No code
757
+ change for callers.
758
+
759
+ ### Changed
760
+
761
+ - `GET /v1/market-stats` `Cache-Control` is `public, max-age=N` with N at most
762
+ 30 and never past the snapshot's `valid_until`, or `no-store` within a second
763
+ of expiry. Its generated header type is `string`.
764
+
765
+ ## 0.32.0
766
+
767
+ Vault v1 (TT-1959). Generated from contract 135. **Breaking** for makers that
768
+ open or fund a vault with the SDK.
769
+
770
+ ### Changed
771
+
772
+ - `openMakerVaultTransaction(deployment, quoteSigner)`: the controller argument
773
+ is gone. The sending wallet becomes the controller, a controller opens one
774
+ maker, and the vault's `makerOf(controller)` returns its maker ID.
775
+ - `controllerTransactions(deployment, makerId, controller)`: `deposit` encodes
776
+ `depositMaker(makerId, controller, amount)`, which the vault refuses unless
777
+ `controller` is the maker's current controller. `maker.controller()` reads
778
+ it from `GET /v1/makers/{maker_id}/capital`.
779
+ - `GET /v1/makers/{maker_id}/funding-transaction` returns the three-argument
780
+ `depositMaker` call bound to the projected controller, or 404 for a maker
781
+ the projection has not seen.
782
+ - Position and cash-out RFQ legs allow up to 100 (`maxItems`), the vault's leg
783
+ limit. Entry RFQs and quotes keep their 50-leg request limit.
784
+ - `AWAITING_SETTLEMENT` also covers a position whose payout, with every
785
+ unresolved leg counted as a win, already rounds down to zero.
786
+ - New error code `COLLATERAL_REDUCTION_UNAVAILABLE` (503, `BACKOFF`):
787
+ `POST /v1/makers/{maker_id}/collateral-reductions` refuses it, without
788
+ queueing a job, while the vault has no attestor. Vault v1 starts that way.
789
+
790
+ ## 0.31.0
791
+
792
+ Every account has a generated avatar (TT-1975). Generated from contract 134.
793
+ Additive.
794
+
795
+ ### Added
796
+
797
+ - `VenueIdentity.avatar_seed`: a random UUID fixed when the account is created,
798
+ for drawing the account's avatar. Optional, so servers before contract 134
799
+ may omit it.
800
+
801
+ ## 0.30.0
802
+
803
+ Partner admission needs the wallet's consent (TT-1688). Generated from contract
804
+ 133. **Breaking** for partner servers.
805
+
806
+ ### Changed
807
+
808
+ - `createPartnerServer(...).admitWallet(address, consent)`: the consent is
809
+ required. A consent for another partner, wallet, environment or chain, or an
810
+ expired one, is `INVALID_SIGNATURE`.
811
+
812
+ ### Added
813
+
814
+ - `signAdmissionConsent({ signer, partner, environment, chainId })`: in the
815
+ partner's frontend, the wallet signs that the partner may open its account.
816
+ `admissionConsentMessage` is the exact message.
817
+
818
+ ## 0.29.0
819
+
820
+ Funding helpers for external wallets (TT-1685). Still contract 132. Additive.
821
+
822
+ ### Added
823
+
824
+ - `exitToCore({ amount, purpose? })`: the wallet signs an Exit to the CoreExit
825
+ router and the exit is sent once under its exit ID. `waitForCoreExit(exitId)`
826
+ follows it on the stream until it is credited on HyperCore, and rejects
827
+ `RECOVERED`, `FAILED` or `ABANDONED`. External wallets have no background
828
+ sweep, so this is how their cash reaches HyperCore before a native order.
829
+ - `directDepositCalls(amount)`: the approve and `depositUser(account, amount)`
830
+ transactions for a self-paid HyperEVM deposit.
831
+
832
+ ## 0.28.0
833
+
834
+ Wallet sign-in and partner credentials for external wallets (TT-1685). Still
835
+ contract 132. Additive.
836
+
837
+ ### Added
838
+
839
+ - `./wallet-session`: `signInWithWallet` asks for a challenge, checks it is
840
+ the Totalis sign-in for this origin, wallet and request, has the wallet sign
841
+ it, and returns the session. `signOutWallet` ends it.
842
+ `checkSignInChallenge` is the check on its own.
843
+ - `./partner`: `createPartnerServer({ serverKey }).admitWallet(address)`, for a
844
+ partner's server. It refuses to run in a browser.
845
+ - `partnerKey` on every client: the publishable `tpb_` key, sent as
846
+ `X-Totalis-Partner`. A `tpk_` server key is refused.
847
+ - `examples/partner-frontend.mjs` and `examples/partner-server.mjs`.
848
+
849
+ ## 0.27.0
850
+
851
+ Partners admit wallets (TT-1678). Generated from contract 132. Additive.
852
+
853
+ ### Added
854
+
855
+ - `admitPartnerWallet` (`POST /v1/partner/wallet-admissions`): a partner's
856
+ server, with its secret `tpk_` key, admits a wallet so the wallet's next
857
+ `createWalletSession` creates its account. Server-side only; never put the
858
+ key in a browser.
859
+
860
+ ## 0.26.0
861
+
862
+ Browse contract 4 groups IPO market-cap ladders and sports games (TT-1853).
863
+ Generated from contract 131. Additive for contracts 2 and 3.
864
+
865
+ ### Added
866
+
867
+ - `./browse`: contract `"4"` (query parameter, header, `totalis.market.browse.v4`
868
+ stream). Contract 4 cards add `DiscoveryGameItem` (`kind: "GAME"`, `game:<key>`
869
+ ID, `game` with `sport`, `scheduled_start`, `participants` and the
870
+ `winner_outcome_ids`, `spread_outcome_ids`, `total_outcome_ids` that partition
871
+ its markets) and SERIES cards whose `series` is an `IpoMarketCapSeries`
872
+ (`template: "COMPANY_IPO_MARKET_CAP"`, `company`, `listing_deadline`).
873
+ - `getMarket`: optional `contract` query parameter. With `"4"` the detail adds
874
+ `game` (`MarketGame` or null) and sets `series_id` for IPO ladder members.
875
+
876
+ ### Changed
877
+
878
+ - `Series.series` and `DiscoverySeriesItem.series` are `SeriesDescriptor`, a
879
+ union discriminated by `template`: `PriceSeries` or `IpoMarketCapSeries`.
880
+ Contracts 2 and 3 never return an `IpoMarketCapSeries`; narrow on
881
+ `template` before reading `underlying`.
882
+
883
+ ## 0.25.0
884
+
885
+ Externally owned wallets can sign in (TT-1676). Generated from contract 130.
886
+ Additive.
887
+
888
+ ### Added
889
+
890
+ - `createWalletChallenge` (`POST /v1/auth/wallet-challenges`) returns the
891
+ EIP-4361 message for a wallet to sign with `personal_sign`. It answers
892
+ `WALLET_CONTRACT_UNSUPPORTED` for an address with contract code.
893
+ - `createWalletSession` (`POST /v1/auth/wallet-sessions`) exchanges the
894
+ signature for a `Bearer` session for the wallet's existing account. The
895
+ session lasts at most 30 days and ends after 7 days without an API request.
896
+ A wallet that is not an account's own wallet gets `ACCESS_REQUIRED`.
897
+ - `endWalletSession` (`DELETE /v1/auth/wallet-sessions/current`) logs that
898
+ session out.
899
+ - Error code `WALLET_CONTRACT_UNSUPPORTED`.
900
+
901
+ ## 0.24.0
902
+
903
+ Accounts have a public username, set once (TT-1953). Generated from contract
904
+ 129. Additive.
905
+
906
+ ### Added
907
+
908
+ - `setUsername` (`PUT /v1/me/username`) with `UsernameRequest`, and the errors
909
+ `USERNAME_NOT_ALLOWED`, `USERNAME_TAKEN` and `USERNAME_ALREADY_SET`.
910
+ - `VenueIdentity.username`: the account's username, or `null` until it is set.
911
+ Optional, so servers before contract 129 may omit it.
912
+
913
+ ## 0.23.0
914
+
915
+ A price series links its sibling expiries (TT-1907). Generated from contract
916
+ 128. Additive.
917
+
918
+ ### Added
919
+
920
+ - `Series.siblings`: the other current series on the same network, template and
921
+ underlying, as `SeriesSibling` (`series_id`, `expiry`) by expiry ascending, up
922
+ to 64. Optional, so servers before contract 128 may omit it.
923
+
924
+ ## 0.22.0
925
+
926
+ Settlement credits have their own read, and no read writes. Needs contract 127.
927
+ Additive.
928
+
929
+ ### Added
930
+
931
+ - `getHypercoreSettlementCredits` (`GET /v1/hypercore/settlement-credits`,
932
+ browser session only): the account's retained USDC settlement credits from
933
+ storage, with no Hyperliquid read. Same mainnet and linked-account checks as
934
+ `getHypercorePortfolio`.
935
+
936
+ ### Changed
937
+
938
+ - `getAcceptance` only reads. An unanswered acceptance that has lapsed reads as
939
+ `TIMED_OUT` or `CANCELLED` before the venue stores it.
940
+ - `getHypercorePortfolio` and `getHypercoreWithdrawal` only read. Settlement
941
+ credits come from the background observer, so a new settlement appears once
942
+ the observer has passed it; a withdrawal advances when the background
943
+ reconciler resolves it.
944
+
945
+ ## 0.21.1
946
+ Settlement credits name the market they settled (TT-1929). Generated from
947
+ contract 126; the types are unchanged.
948
+ ### Changed
949
+ - `Activity.fill` is set on `CREDIT` rows: the outcome and side that settled,
950
+ `direction` `SELL`, `size` the shares settled and `price` what one share of
951
+ that side paid (`1` for a win, `0` for a loss, in between for a fractional
952
+ settlement). `size` times `price` is the payout before the fee effect.
953
+ ## 0.21.0
954
+
955
+ A session admits its maker from its linked wallet, with no signature. Needs
956
+ contract 125, which drops the signed registration. Breaking only for callers of
957
+ the removed operations.
958
+
959
+ ### Added
960
+
961
+ - `admitOwnMaker` (`POST /v1/me/maker`, browser session only): admits the
962
+ lowest maker whose controller and quote signer are both the account's
963
+ qualified linked wallet and returns the `GET /v1/me/maker` body (`OwnMaker`).
964
+ No body and no `Idempotency-Key`; a repeat returns the current ownership.
965
+ `404 NOT_FOUND` until such a maker is indexed, `409 STATE_CONFLICT` when the
966
+ wallet already has a profile for a different maker.
967
+
968
+ ### Removed
969
+
970
+ - `createMakerOnboardingChallenge`, `registerMaker` and `getMakerRegistration`
971
+ (`POST /v1/maker-onboarding/challenges`, `POST
972
+ /v1/maker-onboarding/registrations` and `GET
973
+ /v1/maker-onboarding/registrations/{maker_id}`), with the `ChallengeEnvelope`,
974
+ `Challenge`, `ProofEnvelope` and `Profile` maker-access schemas. `OwnerProof`
975
+ stays: API key issuance uses it.
976
+ - `MakerAccess.expires_at`, which was always `null`: owner access does not
977
+ expire.
978
+
979
+ ## 0.20.0
980
+
981
+ Maker dashboard access comes only from owning the maker. Needs contract 124,
982
+ which drops the legacy dashboard grants. Breaking only for callers of the
983
+ removed operations.
984
+
985
+ ### Removed
986
+
987
+ - `createMakerAccessChallenge`, `consumeMakerAccessProof`,
988
+ `grantMakerMembership` and `revokeMakerMembership` (`POST
989
+ /v1/makers/{maker_id}/access/challenges`, `POST .../access/proofs`, `PUT` and
990
+ `DELETE /v1/makers/{maker_id}/members/{participant_id}`), with their
991
+ `MembershipRequest` and `AccessChallenge` schemas and the unused `MakerList`.
992
+ - `MANAGE_ACCESS` from `Permission`.
993
+
994
+ ### Changed
995
+
996
+ - `MakerAccess.expires_at` is always `null`: owner access does not expire.
997
+ - The README and `examples/node-bot.mjs` sign with your exported Totalis
998
+ wallet key, `TOTALIS_WALLET_KEY` (was `QUOTE_SIGNER_KEY`).
999
+
1000
+ ## 0.19.0
1001
+
1002
+ Activity effects carry their asset, fills carry their trade and positions
1003
+ carry what the owner paid (TT-1875, TT-1862). Needs contract 123.
1004
+
1005
+ ### Added
1006
+
1007
+ - `Effect.asset` (`Asset`: `asset_id`, `symbol`, `decimals`). `delta` is in
1008
+ that asset's atomic units: HyperEVM USDC has 6 decimals, HyperCore USDC and
1009
+ HYPE have 8. Never assume 6.
1010
+ - `Activity.fill`: outcome, side, direction, size, price, oid and tid on
1011
+ `FILL` and `CONVERSION` rows; null on every other kind.
1012
+ - `Position.acquisition_cost`: the gross stake with the entry fee for the
1013
+ opener, or the latest transfer price for a buyer; null when the chain
1014
+ history can't establish it.
1015
+
1016
+ ### Changed
1017
+
1018
+ - Workflow activities (a pending or failed Combo, cash-out or withdrawal) set
1019
+ `occurred_at` to the time the request was made, which later revisions keep.
1020
+ - A HyperCore send with a HYPE fee and a spot to perp transfer without a nonce
1021
+ now appear instead of being held back.
1022
+
1023
+ ## 0.18.0
1024
+
1025
+ A quote's `kind` names its terms (TT-1916): `ENTRY`, `SELL_BACK` or
1026
+ `TRANSFER`, replacing `CASHOUT`. Needs contract 122, which serves only the new
1027
+ shape. Breaking. Terms and signed EIP-712 structs are unchanged.
1028
+
1029
+ ### Changed
1030
+
1031
+ - `Quote` (list quotes, the account snapshot's `quotes`, `QUOTE_CREATED`) is
1032
+ the union of `EntryQuote`, `SellBackQuote` and `TransferQuote`; each carries
1033
+ exactly its own terms (`entry`, `sell_back` or `transfer`), so narrowing on
1034
+ `kind` types the terms.
1035
+ - `MakerAcceptance` (`QUOTE_ACCEPTED`, the maker snapshot's `acceptances`,
1036
+ `GET /v1/makers/{maker_id}/acceptances`) is the same three-way union.
1037
+ - `CashoutBid` is `SellBackQuote | TransferQuote`; `SellBackQuote` and
1038
+ `TransferQuote` are exported from the root.
1039
+ - An RFQ's `kind` stays `ENTRY` or `CASHOUT`.
1040
+
1041
+ ## 0.17.0
1042
+
1043
+ Compact chart closes and a preflight-free browse contract. Needs contract 121.
1044
+
1045
+ ### Added
1046
+
1047
+ - `GET /v1/markets/{outcome_id}/reference-closes`
1048
+ (`getMarketReferenceCloses`): `REFERENCE_PRICE_OHLC` history reduced to
1049
+ closes. `runs` holds `CloseRun` tuples `[minute, close, minutes]`, with
1050
+ `minute` in Unix seconds; `anchor` is `{ minute, close }`. The parameters,
1051
+ source, scale, `closed_before` and cursor match history, and `limit`
1052
+ counts minutes, not runs.
1053
+ - `./browse`: a `contract` query parameter (`"2"` or `"3"`) on discovery,
1054
+ search and taxonomy. It negotiates like `X-Totalis-Browse-Contract` but adds
1055
+ no custom header, so browsers skip the CORS preflight.
1056
+
1057
+ ### Changed
1058
+
1059
+ - `./browse`: `contract` is required and `X-Totalis-Browse-Contract` is
1060
+ optional, so every typed request negotiates and matches its typed response.
1061
+ A header-only caller adds `query: { contract }`; the header may stay if it
1062
+ matches. The server still negotiates on the header alone.
1063
+
1064
+ ## 0.16.0
1065
+
1066
+ Everything the caller owns lives under `/v1/me` (TT-1786). Needs contract
1067
+ 120, which serves only the new paths. Breaking. Signed EIP-712 structs are
1068
+ unchanged.
1069
+
1070
+ ### Changed
1071
+
1072
+ - `POST /v1/positions/{position_id}/cashout` is now
1073
+ `POST /v1/me/positions/{position_id}/cashout` (`createCashout`), which
1074
+ `cashOut` calls.
1075
+ - `GET /v1/operations/{operation_id}` is now
1076
+ `GET /v1/me/operations/{operation_id}` (`getOperation`), which
1077
+ `waitForOperation` rereads, for personal and maker keys alike.
1078
+ - `POST /v1/withdrawals` is now `POST /v1/me/withdrawals` (`createWithdrawal`),
1079
+ which `sendWithdrawal` and `withdraw` call.
1080
+ - `GET /v1/withdrawals/{withdrawal_id}` is now
1081
+ `GET /v1/me/withdrawals/{withdrawal_id}` (`getWithdrawal`), the recovery read
1082
+ behind `withdraw` and `waitForWithdrawal`.
1083
+ - The `Operation` and `Withdrawal` types are unchanged; only the paths they
1084
+ are keyed on moved.
1085
+
1086
+ ## 0.15.0
1087
+
1088
+ Browse contract 3 groups standalone price-threshold markets into price series
1089
+ (TT-1905). Needs contract 119.
1090
+
1091
+ ### Added
1092
+
1093
+ - `./browse`: `X-Totalis-Browse-Contract: "3"`, the `DiscoverySeriesItem`
1094
+ card (`kind: "SERIES"`, `series: {template, underlying, expiry}`, two or more
1095
+ member `markets`) and `series:` item IDs in cards and browse updates.
1096
+ Contract 2 never returns them.
1097
+ - `GET /v1/series/{series_id}` (`getSeries`): one price series with every
1098
+ active member plus the most recently listed inactive members, up to 256.
1099
+ Members are `SeriesMarket`s, whose `native_question_id` is always `null`.
1100
+ - `series_id` on `MarketDetail`: the series key of a standalone binaryPrice or
1101
+ priceTouch market, else `null`.
1102
+ - `totalis.market.browse.v3` stream updates carry contract `"3"` and may name
1103
+ `series:` cards.
1104
+
1105
+ ## 0.14.0
1106
+
1107
+ The API speaks prediction-market vocabulary (TT-1904): quotes, acceptances
1108
+ and positions, keyed by `quote_id` and `position_id`, and a v2 stream. Needs
1109
+ contract 118, which serves only the new surface. Breaking.
1110
+
1111
+ ### Changed
1112
+
1113
+ - Taker (`createTotalis`): `placeBet` is `openPosition`, `watchBook` is
1114
+ `watchQuotes`, and `release()` is `deployment()` (`GET /v1/deployment`).
1115
+ `openPosition` returns `{ rfqId, acceptanceId, quoteId, positionId, entry,
1116
+ status, operationId, outcome }`; an entry position is named by its quote, so
1117
+ `positionId` is `quoteId`. `cashOut({ positionId })` creates the cash-out RFQ
1118
+ with `POST /v1/positions/{position_id}/cashout` (`POST /v1/rfqs` is
1119
+ entry-only) and returns `{ rfqId, acceptanceId, quoteId, positionId, status,
1120
+ operationId, outcome }`.
1121
+ - Accepting is `POST /v1/quotes/{quote_id}/accept` with `{ taker_signature,
1122
+ funding? }`. Its required `Idempotency-Key` is the acceptance ID, a UUIDv7
1123
+ made before the first send and reused for every resend. A lost accept is
1124
+ recovered from `GET /v1/quotes/{quote_id}/acceptance`; `NotAdmitted` is
1125
+ `{ status: "NOT_ADMITTED", quote_id, rfq_id }`.
1126
+ - Acceptance status: `PENDING_CONFIRM`, `PENDING_FUNDING` (was `CONFIRMED`),
1127
+ `ACCEPTED` (was `COMMITTED`), `FILLED` and `FAILED` (from the operation),
1128
+ `DECLINED`, `TIMED_OUT`, and `CANCELLED` (was `WITHDRAWN`).
1129
+ - Maker (`createMaker`): `withdraw(rfqId, digest)` is `cancelQuote(quoteId)`
1130
+ (`DELETE /v1/quotes/{quote_id}`, answering `{ status }`), `onConfirmation` is
1131
+ `onAcceptance`, and `release()` is `deployment()`. `quote()` posts
1132
+ `{ quote_id, entry }` and `bid()` `{ quote_id, sell_back | transfer }` to
1133
+ `POST /v1/rfqs/{rfq_id}/quotes`; both return `quoteId`. The answer is
1134
+ `POST /v1/quotes/{quote_id}/confirm` with a `decision` and no
1135
+ Idempotency-Key: the quote keys it. Truncated acceptances are paged from
1136
+ `GET /v1/makers/{maker_id}/acceptances`.
1137
+ - Legs are `{ outcome_id: "<decimal>", side: "YES" | "NO" }` everywhere, as
1138
+ markets and positions name them. The typed-data builders encode them as the
1139
+ signed `uint32`/`uint8`, and read `position_id` into the signed `ticketId`;
1140
+ digests and signatures are unchanged.
1141
+ - Entry RFQs carry `taker` and `stake` (were `taker_address` and
1142
+ `stake_amount`); cash-out RFQs and cash-out terms carry `position_id` (was
1143
+ `ticket_id`). A quote's entry terms are `entry` (was `quote`).
1144
+ - Lifecycle fields are `status` (were `state`) on RFQs, operations,
1145
+ withdrawals, collateral reductions (`operation_status`) and stream payloads.
1146
+ RFQs are `OPEN`, `ACCEPTED` (was `SELECTED`), `EXPIRED`, `CANCELLED` (the
1147
+ stream's `EXPIRED` and REST's `CANCELLED` now agree) or `FAILED` (was
1148
+ `CLOSED`); an operation's `DURABLE` is `QUEUED`.
1149
+ - The stream is `totalis.realtime.v2`. `StreamOptions.topic` is `subscription`:
1150
+ `{ type: "account", open_rfqs? }` or `{ type: "maker", maker_id }`. The client
1151
+ sends `{ method: "subscribe", subscription }` and every server frame is
1152
+ `{ channel, data }`; `RealtimeHello` and `RealtimeReady` are
1153
+ `RealtimeSubscribe` and `RealtimeSubscriptionResponse`. An event carries
1154
+ `cursor` (was `stream`); a snapshot carries `truncated` (was
1155
+ `continuations`) and the account's `quotes` (was `book_quotes`) and
1156
+ `acceptances`.
1157
+ - Event names: `QUOTE_CREATED` / `QUOTE_REMOVED` (were `BOOK_QUOTE_*`),
1158
+ `QUOTE_ACCEPTED` (was `CONFIRMATION_REQUESTED`), `RFQ_CREATED` (was
1159
+ `ENTRY_RFQ_OPENED` and `CASHOUT_RFQ_OPENED`), `RFQ_ACCEPTED` (was
1160
+ `RFQ_SELECTION_DURABLE`), `RFQ_FAILED` (was `RFQ_CLOSED`),
1161
+ `OPERATION_UPDATED` (was `EXECUTION_REPORT` and `WITHDRAWAL_REPORT`),
1162
+ `VAULT_BALANCE_CHANGED` (was `BALANCE_CHANGED`), `WALLET_FUNDING_UPDATED`,
1163
+ `POSITION_*` (were `TICKET_*`, now `{ position_id, block_number, log_index }`
1164
+ without the stored ticket status) and `MAKER_CAPITAL_UPDATED`.
1165
+ - A wallet funding carries `kind: "WALLET"`.
1166
+ - Types: `BookQuote`, `Confirmation` and `Release` are `Quote`, `Acceptance`
1167
+ and `Deployment`; `MakerConfirmationRequest` and `MakerConfirmation` are
1168
+ `MakerAcceptance` and `Acceptance`; `TotalisRelease` and `UsdcRelease` are
1169
+ `TotalisDeployment` and `UsdcDeployment`.
1170
+ - API key scopes `ticket:accept` and `ticket:cashout` are `quote:accept` and
1171
+ `position:cashout`.
1172
+
1173
+ ### Removed
1174
+
1175
+ - `clientInstanceId` on the stream, and the v1 `session.hello` protocol.
1176
+
1177
+ ## 0.13.0
1178
+
1179
+ `GET /v1/vault` no longer reports whether financial actions are enabled
1180
+ (TT-1900). Needs contract 117. Breaking.
1181
+
1182
+ ### Removed
1183
+
1184
+ - `financial_actions_enabled` on `Release`. The venue still refuses
1185
+ balance-affecting commands while a release is disabled; the command fails
1186
+ with `FINANCIAL_ACTIONS_DISABLED`, so read that error rather than the release.
1187
+
1188
+ ## 0.12.0
1189
+
1190
+ Commands, the stream and identity carry only what a reader uses (TT-1866).
1191
+ Needs contract 116. Breaking.
1192
+
1193
+ ### Changed
1194
+
1195
+ - A command body is the command itself: the five POST commands
1196
+ (`createRfq`, `publishBookQuote`, `beginConfirmation`, `finishConfirmation`,
1197
+ `createWithdrawal`) no longer wrap it in `{schema_version, request_id,
1198
+ sent_at, command}`; `envelope()` now wraps only the commands that still carry
1199
+ it (core exits, HyperCore withdrawals and maker onboarding).
1200
+ `error.request_id` is the response's `X-Request-ID`. The body types are `CreateRfqCommand`, `BookQuoteCommand`,
1201
+ `ConfirmationAcceptanceCommand`, `MakerConfirmationCommand` and
1202
+ `WithdrawalCommand` (were the `…Envelope` types).
1203
+ - The venue fills the addresses the credential implies from its one embedded
1204
+ wallet, and the signed typed data still names that wallet: `createRfq` sends
1205
+ no `taker_address`, a wallet funding (`WalletFunding`, was the collateral
1206
+ envelope's `command`) no `account` or `from`, and `createWithdrawal` no
1207
+ `account` and a `vault_withdrawal` without `account` and `to`.
1208
+ `signWithdrawal` returns `{ idempotencyKey, account, body }`.
1209
+ - A stream event is `{stream, event_id, event_type, occurred_at, payload}`.
1210
+ `ENTRY_RFQ_OPENED` carries the whole open entry RFQ; `onRfq` delivers it, and
1211
+ a cash-out RFQ, as an `Rfq` with `state: "OPEN"` and reads nothing. A
1212
+ replayed opening is skipped once its collection has ended, and otherwise
1213
+ re-read and delivered only while the RFQ is still open.
1214
+ - `GET /v1/me` returns `{ account_id, status, wallet }`.
1215
+ - The attempt routes' `Idempotency-Key` header is optional; `attempt_id` is
1216
+ the key. The SDK still sends it.
1217
+
1218
+ ### Removed
1219
+
1220
+ - `quote_digest` and `taker_signature` inside a wallet funding (copies of the
1221
+ accept's own).
1222
+ - `chain_id` and `vault_address` on book offers (the list, the snapshot's
1223
+ `book_quotes` and `BOOK_QUOTE_PUBLISHED`), on the publication checkpoint,
1224
+ and `max_frame_bytes` on `session.ready`: read the deployment from
1225
+ `/v1/vault`.
1226
+ - `schema_version`, `resource_kind` and `resource_id` on stream events; the
1227
+ `rfqDetails` stream option and the event frame's `rfq`.
1228
+ - `state` and `terminal_reason` on `ENTRY_RFQ_OPENED` and `CASHOUT_RFQ_OPENED`
1229
+ payloads (the event type says it is OPEN).
1230
+ - The retired `ENTRY_QUOTE_DISPLAYED`, `CASHOUT_BID_DISPLAYED` and
1231
+ `*_REMOVED_FROM_DISPLAY` events and their payload types.
1232
+ - `state` and `operation_id` on `MakerConfirmationRequest`.
1233
+ - `LegacyTerminalCashoutRfq`.
1234
+ - `wallets`, `owner`, `signer` and `privy_did` on `GET /v1/me`.
1235
+
1236
+ ## 0.11.0
1237
+
1238
+ Account and maker reads carry amounts, not envelopes (TT-1866). Needs contract
1239
+ 115. Breaking.
1240
+
1241
+ ### Changed
1242
+
1243
+ - Every account-read amount (`Metric`, `UnsignedMetric`) is an atomic USDC
1244
+ string, or `null` when unavailable. One `context: { as_of, status }` per
1245
+ response replaces each amount's asset, authority, sources, method, time,
1246
+ status and reason.
1247
+ - `context` is `{ as_of, status }`. Paging binds to one snapshot through the
1248
+ opaque `next_cursor`; there is no `snapshot_id` to compare.
1249
+ - An activity lists `transaction_hashes` (was `evidence`), and each effect is
1250
+ `{ bucket, delta, classification }`.
1251
+ - `GET /v1/me/balances` returns the one balance at the top level (was
1252
+ `balances[0]`), without `product` or `unit`. A `Checkpoint` has no
1253
+ `chain_id`. The `ProductBalanceList` type is `Balance`.
1254
+ - The activity, position and list types are shared by account and maker
1255
+ reads: `ActivityList`, `ActivityDetail` and `PositionList` (were the
1256
+ `Account…` and `Maker…` variants).
1257
+
1258
+ ### Removed
1259
+
1260
+ - `contract_version` and `scope` on account and maker reads.
1261
+ - `funding_id` and `transfer_id` on an activity, and the `asset` activity
1262
+ filter.
1263
+ - `initial_exposure` (it is `signed_payout - net_stake`) and
1264
+ `claim_evidence_ids` on a position; `total_net_stake`,
1265
+ `total_initial_exposure` and `activity_url` on position reads.
1266
+ - `allocated_wallet_cash` on maker capital; `asset`, `bucket`, `funding_id`,
1267
+ `expires_at` and evidence IDs on its reservations.
1268
+ - `unrealized_pnl`, `return_on_capital` and `gas_by_asset` on maker
1269
+ performance, which were never available.
1270
+ - `lens_address` on `Release`.
1271
+
1272
+ ## 0.10.0
1273
+
1274
+ Market data carries only what a reader uses (TT-1866). Needs contract 114.
1275
+ Breaking.
1276
+
1277
+ ### Changed
1278
+
1279
+ - `Market.dates` is always present, and also carries `scheduled_event_at`,
1280
+ `observation_ends_at` and `market_class`. It is null only when the market has
1281
+ neither reviewed timing nor a market class.
1282
+ - `Question` and `MarketDetail` carry `catalog_generation`; a `MarketDetail`'s
1283
+ `question.markets` omits the requested market, which is `market`.
1284
+ - `MarketHistory` carries `side`, `scale` and `volume_scale` once; each bar is
1285
+ `{minute, open, high, low, close, volume, trade_count}`. A scale change starts
1286
+ a new page. `include_gaps` defaults to `false`.
1287
+ - `MarketDetail.stats` is `{volume_24h, open_interest}` in atomic USDC.
1288
+ - `MarketDetail.metadata` is `{content: {title, rules}, parent, sides: [{side,
1289
+ label}]}`.
1290
+
1291
+ ### Removed
1292
+
1293
+ - From `Market`: `deadline`, `quote_asset`, `catalog_generation`, `source`,
1294
+ `taxonomy_state`, `taxonomy_source` and `taxonomy_version`. From its sides:
1295
+ `asset_id`, and the reference's `source`, `feed_generation` and
1296
+ `source_time`; `quality` names the feed class.
1297
+ - The same provenance fields from `Question` and discovery items, and the
1298
+ `CatalogSource`, `TaxonomySource`, `TaxonomyState` and `TaxonomyVersion`
1299
+ types.
1300
+ - `MarketDetail.feed_generation`, and `price_semantics`, `volume_semantics`,
1301
+ `interval` and `fill_policy` from `MarketHistory`, which follow from
1302
+ `series_type`.
1303
+
1304
+ The market stream's catalog entries and references keep their shape
1305
+ (`FeedReference`).
1306
+
1307
+ ## 0.9.0
1308
+
1309
+ Partners call only what trading needs (TT-1841). Needs contract 112. Breaking.
1310
+
1311
+ ### Changed
1312
+
1313
+ - `withdraw`, `signWithdrawal` and `sendWithdrawal` send
1314
+ `POST /v1/withdrawals` (was `/v1/totalis-withdrawals`), and follow
1315
+ `WITHDRAWAL_UPDATED` on a `WITHDRAWAL` (was
1316
+ `TOTALIS_WITHDRAWAL_CONTINUATION_UPDATED` on a `CONTINUATION`), reading
1317
+ `GET /v1/withdrawals/{withdrawal_id}` only after a reconnect.
1318
+ - A withdrawal is the `Withdrawal` type (was `TotalisWithdrawal`) and its ID is
1319
+ `withdrawal_id` (was `continuation_id`); `onStarted` and `waitForWithdrawal`
1320
+ take that ID.
1321
+
1322
+ ### Removed
1323
+
1324
+ - `deposit` and `POST /v1/deposits`: `placeBet` already funds a vault
1325
+ shortfall from the wallet in the accept. The `DepositAccepted` type.
1326
+ - `withdrawFromVault` and the vault-only `POST /v1/withdrawals`: `withdraw`
1327
+ moves any vault shortfall on its way out. The `OperationAccepted` type.
1328
+ - `settleTicket`, `claimTicket` and the ticket routes (`/claims`,
1329
+ `/settlements`, `/transfers`): Totalis settles and claims every decided
1330
+ ticket itself. `transferTypedData` and the plain `Transfer` type.
1331
+ - `POST /v1/operations/{operation_id}/self-funded-transaction`; a maker's
1332
+ `reduceCollateral` keeps its own route.
1333
+ - The `ticket:settle` and `ticket:transfer` key scopes, and `operations:submit`
1334
+ for personal keys.
1335
+
1336
+ ## 0.8.0
1337
+
1338
+ A maker key reads its own account through `/v1/me`, and the maker stream is its
1339
+ only replay (TT-1841). Needs contract 111. Breaking.
1340
+
1341
+ ### Changed
1342
+
1343
+ - `TotalisStream` resumes a persisted `cursor` on the stream itself: the hello
1344
+ carries it and the venue replays the retained events after it, or resets to
1345
+ a snapshot. `createMaker` no longer reads events over HTTP first. Every
1346
+ `event` listener now receives the frame.
1347
+ - The maker snapshot has no `quotes` class, and its `operations` continuation is
1348
+ `GET /v1/me/operations`.
1349
+ - A maker key reads `GET /v1/me/positions[/{ticket_id}]`,
1350
+ `GET /v1/me/activity[/{activity_id}]`, `GET /v1/me/operations` and
1351
+ `GET /v1/operations/{operation_id}` for its maker.
1352
+
1353
+ ### Removed
1354
+
1355
+ - The `replay` stream option and `replayPages`.
1356
+ - Calls to `GET /v1/makers/{maker_id}/events`, `/snapshot`, `/offers`,
1357
+ `/operations[/{operation_id}]`, `GET /v1/me/makers` and
1358
+ `GET /v1/hypercore/history`, which are gone from the venue.
1359
+ - Issuing the `maker:access:read` key scope (its reads are app-session only).
1360
+
1361
+ ## 0.7.0
1362
+
1363
+ Market data is list, detail and history (TT-1841). Needs contract 110. Breaking.
1364
+
1365
+ ### Changed
1366
+
1367
+ - `GET /v1/markets/{outcome_id}` (`MarketDetail`) also carries `metadata`
1368
+ (the product metadata at the market's catalog generation),
1369
+ `recurring_round` (null outside a recurring series) and `stats` (the
1370
+ market's 24h volume and open interest, null before a snapshot).
1371
+
1372
+ ### Removed
1373
+
1374
+ - `GET /v1/markets/{outcome_id}/metadata` (read `metadata` on the market
1375
+ detail) and `GET /v1/questions` (read `question` on the market detail),
1376
+ with the `STALE_CATALOG` error code.
1377
+
1378
+ ## 0.6.0
1379
+
1380
+ An external withdrawal is one request (TT-1775). Needs contract 109. Breaking.
1381
+
1382
+ ### Changed
1383
+
1384
+ - `withdraw` signs the Exit for any wallet shortfall and the USDC
1385
+ `TransferWithAuthorization` payout up front and sends them in one
1386
+ `POST /v1/totalis-withdrawals` (`payout_authorization`). The payout's nonce is
1387
+ `payoutNonce(release, account, idempotencyKey)`, so the signature is bound to
1388
+ that request. It resolves at `PAYOUT_COMMITTED` from
1389
+ `TOTALIS_WITHDRAWAL_CONTINUATION_UPDATED`, which now carries the whole
1390
+ withdrawal, and reads `GET /v1/totalis-withdrawals/{id}` only after a
1391
+ reconnect. `FAILED` throws; the USDC is then still in the vault or the
1392
+ wallet.
1393
+ - `transferWithAuthorizationTypedData(release, payout)` takes
1394
+ `{ from, to, value, valid_after, valid_before, nonce }`.
1395
+ - A withdrawal is `VAULT_WITHDRAWAL_QUEUED`, `PAYOUT_SUBMITTED`,
1396
+ `PAYOUT_COMMITTED` or `FAILED`, and carries `payout_operation_id`,
1397
+ `payout_transaction_hash` and `updated_at`.
1398
+
1399
+ ### Added
1400
+
1401
+ - `signWithdrawal` and `sendWithdrawal`, to store a signed withdrawal before
1402
+ sending it, and `waitForWithdrawal` to follow one after a restart.
1403
+ - `payoutNonce` and the `PayoutAuthorization` type in `./typed-data`.
1404
+
1405
+ ### Removed
1406
+
1407
+ - `resumeWithdrawal` (use `waitForWithdrawal`), the `WalletTransfer` type, and
1408
+ calls to `/payout-claim` and `/payout-submission`.
1409
+
1410
+ ## 0.5.0
1411
+
1412
+ A maker that starts or reconnects with more than 100 pending confirmation
1413
+ requests now sees all of them (TT-1838). Needs contract 107.
1414
+
1415
+ ### Changed
1416
+
1417
+ - `onConfirmation` pages `GET /v1/makers/{maker_id}/confirmations` when the
1418
+ snapshot names it as the `confirmations` continuation, and handles every
1419
+ request it returns once, like the snapshot's and the stream's. A failed read
1420
+ reaches `onError` without a request, so its `request` parameter is now
1421
+ optional.
1422
+
1423
+ ## 0.4.0
1424
+
1425
+ Fewer RFQ routes: the taker keeps the book from the account stream, and entry
1426
+ and cash-out share one accept (TT-1835). Needs contract 106. Breaking.
1427
+
1428
+ ### Changed
1429
+
1430
+ - The taker's book comes from the account stream: the snapshot's
1431
+ `book_quotes`, then `BOOK_QUOTE_PUBLISHED` and `BOOK_QUOTE_REMOVED`.
1432
+ `GET /v1/rfqs/{rfq_id}/book-quotes` is read only for an RFQ followed after a
1433
+ snapshot that truncated `book_quotes`. `BookQuote` is the one offer shape
1434
+ for both kinds; choosers take `Chooser<EntryQuote>` (`bestQuote`) or
1435
+ `Chooser<CashoutBid>` (`bestBid`) with the venue clock. Expiry sends no
1436
+ event, so an offer leaves the book (and `watchBook` re-renders) once it has
1437
+ no more signed life than the venue needs to begin on it: 2 s for a quote,
1438
+ 22 s for a bid.
1439
+ - `placeBet` and `cashOut` use one accept,
1440
+ `POST /v1/rfqs/{rfq_id}/attempts/{attempt_id}`. `cashOut` has the owner sign
1441
+ the bid's `SellBack` or `CashoutTransfer` before the accept and returns
1442
+ `{ rfqId, attemptId, quoteDigest, state, operationId, outcome }`: `COMMITTED`
1443
+ with `operationId` means the sell-back or transfer is queued. `bid_digest` is
1444
+ now `quote_digest`.
1445
+ - A lost accept the venue never received is recovered by reading the attempt,
1446
+ cancelling the RFQ (204 or 409) and reading again; still absent is
1447
+ `{ state: "NOT_ADMITTED" }`. `ABANDONED` is gone.
1448
+ - `createMaker`: `bid` publishes on `POST /v1/rfqs/{rfq_id}/book-quotes` with
1449
+ `{ quote_digest, sell_back | transfer }` and returns `quoteDigest`.
1450
+ `onConfirmation` answers `CONFIRMATION_REQUESTED` (live, or replayed from
1451
+ `GET /v1/makers/{maker_id}/events` on resume) and the snapshot's
1452
+ `confirmations`, including requests delivered before it was attached; its
1453
+ `onError` always receives the request. `MakerConfirmationRequest` is the
1454
+ event's payload type.
1455
+
1456
+ ### Removed
1457
+
1458
+ - `watchCashoutBook` (`watchBook` renders quotes and bids) and the
1459
+ `CashoutConfirmation` type.
1460
+ - Calls to `/cashout-book`, `/cashout-attempts`, `/attempts/{id}/abandon`,
1461
+ `/tickets/{ticket_id}/sell-back` and `GET /v1/makers/{maker_id}/confirmations`.
1462
+
1463
+ ### Added
1464
+
1465
+ - `stream.serverNow()`: the venue clock from `session.ready` and publication
1466
+ checkpoints.
1467
+ - `EntryQuote` and `NotAdmitted` types.
1468
+
1469
+ ## 0.3.1
1470
+
1471
+ ### Fixed
1472
+
1473
+ - `withdraw` / `resumeWithdrawal` no longer wait forever after the vault
1474
+ top-up or the payout commits. The venue advances a withdrawal only when it is
1475
+ read, so the flow now also re-reads on the `WITHDRAWAL_REPORT` or
1476
+ `EXECUTION_REPORT` of the withdrawal's own operation, and on
1477
+ `WALLET_BALANCE_CHANGED` for its wallet (found by TT-1778).
1478
+
1479
+ ## 0.3.0
1480
+
1481
+ Helpers for the flows the SDK-first docs could only show as raw API calls, and
1482
+ fees and USDC read from `GET /v1/vault` (TT-1832). Needs contract 105.
1483
+
1484
+ ### Added
1485
+
1486
+ - `createTotalis`: `withdrawFromVault` (direct `POST /v1/withdrawals` with a
1487
+ signed Exit), `settleTicket` and `claimTicket`.
1488
+ - `createMaker`: `controller()` builds the maker's vault transactions
1489
+ (`setQuoteSigner`, `approveUsdc`, `deposit`, `requestWithdraw`,
1490
+ `executeWithdraw`, `cancelWithdraw`, `resetDiscount`) from the canonical ABI
1491
+ for the controller wallet to send; `reduceCollateral` follows a collateral
1492
+ reduction and can submit its attestation through the self-funded route.
1493
+ - `/maker` also exports `controllerTransactions`,
1494
+ `openMakerVaultTransaction`, `encodeCall` and `TransactionCall`.
1495
+
1496
+ ### Changed
1497
+
1498
+ - `createMaker` no longer takes `fees`: quotes carry the vault's current
1499
+ `fee_bps` and `taker_fee_bps`, read from `GET /v1/vault` for every quote so a
1500
+ governance change applies at once, and `quote` throws until the venue
1501
+ publishes them.
1502
+ - `usdcDomain(release)`, `receiveWithAuthorizationTypedData(release, …)` and
1503
+ `transferWithAuthorizationTypedData(release, transfer, window)` take USDC and
1504
+ its signing domain from the release; `usdcTokens` is removed.
1505
+
1506
+ ## 0.2.0
1507
+
1508
+ The SDK core on the current API (TT-1784).
1509
+
1510
+ ### Added
1511
+
1512
+ - `createTotalis`: `placeBet` (RFQ, book from the stream, one synchronous
1513
+ accept, wallet funding of a vault shortfall), `cashOut`, `deposit`,
1514
+ `withdraw` / `resumeWithdrawal` (sponsored Totalis withdrawal),
1515
+ `waitForOperation`, `watchBook` / `watchCashoutBook`, `issueApiKey` /
1516
+ `rotateApiKey`.
1517
+ - `createMaker` (`/maker`): `quote`, `bid`, `withdraw`, `confirm`,
1518
+ `onConfirmation`, `onRfq`, with HTTP replay from a persisted cursor.
1519
+ - `TotalisStream` (`/realtime`): snapshot, replay, deduplication, reconnect
1520
+ with backoff, close-reason retry handling and stale-socket detection.
1521
+ - A request layer: every client resends the same bytes and `Idempotency-Key`
1522
+ after network failures and `BACKOFF` errors, honouring `Retry-After`;
1523
+ `unwrap` throws `ApiError`; `NetworkError` (with `resend()` for flow commands); `sendOnce`; `uuidv7`; `envelope`.
1524
+ - `pages`, `items` and `replayPages` over the TT-1771 list shape.
1525
+ - `toTotalisSigner` (`/signer`) for viem accounts and wallet clients,
1526
+ EIP-1193 providers and ethers signers.
1527
+ - Typed data: `hashTypedData`, `hashDomain`, `receiveWithAuthorizationTypedData`,
1528
+ `depositNonce`, `transferWithAuthorizationTypedData`, `usdcDomain`,
1529
+ `canonicalSignature`, `issueKeyMessage`, `parseIssueKeyMessage`.
1530
+ - `ApiClientOptions`: `baseUrl`, `retry`, and `accessToken` as a function.
1531
+ - Node bot and browser-wallet examples.
1532
+
1533
+ ### Changed
1534
+
1535
+ - `signTotalis` returns a canonical signature (v in {27, 28}).
1536
+ - `./errors` also exports `ApiError` and `NetworkError`.
1537
+
1538
+ ## 0.1.0
1539
+
1540
+ Generated client, maker, operator, realtime, browse and account-read types;
1541
+ API-key client; typed data for vault signatures.