@0xmonaco/types 1.0.77 → 1.0.80

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.
@@ -26,7 +26,11 @@ export interface MarginAccountSummary {
26
26
  /** Equity headroom: equity less the initial margin requirement. */
27
27
  freeCollateral: string;
28
28
  /**
29
- * The largest amount a transfer-out of this scope will actually accept.
29
+ * The largest amount a transfer-out of this scope accepts without lowering
30
+ * any position's posted margin, so without moving a leverage or a
31
+ * liquidation price. A removal from an isolated risk bucket with one open
32
+ * position can take more, out of that position's margin: see
33
+ * `maxRemovableCollateral`.
30
34
  *
31
35
  * Not a clamped `freeCollateral`. Free collateral is equity headroom, and
32
36
  * equity includes mark-to-market gains that a transfer cannot move — so the
@@ -93,6 +97,24 @@ export interface MarginAccountSummary {
93
97
  * precision, like `withdrawableCollateral`.
94
98
  */
95
99
  availableOrderCollateral?: string;
100
+ /**
101
+ * The largest removal from this risk bucket the risk engine accepts when the
102
+ * removal may also lower the posted margin of the bucket's one open
103
+ * position: `withdrawableCollateral` plus the position's margin above its
104
+ * initial margin at the mark, capped by what the parent margin account
105
+ * accepts. Everything past `withdrawableCollateral` comes out of the
106
+ * position's margin, so it raises the position's leverage and moves its
107
+ * liquidation price toward the mark.
108
+ *
109
+ * Equal to `withdrawableCollateral` on a cross risk bucket and on an
110
+ * isolated one with no open position or several.
111
+ *
112
+ * Present only on risk-bucket rows served from a live risk engine snapshot;
113
+ * absent (the key is omitted, never null) on parent rows and on
114
+ * persisted-fallback reads. Truncated toward zero at the quote asset's
115
+ * precision, like `withdrawableCollateral`.
116
+ */
117
+ maxRemovableCollateral?: string;
96
118
  /**
97
119
  * Copy trading: present only on a copy risk bucket row (a follow's copy
98
120
  * account — its cross risk bucket and any isolated children). The id of the
@@ -93,7 +93,8 @@ export interface PitpassAPI extends BaseAPI {
93
93
  transferRewards(params: TransferRewardsParams): Promise<TransferRewardsResponse>;
94
94
  /**
95
95
  * Read your own referral position: your referral chain upward (`upline`, L1
96
- * then L2 then L3), your direct referrer, total earned, and most recent
96
+ * then L2 and onward, as many levels as your trades on this client
97
+ * application pay), your direct referrer, total earned, and most recent
97
98
  * reward rows.
98
99
  *
99
100
  * Self-scoped — the server derives your identity from the session, so you can
@@ -125,7 +126,8 @@ export interface PitpassAPI extends BaseAPI {
125
126
  * referred (yourself when `parent` is omitted), a page at a time, newest
126
127
  * first. Expand a node by calling again with `parent` set to its wallet;
127
128
  * nodes with `refereeCount > 0` are expandable, down to the deepest level
128
- * PitPass rewards (configured by Monaco, at most 10).
129
+ * any client application rewards (at most 10). Your direct referees (L1)
130
+ * are always listed.
129
131
  *
130
132
  * Self-scoped: `parent` must be you or one of your own referees above that
131
133
  * deepest level — any other wallet is a 404. Each wallet appears once, under the referrer that
@@ -107,13 +107,13 @@ export const ReferralRewardEntrySchema = z.object({
107
107
  source: z.string(),
108
108
  /** Human-facing name for the source: their custom handle if claimed, else the wallet. */
109
109
  sourceDisplay: z.string(),
110
- /** Referral level (1 = direct/30%, 2 = 15%, 3 = 5%). */
110
+ /** Referral level: 1 (direct), 2, and so on (at most 10). */
111
111
  level: z.number(),
112
112
  /** Reward amount, in RAW atomic units of the token. */
113
113
  amount: z.string(),
114
114
  /** Reward token contract address (0x-prefixed). */
115
115
  token: z.string(),
116
- /** The referral rate applied, as a decimal fraction (e.g. `0.30` for L1). */
116
+ /** The referral rate applied, as a decimal fraction (e.g. `0.30`). */
117
117
  rateApplied: z.string(),
118
118
  /** RFC 3339 timestamp when the reward row was recorded. */
119
119
  createdAt: z.string(),
@@ -124,14 +124,15 @@ export const ReferralUplineEntrySchema = z.object({
124
124
  wallet: z.string(),
125
125
  /** Human-facing name for the ancestor: their custom handle if claimed, else the wallet. */
126
126
  display: z.string(),
127
- /** How far above the caller this ancestor is: 1 (direct referrer), 2, or 3. */
127
+ /** How far above the caller this ancestor is: 1 (direct referrer), 2, and so on (at most 10). */
128
128
  level: z.number(),
129
129
  });
130
130
  /** The caller's own referral position: who referred them and what they've earned. */
131
131
  export const GetMyReferralPositionResponseSchema = z.object({
132
132
  /**
133
133
  * Public wallet address of the caller's direct (L1) referrer. Empty string
134
- * when the caller was not referred. Same wallet as the first `upline` entry.
134
+ * when the caller was not referred. Same wallet as the first `upline` entry
135
+ * whenever `upline` is not empty.
135
136
  */
136
137
  referrer: z.string(),
137
138
  /** Human-facing name for the referrer: their custom handle if claimed, else the wallet (empty when not referred). */
@@ -141,10 +142,12 @@ export const GetMyReferralPositionResponseSchema = z.object({
141
142
  /** The caller's most recent reward rows, newest first (bounded server-side). */
142
143
  rewards: z.array(ReferralRewardEntrySchema),
143
144
  /**
144
- * The caller's referral chain upward, nearest first: L1, L2, and so on, at
145
- * most as many entries as PitPass currently rewards levels (at most 10);
146
- * empty when the caller was not referred. These are the wallets the caller's
147
- * own trades pay referral rewards to.
145
+ * The caller's referral chain upward, nearest first: L1, L2, and so on, as
146
+ * many levels as the caller's trades on this client application pay (at
147
+ * most 10). Shorter when the chain ends; empty when the caller was not
148
+ * referred or this client application pays no referral levels. These are the
149
+ * wallets the caller's own trades on this client application pay referral
150
+ * rewards to.
148
151
  */
149
152
  upline: z.array(ReferralUplineEntrySchema),
150
153
  });
@@ -241,7 +244,7 @@ export const ReferralTreeNodeSchema = z.object({
241
244
  wallet: z.string(),
242
245
  /** Human-facing name: their custom handle if claimed, else the wallet. */
243
246
  display: z.string(),
244
- /** Depth below the caller: 1 (you referred them), 2, and so on up to the configured reward depth (at most 10). */
247
+ /** Depth below the caller: 1 (you referred them), 2, and so on, as deep as any client application rewards (at most 10). */
245
248
  level: z.number(),
246
249
  /** Wallet address of this node's referrer — your own wallet for a level-1 node. */
247
250
  parent: z.string(),
@@ -195,8 +195,10 @@ export interface PortfolioRiskBucket {
195
195
  unrealizedPnl: string;
196
196
  positionCount: number;
197
197
  /**
198
- * The largest transfer-out of this risk bucket the engine will actually
199
- * accept. NOT a clamped `freeCollateral`: the bucket's allocated
198
+ * The largest transfer-out of this risk bucket the engine accepts without
199
+ * lowering a position's posted margin; a removal from an isolated risk
200
+ * bucket with one open position can take more (`maxRemovableCollateral`).
201
+ * NOT a clamped `freeCollateral`: the bucket's allocated
200
202
  * collateral plus its realized PnL, less funding paid, unrealized losses
201
203
  * and the margin its positions and resting orders require. Realized profit
202
204
  * can leave a live bucket this way (the bucket's allocation may go
@@ -218,6 +220,18 @@ export interface PortfolioRiskBucket {
218
220
  * (the key is omitted, never null) on persisted-fallback reads.
219
221
  */
220
222
  availableOrderCollateral?: string;
223
+ /**
224
+ * The largest removal from this risk bucket the engine accepts when the
225
+ * removal may also lower the posted margin of the bucket's one open
226
+ * position, down to its initial margin at the mark — the same figure as
227
+ * `MarginAccountSummary.maxRemovableCollateral`. Equal to
228
+ * `withdrawableCollateral` for a cross risk bucket and for an isolated one
229
+ * with no open position or several.
230
+ *
231
+ * Present only when a live risk engine snapshot served it; absent (the key
232
+ * is omitted, never null) on persisted-fallback reads.
233
+ */
234
+ maxRemovableCollateral?: string;
221
235
  /**
222
236
  * The mode this bucket is margined under.
223
237
  *
@@ -13,6 +13,37 @@ export type PositionStatus = "OPEN" | "CLOSED" | "LIQUIDATING" | "LIQUIDATED" |
13
13
  */
14
14
  export type PositionStatusFilter = "OPEN" | "CLOSED" | "LIQUIDATING" | "LIQUIDATED";
15
15
  export type ClosePositionType = "MARKET" | "LIMIT" | "IOC";
16
+ /**
17
+ * Whether a position's lifetime totals (`exitPrice`, `realizedRoe`,
18
+ * `feesPaid`, `fundingPaid`, `cumFees`, `netRealizedPnl`) are served, and if
19
+ * not, whether they will be. The server never sends
20
+ * `LIFETIME_TOTALS_STATUS_UNSPECIFIED`.
21
+ *
22
+ * - `LIFETIME_TOTALS_STATUS_COMPLETE`: the position's history covers its whole
23
+ * lifetime. The lifetime fields are served under their own rules (a
24
+ * terminal row's `netRealizedPnl`, `realizedRoe` and `cumFees` can still wait
25
+ * on the position's PnL sample).
26
+ * - `LIFETIME_TOTALS_STATUS_PENDING`: the position's history is still being
27
+ * written up to this row's `version`, or the row changed while it was being
28
+ * read. Every lifetime field is absent.
29
+ * Temporary: retry the read after a short backoff (seconds). Until the
30
+ * position-history checkpoint is seeded, PENDING arises only when the
31
+ * position row changed between the row read and the totals read.
32
+ * - `LIFETIME_TOTALS_STATUS_INCOMPLETE`: the lifetime totals are not complete
33
+ * now, and a quick retry will not change that. A gap in legacy history (or
34
+ * reducing executions that do not reconcile with `realizedPnl`) is
35
+ * permanent; a maintained-totals row that is missing or has drifted is
36
+ * repaired by the background reconcile (at startup and daily), after which
37
+ * the row reads COMPLETE. Every lifetime field that is present comes from
38
+ * the maintained totals, which are cross-checked against each other and
39
+ * repaired by the background reconcile (e.g. `exitPrice` can be present
40
+ * while `cumFees` is absent). `OPEN` and `LIQUIDATING` positions are
41
+ * checked against realized PnL too: an `OPEN` or `LIQUIDATING` row whose
42
+ * reductions do not account for it is INCOMPLETE with no `cumFees`.
43
+ *
44
+ * Never read an absent lifetime field as zero.
45
+ */
46
+ export type LifetimeTotalsStatus = "LIFETIME_TOTALS_STATUS_UNSPECIFIED" | "LIFETIME_TOTALS_STATUS_COMPLETE" | "LIFETIME_TOTALS_STATUS_PENDING" | "LIFETIME_TOTALS_STATUS_INCOMPLETE";
16
47
  export interface Position {
17
48
  positionId: string;
18
49
  marginAccountId: string;
@@ -108,6 +139,9 @@ export interface Position {
108
139
  * of PnL retention, or for positions predating the PnL service — rather than
109
140
  * an understated partial. On a terminal row it is also null until the
110
141
  * final close is recorded in its PnL sample, or while fee data is incomplete.
142
+ * On an `OPEN` or `LIQUIDATING` row it is also null when the position's reductions do not
143
+ * account for its `realizedPnl` (`lifetimeTotalsStatus` INCOMPLETE), rather
144
+ * than an understated total.
111
145
  */
112
146
  cumFees?: string;
113
147
  /**
@@ -162,6 +196,14 @@ export interface Position {
162
196
  * version.
163
197
  */
164
198
  openedAt?: string | null;
199
+ /**
200
+ * Whether this row's lifetime totals are served — see
201
+ * {@link LifetimeTotalsStatus}. Set on every REST read row; `null` or absent
202
+ * from a server that predates the field. WebSocket position frames do not
203
+ * carry it. Widened with `string` so a status this SDK version predates is
204
+ * passed through rather than mistyped; handle the unknown case.
205
+ */
206
+ lifetimeTotalsStatus?: LifetimeTotalsStatus | (string & {}) | null;
165
207
  }
166
208
  export interface ListPositionsParams {
167
209
  marginAccountId?: string;
@@ -179,9 +221,12 @@ export interface ListPositionsParams {
179
221
  * **Order depends on the filter.** `status: "OPEN"` is answered from the
180
222
  * matching engine's live view and is ordered by
181
223
  * `(marginAccountId, tradingPairId, positionId)` ascending — stable, but
182
- * UUID order, NOT newest-first. Every other filter reads persisted rows
183
- * newest-opened first. The two are separate cursor spaces, so a token is
184
- * only valid in the one that minted it, and crossing between them is
224
+ * UUID order, NOT newest-first. `status: "CLOSED"` and
225
+ * `status: "LIQUIDATED"` read persisted rows newest-closed first, so a
226
+ * position held for weeks and closed today leads the list. Every other
227
+ * filter reads persisted rows newest-opened first. Each is a separate
228
+ * cursor space, so a token is only valid in the one that minted it, and
229
+ * crossing between the live and persisted walks is
185
230
  * ASYMMETRIC: a persisted token offered to `status: "OPEN"` is served by
186
231
  * the persisted walk while the engine is reachable, but a LIVE token
187
232
  * cannot cross — once the engine is unreachable the request is a 400 and
@@ -44,7 +44,10 @@ export interface Order {
44
44
  averageFillPrice?: string;
45
45
  /** Trading mode (SPOT or MARGIN) */
46
46
  tradingMode: TradingMode;
47
- /** Time in force - GTC, IOC, or FOK (GTD is deprecated and rejected) */
47
+ /**
48
+ * Time in force - GTC, IOC, or FOK (GTD is deprecated and rejected).
49
+ * Absent on a MARKET order, which has none.
50
+ */
48
51
  timeInForce?: TimeInForce;
49
52
  /** Order creation timestamp (ISO 8601) */
50
53
  createdAt: string;
@@ -42,17 +42,20 @@
42
42
  * baseline over REST for the extra consumer.
43
43
  *
44
44
  * Where the server has no snapshot arm for a channel yet, the callback is
45
- * simply never invoked — a silent no-op, not an error. `orderbook`, `ohlcv`,
46
- * `trades` and `movements` take no `onSnapshot` at all: they stream events
47
- * rather than state, and the channel-coverage lock pins that classification
48
- * against the server's own snapshot dispatch.
45
+ * simply never invoked — a silent no-op, not an error. `orderbook`, `ohlcv`
46
+ * and `movements` take no `onSnapshot` at all: they stream events rather than
47
+ * state, and the channel-coverage lock pins that classification against the
48
+ * server's own snapshot dispatch. `trades` is also an event stream, but its
49
+ * `onSnapshot` delivers the pair's newest trades as a recent-history baseline:
50
+ * it can overlap the first live trades, or miss one executed just before the
51
+ * subscribe, so a consumer dedupes on `tradeId`.
49
52
  */
50
53
  import type { SessionCredentials } from "../auth/index";
51
54
  import type { Interval } from "../market";
52
55
  import type { TradingMode } from "../trading";
53
56
  import type { WebSocketStatus } from "./base";
54
57
  import type { OrderbookQuotationMode } from "./clients/orderbook-client";
55
- import type { AccountEvent, AccountEventData, ConditionalOrderEvent, ConditionalOrderEventData, CopyEvent, CopyRelationshipEventData, InstrumentEvent, InstrumentEventData, LiquidationEvent, LiquidationEventData, MarketStatsAllEvent, MarketStatsData, MarketStatsEvent, MarketStatsSummary, OHLCVEvent, OHLCVPriceType, OrderbookEvent, OrderEvent, PositionEvent, PositionEventData, PositionValuationEvent, TradeEvent, TwapOrderEvent, TwapOrderEventData, UserBalanceEvent, UserBalanceEventData, UserMovementEvent } from "./events";
58
+ import type { AccountEvent, AccountEventData, ConditionalOrderEvent, ConditionalOrderEventData, CopyEvent, CopyRelationshipEventData, InstrumentEvent, InstrumentEventData, LiquidationEvent, LiquidationEventData, MarketStatsAllEvent, MarketStatsData, MarketStatsEvent, MarketStatsSummary, OHLCVEvent, OHLCVPriceType, OrderbookEvent, OrderEvent, PositionEvent, PositionEventData, PositionValuationEvent, TradeEvent, TradeEventData, TwapOrderEvent, TwapOrderEventData, UserBalanceEvent, UserBalanceEventData, UserMovementEvent } from "./events";
56
59
  import type { OrderSnapshotItem, SnapshotHandler } from "./snapshots";
57
60
  export type MessageHandler<T> = (data: T) => void;
58
61
  export interface MonacoWebSocket {
@@ -72,8 +75,11 @@ export interface MonacoWebSocket {
72
75
  orderbook: (tradingPairId: string, tradingMode: TradingMode, magnitude: number, quotationMode: OrderbookQuotationMode, handler: MessageHandler<OrderbookEvent>) => () => void;
73
76
  /** Subscribe to OHLCV candlestick events (public) */
74
77
  ohlcv: (tradingPairId: string, tradingMode: TradingMode, interval: Interval, handler: MessageHandler<OHLCVEvent>, priceType?: OHLCVPriceType) => () => void;
75
- /** Subscribe to trade events (public) */
76
- trades: (tradingPairId: string, handler: MessageHandler<TradeEvent>) => () => void;
78
+ /**
79
+ * Subscribe to trade events (public); `onSnapshot` receives the pair's newest 50 trades, newest first.
80
+ * The snapshot can overlap the first live trades or miss one executed just before subscribing, so dedupe on `tradeId`.
81
+ */
82
+ trades: (tradingPairId: string, handler: MessageHandler<TradeEvent>, onSnapshot?: SnapshotHandler<TradeEventData>) => () => void;
77
83
  /** Subscribe to user movement events (requires authentication) */
78
84
  movements: (handler: MessageHandler<UserMovementEvent>) => () => void;
79
85
  /** Subscribe to user order events for all trading pairs (requires authentication); `onSnapshot` receives every resting order */
@@ -42,8 +42,11 @@
42
42
  * baseline over REST for the extra consumer.
43
43
  *
44
44
  * Where the server has no snapshot arm for a channel yet, the callback is
45
- * simply never invoked — a silent no-op, not an error. `orderbook`, `ohlcv`,
46
- * `trades` and `movements` take no `onSnapshot` at all: they stream events
47
- * rather than state, and the channel-coverage lock pins that classification
48
- * against the server's own snapshot dispatch.
45
+ * simply never invoked — a silent no-op, not an error. `orderbook`, `ohlcv`
46
+ * and `movements` take no `onSnapshot` at all: they stream events rather than
47
+ * state, and the channel-coverage lock pins that classification against the
48
+ * server's own snapshot dispatch. `trades` is also an event stream, but its
49
+ * `onSnapshot` delivers the pair's newest trades as a recent-history baseline:
50
+ * it can overlap the first live trades, or miss one executed just before the
51
+ * subscribe, so a consumer dedupes on `tradeId`.
49
52
  */
@@ -12,7 +12,11 @@
12
12
  *
13
13
  * A subscribe-time snapshot arrives ahead of the live diffs, carrying one row
14
14
  * per margin account you own IN THE APPLICATION YOU AUTHENTICATED UNDER -
15
- * including FLAT accounts, which the live producer never emits for. Live
15
+ * including FLAT accounts. A flat account sends no periodic frame; it gets a
16
+ * live frame (on the same per-account `sequence`) only after its collateral
17
+ * moves. Moves before the producer's next tick collapse into one frame with
18
+ * the latest state, normally within ~2s; a burst wider than 512 flat accounts
19
+ * spreads over the following ticks. Live
16
20
  * delivery is wider: it is per user and carries no application filter, so if
17
21
  * the same wallet trades through more than one application you also receive
18
22
  * live frames for those accounts. Do NOT treat an account absent from the
@@ -12,7 +12,11 @@
12
12
  *
13
13
  * A subscribe-time snapshot arrives ahead of the live diffs, carrying one row
14
14
  * per margin account you own IN THE APPLICATION YOU AUTHENTICATED UNDER -
15
- * including FLAT accounts, which the live producer never emits for. Live
15
+ * including FLAT accounts. A flat account sends no periodic frame; it gets a
16
+ * live frame (on the same per-account `sequence`) only after its collateral
17
+ * moves. Moves before the producer's next tick collapse into one frame with
18
+ * the latest state, normally within ~2s; a burst wider than 512 flat accounts
19
+ * spreads over the following ticks. Live
16
20
  * delivery is wider: it is per user and carries no application filter, so if
17
21
  * the same wallet trades through more than one application you also receive
18
22
  * live frames for those accounts. Do NOT treat an account absent from the
@@ -30,7 +30,13 @@
30
30
  * `quoteAssetId`, `baseToken`, `quoteToken`, `baseAssetName`, `quoteAssetName`,
31
31
  * `baseDecimals` and `quoteDecimals`. Perp frames add `minLeverage`. These are
32
32
  * declared optional because a server that predates them omits them.
33
+ *
34
+ * Perp frames also carry `riskTiers`, the market's whole margin ladder in the
35
+ * same {@link RiskTier} shape and values as the REST perp config's
36
+ * `riskTiers`. An edit to any tier emits a `config_change` whose
37
+ * `changedFields` names `risk_tiers`.
33
38
  */
39
+ import type { RiskTier } from "../../market";
34
40
  /**
35
41
  * The kind of instrument change a frame reports.
36
42
  *
@@ -118,6 +124,13 @@ export interface InstrumentEventData {
118
124
  initialMarginRate?: string;
119
125
  /** Maintenance margin rate (decimal string). Perp-only; omitted for spot. */
120
126
  maintenanceMarginRate?: string;
127
+ /**
128
+ * The market's whole margin ladder, ascending by `tierLevel`, with the same
129
+ * fields and values as the REST perp config's `riskTiers` (no
130
+ * `maxPositionSize`). Perp-only; omitted for spot, and declared optional
131
+ * because a server that predates it omits it.
132
+ */
133
+ riskTiers?: RiskTier[];
121
134
  /** Names of the fields this mutation touched (snake_case wire field names) */
122
135
  changedFields: string[];
123
136
  /** Timestamp when the configuration was last updated (ISO 8601) */
@@ -30,4 +30,9 @@
30
30
  * `quoteAssetId`, `baseToken`, `quoteToken`, `baseAssetName`, `quoteAssetName`,
31
31
  * `baseDecimals` and `quoteDecimals`. Perp frames add `minLeverage`. These are
32
32
  * declared optional because a server that predates them omits them.
33
+ *
34
+ * Perp frames also carry `riskTiers`, the market's whole margin ladder in the
35
+ * same {@link RiskTier} shape and values as the REST perp config's
36
+ * `riskTiers`. An edit to any tier emits a `config_change` whose
37
+ * `changedFields` names `risk_tiers`.
33
38
  */
@@ -57,8 +57,11 @@ export interface CommonOrderEventData {
57
57
  quantity?: string;
58
58
  /** Order quantity in RAW (integer, base-unit) precision. Wire: `quantity_raw`. */
59
59
  quantityRaw?: string;
60
- /** Time in force - present in most events */
61
- timeInForce?: TimeInForce | (string & {});
60
+ /**
61
+ * Time in force. `null` on every event of a MARKET order, which has none,
62
+ * and on a maker fill, which does not carry the maker's value.
63
+ */
64
+ timeInForce?: TimeInForce | (string & {}) | null;
62
65
  /**
63
66
  * Client-assigned correlation handle, echoed so an event can be matched to
64
67
  * the request that placed the order without a round trip to `getOrder`.
@@ -127,11 +127,13 @@ export interface PositionEventData {
127
127
  * not move it. Do not use it as a reconciliation key — that is `version`'s
128
128
  * job; this is display metadata.
129
129
  *
130
- * It matches a REST read of the same OPEN position exactly. Two cases come
131
- * from the server's persistence clock instead and differ by the persistence
132
- * lag: a TERMINAL row (this frame carries the engine's close instant, a
133
- * terminal REST read carries the stored one), and any position read after a
134
- * matching-engine restart. Accurate to that lag, not to the microsecond.
130
+ * It matches a REST read of the same OPEN position exactly. A TERMINAL REST
131
+ * read carries the instant the matching engine emitted the close, which can
132
+ * differ slightly from this frame's close instant; older terminal rows may
133
+ * instead carry the server's persistence clock, trailing the close by the
134
+ * persistence lag. Any position read after a matching-engine restart also
135
+ * comes from the persistence clock and differs by that lag. Accurate to that
136
+ * lag, not to the microsecond.
135
137
  *
136
138
  * A third case is not lag-bounded: while the server's matching engine is
137
139
  * unreachable, a REST read of an OPEN position falls back to that row's
@@ -4,7 +4,10 @@
4
4
  * The server injects one `Snapshot` frame per subscription, after the
5
5
  * `Subscribed` ack and before that subscription's first live diff. Its `data`
6
6
  * is the channel's COMPLETE current state as a flat array — a consumer that
7
- * applies it wholesale needs no REST baseline read for that channel.
7
+ * applies it wholesale needs no REST baseline read for that channel. `trades`
8
+ * is the exception: its array is the pair's newest trades, a recent-history
9
+ * baseline rather than complete state, which can overlap the first live trades
10
+ * or miss one executed just before the subscribe — dedupe on `tradeId`.
8
11
  *
9
12
  * Two rules hold across every channel:
10
13
  *
@@ -102,7 +105,7 @@ export interface OrderSnapshotItem {
102
105
  remainingQuantityRaw: string | null;
103
106
  /** Order status; the snapshot carries only resting statuses */
104
107
  status: string;
105
- /** Time in force */
108
+ /** Time in force; `null` on a MARKET order, which has none */
106
109
  timeInForce: TimeInForce | (string & {}) | null;
107
110
  /** Average fill price (decimal string); `null` before the first fill */
108
111
  averageFillPrice: string | null;
@@ -4,7 +4,10 @@
4
4
  * The server injects one `Snapshot` frame per subscription, after the
5
5
  * `Subscribed` ack and before that subscription's first live diff. Its `data`
6
6
  * is the channel's COMPLETE current state as a flat array — a consumer that
7
- * applies it wholesale needs no REST baseline read for that channel.
7
+ * applies it wholesale needs no REST baseline read for that channel. `trades`
8
+ * is the exception: its array is the pair's newest trades, a recent-history
9
+ * baseline rather than complete state, which can overlap the first live trades
10
+ * or miss one executed just before the subscribe — dedupe on `tradeId`.
8
11
  *
9
12
  * Two rules hold across every channel:
10
13
  *
@@ -2804,12 +2804,12 @@ export interface paths {
2804
2804
  *
2805
2805
  * Return the authenticated caller's referral position: their referral chain
2806
2806
  * upward (L1, L2 and onward — who referred them, who referred that wallet, and
2807
- * so on, as many levels as PitPass currently rewards), the total rewards they
2808
- * have earned, and their most recent reward rows.
2807
+ * so on, as many levels as their trades on this client application pay), the
2808
+ * total rewards they have earned, and their most recent reward rows.
2809
2809
  * Self-scoped — identity comes only from the session, never a path id,
2810
2810
  * so a caller can only ever read their own chain. Every other user is
2811
2811
  * identified by their public wallet address, never an internal id. An empty
2812
- * `referrer` and `upline` mean the caller was not referred.
2812
+ * `referrer` means the caller was not referred.
2813
2813
  */
2814
2814
  get: operations["get_my_referral_position"];
2815
2815
  put?: never;
@@ -2867,8 +2867,9 @@ export interface paths {
2867
2867
  * relative to the caller, its parent, how many wallets it has referred (so the
2868
2868
  * client knows whether it can be expanded), and what the caller has earned
2869
2869
  * from that wallet's own trades. Expanding a node is another call with
2870
- * `parent` set to that node's wallet; the tree stops at the deepest level that
2871
- * pays referral rewards, which an admin configures (at most 10).
2870
+ * `parent` set to that node's wallet; the tree always lists the caller's
2871
+ * direct referees (L1) and goes as deep as any client application rewards,
2872
+ * at most 10 levels.
2872
2873
  *
2873
2874
  * Self-scoped — identity comes only from the session. A `parent` that is not
2874
2875
  * the caller or a referee the caller can expand returns 404, the same
@@ -4137,7 +4138,7 @@ export interface components {
4137
4138
  amount?: string | null;
4138
4139
  /**
4139
4140
  * Format: int32
4140
- * @description Basis-point rate applied to this credit. For `BUILDER_FEE`, this is the normalized builder-fee rate charged to the taker. For `REVENUE_SHARE`, it is the realized whole-basis-point rate after the Monaco-floor clamp and can be lower than the configured BuilderCodes budget.
4141
+ * @description Basis-point rate applied to this credit. For `BUILDER_FEE`, this is the normalized builder-fee rate charged to the taker. For `REVENUE_SHARE`, it is the realized whole-basis-point rate for that fill and can be lower than the configured BuilderCodes budget.
4141
4142
  * @example 1000
4142
4143
  */
4143
4144
  appliedBps?: number | null;
@@ -5517,15 +5518,15 @@ export interface components {
5517
5518
  * @example 0x0000000000000000000000000000000000000001
5518
5519
  */
5519
5520
  payoutAddress?: string | null;
5520
- /** @description Whether the BuilderCodes revenue share is switched on. While false no new share accrues; balances already credited stay readable and claimable. */
5521
+ /** @description Whether the BuilderCodes revenue share is switched on for this application. While false no new share accrues on this application's fills; balances already credited stay readable and claimable. */
5521
5522
  buildercodesEnabled?: boolean | null;
5522
5523
  /**
5523
5524
  * Format: uint32
5524
- * @description Target BuilderCodes share in basis points, computed from the fill's gross non-negative Monaco protocol take and capped by the remainder after Monaco's floor.
5525
+ * @description This application's configured target BuilderCodes revenue share of Monaco's protocol fee on each taker fill, in basis points. The rate actually paid on a fill is the payout row's appliedBps, which can be lower.
5525
5526
  * @example 1000
5526
5527
  */
5527
5528
  buildercodesBudgetBps?: number | null;
5528
- /** @description Whether builder fees are currently charged. While false, `builderFeeBps` is stored but no builder fee is charged. */
5529
+ /** @description Whether builder fees are currently charged on this application's orders. While false, `builderFeeBps` is stored but no builder fee is charged. */
5529
5530
  builderFeeEnabled?: boolean | null;
5530
5531
  /**
5531
5532
  * Format: uint32
@@ -5698,7 +5699,11 @@ export interface components {
5698
5699
  maintenanceMarginRequired?: string | null;
5699
5700
  freeCollateral?: string | null;
5700
5701
  /**
5701
- * @description The largest amount a transfer-out of this scope will actually accept.
5702
+ * @description The largest amount a transfer-out of this scope accepts without lowering
5703
+ * any position's posted margin, so without moving a leverage or a
5704
+ * liquidation price. A removal from an isolated risk bucket with one open
5705
+ * position can take more, out of that position's margin: see
5706
+ * `max_removable_collateral`.
5702
5707
  *
5703
5708
  * NOT a clamped `free_collateral`. Free collateral is equity headroom, and
5704
5709
  * equity includes mark-to-market gains that a transfer cannot move — so
@@ -5765,6 +5770,12 @@ export interface components {
5765
5770
  subaccountKey?: string | null;
5766
5771
  /** @description See `MarginAccountSummary.margin_account_state`. */
5767
5772
  marginAccountState?: string | null;
5773
+ /**
5774
+ * @description See `MarginAccountSummary.max_removable_collateral`: the largest removal
5775
+ * the risk engine accepts when it may also lower the posted margin of the
5776
+ * bucket's one open position.
5777
+ */
5778
+ maxRemovableCollateral?: string | null;
5768
5779
  };
5769
5780
  GetMarkPriceResponse: {
5770
5781
  /** Format: uuid */
@@ -5970,7 +5981,7 @@ export interface components {
5970
5981
  };
5971
5982
  GetMyReferralPositionResponse: {
5972
5983
  /**
5973
- * @description Public wallet address of the caller's direct (L1) referrer — who referred them. Empty when the caller was not referred. The same wallet as the first `upline` entry; never an internal id.
5984
+ * @description Public wallet address of the caller's direct (L1) referrer — who referred them. Empty when the caller was not referred. The same wallet as the first `upline` entry whenever `upline` is not empty; never an internal id.
5974
5985
  * @example 0x0000000000000000000000000000000000000002
5975
5986
  */
5976
5987
  referrer?: string | null;
@@ -5986,7 +5997,7 @@ export interface components {
5986
5997
  referrerDisplay?: string | null;
5987
5998
  /** @description The caller's most recent reward rows, newest first. Bounded server-side — not the full history. */
5988
5999
  rewards?: components["schemas"]["ReferralRewardEntry"][] | null;
5989
- /** @description The caller's referral chain upward, nearest first: L1 (who referred the caller), then L2 (who referred them), and so on. At most as many entries as PitPass currently rewards levels (at most 10); shorter when the chain ends, empty when the caller was not referred. These are the wallets the caller's own trades pay referral rewards to. */
6000
+ /** @description The caller's referral chain upward, nearest first: L1 (who referred the caller), then L2 (who referred them), and so on: the levels the caller's trades on this client application pay (at most 10). Shorter when the chain ends; empty when the caller was not referred or this client application pays no referral levels. These are the wallets the caller's own trades on this client application pay referral rewards to. */
5990
6001
  upline?: components["schemas"]["ReferralUplineEntry"][] | null;
5991
6002
  };
5992
6003
  GetMyReferralTreeResponse: {
@@ -6085,7 +6096,7 @@ export interface components {
6085
6096
  */
6086
6097
  tradingMode?: string | null;
6087
6098
  /**
6088
- * @description Time in force: GTC, IOC, or FOK
6099
+ * @description Time in force: GTC, IOC, or FOK. Absent on MARKET orders, which have none.
6089
6100
  * @example GTC
6090
6101
  */
6091
6102
  timeInForce?: string | null;
@@ -6609,11 +6620,13 @@ export interface components {
6609
6620
  * same instant — the list, the detail read, the risk read, the WebSocket
6610
6621
  * positions snapshot, and the live position_update frames.
6611
6622
  *
6612
- * Two cases come from the persistence clock instead and differ from the
6613
- * matching engine's by the persistence lag: a TERMINAL row (the live
6614
- * position_update frame carries the engine's close instant, this field
6615
- * carries the stored one), and any position read after a matching-engine
6616
- * restart. Accurate to that lag, not to the microsecond.
6623
+ * A TERMINAL row carries the instant the matching engine emitted the
6624
+ * close, which can differ slightly from the close instant on the live
6625
+ * position_update frame; older terminal rows may instead carry the
6626
+ * persistence clock, trailing the close by the persistence lag. Any
6627
+ * position read after a matching-engine restart also comes from the
6628
+ * persistence clock and differs from the matching engine's by that lag.
6629
+ * Accurate to that lag, not to the microsecond.
6617
6630
  *
6618
6631
  * A third case is not lag-bounded: an OPEN row read while the matching
6619
6632
  * engine is unreachable falls back to the row's own lifecycle columns
@@ -6680,6 +6693,9 @@ export interface components {
6680
6693
  * for positions predating the PnL service — rather than an understated
6681
6694
  * partial. On a terminal row it is also null until the final close is
6682
6695
  * recorded in the position's PnL sample, or while fee data is incomplete.
6696
+ * On an OPEN or LIQUIDATING row it is also null when the position's reductions
6697
+ * do not account for its realized PnL (lifetime_totals_status INCOMPLETE),
6698
+ * rather than an understated total.
6683
6699
  */
6684
6700
  cumFees?: string | null;
6685
6701
  /**
@@ -6693,6 +6709,13 @@ export interface components {
6693
6709
  * `Position.opened_at` above.
6694
6710
  */
6695
6711
  openedAt?: string | null;
6712
+ /**
6713
+ * Format: enum
6714
+ * @description Whether this position's lifetime totals are served. Same contract as
6715
+ * `Position.lifetime_totals_status` above.
6716
+ * @enum {string|null}
6717
+ */
6718
+ lifetimeTotalsStatus?: "LIFETIME_TOTALS_STATUS_UNSPECIFIED" | "LIFETIME_TOTALS_STATUS_COMPLETE" | "LIFETIME_TOTALS_STATUS_PENDING" | "LIFETIME_TOTALS_STATUS_INCOMPLETE" | null;
6696
6719
  };
6697
6720
  GetPositionRiskResponse: {
6698
6721
  positionId?: string | null;
@@ -6738,11 +6761,13 @@ export interface components {
6738
6761
  * same instant — the list, the detail read, the risk read, the WebSocket
6739
6762
  * positions snapshot, and the live position_update frames.
6740
6763
  *
6741
- * Two cases come from the persistence clock instead and differ from the
6742
- * matching engine's by the persistence lag: a TERMINAL row (the live
6743
- * position_update frame carries the engine's close instant, this field
6744
- * carries the stored one), and any position read after a matching-engine
6745
- * restart. Accurate to that lag, not to the microsecond.
6764
+ * A TERMINAL row carries the instant the matching engine emitted the
6765
+ * close, which can differ slightly from the close instant on the live
6766
+ * position_update frame; older terminal rows may instead carry the
6767
+ * persistence clock, trailing the close by the persistence lag. Any
6768
+ * position read after a matching-engine restart also comes from the
6769
+ * persistence clock and differs from the matching engine's by that lag.
6770
+ * Accurate to that lag, not to the microsecond.
6746
6771
  *
6747
6772
  * A third case is not lag-bounded: an OPEN row read while the matching
6748
6773
  * engine is unreachable falls back to the row's own lifecycle columns
@@ -7835,7 +7860,11 @@ export interface components {
7835
7860
  maintenanceMarginRequired?: string | null;
7836
7861
  freeCollateral?: string | null;
7837
7862
  /**
7838
- * @description The largest amount a transfer-out of this scope will actually accept.
7863
+ * @description The largest amount a transfer-out of this scope accepts without lowering
7864
+ * any position's posted margin, so without moving a leverage or a
7865
+ * liquidation price. A removal from an isolated risk bucket with one open
7866
+ * position can take more, out of that position's margin: see
7867
+ * `max_removable_collateral`.
7839
7868
  *
7840
7869
  * NOT a clamped `free_collateral`. Free collateral is equity headroom, and
7841
7870
  * equity includes mark-to-market gains that a transfer cannot move — so
@@ -7940,6 +7969,25 @@ export interface components {
7940
7969
  * sub-account).
7941
7970
  */
7942
7971
  marginAccountState?: string | null;
7972
+ /**
7973
+ * @description The largest removal from this risk bucket the risk engine accepts when
7974
+ * the removal may also lower the posted margin of the bucket's one open
7975
+ * position: `withdrawable_collateral` plus the position's margin above its
7976
+ * initial margin at the mark, capped by what the parent margin account
7977
+ * accepts. Everything past `withdrawable_collateral` comes out of the
7978
+ * position's margin, so it raises the position's leverage and moves its
7979
+ * liquidation price toward the mark.
7980
+ *
7981
+ * Equal to `withdrawable_collateral` on a cross risk bucket and on an
7982
+ * isolated one with no open position or several, where a removal never
7983
+ * reaches into posted margin.
7984
+ *
7985
+ * Present only on risk-bucket rows served from a live risk engine snapshot;
7986
+ * absent on parent rows and on persisted-fallback reads. Printed truncated
7987
+ * toward zero at the quote asset's precision, like
7988
+ * `withdrawable_collateral`.
7989
+ */
7990
+ maxRemovableCollateral?: string | null;
7943
7991
  };
7944
7992
  MatchResult: {
7945
7993
  /**
@@ -8347,8 +8395,11 @@ export interface components {
8347
8395
  unrealizedPnl?: string | null;
8348
8396
  positionCount?: string | null;
8349
8397
  /**
8350
- * @description The largest transfer-out of this risk bucket the engine will actually
8351
- * accept — the bound enforced on bucket collateral withdrawals.
8398
+ * @description The largest transfer-out of this risk bucket the engine accepts without
8399
+ * lowering a position's posted margin — the bound enforced on bucket
8400
+ * collateral withdrawals that leave the positions' leverage alone. A removal
8401
+ * from an isolated risk bucket with one open position can take more: see
8402
+ * `max_removable_collateral`.
8352
8403
  *
8353
8404
  * NOT a clamped `free_collateral`: free collateral is equity headroom and
8354
8405
  * credits mark-to-market gains that a transfer-out cannot move. This bound
@@ -8410,6 +8461,16 @@ export interface components {
8410
8461
  copyFollowId?: string | null;
8411
8462
  /** @description On a copy risk bucket row, the followed leader's custom TraderCode handle, when they still hold one */
8412
8463
  copyLeaderHandle?: string | null;
8464
+ /**
8465
+ * @description The largest removal from this risk bucket the engine accepts when the
8466
+ * removal may also lower the posted margin of the bucket's one open
8467
+ * position, down to its initial margin at the mark — the same figure as
8468
+ * `MarginAccountSummary.max_removable_collateral`. Equal to
8469
+ * `withdrawable_collateral` for a cross risk bucket and for an isolated one
8470
+ * with no open position or several. Present only when a live risk engine
8471
+ * snapshot served it; truncated toward zero at quote decimals.
8472
+ */
8473
+ maxRemovableCollateral?: string | null;
8413
8474
  };
8414
8475
  PortfolioSeriesWindow: {
8415
8476
  /**
@@ -8532,11 +8593,13 @@ export interface components {
8532
8593
  * same instant — the list, the detail read, the risk read, the WebSocket
8533
8594
  * positions snapshot, and the live position_update frames.
8534
8595
  *
8535
- * Two cases come from the persistence clock instead and differ from the
8536
- * matching engine's by the persistence lag: a TERMINAL row (the live
8537
- * position_update frame carries the engine's close instant, this field
8538
- * carries the stored one), and any position read after a matching-engine
8539
- * restart. Accurate to that lag, not to the microsecond.
8596
+ * A TERMINAL row carries the instant the matching engine emitted the
8597
+ * close, which can differ slightly from the close instant on the live
8598
+ * position_update frame; older terminal rows may instead carry the
8599
+ * persistence clock, trailing the close by the persistence lag. Any
8600
+ * position read after a matching-engine restart also comes from the
8601
+ * persistence clock and differs from the matching engine's by that lag.
8602
+ * Accurate to that lag, not to the microsecond.
8540
8603
  *
8541
8604
  * A third case is not lag-bounded: an OPEN row read while the matching
8542
8605
  * engine is unreachable falls back to the row's own lifecycle columns
@@ -8603,6 +8666,9 @@ export interface components {
8603
8666
  * for positions predating the PnL service — rather than an understated
8604
8667
  * partial. On a terminal row it is also null until the final close is
8605
8668
  * recorded in the position's PnL sample, or while fee data is incomplete.
8669
+ * On an OPEN or LIQUIDATING row it is also null when the position's reductions
8670
+ * do not account for its realized PnL (lifetime_totals_status INCOMPLETE),
8671
+ * rather than an understated total.
8606
8672
  */
8607
8673
  cumFees?: string | null;
8608
8674
  /**
@@ -8639,6 +8705,28 @@ export interface components {
8639
8705
  * equal version.
8640
8706
  */
8641
8707
  openedAt?: string | null;
8708
+ /**
8709
+ * Format: enum
8710
+ * @description Whether this row's lifetime totals (exit_price, realized_roe, fees_paid,
8711
+ * funding_paid, cum_fees, net_realized_pnl) are served: COMPLETE when the
8712
+ * position's history covers its whole lifetime, PENDING while that history
8713
+ * is still being written up to this row's version or the row changed while
8714
+ * it was being read (every lifetime field is
8715
+ * absent; retry shortly), INCOMPLETE when the totals are not complete now
8716
+ * and a quick retry will not change that (a legacy-history gap is
8717
+ * permanent; a missing or drifted maintained-totals row is repaired by the
8718
+ * background reconcile at startup and daily; every field that is present
8719
+ * comes from the maintained totals, which are cross-checked against each
8720
+ * other and repaired by the background reconcile; an absent one is not
8721
+ * zero). Until the position-history
8722
+ * checkpoint is seeded, PENDING arises only when the position row changed
8723
+ * between the row read and the totals read. OPEN and LIQUIDATING positions
8724
+ * are checked against realized PnL too, and are INCOMPLETE without cum_fees
8725
+ * when their reductions do not account for it. Set on every row of the REST and
8726
+ * gRPC reads; WebSocket position frames do not carry it.
8727
+ * @enum {string|null}
8728
+ */
8729
+ lifetimeTotalsStatus?: "LIFETIME_TOTALS_STATUS_UNSPECIFIED" | "LIFETIME_TOTALS_STATUS_COMPLETE" | "LIFETIME_TOTALS_STATUS_PENDING" | "LIFETIME_TOTALS_STATUS_INCOMPLETE" | null;
8642
8730
  };
8643
8731
  PositionHistoryEvent: {
8644
8732
  id?: string | null;
@@ -17611,19 +17699,33 @@ export interface operations {
17611
17699
  * carries no timestamps for a position the persistor has not written
17612
17700
  * yet. It is ordered by `(marginAccountId, tradingPairId, positionId)`
17613
17701
  * ascending — stable and total, but UUID order, NOT newest-first.
17614
- * - Every other filter reads persisted rows, ordered by the IMMUTABLE
17615
- * `(opened_at, id)` descending: newest-opened first. The removed
17616
- * page-number mode sorted on `COALESCE(closed_at, last_funding_at,
17617
- * opened_at)`, which *advances* whenever a position takes a funding
17618
- * payment or closes, so rows moved across a resume point mid-walk;
17619
- * `opened_at` never changes after the insert. Order therefore differs
17620
- * from the removed mode's. One exception: an operator correction may
17621
- * move an OPEN position's `opened_at` EARLIER, never later, to its
17622
- * opening fill. A walk in flight while that runs can return such a
17623
- * position a second time, but cannot skip one: dedupe on `positionId`.
17702
+ * - `status=CLOSED` and `status=LIQUIDATED` read persisted terminal
17703
+ * rows, ordered by `(closed_at, id)` descending: newest-closed first,
17704
+ * so a position held for weeks and closed today leads the list. A
17705
+ * terminal row's `closed_at` is the closing command's instant, stamped
17706
+ * once. A legacy terminal row with no `closed_at` sorts by its
17707
+ * `opened_at` instead (the epoch if that is missing too).
17708
+ * - Every other persisted walk (no filter, `status=LIQUIDATING`, and
17709
+ * `status=OPEN` when it falls back to persisted rows, see below) is
17710
+ * ordered by the IMMUTABLE `(opened_at, id)` descending:
17711
+ * newest-opened first. These filters admit live rows, whose close time
17712
+ * is unset and changes when they close, so they cannot sort on it. The
17713
+ * removed page-number mode sorted on `COALESCE(closed_at,
17714
+ * last_funding_at, opened_at)`, which *advances* whenever a position
17715
+ * takes a funding payment or closes, so rows moved across a resume
17716
+ * point mid-walk; `opened_at` never changes after the insert. Order
17717
+ * therefore differs from the removed mode's. One exception: an operator
17718
+ * correction may move an OPEN position's `opened_at` EARLIER, never
17719
+ * later, to its opening fill. A walk in flight while that runs can
17720
+ * return such a position a second time, but cannot skip one: dedupe on
17721
+ * `positionId`.
17722
+ *
17723
+ * The two persisted orders are separate cursor spaces too: a token is
17724
+ * pinned to its filter, so it only resumes the order that minted it.
17624
17725
  *
17625
- * Those are two separate cursor spaces, so a token is only valid in the one
17626
- * that minted it, and crossing between them is ASYMMETRIC:
17726
+ * The live and persisted walks are separate cursor spaces, so a token is
17727
+ * only valid in the one that minted it, and crossing between them is
17728
+ * ASYMMETRIC:
17627
17729
  *
17628
17730
  * - A PERSISTED token offered to `status=OPEN` while the engine is
17629
17731
  * reachable is served: the live branch does not recognise it, declines,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xmonaco/types",
3
- "version": "1.0.77",
3
+ "version": "1.0.80",
4
4
  "type": "module",
5
5
  "homepage": "https://docs.0xmonaco.com/sdk/typescript",
6
6
  "main": "./dist/index.js",
@@ -16,7 +16,7 @@
16
16
  "lint": "biome lint ."
17
17
  },
18
18
  "dependencies": {
19
- "@0xmonaco/contracts": "1.0.77",
19
+ "@0xmonaco/contracts": "1.0.80",
20
20
  "zod": "^4.1.12"
21
21
  },
22
22
  "peerDependencies": {