@orderly.network/ui-order-entry 3.1.12 → 3.2.0-alpha.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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import React3, { memo, forwardRef, useState, useImperativeHandle, useEffect, createContext, useMemo, useRef, useCallback, useContext, useId } from 'react';
2
- import { useLocalStorage, utils, useGetEstLiqPrice, useOrderlyContext, useMemoizedFn, ERROR_MSG_CODES, usePositionStream, useFeeState, useRwaSymbolsInfoStore, useMarkets, MarketsType, useMarginModes, useMarginModeBySymbol, useBadgeBySymbol, useEventEmitter, useDebouncedCallback, useHoldingStream, useAppStore, useIndexPricesStream, useComputedLTV, useBoolean, useFeatureFlag, FlagKeys, useQuery, useAccount, useOrderEntry, useMarginRatio, useTpslPriceChecker, useTrack } from '@orderly.network/hooks';
2
+ import { useLocalStorage, utils, useGetEstLiqPrice, useOrderlyContext, useMemoizedFn, ERROR_MSG_CODES, USDCBorrowLimitExceededError, usePositionStream, useFeeState, useRwaSymbolsInfoStore, useMarkets, MarketsType, useMarginModes, useMarginModeBySymbol, useBadgeBySymbol, useEventEmitter, useDebouncedCallback, useHoldingStream, useConvertThreshold, useAppStore, useIndexPricesStream, useComputedLTV, useBoolean, useFeatureFlag, FlagKeys, useAccount, useOrderEntry, useMarginRatio, normalizeUSDCBorrowLimit, useTpslPriceChecker, useTrack } from '@orderly.network/hooks';
3
3
  import { i18n, useTranslation, Trans } from '@orderly.network/i18n';
4
4
  import { useOrderEntryFormErrorMsg, useCanTrade } from '@orderly.network/react-app';
5
5
  import { OrderSide, EMPTY_LIST, DistributionType, TrailingCallbackType, OrderType, MarginMode, PositionType, BBOOrderType, ORDER_ENTRY_EST_LIQ_PRICE_CHANGE, OrderLevel, TrackerEventName } from '@orderly.network/types';
@@ -605,9 +605,9 @@ var OrderConfirmDialog = (props) => {
605
605
  const { t } = useTranslation();
606
606
  const [{ rows: positions }] = usePositionStream(symbol);
607
607
  const position = useMemo(
608
- () => orderMarginMode != null ? positions?.find(
609
- (row) => row.symbol === symbol && row.margin_mode === orderMarginMode
610
- ) : positions?.[0],
608
+ () => positions?.find(
609
+ (row) => row.symbol === symbol && (row.margin_mode ?? MarginMode.CROSS) === (orderMarginMode ?? MarginMode.CROSS)
610
+ ),
611
611
  [positions, symbol, orderMarginMode]
612
612
  );
613
613
  const positionQty = position?.position_qty;
@@ -680,15 +680,17 @@ var OrderConfirmDialog = (props) => {
680
680
  );
681
681
  };
682
682
  const renderTPSLQty = () => {
683
+ if (order.position_type === PositionType.FULL)
684
+ return /* @__PURE__ */ jsxs(Flex, { justify: "between", children: [
685
+ /* @__PURE__ */ jsx(Text, { children: t("common.orderQty") }),
686
+ /* @__PURE__ */ jsx(Text, { children: t("tpsl.entirePosition") })
687
+ ] });
683
688
  if (!positionQty || !order.order_quantity) {
684
689
  return null;
685
690
  }
686
- let qty = new Decimal(order.order_quantity);
687
- if (order.position_type === PositionType.FULL) {
688
- qty = qty.plus(new Decimal(positionQty ?? 0));
689
- }
691
+ const qty = new Decimal(order.order_quantity);
690
692
  return /* @__PURE__ */ jsxs(Flex, { justify: "between", children: [
691
- /* @__PURE__ */ jsx(Text, { children: order.position_type === PositionType.FULL ? t("common.positionQty") : t("common.orderQty") }),
693
+ /* @__PURE__ */ jsx(Text, { children: t("common.orderQty") }),
692
694
  /* @__PURE__ */ jsx(
693
695
  Text.numeral,
694
696
  {
@@ -1907,18 +1909,6 @@ var LTVRiskTooltipUI = (props) => {
1907
1909
  }
1908
1910
  );
1909
1911
  };
1910
- var useConvertThreshold = () => {
1911
- const { data, error, isLoading } = useQuery(
1912
- "/v1/public/auto_convert_threshold",
1913
- { errorRetryCount: 3 }
1914
- );
1915
- return {
1916
- ltv_threshold: new Decimal(data?.ltv_threshold ?? 0).mul(100).toNumber(),
1917
- negative_usdc_threshold: data?.negative_usdc_threshold,
1918
- isLoading,
1919
- error
1920
- };
1921
- };
1922
1912
  var useLTVTooltipScript = (marginMode) => {
1923
1913
  const { isMobile } = useScreen();
1924
1914
  const { data: holdingList = [], isLoading: isHoldingLoading } = useHoldingStream();
@@ -1927,6 +1917,7 @@ var useLTVTooltipScript = (marginMode) => {
1927
1917
  negative_usdc_threshold,
1928
1918
  isLoading: isThresholdLoading
1929
1919
  } = useConvertThreshold();
1920
+ const ltvThresholdPercentage = new Decimal(ltv_threshold ?? 0).mul(100).toNumber();
1930
1921
  const tokensInfo = useAppStore((state) => state.tokensInfo);
1931
1922
  const { getIndexPrice } = useIndexPricesStream();
1932
1923
  const holdingData = holdingList.map((item) => {
@@ -1957,7 +1948,7 @@ var useLTVTooltipScript = (marginMode) => {
1957
1948
  return {
1958
1949
  holdingData,
1959
1950
  isHoldingLoading,
1960
- ltv_threshold,
1951
+ ltv_threshold: ltvThresholdPercentage,
1961
1952
  negative_usdc_threshold,
1962
1953
  isThresholdLoading,
1963
1954
  currentLtv,
@@ -3357,6 +3348,7 @@ var LeverageBadge = (props) => {
3357
3348
  const { enabled } = useFeatureFlag(FlagKeys.IsolatedMargin);
3358
3349
  const marginMode = props.marginMode;
3359
3350
  const isDisabled = !!disabled;
3351
+ const isMarginModeDisabled = isDisabled || !enabled;
3360
3352
  const curLeverage = symbolLeverage ?? 1;
3361
3353
  const showLeverageModal = () => {
3362
3354
  if (isDisabled) return;
@@ -3369,7 +3361,7 @@ var LeverageBadge = (props) => {
3369
3361
  });
3370
3362
  };
3371
3363
  const showMarginModeModal = () => {
3372
- if (isDisabled || !enabled) {
3364
+ if (isMarginModeDisabled) {
3373
3365
  return;
3374
3366
  }
3375
3367
  const modalId = isMobile ? MarginModeSwitchSheetId : MarginModeSwitchDialogId;
@@ -3396,11 +3388,11 @@ var LeverageBadge = (props) => {
3396
3388
  "oui-flex oui-flex-1 oui-items-center oui-justify-center oui-gap-x-1",
3397
3389
  "oui-px-3 oui-py-1.5",
3398
3390
  "oui-text-xs oui-font-semibold oui-text-base-contrast-54",
3399
- isDisabled ? "oui-cursor-not-allowed" : "oui-cursor-pointer"
3391
+ isMarginModeDisabled ? "oui-cursor-not-allowed" : "oui-cursor-pointer"
3400
3392
  ),
3401
3393
  "data-testid": "oui-testid-orderEntry-margin-mode",
3402
3394
  "aria-label": t("marginMode.switchMarginMode"),
3403
- disabled: isDisabled,
3395
+ disabled: isMarginModeDisabled,
3404
3396
  onClick: showMarginModeModal,
3405
3397
  children: /* @__PURE__ */ jsx(Text, { children: marginMode === void 0 ? "--" : marginMode === MarginMode.ISOLATED ? t("marginMode.isolated") : t("marginMode.cross") })
3406
3398
  }
@@ -5694,7 +5686,8 @@ var OrderEntry = (props) => {
5694
5686
  currentFocusInput,
5695
5687
  walletAddress,
5696
5688
  isPermissionlessListing,
5697
- symbol
5689
+ symbol,
5690
+ usdcBorrowLimit
5698
5691
  } = props;
5699
5692
  const [maxQtyConfirmOpen, setMaxQtyConfirmOpen] = useState(false);
5700
5693
  const [selectedExtraId, setSelectedExtraId] = useState(null);
@@ -5778,6 +5771,15 @@ var OrderEntry = (props) => {
5778
5771
  return Promise.reject();
5779
5772
  }
5780
5773
  ).then((order) => {
5774
+ const projectedBorrow = helper.getProjectedUSDCBorrow(order);
5775
+ if (projectedBorrow !== null && projectedBorrow > usdcBorrowLimit) {
5776
+ throw new USDCBorrowLimitExceededError(
5777
+ projectedBorrow,
5778
+ usdcBorrowLimit
5779
+ );
5780
+ }
5781
+ return order;
5782
+ }).then((order) => {
5781
5783
  const shouldShowPermissionlessNotice = isPermissionlessListing && walletAddress && !(permissionlessAcknowledgedKeys ?? []).includes(
5782
5784
  `${walletAddress}_${symbol}`
5783
5785
  );
@@ -5809,7 +5811,10 @@ var OrderEntry = (props) => {
5809
5811
  }
5810
5812
  return true;
5811
5813
  }).then(() => {
5812
- return submit({ resetOnSuccess: false }).then((result) => {
5814
+ return submit({
5815
+ resetOnSuccess: false,
5816
+ usdcBorrowLimit
5817
+ }).then((result) => {
5813
5818
  if (!result.success && result.message) {
5814
5819
  toast.error(result.message);
5815
5820
  } else if (result.success && isScaledOrder) {
@@ -5820,6 +5825,17 @@ var OrderEntry = (props) => {
5820
5825
  }
5821
5826
  });
5822
5827
  }).catch((error) => {
5828
+ if (error instanceof USDCBorrowLimitExceededError) {
5829
+ modal.alert({
5830
+ title: t("orderEntry.usdcBorrowLimit.title"),
5831
+ message: t("orderEntry.usdcBorrowLimit.content", {
5832
+ limit: new Intl.NumberFormat("en-US", {
5833
+ maximumFractionDigits: 8
5834
+ }).format(error.borrowLimit)
5835
+ })
5836
+ });
5837
+ return;
5838
+ }
5823
5839
  if (error?.message) {
5824
5840
  toast.error(error.message);
5825
5841
  }
@@ -6610,6 +6626,8 @@ var useOrderEntryScript = (inputs) => {
6610
6626
  }
6611
6627
  }, [isSymbolPostOnly, formattedOrder.order_type, setOrderValues]);
6612
6628
  const currentLtv = useComputedLTV();
6629
+ const { negative_usdc_threshold } = useConvertThreshold();
6630
+ const usdcBorrowLimit = normalizeUSDCBorrowLimit(negative_usdc_threshold);
6613
6631
  const askAndBid = useAskAndBid();
6614
6632
  const fillMiddleValue = () => {
6615
6633
  if (bboStatus === "on" /* ON */) {
@@ -6706,6 +6724,7 @@ var useOrderEntryScript = (inputs) => {
6706
6724
  onBBOChange,
6707
6725
  toggleBBO,
6708
6726
  currentLtv,
6727
+ usdcBorrowLimit,
6709
6728
  fillMiddleValue,
6710
6729
  symbol,
6711
6730
  soundAlert,