@orderly.network/hooks 1.0.29 → 1.1.1

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.mjs CHANGED
@@ -6,23 +6,23 @@ import useSWRMutation from 'swr/mutation';
6
6
  import useConstant4 from 'use-constant';
7
7
  export { default as useConstant } from 'use-constant';
8
8
  import { SimpleDI, Account, EventEmitter, DefaultConfigStore, LocalStorageStore, EtherAdapter, utils } from '@orderly.network/core';
9
- import { AccountStatusEnum, OrderStatus, OrderSide, chainsInfoMap, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, WS_WalletStatusEnum, OrderType } from '@orderly.network/types';
9
+ import { OrderType, AccountStatusEnum, SDKError, OrderStatus, OrderSide, chainsInfoMap, TestnetChains, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, MaxUint256, DEPOSIT_FEE_RATE, WS_WalletStatusEnum } from '@orderly.network/types';
10
10
  import useSWRInfinite, { unstable_serialize } from 'swr/infinite';
11
11
  import { useDebouncedCallback } from 'use-debounce';
12
12
  export * from 'use-debounce';
13
13
  import { jsx } from 'react/jsx-runtime';
14
- import { Decimal, zero, getPrecisionByNumber, timeConvertString } from '@orderly.network/utils';
14
+ import { Decimal, zero, getPrecisionByNumber, timeConvertString, isTestnet } from '@orderly.network/utils';
15
15
  import useSWRSubscription from 'swr/subscription';
16
- import { pathOr, propOr, compose, head, prop, mergeDeepRight, pick, min } from 'ramda';
16
+ import { pathOr, propOr, compose, head, prop, mergeDeepRight, pick, includes, omit, min } from 'ramda';
17
17
  import { positions, account, order } from '@orderly.network/perp';
18
18
  import { createClient } from '@layerzerolabs/scan-client';
19
19
 
20
20
  // src/version.ts
21
21
  if (typeof window !== "undefined") {
22
22
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
23
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "1.0.29";
23
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "1.1.1";
24
24
  }
25
- var version_default = "1.0.29";
25
+ var version_default = "1.1.1";
26
26
  var fetcher = (url, init = {}, queryOptions) => get(url, init, queryOptions?.formatter);
27
27
  var OrderlyContext = createContext({
28
28
  // configStore: new MemoryConfigStore(),
@@ -193,7 +193,6 @@ var signatureMiddleware = (useSWRNext) => {
193
193
  };
194
194
  return useSWRNext(key, extendedFetcher, config);
195
195
  } catch (e) {
196
- console.error("signature error:", e);
197
196
  throw e;
198
197
  }
199
198
  };
@@ -338,23 +337,16 @@ function useSessionStorage(key, initialValue) {
338
337
  const item = window.sessionStorage.getItem(key);
339
338
  return item ? parseJSON(item) : initialValue;
340
339
  } catch (error) {
341
- console.warn(`Error reading sessionStorage key \u201C${key}\u201D:`, error);
342
340
  return initialValue;
343
341
  }
344
342
  }, [initialValue, key]);
345
343
  const [storedValue, setStoredValue] = useState(readValue);
346
344
  const setValue = (value) => {
347
- if (typeof window == "undefined") {
348
- console.warn(
349
- `Tried setting sessionStorage key \u201C${key}\u201D even though environment is not a client`
350
- );
351
- }
352
345
  try {
353
346
  const newValue = value instanceof Function ? value(storedValue) : value;
354
347
  window.sessionStorage.setItem(key, JSON.stringify(newValue));
355
348
  setStoredValue(newValue);
356
349
  } catch (error) {
357
- console.warn(`Error setting sessionStorage key \u201C${key}\u201D:`, error);
358
350
  }
359
351
  };
360
352
  useEffect(() => {
@@ -389,24 +381,18 @@ function useLocalStorage(key, initialValue) {
389
381
  const item = window.localStorage.getItem(key);
390
382
  return item ? parseJSON(item) : initialValue;
391
383
  } catch (error) {
392
- console.warn(`Error reading localStorage key \u201C${key}\u201D:`, error);
393
384
  return initialValue;
394
385
  }
395
386
  }, [initialValue, key]);
396
387
  const [storedValue, setStoredValue] = useState(readValue);
397
388
  const setValue = useCallback(
398
389
  (value) => {
399
- if (typeof window === "undefined") {
400
- console.warn(
401
- `Tried setting localStorage key \u201C${key}\u201D even though environment is not a client`
402
- );
403
- }
404
390
  try {
405
391
  const newValue = value instanceof Function ? value(storedValue) : value;
406
392
  window.localStorage.setItem(key, JSON.stringify(newValue));
393
+ window.dispatchEvent(new Event("storage"));
407
394
  setStoredValue(() => newValue);
408
395
  } catch (error) {
409
- console.warn(`Error setting localStorage key \u201C${key}\u201D:`, error);
410
396
  }
411
397
  },
412
398
  [storedValue]
@@ -414,6 +400,18 @@ function useLocalStorage(key, initialValue) {
414
400
  useEffect(() => {
415
401
  setStoredValue(readValue());
416
402
  }, []);
403
+ useEffect(() => {
404
+ const handleStorageChange = (event) => {
405
+ if (event?.key && event.key !== key) {
406
+ return;
407
+ }
408
+ setStoredValue(readValue());
409
+ };
410
+ window.addEventListener("storage", handleStorageChange);
411
+ return () => {
412
+ window.removeEventListener("storage", handleStorageChange);
413
+ };
414
+ }, [key]);
417
415
  return [storedValue, setValue];
418
416
  }
419
417
  var WS_NAME = "nativeWebsocketClient";
@@ -451,36 +449,48 @@ var useWS = () => {
451
449
  });
452
450
  return ws;
453
451
  };
454
- var usePrivateDataObserver = () => {
452
+ var usePrivateDataObserver = (options) => {
455
453
  const ws = useWS();
456
454
  const { mutate: mutate2 } = useSWRConfig();
457
455
  const ee = useEventEmitter();
458
456
  const { state } = useAccount();
459
- const updateOrders = useDebouncedCallback(() => {
460
- mutate2(
461
- unstable_serialize(() => [
462
- `/v1/orders?size=100&page=1&status=${OrderStatus.INCOMPLETE}`,
463
- state.accountId
464
- ])
465
- );
466
- mutate2(
467
- unstable_serialize(() => [
468
- `/v1/orders?size=100&page=1&status=${OrderStatus.NEW}`,
469
- state.accountId
470
- ])
471
- );
457
+ const updateOrders = useDebouncedCallback((data) => {
458
+ const map = options.getKeysMap("orders");
459
+ map.forEach((getKey, key) => {
460
+ mutate2(
461
+ unstable_serialize((index, prevData) => [
462
+ getKey(index, prevData),
463
+ state.accountId
464
+ ])
465
+ );
466
+ });
472
467
  }, 500);
473
468
  useEffect(() => {
474
469
  if (!state.accountId)
475
470
  return;
476
471
  const unsubscribe = ws.privateSubscribe("executionreport", {
477
472
  onMessage: (data) => {
478
- updateOrders();
473
+ updateOrders(data);
479
474
  ee.emit("orders:changed", data);
480
475
  }
481
476
  });
482
477
  return () => unsubscribe?.();
483
478
  }, [state.accountId]);
479
+ useEffect(() => {
480
+ if (!state.accountId)
481
+ return;
482
+ const unsubscribe = ws.privateSubscribe("algoexecutionreport", {
483
+ onMessage: (data) => {
484
+ updateOrders(data);
485
+ if (Array.isArray(data)) {
486
+ data.forEach((item) => ee.emit("orders:changed", { ...item, status: item.algoStatus }));
487
+ } else {
488
+ ee.emit("orders:changed", { ...data, status: data.algoStatus });
489
+ }
490
+ }
491
+ });
492
+ return () => unsubscribe?.();
493
+ }, [state.accountId]);
484
494
  useEffect(() => {
485
495
  if (!state.accountId)
486
496
  return;
@@ -539,15 +549,31 @@ var usePrivateDataObserver = () => {
539
549
  var DataCenterContext = createContext(
540
550
  {}
541
551
  );
552
+ var useDataCenterContext = () => useContext(DataCenterContext);
542
553
  var DataCenterProvider = ({ children }) => {
543
554
  const { error, done } = usePreLoadData();
544
- usePrivateDataObserver();
555
+ const getKeyHandlerMapRef = useRef(/* @__PURE__ */ new Map());
556
+ usePrivateDataObserver({
557
+ getKeysMap(type) {
558
+ return getKeyHandlerMapRef.current;
559
+ }
560
+ });
545
561
  if (error) {
546
562
  return /* @__PURE__ */ jsx("div", { children: "Data load failed" });
547
563
  }
548
564
  if (!done)
549
565
  return null;
550
- return /* @__PURE__ */ jsx(DataCenterContext.Provider, { value: {}, children });
566
+ return /* @__PURE__ */ jsx(
567
+ DataCenterContext.Provider,
568
+ {
569
+ value: {
570
+ regesterKeyHandler: (key, fun) => {
571
+ getKeyHandlerMapRef.current.set(key, fun);
572
+ }
573
+ },
574
+ children
575
+ }
576
+ );
551
577
  };
552
578
  var OrderlyConfigProvider = (props) => {
553
579
  const [account5, setAccount] = React.useState(null);
@@ -560,9 +586,6 @@ var OrderlyConfigProvider = (props) => {
560
586
  enableSwapDeposit,
561
587
  contracts
562
588
  } = props;
563
- if (!brokerId && typeof configStore === "undefined") {
564
- console.error("[OrderlyConfigProvider]: brokerId is required");
565
- }
566
589
  const innerConfigStore = useConstant4(() => {
567
590
  return configStore || new DefaultConfigStore({ brokerId, networkId });
568
591
  });
@@ -786,7 +809,7 @@ var reduceItems = (depth, level, data, asks = false) => {
786
809
  const result = [];
787
810
  if (typeof depth !== "undefined") {
788
811
  const prices = /* @__PURE__ */ new Map();
789
- for (let i = 0; i < data.length; i++) {
812
+ for (let i = 0; i < min(level, data.length); i++) {
790
813
  const [price, quantity] = data[i];
791
814
  if (isNaN(price) || isNaN(quantity))
792
815
  continue;
@@ -821,7 +844,8 @@ var reduceItems = (depth, level, data, asks = false) => {
821
844
  if (isNaN(price) || isNaN(quantity))
822
845
  continue;
823
846
  const newQuantity = new Decimal(quantity).add(result.length > 0 ? result[result.length - 1][2] : 0).toNumber();
824
- result.push([price, quantity, newQuantity]);
847
+ const newAmount = new Decimal(quantity * price).add(result.length > 0 ? result[result.length - 1][3] : 0).toNumber();
848
+ result.push([price, quantity, newQuantity, newAmount]);
825
849
  }
826
850
  return result;
827
851
  };
@@ -852,9 +876,11 @@ var reduceOrderbook = (depth, level, data) => {
852
876
  }
853
877
  }
854
878
  asks = asks.reverse();
879
+ asks = asks.length < level ? paddingFn(level - asks.length).concat(asks) : asks;
880
+ bids = bids.length < level ? bids.concat(paddingFn(level - bids.length)) : bids;
855
881
  return {
856
- asks: asks.length < level ? paddingFn(level - asks.length).concat(asks) : asks,
857
- bids: bids.length < level ? bids.concat(paddingFn(level - bids.length)) : bids
882
+ asks,
883
+ bids
858
884
  };
859
885
  };
860
886
  var mergeItems = (data, update) => {
@@ -894,7 +920,7 @@ var mergeOrderbook = (data, update) => {
894
920
  var INIT_DATA = { asks: [], bids: [] };
895
921
  var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
896
922
  if (!symbol) {
897
- throw new Error("useOrderbookStream requires a symbol");
923
+ throw new SDKError("useOrderbookStream requires a symbol");
898
924
  }
899
925
  const level = options?.level ?? 10;
900
926
  const [requestData, setRequestData] = useState(null);
@@ -1002,6 +1028,12 @@ var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
1002
1028
  asks: [...data.asks],
1003
1029
  bids: [...data.bids]
1004
1030
  });
1031
+ useEffect(() => {
1032
+ eventEmitter.emit("orderbook:update", [
1033
+ reducedData.asks[0][0],
1034
+ reducedData.bids[0][0]
1035
+ ]);
1036
+ }, [reducedData.asks[0][0], reducedData.bids[0][0]]);
1005
1037
  return [
1006
1038
  {
1007
1039
  asks: reducedData.asks.slice(-level),
@@ -1012,13 +1044,28 @@ var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
1012
1044
  { onDepthChange, depth, allDepths: depths, isLoading, onItemClick }
1013
1045
  ];
1014
1046
  };
1015
- var needNumberOnlyFields = ["order_quantity", "order_price", "total"];
1047
+ var needNumberOnlyFields = [
1048
+ "order_quantity",
1049
+ "order_price",
1050
+ "total"
1051
+ ];
1052
+ var cleanStringStyle = (str) => {
1053
+ if (typeof str !== "string") {
1054
+ str = str.toString();
1055
+ }
1056
+ str = str.replace(/,/g, "");
1057
+ str = str.replace(/[^\d.]/g, "").replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
1058
+ return str;
1059
+ };
1016
1060
  function baseInputHandle(inputs) {
1017
1061
  let [values, input, value, markPrice, config] = inputs;
1062
+ needNumberOnlyFields.forEach((field) => {
1063
+ if (typeof values[field] !== "undefined") {
1064
+ values[field] = cleanStringStyle(values[field]);
1065
+ }
1066
+ });
1018
1067
  if (needNumberOnlyFields.includes(input)) {
1019
- value = value.toString();
1020
- value = value.replace(/,/g, "");
1021
- value = value.replace(/[^\d.]/g, "");
1068
+ value = cleanStringStyle(value);
1022
1069
  }
1023
1070
  return [
1024
1071
  {
@@ -1048,15 +1095,23 @@ function priceInputHandle(inputs) {
1048
1095
  values.order_price = price.toDecimalPlaces(config.quoteDP).toString();
1049
1096
  }
1050
1097
  price.toDecimalPlaces(Math.min(priceDP, config.quoteDP));
1051
- if (!values.order_quantity) {
1098
+ if (!values.order_quantity && !values.total) {
1052
1099
  return [values, input, value, markPrice, config];
1053
1100
  }
1054
- const total = price.mul(values.order_quantity);
1101
+ const newValue = {
1102
+ ...values
1103
+ };
1104
+ if (values.order_quantity) {
1105
+ newValue.total = price.mul(values.order_quantity).todp(2).toString();
1106
+ } else if (values.total) {
1107
+ newValue.order_quantity = new Decimal(values.total).div(price).todp(config.baseDP).toString();
1108
+ }
1055
1109
  return [
1056
- {
1057
- ...values,
1058
- total: total.todp(2).toString()
1059
- },
1110
+ // {
1111
+ // ...values,
1112
+ // total: total.todp(2).toString(),
1113
+ // },
1114
+ newValue,
1060
1115
  input,
1061
1116
  value,
1062
1117
  markPrice,
@@ -1074,11 +1129,11 @@ function quantityInputHandle(inputs) {
1074
1129
  quantity = quantity.toDecimalPlaces(config.baseDP);
1075
1130
  values.order_quantity = quantity.toNumber();
1076
1131
  }
1077
- if (values.order_type === OrderType.MARKET) {
1132
+ if (values.order_type === OrderType.MARKET || values.order_type === OrderType.STOP_MARKET) {
1078
1133
  const price = markPrice;
1079
1134
  values.total = quantity.mul(price).todp(2).toNumber();
1080
1135
  }
1081
- if (values.order_type === OrderType.LIMIT) {
1136
+ if (values.order_type === OrderType.LIMIT || values.order_type === OrderType.STOP_LIMIT) {
1082
1137
  if (values.order_price) {
1083
1138
  const price = Number(values.order_price);
1084
1139
  const total = quantity.mul(price);
@@ -1104,7 +1159,7 @@ function totalInputHandle(inputs) {
1104
1159
  return [{ ...values, order_quantity: "" }, input, value, markPrice, config];
1105
1160
  }
1106
1161
  let price = markPrice;
1107
- if (values.order_type === OrderType.LIMIT && !!values.order_price) {
1162
+ if ((values.order_type === OrderType.LIMIT || values.order_type === OrderType.STOP_LIMIT) && !!values.order_price) {
1108
1163
  price = Number(values.order_price);
1109
1164
  }
1110
1165
  let total = new Decimal(value);
@@ -1212,6 +1267,60 @@ var parseHolding = (holding, markPrices) => {
1212
1267
  });
1213
1268
  return [USDC_holding, nonUSDC];
1214
1269
  };
1270
+ var useMarketsStream = () => {
1271
+ const ws = useWS();
1272
+ const { data: futures } = useQuery(`/v1/public/futures`, {
1273
+ revalidateOnFocus: false
1274
+ });
1275
+ const { data: tickers } = useSWRSubscription("tickers", (_, { next }) => {
1276
+ const unsubscribe = ws.subscribe(
1277
+ // { event: "subscribe", topic: "markprices" },
1278
+ "tickers",
1279
+ {
1280
+ onMessage: (message) => {
1281
+ next(null, message);
1282
+ }
1283
+ // onUnsubscribe: () => {
1284
+ // return "markprices";
1285
+ // },
1286
+ // onError: (error: any) => {
1287
+ //
1288
+ // },
1289
+ }
1290
+ );
1291
+ return () => {
1292
+ unsubscribe?.();
1293
+ };
1294
+ });
1295
+ const value = useMemo(() => {
1296
+ if (!futures)
1297
+ return null;
1298
+ if (!tickers)
1299
+ return futures;
1300
+ return futures.map((item) => {
1301
+ const ticker = tickers.find(
1302
+ (t) => t.symbol === item.symbol
1303
+ );
1304
+ if (ticker) {
1305
+ const data = {
1306
+ ...item,
1307
+ ["24h_close"]: ticker.close,
1308
+ ["24h_open"]: ticker.open,
1309
+ ["24h_volumn"]: ticker.volume,
1310
+ change: 0
1311
+ };
1312
+ if (ticker.close !== void 0 && ticker.open !== void 0) {
1313
+ data["change"] = new Decimal(ticker.close).minus(ticker.open).div(ticker.open).toNumber();
1314
+ }
1315
+ return data;
1316
+ }
1317
+ return item;
1318
+ });
1319
+ }, [futures, tickers]);
1320
+ return { data: value };
1321
+ };
1322
+
1323
+ // src/orderly/usePositionStream.ts
1215
1324
  var usePositionStream = (symbol, options) => {
1216
1325
  const symbolInfo = useSymbolsInfo();
1217
1326
  const { data: accountInfo } = usePrivateQuery("/v1/client/info");
@@ -1227,7 +1336,7 @@ var usePositionStream = (symbol, options) => {
1227
1336
  const {
1228
1337
  data,
1229
1338
  error,
1230
- mutate: updatePositions
1339
+ mutate: refreshPositions
1231
1340
  } = usePrivateQuery(`/v1/positions`, {
1232
1341
  // revalidateOnFocus: false,
1233
1342
  // revalidateOnReconnect: false,
@@ -1240,6 +1349,20 @@ var usePositionStream = (symbol, options) => {
1240
1349
  }
1241
1350
  });
1242
1351
  const { data: markPrices } = useMarkPricesStream();
1352
+ const [priceMode, setPriceMode] = useState(options?.calcMode || "markPrice");
1353
+ useEffect(() => {
1354
+ if (options?.calcMode && priceMode !== options?.calcMode) {
1355
+ setPriceMode(options?.calcMode);
1356
+ }
1357
+ }, [options?.calcMode]);
1358
+ const { data: tickers } = useMarketsStream();
1359
+ const tickerPrices = useMemo(() => {
1360
+ const data2 = /* @__PURE__ */ Object.create(null);
1361
+ tickers?.forEach((item) => {
1362
+ data2[item.symbol] = item["24h_close"];
1363
+ });
1364
+ return data2;
1365
+ }, [tickers]);
1243
1366
  const formatedPositions = useMemo(() => {
1244
1367
  if (!data?.rows || !symbolInfo || !accountInfo)
1245
1368
  return null;
@@ -1248,6 +1371,11 @@ var usePositionStream = (symbol, options) => {
1248
1371
  });
1249
1372
  let unrealPnL_total = zero, notional_total = zero, unsettlementPnL_total = zero;
1250
1373
  const formatted = filteredData.map((item) => {
1374
+ const unRealizedPrice = propOr(
1375
+ item.mark_price,
1376
+ item.symbol,
1377
+ priceMode === "markPrice" ? markPrices : tickerPrices
1378
+ );
1251
1379
  const price = propOr(
1252
1380
  item.mark_price,
1253
1381
  item.symbol,
@@ -1257,8 +1385,8 @@ var usePositionStream = (symbol, options) => {
1257
1385
  const notional = positions.notional(item.position_qty, price);
1258
1386
  const unrealPnl = positions.unrealizedPnL({
1259
1387
  qty: item.position_qty,
1260
- openPrice: item.average_open_price,
1261
- markPrice: price
1388
+ openPrice: item?.average_open_price,
1389
+ markPrice: unRealizedPrice
1262
1390
  });
1263
1391
  const imr = account.IMR({
1264
1392
  maxLeverage: accountInfo.max_leverage,
@@ -1305,7 +1433,16 @@ var usePositionStream = (symbol, options) => {
1305
1433
  unsettledPnL: unsettlementPnL_total.toNumber()
1306
1434
  }
1307
1435
  ];
1308
- }, [data?.rows, symbolInfo, accountInfo, markPrices, symbol, holding]);
1436
+ }, [
1437
+ data?.rows,
1438
+ symbolInfo,
1439
+ accountInfo,
1440
+ markPrices,
1441
+ priceMode,
1442
+ tickerPrices,
1443
+ symbol,
1444
+ holding
1445
+ ]);
1309
1446
  const [totalCollateral, totalValue, totalUnrealizedROI] = useMemo(() => {
1310
1447
  if (!holding || !markPrices) {
1311
1448
  return [zero, zero, 0];
@@ -1335,7 +1472,7 @@ var usePositionStream = (symbol, options) => {
1335
1472
  if (!symbolInfo || !accountInfo)
1336
1473
  return formatedPositions[0];
1337
1474
  const total = totalCollateral.toNumber();
1338
- return formatedPositions[0].filter((item) => item.position_qty !== 0).map((item) => {
1475
+ let rows = formatedPositions[0].filter((item) => item.position_qty !== 0).map((item) => {
1339
1476
  const info = symbolInfo?.[item.symbol];
1340
1477
  const MMR = positions.MMR({
1341
1478
  baseMMR: info("base_mmr"),
@@ -1351,15 +1488,29 @@ var usePositionStream = (symbol, options) => {
1351
1488
  markPrice: item.mark_price,
1352
1489
  MMR
1353
1490
  }),
1354
- est_liq_price: positions.liqPrice({
1355
- markPrice: item.mark_price,
1356
- totalCollateral: total,
1357
- positionQty: item.position_qty,
1358
- MMR
1359
- }),
1360
- MMR
1491
+ // est_liq_price: positions.liqPrice({
1492
+ // markPrice: item.mark_price,
1493
+ // totalCollateral: total,
1494
+ // positionQty: item.position_qty,
1495
+ // MMR,
1496
+ // }),
1497
+ mmr: MMR
1498
+ };
1499
+ });
1500
+ rows = rows.map((item) => {
1501
+ const est_liq_price = positions.liqPrice({
1502
+ markPrice: item.mark_price,
1503
+ totalCollateral: total,
1504
+ positionQty: item.position_qty,
1505
+ positions: rows,
1506
+ MMR: item.mmr
1507
+ });
1508
+ return {
1509
+ ...item,
1510
+ est_liq_price
1361
1511
  };
1362
1512
  });
1513
+ return rows;
1363
1514
  }, [formatedPositions, symbolInfo, accountInfo, totalCollateral]);
1364
1515
  return [
1365
1516
  {
@@ -1378,10 +1529,8 @@ var usePositionStream = (symbol, options) => {
1378
1529
  loading: false,
1379
1530
  // showSymbol,
1380
1531
  error,
1381
- loadMore: () => {
1382
- },
1383
- refresh: () => {
1384
- }
1532
+ // loadMore: () => {},
1533
+ refresh: refreshPositions
1385
1534
  }
1386
1535
  ];
1387
1536
  };
@@ -1442,6 +1591,7 @@ var useHoldingStream = () => {
1442
1591
  var useOrderStream = (params) => {
1443
1592
  const { status, symbol, side, size = 100 } = params;
1444
1593
  const { data: markPrices = {} } = useMarkPricesStream();
1594
+ const { regesterKeyHandler } = useDataCenterContext();
1445
1595
  const [
1446
1596
  doCancelOrder,
1447
1597
  { error: cancelOrderError, isMutating: cancelMutating }
@@ -1450,65 +1600,124 @@ var useOrderStream = (params) => {
1450
1600
  doUpdateOrder,
1451
1601
  { error: updateOrderError, isMutating: updateMutating }
1452
1602
  ] = useMutation("/v1/order", "PUT");
1453
- const ordersResponse = usePrivateInfiniteQuery(
1454
- (pageIndex, previousPageData) => {
1455
- if (previousPageData && !previousPageData.rows?.length)
1456
- return null;
1457
- const search = new URLSearchParams([
1458
- ["size", size.toString()],
1459
- ["page", `${pageIndex + 1}`]
1460
- ]);
1461
- if (status) {
1462
- search.set(`status`, status);
1463
- }
1464
- if (symbol) {
1465
- search.set(`symbol`, symbol);
1466
- }
1467
- if (side) {
1468
- search.set(`side`, side);
1469
- }
1470
- return `/v1/orders?${search.toString()}`;
1471
- },
1472
- {
1473
- initialSize: 1,
1474
- // revalidateFirstPage: false,
1475
- // onError: (err) => {
1476
- // console.error("fetch failed::::", err);
1477
- // },
1478
- formatter: (data) => data
1603
+ const [
1604
+ doCanceAlgolOrder,
1605
+ { error: cancelAlgoOrderError, isMutating: cancelAlgoMutating }
1606
+ ] = useMutation("/v1/algo/order", "DELETE");
1607
+ const [
1608
+ doUpdateAlgoOrder,
1609
+ { error: updateAlgoOrderError, isMutating: updateAlgoMutating }
1610
+ ] = useMutation("/v1/algo/order", "PUT");
1611
+ const getKey = (pageIndex, previousPageData) => {
1612
+ if (previousPageData && !previousPageData.rows?.length)
1613
+ return null;
1614
+ const search = new URLSearchParams([
1615
+ ["size", size.toString()],
1616
+ ["page", `${pageIndex + 1}`],
1617
+ ["source_type", "ALL"]
1618
+ ]);
1619
+ if (status) {
1620
+ search.set(`status`, status);
1479
1621
  }
1480
- );
1481
- const orders = useMemo(() => {
1622
+ if (symbol) {
1623
+ search.set(`symbol`, symbol);
1624
+ }
1625
+ if (side) {
1626
+ search.set(`side`, side);
1627
+ }
1628
+ return `/v1/orders?${search.toString()}`;
1629
+ };
1630
+ useEffect(() => {
1631
+ const key = `orders:${status}:${symbol}:${side}`;
1632
+ regesterKeyHandler(key, getKey);
1633
+ }, [status, symbol, side]);
1634
+ const ordersResponse = usePrivateInfiniteQuery(getKey, {
1635
+ initialSize: 1,
1636
+ // revalidateFirstPage: false,
1637
+ // onError: (err) => {
1638
+ // console.error("fetch failed::::", err);
1639
+ // },
1640
+ formatter: (data) => data
1641
+ });
1642
+ const flattenOrders = useMemo(() => {
1482
1643
  if (!ordersResponse.data) {
1483
1644
  return null;
1484
1645
  }
1485
- return ordersResponse.data?.map((item) => item.rows)?.flat().map((item) => {
1646
+ return ordersResponse.data?.map((item) => item.rows)?.flat();
1647
+ }, [ordersResponse.data]);
1648
+ const orders = useMemo(() => {
1649
+ if (!flattenOrders) {
1650
+ return null;
1651
+ }
1652
+ if (status !== OrderStatus.NEW && status !== OrderStatus.INCOMPLETE) {
1653
+ return flattenOrders;
1654
+ }
1655
+ return flattenOrders.map((item) => {
1486
1656
  return {
1487
1657
  ...item,
1488
1658
  mark_price: markPrices[item.symbol] ?? 0
1489
1659
  };
1490
1660
  });
1491
- }, [ordersResponse.data, markPrices]);
1661
+ }, [flattenOrders, markPrices, status]);
1492
1662
  const total = useMemo(() => {
1493
1663
  return ordersResponse.data?.[0]?.meta?.total || 0;
1494
1664
  }, [ordersResponse.data?.[0]?.meta?.total]);
1495
1665
  const cancelAllOrders = useCallback(() => {
1496
1666
  }, [ordersResponse.data]);
1497
- const updateOrder = useCallback((orderId, order2) => {
1498
- return doUpdateOrder({ ...order2, order_id: orderId });
1667
+ const _updateOrder = useCallback((orderId, order3, type) => {
1668
+ switch (type) {
1669
+ case "algoOrder":
1670
+ return doUpdateAlgoOrder({
1671
+ order_id: orderId,
1672
+ price: order3["order_price"],
1673
+ quantity: order3["order_quantity"],
1674
+ trigger_price: order3["trigger_price"]
1675
+ });
1676
+ default:
1677
+ return doUpdateOrder({ ...order3, order_id: orderId });
1678
+ }
1679
+ }, []);
1680
+ const updateOrder = useCallback((orderId, order3) => {
1681
+ return _updateOrder(orderId, order3, "normalOrder");
1682
+ }, []);
1683
+ const updateAlgoOrder = useCallback((orderId, order3) => {
1684
+ return _updateOrder(orderId, order3, "algoOrder");
1685
+ }, []);
1686
+ const _cancelOrder = useCallback((orderId, type, symbol2) => {
1687
+ switch (type) {
1688
+ case "algoOrder":
1689
+ return doCanceAlgolOrder(null, {
1690
+ // @ts-ignore
1691
+ order_id: orderId,
1692
+ symbol: symbol2,
1693
+ source: `SDK${version_default}`
1694
+ }).then((res) => {
1695
+ if (res.success) {
1696
+ ordersResponse.mutate();
1697
+ return res;
1698
+ } else {
1699
+ throw new Error(res.message);
1700
+ }
1701
+ });
1702
+ default:
1703
+ return doCancelOrder(null, {
1704
+ order_id: orderId,
1705
+ symbol: symbol2,
1706
+ source: `SDK_${version_default}`
1707
+ }).then((res) => {
1708
+ if (res.success) {
1709
+ return res;
1710
+ } else {
1711
+ throw new Error(res.message);
1712
+ }
1713
+ });
1714
+ }
1499
1715
  }, []);
1500
1716
  const cancelOrder = useCallback((orderId, symbol2) => {
1501
- return doCancelOrder(null, {
1502
- order_id: orderId,
1503
- symbol: symbol2,
1504
- source: "mweb"
1505
- }).then((res) => {
1506
- if (res.success) {
1507
- return res;
1508
- } else {
1509
- throw new Error(res.message);
1510
- }
1511
- });
1717
+ return _cancelOrder(orderId, "normalOrder", symbol2);
1718
+ }, []);
1719
+ const cancelAlgoOrder = useCallback((orderId, symbol2) => {
1720
+ return _cancelOrder(orderId, "algoOrder", symbol2);
1512
1721
  }, []);
1513
1722
  const loadMore = () => {
1514
1723
  ordersResponse.setSize(ordersResponse.size + 1);
@@ -1518,17 +1727,24 @@ var useOrderStream = (params) => {
1518
1727
  {
1519
1728
  total,
1520
1729
  isLoading: ordersResponse.isLoading,
1730
+ refresh: ordersResponse.mutate,
1521
1731
  loadMore,
1522
1732
  cancelAllOrders,
1523
1733
  updateOrder,
1524
1734
  cancelOrder,
1735
+ updateAlgoOrder,
1736
+ cancelAlgoOrder,
1525
1737
  errors: {
1526
1738
  cancelOrder: cancelOrderError,
1527
- updateOrder: updateOrderError
1739
+ updateOrder: updateOrderError,
1740
+ cancelAlgoOrder: cancelAlgoOrderError,
1741
+ updateAlgoOrder: updateAlgoOrderError
1528
1742
  },
1529
1743
  submitting: {
1530
1744
  cancelOrder: cancelMutating,
1531
- updateOrder: updateMutating
1745
+ updateOrder: updateMutating,
1746
+ cancelAlgoOrder: cancelAlgoMutating,
1747
+ updateAlglOrder: updateAlgoMutating
1532
1748
  }
1533
1749
  }
1534
1750
  ];
@@ -1539,31 +1755,32 @@ var positionsPath = pathOr([], [0, "rows"]);
1539
1755
  pathOr(0, [0, "totalCollateral"]);
1540
1756
  var useCollateral = (options = { dp: 6 }) => {
1541
1757
  const { dp } = options;
1542
- const positions2 = usePositionStream();
1758
+ const positions3 = usePositionStream();
1543
1759
  const [orders] = useOrderStream({ status: OrderStatus.NEW });
1544
1760
  const { data: accountInfo } = usePrivateQuery("/v1/client/info");
1545
1761
  const symbolInfo = useSymbolsInfo();
1546
1762
  const { data: markPrices } = useMarkPricesStream();
1547
1763
  const { usdc } = useHoldingStream();
1764
+ const filterAlgoOrders = orders?.filter((item) => item.algo_order_id === void 0) ?? [];
1548
1765
  const [totalCollateral, totalValue] = useMemo(() => {
1549
1766
  return [
1550
- pathOr(zero, [0, "totalCollateral"], positions2),
1551
- pathOr(zero, [0, "totalValue"], positions2)
1767
+ pathOr(zero, [0, "totalCollateral"], positions3),
1768
+ pathOr(zero, [0, "totalValue"], positions3)
1552
1769
  ];
1553
- }, [positions2, markPrices]);
1770
+ }, [positions3, markPrices]);
1554
1771
  const totalInitialMarginWithOrders = useMemo(() => {
1555
1772
  if (!accountInfo || !symbolInfo || !markPrices) {
1556
1773
  return 0;
1557
1774
  }
1558
1775
  return account.totalInitialMarginWithOrders({
1559
- positions: positionsPath(positions2),
1560
- orders: orders ?? [],
1776
+ positions: positionsPath(positions3),
1777
+ orders: filterAlgoOrders,
1561
1778
  markPrices,
1562
1779
  IMR_Factors: accountInfo.imr_factor,
1563
1780
  maxLeverage: accountInfo.max_leverage,
1564
1781
  symbolInfo
1565
1782
  });
1566
- }, [positions2, orders, markPrices, accountInfo, symbolInfo]);
1783
+ }, [positions3, filterAlgoOrders, markPrices, accountInfo, symbolInfo]);
1567
1784
  const freeCollateral = useMemo(() => {
1568
1785
  return account.freeCollateral({
1569
1786
  totalCollateral,
@@ -1573,15 +1790,18 @@ var useCollateral = (options = { dp: 6 }) => {
1573
1790
  const availableBalance = useMemo(() => {
1574
1791
  return account.availableBalance({
1575
1792
  USDCHolding: usdc?.holding ?? 0,
1576
- unsettlementPnL: pathOr_unsettledPnLPathOr(positions2)
1793
+ unsettlementPnL: pathOr_unsettledPnLPathOr(positions3)
1577
1794
  });
1578
- }, [usdc, pathOr_unsettledPnLPathOr(positions2)]);
1795
+ }, [usdc?.holding, pathOr_unsettledPnLPathOr(positions3)]);
1579
1796
  return {
1580
1797
  totalCollateral: totalCollateral.toDecimalPlaces(dp).toNumber(),
1581
1798
  freeCollateral: freeCollateral.toDecimalPlaces(dp).toNumber(),
1582
1799
  totalValue: totalValue.toDecimalPlaces(dp).toNumber(),
1583
1800
  availableBalance,
1584
- unsettledPnL: pathOr_unsettledPnLPathOr(positions2)
1801
+ unsettledPnL: pathOr_unsettledPnLPathOr(positions3),
1802
+ accountInfo,
1803
+ // @hidden
1804
+ positions: positionsPath(positions3)
1585
1805
  };
1586
1806
  };
1587
1807
  var positionsPath2 = pathOr([], [0, "rows"]);
@@ -1595,8 +1815,8 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
1595
1815
  const maxQty = useMemo(() => {
1596
1816
  if (!symbol)
1597
1817
  return 0;
1598
- const positions2 = positionsPath2(positionsData);
1599
- const positionQty = account.getQtyFromPositions(positions2, symbol);
1818
+ const positions3 = positionsPath2(positionsData);
1819
+ const positionQty = account.getQtyFromPositions(positions3, symbol);
1600
1820
  if (reduceOnly) {
1601
1821
  if (positionQty > 0) {
1602
1822
  if (side === OrderSide.BUY) {
@@ -1617,20 +1837,21 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
1617
1837
  if (!markPrices || !markPrices[symbol] || !orders || !accountInfo)
1618
1838
  return 0;
1619
1839
  const getSymbolInfo = symbolInfo[symbol];
1840
+ const filterAlgoOrders = orders.filter((item) => item.algo_order_id === void 0);
1620
1841
  const buyOrdersQty = account.getQtyFromOrdersBySide(
1621
- orders,
1842
+ filterAlgoOrders,
1622
1843
  symbol,
1623
1844
  OrderSide.BUY
1624
1845
  );
1625
1846
  const sellOrdersQty = account.getQtyFromOrdersBySide(
1626
- orders,
1847
+ filterAlgoOrders,
1627
1848
  symbol,
1628
1849
  OrderSide.SELL
1629
1850
  );
1630
- const otherPositions = positions2.filter(
1851
+ const otherPositions = positions3.filter(
1631
1852
  (item) => item.symbol !== symbol
1632
1853
  );
1633
- const otherOrders = orders.filter(
1854
+ const otherOrders = filterAlgoOrders.filter(
1634
1855
  (item) => item.symbol !== symbol
1635
1856
  );
1636
1857
  const otherIMs = account.otherIMs({
@@ -1666,27 +1887,36 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
1666
1887
  totalCollateral,
1667
1888
  reduceOnly
1668
1889
  ]);
1669
- return maxQty;
1890
+ return Math.max(maxQty, 0);
1670
1891
  };
1671
- var { maxPrice, minPrice } = order;
1892
+ var { maxPrice, minPrice, scropePrice } = order;
1672
1893
  var BaseOrderCreator = class {
1673
1894
  baseOrder(data) {
1674
- const order2 = {
1675
- // symbol: data.symbol,
1895
+ const order3 = {
1896
+ symbol: data.symbol,
1676
1897
  order_type: data.order_type === OrderType.LIMIT ? !!data.order_type_ext ? data.order_type_ext : data.order_type : data.order_type,
1677
1898
  side: data.side,
1678
1899
  reduce_only: data.reduce_only,
1679
- order_quantity: data.order_quantity
1900
+ order_quantity: data.order_quantity,
1901
+ total: data.total
1680
1902
  };
1681
1903
  if (data.visible_quantity === 0) {
1682
- order2.visible_quantity = data.visible_quantity;
1904
+ order3.visible_quantity = data.visible_quantity;
1683
1905
  }
1684
- return order2;
1906
+ return order3;
1685
1907
  }
1686
1908
  baseValidate(values, configs) {
1687
1909
  const errors = {};
1688
1910
  const { maxQty } = configs;
1689
- const { order_quantity, total } = values;
1911
+ let { order_quantity, total, order_price } = values;
1912
+ if (!order_quantity) {
1913
+ if (total && order_price) {
1914
+ const { quote_dp } = configs.symbol;
1915
+ const totalNumber = new Decimal(total);
1916
+ const qty = totalNumber.dividedBy(order_price).toFixed(quote_dp);
1917
+ order_quantity = qty;
1918
+ }
1919
+ }
1690
1920
  if (!order_quantity) {
1691
1921
  errors.order_quantity = {
1692
1922
  type: "required",
@@ -1732,13 +1962,28 @@ var BaseOrderCreator = class {
1732
1962
  }
1733
1963
  return Promise.resolve(errors);
1734
1964
  }
1965
+ fixOrderQuantity(order3, config) {
1966
+ if (!order3.order_quantity && order3.total && order3.order_price) {
1967
+ const { base_dp } = config.symbol;
1968
+ const totalNumber = new Decimal(order3.total);
1969
+ const qty = totalNumber.div(order3.order_price).toDecimalPlaces(base_dp);
1970
+ order3.order_quantity = qty.toNumber();
1971
+ delete order3.total;
1972
+ }
1973
+ return order3;
1974
+ }
1735
1975
  };
1736
1976
  var LimitOrderCreator = class extends BaseOrderCreator {
1737
- create(values) {
1738
- return {
1977
+ create(values, config) {
1978
+ const order3 = {
1739
1979
  ...this.baseOrder(values),
1740
1980
  order_price: values.order_price
1741
1981
  };
1982
+ this.fixOrderQuantity(order3, config);
1983
+ delete order3["total"];
1984
+ delete order3["trigger_price"];
1985
+ delete order3["isStopOrder"];
1986
+ return order3;
1742
1987
  }
1743
1988
  validate(values, config) {
1744
1989
  return this.baseValidate(values, config).then((errors) => {
@@ -1751,22 +1996,34 @@ var LimitOrderCreator = class extends BaseOrderCreator {
1751
1996
  } else {
1752
1997
  const price = new Decimal(order_price);
1753
1998
  const { symbol } = config;
1754
- const { price_range } = symbol;
1999
+ const { price_range, price_scope } = symbol;
1755
2000
  const maxPriceNumber = maxPrice(config.markPrice, price_range);
1756
2001
  const minPriceNumber = minPrice(config.markPrice, price_range);
1757
- console.log(`side: ${side} value:`, values);
1758
- if (side === "BUY" && price.gt(maxPriceNumber)) {
2002
+ const scropePriceNumbere = scropePrice(
2003
+ config.markPrice,
2004
+ price_scope,
2005
+ side
2006
+ );
2007
+ const priceRange = side === "BUY" ? {
2008
+ min: scropePriceNumbere,
2009
+ max: maxPriceNumber
2010
+ } : {
2011
+ min: minPriceNumber,
2012
+ max: scropePriceNumbere
2013
+ };
2014
+ if (price.gt(priceRange.max)) {
1759
2015
  errors.order_price = {
1760
2016
  type: "max",
1761
- message: `price must be less than ${new Decimal(
1762
- maxPriceNumber
2017
+ message: `Price must be less than ${new Decimal(
2018
+ priceRange.max
1763
2019
  ).todp(symbol.quote_dp)}`
1764
2020
  };
1765
- } else if (side === "SELL" && price.lt(minPriceNumber)) {
2021
+ }
2022
+ if (price.lt(priceRange.min)) {
1766
2023
  errors.order_price = {
1767
2024
  type: "min",
1768
- message: `price must be greater than ${new Decimal(
1769
- minPriceNumber
2025
+ message: `Price must be greater than ${new Decimal(
2026
+ priceRange.min
1770
2027
  ).todp(symbol.quote_dp)}`
1771
2028
  };
1772
2029
  }
@@ -1779,6 +2036,9 @@ var MarketOrderCreator = class extends BaseOrderCreator {
1779
2036
  create(values) {
1780
2037
  const data = this.baseOrder(values);
1781
2038
  delete data["order_price"];
2039
+ delete data["total"];
2040
+ delete data["trigger_price"];
2041
+ delete data["isStopOrder"];
1782
2042
  return {
1783
2043
  ...data
1784
2044
  };
@@ -1793,6 +2053,110 @@ var FOKOrderCreator = class extends LimitOrderCreator {
1793
2053
  };
1794
2054
  var IOCOrderCreator = class extends LimitOrderCreator {
1795
2055
  };
2056
+ var StopLimitOrderCreator = class extends LimitOrderCreator {
2057
+ create(values, config) {
2058
+ const order3 = {
2059
+ ...this.baseOrder(values),
2060
+ order_price: values.order_price,
2061
+ trigger_price: values.trigger_price,
2062
+ algo_type: "STOP",
2063
+ type: "LIMIT",
2064
+ quantity: values["order_quantity"],
2065
+ price: values["order_price"],
2066
+ trigger_price_type: "MARK_PRICE"
2067
+ };
2068
+ this.fixOrderQuantity(order3, config);
2069
+ delete order3["order_quantity"];
2070
+ delete order3["order_price"];
2071
+ delete order3["isStopOrder"];
2072
+ delete order3["total"];
2073
+ return order3;
2074
+ }
2075
+ validate(values, config) {
2076
+ return this.baseValidate(values, config).then((errors) => {
2077
+ const { order_price, trigger_price, side } = values;
2078
+ if (!order_price) {
2079
+ errors.order_price = {
2080
+ type: "required",
2081
+ message: "price is required"
2082
+ };
2083
+ }
2084
+ if (!trigger_price) {
2085
+ errors.trigger_price = {
2086
+ type: "required",
2087
+ message: "Trigger price is required"
2088
+ };
2089
+ }
2090
+ if (trigger_price && order_price) {
2091
+ const price = new Decimal(order_price);
2092
+ const { symbol } = config;
2093
+ const { price_range, price_scope } = symbol;
2094
+ const maxPriceNumber = maxPrice(trigger_price, price_range);
2095
+ const minPriceNumber = minPrice(trigger_price, price_range);
2096
+ const scropePriceNumbere = scropePrice(
2097
+ trigger_price,
2098
+ price_scope,
2099
+ side
2100
+ );
2101
+ const priceRange = side === "BUY" ? {
2102
+ min: scropePriceNumbere,
2103
+ max: maxPriceNumber
2104
+ } : {
2105
+ min: minPriceNumber,
2106
+ max: scropePriceNumbere
2107
+ };
2108
+ if (price.gt(priceRange.max)) {
2109
+ errors.order_price = {
2110
+ type: "max",
2111
+ message: `Price must be less than ${new Decimal(
2112
+ priceRange.max
2113
+ ).todp(symbol.quote_dp)}`
2114
+ };
2115
+ }
2116
+ if (price.lt(priceRange.min)) {
2117
+ errors.order_price = {
2118
+ type: "min",
2119
+ message: `Price must be greater than ${new Decimal(
2120
+ priceRange.min
2121
+ ).todp(symbol.quote_dp)}`
2122
+ };
2123
+ }
2124
+ }
2125
+ return errors;
2126
+ });
2127
+ }
2128
+ };
2129
+ var StopMarketOrderCreator = class extends LimitOrderCreator {
2130
+ create(values, _) {
2131
+ const result = {
2132
+ ...this.baseOrder(values),
2133
+ order_price: values.order_price,
2134
+ trigger_price: values.trigger_price,
2135
+ algo_type: "STOP",
2136
+ type: "MARKET",
2137
+ quantity: values["order_quantity"],
2138
+ price: values["order_price"],
2139
+ trigger_price_type: "MARK_PRICE"
2140
+ };
2141
+ delete result["order_quantity"];
2142
+ delete result["order_price"];
2143
+ delete result["isStopOrder"];
2144
+ delete result["total"];
2145
+ return result;
2146
+ }
2147
+ validate(values, config) {
2148
+ return this.baseValidate(values, config).then((errors) => {
2149
+ const { order_price, trigger_price, side } = values;
2150
+ if (!trigger_price) {
2151
+ errors.trigger_price = {
2152
+ type: "required",
2153
+ message: "Trigger price is required"
2154
+ };
2155
+ }
2156
+ return errors;
2157
+ });
2158
+ }
2159
+ };
1796
2160
  var GeneralOrderCreator = class extends BaseOrderCreator {
1797
2161
  create(data) {
1798
2162
  return {
@@ -1805,6 +2169,15 @@ var GeneralOrderCreator = class extends BaseOrderCreator {
1805
2169
  return super.baseValidate(values, configs);
1806
2170
  }
1807
2171
  };
2172
+ var availableOrderTypes = [
2173
+ OrderType.LIMIT,
2174
+ OrderType.MARKET,
2175
+ OrderType.IOC,
2176
+ OrderType.FOK,
2177
+ OrderType.POST_ONLY,
2178
+ OrderType.STOP_LIMIT,
2179
+ OrderType.STOP_MARKET
2180
+ ];
1808
2181
  var OrderFactory = class {
1809
2182
  static create(type) {
1810
2183
  switch (type) {
@@ -1818,17 +2191,68 @@ var OrderFactory = class {
1818
2191
  return new FOKOrderCreator();
1819
2192
  case OrderType.POST_ONLY:
1820
2193
  return new PostOnlyOrderCreator();
2194
+ case OrderType.STOP_LIMIT:
2195
+ return new StopLimitOrderCreator();
2196
+ case OrderType.STOP_MARKET:
2197
+ return new StopMarketOrderCreator();
1821
2198
  default:
1822
2199
  return new GeneralOrderCreator();
1823
2200
  }
1824
2201
  }
1825
2202
  };
1826
-
1827
- // src/orderly/useOrderEntry.ts
1828
- var useOrderEntry = (symbol, side, reduceOnly = false, options) => {
1829
- const [doCreateOrder, { data, error, reset, isMutating }] = useMutation("/v1/order");
1830
- const { freeCollateral } = useCollateral();
2203
+ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
2204
+ if (typeof symbolOrOrder === "object") {
2205
+ if (!symbolOrOrder.symbol) {
2206
+ throw new SDKError("symbol is required");
2207
+ }
2208
+ if (!symbolOrOrder.side) {
2209
+ throw new SDKError("Order side is required");
2210
+ }
2211
+ if (!symbolOrOrder.order_type) {
2212
+ throw new SDKError("order_type is required");
2213
+ }
2214
+ }
2215
+ const prevOrderData = useRef(null);
2216
+ const orderDataCache = useRef(null);
2217
+ const notSupportData = useRef({});
2218
+ const [doCreateOrder, { data, error, reset, isMutating }] = useMutation(orderDataCache?.current?.isStopOrder ? "/v1/algo/order" : "/v1/order");
2219
+ const [errors, setErrors] = useState(null);
2220
+ const ee = useEventEmitter();
2221
+ const fieldDirty = useRef({});
2222
+ const submitted = useRef(false);
2223
+ const askAndBid = useRef([]);
2224
+ const onOrderbookUpdate = useDebouncedCallback((data2) => {
2225
+ askAndBid.current = data2;
2226
+ }, 200);
2227
+ const { freeCollateral, totalCollateral, positions: positions3, accountInfo } = useCollateral();
1831
2228
  const symbolInfo = useSymbolsInfo();
2229
+ const symbol = useMemo(() => {
2230
+ if (typeof symbolOrOrder === "string") {
2231
+ return symbolOrOrder;
2232
+ }
2233
+ return symbolOrOrder.symbol;
2234
+ }, [symbolOrOrder]);
2235
+ const optionsValue = useMemo(() => {
2236
+ if (typeof sideOrOptions === "object") {
2237
+ return sideOrOptions;
2238
+ }
2239
+ return options;
2240
+ }, [sideOrOptions]);
2241
+ const isReduceOnly = useMemo(() => {
2242
+ if (typeof reduceOnly === "boolean") {
2243
+ return reduceOnly;
2244
+ }
2245
+ if (typeof symbolOrOrder === "object") {
2246
+ return !!symbolOrOrder.reduce_only;
2247
+ }
2248
+ return false;
2249
+ }, [symbolOrOrder, reduceOnly]);
2250
+ const sideValue = useMemo(() => {
2251
+ if (typeof symbolOrOrder === "object") {
2252
+ return symbolOrOrder.side;
2253
+ }
2254
+ return sideOrOptions;
2255
+ }, [symbolOrOrder, sideOrOptions]);
1832
2256
  const baseDP = useMemo(
1833
2257
  () => getPrecisionByNumber(symbolInfo[symbol]("base_tick", 0)),
1834
2258
  [symbolInfo]
@@ -1836,42 +2260,123 @@ var useOrderEntry = (symbol, side, reduceOnly = false, options) => {
1836
2260
  const quoteDP = useMemo(() => {
1837
2261
  return getPrecisionByNumber(symbolInfo[symbol]("quote_tick", 0));
1838
2262
  }, [symbolInfo]);
2263
+ const baseIMR = useMemo(() => symbolInfo[symbol]("base_imr"), [symbolInfo]);
2264
+ const baseMMR = useMemo(() => symbolInfo[symbol]("base_mmr"), [symbolInfo]);
1839
2265
  const { data: markPrice } = useMarkPrice(symbol);
1840
- const maxQty = useMaxQty(
1841
- symbol,
1842
- side,
1843
- // orderExtraValues.reduce_only
1844
- reduceOnly
1845
- );
1846
- const onSubmit = (values) => {
1847
- if (!values || typeof values.order_type === "undefined" || values.order_type !== OrderType.MARKET && values.order_type !== OrderType.LIMIT) {
1848
- throw new Error("order_type is error");
2266
+ const diffOrderEntry = (prev, current) => {
2267
+ if (!prev)
2268
+ return null;
2269
+ let key, value;
2270
+ const keys = Object.keys(current);
2271
+ for (let i = 0; i < keys.length; i++) {
2272
+ const k = keys[i];
2273
+ let preveValue = prev[k];
2274
+ let currentValue = current[k];
2275
+ if (typeof preveValue === "undefined" && typeof currentValue === "undefined")
2276
+ continue;
2277
+ if (preveValue !== currentValue) {
2278
+ key = k;
2279
+ value = currentValue;
2280
+ break;
2281
+ }
2282
+ }
2283
+ if (!key)
2284
+ return null;
2285
+ return { key, value };
2286
+ };
2287
+ const maxQty = useMaxQty(symbol, sideValue, isReduceOnly);
2288
+ const parsedData = useMemo(() => {
2289
+ if (typeof symbolOrOrder === "string") {
2290
+ return null;
2291
+ }
2292
+ if (typeof symbolOrOrder.order_quantity === "string") {
2293
+ symbolOrOrder.order_quantity = symbolOrOrder.order_quantity.replace(
2294
+ /,/g,
2295
+ ""
2296
+ );
2297
+ }
2298
+ if (typeof symbolOrOrder.order_price === "string") {
2299
+ symbolOrOrder.order_price = symbolOrOrder.order_price.replace(/,/g, "");
2300
+ }
2301
+ if (typeof symbolOrOrder.total === "string") {
2302
+ symbolOrOrder.total = symbolOrOrder.total.replace(/,/g, "");
2303
+ }
2304
+ if (typeof symbolOrOrder.order_quantity === "number") {
2305
+ symbolOrOrder.order_quantity = new Decimal(symbolOrOrder.order_quantity).toDecimalPlaces(baseDP).toString();
2306
+ }
2307
+ return symbolOrOrder;
2308
+ }, [symbolOrOrder]);
2309
+ const createOrder = (values) => {
2310
+ if (!values.symbol) {
2311
+ throw new SDKError("symbol is error");
2312
+ }
2313
+ if (!values.side) {
2314
+ throw new SDKError("side is error");
2315
+ }
2316
+ if (!values || typeof values.order_type === "undefined" || !includes(values.order_type, availableOrderTypes)) {
2317
+ throw new SDKError("order_type is error");
1849
2318
  }
1850
2319
  const orderCreator = OrderFactory.create(
1851
- !!values.order_type_ext ? values.order_type_ext : values.order_type
2320
+ values.order_type_ext ? values.order_type_ext : values.order_type
1852
2321
  );
1853
2322
  if (!orderCreator) {
1854
- return Promise.reject(new Error("orderCreator is null"));
2323
+ return Promise.reject(new SDKError("orderCreator is null"));
1855
2324
  }
1856
- return orderCreator?.validate(values, {
1857
- symbol: symbolInfo[symbol](),
1858
- // token: tokenInfo[symbol](),
1859
- maxQty,
1860
- markPrice
1861
- }).then(() => {
1862
- if (!orderCreator) {
1863
- throw new Error("orderCreator is null");
1864
- }
1865
- if (!symbol) {
1866
- throw new Error("symbol is null");
1867
- }
1868
- const data2 = orderCreator.create(values);
1869
- return doCreateOrder({
1870
- ...data2,
1871
- symbol
2325
+ return new Promise((resolve, reject) => {
2326
+ return orderCreator.validate(values, {
2327
+ symbol: symbolInfo[symbol](),
2328
+ // token: tokenInfo[symbol](),
2329
+ maxQty,
2330
+ markPrice
2331
+ }).then((errors2) => {
2332
+ submitted.current = true;
2333
+ if (errors2.order_price || errors2.order_quantity || errors2.trigger_price) {
2334
+ setErrors(errors2);
2335
+ reject(
2336
+ errors2.order_price?.message || errors2.order_quantity?.message
2337
+ );
2338
+ } else {
2339
+ const data2 = orderCreator.create(values, {
2340
+ symbol: symbolInfo[symbol](),
2341
+ maxQty,
2342
+ markPrice
2343
+ });
2344
+ return doCreateOrder(
2345
+ omit(["order_type_ext"], {
2346
+ // ...values,
2347
+ // ...omit(["order_price"], values),
2348
+ ...data2
2349
+ })
2350
+ ).then((res) => {
2351
+ if (res.success) {
2352
+ resolve(res.data);
2353
+ } else {
2354
+ reject(res);
2355
+ }
2356
+ }, reject);
2357
+ }
1872
2358
  });
1873
2359
  });
1874
2360
  };
2361
+ const onSubmit = (values) => {
2362
+ if (typeof reduceOnly === "boolean" && reduceOnly && !values.reduce_only) {
2363
+ return Promise.reject(
2364
+ new SDKError(
2365
+ "The reduceOny parameter of hook does not match your order data"
2366
+ )
2367
+ );
2368
+ }
2369
+ return createOrder({
2370
+ ...values,
2371
+ symbol
2372
+ });
2373
+ };
2374
+ const submit = useCallback(() => {
2375
+ if (typeof symbolOrOrder === "string") {
2376
+ throw new SDKError("Function is not supported, please use onSubmit()");
2377
+ }
2378
+ return createOrder(symbolOrOrder);
2379
+ }, [symbolOrOrder]);
1875
2380
  const calculate = useCallback(
1876
2381
  (values, field, value) => {
1877
2382
  const fieldHandler = getCalculateHandler(field);
@@ -1894,75 +2399,407 @@ var useOrderEntry = (symbol, side, reduceOnly = false, options) => {
1894
2399
  markPrice
1895
2400
  });
1896
2401
  };
2402
+ const formattedOrder = useMemo(() => {
2403
+ if (!parsedData) {
2404
+ return notSupportData.current;
2405
+ }
2406
+ if (!prevOrderData.current) {
2407
+ prevOrderData.current = parsedData;
2408
+ orderDataCache.current = {
2409
+ ...parsedData,
2410
+ total: ""
2411
+ };
2412
+ return orderDataCache.current;
2413
+ }
2414
+ const item = diffOrderEntry(prevOrderData.current, parsedData);
2415
+ if (!item) {
2416
+ return orderDataCache.current;
2417
+ }
2418
+ if (typeof parsedData.order_price !== "undefined") {
2419
+ fieldDirty.current.order_price = true;
2420
+ }
2421
+ if (typeof parsedData.order_quantity !== "undefined") {
2422
+ fieldDirty.current.order_quantity = true;
2423
+ }
2424
+ const values = calculate(parsedData, item.key, item.value);
2425
+ values.isStopOrder = values.order_type?.startsWith("STOP") || false;
2426
+ values.total = values.total || "";
2427
+ prevOrderData.current = parsedData;
2428
+ orderDataCache.current = values;
2429
+ return values;
2430
+ }, [
2431
+ parsedData?.order_price,
2432
+ parsedData?.side,
2433
+ parsedData?.order_quantity,
2434
+ parsedData?.visible_quantity,
2435
+ parsedData?.order_type,
2436
+ parsedData?.order_type_ext,
2437
+ parsedData?.symbol,
2438
+ parsedData?.total,
2439
+ parsedData?.reduce_only,
2440
+ parsedData?.trigger_price,
2441
+ markPrice
2442
+ ]);
2443
+ useEffect(() => {
2444
+ if (!markPrice)
2445
+ return;
2446
+ validator(formattedOrder)?.then((err) => {
2447
+ setErrors(err);
2448
+ });
2449
+ }, [
2450
+ formattedOrder.broker_id,
2451
+ formattedOrder.order_quantity,
2452
+ formattedOrder.total,
2453
+ formattedOrder.trigger_price,
2454
+ markPrice
2455
+ ]);
2456
+ useEffect(() => {
2457
+ if (!optionsValue?.watchOrderbook)
2458
+ return;
2459
+ ee.on("orderbook:update", onOrderbookUpdate);
2460
+ return () => {
2461
+ ee.off("orderbook_update", onOrderbookUpdate);
2462
+ };
2463
+ }, [optionsValue?.watchOrderbook]);
2464
+ useEffect(() => {
2465
+ askAndBid.current = [];
2466
+ }, [parsedData?.symbol]);
2467
+ const getPriceAndQty = (symbolOrOrder2) => {
2468
+ let quantity = Number(symbolOrOrder2.order_quantity);
2469
+ const orderPrice = Number(symbolOrOrder2.order_price);
2470
+ if (isNaN(quantity) || quantity <= 0 || askAndBid.current.length === 0)
2471
+ return null;
2472
+ if ((symbolOrOrder2.order_type === OrderType.LIMIT || symbolOrOrder2.order_type === OrderType.STOP_LIMIT) && isNaN(orderPrice))
2473
+ return null;
2474
+ let price;
2475
+ if (symbolOrOrder2.order_type === OrderType.MARKET || symbolOrOrder2.order_type === OrderType.STOP_MARKET) {
2476
+ if (symbolOrOrder2.side === OrderSide.BUY) {
2477
+ price = askAndBid.current[0];
2478
+ } else {
2479
+ price = askAndBid.current[1];
2480
+ }
2481
+ } else {
2482
+ if (symbolOrOrder2.side === OrderSide.BUY) {
2483
+ if (orderPrice >= askAndBid.current[0]) {
2484
+ price = askAndBid.current[0];
2485
+ } else {
2486
+ price = orderPrice;
2487
+ }
2488
+ } else {
2489
+ if (orderPrice <= askAndBid.current[1]) {
2490
+ price = askAndBid.current[1];
2491
+ } else {
2492
+ price = orderPrice;
2493
+ }
2494
+ }
2495
+ }
2496
+ if (symbolOrOrder2.side === OrderSide.SELL) {
2497
+ quantity = -quantity;
2498
+ }
2499
+ return { price, quantity };
2500
+ };
2501
+ const estLiqPrice = useMemo(() => {
2502
+ if (!accountInfo || !parsedData || !markPrice)
2503
+ return null;
2504
+ const result = getPriceAndQty(formattedOrder);
2505
+ if (result === null)
2506
+ return null;
2507
+ const { price, quantity } = result;
2508
+ if (!price || !quantity)
2509
+ return null;
2510
+ const liqPrice = order.estLiqPrice({
2511
+ markPrice,
2512
+ baseIMR,
2513
+ baseMMR,
2514
+ totalCollateral,
2515
+ positions: positions3,
2516
+ IMR_Factor: accountInfo["imr_factor"][symbol],
2517
+ newOrder: {
2518
+ qty: quantity,
2519
+ price,
2520
+ symbol: parsedData.symbol
2521
+ }
2522
+ });
2523
+ if (liqPrice <= 0)
2524
+ return null;
2525
+ return liqPrice;
2526
+ }, [
2527
+ markPrice,
2528
+ baseIMR,
2529
+ baseMMR,
2530
+ totalCollateral,
2531
+ formattedOrder?.order_price,
2532
+ formattedOrder?.order_quantity,
2533
+ formattedOrder?.total,
2534
+ formattedOrder?.trigger_price,
2535
+ accountInfo
2536
+ ]);
2537
+ const estLeverage = useMemo(() => {
2538
+ if (!accountInfo || !parsedData)
2539
+ return null;
2540
+ const result = getPriceAndQty(formattedOrder);
2541
+ if (result === null || !result.price || !result.quantity)
2542
+ return null;
2543
+ const leverage = order.estLeverage({
2544
+ totalCollateral,
2545
+ positions: positions3,
2546
+ newOrder: {
2547
+ symbol: parsedData.symbol,
2548
+ qty: result.quantity,
2549
+ price: result.price
2550
+ }
2551
+ });
2552
+ return leverage;
2553
+ }, [
2554
+ baseIMR,
2555
+ baseMMR,
2556
+ totalCollateral,
2557
+ positions3,
2558
+ formattedOrder?.order_price,
2559
+ formattedOrder?.order_quantity,
2560
+ formattedOrder?.total,
2561
+ formattedOrder?.trigger_price
2562
+ ]);
1897
2563
  return {
1898
2564
  maxQty,
1899
2565
  freeCollateral,
1900
2566
  markPrice,
1901
2567
  onSubmit,
2568
+ submit,
1902
2569
  submitting: isMutating,
2570
+ formattedOrder,
2571
+ // errors,
2572
+ estLiqPrice,
2573
+ estLeverage,
1903
2574
  helper: {
1904
2575
  calculate,
1905
2576
  validator
2577
+ // clearErrors,
2578
+ },
2579
+ metaState: {
2580
+ dirty: fieldDirty.current,
2581
+ submitted: submitted.current,
2582
+ errors
1906
2583
  },
1907
2584
  symbolConfig: symbolInfo[symbol]()
1908
2585
  };
1909
- };
2586
+ }
1910
2587
 
1911
2588
  // src/orderly/useAccountInfo.ts
1912
2589
  var useAccountInfo = () => {
1913
2590
  return usePrivateQuery("/v1/client/info");
1914
2591
  };
1915
- var useMarketsStream = () => {
1916
- const ws = useWS();
1917
- const { data: futures } = useQuery(`/v1/public/futures`, {
1918
- revalidateOnFocus: false
1919
- });
1920
- const { data: tickers } = useSWRSubscription("tickers", (_, { next }) => {
1921
- const unsubscribe = ws.subscribe(
1922
- // { event: "subscribe", topic: "markprices" },
1923
- "tickers",
1924
- {
1925
- onMessage: (message) => {
1926
- next(null, message);
1927
- }
1928
- // onUnsubscribe: () => {
1929
- // return "markprices";
1930
- // },
1931
- // onError: (error: any) => {
1932
- //
1933
- // },
2592
+ var MarketsType = /* @__PURE__ */ ((MarketsType2) => {
2593
+ MarketsType2[MarketsType2["FAVORITES"] = 0] = "FAVORITES";
2594
+ MarketsType2[MarketsType2["RECENT"] = 1] = "RECENT";
2595
+ MarketsType2[MarketsType2["ALL"] = 2] = "ALL";
2596
+ return MarketsType2;
2597
+ })(MarketsType || {});
2598
+ var useMarkets = (type) => {
2599
+ const marketsKey = "markets";
2600
+ const { data } = useMarketsStream();
2601
+ const { configStore } = useContext(OrderlyContext);
2602
+ const publicInfo = useSymbolsInfo();
2603
+ if (!configStore.get(marketsKey)) {
2604
+ const jsonStr = localStorage.getItem(marketsKey);
2605
+ if (jsonStr) {
2606
+ configStore.set(marketsKey, JSON.parse(jsonStr));
2607
+ } else {
2608
+ const defaultTab = { name: "Popular", id: 1 };
2609
+ configStore.set(marketsKey, {
2610
+ recent: [],
2611
+ favorites: [
2612
+ { name: "PERP_ETH_USDC", tabs: [{ ...defaultTab }] },
2613
+ { name: "PERP_BTC_USDC", tabs: [{ ...defaultTab }] }
2614
+ ],
2615
+ favoriteTabs: [{ ...defaultTab }],
2616
+ lastSelectFavoriteTab: { ...defaultTab }
2617
+ });
2618
+ }
2619
+ }
2620
+ const getFavoriteTabs = useMemo(() => {
2621
+ const tabs2 = configStore.get(marketsKey)["favoriteTabs"];
2622
+ return tabs2 || [{ name: "Popular", id: 1 }];
2623
+ }, []);
2624
+ const getFavorites = useMemo(() => {
2625
+ const curData = configStore.get(marketsKey)["favorites"] || [];
2626
+ const tabs2 = getFavoriteTabs;
2627
+ const result = [];
2628
+ for (let index = 0; index < curData.length; index++) {
2629
+ const favData = curData[index];
2630
+ var favTabs = favData.tabs.filter((tab) => tabs2.findIndex((item) => tab.id === item.id) !== -1);
2631
+ if (favTabs.length > 0) {
2632
+ result.push({ ...favData, tabs: favTabs });
1934
2633
  }
1935
- );
1936
- return () => {
1937
- unsubscribe?.();
2634
+ }
2635
+ configStore.set(marketsKey, { ...configStore.getOr(marketsKey, {}), favorites: result });
2636
+ return result;
2637
+ }, [configStore]);
2638
+ const getRecent = useMemo(() => {
2639
+ const curData = configStore.get(marketsKey)["recent"];
2640
+ return (curData || []).filter((e) => e);
2641
+ }, []);
2642
+ const [favoriteTabs, setFavoriteTabs] = useState(getFavoriteTabs);
2643
+ const [favorites, setFavorites] = useState(getFavorites);
2644
+ const [recent, setRecent] = useState(getRecent);
2645
+ const updateFavoriteTabs = (tab, operator) => {
2646
+ const saveTabs = (tabs3) => {
2647
+ setFavoriteTabs(tabs3);
2648
+ configStore.set(marketsKey, {
2649
+ ...configStore.getOr(marketsKey, {}),
2650
+ "favoriteTabs": tabs3
2651
+ });
1938
2652
  };
1939
- });
1940
- const value = useMemo(() => {
1941
- if (!futures)
1942
- return null;
1943
- if (!tickers)
1944
- return futures;
1945
- return futures.map((item) => {
1946
- const ticker = tickers.find(
1947
- (t) => t.symbol === item.symbol
1948
- );
1949
- if (ticker) {
1950
- const data = {
1951
- ...item,
1952
- ["24h_close"]: ticker.close,
1953
- ["24h_open"]: ticker.open,
1954
- ["24h_volumn"]: ticker.volume,
1955
- change: 0
1956
- };
1957
- if (ticker.close !== void 0 && ticker.open !== void 0) {
1958
- data["change"] = new Decimal(ticker.close).minus(ticker.open).div(ticker.open).toNumber();
2653
+ if (Array.isArray(tab)) {
2654
+ saveTabs(tab);
2655
+ return;
2656
+ }
2657
+ var tabs2 = [...favoriteTabs];
2658
+ const index = tabs2.findIndex((item) => item.id === tab.id);
2659
+ if (operator?.add) {
2660
+ tabs2.push(tab);
2661
+ } else if (operator?.update) {
2662
+ if (index !== -1) {
2663
+ tabs2[index] = tab;
2664
+ }
2665
+ } else if (operator?.delete) {
2666
+ if (index !== -1) {
2667
+ tabs2.splice(index, 1);
2668
+ }
2669
+ }
2670
+ saveTabs(tabs2);
2671
+ };
2672
+ const setRecentData = (symbol) => {
2673
+ const curData = [...recent];
2674
+ const index = curData.findIndex((item) => item.name == symbol.symbol);
2675
+ if (index !== -1) {
2676
+ curData.splice(index, 1);
2677
+ }
2678
+ curData.unshift({ name: symbol.symbol });
2679
+ configStore.set(marketsKey, {
2680
+ ...configStore.getOr(marketsKey, {}),
2681
+ "recent": curData
2682
+ });
2683
+ setRecent(curData);
2684
+ };
2685
+ const setFavoritesData = (symbol, tab, remove = false) => {
2686
+ const curData = [...favorites];
2687
+ const index = curData.findIndex((item) => item.name == symbol.symbol);
2688
+ if (index === -1) {
2689
+ if (Array.isArray(tab)) {
2690
+ if (tab.length > 0) {
2691
+ curData.unshift({ name: symbol.symbol, tabs: tab });
2692
+ }
2693
+ } else {
2694
+ if (!remove) {
2695
+ curData.unshift({ name: symbol.symbol, tabs: [tab] });
1959
2696
  }
1960
- return data;
1961
2697
  }
1962
- return item;
2698
+ } else {
2699
+ const favorite = curData[index];
2700
+ if (Array.isArray(tab)) {
2701
+ if (tab.length === 0) {
2702
+ curData.splice(index, 1);
2703
+ } else {
2704
+ curData[index] = { ...favorite, tabs: tab };
2705
+ }
2706
+ } else {
2707
+ if (remove) {
2708
+ const tabs2 = favorite.tabs.filter((tab2) => tab2.id != tab2.id);
2709
+ if (tabs2.length === 0) {
2710
+ curData.splice(index, 1);
2711
+ } else {
2712
+ curData[index] = { ...favorite, tabs: tabs2 };
2713
+ }
2714
+ } else {
2715
+ const tabs2 = favorite.tabs;
2716
+ tabs2.push(tab);
2717
+ curData[index] = { ...favorite, tabs: tabs2 };
2718
+ }
2719
+ }
2720
+ }
2721
+ configStore.set(marketsKey, {
2722
+ ...configStore.getOr(marketsKey, {}),
2723
+ "favorites": curData
1963
2724
  });
1964
- }, [futures, tickers]);
1965
- return { data: value };
2725
+ setFavorites(() => curData);
2726
+ };
2727
+ const getData = (type2) => {
2728
+ const localData = type2 === 0 /* FAVORITES */ ? [...favorites] : [...recent];
2729
+ const keys = localData.map((item) => item.name);
2730
+ const filter = type2 == 2 /* ALL */ ? data : data?.filter((item) => keys.includes(item.symbol));
2731
+ const favoritesData = [...favorites];
2732
+ const favoriteKeys = favoritesData.map((item) => item.name);
2733
+ if (filter) {
2734
+ for (let index = 0; index < filter.length; index++) {
2735
+ const element = filter[index];
2736
+ const isFavorite = type2 == 0 /* FAVORITES */ ? true : favoriteKeys.includes(element.symbol);
2737
+ const fIndex = favoritesData.findIndex((item) => item.name === element.symbol);
2738
+ const tabs2 = fIndex === -1 ? [] : favoritesData[fIndex].tabs;
2739
+ let imr = void 0;
2740
+ if (publicInfo) {
2741
+ imr = publicInfo?.[element.symbol]("base_imr");
2742
+ }
2743
+ filter[index] = {
2744
+ ...filter[index],
2745
+ // @ts-ignore
2746
+ isFavorite,
2747
+ tabs: tabs2,
2748
+ leverage: imr ? 1 / imr : void 0
2749
+ };
2750
+ }
2751
+ }
2752
+ return filter;
2753
+ };
2754
+ const addToHistory = (symbol) => {
2755
+ setRecentData(symbol);
2756
+ };
2757
+ const updateSymbolFavoriteState = (symbol, tab, del = false) => {
2758
+ setFavoritesData(symbol, tab, del);
2759
+ };
2760
+ const markets = getData(type);
2761
+ const pinToTop = (symbol) => {
2762
+ const index = favorites.findIndex((item) => item.name === symbol.symbol);
2763
+ if (index !== -1) {
2764
+ const element = favorites[index];
2765
+ const list = [...favorites];
2766
+ list.splice(index, 1);
2767
+ list.unshift(element);
2768
+ configStore.set(marketsKey, {
2769
+ ...configStore.getOr(marketsKey, {}),
2770
+ "favorites": list
2771
+ });
2772
+ setFavorites(list);
2773
+ }
2774
+ };
2775
+ const tabs = useMemo(() => {
2776
+ return favoriteTabs;
2777
+ }, [favoriteTabs]);
2778
+ const getLastSelFavTab = () => {
2779
+ const curData = configStore.get(marketsKey)["lastSelectedFavoriteTab"];
2780
+ return curData || { name: "Popular", id: 1 };
2781
+ };
2782
+ const updateSelectedFavoriteTab = (tab) => {
2783
+ configStore.set(marketsKey, {
2784
+ ...configStore.getOr(marketsKey, {}),
2785
+ lastSelectedFavoriteTab: tab
2786
+ });
2787
+ };
2788
+ return [
2789
+ markets || [],
2790
+ {
2791
+ favoriteTabs: tabs,
2792
+ favorites,
2793
+ recent,
2794
+ addToHistory,
2795
+ // updateFavoriteTabs("tab", operator: {add/update/delete})
2796
+ updateFavoriteTabs,
2797
+ updateSymbolFavoriteState,
2798
+ pinToTop,
2799
+ getLastSelFavTab,
2800
+ updateSelectedFavoriteTab
2801
+ }
2802
+ ];
1966
2803
  };
1967
2804
  var useLeverage = () => {
1968
2805
  const { data, mutate: mutate2 } = usePrivateQuery("/v1/client/info");
@@ -2083,7 +2920,7 @@ var useMarketTradeStream = (symbol, options = {}) => {
2083
2920
  return { data: trades, isLoading };
2084
2921
  };
2085
2922
  var useMarginRatio = () => {
2086
- const [{ rows }] = usePositionStream();
2923
+ const [{ rows, aggregated }] = usePositionStream();
2087
2924
  const { data: markPrices } = useMarkPricesStream();
2088
2925
  const { totalCollateral } = useCollateral();
2089
2926
  const marginRatio = useMemo(() => {
@@ -2100,7 +2937,20 @@ var useMarginRatio = () => {
2100
2937
  const currentLeverage = useMemo(() => {
2101
2938
  return account.currentLeverage(marginRatio);
2102
2939
  }, [marginRatio]);
2103
- return { marginRatio, currentLeverage };
2940
+ const mmr = useMemo(() => {
2941
+ if (!rows || rows.length <= 0)
2942
+ return null;
2943
+ let positionsMM = zero;
2944
+ for (let index = 0; index < rows.length; index++) {
2945
+ const item = rows[index];
2946
+ positionsMM = positionsMM.add(item.mm);
2947
+ }
2948
+ return account.MMR({
2949
+ positionsMMR: positionsMM.toNumber(),
2950
+ positionsNotional: aggregated.notional
2951
+ });
2952
+ }, [rows, aggregated]);
2953
+ return { marginRatio, currentLeverage, mmr };
2104
2954
  };
2105
2955
 
2106
2956
  // src/woo/constants.ts
@@ -3116,53 +3966,41 @@ var woofiDexCrossChainRouterAbi = [
3116
3966
  ];
3117
3967
  var nativeTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
3118
3968
  var isNativeTokenChecker = (address) => address === nativeTokenAddress;
3119
-
3120
- // src/orderly/useChains.ts
3121
3969
  var useChains = (networkId, options = {}) => {
3122
- const { filter, pick: pick3, crossEnabled, wooSwapEnabled, ...swrOptions } = options;
3123
- const { configStore, networkId: networkEnv } = useContext(OrderlyContext);
3970
+ const { pick: pick3, crossEnabled, wooSwapEnabled, ...swrOptions } = options;
3971
+ const { configStore } = useContext(OrderlyContext);
3124
3972
  const field = options?.pick;
3973
+ const filterFun = useRef(options?.filter);
3974
+ filterFun.current = options?.filter;
3125
3975
  const map = useRef(
3126
3976
  /* @__PURE__ */ new Map()
3127
3977
  );
3128
- const { data, error: swapSupportError } = useSWR(
3978
+ const commonSwrOpts = {
3979
+ revalidateIfStale: false,
3980
+ revalidateOnFocus: false,
3981
+ revalidateOnReconnect: false,
3982
+ // If false, undefined data gets cached against the key.
3983
+ revalidateOnMount: true,
3984
+ // dont duplicate a request w/ same key for 1hr
3985
+ dedupingInterval: 36e5,
3986
+ ...swrOptions
3987
+ };
3988
+ const { data: wooSupportData, error: swapSupportError } = useSWR(
3129
3989
  () => wooSwapEnabled ? `${configStore.get("swapSupportApiUrl")}/swap_support` : null,
3130
- // `${configStore.get("swapSupportApiUrl")}/swap_support`,
3131
3990
  (url) => fetch(url).then((res) => res.json()),
3132
- {
3133
- revalidateIfStale: false,
3134
- revalidateOnFocus: false,
3135
- revalidateOnReconnect: false,
3136
- revalidateOnMount: true,
3137
- // If false, undefined data gets cached against the key.
3138
- dedupingInterval: 36e5,
3139
- // dont duplicate a request w/ same key for 1hr
3140
- ...swrOptions
3141
- }
3991
+ { ...commonSwrOpts, ...swrOptions }
3142
3992
  );
3143
3993
  const { data: chainInfos, error: chainInfoErr } = useQuery(
3144
3994
  "/v1/public/chain_info",
3145
3995
  {
3146
- revalidateIfStale: false,
3147
- revalidateOnFocus: false,
3148
- revalidateOnReconnect: false,
3149
- revalidateOnMount: true,
3150
- dedupingInterval: 36e5,
3151
- formatter: (data2) => data2.rows
3996
+ ...commonSwrOpts,
3997
+ formatter: (data) => data.rows
3152
3998
  }
3153
3999
  );
3154
4000
  const { data: orderlyChains, error: tokenError } = useQuery(
3155
- // wooSwapEnabled ? "/v1/public/token" :
3156
4001
  "https://api-evm.orderly.org/v1/public/token",
3157
- {
3158
- revalidateIfStale: false,
3159
- revalidateOnFocus: false,
3160
- revalidateOnReconnect: false,
3161
- revalidateOnMount: true,
3162
- dedupingInterval: 36e5
3163
- }
4002
+ { ...commonSwrOpts }
3164
4003
  );
3165
- configStore.get("apiBaseUrl");
3166
4004
  const chains = useMemo(() => {
3167
4005
  let orderlyChainsArr = [];
3168
4006
  const orderlyChainIds = /* @__PURE__ */ new Set();
@@ -3177,6 +4015,7 @@ var useChains = (networkId, options = {}) => {
3177
4015
  // "public_rpc_url": "https://arb1.arbitrum.io/rpc",
3178
4016
  chain_id: chainId,
3179
4017
  withdrawal_fee: chain.withdrawal_fee,
4018
+ cross_chain_withdrawal_fee: chain.cross_chain_withdrawal_fee,
3180
4019
  bridgeless: true
3181
4020
  },
3182
4021
  token_infos: [
@@ -3187,13 +4026,13 @@ var useChains = (networkId, options = {}) => {
3187
4026
  }
3188
4027
  ]
3189
4028
  };
3190
- if (typeof options?.filter === "function") {
3191
- if (!options.filter(_chain))
4029
+ if (typeof filterFun.current === "function") {
4030
+ if (!filterFun.current(_chain))
3192
4031
  return;
3193
4032
  }
3194
- if (_chain.chain_id === 421613) {
3195
- const index = testnetArr.findIndex(
3196
- (item2) => item2.network_infos.chain_id === 421613
4033
+ if (isTestnet(_chain.chain_id)) {
4034
+ const index = testnetArr?.findIndex(
4035
+ (item2) => isTestnet(item2.network_infos.chain_id)
3197
4036
  );
3198
4037
  if (index > -1) {
3199
4038
  testnetArr[index] = _chain;
@@ -3203,40 +4042,16 @@ var useChains = (networkId, options = {}) => {
3203
4042
  orderlyChainsArr.push(_chain);
3204
4043
  });
3205
4044
  });
3206
- let testnetArr = [
3207
- //@ts-ignore
3208
- {
3209
- network_infos: {
3210
- name: "Arbitrum Goerli",
3211
- shortName: "Arbitrum Goerli",
3212
- public_rpc_url: "https://goerli-rollup.arbitrum.io/rpc",
3213
- chain_id: 421613,
3214
- currency_symbol: "ETH",
3215
- bridge_enable: true,
3216
- mainnet: false,
3217
- explorer_base_url: "https://goerli.arbiscan.io/",
3218
- est_txn_mins: null,
3219
- woofi_dex_cross_chain_router: "",
3220
- woofi_dex_depositor: ""
3221
- },
3222
- token_infos: [
3223
- {
3224
- symbol: "USDC",
3225
- address: "0xfd064A18f3BF249cf1f87FC203E90D8f650f2d63",
3226
- decimals: 6,
3227
- swap_enable: false,
3228
- woofi_dex_precision: 2
3229
- }
3230
- ]
3231
- }
3232
- ];
4045
+ let testnetArr = [...TestnetChains];
4046
+ testnetArr.forEach((chain) => {
4047
+ map.current.set(chain.network_infos?.chain_id, chain);
4048
+ });
3233
4049
  let mainnetArr = [];
3234
- map.current.set(421613, testnetArr[0]);
3235
4050
  if (wooSwapEnabled) {
3236
- if (!data || !data.data)
3237
- return data;
3238
- Object.keys(data.data).forEach((key) => {
3239
- const chain = data.data[key];
4051
+ if (!wooSupportData || !wooSupportData.data)
4052
+ return wooSupportData;
4053
+ Object.keys(wooSupportData.data).forEach((key) => {
4054
+ const chain = wooSupportData.data[key];
3240
4055
  const item = mergeDeepRight(chain, {
3241
4056
  name: key,
3242
4057
  network_infos: {
@@ -3250,8 +4065,8 @@ var useChains = (networkId, options = {}) => {
3250
4065
  if (item.token_infos?.length === 0)
3251
4066
  return;
3252
4067
  map.current.set(item.network_infos.chain_id, item);
3253
- if (typeof options?.filter === "function") {
3254
- if (!options.filter(item))
4068
+ if (typeof filterFun.current === "function") {
4069
+ if (!filterFun.current(item))
3255
4070
  return;
3256
4071
  }
3257
4072
  if (item.network_infos.mainnet) {
@@ -3289,24 +4104,16 @@ var useChains = (networkId, options = {}) => {
3289
4104
  };
3290
4105
  }
3291
4106
  map.current.set(_chain.network_infos.chain_id, _chain);
3292
- if (_chain.network_infos.chain_id === 421613) {
4107
+ if (isTestnet(_chain.network_infos.chain_id)) {
3293
4108
  const index = testnetArr.findIndex(
3294
- (item) => item.network_infos.chain_id === 421613
4109
+ (item) => isTestnet(item.network_infos.chain_id)
3295
4110
  );
3296
4111
  if (index > -1) {
3297
4112
  testnetArr[index] = _chain;
3298
4113
  }
3299
4114
  }
3300
- if (_chain.network_infos.chain_id === 420) {
3301
- const index = testnetArr.findIndex(
3302
- (item) => item.network_infos.chain_id === 420
3303
- );
3304
- if (index > -1) {
3305
- testnetArr[index] = _chain;
3306
- }
3307
- }
3308
- if (typeof options?.filter === "function") {
3309
- if (!options.filter(_chain))
4115
+ if (typeof filterFun.current === "function") {
4116
+ if (!filterFun.current(_chain))
3310
4117
  return;
3311
4118
  }
3312
4119
  mainnetArr.push(_chain);
@@ -3333,10 +4140,9 @@ var useChains = (networkId, options = {}) => {
3333
4140
  mainnet: mainnetArr
3334
4141
  };
3335
4142
  }, [
3336
- data,
4143
+ wooSupportData,
3337
4144
  networkId,
3338
4145
  field,
3339
- options,
3340
4146
  orderlyChains,
3341
4147
  wooSwapEnabled,
3342
4148
  chainInfos
@@ -3347,7 +4153,9 @@ var useChains = (networkId, options = {}) => {
3347
4153
  if (chain) {
3348
4154
  chain.nativeToken = chain.token_infos?.find(
3349
4155
  (item) => item.address === nativeTokenAddress
3350
- );
4156
+ ) || {
4157
+ symbol: chain.network_infos?.currency_symbol
4158
+ };
3351
4159
  }
3352
4160
  if (typeof field2 === "string") {
3353
4161
  return prop(field2, chain);
@@ -3401,7 +4209,21 @@ var useWithdraw = () => {
3401
4209
  const maxAmount = useMemo(() => {
3402
4210
  return freeCollateral;
3403
4211
  }, [freeCollateral]);
3404
- return { withdraw, isLoading, maxAmount, availableBalance, unsettledPnL };
4212
+ const availableWithdraw = useMemo(() => {
4213
+ if (unsettledPnL < 0) {
4214
+ return freeCollateral;
4215
+ } else {
4216
+ return freeCollateral - unsettledPnL;
4217
+ }
4218
+ }, [freeCollateral, unsettledPnL]);
4219
+ return {
4220
+ withdraw,
4221
+ isLoading,
4222
+ maxAmount,
4223
+ availableBalance,
4224
+ availableWithdraw,
4225
+ unsettledPnL
4226
+ };
3405
4227
  };
3406
4228
  var useDeposit = (options) => {
3407
4229
  const { enableSwapDeposit } = useContext(OrderlyContext);
@@ -3411,28 +4233,41 @@ var useDeposit = (options) => {
3411
4233
  const [_, { findByChainId }] = useChains(void 0, {
3412
4234
  wooSwapEnabled: enableSwapDeposit
3413
4235
  });
4236
+ const [quantity, setQuantity] = useState("");
4237
+ const [depositFee, setDepositFee] = useState(0n);
4238
+ const [depositFeeRevalidating, setDepositFeeRevalidating] = useState(false);
3414
4239
  const [balance, setBalance] = useState("0");
3415
4240
  const [allowance, setAllowance] = useState("0");
3416
4241
  const { account: account5, state } = useAccount();
3417
4242
  const prevAddress = useRef();
3418
4243
  const getBalanceListener = useRef();
4244
+ const targetChain = useMemo(() => {
4245
+ let chain;
4246
+ if (networkId === "testnet") {
4247
+ chain = findByChainId(ARBITRUM_TESTNET_CHAINID);
4248
+ } else {
4249
+ chain = findByChainId(options?.srcChainId);
4250
+ if (!chain?.network_infos?.bridgeless) {
4251
+ chain = findByChainId(ARBITRUM_MAINNET_CHAINID);
4252
+ }
4253
+ }
4254
+ return chain;
4255
+ }, [networkId, findByChainId, options?.srcChainId]);
3419
4256
  const dst = useMemo(() => {
3420
- const chain = networkId === "testnet" ? findByChainId(ARBITRUM_TESTNET_CHAINID) : findByChainId(ARBITRUM_MAINNET_CHAINID);
3421
- const USDC = chain?.token_infos.find(
3422
- (token) => token.symbol === "USDC"
3423
- );
3424
- if (!chain) {
4257
+ if (!targetChain) {
3425
4258
  throw new Error("dst chain not found");
3426
4259
  }
4260
+ const USDC = targetChain?.token_infos.find(
4261
+ (token) => token.symbol === "USDC"
4262
+ );
3427
4263
  return {
3428
4264
  symbol: "USDC",
3429
4265
  address: USDC?.address,
3430
4266
  decimals: USDC?.decimals,
3431
- chainId: chain.network_infos.chain_id,
3432
- network: chain.network_infos.shortName
3433
- // chainId: 42161,
4267
+ chainId: targetChain.network_infos.chain_id,
4268
+ network: targetChain.network_infos.shortName
3434
4269
  };
3435
- }, [networkId, findByChainId]);
4270
+ }, [targetChain]);
3436
4271
  const isNativeToken = useMemo(
3437
4272
  () => isNativeTokenChecker(options?.address || ""),
3438
4273
  [options?.address]
@@ -3459,7 +4294,6 @@ var useDeposit = (options) => {
3459
4294
  const balance2 = await fetchBalanceHandler(address, decimals);
3460
4295
  setBalance(() => balance2);
3461
4296
  } catch (e) {
3462
- console.warn("----- refresh balance error -----", e);
3463
4297
  setBalance(() => "0");
3464
4298
  }
3465
4299
  },
@@ -3509,18 +4343,30 @@ var useDeposit = (options) => {
3509
4343
  }
3510
4344
  }
3511
4345
  }, [options, dst]);
4346
+ const queryBalance = useDebouncedCallback(
4347
+ (tokenAddress, decimals) => {
4348
+ fetchBalance(options?.address, options?.decimals).finally(() => {
4349
+ setBalanceRevalidating(false);
4350
+ });
4351
+ },
4352
+ 100
4353
+ );
4354
+ const queryAllowance = useDebouncedCallback(
4355
+ (tokenAddress, vaultAddress) => {
4356
+ getAllowance(tokenAddress, vaultAddress);
4357
+ },
4358
+ 100
4359
+ );
3512
4360
  useEffect(() => {
3513
4361
  if (state.status < AccountStatusEnum.Connected)
3514
4362
  return;
3515
4363
  setBalanceRevalidating(true);
3516
- fetchBalance(options?.address, options?.decimals).finally(() => {
3517
- setBalanceRevalidating(false);
3518
- });
4364
+ queryBalance(options?.address, options?.decimals);
3519
4365
  if (dst.chainId !== options?.srcChainId) {
3520
- getAllowance(options?.address, options?.crossChainRouteAddress);
4366
+ queryAllowance(options?.address, options?.crossChainRouteAddress);
3521
4367
  } else {
3522
4368
  if (dst.symbol !== options?.srcToken) {
3523
- getAllowance(options?.address, options?.depositorAddress);
4369
+ queryAllowance(options?.address, options?.depositorAddress);
3524
4370
  } else {
3525
4371
  getAllowanceByDefaultAddress(options?.address);
3526
4372
  }
@@ -3537,41 +4383,72 @@ var useDeposit = (options) => {
3537
4383
  dst.symbol
3538
4384
  ]);
3539
4385
  const approve = useCallback(
3540
- (amount) => {
4386
+ async (amount) => {
3541
4387
  if (!options?.address) {
3542
4388
  throw new Error("address is required");
3543
4389
  }
3544
4390
  const vaultAddress = getVaultAddress();
3545
4391
  return account5.assetsManager.approve(options.address, amount, vaultAddress).then((result) => {
3546
4392
  if (typeof amount !== "undefined") {
3547
- setAllowance((value) => new Decimal(value).add(amount).toString());
4393
+ setAllowance(
4394
+ (value) => new Decimal(value).add(amount || MaxUint256.toString()).toString()
4395
+ );
3548
4396
  }
3549
4397
  return result;
3550
4398
  });
3551
4399
  },
3552
4400
  [account5, getAllowance, options?.address]
3553
4401
  );
3554
- const deposit = useCallback(
3555
- (amount) => {
3556
- return account5.assetsManager.deposit(amount).then((res) => {
3557
- setAllowance((value) => new Decimal(value).sub(amount).toString());
3558
- setBalance((value) => new Decimal(value).sub(amount).toString());
3559
- return res;
3560
- });
3561
- },
3562
- [account5, fetchBalance, getAllowance]
3563
- );
4402
+ const deposit = useCallback(async () => {
4403
+ return account5.assetsManager.deposit(quantity, depositFee).then((res) => {
4404
+ setAllowance((value) => new Decimal(value).sub(quantity).toString());
4405
+ setBalance((value) => new Decimal(value).sub(quantity).toString());
4406
+ return res;
4407
+ });
4408
+ }, [account5, fetchBalance, getAllowance, quantity, depositFee]);
3564
4409
  const loopGetBalance = async () => {
3565
4410
  getBalanceListener.current && clearTimeout(getBalanceListener.current);
3566
4411
  getBalanceListener.current = setTimeout(async () => {
3567
- const balance2 = await fetchBalanceHandler(
3568
- options?.address,
3569
- options?.decimals
3570
- );
3571
- setBalance(balance2);
3572
- loopGetBalance();
4412
+ try {
4413
+ const balance2 = await fetchBalanceHandler(
4414
+ options?.address,
4415
+ options?.decimals
4416
+ );
4417
+ setBalance(balance2);
4418
+ loopGetBalance();
4419
+ } catch (err) {
4420
+ }
3573
4421
  }, 3e3);
3574
4422
  };
4423
+ const getDepositFee = useCallback(
4424
+ async (quantity2) => {
4425
+ return account5.assetsManager.getDepositFee(
4426
+ quantity2,
4427
+ targetChain?.network_infos
4428
+ );
4429
+ },
4430
+ [account5, targetChain]
4431
+ );
4432
+ const enquiryDepositFee = useCallback(() => {
4433
+ if (isNaN(Number(quantity)) || !quantity) {
4434
+ setDepositFee(0n);
4435
+ setDepositFeeRevalidating(false);
4436
+ return;
4437
+ }
4438
+ setDepositFeeRevalidating(true);
4439
+ getDepositFee(quantity).then((res = 0n) => {
4440
+ const fee = BigInt(
4441
+ new Decimal(res.toString()).mul(DEPOSIT_FEE_RATE).toFixed(0, Decimal.ROUND_UP).toString()
4442
+ );
4443
+ setDepositFee(fee);
4444
+ }).catch((error) => {
4445
+ }).finally(() => {
4446
+ setDepositFeeRevalidating(false);
4447
+ });
4448
+ }, [quantity]);
4449
+ useEffect(() => {
4450
+ enquiryDepositFee();
4451
+ }, [quantity]);
3575
4452
  useEffect(() => {
3576
4453
  if (!options?.address) {
3577
4454
  return;
@@ -3582,16 +4459,25 @@ var useDeposit = (options) => {
3582
4459
  };
3583
4460
  }, [options?.address, options?.decimals]);
3584
4461
  return {
4462
+ /** orderly support chain dst */
3585
4463
  dst,
3586
4464
  balance,
3587
4465
  allowance,
3588
4466
  isNativeToken,
3589
4467
  balanceRevalidating,
3590
4468
  allowanceRevalidating,
4469
+ /** input quantiy */
4470
+ quantity,
4471
+ /** orderly deposit fee, unit: wei */
4472
+ depositFee,
4473
+ /** enquiring depositFee status on chain */
4474
+ depositFeeRevalidating,
3591
4475
  approve,
3592
4476
  deposit,
3593
4477
  fetchBalances,
3594
- fetchBalance: fetchBalanceHandler
4478
+ fetchBalance: fetchBalanceHandler,
4479
+ /** set input quantity */
4480
+ setQuantity
3595
4481
  };
3596
4482
  };
3597
4483
  var useWalletSubscription = (options) => {
@@ -3634,6 +4520,32 @@ var useSettleSubscription = (options) => {
3634
4520
  return () => unsubscribe();
3635
4521
  });
3636
4522
  };
4523
+ var useSymbolPriceRange = (symbol, side, price) => {
4524
+ const config = useSymbolsInfo();
4525
+ const priceRange = config?.[symbol]("price_range");
4526
+ const priceScrope = config?.[symbol]("price_scope");
4527
+ const { data: prices } = useMarkPricesStream();
4528
+ const markPrice = price || prices?.[symbol];
4529
+ const range = useMemo(() => {
4530
+ if (config === void 0 || markPrice === void 0) {
4531
+ return void 0;
4532
+ }
4533
+ if (priceRange === void 0 || Number.isNaN(markPrice)) {
4534
+ return void 0;
4535
+ }
4536
+ if (side === "BUY") {
4537
+ return {
4538
+ max: new Decimal(markPrice).mul(1 + priceRange).toNumber(),
4539
+ min: new Decimal(markPrice).mul(1 - priceScrope).toNumber()
4540
+ };
4541
+ }
4542
+ return {
4543
+ max: new Decimal(markPrice).mul(1 + priceScrope).toNumber(),
4544
+ min: new Decimal(markPrice).mul(1 - priceRange).toNumber()
4545
+ };
4546
+ }, [symbol, side, priceRange, markPrice]);
4547
+ return range;
4548
+ };
3637
4549
  function useMediaQuery(query) {
3638
4550
  const getMatches = (query2) => {
3639
4551
  if (typeof window !== "undefined") {
@@ -3673,8 +4585,8 @@ var useWooSwapQuery = () => {
3673
4585
  return;
3674
4586
  start();
3675
4587
  const params = {
3676
- // src_network: inputs.srcNetwork,
3677
- network: "arbitrum",
4588
+ network: inputs.srcNetwork,
4589
+ // network: "arbitrum",
3678
4590
  from_token: inputs.srcToken,
3679
4591
  to_token: inputs.dstToken,
3680
4592
  //account.assetsManager.usdcAddress,
@@ -4265,6 +5177,6 @@ var useSwap = () => {
4265
5177
  };
4266
5178
  };
4267
5179
 
4268
- export { OrderlyConfigProvider, OrderlyContext, OrderlyProvider, WalletConnectorContext, useAccount, useAccountInfo, useAccountInstance, useBoolean, useChain, useChains, useCollateral, useConfig, useCrossSwap, useDeposit, useEventEmitter, useFundingRate, useHoldingStream, useIndexPrice, useLazyQuery, useLeverage, useLocalStorage, useMarginRatio, useMarkPrice, useMarkPricesStream, useMarketTradeStream, useMarketsStream, useMaxQty, useMediaQuery, useMutation, useOrderEntry, useOrderStream, useOrderbookStream, usePositionStream, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useSessionStorage, useSettleSubscription, useSwap, useSymbolsInfo, useTickerStream, useWS, useWalletConnector, useWalletSubscription, useWithdraw, useWooCrossSwapQuery, useWooSwapQuery, version_default as version };
5180
+ export { MarketsType, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, WalletConnectorContext, useAccount, useAccountInfo, useAccountInstance, useBoolean, useChain, useChains, useCollateral, useConfig, useCrossSwap, useDeposit, useEventEmitter, useFundingRate, useHoldingStream, useIndexPrice, useLazyQuery, useLeverage, useLocalStorage, useMarginRatio, useMarkPrice, useMarkPricesStream, useMarketTradeStream, useMarkets, useMarketsStream, useMaxQty, useMediaQuery, useMutation, useOrderEntry, useOrderStream, useOrderbookStream, usePositionStream, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useSessionStorage, useSettleSubscription, useSwap, useSymbolPriceRange, useSymbolsInfo, useTickerStream, useWS, useWalletConnector, useWalletSubscription, useWithdraw, useWooCrossSwapQuery, useWooSwapQuery, version_default as version };
4269
5181
  //# sourceMappingURL=out.js.map
4270
5182
  //# sourceMappingURL=index.mjs.map