@0xmonaco/core 1.0.41 → 1.0.42
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/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}`
|
|
@@ -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
|
}
|
|
@@ -170,6 +170,104 @@ function parseLiquidationEvent(rawData) {
|
|
|
170
170
|
},
|
|
171
171
|
};
|
|
172
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
|
+
}
|
|
173
271
|
/**
|
|
174
272
|
* Create a Monaco WebSocket client
|
|
175
273
|
*/
|
|
@@ -741,6 +839,72 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
741
839
|
}
|
|
742
840
|
});
|
|
743
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
|
+
};
|
|
744
908
|
return {
|
|
745
909
|
connect,
|
|
746
910
|
disconnect,
|
|
@@ -771,5 +935,8 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
771
935
|
conditionalOrders: subscribeConditionalOrders,
|
|
772
936
|
positions: subscribePositions,
|
|
773
937
|
liquidations: subscribeLiquidations,
|
|
938
|
+
account: subscribeAccount,
|
|
939
|
+
marketStats: subscribeMarketStats,
|
|
940
|
+
marketStatsAll: subscribeMarketStatsAll,
|
|
774
941
|
};
|
|
775
942
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xmonaco/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.42",
|
|
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.42",
|
|
27
|
+
"@0xmonaco/types": "1.0.42",
|
|
28
28
|
"@noble/curves": "^1.9.1",
|
|
29
29
|
"@noble/hashes": "^1.8.0",
|
|
30
30
|
"http-status-codes": "^2.3.0"
|