@0xmonaco/core 1.0.39 → 1.0.41-develop.ebb62ed
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/margin-accounts/api.js +1 -0
- package/dist/api/market/api.js +4 -0
- package/dist/api/perp/routes.d.ts +0 -2
- package/dist/api/perp/routes.js +0 -2
- package/dist/api/positions/api.d.ts +1 -3
- package/dist/api/positions/api.js +1 -20
- package/dist/api/trading/api.d.ts +3 -0
- package/dist/api/trading/api.js +12 -0
- package/dist/api/websocket/types.d.ts +7 -1
- package/dist/api/websocket/websocket.js +184 -5
- package/dist/coverage.d.ts +0 -2
- package/dist/coverage.js +0 -2
- package/package.json +3 -3
package/dist/api/market/api.js
CHANGED
|
@@ -54,6 +54,7 @@ export class MarketAPIImpl extends BaseAPI {
|
|
|
54
54
|
startTime: params?.startTime,
|
|
55
55
|
endTime: params?.endTime,
|
|
56
56
|
limit: params?.limit,
|
|
57
|
+
priceType: params?.priceType,
|
|
57
58
|
});
|
|
58
59
|
const searchParams = new URLSearchParams();
|
|
59
60
|
if (params?.startTime !== undefined) {
|
|
@@ -65,6 +66,9 @@ export class MarketAPIImpl extends BaseAPI {
|
|
|
65
66
|
if (params?.limit !== undefined) {
|
|
66
67
|
searchParams.append("limit", params.limit.toString());
|
|
67
68
|
}
|
|
69
|
+
if (params?.priceType !== undefined) {
|
|
70
|
+
searchParams.append("priceType", params.priceType);
|
|
71
|
+
}
|
|
68
72
|
const queryString = searchParams.toString();
|
|
69
73
|
const url = queryString
|
|
70
74
|
? `/api/v1/market/pairs/charts/candlestick/${encodeURIComponent(tradingPairId)}/${interval}?${queryString}`
|
|
@@ -170,8 +170,6 @@ export declare const perpRoutes: {
|
|
|
170
170
|
readonly close: (positionId: string) => string;
|
|
171
171
|
readonly batchCloseAll: () => string;
|
|
172
172
|
readonly risk: (positionId: string) => string;
|
|
173
|
-
readonly addMargin: (positionId: string) => string;
|
|
174
|
-
readonly reduceMargin: (positionId: string) => string;
|
|
175
173
|
readonly attachTpSl: (positionId: string) => string;
|
|
176
174
|
readonly history: (params?: {
|
|
177
175
|
positionId?: string;
|
package/dist/api/perp/routes.js
CHANGED
|
@@ -94,8 +94,6 @@ export const perpRoutes = {
|
|
|
94
94
|
close: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/close`,
|
|
95
95
|
batchCloseAll: () => `${API_V1}/positions/batch-close-all`,
|
|
96
96
|
risk: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/risk`,
|
|
97
|
-
addMargin: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/margin/add`,
|
|
98
|
-
reduceMargin: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/margin/reduce`,
|
|
99
97
|
attachTpSl: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/tp-sl`,
|
|
100
98
|
history: (params) => withQuery(`${API_V1}/positions/history`, params),
|
|
101
99
|
pnlHistory: (positionId, params) => withQuery(`${API_V1}/positions/${encodeSegment(positionId)}/pnl/history`, params),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AttachPositionTpSlRequest, AttachPositionTpSlResponse, BatchCloseAllRequest, BatchCloseAllResponse, ClosePositionRequest, ClosePositionResponse, GetPositionPnlHistoryParams, GetPositionPnlHistoryResponse, GetPositionResponse, ListPositionHistoryParams, ListPositionHistoryResponse, ListPositionsParams, ListPositionsResponse, PositionRisk, PositionsAPI } from "@0xmonaco/types";
|
|
2
2
|
import { BaseAPI } from "../base";
|
|
3
3
|
export declare class PositionsAPIImpl extends BaseAPI implements PositionsAPI {
|
|
4
4
|
listPositions(params?: ListPositionsParams): Promise<ListPositionsResponse>;
|
|
@@ -6,8 +6,6 @@ export declare class PositionsAPIImpl extends BaseAPI implements PositionsAPI {
|
|
|
6
6
|
closePosition(positionId: string, request: ClosePositionRequest): Promise<ClosePositionResponse>;
|
|
7
7
|
batchCloseAllPositions(request?: BatchCloseAllRequest): Promise<BatchCloseAllResponse>;
|
|
8
8
|
getPositionRisk(positionId: string): Promise<PositionRisk>;
|
|
9
|
-
addPositionMargin(positionId: string, request: AddPositionMarginRequest): Promise<PositionMarginResponse>;
|
|
10
|
-
reducePositionMargin(positionId: string, request: ReducePositionMarginRequest): Promise<PositionMarginResponse>;
|
|
11
9
|
attachPositionTpSl(positionId: string, request: AttachPositionTpSlRequest): Promise<AttachPositionTpSlResponse>;
|
|
12
10
|
listPositionHistory(params?: ListPositionHistoryParams): Promise<ListPositionHistoryResponse>;
|
|
13
11
|
getPositionPnlHistory(positionId: string, params: GetPositionPnlHistoryParams): Promise<GetPositionPnlHistoryResponse>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AttachPositionTpSlSchema, BatchCloseAllSchema, ClosePositionSchema, GetPositionPnlHistorySchema, GetPositionRiskSchema, GetPositionSchema, ListPositionHistorySchema, ListPositionsSchema, validate, } from "@0xmonaco/types";
|
|
2
2
|
import { BaseAPI } from "../base";
|
|
3
3
|
import { perpRoutes } from "../perp";
|
|
4
4
|
export class PositionsAPIImpl extends BaseAPI {
|
|
@@ -40,25 +40,6 @@ export class PositionsAPIImpl extends BaseAPI {
|
|
|
40
40
|
validate(GetPositionRiskSchema, { positionId });
|
|
41
41
|
return await this.makeAuthenticatedRequest(perpRoutes.positions.risk(positionId));
|
|
42
42
|
}
|
|
43
|
-
async addPositionMargin(positionId, request) {
|
|
44
|
-
validate(AddPositionMarginSchema, { positionId, request });
|
|
45
|
-
return await this.makeAuthenticatedRequest(perpRoutes.positions.addMargin(positionId), {
|
|
46
|
-
method: "POST",
|
|
47
|
-
body: JSON.stringify({
|
|
48
|
-
amount: request.amount,
|
|
49
|
-
asset: request.asset,
|
|
50
|
-
}),
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
async reducePositionMargin(positionId, request) {
|
|
54
|
-
validate(ReducePositionMarginSchema, { positionId, request });
|
|
55
|
-
return await this.makeAuthenticatedRequest(perpRoutes.positions.reduceMargin(positionId), {
|
|
56
|
-
method: "POST",
|
|
57
|
-
body: JSON.stringify({
|
|
58
|
-
amount: request.amount,
|
|
59
|
-
}),
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
43
|
async attachPositionTpSl(positionId, request) {
|
|
63
44
|
validate(AttachPositionTpSlSchema, { positionId, request });
|
|
64
45
|
return await this.makeAuthenticatedRequest(perpRoutes.positions.attachTpSl(positionId), {
|
|
@@ -88,6 +88,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
88
88
|
leverage?: string;
|
|
89
89
|
reduceOnly?: boolean;
|
|
90
90
|
postOnly?: boolean;
|
|
91
|
+
clientOrderId?: string;
|
|
91
92
|
takeProfit?: ParentTpSlLegParams;
|
|
92
93
|
stopLoss?: ParentTpSlLegParams;
|
|
93
94
|
}): Promise<CreateOrderResponse>;
|
|
@@ -147,6 +148,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
147
148
|
reduceOnly?: boolean;
|
|
148
149
|
takeProfit?: ParentTpSlLegParams;
|
|
149
150
|
stopLoss?: ParentTpSlLegParams;
|
|
151
|
+
clientOrderId?: string;
|
|
150
152
|
}): Promise<CreateOrderResponse>;
|
|
151
153
|
/**
|
|
152
154
|
* Cancels an existing order.
|
|
@@ -203,6 +205,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
203
205
|
quantity?: string;
|
|
204
206
|
useMasterBalance?: boolean;
|
|
205
207
|
postOnly?: boolean;
|
|
208
|
+
clientOrderId?: string;
|
|
206
209
|
}): Promise<ReplaceOrderResponse>;
|
|
207
210
|
/**
|
|
208
211
|
* Batch creates multiple orders in a single request.
|
package/dist/api/trading/api.js
CHANGED
|
@@ -34,6 +34,11 @@ function parentTpSlLegToRequest(leg) {
|
|
|
34
34
|
timeInForce: leg.timeInForce,
|
|
35
35
|
slippageToleranceBps: leg.slippageToleranceBps,
|
|
36
36
|
expiresAt: leg.expiresAt,
|
|
37
|
+
// The leg's sizing contract. Omitting these sends neither field, which the
|
|
38
|
+
// server reads as the legacy "size from the parent order" shape — so a
|
|
39
|
+
// caller asking to track the position would silently get a frozen partial.
|
|
40
|
+
quantity: leg.quantity,
|
|
41
|
+
closePosition: leg.closePosition,
|
|
37
42
|
};
|
|
38
43
|
}
|
|
39
44
|
export class TradingAPIImpl extends BaseAPI {
|
|
@@ -115,6 +120,7 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
115
120
|
leverage: options?.leverage,
|
|
116
121
|
reduceOnly: options?.reduceOnly,
|
|
117
122
|
postOnly: options?.postOnly,
|
|
123
|
+
clientOrderId: options?.clientOrderId,
|
|
118
124
|
takeProfit: parentTpSlLegToRequest(options?.takeProfit),
|
|
119
125
|
stopLoss: parentTpSlLegToRequest(options?.stopLoss),
|
|
120
126
|
};
|
|
@@ -192,6 +198,7 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
192
198
|
reduceOnly: options?.reduceOnly,
|
|
193
199
|
takeProfit: parentTpSlLegToRequest(options?.takeProfit),
|
|
194
200
|
stopLoss: parentTpSlLegToRequest(options?.stopLoss),
|
|
201
|
+
clientOrderId: options?.clientOrderId,
|
|
195
202
|
};
|
|
196
203
|
return await this.makeAuthenticatedRequest(perpRoutes.orders.create(), {
|
|
197
204
|
method: "POST",
|
|
@@ -308,6 +315,9 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
308
315
|
if (newOrder.postOnly !== undefined) {
|
|
309
316
|
requestBody.postOnly = newOrder.postOnly;
|
|
310
317
|
}
|
|
318
|
+
if (newOrder.clientOrderId !== undefined) {
|
|
319
|
+
requestBody.clientOrderId = newOrder.clientOrderId;
|
|
320
|
+
}
|
|
311
321
|
return await this.makeAuthenticatedRequest(perpRoutes.orders.replace(orderId), {
|
|
312
322
|
method: "PUT",
|
|
313
323
|
body: JSON.stringify(requestBody),
|
|
@@ -366,6 +376,7 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
366
376
|
leverage: order.leverage,
|
|
367
377
|
reduceOnly: order.reduceOnly,
|
|
368
378
|
postOnly: order.postOnly,
|
|
379
|
+
clientOrderId: order.clientOrderId,
|
|
369
380
|
})),
|
|
370
381
|
};
|
|
371
382
|
return this.makeAuthenticatedRequest(perpRoutes.orders.batchCreate(), {
|
|
@@ -407,6 +418,7 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
407
418
|
quantity: order.quantity,
|
|
408
419
|
useMasterBalance: order.useMasterBalance,
|
|
409
420
|
postOnly: order.postOnly,
|
|
421
|
+
clientOrderId: order.clientOrderId,
|
|
410
422
|
})),
|
|
411
423
|
};
|
|
412
424
|
return this.makeAuthenticatedRequest(perpRoutes.orders.batchReplace(), {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConditionalOrderEvent, Interval, LiquidationEvent, MonacoWebSocketConfig, OHLCVEvent, OrderbookEvent, OrderbookQuotationMode, OrderEvent, PositionEvent, SessionCredentials, TradeEvent, TradingMode, UserBalanceEvent, UserMovementEvent, WebSocketStatus } from "@0xmonaco/types";
|
|
1
|
+
import type { AccountEvent, ConditionalOrderEvent, Interval, LiquidationEvent, MarketStatsAllEvent, MarketStatsEvent, MonacoWebSocketConfig, OHLCVEvent, OrderbookEvent, OrderbookQuotationMode, OrderEvent, PositionEvent, SessionCredentials, TradeEvent, TradingMode, UserBalanceEvent, UserMovementEvent, WebSocketStatus } from "@0xmonaco/types";
|
|
2
2
|
export type { ResyncHandler, StatusHandler, WebSocketResyncInfo } from "@0xmonaco/types";
|
|
3
3
|
export type MessageHandler<T> = (data: T) => void;
|
|
4
4
|
/**
|
|
@@ -42,4 +42,10 @@ export interface MonacoWebSocket {
|
|
|
42
42
|
positions: (handler: MessageHandler<PositionEvent>, tradingPairId?: string) => () => void;
|
|
43
43
|
/** Subscribe to liquidation alerts (requires authentication); omit `tradingPairId` for all pairs */
|
|
44
44
|
liquidations: (handler: MessageHandler<LiquidationEvent>, tradingPairId?: string) => () => void;
|
|
45
|
+
/** Subscribe to account-level margin health updates for the authenticated user (requires authentication) */
|
|
46
|
+
account: (handler: MessageHandler<AccountEvent>) => () => void;
|
|
47
|
+
/** Subscribe to per-market statistics for one trading pair (public) */
|
|
48
|
+
marketStats: (tradingPairId: string, handler: MessageHandler<MarketStatsEvent>) => () => void;
|
|
49
|
+
/** Subscribe to the all-markets statistics summary (public) */
|
|
50
|
+
marketStatsAll: (handler: MessageHandler<MarketStatsAllEvent>) => () => void;
|
|
45
51
|
}
|
|
@@ -133,6 +133,8 @@ function parsePositionEvent(rawData) {
|
|
|
133
133
|
liquidationPrice: readOptionalString(data, "liquidationPrice"),
|
|
134
134
|
isolatedMargin: readString(data, "isolatedMargin"),
|
|
135
135
|
leverage: readString(data, "leverage"),
|
|
136
|
+
tradeId: readOptionalString(data, "tradeId"),
|
|
137
|
+
orderId: readOptionalString(data, "orderId"),
|
|
136
138
|
reason: readString(data, "reason"),
|
|
137
139
|
updatedAt: readString(data, "updatedAt"),
|
|
138
140
|
},
|
|
@@ -168,6 +170,104 @@ function parseLiquidationEvent(rawData) {
|
|
|
168
170
|
},
|
|
169
171
|
};
|
|
170
172
|
}
|
|
173
|
+
function parseAccountEvent(rawData) {
|
|
174
|
+
if (!isRecord(rawData)) {
|
|
175
|
+
throw new Error("Invalid account event: payload must be an object");
|
|
176
|
+
}
|
|
177
|
+
if (!isRecord(rawData.data)) {
|
|
178
|
+
throw new Error("Invalid account event: data must be an object");
|
|
179
|
+
}
|
|
180
|
+
const data = keysToCamelCase(rawData.data);
|
|
181
|
+
return {
|
|
182
|
+
// event_type is the event-class discriminator, validated strictly so a
|
|
183
|
+
// mis-routed frame is rejected rather than parsed as an account update.
|
|
184
|
+
eventType: readEnum(rawData, "event_type", ["account_update"]),
|
|
185
|
+
userId: readString(rawData, "user_id"),
|
|
186
|
+
data: {
|
|
187
|
+
marginAccountId: readString(data, "marginAccountId"),
|
|
188
|
+
equity: readString(data, "equity"),
|
|
189
|
+
collateral: readString(data, "collateral"),
|
|
190
|
+
freeCollateral: readString(data, "freeCollateral"),
|
|
191
|
+
marginRatio: readString(data, "marginRatio"),
|
|
192
|
+
maintenanceRequirement: readString(data, "maintenanceRequirement"),
|
|
193
|
+
updatedAt: readString(data, "updatedAt"),
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function parseMarketStatsData(raw) {
|
|
198
|
+
if (!isRecord(raw)) {
|
|
199
|
+
throw new Error("Invalid market stats event: data must be an object");
|
|
200
|
+
}
|
|
201
|
+
const data = keysToCamelCase(raw);
|
|
202
|
+
return {
|
|
203
|
+
symbol: readString(data, "symbol"),
|
|
204
|
+
tradingPairId: readString(data, "tradingPairId"),
|
|
205
|
+
indexPrice: readOptionalString(data, "indexPrice"),
|
|
206
|
+
markPrice: readOptionalString(data, "markPrice"),
|
|
207
|
+
midPrice: readOptionalString(data, "midPrice"),
|
|
208
|
+
bestBidPrice: readOptionalString(data, "bestBidPrice"),
|
|
209
|
+
bestAskPrice: readOptionalString(data, "bestAskPrice"),
|
|
210
|
+
openInterest: readOptionalString(data, "openInterest"),
|
|
211
|
+
openInterestLimit: readOptionalString(data, "openInterestLimit"),
|
|
212
|
+
lastTradePrice: readOptionalString(data, "lastTradePrice"),
|
|
213
|
+
dailyBaseTokenVolume: readOptionalString(data, "dailyBaseTokenVolume"),
|
|
214
|
+
dailyQuoteTokenVolume: readOptionalString(data, "dailyQuoteTokenVolume"),
|
|
215
|
+
dailyPriceLow: readOptionalString(data, "dailyPriceLow"),
|
|
216
|
+
dailyPriceHigh: readOptionalString(data, "dailyPriceHigh"),
|
|
217
|
+
dailyPriceChange: readOptionalString(data, "dailyPriceChange"),
|
|
218
|
+
dailyPriceChangePercent: readOptionalString(data, "dailyPriceChangePercent"),
|
|
219
|
+
currentFundingRate: readOptionalString(data, "currentFundingRate"),
|
|
220
|
+
fundingRate: readOptionalString(data, "fundingRate"),
|
|
221
|
+
fundingTimestamp: readOptionalNumber(data, "fundingTimestamp"),
|
|
222
|
+
premium: readOptionalString(data, "premium"),
|
|
223
|
+
baseInterestRate: readOptionalString(data, "baseInterestRate"),
|
|
224
|
+
fundingClampSmall: readOptionalString(data, "fundingClampSmall"),
|
|
225
|
+
fundingClampBig: readOptionalString(data, "fundingClampBig"),
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function parseMarketStatsEvent(rawData) {
|
|
229
|
+
if (!isRecord(rawData)) {
|
|
230
|
+
throw new Error("Invalid market stats event: payload must be an object");
|
|
231
|
+
}
|
|
232
|
+
// The per-market frame's top-level `trading_pair_id` is not inside `data`, so
|
|
233
|
+
// it stays snake_case (only `data` is camelCased by parseMarketStatsData).
|
|
234
|
+
return {
|
|
235
|
+
tradingPairId: readString(rawData, "trading_pair_id"),
|
|
236
|
+
data: parseMarketStatsData(rawData.data),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function parseMarketStatsSummary(raw) {
|
|
240
|
+
if (!isRecord(raw)) {
|
|
241
|
+
throw new Error("Invalid market stats summary: entry must be an object");
|
|
242
|
+
}
|
|
243
|
+
const data = keysToCamelCase(raw);
|
|
244
|
+
return {
|
|
245
|
+
tradingPairId: readString(data, "tradingPairId"),
|
|
246
|
+
symbol: readString(data, "symbol"),
|
|
247
|
+
lastTradePrice: readOptionalString(data, "lastTradePrice"),
|
|
248
|
+
markPrice: readOptionalString(data, "markPrice"),
|
|
249
|
+
dailyPriceChange: readOptionalString(data, "dailyPriceChange"),
|
|
250
|
+
dailyPriceChangePercent: readOptionalString(data, "dailyPriceChangePercent"),
|
|
251
|
+
dailyBaseTokenVolume: readOptionalString(data, "dailyBaseTokenVolume"),
|
|
252
|
+
dailyQuoteTokenVolume: readOptionalString(data, "dailyQuoteTokenVolume"),
|
|
253
|
+
dailyPriceHigh: readOptionalString(data, "dailyPriceHigh"),
|
|
254
|
+
dailyPriceLow: readOptionalString(data, "dailyPriceLow"),
|
|
255
|
+
openInterest: readOptionalString(data, "openInterest"),
|
|
256
|
+
currentFundingRate: readOptionalString(data, "currentFundingRate"),
|
|
257
|
+
fundingTimestamp: readOptionalNumber(data, "fundingTimestamp"),
|
|
258
|
+
// marketStatus stays lenient (read as string, not a strict enum) so an
|
|
259
|
+
// unrecognized status value never drops an otherwise-valid summary row.
|
|
260
|
+
marketStatus: readString(data, "marketStatus"),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function parseMarketStatsAllEvent(rawData) {
|
|
264
|
+
if (!isRecord(rawData) || !Array.isArray(rawData.markets)) {
|
|
265
|
+
throw new Error("Invalid market stats all event: markets must be an array");
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
markets: rawData.markets.map(parseMarketStatsSummary),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
171
271
|
/**
|
|
172
272
|
* Create a Monaco WebSocket client
|
|
173
273
|
*/
|
|
@@ -488,15 +588,21 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
488
588
|
quantity: level.quantity,
|
|
489
589
|
orderCount: level.order_count || 0,
|
|
490
590
|
})),
|
|
491
|
-
|
|
492
|
-
|
|
591
|
+
// Rust sends `null` for an empty side; normalize the nullable
|
|
592
|
+
// `Option` to `undefined` so it matches the `string | undefined` type
|
|
593
|
+
// rather than leaking `null` past the cast.
|
|
594
|
+
bestBid: orderbookData?.best_bid ?? undefined,
|
|
595
|
+
bestAsk: orderbookData?.best_ask ?? undefined,
|
|
493
596
|
bidVolume: orderbookData?.bid_volume || undefined,
|
|
494
597
|
askVolume: orderbookData?.ask_volume || undefined,
|
|
495
598
|
priceChange: orderbookData?.price_change
|
|
496
599
|
? {
|
|
497
600
|
side: orderbookData.price_change.side,
|
|
498
|
-
|
|
499
|
-
|
|
601
|
+
// Normalize nullable Rust `Option` prices to `undefined` (a
|
|
602
|
+
// level-add has no old price, a level-remove no new price) so
|
|
603
|
+
// neither leaks `null` past the `string | undefined` type.
|
|
604
|
+
oldPrice: orderbookData.price_change.old_price ?? undefined,
|
|
605
|
+
newPrice: orderbookData.price_change.new_price ?? undefined,
|
|
500
606
|
levelRemoved: orderbookData.price_change.level_removed || false,
|
|
501
607
|
levelAdded: orderbookData.price_change.level_added || false,
|
|
502
608
|
}
|
|
@@ -584,7 +690,10 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
584
690
|
id: movementData.id,
|
|
585
691
|
entryType: movementData.entry_type,
|
|
586
692
|
transactionType: movementData.transaction_type,
|
|
587
|
-
|
|
693
|
+
status: movementData.status,
|
|
694
|
+
token: (movementData.token ?? movementData.token_address),
|
|
695
|
+
tokenAddress: (movementData.token ?? movementData.token_address),
|
|
696
|
+
assetId: movementData.asset_id,
|
|
588
697
|
amount: String(movementData.amount),
|
|
589
698
|
amountRaw: movementData.amount_raw,
|
|
590
699
|
balanceBefore: movementData.balance_before != null ? String(movementData.balance_before) : undefined,
|
|
@@ -595,6 +704,7 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
595
704
|
referenceType: movementData.reference_type,
|
|
596
705
|
description: movementData.description,
|
|
597
706
|
txHash: movementData.tx_hash,
|
|
707
|
+
blockNumber: movementData.block_number,
|
|
598
708
|
createdAt: movementData.created_at,
|
|
599
709
|
decimals: movementData.decimals,
|
|
600
710
|
},
|
|
@@ -729,6 +839,72 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
729
839
|
}
|
|
730
840
|
});
|
|
731
841
|
};
|
|
842
|
+
/**
|
|
843
|
+
* Subscribe to the authenticated user's account-level margin health updates
|
|
844
|
+
* (equity, collateral, free collateral, margin ratio, maintenance
|
|
845
|
+
* requirement). Requires authentication - the user is identified from the
|
|
846
|
+
* signed session-key handshake. Lag policy is Conflate: a lagging subscriber
|
|
847
|
+
* is fast-forwarded, no gap signal. Each frame is a terminal-state snapshot
|
|
848
|
+
* per margin account, not an additive delta.
|
|
849
|
+
*/
|
|
850
|
+
const subscribeAccount = (handler) => {
|
|
851
|
+
if (!handler) {
|
|
852
|
+
throw new Error("account subscription requires a handler");
|
|
853
|
+
}
|
|
854
|
+
return subscribe("account", (rawData) => {
|
|
855
|
+
try {
|
|
856
|
+
handler(parseAccountEvent(rawData));
|
|
857
|
+
}
|
|
858
|
+
catch (err) {
|
|
859
|
+
console.error("WebSocket: Error processing account event", err);
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
};
|
|
863
|
+
/**
|
|
864
|
+
* Subscribe to per-market statistics for a single trading pair (public). Each
|
|
865
|
+
* frame carries the market's full current stats as a terminal-state snapshot.
|
|
866
|
+
* Use {@link subscribeMarketStatsAll} for the all-markets summary instead.
|
|
867
|
+
*/
|
|
868
|
+
const subscribeMarketStats = (tradingPairId, handler) => {
|
|
869
|
+
if (!tradingPairId) {
|
|
870
|
+
throw new Error("marketStats subscription requires a tradingPairId");
|
|
871
|
+
}
|
|
872
|
+
if (!handler) {
|
|
873
|
+
throw new Error("marketStats subscription requires a handler");
|
|
874
|
+
}
|
|
875
|
+
return subscribe(`market_stats:${tradingPairId}`, (rawData) => {
|
|
876
|
+
try {
|
|
877
|
+
handler(parseMarketStatsEvent(rawData));
|
|
878
|
+
}
|
|
879
|
+
catch (err) {
|
|
880
|
+
console.error("WebSocket: Error processing market stats event", err);
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
};
|
|
884
|
+
/**
|
|
885
|
+
* Subscribe to the all-markets statistics summary (public): one summary row
|
|
886
|
+
* per market in a single frame per push.
|
|
887
|
+
*/
|
|
888
|
+
const subscribeMarketStatsAll = (handler) => {
|
|
889
|
+
if (!handler) {
|
|
890
|
+
throw new Error("marketStatsAll subscription requires a handler");
|
|
891
|
+
}
|
|
892
|
+
return subscribe("market_stats", (rawData) => {
|
|
893
|
+
// routeMessage prefix-matches the bare `market_stats` subscription against
|
|
894
|
+
// per-market `market_stats:<pair>` frames too; those carry
|
|
895
|
+
// `{ trading_pair_id, data }`, not `{ markets }`. Drop them here so the
|
|
896
|
+
// all-markets handler only ever sees all-markets frames.
|
|
897
|
+
if (!isRecord(rawData) || !Array.isArray(rawData.markets)) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
try {
|
|
901
|
+
handler(parseMarketStatsAllEvent(rawData));
|
|
902
|
+
}
|
|
903
|
+
catch (err) {
|
|
904
|
+
console.error("WebSocket: Error processing market stats all event", err);
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
};
|
|
732
908
|
return {
|
|
733
909
|
connect,
|
|
734
910
|
disconnect,
|
|
@@ -759,5 +935,8 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
759
935
|
conditionalOrders: subscribeConditionalOrders,
|
|
760
936
|
positions: subscribePositions,
|
|
761
937
|
liquidations: subscribeLiquidations,
|
|
938
|
+
account: subscribeAccount,
|
|
939
|
+
marketStats: subscribeMarketStats,
|
|
940
|
+
marketStatsAll: subscribeMarketStatsAll,
|
|
762
941
|
};
|
|
763
942
|
}
|
package/dist/coverage.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** operationId → the @0xmonaco/core client method that covers it. */
|
|
2
2
|
export declare const COVERED: {
|
|
3
|
-
add_position_margin: string;
|
|
4
3
|
attach_position_tp_sl: string;
|
|
5
4
|
batch_cancel_all: string;
|
|
6
5
|
batch_cancel_all_by_pair: string;
|
|
@@ -84,7 +83,6 @@ export declare const COVERED: {
|
|
|
84
83
|
list_sub_accounts_with_balances: string;
|
|
85
84
|
list_trading_pairs: string;
|
|
86
85
|
mint_tokens: string;
|
|
87
|
-
reduce_position_margin: string;
|
|
88
86
|
refresh_session: string;
|
|
89
87
|
replace_order: string;
|
|
90
88
|
revoke_delegated_agent: string;
|
package/dist/coverage.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** operationId → the @0xmonaco/core client method that covers it. */
|
|
2
2
|
export const COVERED = {
|
|
3
|
-
add_position_margin: "addPositionMargin",
|
|
4
3
|
attach_position_tp_sl: "attachPositionTpSl",
|
|
5
4
|
batch_cancel_all: "batchCancelAll",
|
|
6
5
|
batch_cancel_all_by_pair: "batchCancelAll (with tradingPairId)",
|
|
@@ -84,7 +83,6 @@ export const COVERED = {
|
|
|
84
83
|
list_sub_accounts_with_balances: "subAccounts.list",
|
|
85
84
|
list_trading_pairs: "getPaginatedTradingPairs",
|
|
86
85
|
mint_tokens: "faucet.mint",
|
|
87
|
-
reduce_position_margin: "reducePositionMargin",
|
|
88
86
|
refresh_session: "refreshSession",
|
|
89
87
|
replace_order: "replaceOrder",
|
|
90
88
|
revoke_delegated_agent: "revokeDelegatedAgent",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xmonaco/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.41-develop.ebb62ed",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"viem": "^2.45.2"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@0xmonaco/contracts": "1.0.
|
|
27
|
-
"@0xmonaco/types": "1.0.
|
|
26
|
+
"@0xmonaco/contracts": "1.0.41-develop.ebb62ed",
|
|
27
|
+
"@0xmonaco/types": "1.0.41-develop.ebb62ed",
|
|
28
28
|
"@noble/curves": "^1.9.1",
|
|
29
29
|
"@noble/hashes": "^1.8.0",
|
|
30
30
|
"http-status-codes": "^2.3.0"
|