@0xmonaco/core 1.0.47 → 1.0.48

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.
@@ -7,11 +7,6 @@ const CONNECTION_TIMEOUT = 10000;
7
7
  const HEARTBEAT_INTERVAL = 15000;
8
8
  const MAX_RECONNECT_DELAY = 30000;
9
9
  const RECONNECT_BASE_DELAY = 1000;
10
- const CONDITIONAL_ORDER_REASONS = ["created", "activated", "cancelled", "parent_cancelled", "triggered", "failed", "oco_cancelled"];
11
- const CONDITIONAL_ORDER_CONDITION_TYPES = ["STOP_LOSS", "TAKE_PROFIT"];
12
- const CONDITIONAL_ORDER_TRIGGER_SOURCES = ["MARK_PRICE"];
13
- const CONDITIONAL_ORDER_STATES = ["PENDING_PARENT", "ACTIVE", "TRIGGERING", "TRIGGERED", "CANCELLED", "EXPIRED", "FAILED"];
14
- const CONDITIONAL_ORDER_ASSOCIATION_TYPES = ["POSITION", "PARENT_ORDER"];
15
10
  const TWAP_ORDER_STATES = ["PENDING", "ACTIVE", "COMPLETED", "CANCELLED"];
16
11
  const INSTRUMENT_CHANGE_KINDS = ["listing", "delisting", "halt", "unhalt", "config_change"];
17
12
  function isRecord(value) {
@@ -76,14 +71,20 @@ function readEnum(source, field, allowed) {
76
71
  }
77
72
  return value;
78
73
  }
79
- function readOptionalEnum(source, field, allowed) {
80
- const value = source[field];
81
- if (value === undefined || value === null)
82
- return undefined;
83
- if (typeof value !== "string" || !allowed.includes(value)) {
84
- throw new Error(`Invalid WebSocket event: ${field} must be one of ${allowed.join(", ")}`);
85
- }
86
- return value;
74
+ /**
75
+ * Read an optional wire enum leniently.
76
+ *
77
+ * Absent, `null`, and a present-but-empty string all mean "not set": server
78
+ * side these fields are `Option<..>` over closed enums, so `""` is a malformed
79
+ * value rather than a variant this SDK version predates, and letting it through
80
+ * would put a string the union does not contain onto the typed surface. It is
81
+ * mapped to absent rather than thrown on, because throwing would drop the whole
82
+ * frame over one optional field. A non-empty value is passed through untouched,
83
+ * whether or not the SDK recognizes it.
84
+ */
85
+ function readOptionalEnumValue(source, field) {
86
+ const value = readOptionalString(source, field);
87
+ return value === undefined || value.length === 0 ? undefined : value;
87
88
  }
88
89
  function parseConditionalOrderEvent(rawData) {
89
90
  if (!isRecord(rawData)) {
@@ -94,6 +95,13 @@ function parseConditionalOrderEvent(rawData) {
94
95
  }
95
96
  const data = keysToCamelCase(rawData.data);
96
97
  return {
98
+ // event_type is the event-class discriminator, validated strictly so a
99
+ // mis-routed frame is rejected rather than parsed as a conditional order.
100
+ // The value fields below stay lenient — read as strings and cast, never
101
+ // checked against an allow-list — so an unexpected *value* never drops the
102
+ // whole update (0XM-2627). The parse throw is swallowed by the
103
+ // message-handler catch, so a strict enum here means a silently lost frame
104
+ // with nothing surfaced to the consumer.
97
105
  eventType: readEnum(rawData, "event_type", ["conditional_order_update"]),
98
106
  userId: readString(rawData, "user_id"),
99
107
  data: {
@@ -102,27 +110,29 @@ function parseConditionalOrderEvent(rawData) {
102
110
  marginAccountId: readString(data, "marginAccountId"),
103
111
  positionId: readOptionalString(data, "positionId"),
104
112
  parentOrderId: readOptionalString(data, "parentOrderId"),
105
- associationType: readOptionalEnum(data, "associationType", CONDITIONAL_ORDER_ASSOCIATION_TYPES),
113
+ associationType: readOptionalEnumValue(data, "associationType"),
106
114
  linkedGroupId: readOptionalString(data, "linkedGroupId"),
107
- conditionType: readEnum(data, "conditionType", CONDITIONAL_ORDER_CONDITION_TYPES),
108
- triggerSource: readEnum(data, "triggerSource", CONDITIONAL_ORDER_TRIGGER_SOURCES),
115
+ conditionType: readString(data, "conditionType"),
116
+ triggerSource: readString(data, "triggerSource"),
109
117
  triggerPrice: readString(data, "triggerPrice"),
110
- side: readEnum(data, "side", ["BUY", "SELL"]),
111
- positionSide: readEnum(data, "positionSide", ["LONG", "SHORT", "NONE"]),
112
- orderType: readEnum(data, "orderType", ["LIMIT", "MARKET"]),
118
+ side: readString(data, "side"),
119
+ positionSide: readString(data, "positionSide"),
120
+ orderType: readString(data, "orderType"),
113
121
  limitPrice: readOptionalString(data, "limitPrice"),
114
122
  quantity: readOptionalString(data, "quantity"),
115
123
  slippageToleranceBps: readOptionalNumber(data, "slippageToleranceBps"),
116
124
  reduceOnly: readBoolean(data, "reduceOnly"),
117
- timeInForce: readOptionalEnum(data, "timeInForce", ["GTC", "IOC"]),
118
- state: readEnum(data, "state", CONDITIONAL_ORDER_STATES),
125
+ timeInForce: readOptionalEnumValue(data, "timeInForce"),
126
+ state: readString(data, "state"),
119
127
  triggeredOrderId: readOptionalString(data, "triggeredOrderId"),
120
128
  triggeredAt: readOptionalString(data, "triggeredAt"),
121
129
  activatedAt: readOptionalString(data, "activatedAt"),
122
130
  cancelledAt: readOptionalString(data, "cancelledAt"),
123
131
  expiresAt: readOptionalString(data, "expiresAt"),
124
132
  failureReason: readOptionalString(data, "failureReason"),
125
- reason: readEnum(data, "reason", CONDITIONAL_ORDER_REASONS),
133
+ // Free-form on the wire (the server field is a plain string), so it is
134
+ // passed through untouched rather than matched against a value list.
135
+ reason: readString(data, "reason"),
126
136
  updatedAt: readString(data, "updatedAt"),
127
137
  },
128
138
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xmonaco/core",
3
- "version": "1.0.47",
3
+ "version": "1.0.48",
4
4
  "type": "module",
5
5
  "homepage": "https://docs.0xmonaco.com/sdk/typescript",
6
6
  "main": "./dist/index.js",
@@ -19,8 +19,8 @@
19
19
  "viem": "^2.45.2"
20
20
  },
21
21
  "dependencies": {
22
- "@0xmonaco/contracts": "1.0.47",
23
- "@0xmonaco/types": "1.0.47",
22
+ "@0xmonaco/contracts": "1.0.48",
23
+ "@0xmonaco/types": "1.0.48",
24
24
  "@noble/curves": "^1.9.1",
25
25
  "@noble/hashes": "^1.8.0",
26
26
  "http-status-codes": "^2.3.0"