@orderly.network/hooks 1.0.28 → 1.1.0

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/index.js CHANGED
@@ -28,9 +28,9 @@ var useSWRSubscription__default = /*#__PURE__*/_interopDefault(useSWRSubscriptio
28
28
  // src/version.ts
29
29
  if (typeof window !== "undefined") {
30
30
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
31
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "1.0.28";
31
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "1.1.0";
32
32
  }
33
- var version_default = "1.0.28";
33
+ var version_default = "1.1.0";
34
34
  var fetcher = (url, init = {}, queryOptions) => net.get(url, init, queryOptions?.formatter);
35
35
  var OrderlyContext = React.createContext({
36
36
  // configStore: new MemoryConfigStore(),
@@ -201,7 +201,6 @@ var signatureMiddleware = (useSWRNext) => {
201
201
  };
202
202
  return useSWRNext(key, extendedFetcher, config);
203
203
  } catch (e) {
204
- console.error("signature error:", e);
205
204
  throw e;
206
205
  }
207
206
  };
@@ -346,23 +345,16 @@ function useSessionStorage(key, initialValue) {
346
345
  const item = window.sessionStorage.getItem(key);
347
346
  return item ? parseJSON(item) : initialValue;
348
347
  } catch (error) {
349
- console.warn(`Error reading sessionStorage key \u201C${key}\u201D:`, error);
350
348
  return initialValue;
351
349
  }
352
350
  }, [initialValue, key]);
353
351
  const [storedValue, setStoredValue] = React.useState(readValue);
354
352
  const setValue = (value) => {
355
- if (typeof window == "undefined") {
356
- console.warn(
357
- `Tried setting sessionStorage key \u201C${key}\u201D even though environment is not a client`
358
- );
359
- }
360
353
  try {
361
354
  const newValue = value instanceof Function ? value(storedValue) : value;
362
355
  window.sessionStorage.setItem(key, JSON.stringify(newValue));
363
356
  setStoredValue(newValue);
364
357
  } catch (error) {
365
- console.warn(`Error setting sessionStorage key \u201C${key}\u201D:`, error);
366
358
  }
367
359
  };
368
360
  React.useEffect(() => {
@@ -397,24 +389,18 @@ function useLocalStorage(key, initialValue) {
397
389
  const item = window.localStorage.getItem(key);
398
390
  return item ? parseJSON(item) : initialValue;
399
391
  } catch (error) {
400
- console.warn(`Error reading localStorage key \u201C${key}\u201D:`, error);
401
392
  return initialValue;
402
393
  }
403
394
  }, [initialValue, key]);
404
395
  const [storedValue, setStoredValue] = React.useState(readValue);
405
396
  const setValue = React.useCallback(
406
397
  (value) => {
407
- if (typeof window === "undefined") {
408
- console.warn(
409
- `Tried setting localStorage key \u201C${key}\u201D even though environment is not a client`
410
- );
411
- }
412
398
  try {
413
399
  const newValue = value instanceof Function ? value(storedValue) : value;
414
400
  window.localStorage.setItem(key, JSON.stringify(newValue));
401
+ window.dispatchEvent(new Event("storage"));
415
402
  setStoredValue(() => newValue);
416
403
  } catch (error) {
417
- console.warn(`Error setting localStorage key \u201C${key}\u201D:`, error);
418
404
  }
419
405
  },
420
406
  [storedValue]
@@ -422,6 +408,18 @@ function useLocalStorage(key, initialValue) {
422
408
  React.useEffect(() => {
423
409
  setStoredValue(readValue());
424
410
  }, []);
411
+ React.useEffect(() => {
412
+ const handleStorageChange = (event) => {
413
+ if (event?.key && event.key !== key) {
414
+ return;
415
+ }
416
+ setStoredValue(readValue());
417
+ };
418
+ window.addEventListener("storage", handleStorageChange);
419
+ return () => {
420
+ window.removeEventListener("storage", handleStorageChange);
421
+ };
422
+ }, [key]);
425
423
  return [storedValue, setValue];
426
424
  }
427
425
  var WS_NAME = "nativeWebsocketClient";
@@ -459,36 +457,48 @@ var useWS = () => {
459
457
  });
460
458
  return ws;
461
459
  };
462
- var usePrivateDataObserver = () => {
460
+ var usePrivateDataObserver = (options) => {
463
461
  const ws = useWS();
464
462
  const { mutate: mutate2 } = useSWR.useSWRConfig();
465
463
  const ee = useEventEmitter();
466
464
  const { state } = useAccount();
467
- const updateOrders = useDebounce.useDebouncedCallback(() => {
468
- mutate2(
469
- useSWRInfinite.unstable_serialize(() => [
470
- `/v1/orders?size=100&page=1&status=${types.OrderStatus.INCOMPLETE}`,
471
- state.accountId
472
- ])
473
- );
474
- mutate2(
475
- useSWRInfinite.unstable_serialize(() => [
476
- `/v1/orders?size=100&page=1&status=${types.OrderStatus.NEW}`,
477
- state.accountId
478
- ])
479
- );
465
+ const updateOrders = useDebounce.useDebouncedCallback((data) => {
466
+ const map = options.getKeysMap("orders");
467
+ map.forEach((getKey, key) => {
468
+ mutate2(
469
+ useSWRInfinite.unstable_serialize((index, prevData) => [
470
+ getKey(index, prevData),
471
+ state.accountId
472
+ ])
473
+ );
474
+ });
480
475
  }, 500);
481
476
  React.useEffect(() => {
482
477
  if (!state.accountId)
483
478
  return;
484
479
  const unsubscribe = ws.privateSubscribe("executionreport", {
485
480
  onMessage: (data) => {
486
- updateOrders();
481
+ updateOrders(data);
487
482
  ee.emit("orders:changed", data);
488
483
  }
489
484
  });
490
485
  return () => unsubscribe?.();
491
486
  }, [state.accountId]);
487
+ React.useEffect(() => {
488
+ if (!state.accountId)
489
+ return;
490
+ const unsubscribe = ws.privateSubscribe("algoexecutionreport", {
491
+ onMessage: (data) => {
492
+ updateOrders(data);
493
+ if (Array.isArray(data)) {
494
+ data.forEach((item) => ee.emit("orders:changed", { ...item, status: item.algoStatus }));
495
+ } else {
496
+ ee.emit("orders:changed", { ...data, status: data.algoStatus });
497
+ }
498
+ }
499
+ });
500
+ return () => unsubscribe?.();
501
+ }, [state.accountId]);
492
502
  React.useEffect(() => {
493
503
  if (!state.accountId)
494
504
  return;
@@ -547,15 +557,31 @@ var usePrivateDataObserver = () => {
547
557
  var DataCenterContext = React.createContext(
548
558
  {}
549
559
  );
560
+ var useDataCenterContext = () => React.useContext(DataCenterContext);
550
561
  var DataCenterProvider = ({ children }) => {
551
562
  const { error, done } = usePreLoadData();
552
- usePrivateDataObserver();
563
+ const getKeyHandlerMapRef = React.useRef(/* @__PURE__ */ new Map());
564
+ usePrivateDataObserver({
565
+ getKeysMap(type) {
566
+ return getKeyHandlerMapRef.current;
567
+ }
568
+ });
553
569
  if (error) {
554
570
  return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Data load failed" });
555
571
  }
556
572
  if (!done)
557
573
  return null;
558
- return /* @__PURE__ */ jsxRuntime.jsx(DataCenterContext.Provider, { value: {}, children });
574
+ return /* @__PURE__ */ jsxRuntime.jsx(
575
+ DataCenterContext.Provider,
576
+ {
577
+ value: {
578
+ regesterKeyHandler: (key, fun) => {
579
+ getKeyHandlerMapRef.current.set(key, fun);
580
+ }
581
+ },
582
+ children
583
+ }
584
+ );
559
585
  };
560
586
  var OrderlyConfigProvider = (props) => {
561
587
  const [account5, setAccount] = React__default.default.useState(null);
@@ -568,9 +594,6 @@ var OrderlyConfigProvider = (props) => {
568
594
  enableSwapDeposit,
569
595
  contracts
570
596
  } = props;
571
- if (!brokerId && typeof configStore === "undefined") {
572
- console.error("[OrderlyConfigProvider]: brokerId is required");
573
- }
574
597
  const innerConfigStore = useConstant4__default.default(() => {
575
598
  return configStore || new core.DefaultConfigStore({ brokerId, networkId });
576
599
  });
@@ -794,7 +817,7 @@ var reduceItems = (depth, level, data, asks = false) => {
794
817
  const result = [];
795
818
  if (typeof depth !== "undefined") {
796
819
  const prices = /* @__PURE__ */ new Map();
797
- for (let i = 0; i < data.length; i++) {
820
+ for (let i = 0; i < ramda.min(level, data.length); i++) {
798
821
  const [price, quantity] = data[i];
799
822
  if (isNaN(price) || isNaN(quantity))
800
823
  continue;
@@ -829,7 +852,8 @@ var reduceItems = (depth, level, data, asks = false) => {
829
852
  if (isNaN(price) || isNaN(quantity))
830
853
  continue;
831
854
  const newQuantity = new utils.Decimal(quantity).add(result.length > 0 ? result[result.length - 1][2] : 0).toNumber();
832
- result.push([price, quantity, newQuantity]);
855
+ const newAmount = new utils.Decimal(quantity * price).add(result.length > 0 ? result[result.length - 1][3] : 0).toNumber();
856
+ result.push([price, quantity, newQuantity, newAmount]);
833
857
  }
834
858
  return result;
835
859
  };
@@ -860,9 +884,11 @@ var reduceOrderbook = (depth, level, data) => {
860
884
  }
861
885
  }
862
886
  asks = asks.reverse();
887
+ asks = asks.length < level ? paddingFn(level - asks.length).concat(asks) : asks;
888
+ bids = bids.length < level ? bids.concat(paddingFn(level - bids.length)) : bids;
863
889
  return {
864
- asks: asks.length < level ? paddingFn(level - asks.length).concat(asks) : asks,
865
- bids: bids.length < level ? bids.concat(paddingFn(level - bids.length)) : bids
890
+ asks,
891
+ bids
866
892
  };
867
893
  };
868
894
  var mergeItems = (data, update) => {
@@ -902,7 +928,7 @@ var mergeOrderbook = (data, update) => {
902
928
  var INIT_DATA = { asks: [], bids: [] };
903
929
  var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
904
930
  if (!symbol) {
905
- throw new Error("useOrderbookStream requires a symbol");
931
+ throw new types.SDKError("useOrderbookStream requires a symbol");
906
932
  }
907
933
  const level = options?.level ?? 10;
908
934
  const [requestData, setRequestData] = React.useState(null);
@@ -1010,6 +1036,12 @@ var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
1010
1036
  asks: [...data.asks],
1011
1037
  bids: [...data.bids]
1012
1038
  });
1039
+ React.useEffect(() => {
1040
+ eventEmitter.emit("orderbook:update", [
1041
+ reducedData.asks[0][0],
1042
+ reducedData.bids[0][0]
1043
+ ]);
1044
+ }, [reducedData.asks[0][0], reducedData.bids[0][0]]);
1013
1045
  return [
1014
1046
  {
1015
1047
  asks: reducedData.asks.slice(-level),
@@ -1020,13 +1052,28 @@ var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
1020
1052
  { onDepthChange, depth, allDepths: depths, isLoading, onItemClick }
1021
1053
  ];
1022
1054
  };
1023
- var needNumberOnlyFields = ["order_quantity", "order_price", "total"];
1055
+ var needNumberOnlyFields = [
1056
+ "order_quantity",
1057
+ "order_price",
1058
+ "total"
1059
+ ];
1060
+ var cleanStringStyle = (str) => {
1061
+ if (typeof str !== "string") {
1062
+ str = str.toString();
1063
+ }
1064
+ str = str.replace(/,/g, "");
1065
+ str = str.replace(/[^\d.]/g, "").replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
1066
+ return str;
1067
+ };
1024
1068
  function baseInputHandle(inputs) {
1025
1069
  let [values, input, value, markPrice, config] = inputs;
1070
+ needNumberOnlyFields.forEach((field) => {
1071
+ if (typeof values[field] !== "undefined") {
1072
+ values[field] = cleanStringStyle(values[field]);
1073
+ }
1074
+ });
1026
1075
  if (needNumberOnlyFields.includes(input)) {
1027
- value = value.toString();
1028
- value = value.replace(/,/g, "");
1029
- value = value.replace(/[^\d.]/g, "");
1076
+ value = cleanStringStyle(value);
1030
1077
  }
1031
1078
  return [
1032
1079
  {
@@ -1056,15 +1103,23 @@ function priceInputHandle(inputs) {
1056
1103
  values.order_price = price.toDecimalPlaces(config.quoteDP).toString();
1057
1104
  }
1058
1105
  price.toDecimalPlaces(Math.min(priceDP, config.quoteDP));
1059
- if (!values.order_quantity) {
1106
+ if (!values.order_quantity && !values.total) {
1060
1107
  return [values, input, value, markPrice, config];
1061
1108
  }
1062
- const total = price.mul(values.order_quantity);
1109
+ const newValue = {
1110
+ ...values
1111
+ };
1112
+ if (values.order_quantity) {
1113
+ newValue.total = price.mul(values.order_quantity).todp(2).toString();
1114
+ } else if (values.total) {
1115
+ newValue.order_quantity = new utils.Decimal(values.total).div(price).todp(config.baseDP).toString();
1116
+ }
1063
1117
  return [
1064
- {
1065
- ...values,
1066
- total: total.todp(2).toString()
1067
- },
1118
+ // {
1119
+ // ...values,
1120
+ // total: total.todp(2).toString(),
1121
+ // },
1122
+ newValue,
1068
1123
  input,
1069
1124
  value,
1070
1125
  markPrice,
@@ -1082,11 +1137,11 @@ function quantityInputHandle(inputs) {
1082
1137
  quantity = quantity.toDecimalPlaces(config.baseDP);
1083
1138
  values.order_quantity = quantity.toNumber();
1084
1139
  }
1085
- if (values.order_type === types.OrderType.MARKET) {
1140
+ if (values.order_type === types.OrderType.MARKET || values.order_type === types.OrderType.STOP_MARKET) {
1086
1141
  const price = markPrice;
1087
1142
  values.total = quantity.mul(price).todp(2).toNumber();
1088
1143
  }
1089
- if (values.order_type === types.OrderType.LIMIT) {
1144
+ if (values.order_type === types.OrderType.LIMIT || values.order_type === types.OrderType.STOP_LIMIT) {
1090
1145
  if (values.order_price) {
1091
1146
  const price = Number(values.order_price);
1092
1147
  const total = quantity.mul(price);
@@ -1112,7 +1167,7 @@ function totalInputHandle(inputs) {
1112
1167
  return [{ ...values, order_quantity: "" }, input, value, markPrice, config];
1113
1168
  }
1114
1169
  let price = markPrice;
1115
- if (values.order_type === types.OrderType.LIMIT && !!values.order_price) {
1170
+ if ((values.order_type === types.OrderType.LIMIT || values.order_type === types.OrderType.STOP_LIMIT) && !!values.order_price) {
1116
1171
  price = Number(values.order_price);
1117
1172
  }
1118
1173
  let total = new utils.Decimal(value);
@@ -1220,6 +1275,60 @@ var parseHolding = (holding, markPrices) => {
1220
1275
  });
1221
1276
  return [USDC_holding, nonUSDC];
1222
1277
  };
1278
+ var useMarketsStream = () => {
1279
+ const ws = useWS();
1280
+ const { data: futures } = useQuery(`/v1/public/futures`, {
1281
+ revalidateOnFocus: false
1282
+ });
1283
+ const { data: tickers } = useSWRSubscription__default.default("tickers", (_, { next }) => {
1284
+ const unsubscribe = ws.subscribe(
1285
+ // { event: "subscribe", topic: "markprices" },
1286
+ "tickers",
1287
+ {
1288
+ onMessage: (message) => {
1289
+ next(null, message);
1290
+ }
1291
+ // onUnsubscribe: () => {
1292
+ // return "markprices";
1293
+ // },
1294
+ // onError: (error: any) => {
1295
+ //
1296
+ // },
1297
+ }
1298
+ );
1299
+ return () => {
1300
+ unsubscribe?.();
1301
+ };
1302
+ });
1303
+ const value = React.useMemo(() => {
1304
+ if (!futures)
1305
+ return null;
1306
+ if (!tickers)
1307
+ return futures;
1308
+ return futures.map((item) => {
1309
+ const ticker = tickers.find(
1310
+ (t) => t.symbol === item.symbol
1311
+ );
1312
+ if (ticker) {
1313
+ const data = {
1314
+ ...item,
1315
+ ["24h_close"]: ticker.close,
1316
+ ["24h_open"]: ticker.open,
1317
+ ["24h_volumn"]: ticker.volume,
1318
+ change: 0
1319
+ };
1320
+ if (ticker.close !== void 0 && ticker.open !== void 0) {
1321
+ data["change"] = new utils.Decimal(ticker.close).minus(ticker.open).div(ticker.open).toNumber();
1322
+ }
1323
+ return data;
1324
+ }
1325
+ return item;
1326
+ });
1327
+ }, [futures, tickers]);
1328
+ return { data: value };
1329
+ };
1330
+
1331
+ // src/orderly/usePositionStream.ts
1223
1332
  var usePositionStream = (symbol, options) => {
1224
1333
  const symbolInfo = useSymbolsInfo();
1225
1334
  const { data: accountInfo } = usePrivateQuery("/v1/client/info");
@@ -1235,7 +1344,7 @@ var usePositionStream = (symbol, options) => {
1235
1344
  const {
1236
1345
  data,
1237
1346
  error,
1238
- mutate: updatePositions
1347
+ mutate: refreshPositions
1239
1348
  } = usePrivateQuery(`/v1/positions`, {
1240
1349
  // revalidateOnFocus: false,
1241
1350
  // revalidateOnReconnect: false,
@@ -1248,6 +1357,20 @@ var usePositionStream = (symbol, options) => {
1248
1357
  }
1249
1358
  });
1250
1359
  const { data: markPrices } = useMarkPricesStream();
1360
+ const [priceMode, setPriceMode] = React.useState(options?.calcMode || "markPrice");
1361
+ React.useEffect(() => {
1362
+ if (options?.calcMode && priceMode !== options?.calcMode) {
1363
+ setPriceMode(options?.calcMode);
1364
+ }
1365
+ }, [options?.calcMode]);
1366
+ const { data: tickers } = useMarketsStream();
1367
+ const tickerPrices = React.useMemo(() => {
1368
+ const data2 = /* @__PURE__ */ Object.create(null);
1369
+ tickers?.forEach((item) => {
1370
+ data2[item.symbol] = item["24h_close"];
1371
+ });
1372
+ return data2;
1373
+ }, [tickers]);
1251
1374
  const formatedPositions = React.useMemo(() => {
1252
1375
  if (!data?.rows || !symbolInfo || !accountInfo)
1253
1376
  return null;
@@ -1256,6 +1379,11 @@ var usePositionStream = (symbol, options) => {
1256
1379
  });
1257
1380
  let unrealPnL_total = utils.zero, notional_total = utils.zero, unsettlementPnL_total = utils.zero;
1258
1381
  const formatted = filteredData.map((item) => {
1382
+ const unRealizedPrice = ramda.propOr(
1383
+ item.mark_price,
1384
+ item.symbol,
1385
+ priceMode === "markPrice" ? markPrices : tickerPrices
1386
+ );
1259
1387
  const price = ramda.propOr(
1260
1388
  item.mark_price,
1261
1389
  item.symbol,
@@ -1266,7 +1394,7 @@ var usePositionStream = (symbol, options) => {
1266
1394
  const unrealPnl = perp.positions.unrealizedPnL({
1267
1395
  qty: item.position_qty,
1268
1396
  openPrice: item?.average_open_price,
1269
- markPrice: price
1397
+ markPrice: unRealizedPrice
1270
1398
  });
1271
1399
  const imr = perp.account.IMR({
1272
1400
  maxLeverage: accountInfo.max_leverage,
@@ -1313,7 +1441,16 @@ var usePositionStream = (symbol, options) => {
1313
1441
  unsettledPnL: unsettlementPnL_total.toNumber()
1314
1442
  }
1315
1443
  ];
1316
- }, [data?.rows, symbolInfo, accountInfo, markPrices, symbol, holding]);
1444
+ }, [
1445
+ data?.rows,
1446
+ symbolInfo,
1447
+ accountInfo,
1448
+ markPrices,
1449
+ priceMode,
1450
+ tickerPrices,
1451
+ symbol,
1452
+ holding
1453
+ ]);
1317
1454
  const [totalCollateral, totalValue, totalUnrealizedROI] = React.useMemo(() => {
1318
1455
  if (!holding || !markPrices) {
1319
1456
  return [utils.zero, utils.zero, 0];
@@ -1343,7 +1480,7 @@ var usePositionStream = (symbol, options) => {
1343
1480
  if (!symbolInfo || !accountInfo)
1344
1481
  return formatedPositions[0];
1345
1482
  const total = totalCollateral.toNumber();
1346
- return formatedPositions[0].filter((item) => item.position_qty !== 0).map((item) => {
1483
+ let rows = formatedPositions[0].filter((item) => item.position_qty !== 0).map((item) => {
1347
1484
  const info = symbolInfo?.[item.symbol];
1348
1485
  const MMR = perp.positions.MMR({
1349
1486
  baseMMR: info("base_mmr"),
@@ -1359,15 +1496,29 @@ var usePositionStream = (symbol, options) => {
1359
1496
  markPrice: item.mark_price,
1360
1497
  MMR
1361
1498
  }),
1362
- est_liq_price: perp.positions.liqPrice({
1363
- markPrice: item.mark_price,
1364
- totalCollateral: total,
1365
- positionQty: item.position_qty,
1366
- MMR
1367
- }),
1368
- MMR
1499
+ // est_liq_price: positions.liqPrice({
1500
+ // markPrice: item.mark_price,
1501
+ // totalCollateral: total,
1502
+ // positionQty: item.position_qty,
1503
+ // MMR,
1504
+ // }),
1505
+ mmr: MMR
1506
+ };
1507
+ });
1508
+ rows = rows.map((item) => {
1509
+ const est_liq_price = perp.positions.liqPrice({
1510
+ markPrice: item.mark_price,
1511
+ totalCollateral: total,
1512
+ positionQty: item.position_qty,
1513
+ positions: rows,
1514
+ MMR: item.mmr
1515
+ });
1516
+ return {
1517
+ ...item,
1518
+ est_liq_price
1369
1519
  };
1370
1520
  });
1521
+ return rows;
1371
1522
  }, [formatedPositions, symbolInfo, accountInfo, totalCollateral]);
1372
1523
  return [
1373
1524
  {
@@ -1386,10 +1537,8 @@ var usePositionStream = (symbol, options) => {
1386
1537
  loading: false,
1387
1538
  // showSymbol,
1388
1539
  error,
1389
- loadMore: () => {
1390
- },
1391
- refresh: () => {
1392
- }
1540
+ // loadMore: () => {},
1541
+ refresh: refreshPositions
1393
1542
  }
1394
1543
  ];
1395
1544
  };
@@ -1450,6 +1599,7 @@ var useHoldingStream = () => {
1450
1599
  var useOrderStream = (params) => {
1451
1600
  const { status, symbol, side, size = 100 } = params;
1452
1601
  const { data: markPrices = {} } = useMarkPricesStream();
1602
+ const { regesterKeyHandler } = useDataCenterContext();
1453
1603
  const [
1454
1604
  doCancelOrder,
1455
1605
  { error: cancelOrderError, isMutating: cancelMutating }
@@ -1458,58 +1608,113 @@ var useOrderStream = (params) => {
1458
1608
  doUpdateOrder,
1459
1609
  { error: updateOrderError, isMutating: updateMutating }
1460
1610
  ] = useMutation("/v1/order", "PUT");
1461
- const ordersResponse = usePrivateInfiniteQuery(
1462
- (pageIndex, previousPageData) => {
1463
- if (previousPageData && !previousPageData.rows?.length)
1464
- return null;
1465
- const search = new URLSearchParams([
1466
- ["size", size.toString()],
1467
- ["page", `${pageIndex + 1}`]
1468
- ]);
1469
- if (status) {
1470
- search.set(`status`, status);
1471
- }
1472
- if (symbol) {
1473
- search.set(`symbol`, symbol);
1474
- }
1475
- if (side) {
1476
- search.set(`side`, side);
1477
- }
1478
- return `/v1/orders?${search.toString()}`;
1479
- },
1480
- {
1481
- initialSize: 1,
1482
- // revalidateFirstPage: false,
1483
- // onError: (err) => {
1484
- // console.error("fetch failed::::", err);
1485
- // },
1486
- formatter: (data) => data
1611
+ const [
1612
+ doCanceAlgolOrder,
1613
+ { error: cancelAlgoOrderError, isMutating: cancelAlgoMutating }
1614
+ ] = useMutation("/v1/algo/order", "DELETE");
1615
+ const [
1616
+ doUpdateAlgoOrder,
1617
+ { error: updateAlgoOrderError, isMutating: updateAlgoMutating }
1618
+ ] = useMutation("/v1/algo/order", "PUT");
1619
+ const getKey = (pageIndex, previousPageData) => {
1620
+ if (previousPageData && !previousPageData.rows?.length)
1621
+ return null;
1622
+ const search = new URLSearchParams([
1623
+ ["size", size.toString()],
1624
+ ["page", `${pageIndex + 1}`],
1625
+ ["source_type", "ALL"]
1626
+ ]);
1627
+ if (status) {
1628
+ search.set(`status`, status);
1487
1629
  }
1488
- );
1489
- const orders = React.useMemo(() => {
1630
+ if (symbol) {
1631
+ search.set(`symbol`, symbol);
1632
+ }
1633
+ if (side) {
1634
+ search.set(`side`, side);
1635
+ }
1636
+ return `/v1/orders?${search.toString()}`;
1637
+ };
1638
+ React.useEffect(() => {
1639
+ const key = `orders:${status}:${symbol}:${side}`;
1640
+ regesterKeyHandler(key, getKey);
1641
+ }, [status, symbol, side]);
1642
+ const ordersResponse = usePrivateInfiniteQuery(getKey, {
1643
+ initialSize: 1,
1644
+ // revalidateFirstPage: false,
1645
+ // onError: (err) => {
1646
+ // console.error("fetch failed::::", err);
1647
+ // },
1648
+ formatter: (data) => data
1649
+ });
1650
+ const flattenOrders = React.useMemo(() => {
1490
1651
  if (!ordersResponse.data) {
1491
1652
  return null;
1492
1653
  }
1493
- return ordersResponse.data?.map((item) => item.rows)?.flat().map((item) => {
1654
+ return ordersResponse.data?.map((item) => item.rows)?.flat();
1655
+ }, [ordersResponse.data]);
1656
+ const orders = React.useMemo(() => {
1657
+ if (!flattenOrders) {
1658
+ return null;
1659
+ }
1660
+ if (status !== types.OrderStatus.NEW && status !== types.OrderStatus.INCOMPLETE) {
1661
+ return flattenOrders;
1662
+ }
1663
+ return flattenOrders.map((item) => {
1494
1664
  return {
1495
1665
  ...item,
1496
1666
  mark_price: markPrices[item.symbol] ?? 0
1497
1667
  };
1498
1668
  });
1499
- }, [ordersResponse.data, markPrices]);
1669
+ }, [flattenOrders, markPrices, status]);
1500
1670
  const total = React.useMemo(() => {
1501
1671
  return ordersResponse.data?.[0]?.meta?.total || 0;
1502
1672
  }, [ordersResponse.data?.[0]?.meta?.total]);
1503
1673
  const cancelAllOrders = React.useCallback(() => {
1504
1674
  }, [ordersResponse.data]);
1505
- const updateOrder = React.useCallback((orderId, order2) => {
1506
- return doUpdateOrder({ ...order2, order_id: orderId });
1675
+ const updateOrder = React.useCallback((orderId, order3) => {
1676
+ if (order3.algo_order_id !== void 0) {
1677
+ return doUpdateAlgoOrder({
1678
+ order_id: orderId,
1679
+ price: order3["order_price"],
1680
+ quantity: order3["order_quantity"],
1681
+ trigger_price: order3["trigger_price"]
1682
+ });
1683
+ }
1684
+ return doUpdateOrder({ ...order3, order_id: orderId });
1507
1685
  }, []);
1508
1686
  const cancelOrder = React.useCallback((orderId, symbol2) => {
1687
+ let isAlgoOrder = false;
1688
+ let order_id;
1689
+ if (typeof orderId === "number") {
1690
+ isAlgoOrder = false;
1691
+ order_id = orderId;
1692
+ } else {
1693
+ order_id = orderId?.order_id;
1694
+ if (orderId?.algo_order_id !== void 0) {
1695
+ isAlgoOrder = true;
1696
+ order_id = orderId?.algo_order_id;
1697
+ }
1698
+ }
1699
+ if (isAlgoOrder) {
1700
+ return doCanceAlgolOrder(null, {
1701
+ // @ts-ignore
1702
+ order_id,
1703
+ symbol: symbol2,
1704
+ source: `SDK${version_default}`
1705
+ }).then((res) => {
1706
+ if (res.success) {
1707
+ ordersResponse.mutate();
1708
+ return res;
1709
+ } else {
1710
+ throw new Error(res.message);
1711
+ }
1712
+ });
1713
+ }
1509
1714
  return doCancelOrder(null, {
1510
- order_id: orderId,
1715
+ order_id,
1511
1716
  symbol: symbol2,
1512
- source: "mweb"
1717
+ source: `SDK_${version_default}`
1513
1718
  }).then((res) => {
1514
1719
  if (res.success) {
1515
1720
  return res;
@@ -1526,17 +1731,22 @@ var useOrderStream = (params) => {
1526
1731
  {
1527
1732
  total,
1528
1733
  isLoading: ordersResponse.isLoading,
1734
+ refresh: ordersResponse.mutate,
1529
1735
  loadMore,
1530
1736
  cancelAllOrders,
1531
1737
  updateOrder,
1532
1738
  cancelOrder,
1533
1739
  errors: {
1534
1740
  cancelOrder: cancelOrderError,
1535
- updateOrder: updateOrderError
1741
+ updateOrder: updateOrderError,
1742
+ cancelAlgoOrder: cancelAlgoOrderError,
1743
+ updateAlgoOrder: updateAlgoOrderError
1536
1744
  },
1537
1745
  submitting: {
1538
1746
  cancelOrder: cancelMutating,
1539
- updateOrder: updateMutating
1747
+ updateOrder: updateMutating,
1748
+ cancelAlgoOrder: cancelAlgoMutating,
1749
+ updateAlglOrder: updateAlgoMutating
1540
1750
  }
1541
1751
  }
1542
1752
  ];
@@ -1547,31 +1757,32 @@ var positionsPath = ramda.pathOr([], [0, "rows"]);
1547
1757
  ramda.pathOr(0, [0, "totalCollateral"]);
1548
1758
  var useCollateral = (options = { dp: 6 }) => {
1549
1759
  const { dp } = options;
1550
- const positions2 = usePositionStream();
1760
+ const positions3 = usePositionStream();
1551
1761
  const [orders] = useOrderStream({ status: types.OrderStatus.NEW });
1552
1762
  const { data: accountInfo } = usePrivateQuery("/v1/client/info");
1553
1763
  const symbolInfo = useSymbolsInfo();
1554
1764
  const { data: markPrices } = useMarkPricesStream();
1555
1765
  const { usdc } = useHoldingStream();
1766
+ const filterAlgoOrders = orders?.filter((item) => item.algo_order_id === void 0) ?? [];
1556
1767
  const [totalCollateral, totalValue] = React.useMemo(() => {
1557
1768
  return [
1558
- ramda.pathOr(utils.zero, [0, "totalCollateral"], positions2),
1559
- ramda.pathOr(utils.zero, [0, "totalValue"], positions2)
1769
+ ramda.pathOr(utils.zero, [0, "totalCollateral"], positions3),
1770
+ ramda.pathOr(utils.zero, [0, "totalValue"], positions3)
1560
1771
  ];
1561
- }, [positions2, markPrices]);
1772
+ }, [positions3, markPrices]);
1562
1773
  const totalInitialMarginWithOrders = React.useMemo(() => {
1563
1774
  if (!accountInfo || !symbolInfo || !markPrices) {
1564
1775
  return 0;
1565
1776
  }
1566
1777
  return perp.account.totalInitialMarginWithOrders({
1567
- positions: positionsPath(positions2),
1568
- orders: orders ?? [],
1778
+ positions: positionsPath(positions3),
1779
+ orders: filterAlgoOrders,
1569
1780
  markPrices,
1570
1781
  IMR_Factors: accountInfo.imr_factor,
1571
1782
  maxLeverage: accountInfo.max_leverage,
1572
1783
  symbolInfo
1573
1784
  });
1574
- }, [positions2, orders, markPrices, accountInfo, symbolInfo]);
1785
+ }, [positions3, filterAlgoOrders, markPrices, accountInfo, symbolInfo]);
1575
1786
  const freeCollateral = React.useMemo(() => {
1576
1787
  return perp.account.freeCollateral({
1577
1788
  totalCollateral,
@@ -1581,15 +1792,18 @@ var useCollateral = (options = { dp: 6 }) => {
1581
1792
  const availableBalance = React.useMemo(() => {
1582
1793
  return perp.account.availableBalance({
1583
1794
  USDCHolding: usdc?.holding ?? 0,
1584
- unsettlementPnL: pathOr_unsettledPnLPathOr(positions2)
1795
+ unsettlementPnL: pathOr_unsettledPnLPathOr(positions3)
1585
1796
  });
1586
- }, [usdc, pathOr_unsettledPnLPathOr(positions2)]);
1797
+ }, [usdc?.holding, pathOr_unsettledPnLPathOr(positions3)]);
1587
1798
  return {
1588
1799
  totalCollateral: totalCollateral.toDecimalPlaces(dp).toNumber(),
1589
1800
  freeCollateral: freeCollateral.toDecimalPlaces(dp).toNumber(),
1590
1801
  totalValue: totalValue.toDecimalPlaces(dp).toNumber(),
1591
1802
  availableBalance,
1592
- unsettledPnL: pathOr_unsettledPnLPathOr(positions2)
1803
+ unsettledPnL: pathOr_unsettledPnLPathOr(positions3),
1804
+ accountInfo,
1805
+ // @hidden
1806
+ positions: positionsPath(positions3)
1593
1807
  };
1594
1808
  };
1595
1809
  var positionsPath2 = ramda.pathOr([], [0, "rows"]);
@@ -1603,8 +1817,8 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
1603
1817
  const maxQty = React.useMemo(() => {
1604
1818
  if (!symbol)
1605
1819
  return 0;
1606
- const positions2 = positionsPath2(positionsData);
1607
- const positionQty = perp.account.getQtyFromPositions(positions2, symbol);
1820
+ const positions3 = positionsPath2(positionsData);
1821
+ const positionQty = perp.account.getQtyFromPositions(positions3, symbol);
1608
1822
  if (reduceOnly) {
1609
1823
  if (positionQty > 0) {
1610
1824
  if (side === types.OrderSide.BUY) {
@@ -1625,20 +1839,21 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
1625
1839
  if (!markPrices || !markPrices[symbol] || !orders || !accountInfo)
1626
1840
  return 0;
1627
1841
  const getSymbolInfo = symbolInfo[symbol];
1842
+ const filterAlgoOrders = orders.filter((item) => item.algo_order_id === void 0);
1628
1843
  const buyOrdersQty = perp.account.getQtyFromOrdersBySide(
1629
- orders,
1844
+ filterAlgoOrders,
1630
1845
  symbol,
1631
1846
  types.OrderSide.BUY
1632
1847
  );
1633
1848
  const sellOrdersQty = perp.account.getQtyFromOrdersBySide(
1634
- orders,
1849
+ filterAlgoOrders,
1635
1850
  symbol,
1636
1851
  types.OrderSide.SELL
1637
1852
  );
1638
- const otherPositions = positions2.filter(
1853
+ const otherPositions = positions3.filter(
1639
1854
  (item) => item.symbol !== symbol
1640
1855
  );
1641
- const otherOrders = orders.filter(
1856
+ const otherOrders = filterAlgoOrders.filter(
1642
1857
  (item) => item.symbol !== symbol
1643
1858
  );
1644
1859
  const otherIMs = perp.account.otherIMs({
@@ -1674,27 +1889,36 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
1674
1889
  totalCollateral,
1675
1890
  reduceOnly
1676
1891
  ]);
1677
- return maxQty;
1892
+ return Math.max(maxQty, 0);
1678
1893
  };
1679
- var { maxPrice, minPrice } = perp.order;
1894
+ var { maxPrice, minPrice, scropePrice } = perp.order;
1680
1895
  var BaseOrderCreator = class {
1681
1896
  baseOrder(data) {
1682
- const order2 = {
1683
- // symbol: data.symbol,
1897
+ const order3 = {
1898
+ symbol: data.symbol,
1684
1899
  order_type: data.order_type === types.OrderType.LIMIT ? !!data.order_type_ext ? data.order_type_ext : data.order_type : data.order_type,
1685
1900
  side: data.side,
1686
1901
  reduce_only: data.reduce_only,
1687
- order_quantity: data.order_quantity
1902
+ order_quantity: data.order_quantity,
1903
+ total: data.total
1688
1904
  };
1689
1905
  if (data.visible_quantity === 0) {
1690
- order2.visible_quantity = data.visible_quantity;
1906
+ order3.visible_quantity = data.visible_quantity;
1691
1907
  }
1692
- return order2;
1908
+ return order3;
1693
1909
  }
1694
1910
  baseValidate(values, configs) {
1695
1911
  const errors = {};
1696
1912
  const { maxQty } = configs;
1697
- const { order_quantity, total } = values;
1913
+ let { order_quantity, total, order_price } = values;
1914
+ if (!order_quantity) {
1915
+ if (total && order_price) {
1916
+ const { quote_dp } = configs.symbol;
1917
+ const totalNumber = new utils.Decimal(total);
1918
+ const qty = totalNumber.dividedBy(order_price).toFixed(quote_dp);
1919
+ order_quantity = qty;
1920
+ }
1921
+ }
1698
1922
  if (!order_quantity) {
1699
1923
  errors.order_quantity = {
1700
1924
  type: "required",
@@ -1740,13 +1964,28 @@ var BaseOrderCreator = class {
1740
1964
  }
1741
1965
  return Promise.resolve(errors);
1742
1966
  }
1967
+ fixOrderQuantity(order3, config) {
1968
+ if (!order3.order_quantity && order3.total && order3.order_price) {
1969
+ const { base_dp } = config.symbol;
1970
+ const totalNumber = new utils.Decimal(order3.total);
1971
+ const qty = totalNumber.div(order3.order_price).toDecimalPlaces(base_dp);
1972
+ order3.order_quantity = qty.toNumber();
1973
+ delete order3.total;
1974
+ }
1975
+ return order3;
1976
+ }
1743
1977
  };
1744
1978
  var LimitOrderCreator = class extends BaseOrderCreator {
1745
- create(values) {
1746
- return {
1979
+ create(values, config) {
1980
+ const order3 = {
1747
1981
  ...this.baseOrder(values),
1748
1982
  order_price: values.order_price
1749
1983
  };
1984
+ this.fixOrderQuantity(order3, config);
1985
+ delete order3["total"];
1986
+ delete order3["trigger_price"];
1987
+ delete order3["isStopOrder"];
1988
+ return order3;
1750
1989
  }
1751
1990
  validate(values, config) {
1752
1991
  return this.baseValidate(values, config).then((errors) => {
@@ -1759,22 +1998,34 @@ var LimitOrderCreator = class extends BaseOrderCreator {
1759
1998
  } else {
1760
1999
  const price = new utils.Decimal(order_price);
1761
2000
  const { symbol } = config;
1762
- const { price_range } = symbol;
2001
+ const { price_range, price_scope } = symbol;
1763
2002
  const maxPriceNumber = maxPrice(config.markPrice, price_range);
1764
2003
  const minPriceNumber = minPrice(config.markPrice, price_range);
1765
- console.log(`side: ${side} value:`, values);
1766
- if (side === "BUY" && price.gt(maxPriceNumber)) {
2004
+ const scropePriceNumbere = scropePrice(
2005
+ config.markPrice,
2006
+ price_scope,
2007
+ side
2008
+ );
2009
+ const priceRange = side === "BUY" ? {
2010
+ min: scropePriceNumbere,
2011
+ max: maxPriceNumber
2012
+ } : {
2013
+ min: minPriceNumber,
2014
+ max: scropePriceNumbere
2015
+ };
2016
+ if (price.gt(priceRange.max)) {
1767
2017
  errors.order_price = {
1768
2018
  type: "max",
1769
- message: `price must be less than ${new utils.Decimal(
1770
- maxPriceNumber
2019
+ message: `Price must be less than ${new utils.Decimal(
2020
+ priceRange.max
1771
2021
  ).todp(symbol.quote_dp)}`
1772
2022
  };
1773
- } else if (side === "SELL" && price.lt(minPriceNumber)) {
2023
+ }
2024
+ if (price.lt(priceRange.min)) {
1774
2025
  errors.order_price = {
1775
2026
  type: "min",
1776
- message: `price must be greater than ${new utils.Decimal(
1777
- minPriceNumber
2027
+ message: `Price must be greater than ${new utils.Decimal(
2028
+ priceRange.min
1778
2029
  ).todp(symbol.quote_dp)}`
1779
2030
  };
1780
2031
  }
@@ -1787,6 +2038,9 @@ var MarketOrderCreator = class extends BaseOrderCreator {
1787
2038
  create(values) {
1788
2039
  const data = this.baseOrder(values);
1789
2040
  delete data["order_price"];
2041
+ delete data["total"];
2042
+ delete data["trigger_price"];
2043
+ delete data["isStopOrder"];
1790
2044
  return {
1791
2045
  ...data
1792
2046
  };
@@ -1801,6 +2055,110 @@ var FOKOrderCreator = class extends LimitOrderCreator {
1801
2055
  };
1802
2056
  var IOCOrderCreator = class extends LimitOrderCreator {
1803
2057
  };
2058
+ var StopLimitOrderCreator = class extends LimitOrderCreator {
2059
+ create(values, config) {
2060
+ const order3 = {
2061
+ ...this.baseOrder(values),
2062
+ order_price: values.order_price,
2063
+ trigger_price: values.trigger_price,
2064
+ algo_type: "STOP",
2065
+ type: "LIMIT",
2066
+ quantity: values["order_quantity"],
2067
+ price: values["order_price"],
2068
+ trigger_price_type: "MARK_PRICE"
2069
+ };
2070
+ this.fixOrderQuantity(order3, config);
2071
+ delete order3["order_quantity"];
2072
+ delete order3["order_price"];
2073
+ delete order3["isStopOrder"];
2074
+ delete order3["total"];
2075
+ return order3;
2076
+ }
2077
+ validate(values, config) {
2078
+ return this.baseValidate(values, config).then((errors) => {
2079
+ const { order_price, trigger_price, side } = values;
2080
+ if (!order_price) {
2081
+ errors.order_price = {
2082
+ type: "required",
2083
+ message: "price is required"
2084
+ };
2085
+ }
2086
+ if (!trigger_price) {
2087
+ errors.trigger_price = {
2088
+ type: "required",
2089
+ message: "Trigger price is required"
2090
+ };
2091
+ }
2092
+ if (trigger_price && order_price) {
2093
+ const price = new utils.Decimal(order_price);
2094
+ const { symbol } = config;
2095
+ const { price_range, price_scope } = symbol;
2096
+ const maxPriceNumber = maxPrice(trigger_price, price_range);
2097
+ const minPriceNumber = minPrice(trigger_price, price_range);
2098
+ const scropePriceNumbere = scropePrice(
2099
+ trigger_price,
2100
+ price_scope,
2101
+ side
2102
+ );
2103
+ const priceRange = side === "BUY" ? {
2104
+ min: scropePriceNumbere,
2105
+ max: maxPriceNumber
2106
+ } : {
2107
+ min: minPriceNumber,
2108
+ max: scropePriceNumbere
2109
+ };
2110
+ if (price.gt(priceRange.max)) {
2111
+ errors.order_price = {
2112
+ type: "max",
2113
+ message: `Price must be less than ${new utils.Decimal(
2114
+ priceRange.max
2115
+ ).todp(symbol.quote_dp)}`
2116
+ };
2117
+ }
2118
+ if (price.lt(priceRange.min)) {
2119
+ errors.order_price = {
2120
+ type: "min",
2121
+ message: `Price must be greater than ${new utils.Decimal(
2122
+ priceRange.min
2123
+ ).todp(symbol.quote_dp)}`
2124
+ };
2125
+ }
2126
+ }
2127
+ return errors;
2128
+ });
2129
+ }
2130
+ };
2131
+ var StopMarketOrderCreator = class extends LimitOrderCreator {
2132
+ create(values, _) {
2133
+ const result = {
2134
+ ...this.baseOrder(values),
2135
+ order_price: values.order_price,
2136
+ trigger_price: values.trigger_price,
2137
+ algo_type: "STOP",
2138
+ type: "MARKET",
2139
+ quantity: values["order_quantity"],
2140
+ price: values["order_price"],
2141
+ trigger_price_type: "MARK_PRICE"
2142
+ };
2143
+ delete result["order_quantity"];
2144
+ delete result["order_price"];
2145
+ delete result["isStopOrder"];
2146
+ delete result["total"];
2147
+ return result;
2148
+ }
2149
+ validate(values, config) {
2150
+ return this.baseValidate(values, config).then((errors) => {
2151
+ const { order_price, trigger_price, side } = values;
2152
+ if (!trigger_price) {
2153
+ errors.trigger_price = {
2154
+ type: "required",
2155
+ message: "Trigger price is required"
2156
+ };
2157
+ }
2158
+ return errors;
2159
+ });
2160
+ }
2161
+ };
1804
2162
  var GeneralOrderCreator = class extends BaseOrderCreator {
1805
2163
  create(data) {
1806
2164
  return {
@@ -1813,6 +2171,15 @@ var GeneralOrderCreator = class extends BaseOrderCreator {
1813
2171
  return super.baseValidate(values, configs);
1814
2172
  }
1815
2173
  };
2174
+ var availableOrderTypes = [
2175
+ types.OrderType.LIMIT,
2176
+ types.OrderType.MARKET,
2177
+ types.OrderType.IOC,
2178
+ types.OrderType.FOK,
2179
+ types.OrderType.POST_ONLY,
2180
+ types.OrderType.STOP_LIMIT,
2181
+ types.OrderType.STOP_MARKET
2182
+ ];
1816
2183
  var OrderFactory = class {
1817
2184
  static create(type) {
1818
2185
  switch (type) {
@@ -1826,17 +2193,68 @@ var OrderFactory = class {
1826
2193
  return new FOKOrderCreator();
1827
2194
  case types.OrderType.POST_ONLY:
1828
2195
  return new PostOnlyOrderCreator();
2196
+ case types.OrderType.STOP_LIMIT:
2197
+ return new StopLimitOrderCreator();
2198
+ case types.OrderType.STOP_MARKET:
2199
+ return new StopMarketOrderCreator();
1829
2200
  default:
1830
2201
  return new GeneralOrderCreator();
1831
2202
  }
1832
2203
  }
1833
2204
  };
1834
-
1835
- // src/orderly/useOrderEntry.ts
1836
- var useOrderEntry = (symbol, side, reduceOnly = false, options) => {
1837
- const [doCreateOrder, { data, error, reset, isMutating }] = useMutation("/v1/order");
1838
- const { freeCollateral } = useCollateral();
2205
+ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
2206
+ if (typeof symbolOrOrder === "object") {
2207
+ if (!symbolOrOrder.symbol) {
2208
+ throw new types.SDKError("symbol is required");
2209
+ }
2210
+ if (!symbolOrOrder.side) {
2211
+ throw new types.SDKError("Order side is required");
2212
+ }
2213
+ if (!symbolOrOrder.order_type) {
2214
+ throw new types.SDKError("order_type is required");
2215
+ }
2216
+ }
2217
+ const prevOrderData = React.useRef(null);
2218
+ const orderDataCache = React.useRef(null);
2219
+ const notSupportData = React.useRef({});
2220
+ const [doCreateOrder, { data, error, reset, isMutating }] = useMutation(orderDataCache?.current?.isStopOrder ? "/v1/algo/order" : "/v1/order");
2221
+ const [errors, setErrors] = React.useState(null);
2222
+ const ee = useEventEmitter();
2223
+ const fieldDirty = React.useRef({});
2224
+ const submitted = React.useRef(false);
2225
+ const askAndBid = React.useRef([]);
2226
+ const onOrderbookUpdate = useDebounce.useDebouncedCallback((data2) => {
2227
+ askAndBid.current = data2;
2228
+ }, 200);
2229
+ const { freeCollateral, totalCollateral, positions: positions3, accountInfo } = useCollateral();
1839
2230
  const symbolInfo = useSymbolsInfo();
2231
+ const symbol = React.useMemo(() => {
2232
+ if (typeof symbolOrOrder === "string") {
2233
+ return symbolOrOrder;
2234
+ }
2235
+ return symbolOrOrder.symbol;
2236
+ }, [symbolOrOrder]);
2237
+ const optionsValue = React.useMemo(() => {
2238
+ if (typeof sideOrOptions === "object") {
2239
+ return sideOrOptions;
2240
+ }
2241
+ return options;
2242
+ }, [sideOrOptions]);
2243
+ const isReduceOnly = React.useMemo(() => {
2244
+ if (typeof reduceOnly === "boolean") {
2245
+ return reduceOnly;
2246
+ }
2247
+ if (typeof symbolOrOrder === "object") {
2248
+ return !!symbolOrOrder.reduce_only;
2249
+ }
2250
+ return false;
2251
+ }, [symbolOrOrder, reduceOnly]);
2252
+ const sideValue = React.useMemo(() => {
2253
+ if (typeof symbolOrOrder === "object") {
2254
+ return symbolOrOrder.side;
2255
+ }
2256
+ return sideOrOptions;
2257
+ }, [symbolOrOrder, sideOrOptions]);
1840
2258
  const baseDP = React.useMemo(
1841
2259
  () => utils.getPrecisionByNumber(symbolInfo[symbol]("base_tick", 0)),
1842
2260
  [symbolInfo]
@@ -1844,42 +2262,123 @@ var useOrderEntry = (symbol, side, reduceOnly = false, options) => {
1844
2262
  const quoteDP = React.useMemo(() => {
1845
2263
  return utils.getPrecisionByNumber(symbolInfo[symbol]("quote_tick", 0));
1846
2264
  }, [symbolInfo]);
2265
+ const baseIMR = React.useMemo(() => symbolInfo[symbol]("base_imr"), [symbolInfo]);
2266
+ const baseMMR = React.useMemo(() => symbolInfo[symbol]("base_mmr"), [symbolInfo]);
1847
2267
  const { data: markPrice } = useMarkPrice(symbol);
1848
- const maxQty = useMaxQty(
1849
- symbol,
1850
- side,
1851
- // orderExtraValues.reduce_only
1852
- reduceOnly
1853
- );
1854
- const onSubmit = (values) => {
1855
- if (!values || typeof values.order_type === "undefined" || values.order_type !== types.OrderType.MARKET && values.order_type !== types.OrderType.LIMIT) {
1856
- throw new Error("order_type is error");
2268
+ const diffOrderEntry = (prev, current) => {
2269
+ if (!prev)
2270
+ return null;
2271
+ let key, value;
2272
+ const keys = Object.keys(current);
2273
+ for (let i = 0; i < keys.length; i++) {
2274
+ const k = keys[i];
2275
+ let preveValue = prev[k];
2276
+ let currentValue = current[k];
2277
+ if (typeof preveValue === "undefined" && typeof currentValue === "undefined")
2278
+ continue;
2279
+ if (preveValue !== currentValue) {
2280
+ key = k;
2281
+ value = currentValue;
2282
+ break;
2283
+ }
2284
+ }
2285
+ if (!key)
2286
+ return null;
2287
+ return { key, value };
2288
+ };
2289
+ const maxQty = useMaxQty(symbol, sideValue, isReduceOnly);
2290
+ const parsedData = React.useMemo(() => {
2291
+ if (typeof symbolOrOrder === "string") {
2292
+ return null;
2293
+ }
2294
+ if (typeof symbolOrOrder.order_quantity === "string") {
2295
+ symbolOrOrder.order_quantity = symbolOrOrder.order_quantity.replace(
2296
+ /,/g,
2297
+ ""
2298
+ );
2299
+ }
2300
+ if (typeof symbolOrOrder.order_price === "string") {
2301
+ symbolOrOrder.order_price = symbolOrOrder.order_price.replace(/,/g, "");
2302
+ }
2303
+ if (typeof symbolOrOrder.total === "string") {
2304
+ symbolOrOrder.total = symbolOrOrder.total.replace(/,/g, "");
2305
+ }
2306
+ if (typeof symbolOrOrder.order_quantity === "number") {
2307
+ symbolOrOrder.order_quantity = new utils.Decimal(symbolOrOrder.order_quantity).toDecimalPlaces(baseDP).toString();
2308
+ }
2309
+ return symbolOrOrder;
2310
+ }, [symbolOrOrder]);
2311
+ const createOrder = (values) => {
2312
+ if (!values.symbol) {
2313
+ throw new types.SDKError("symbol is error");
2314
+ }
2315
+ if (!values.side) {
2316
+ throw new types.SDKError("side is error");
2317
+ }
2318
+ if (!values || typeof values.order_type === "undefined" || !ramda.includes(values.order_type, availableOrderTypes)) {
2319
+ throw new types.SDKError("order_type is error");
1857
2320
  }
1858
2321
  const orderCreator = OrderFactory.create(
1859
- !!values.order_type_ext ? values.order_type_ext : values.order_type
2322
+ values.order_type_ext ? values.order_type_ext : values.order_type
1860
2323
  );
1861
2324
  if (!orderCreator) {
1862
- return Promise.reject(new Error("orderCreator is null"));
2325
+ return Promise.reject(new types.SDKError("orderCreator is null"));
1863
2326
  }
1864
- return orderCreator?.validate(values, {
1865
- symbol: symbolInfo[symbol](),
1866
- // token: tokenInfo[symbol](),
1867
- maxQty,
1868
- markPrice
1869
- }).then(() => {
1870
- if (!orderCreator) {
1871
- throw new Error("orderCreator is null");
1872
- }
1873
- if (!symbol) {
1874
- throw new Error("symbol is null");
1875
- }
1876
- const data2 = orderCreator.create(values);
1877
- return doCreateOrder({
1878
- ...data2,
1879
- symbol
2327
+ return new Promise((resolve, reject) => {
2328
+ return orderCreator.validate(values, {
2329
+ symbol: symbolInfo[symbol](),
2330
+ // token: tokenInfo[symbol](),
2331
+ maxQty,
2332
+ markPrice
2333
+ }).then((errors2) => {
2334
+ submitted.current = true;
2335
+ if (errors2.order_price || errors2.order_quantity || errors2.trigger_price) {
2336
+ setErrors(errors2);
2337
+ reject(
2338
+ errors2.order_price?.message || errors2.order_quantity?.message
2339
+ );
2340
+ } else {
2341
+ const data2 = orderCreator.create(values, {
2342
+ symbol: symbolInfo[symbol](),
2343
+ maxQty,
2344
+ markPrice
2345
+ });
2346
+ return doCreateOrder(
2347
+ ramda.omit(["order_type_ext"], {
2348
+ // ...values,
2349
+ // ...omit(["order_price"], values),
2350
+ ...data2
2351
+ })
2352
+ ).then((res) => {
2353
+ if (res.success) {
2354
+ resolve(res.data);
2355
+ } else {
2356
+ reject(res);
2357
+ }
2358
+ }, reject);
2359
+ }
1880
2360
  });
1881
2361
  });
1882
2362
  };
2363
+ const onSubmit = (values) => {
2364
+ if (typeof reduceOnly === "boolean" && reduceOnly && !values.reduce_only) {
2365
+ return Promise.reject(
2366
+ new types.SDKError(
2367
+ "The reduceOny parameter of hook does not match your order data"
2368
+ )
2369
+ );
2370
+ }
2371
+ return createOrder({
2372
+ ...values,
2373
+ symbol
2374
+ });
2375
+ };
2376
+ const submit = React.useCallback(() => {
2377
+ if (typeof symbolOrOrder === "string") {
2378
+ throw new types.SDKError("Function is not supported, please use onSubmit()");
2379
+ }
2380
+ return createOrder(symbolOrOrder);
2381
+ }, [symbolOrOrder]);
1883
2382
  const calculate = React.useCallback(
1884
2383
  (values, field, value) => {
1885
2384
  const fieldHandler = getCalculateHandler(field);
@@ -1902,75 +2401,407 @@ var useOrderEntry = (symbol, side, reduceOnly = false, options) => {
1902
2401
  markPrice
1903
2402
  });
1904
2403
  };
2404
+ const formattedOrder = React.useMemo(() => {
2405
+ if (!parsedData) {
2406
+ return notSupportData.current;
2407
+ }
2408
+ if (!prevOrderData.current) {
2409
+ prevOrderData.current = parsedData;
2410
+ orderDataCache.current = {
2411
+ ...parsedData,
2412
+ total: ""
2413
+ };
2414
+ return orderDataCache.current;
2415
+ }
2416
+ const item = diffOrderEntry(prevOrderData.current, parsedData);
2417
+ if (!item) {
2418
+ return orderDataCache.current;
2419
+ }
2420
+ if (typeof parsedData.order_price !== "undefined") {
2421
+ fieldDirty.current.order_price = true;
2422
+ }
2423
+ if (typeof parsedData.order_quantity !== "undefined") {
2424
+ fieldDirty.current.order_quantity = true;
2425
+ }
2426
+ const values = calculate(parsedData, item.key, item.value);
2427
+ values.isStopOrder = values.order_type?.startsWith("STOP") || false;
2428
+ values.total = values.total || "";
2429
+ prevOrderData.current = parsedData;
2430
+ orderDataCache.current = values;
2431
+ return values;
2432
+ }, [
2433
+ parsedData?.order_price,
2434
+ parsedData?.side,
2435
+ parsedData?.order_quantity,
2436
+ parsedData?.visible_quantity,
2437
+ parsedData?.order_type,
2438
+ parsedData?.order_type_ext,
2439
+ parsedData?.symbol,
2440
+ parsedData?.total,
2441
+ parsedData?.reduce_only,
2442
+ parsedData?.trigger_price,
2443
+ markPrice
2444
+ ]);
2445
+ React.useEffect(() => {
2446
+ if (!markPrice)
2447
+ return;
2448
+ validator(formattedOrder)?.then((err) => {
2449
+ setErrors(err);
2450
+ });
2451
+ }, [
2452
+ formattedOrder.broker_id,
2453
+ formattedOrder.order_quantity,
2454
+ formattedOrder.total,
2455
+ formattedOrder.trigger_price,
2456
+ markPrice
2457
+ ]);
2458
+ React.useEffect(() => {
2459
+ if (!optionsValue?.watchOrderbook)
2460
+ return;
2461
+ ee.on("orderbook:update", onOrderbookUpdate);
2462
+ return () => {
2463
+ ee.off("orderbook_update", onOrderbookUpdate);
2464
+ };
2465
+ }, [optionsValue?.watchOrderbook]);
2466
+ React.useEffect(() => {
2467
+ askAndBid.current = [];
2468
+ }, [parsedData?.symbol]);
2469
+ const getPriceAndQty = (symbolOrOrder2) => {
2470
+ let quantity = Number(symbolOrOrder2.order_quantity);
2471
+ const orderPrice = Number(symbolOrOrder2.order_price);
2472
+ if (isNaN(quantity) || quantity <= 0 || askAndBid.current.length === 0)
2473
+ return null;
2474
+ if ((symbolOrOrder2.order_type === types.OrderType.LIMIT || symbolOrOrder2.order_type === types.OrderType.STOP_LIMIT) && isNaN(orderPrice))
2475
+ return null;
2476
+ let price;
2477
+ if (symbolOrOrder2.order_type === types.OrderType.MARKET || symbolOrOrder2.order_type === types.OrderType.STOP_MARKET) {
2478
+ if (symbolOrOrder2.side === types.OrderSide.BUY) {
2479
+ price = askAndBid.current[0];
2480
+ } else {
2481
+ price = askAndBid.current[1];
2482
+ }
2483
+ } else {
2484
+ if (symbolOrOrder2.side === types.OrderSide.BUY) {
2485
+ if (orderPrice >= askAndBid.current[0]) {
2486
+ price = askAndBid.current[0];
2487
+ } else {
2488
+ price = orderPrice;
2489
+ }
2490
+ } else {
2491
+ if (orderPrice <= askAndBid.current[1]) {
2492
+ price = askAndBid.current[1];
2493
+ } else {
2494
+ price = orderPrice;
2495
+ }
2496
+ }
2497
+ }
2498
+ if (symbolOrOrder2.side === types.OrderSide.SELL) {
2499
+ quantity = -quantity;
2500
+ }
2501
+ return { price, quantity };
2502
+ };
2503
+ const estLiqPrice = React.useMemo(() => {
2504
+ if (!accountInfo || !parsedData || !markPrice)
2505
+ return null;
2506
+ const result = getPriceAndQty(formattedOrder);
2507
+ if (result === null)
2508
+ return null;
2509
+ const { price, quantity } = result;
2510
+ if (!price || !quantity)
2511
+ return null;
2512
+ const liqPrice = perp.order.estLiqPrice({
2513
+ markPrice,
2514
+ baseIMR,
2515
+ baseMMR,
2516
+ totalCollateral,
2517
+ positions: positions3,
2518
+ IMR_Factor: accountInfo["imr_factor"][symbol],
2519
+ newOrder: {
2520
+ qty: quantity,
2521
+ price,
2522
+ symbol: parsedData.symbol
2523
+ }
2524
+ });
2525
+ if (liqPrice <= 0)
2526
+ return null;
2527
+ return liqPrice;
2528
+ }, [
2529
+ markPrice,
2530
+ baseIMR,
2531
+ baseMMR,
2532
+ totalCollateral,
2533
+ formattedOrder?.order_price,
2534
+ formattedOrder?.order_quantity,
2535
+ formattedOrder?.total,
2536
+ formattedOrder?.trigger_price,
2537
+ accountInfo
2538
+ ]);
2539
+ const estLeverage = React.useMemo(() => {
2540
+ if (!accountInfo || !parsedData)
2541
+ return null;
2542
+ const result = getPriceAndQty(formattedOrder);
2543
+ if (result === null || !result.price || !result.quantity)
2544
+ return null;
2545
+ const leverage = perp.order.estLeverage({
2546
+ totalCollateral,
2547
+ positions: positions3,
2548
+ newOrder: {
2549
+ symbol: parsedData.symbol,
2550
+ qty: result.quantity,
2551
+ price: result.price
2552
+ }
2553
+ });
2554
+ return leverage;
2555
+ }, [
2556
+ baseIMR,
2557
+ baseMMR,
2558
+ totalCollateral,
2559
+ positions3,
2560
+ formattedOrder?.order_price,
2561
+ formattedOrder?.order_quantity,
2562
+ formattedOrder?.total,
2563
+ formattedOrder?.trigger_price
2564
+ ]);
1905
2565
  return {
1906
2566
  maxQty,
1907
2567
  freeCollateral,
1908
2568
  markPrice,
1909
2569
  onSubmit,
2570
+ submit,
1910
2571
  submitting: isMutating,
2572
+ formattedOrder,
2573
+ // errors,
2574
+ estLiqPrice,
2575
+ estLeverage,
1911
2576
  helper: {
1912
2577
  calculate,
1913
2578
  validator
2579
+ // clearErrors,
2580
+ },
2581
+ metaState: {
2582
+ dirty: fieldDirty.current,
2583
+ submitted: submitted.current,
2584
+ errors
1914
2585
  },
1915
2586
  symbolConfig: symbolInfo[symbol]()
1916
2587
  };
1917
- };
2588
+ }
1918
2589
 
1919
2590
  // src/orderly/useAccountInfo.ts
1920
2591
  var useAccountInfo = () => {
1921
2592
  return usePrivateQuery("/v1/client/info");
1922
2593
  };
1923
- var useMarketsStream = () => {
1924
- const ws = useWS();
1925
- const { data: futures } = useQuery(`/v1/public/futures`, {
1926
- revalidateOnFocus: false
1927
- });
1928
- const { data: tickers } = useSWRSubscription__default.default("tickers", (_, { next }) => {
1929
- const unsubscribe = ws.subscribe(
1930
- // { event: "subscribe", topic: "markprices" },
1931
- "tickers",
1932
- {
1933
- onMessage: (message) => {
1934
- next(null, message);
1935
- }
1936
- // onUnsubscribe: () => {
1937
- // return "markprices";
1938
- // },
1939
- // onError: (error: any) => {
1940
- //
1941
- // },
2594
+ var MarketsType = /* @__PURE__ */ ((MarketsType2) => {
2595
+ MarketsType2[MarketsType2["FAVORITES"] = 0] = "FAVORITES";
2596
+ MarketsType2[MarketsType2["RECENT"] = 1] = "RECENT";
2597
+ MarketsType2[MarketsType2["ALL"] = 2] = "ALL";
2598
+ return MarketsType2;
2599
+ })(MarketsType || {});
2600
+ var useMarkets = (type) => {
2601
+ const marketsKey = "markets";
2602
+ const { data } = useMarketsStream();
2603
+ const { configStore } = React.useContext(OrderlyContext);
2604
+ const publicInfo = useSymbolsInfo();
2605
+ if (!configStore.get(marketsKey)) {
2606
+ const jsonStr = localStorage.getItem(marketsKey);
2607
+ if (jsonStr) {
2608
+ configStore.set(marketsKey, JSON.parse(jsonStr));
2609
+ } else {
2610
+ const defaultTab = { name: "Popular", id: 1 };
2611
+ configStore.set(marketsKey, {
2612
+ recent: [],
2613
+ favorites: [
2614
+ { name: "PERP_ETH_USDC", tabs: [{ ...defaultTab }] },
2615
+ { name: "PERP_BTC_USDC", tabs: [{ ...defaultTab }] }
2616
+ ],
2617
+ favoriteTabs: [{ ...defaultTab }],
2618
+ lastSelectFavoriteTab: { ...defaultTab }
2619
+ });
2620
+ }
2621
+ }
2622
+ const getFavoriteTabs = React.useMemo(() => {
2623
+ const tabs2 = configStore.get(marketsKey)["favoriteTabs"];
2624
+ return tabs2 || [{ name: "Popular", id: 1 }];
2625
+ }, []);
2626
+ const getFavorites = React.useMemo(() => {
2627
+ const curData = configStore.get(marketsKey)["favorites"] || [];
2628
+ const tabs2 = getFavoriteTabs;
2629
+ const result = [];
2630
+ for (let index = 0; index < curData.length; index++) {
2631
+ const favData = curData[index];
2632
+ var favTabs = favData.tabs.filter((tab) => tabs2.findIndex((item) => tab.id === item.id) !== -1);
2633
+ if (favTabs.length > 0) {
2634
+ result.push({ ...favData, tabs: favTabs });
1942
2635
  }
1943
- );
1944
- return () => {
1945
- unsubscribe?.();
2636
+ }
2637
+ configStore.set(marketsKey, { ...configStore.getOr(marketsKey, {}), favorites: result });
2638
+ return result;
2639
+ }, [configStore]);
2640
+ const getRecent = React.useMemo(() => {
2641
+ const curData = configStore.get(marketsKey)["recent"];
2642
+ return (curData || []).filter((e) => e);
2643
+ }, []);
2644
+ const [favoriteTabs, setFavoriteTabs] = React.useState(getFavoriteTabs);
2645
+ const [favorites, setFavorites] = React.useState(getFavorites);
2646
+ const [recent, setRecent] = React.useState(getRecent);
2647
+ const updateFavoriteTabs = (tab, operator) => {
2648
+ const saveTabs = (tabs3) => {
2649
+ setFavoriteTabs(tabs3);
2650
+ configStore.set(marketsKey, {
2651
+ ...configStore.getOr(marketsKey, {}),
2652
+ "favoriteTabs": tabs3
2653
+ });
1946
2654
  };
1947
- });
1948
- const value = React.useMemo(() => {
1949
- if (!futures)
1950
- return null;
1951
- if (!tickers)
1952
- return futures;
1953
- return futures.map((item) => {
1954
- const ticker = tickers.find(
1955
- (t) => t.symbol === item.symbol
1956
- );
1957
- if (ticker) {
1958
- const data = {
1959
- ...item,
1960
- ["24h_close"]: ticker.close,
1961
- ["24h_open"]: ticker.open,
1962
- ["24h_volumn"]: ticker.volume,
1963
- change: 0
1964
- };
1965
- if (ticker.close !== void 0 && ticker.open !== void 0) {
1966
- data["change"] = new utils.Decimal(ticker.close).minus(ticker.open).div(ticker.open).toNumber();
2655
+ if (Array.isArray(tab)) {
2656
+ saveTabs(tab);
2657
+ return;
2658
+ }
2659
+ var tabs2 = [...favoriteTabs];
2660
+ const index = tabs2.findIndex((item) => item.id === tab.id);
2661
+ if (operator?.add) {
2662
+ tabs2.push(tab);
2663
+ } else if (operator?.update) {
2664
+ if (index !== -1) {
2665
+ tabs2[index] = tab;
2666
+ }
2667
+ } else if (operator?.delete) {
2668
+ if (index !== -1) {
2669
+ tabs2.splice(index, 1);
2670
+ }
2671
+ }
2672
+ saveTabs(tabs2);
2673
+ };
2674
+ const setRecentData = (symbol) => {
2675
+ const curData = [...recent];
2676
+ const index = curData.findIndex((item) => item.name == symbol.symbol);
2677
+ if (index !== -1) {
2678
+ curData.splice(index, 1);
2679
+ }
2680
+ curData.unshift({ name: symbol.symbol });
2681
+ configStore.set(marketsKey, {
2682
+ ...configStore.getOr(marketsKey, {}),
2683
+ "recent": curData
2684
+ });
2685
+ setRecent(curData);
2686
+ };
2687
+ const setFavoritesData = (symbol, tab, remove = false) => {
2688
+ const curData = [...favorites];
2689
+ const index = curData.findIndex((item) => item.name == symbol.symbol);
2690
+ if (index === -1) {
2691
+ if (Array.isArray(tab)) {
2692
+ if (tab.length > 0) {
2693
+ curData.unshift({ name: symbol.symbol, tabs: tab });
2694
+ }
2695
+ } else {
2696
+ if (!remove) {
2697
+ curData.unshift({ name: symbol.symbol, tabs: [tab] });
1967
2698
  }
1968
- return data;
1969
2699
  }
1970
- return item;
2700
+ } else {
2701
+ const favorite = curData[index];
2702
+ if (Array.isArray(tab)) {
2703
+ if (tab.length === 0) {
2704
+ curData.splice(index, 1);
2705
+ } else {
2706
+ curData[index] = { ...favorite, tabs: tab };
2707
+ }
2708
+ } else {
2709
+ if (remove) {
2710
+ const tabs2 = favorite.tabs.filter((tab2) => tab2.id != tab2.id);
2711
+ if (tabs2.length === 0) {
2712
+ curData.splice(index, 1);
2713
+ } else {
2714
+ curData[index] = { ...favorite, tabs: tabs2 };
2715
+ }
2716
+ } else {
2717
+ const tabs2 = favorite.tabs;
2718
+ tabs2.push(tab);
2719
+ curData[index] = { ...favorite, tabs: tabs2 };
2720
+ }
2721
+ }
2722
+ }
2723
+ configStore.set(marketsKey, {
2724
+ ...configStore.getOr(marketsKey, {}),
2725
+ "favorites": curData
1971
2726
  });
1972
- }, [futures, tickers]);
1973
- return { data: value };
2727
+ setFavorites(() => curData);
2728
+ };
2729
+ const getData = (type2) => {
2730
+ const localData = type2 === 0 /* FAVORITES */ ? [...favorites] : [...recent];
2731
+ const keys = localData.map((item) => item.name);
2732
+ const filter = type2 == 2 /* ALL */ ? data : data?.filter((item) => keys.includes(item.symbol));
2733
+ const favoritesData = [...favorites];
2734
+ const favoriteKeys = favoritesData.map((item) => item.name);
2735
+ if (filter) {
2736
+ for (let index = 0; index < filter.length; index++) {
2737
+ const element = filter[index];
2738
+ const isFavorite = type2 == 0 /* FAVORITES */ ? true : favoriteKeys.includes(element.symbol);
2739
+ const fIndex = favoritesData.findIndex((item) => item.name === element.symbol);
2740
+ const tabs2 = fIndex === -1 ? [] : favoritesData[fIndex].tabs;
2741
+ let imr = void 0;
2742
+ if (publicInfo) {
2743
+ imr = publicInfo?.[element.symbol]("base_imr");
2744
+ }
2745
+ filter[index] = {
2746
+ ...filter[index],
2747
+ // @ts-ignore
2748
+ isFavorite,
2749
+ tabs: tabs2,
2750
+ leverage: imr ? 1 / imr : void 0
2751
+ };
2752
+ }
2753
+ }
2754
+ return filter;
2755
+ };
2756
+ const addToHistory = (symbol) => {
2757
+ setRecentData(symbol);
2758
+ };
2759
+ const updateSymbolFavoriteState = (symbol, tab, del = false) => {
2760
+ setFavoritesData(symbol, tab, del);
2761
+ };
2762
+ const markets = getData(type);
2763
+ const pinToTop = (symbol) => {
2764
+ const index = favorites.findIndex((item) => item.name === symbol.symbol);
2765
+ if (index !== -1) {
2766
+ const element = favorites[index];
2767
+ const list = [...favorites];
2768
+ list.splice(index, 1);
2769
+ list.unshift(element);
2770
+ configStore.set(marketsKey, {
2771
+ ...configStore.getOr(marketsKey, {}),
2772
+ "favorites": list
2773
+ });
2774
+ setFavorites(list);
2775
+ }
2776
+ };
2777
+ const tabs = React.useMemo(() => {
2778
+ return favoriteTabs;
2779
+ }, [favoriteTabs]);
2780
+ const getLastSelFavTab = () => {
2781
+ const curData = configStore.get(marketsKey)["lastSelectedFavoriteTab"];
2782
+ return curData || { name: "Popular", id: 1 };
2783
+ };
2784
+ const updateSelectedFavoriteTab = (tab) => {
2785
+ configStore.set(marketsKey, {
2786
+ ...configStore.getOr(marketsKey, {}),
2787
+ lastSelectedFavoriteTab: tab
2788
+ });
2789
+ };
2790
+ return [
2791
+ markets || [],
2792
+ {
2793
+ favoriteTabs: tabs,
2794
+ favorites,
2795
+ recent,
2796
+ addToHistory,
2797
+ // updateFavoriteTabs("tab", operator: {add/update/delete})
2798
+ updateFavoriteTabs,
2799
+ updateSymbolFavoriteState,
2800
+ pinToTop,
2801
+ getLastSelFavTab,
2802
+ updateSelectedFavoriteTab
2803
+ }
2804
+ ];
1974
2805
  };
1975
2806
  var useLeverage = () => {
1976
2807
  const { data, mutate: mutate2 } = usePrivateQuery("/v1/client/info");
@@ -2091,7 +2922,7 @@ var useMarketTradeStream = (symbol, options = {}) => {
2091
2922
  return { data: trades, isLoading };
2092
2923
  };
2093
2924
  var useMarginRatio = () => {
2094
- const [{ rows }] = usePositionStream();
2925
+ const [{ rows, aggregated }] = usePositionStream();
2095
2926
  const { data: markPrices } = useMarkPricesStream();
2096
2927
  const { totalCollateral } = useCollateral();
2097
2928
  const marginRatio = React.useMemo(() => {
@@ -2108,7 +2939,20 @@ var useMarginRatio = () => {
2108
2939
  const currentLeverage = React.useMemo(() => {
2109
2940
  return perp.account.currentLeverage(marginRatio);
2110
2941
  }, [marginRatio]);
2111
- return { marginRatio, currentLeverage };
2942
+ const mmr = React.useMemo(() => {
2943
+ if (!rows || rows.length <= 0)
2944
+ return null;
2945
+ let positionsMM = utils.zero;
2946
+ for (let index = 0; index < rows.length; index++) {
2947
+ const item = rows[index];
2948
+ positionsMM = positionsMM.add(item.mm);
2949
+ }
2950
+ return perp.account.MMR({
2951
+ positionsMMR: positionsMM.toNumber(),
2952
+ positionsNotional: aggregated.notional
2953
+ });
2954
+ }, [rows, aggregated]);
2955
+ return { marginRatio, currentLeverage, mmr };
2112
2956
  };
2113
2957
 
2114
2958
  // src/woo/constants.ts
@@ -3124,53 +3968,41 @@ var woofiDexCrossChainRouterAbi = [
3124
3968
  ];
3125
3969
  var nativeTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
3126
3970
  var isNativeTokenChecker = (address) => address === nativeTokenAddress;
3127
-
3128
- // src/orderly/useChains.ts
3129
3971
  var useChains = (networkId, options = {}) => {
3130
- const { filter, pick: pick3, crossEnabled, wooSwapEnabled, ...swrOptions } = options;
3131
- const { configStore, networkId: networkEnv } = React.useContext(OrderlyContext);
3972
+ const { pick: pick3, crossEnabled, wooSwapEnabled, ...swrOptions } = options;
3973
+ const { configStore } = React.useContext(OrderlyContext);
3132
3974
  const field = options?.pick;
3975
+ const filterFun = React.useRef(options?.filter);
3976
+ filterFun.current = options?.filter;
3133
3977
  const map = React.useRef(
3134
3978
  /* @__PURE__ */ new Map()
3135
3979
  );
3136
- const { data, error: swapSupportError } = useSWR__default.default(
3980
+ const commonSwrOpts = {
3981
+ revalidateIfStale: false,
3982
+ revalidateOnFocus: false,
3983
+ revalidateOnReconnect: false,
3984
+ // If false, undefined data gets cached against the key.
3985
+ revalidateOnMount: true,
3986
+ // dont duplicate a request w/ same key for 1hr
3987
+ dedupingInterval: 36e5,
3988
+ ...swrOptions
3989
+ };
3990
+ const { data: wooSupportData, error: swapSupportError } = useSWR__default.default(
3137
3991
  () => wooSwapEnabled ? `${configStore.get("swapSupportApiUrl")}/swap_support` : null,
3138
- // `${configStore.get("swapSupportApiUrl")}/swap_support`,
3139
3992
  (url) => fetch(url).then((res) => res.json()),
3140
- {
3141
- revalidateIfStale: false,
3142
- revalidateOnFocus: false,
3143
- revalidateOnReconnect: false,
3144
- revalidateOnMount: true,
3145
- // If false, undefined data gets cached against the key.
3146
- dedupingInterval: 36e5,
3147
- // dont duplicate a request w/ same key for 1hr
3148
- ...swrOptions
3149
- }
3993
+ { ...commonSwrOpts, ...swrOptions }
3150
3994
  );
3151
3995
  const { data: chainInfos, error: chainInfoErr } = useQuery(
3152
3996
  "/v1/public/chain_info",
3153
3997
  {
3154
- revalidateIfStale: false,
3155
- revalidateOnFocus: false,
3156
- revalidateOnReconnect: false,
3157
- revalidateOnMount: true,
3158
- dedupingInterval: 36e5,
3159
- formatter: (data2) => data2.rows
3998
+ ...commonSwrOpts,
3999
+ formatter: (data) => data.rows
3160
4000
  }
3161
4001
  );
3162
4002
  const { data: orderlyChains, error: tokenError } = useQuery(
3163
- // wooSwapEnabled ? "/v1/public/token" :
3164
4003
  "https://api-evm.orderly.org/v1/public/token",
3165
- {
3166
- revalidateIfStale: false,
3167
- revalidateOnFocus: false,
3168
- revalidateOnReconnect: false,
3169
- revalidateOnMount: true,
3170
- dedupingInterval: 36e5
3171
- }
4004
+ { ...commonSwrOpts }
3172
4005
  );
3173
- configStore.get("apiBaseUrl");
3174
4006
  const chains = React.useMemo(() => {
3175
4007
  let orderlyChainsArr = [];
3176
4008
  const orderlyChainIds = /* @__PURE__ */ new Set();
@@ -3185,6 +4017,7 @@ var useChains = (networkId, options = {}) => {
3185
4017
  // "public_rpc_url": "https://arb1.arbitrum.io/rpc",
3186
4018
  chain_id: chainId,
3187
4019
  withdrawal_fee: chain.withdrawal_fee,
4020
+ cross_chain_withdrawal_fee: chain.cross_chain_withdrawal_fee,
3188
4021
  bridgeless: true
3189
4022
  },
3190
4023
  token_infos: [
@@ -3195,13 +4028,13 @@ var useChains = (networkId, options = {}) => {
3195
4028
  }
3196
4029
  ]
3197
4030
  };
3198
- if (typeof options?.filter === "function") {
3199
- if (!options.filter(_chain))
4031
+ if (typeof filterFun.current === "function") {
4032
+ if (!filterFun.current(_chain))
3200
4033
  return;
3201
4034
  }
3202
- if (_chain.chain_id === 421613) {
3203
- const index = testnetArr.findIndex(
3204
- (item2) => item2.network_infos.chain_id === 421613
4035
+ if (utils.isTestnet(_chain.chain_id)) {
4036
+ const index = testnetArr?.findIndex(
4037
+ (item2) => utils.isTestnet(item2.network_infos.chain_id)
3205
4038
  );
3206
4039
  if (index > -1) {
3207
4040
  testnetArr[index] = _chain;
@@ -3211,59 +4044,16 @@ var useChains = (networkId, options = {}) => {
3211
4044
  orderlyChainsArr.push(_chain);
3212
4045
  });
3213
4046
  });
3214
- let testnetArr = [
3215
- //@ts-ignore
3216
- {
3217
- network_infos: {
3218
- name: "Arbitrum Goerli",
3219
- shortName: "Arbitrum Goerli",
3220
- public_rpc_url: "https://goerli-rollup.arbitrum.io/rpc",
3221
- chain_id: 421613,
3222
- currency_symbol: "ETH",
3223
- bridge_enable: true,
3224
- mainnet: false,
3225
- explorer_base_url: "https://goerli.arbiscan.io/",
3226
- est_txn_mins: null,
3227
- woofi_dex_cross_chain_router: "",
3228
- woofi_dex_depositor: ""
3229
- },
3230
- token_infos: [
3231
- {
3232
- symbol: "USDC",
3233
- address: "0xfd064A18f3BF249cf1f87FC203E90D8f650f2d63",
3234
- decimals: 6,
3235
- swap_enable: false,
3236
- woofi_dex_precision: 2
3237
- }
3238
- ]
3239
- }
3240
- ];
3241
- if (networkEnv === "testnet") {
3242
- const opGoerli = {
3243
- network_infos: {
3244
- name: "Optimism Goerli",
3245
- shortName: "Optimism Goerli",
3246
- public_rpc_url: "https://optimism-goerli.gateway.tenderly.co",
3247
- chain_id: 420,
3248
- currency_symbol: "ETH",
3249
- bridge_enable: true,
3250
- mainnet: false,
3251
- explorer_base_url: "https://goerli-optimism.etherscan.io",
3252
- est_txn_mins: null,
3253
- woofi_dex_cross_chain_router: "",
3254
- woofi_dex_depositor: ""
3255
- }
3256
- };
3257
- testnetArr.push(opGoerli);
3258
- map.current.set(420, opGoerli);
3259
- }
4047
+ let testnetArr = [...types.TestnetChains];
4048
+ testnetArr.forEach((chain) => {
4049
+ map.current.set(chain.network_infos?.chain_id, chain);
4050
+ });
3260
4051
  let mainnetArr = [];
3261
- map.current.set(421613, testnetArr[0]);
3262
4052
  if (wooSwapEnabled) {
3263
- if (!data || !data.data)
3264
- return data;
3265
- Object.keys(data.data).forEach((key) => {
3266
- const chain = data.data[key];
4053
+ if (!wooSupportData || !wooSupportData.data)
4054
+ return wooSupportData;
4055
+ Object.keys(wooSupportData.data).forEach((key) => {
4056
+ const chain = wooSupportData.data[key];
3267
4057
  const item = ramda.mergeDeepRight(chain, {
3268
4058
  name: key,
3269
4059
  network_infos: {
@@ -3277,8 +4067,8 @@ var useChains = (networkId, options = {}) => {
3277
4067
  if (item.token_infos?.length === 0)
3278
4068
  return;
3279
4069
  map.current.set(item.network_infos.chain_id, item);
3280
- if (typeof options?.filter === "function") {
3281
- if (!options.filter(item))
4070
+ if (typeof filterFun.current === "function") {
4071
+ if (!filterFun.current(item))
3282
4072
  return;
3283
4073
  }
3284
4074
  if (item.network_infos.mainnet) {
@@ -3316,24 +4106,16 @@ var useChains = (networkId, options = {}) => {
3316
4106
  };
3317
4107
  }
3318
4108
  map.current.set(_chain.network_infos.chain_id, _chain);
3319
- if (_chain.network_infos.chain_id === 421613) {
3320
- const index = testnetArr.findIndex(
3321
- (item) => item.network_infos.chain_id === 421613
3322
- );
3323
- if (index > -1) {
3324
- testnetArr[index] = _chain;
3325
- }
3326
- }
3327
- if (_chain.network_infos.chain_id === 420) {
4109
+ if (utils.isTestnet(_chain.network_infos.chain_id)) {
3328
4110
  const index = testnetArr.findIndex(
3329
- (item) => item.network_infos.chain_id === 420
4111
+ (item) => utils.isTestnet(item.network_infos.chain_id)
3330
4112
  );
3331
4113
  if (index > -1) {
3332
4114
  testnetArr[index] = _chain;
3333
4115
  }
3334
4116
  }
3335
- if (typeof options?.filter === "function") {
3336
- if (!options.filter(_chain))
4117
+ if (typeof filterFun.current === "function") {
4118
+ if (!filterFun.current(_chain))
3337
4119
  return;
3338
4120
  }
3339
4121
  mainnetArr.push(_chain);
@@ -3360,10 +4142,9 @@ var useChains = (networkId, options = {}) => {
3360
4142
  mainnet: mainnetArr
3361
4143
  };
3362
4144
  }, [
3363
- data,
4145
+ wooSupportData,
3364
4146
  networkId,
3365
4147
  field,
3366
- options,
3367
4148
  orderlyChains,
3368
4149
  wooSwapEnabled,
3369
4150
  chainInfos
@@ -3430,7 +4211,21 @@ var useWithdraw = () => {
3430
4211
  const maxAmount = React.useMemo(() => {
3431
4212
  return freeCollateral;
3432
4213
  }, [freeCollateral]);
3433
- return { withdraw, isLoading, maxAmount, availableBalance, unsettledPnL };
4214
+ const availableWithdraw = React.useMemo(() => {
4215
+ if (unsettledPnL < 0) {
4216
+ return freeCollateral;
4217
+ } else {
4218
+ return freeCollateral - unsettledPnL;
4219
+ }
4220
+ }, [freeCollateral, unsettledPnL]);
4221
+ return {
4222
+ withdraw,
4223
+ isLoading,
4224
+ maxAmount,
4225
+ availableBalance,
4226
+ availableWithdraw,
4227
+ unsettledPnL
4228
+ };
3434
4229
  };
3435
4230
  var useDeposit = (options) => {
3436
4231
  const { enableSwapDeposit } = React.useContext(OrderlyContext);
@@ -3440,12 +4235,15 @@ var useDeposit = (options) => {
3440
4235
  const [_, { findByChainId }] = useChains(void 0, {
3441
4236
  wooSwapEnabled: enableSwapDeposit
3442
4237
  });
4238
+ const [quantity, setQuantity] = React.useState("");
4239
+ const [depositFee, setDepositFee] = React.useState(0n);
4240
+ const [depositFeeRevalidating, setDepositFeeRevalidating] = React.useState(false);
3443
4241
  const [balance, setBalance] = React.useState("0");
3444
4242
  const [allowance, setAllowance] = React.useState("0");
3445
4243
  const { account: account5, state } = useAccount();
3446
4244
  const prevAddress = React.useRef();
3447
4245
  const getBalanceListener = React.useRef();
3448
- const dst = React.useMemo(() => {
4246
+ const targetChain = React.useMemo(() => {
3449
4247
  let chain;
3450
4248
  if (networkId === "testnet") {
3451
4249
  chain = findByChainId(types.ARBITRUM_TESTNET_CHAINID);
@@ -3455,21 +4253,23 @@ var useDeposit = (options) => {
3455
4253
  chain = findByChainId(types.ARBITRUM_MAINNET_CHAINID);
3456
4254
  }
3457
4255
  }
3458
- const USDC = chain?.token_infos.find(
3459
- (token) => token.symbol === "USDC"
3460
- );
3461
- if (!chain) {
4256
+ return chain;
4257
+ }, [networkId, findByChainId, options?.srcChainId]);
4258
+ const dst = React.useMemo(() => {
4259
+ if (!targetChain) {
3462
4260
  throw new Error("dst chain not found");
3463
4261
  }
4262
+ const USDC = targetChain?.token_infos.find(
4263
+ (token) => token.symbol === "USDC"
4264
+ );
3464
4265
  return {
3465
4266
  symbol: "USDC",
3466
4267
  address: USDC?.address,
3467
4268
  decimals: USDC?.decimals,
3468
- chainId: chain.network_infos.chain_id,
3469
- network: chain.network_infos.shortName
3470
- // chainId: 42161,
4269
+ chainId: targetChain.network_infos.chain_id,
4270
+ network: targetChain.network_infos.shortName
3471
4271
  };
3472
- }, [networkId, findByChainId, options?.srcChainId]);
4272
+ }, [targetChain]);
3473
4273
  const isNativeToken = React.useMemo(
3474
4274
  () => isNativeTokenChecker(options?.address || ""),
3475
4275
  [options?.address]
@@ -3496,7 +4296,6 @@ var useDeposit = (options) => {
3496
4296
  const balance2 = await fetchBalanceHandler(address, decimals);
3497
4297
  setBalance(() => balance2);
3498
4298
  } catch (e) {
3499
- console.warn("----- refresh balance error -----", e);
3500
4299
  setBalance(() => "0");
3501
4300
  }
3502
4301
  },
@@ -3546,18 +4345,30 @@ var useDeposit = (options) => {
3546
4345
  }
3547
4346
  }
3548
4347
  }, [options, dst]);
4348
+ const queryBalance = useDebounce.useDebouncedCallback(
4349
+ (tokenAddress, decimals) => {
4350
+ fetchBalance(options?.address, options?.decimals).finally(() => {
4351
+ setBalanceRevalidating(false);
4352
+ });
4353
+ },
4354
+ 100
4355
+ );
4356
+ const queryAllowance = useDebounce.useDebouncedCallback(
4357
+ (tokenAddress, vaultAddress) => {
4358
+ getAllowance(tokenAddress, vaultAddress);
4359
+ },
4360
+ 100
4361
+ );
3549
4362
  React.useEffect(() => {
3550
4363
  if (state.status < types.AccountStatusEnum.Connected)
3551
4364
  return;
3552
4365
  setBalanceRevalidating(true);
3553
- fetchBalance(options?.address, options?.decimals).finally(() => {
3554
- setBalanceRevalidating(false);
3555
- });
4366
+ queryBalance(options?.address, options?.decimals);
3556
4367
  if (dst.chainId !== options?.srcChainId) {
3557
- getAllowance(options?.address, options?.crossChainRouteAddress);
4368
+ queryAllowance(options?.address, options?.crossChainRouteAddress);
3558
4369
  } else {
3559
4370
  if (dst.symbol !== options?.srcToken) {
3560
- getAllowance(options?.address, options?.depositorAddress);
4371
+ queryAllowance(options?.address, options?.depositorAddress);
3561
4372
  } else {
3562
4373
  getAllowanceByDefaultAddress(options?.address);
3563
4374
  }
@@ -3574,47 +4385,72 @@ var useDeposit = (options) => {
3574
4385
  dst.symbol
3575
4386
  ]);
3576
4387
  const approve = React.useCallback(
3577
- (amount) => {
4388
+ async (amount) => {
3578
4389
  if (!options?.address) {
3579
4390
  throw new Error("address is required");
3580
4391
  }
3581
4392
  const vaultAddress = getVaultAddress();
3582
4393
  return account5.assetsManager.approve(options.address, amount, vaultAddress).then((result) => {
3583
4394
  if (typeof amount !== "undefined") {
3584
- setAllowance((value) => new utils.Decimal(value).add(amount).toString());
4395
+ setAllowance(
4396
+ (value) => new utils.Decimal(value).add(amount || types.MaxUint256.toString()).toString()
4397
+ );
3585
4398
  }
3586
4399
  return result;
3587
4400
  });
3588
4401
  },
3589
4402
  [account5, getAllowance, options?.address]
3590
4403
  );
3591
- const getDepositFee = React.useCallback(
3592
- async (amount, chain) => {
3593
- return account5.assetsManager.getDepositFee(amount, chain);
3594
- },
3595
- [account5]
3596
- );
3597
- const deposit = React.useCallback(
3598
- (amount, fee) => {
3599
- return account5.assetsManager.deposit(amount, fee).then((res) => {
3600
- setAllowance((value) => new utils.Decimal(value).sub(amount).toString());
3601
- setBalance((value) => new utils.Decimal(value).sub(amount).toString());
3602
- return res;
3603
- });
3604
- },
3605
- [account5, fetchBalance, getAllowance]
3606
- );
4404
+ const deposit = React.useCallback(async () => {
4405
+ return account5.assetsManager.deposit(quantity, depositFee).then((res) => {
4406
+ setAllowance((value) => new utils.Decimal(value).sub(quantity).toString());
4407
+ setBalance((value) => new utils.Decimal(value).sub(quantity).toString());
4408
+ return res;
4409
+ });
4410
+ }, [account5, fetchBalance, getAllowance, quantity, depositFee]);
3607
4411
  const loopGetBalance = async () => {
3608
4412
  getBalanceListener.current && clearTimeout(getBalanceListener.current);
3609
4413
  getBalanceListener.current = setTimeout(async () => {
3610
- const balance2 = await fetchBalanceHandler(
3611
- options?.address,
3612
- options?.decimals
3613
- );
3614
- setBalance(balance2);
3615
- loopGetBalance();
4414
+ try {
4415
+ const balance2 = await fetchBalanceHandler(
4416
+ options?.address,
4417
+ options?.decimals
4418
+ );
4419
+ setBalance(balance2);
4420
+ loopGetBalance();
4421
+ } catch (err) {
4422
+ }
3616
4423
  }, 3e3);
3617
4424
  };
4425
+ const getDepositFee = React.useCallback(
4426
+ async (quantity2) => {
4427
+ return account5.assetsManager.getDepositFee(
4428
+ quantity2,
4429
+ targetChain?.network_infos
4430
+ );
4431
+ },
4432
+ [account5, targetChain]
4433
+ );
4434
+ const enquiryDepositFee = React.useCallback(() => {
4435
+ if (isNaN(Number(quantity)) || !quantity) {
4436
+ setDepositFee(0n);
4437
+ setDepositFeeRevalidating(false);
4438
+ return;
4439
+ }
4440
+ setDepositFeeRevalidating(true);
4441
+ getDepositFee(quantity).then((res = 0n) => {
4442
+ const fee = BigInt(
4443
+ new utils.Decimal(res.toString()).mul(types.DEPOSIT_FEE_RATE).toFixed(0, utils.Decimal.ROUND_UP).toString()
4444
+ );
4445
+ setDepositFee(fee);
4446
+ }).catch((error) => {
4447
+ }).finally(() => {
4448
+ setDepositFeeRevalidating(false);
4449
+ });
4450
+ }, [quantity]);
4451
+ React.useEffect(() => {
4452
+ enquiryDepositFee();
4453
+ }, [quantity]);
3618
4454
  React.useEffect(() => {
3619
4455
  if (!options?.address) {
3620
4456
  return;
@@ -3625,17 +4461,25 @@ var useDeposit = (options) => {
3625
4461
  };
3626
4462
  }, [options?.address, options?.decimals]);
3627
4463
  return {
4464
+ /** orderly support chain dst */
3628
4465
  dst,
3629
4466
  balance,
3630
4467
  allowance,
3631
4468
  isNativeToken,
3632
4469
  balanceRevalidating,
3633
4470
  allowanceRevalidating,
4471
+ /** input quantiy */
4472
+ quantity,
4473
+ /** orderly deposit fee, unit: wei */
4474
+ depositFee,
4475
+ /** enquiring depositFee status on chain */
4476
+ depositFeeRevalidating,
3634
4477
  approve,
3635
4478
  deposit,
3636
- getDepositFee,
3637
4479
  fetchBalances,
3638
- fetchBalance: fetchBalanceHandler
4480
+ fetchBalance: fetchBalanceHandler,
4481
+ /** set input quantity */
4482
+ setQuantity
3639
4483
  };
3640
4484
  };
3641
4485
  var useWalletSubscription = (options) => {
@@ -3678,6 +4522,32 @@ var useSettleSubscription = (options) => {
3678
4522
  return () => unsubscribe();
3679
4523
  });
3680
4524
  };
4525
+ var useSymbolPriceRange = (symbol, side, price) => {
4526
+ const config = useSymbolsInfo();
4527
+ const priceRange = config?.[symbol]("price_range");
4528
+ const priceScrope = config?.[symbol]("price_scope");
4529
+ const { data: prices } = useMarkPricesStream();
4530
+ const markPrice = price || prices?.[symbol];
4531
+ const range = React.useMemo(() => {
4532
+ if (config === void 0 || markPrice === void 0) {
4533
+ return void 0;
4534
+ }
4535
+ if (priceRange === void 0 || Number.isNaN(markPrice)) {
4536
+ return void 0;
4537
+ }
4538
+ if (side === "BUY") {
4539
+ return {
4540
+ max: new utils.Decimal(markPrice).mul(1 + priceRange).toNumber(),
4541
+ min: new utils.Decimal(markPrice).mul(1 - priceScrope).toNumber()
4542
+ };
4543
+ }
4544
+ return {
4545
+ max: new utils.Decimal(markPrice).mul(1 + priceScrope).toNumber(),
4546
+ min: new utils.Decimal(markPrice).mul(1 - priceRange).toNumber()
4547
+ };
4548
+ }, [symbol, side, priceRange, markPrice]);
4549
+ return range;
4550
+ };
3681
4551
  function useMediaQuery(query) {
3682
4552
  const getMatches = (query2) => {
3683
4553
  if (typeof window !== "undefined") {
@@ -4321,6 +5191,7 @@ Object.defineProperty(exports, 'useConstant', {
4321
5191
  enumerable: true,
4322
5192
  get: function () { return useConstant4__default.default; }
4323
5193
  });
5194
+ exports.MarketsType = MarketsType;
4324
5195
  exports.OrderlyConfigProvider = OrderlyConfigProvider;
4325
5196
  exports.OrderlyContext = OrderlyContext;
4326
5197
  exports.OrderlyProvider = OrderlyProvider;
@@ -4346,6 +5217,7 @@ exports.useMarginRatio = useMarginRatio;
4346
5217
  exports.useMarkPrice = useMarkPrice;
4347
5218
  exports.useMarkPricesStream = useMarkPricesStream;
4348
5219
  exports.useMarketTradeStream = useMarketTradeStream;
5220
+ exports.useMarkets = useMarkets;
4349
5221
  exports.useMarketsStream = useMarketsStream;
4350
5222
  exports.useMaxQty = useMaxQty;
4351
5223
  exports.useMediaQuery = useMediaQuery;
@@ -4362,6 +5234,7 @@ exports.useQuery = useQuery;
4362
5234
  exports.useSessionStorage = useSessionStorage;
4363
5235
  exports.useSettleSubscription = useSettleSubscription;
4364
5236
  exports.useSwap = useSwap;
5237
+ exports.useSymbolPriceRange = useSymbolPriceRange;
4365
5238
  exports.useSymbolsInfo = useSymbolsInfo;
4366
5239
  exports.useTickerStream = useTickerStream;
4367
5240
  exports.useWS = useWS;