@orderly.network/ui-transfer 2.8.8-alpha.0 → 2.8.9-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 { useTranslation, i18n, Trans } from '@orderly.network/i18n';
2
- import { modal, useScreen, useModal, SimpleSheet, SimpleDialog, registerSimpleDialog, registerSimpleSheet, Tabs, TabPanel, ArrowDownSquareFillIcon, ArrowUpSquareFillIcon, toast, Box, ExtensionSlot, ExtensionPositionEnum, textVariants, Flex, Text, Button, cn, Divider, Spinner, Select, Input, inputFormatter, Tooltip, AlertDialog, EditIcon, Icon, TokenIcon, ArrowLeftRightIcon, WalletIcon, DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuPortal, DropdownMenuContent, ScrollArea, CloseCircleFillIcon, CheckedCircleFillIcon, ChainIcon, Badge, CaretDownIcon, InfoCircleIcon, ExclamationFillIcon, CloseIcon } from '@orderly.network/ui';
2
+ import { modal, useScreen, useModal, SimpleSheet, SimpleDialog, registerSimpleDialog, registerSimpleSheet, Tabs, TabPanel, ArrowDownSquareFillIcon, ArrowUpSquareFillIcon, toast, Box, ExtensionSlot, ExtensionPositionEnum, textVariants, Flex, Text, Button, cn, Divider, Spinner, Select, Input, inputFormatter, Tooltip, AlertDialog, EditIcon, Icon, TokenIcon, ArrowLeftRightIcon, WalletIcon, DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuPortal, DropdownMenuContent, ScrollArea, CloseCircleFillIcon, CheckedCircleFillIcon, ChainIcon, Badge, CaretDownIcon, InfoCircleIcon, CaretUpIcon, CloseRoundFillIcon, ExclamationFillIcon, Checkbox, CloseIcon } from '@orderly.network/ui';
3
3
  import { forwardRef, useState, useMemo, useEffect, useCallback, useRef, createElement } from 'react';
4
4
  import { useEventEmitter, useConfig, useWalletConnector, useLocalStorage, useConvert, useOdosQuote, useComputedLTV, useBoolean, useAccountInstance, useAccount, useAppStore, useTransfer, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useTokensInfo, usePositionStream, useIndexPricesStream, useDeposit, useAssetsHistory, useChains, useMemoizedFn, useWithdraw, useWalletTopic, useQuery, useTokenInfo, useIndexPrice, useHoldingStream, useInternalTransfer, useDebouncedCallback, useTransferHistory, useBalanceTopic } from '@orderly.network/hooks';
5
5
  import { Decimal, zero, praseChainIdToNumber, int2hex, toNonExponential, isSolana } from '@orderly.network/utils';
@@ -12,6 +12,7 @@ import { account } from '@orderly.network/perp';
12
12
  import { createClient } from '@layerzerolabs/scan-client';
13
13
  import { pick } from 'ramda';
14
14
  import { utils } from '@orderly.network/core';
15
+ import { PublicKey } from '@solana/web3.js';
15
16
  import { ethers } from 'ethers';
16
17
  import { DefaultSolanaWalletAdapter } from '@orderly.network/default-solana-adapter';
17
18
 
@@ -5371,10 +5372,31 @@ var DepositFormWidget = (props) => {
5371
5372
  return /* @__PURE__ */ jsx(DepositForm, { ...state });
5372
5373
  };
5373
5374
  var TextAreaInput = (props) => {
5374
- const { value, onChange, status, hintMessage, placeholder, label } = props;
5375
+ const { t } = useTranslation();
5376
+ const {
5377
+ value,
5378
+ onChange,
5379
+ status,
5380
+ hintMessage,
5381
+ placeholder,
5382
+ label,
5383
+ enableAccountLookup,
5384
+ accountInfo,
5385
+ accountDropdownOpen,
5386
+ setAccountDropdownOpen
5387
+ } = props;
5375
5388
  const textareaRef = useRef(null);
5389
+ const [selectedAccount, setSelectedAccount] = useState(
5390
+ null
5391
+ );
5392
+ const displayStatus = status;
5393
+ const displayHint = hintMessage;
5376
5394
  const handleChange = (e) => {
5377
- onChange?.(e.target.value);
5395
+ const nextValue = e.target.value;
5396
+ if (selectedAccount) {
5397
+ setSelectedAccount(null);
5398
+ }
5399
+ onChange?.(nextValue);
5378
5400
  const textarea = textareaRef.current;
5379
5401
  if (textarea) {
5380
5402
  textarea.style.height = "auto";
@@ -5387,9 +5409,9 @@ var TextAreaInput = (props) => {
5387
5409
  textarea.style.height = "auto";
5388
5410
  textarea.style.height = `${textarea.scrollHeight}px`;
5389
5411
  }
5390
- }, [value]);
5412
+ }, [value, selectedAccount?.address]);
5391
5413
  const prefix = /* @__PURE__ */ jsx("div", { className: "oui-absolute oui-left-3 oui-top-0.5 oui-z-[1]", children: /* @__PURE__ */ jsx(Text, { size: "2xs", intensity: 36, children: label }) });
5392
- const message = /* @__PURE__ */ jsxs(Flex, { mt: 1, gapX: 1, px: 1, children: [
5414
+ const message = /* @__PURE__ */ jsxs(Flex, { mb: 1, gapX: 1, px: 1, children: [
5393
5415
  /* @__PURE__ */ jsx(
5394
5416
  Box,
5395
5417
  {
@@ -5397,8 +5419,8 @@ var TextAreaInput = (props) => {
5397
5419
  height: 4,
5398
5420
  r: "full",
5399
5421
  className: cn(
5400
- status === "error" && "oui-bg-danger-light",
5401
- status === "warning" && "oui-bg-warning-light"
5422
+ displayStatus === "error" && "oui-bg-danger-light",
5423
+ displayStatus === "warning" && "oui-bg-warning-light"
5402
5424
  )
5403
5425
  }
5404
5426
  ),
@@ -5407,40 +5429,178 @@ var TextAreaInput = (props) => {
5407
5429
  {
5408
5430
  size: "2xs",
5409
5431
  className: cn(
5410
- status === "error" && "oui-text-danger-light",
5411
- status === "warning" && "oui-text-warning-light"
5432
+ displayStatus === "error" && "oui-text-danger-light",
5433
+ displayStatus === "warning" && "oui-text-warning-light"
5412
5434
  ),
5413
- children: hintMessage
5435
+ children: displayHint
5414
5436
  }
5415
5437
  )
5416
5438
  ] });
5417
- return /* @__PURE__ */ jsxs("div", { className: "oui-relative", children: [
5439
+ const textareaNode = /* @__PURE__ */ jsxs("div", { className: "oui-relative", children: [
5418
5440
  prefix,
5419
- /* @__PURE__ */ jsx(
5420
- "textarea",
5441
+ /* @__PURE__ */ jsxs(
5442
+ "div",
5421
5443
  {
5422
- ref: textareaRef,
5423
- placeholder,
5424
5444
  className: cn(
5425
- // hide resize height control and scrollbar
5426
- "oui-resize-none oui-overflow-y-hidden",
5427
- "oui-relative oui-min-h-[54px] oui-px-3 oui-pb-2 oui-pt-5",
5428
- "oui-w-full oui-bg-base-5 oui-text-sm oui-text-base-contrast",
5429
- "oui-rounded-lg oui-outline-none",
5430
- "oui-border oui-border-line focus:oui-border-primary-light",
5431
- status === "error" && "oui-border-danger-light focus-within:oui-border-danger-light focus:oui-border-danger-light",
5432
- status === "warning" && "oui-border-warning-light focus-within:oui-border-warning-light focus:oui-border-warning-light",
5433
- "disabled:oui-cursor-not-allowed",
5434
- props.className
5445
+ "oui-relative oui-w-full oui-rounded-lg oui-border oui-border-line oui-mb-1",
5446
+ "oui-bg-base-5 oui-text-sm oui-text-base-contrast",
5447
+ "focus-within:oui-border-primary-light",
5448
+ displayStatus === "error" && "oui-border-danger-light focus-within:oui-border-danger-light",
5449
+ displayStatus === "warning" && "oui-border-warning-light focus-within:oui-border-warning-light",
5450
+ "disabled:oui-cursor-not-allowed"
5435
5451
  ),
5436
- rows: 1,
5437
- value,
5438
- onChange: handleChange,
5439
- disabled: props.disabled
5452
+ children: [
5453
+ /* @__PURE__ */ jsx(
5454
+ "textarea",
5455
+ {
5456
+ ref: textareaRef,
5457
+ placeholder,
5458
+ className: cn(
5459
+ // hide resize height control and scrollbar
5460
+ "oui-resize-none oui-overflow-y-hidden",
5461
+ "oui-block oui-w-full oui-bg-transparent",
5462
+ "oui-px-3 oui-pt-5",
5463
+ selectedAccount?.address ? "oui-pb-0" : "oui-pb-2",
5464
+ "oui-text-sm oui-text-base-contrast",
5465
+ "oui-rounded-lg oui-outline-none",
5466
+ "placeholder:oui-text-base-contrast-20",
5467
+ props.className
5468
+ ),
5469
+ rows: 1,
5470
+ value,
5471
+ onChange: handleChange,
5472
+ onFocus: () => {
5473
+ if (accountInfo) {
5474
+ setAccountDropdownOpen?.(true);
5475
+ }
5476
+ },
5477
+ disabled: props.disabled
5478
+ }
5479
+ ),
5480
+ selectedAccount?.address && /* @__PURE__ */ jsx("div", { className: "oui-flex oui-items-center oui-justify-between oui-px-3 oui-pb-2 oui-pt-1", children: /* @__PURE__ */ jsxs(
5481
+ Text,
5482
+ {
5483
+ size: "2xs",
5484
+ intensity: 36,
5485
+ className: "oui-truncate oui-leading-[15px]",
5486
+ children: [
5487
+ "(",
5488
+ t("common.address"),
5489
+ ":",
5490
+ " ",
5491
+ /* @__PURE__ */ jsx(Text.formatted, { as: "span", rule: "address", range: [6, 4], children: selectedAccount.address }),
5492
+ ")"
5493
+ ]
5494
+ }
5495
+ ) }),
5496
+ enableAccountLookup && /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "oui-absolute oui-left-0 oui-bottom-0 oui-w-0 oui-h-0" }) })
5497
+ ]
5440
5498
  }
5441
- ),
5442
- hintMessage && message
5499
+ )
5443
5500
  ] });
5501
+ if (!enableAccountLookup) {
5502
+ return /* @__PURE__ */ jsxs("div", { className: "oui-relative", children: [
5503
+ textareaNode,
5504
+ displayHint && message
5505
+ ] });
5506
+ }
5507
+ return /* @__PURE__ */ jsxs(
5508
+ DropdownMenuRoot,
5509
+ {
5510
+ open: !!(accountInfo && accountDropdownOpen),
5511
+ onOpenChange: (open) => {
5512
+ if (!open) {
5513
+ setAccountDropdownOpen?.(false);
5514
+ }
5515
+ },
5516
+ children: [
5517
+ textareaNode,
5518
+ displayHint && message,
5519
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "oui-invisible oui-w-0 oui-h-0 oui-overflow-hidden" }) }),
5520
+ accountInfo && accountDropdownOpen && /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsx(
5521
+ DropdownMenuContent,
5522
+ {
5523
+ align: "start",
5524
+ className: cn(
5525
+ "oui-bg-base-8",
5526
+ "oui-rounded-md oui-shadow-lg",
5527
+ "oui--mt-1 oui-w-[378px] oui-p-1"
5528
+ ),
5529
+ ...{
5530
+ onOpenAutoFocus: (event) => event.preventDefault()
5531
+ },
5532
+ children: /* @__PURE__ */ jsx(
5533
+ AccountResultItem,
5534
+ {
5535
+ item: accountInfo,
5536
+ disabled: props.disabled,
5537
+ selected: !!selectedAccount && selectedAccount.accountId === accountInfo.accountId,
5538
+ onSelect: (account2) => {
5539
+ onChange?.(account2.accountId);
5540
+ setSelectedAccount(account2);
5541
+ setAccountDropdownOpen?.(false);
5542
+ }
5543
+ }
5544
+ )
5545
+ }
5546
+ ) })
5547
+ ]
5548
+ }
5549
+ );
5550
+ };
5551
+ var AccountResultItem = ({
5552
+ item,
5553
+ disabled,
5554
+ selected,
5555
+ onSelect
5556
+ }) => {
5557
+ const { t } = useTranslation();
5558
+ return /* @__PURE__ */ jsxs(
5559
+ "div",
5560
+ {
5561
+ className: cn(
5562
+ "oui-flex oui-w-full oui-items-center oui-justify-between",
5563
+ "oui-gap-1.5 oui-rounded-[4px] oui-px-2 oui-py-1.5",
5564
+ "oui-cursor-pointer hover:oui-bg-base-5",
5565
+ disabled && "oui-cursor-not-allowed oui-opacity-50"
5566
+ ),
5567
+ onClick: () => !disabled && onSelect(item),
5568
+ children: [
5569
+ /* @__PURE__ */ jsxs("div", { className: "oui-flex oui-flex-col oui-items-start oui-gap-0.5", children: [
5570
+ /* @__PURE__ */ jsxs(
5571
+ Text,
5572
+ {
5573
+ size: "sm",
5574
+ intensity: 54,
5575
+ weight: "semibold",
5576
+ className: "oui-tracking-wide",
5577
+ children: [
5578
+ t("common.accountId"),
5579
+ ":",
5580
+ " ",
5581
+ /* @__PURE__ */ jsx(
5582
+ Text.formatted,
5583
+ {
5584
+ rule: "address",
5585
+ range: [6, 4],
5586
+ as: "span",
5587
+ className: "oui-text-primary-light",
5588
+ children: item.accountId
5589
+ }
5590
+ )
5591
+ ]
5592
+ }
5593
+ ),
5594
+ /* @__PURE__ */ jsxs(Text, { size: "2xs", intensity: 36, children: [
5595
+ "(",
5596
+ item.address,
5597
+ ")"
5598
+ ] })
5599
+ ] }),
5600
+ /* @__PURE__ */ jsx(Checkbox, { checked: !!selected })
5601
+ ]
5602
+ }
5603
+ );
5444
5604
  };
5445
5605
  var UnsettlePnlInfo = (props) => {
5446
5606
  const {
@@ -5731,270 +5891,61 @@ var WithdrawWarningMessage = (props) => {
5731
5891
  }
5732
5892
  );
5733
5893
  };
5734
- var WithdrawForm = (props) => {
5894
+ var useSettlePnl = (options2) => {
5895
+ const { accountId } = options2 || {};
5896
+ const { t } = useTranslation();
5897
+ const ee = useEventEmitter();
5898
+ const { account: account2, state } = useAccount();
5899
+ const [positionData] = usePositionStream();
5900
+ const hasPositions = useMemo(
5901
+ () => !!positionData?.rows?.length,
5902
+ [positionData]
5903
+ );
5904
+ const onSettlePnl = async () => {
5905
+ const isSubAccount = accountId && state.mainAccountId !== accountId;
5906
+ const settleFn = isSubAccount ? account2.settleSubAccount({ subAccountId: accountId }) : account2.settle({ accountId });
5907
+ return settleFn.then((res) => {
5908
+ toast.success(t("settle.settlement.requested"));
5909
+ return Promise.resolve(res);
5910
+ }).catch((e) => {
5911
+ if (e.code == -1104) {
5912
+ toast.error(t("settle.settlement.error"));
5913
+ } else if (e.message.indexOf(
5914
+ "Signing off chain messages with Ledger is not yet supported"
5915
+ ) !== -1) {
5916
+ ee.emit("wallet:sign-message-with-ledger-error", {
5917
+ message: e.message,
5918
+ userAddress: account2.address
5919
+ });
5920
+ } else if (e.message.indexOf("user rejected") !== -1) {
5921
+ toast.error(t("transfer.rejectTransaction"));
5922
+ } else {
5923
+ toast.error(e.message);
5924
+ return Promise.reject(e);
5925
+ }
5926
+ });
5927
+ };
5928
+ return {
5929
+ hasPositions,
5930
+ onSettlePnl
5931
+ };
5932
+ };
5933
+ var cctpSupportedChains = [43114, 1, 137, 42161, 10, 8453, 1329];
5934
+ var cctpSupportedTokens = ["USDC"];
5935
+ var useVaultBalance = (inputs) => {
5735
5936
  const {
5736
- address,
5737
- loading,
5738
- disabled,
5739
- quantity,
5740
- onQuantityChange,
5741
- sourceToken,
5742
- amount,
5743
- maxQuantity,
5744
- tokenChains,
5745
5937
  currentChain,
5746
- fee,
5747
- settingChain,
5748
- crossChainTrans,
5749
- checkIsBridgeless,
5938
+ sourceToken,
5750
5939
  withdrawTo,
5751
- sourceTokens,
5752
- onSourceTokenChange,
5753
- vaultBalanceList,
5754
- qtyGreaterThanMaxAmount,
5755
- isTokenUnsupported,
5756
- onSwitchToSupportedNetwork
5757
- } = props;
5940
+ quantity,
5941
+ qtyGreaterThanMaxAmount
5942
+ } = inputs;
5758
5943
  const { t } = useTranslation();
5759
- const internalWithdrawPanel = /* @__PURE__ */ jsxs(
5760
- TabPanel,
5944
+ const { data: vaultBalanceData } = useQuery(
5945
+ `/v1/public/vault_balance`,
5761
5946
  {
5762
- title: t("transfer.withdraw.otherAccount", {
5763
- brokerName: props.brokerName
5764
- }),
5765
- value: "accountId" /* Account */,
5766
- children: [
5767
- /* @__PURE__ */ jsx(
5768
- TextAreaInput,
5769
- {
5770
- label: t("common.accountId"),
5771
- value: props.toAccountId,
5772
- onChange: props.setToAccountId,
5773
- status: props.toAccountIdInputStatus,
5774
- hintMessage: props.toAccountIdHintMessage,
5775
- disabled: !props.isLoggedIn
5776
- }
5777
- ),
5778
- /* @__PURE__ */ jsx(Box, { my: 2, children: /* @__PURE__ */ jsx(Text, { size: "xs", intensity: 54, children: t("transfer.withdraw.accountId.tips") }) })
5779
- ]
5780
- }
5781
- );
5782
- return /* @__PURE__ */ jsxs(
5783
- Box,
5784
- {
5785
- id: "oui-withdraw-form",
5786
- className: textVariants({ weight: "semibold" }),
5787
- children: [
5788
- /* @__PURE__ */ jsxs(Box, { className: "oui-mb-6 lg:oui-mb-8", children: [
5789
- /* @__PURE__ */ jsx(BrokerWallet, {}),
5790
- /* @__PURE__ */ jsx(Box, { mt: 3, mb: 1, children: /* @__PURE__ */ jsx(
5791
- QuantityInput,
5792
- {
5793
- value: quantity,
5794
- onValueChange: onQuantityChange,
5795
- token: sourceToken,
5796
- tokens: sourceTokens,
5797
- onTokenChange: onSourceTokenChange,
5798
- status: props.inputStatus,
5799
- hintMessage: props.hintMessage,
5800
- hintSuffix: isTokenUnsupported ? /* @__PURE__ */ jsxs(
5801
- "button",
5802
- {
5803
- type: "button",
5804
- onClick: onSwitchToSupportedNetwork,
5805
- className: "oui-inline-flex oui-items-center oui-gap-1 oui-text-2xs oui-font-semibold oui-text-primary",
5806
- children: [
5807
- t("common.switch"),
5808
- /* @__PURE__ */ jsx(
5809
- ArrowLeftRightIcon,
5810
- {
5811
- size: 16,
5812
- className: "oui-text-primary oui-mt-0.5",
5813
- opacity: 1
5814
- }
5815
- )
5816
- ]
5817
- }
5818
- ) : void 0,
5819
- vaultBalanceList,
5820
- testId: "oui-testid-withdraw-dialog-quantity-input",
5821
- displayType: "vaultBalance",
5822
- disabled: !props.isLoggedIn
5823
- }
5824
- ) }),
5825
- /* @__PURE__ */ jsx(
5826
- AvailableQuantity,
5827
- {
5828
- token: sourceToken,
5829
- amount,
5830
- maxQuantity: maxQuantity.toString(),
5831
- loading: props.balanceRevalidating,
5832
- onClick: () => {
5833
- onQuantityChange(maxQuantity.toString());
5834
- },
5835
- tooltipContent: t("transfer.withdraw.available.tooltip", {
5836
- amount: maxQuantity.toString()
5837
- })
5838
- }
5839
- ),
5840
- /* @__PURE__ */ jsx(Box, { mx: 2, mt: 1, children: /* @__PURE__ */ jsx(
5841
- UnsettlePnlInfo,
5842
- {
5843
- unsettledPnl: props.unsettledPnL,
5844
- hasPositions: props.hasPositions,
5845
- onSettlePnl: props.onSettlePnl,
5846
- tooltipContent: t("settle.unsettled.tooltip"),
5847
- dialogContent: /* @__PURE__ */ jsx(Trans, { i18nKey: "settle.settlePnl.description" })
5848
- }
5849
- ) }),
5850
- /* @__PURE__ */ jsx(ExchangeDivider, {}),
5851
- /* @__PURE__ */ jsxs(
5852
- Tabs,
5853
- {
5854
- value: withdrawTo,
5855
- onValueChange: props.setWithdrawTo,
5856
- variant: "contained",
5857
- size: "lg",
5858
- classNames: {
5859
- tabsList: "oui-px-0",
5860
- tabsContent: "oui-pt-3"
5861
- },
5862
- children: [
5863
- /* @__PURE__ */ jsxs(
5864
- TabPanel,
5865
- {
5866
- title: t("transfer.web3Wallet.my"),
5867
- icon: props.walletName ? /* @__PURE__ */ jsx(WalletIcon, { size: "xs", name: props.walletName ?? "" }) : void 0,
5868
- value: "wallet" /* Wallet */,
5869
- children: [
5870
- /* @__PURE__ */ jsx(
5871
- ChainSelect,
5872
- {
5873
- chains: tokenChains,
5874
- value: currentChain,
5875
- onValueChange: props.onChainChange,
5876
- wrongNetwork: props.wrongNetwork,
5877
- loading: settingChain,
5878
- disabled: !props.isLoggedIn
5879
- }
5880
- ),
5881
- /* @__PURE__ */ jsx(
5882
- QuantityInput,
5883
- {
5884
- classNames: {
5885
- root: "oui-mt-[2px] oui-rounded-t-sm oui-rounded-b-xl"
5886
- },
5887
- token: sourceToken,
5888
- value: props.showQty,
5889
- readOnly: true
5890
- }
5891
- )
5892
- ]
5893
- }
5894
- ),
5895
- internalWithdrawPanel
5896
- ]
5897
- }
5898
- ),
5899
- /* @__PURE__ */ jsx(Box, { mt: 2, children: /* @__PURE__ */ jsx(
5900
- LtvWidget,
5901
- {
5902
- showDiff: typeof quantity !== "undefined" && Number(quantity) > 0,
5903
- currentLtv: props.currentLTV,
5904
- nextLTV: props.nextLTV
5905
- }
5906
- ) }),
5907
- /* @__PURE__ */ jsx(Flex, { direction: "column", mt: 1, gapY: 1, itemAlign: "start", children: /* @__PURE__ */ jsxs(Text, { size: "xs", intensity: 36, children: [
5908
- t("common.fee"),
5909
- withdrawTo === "wallet" /* Wallet */ ? " \u2248 " : " = ",
5910
- /* @__PURE__ */ jsx(Text, { size: "xs", intensity: 80, children: fee })
5911
- ] }) })
5912
- ] }),
5913
- /* @__PURE__ */ jsx(
5914
- WithdrawWarningMessage,
5915
- {
5916
- checkIsBridgeless,
5917
- crossChainTrans,
5918
- qtyGreaterThanMaxAmount,
5919
- message: props.warningMessage
5920
- }
5921
- ),
5922
- /* @__PURE__ */ jsx(Flex, { justify: "center", children: /* @__PURE__ */ jsx(
5923
- WithdrawAction,
5924
- {
5925
- checkIsBridgeless,
5926
- networkId: props.networkId,
5927
- disabled,
5928
- loading,
5929
- onWithdraw: props.onWithdraw,
5930
- crossChainWithdraw: props.crossChainWithdraw,
5931
- currentChain,
5932
- address,
5933
- quantity,
5934
- fee,
5935
- withdrawTo,
5936
- onTransfer: props.onTransfer
5937
- }
5938
- ) })
5939
- ]
5940
- }
5941
- );
5942
- };
5943
- var useSettlePnl = (options2) => {
5944
- const { accountId } = options2 || {};
5945
- const { t } = useTranslation();
5946
- const ee = useEventEmitter();
5947
- const { account: account2, state } = useAccount();
5948
- const [positionData] = usePositionStream();
5949
- const hasPositions = useMemo(
5950
- () => !!positionData?.rows?.length,
5951
- [positionData]
5952
- );
5953
- const onSettlePnl = async () => {
5954
- const isSubAccount = accountId && state.mainAccountId !== accountId;
5955
- const settleFn = isSubAccount ? account2.settleSubAccount({ subAccountId: accountId }) : account2.settle({ accountId });
5956
- return settleFn.then((res) => {
5957
- toast.success(t("settle.settlement.requested"));
5958
- return Promise.resolve(res);
5959
- }).catch((e) => {
5960
- if (e.code == -1104) {
5961
- toast.error(t("settle.settlement.error"));
5962
- } else if (e.message.indexOf(
5963
- "Signing off chain messages with Ledger is not yet supported"
5964
- ) !== -1) {
5965
- ee.emit("wallet:sign-message-with-ledger-error", {
5966
- message: e.message,
5967
- userAddress: account2.address
5968
- });
5969
- } else if (e.message.indexOf("user rejected") !== -1) {
5970
- toast.error(t("transfer.rejectTransaction"));
5971
- } else {
5972
- toast.error(e.message);
5973
- return Promise.reject(e);
5974
- }
5975
- });
5976
- };
5977
- return {
5978
- hasPositions,
5979
- onSettlePnl
5980
- };
5981
- };
5982
- var cctpSupportedChains = [43114, 1, 137, 42161, 10, 8453, 1329];
5983
- var cctpSupportedTokens = ["USDC"];
5984
- var useVaultBalance = (inputs) => {
5985
- const {
5986
- currentChain,
5987
- sourceToken,
5988
- withdrawTo,
5989
- quantity,
5990
- qtyGreaterThanMaxAmount
5991
- } = inputs;
5992
- const { t } = useTranslation();
5993
- const { data: vaultBalanceData } = useQuery(
5994
- `/v1/public/vault_balance`,
5995
- {
5996
- revalidateOnMount: true,
5997
- errorRetryCount: 3
5947
+ revalidateOnMount: true,
5948
+ errorRetryCount: 3
5998
5949
  }
5999
5950
  );
6000
5951
  const vaultBalanceList = useMemo(() => {
@@ -6066,6 +6017,12 @@ function useWithdrawAccountId(options2) {
6066
6017
  const [toAccountId, setToAccountId] = useState("");
6067
6018
  const [inputStatus, setInputStatus] = useState("default");
6068
6019
  const [hintMessage, setHintMessage] = useState();
6020
+ const [accountInfo, setAccountInfo] = useState(null);
6021
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
6022
+ const latestLookupInputRef = useRef("");
6023
+ const config = useConfig();
6024
+ const brokerId = config.get("brokerId");
6025
+ const apiBaseUrl = config.get("apiBaseUrl");
6069
6026
  const { transfer, submitting } = useInternalTransfer();
6070
6027
  const onTransfer = useCallback(() => {
6071
6028
  const num = Number(quantity);
@@ -6098,23 +6055,123 @@ function useWithdrawAccountId(options2) {
6098
6055
  if (!toAccountId) {
6099
6056
  setInputStatus("default");
6100
6057
  setHintMessage("");
6058
+ setAccountInfo(null);
6059
+ setIsDropdownOpen(false);
6101
6060
  return;
6102
6061
  }
6103
6062
  if (checkIsAccountId(toAccountId)) {
6104
6063
  setInputStatus("default");
6105
6064
  setHintMessage("");
6106
- } else {
6107
- setInputStatus("error");
6108
- setHintMessage(t("transfer.withdraw.accountId.invalid"));
6065
+ return;
6109
6066
  }
6110
6067
  }, [toAccountId]);
6068
+ const walletLookup = async (input, network) => {
6069
+ if (!network || !brokerId)
6070
+ return null;
6071
+ const chainType = network;
6072
+ const res = await fetch(
6073
+ `${apiBaseUrl}/v1/get_account?address=${encodeURIComponent(
6074
+ input
6075
+ )}&broker_id=${encodeURIComponent(
6076
+ brokerId
6077
+ )}&chain_type=${encodeURIComponent(chainType)}`
6078
+ );
6079
+ const json = await res.json();
6080
+ if (res.ok && json?.success && json?.data?.account_id) {
6081
+ return {
6082
+ accountId: json.data.account_id,
6083
+ address: input
6084
+ };
6085
+ }
6086
+ return null;
6087
+ };
6088
+ const accountLookup = async (input) => {
6089
+ const res = await fetch(
6090
+ `${apiBaseUrl}/v1/public/account?account_id=${encodeURIComponent(input)}`
6091
+ );
6092
+ const json = await res.json();
6093
+ if (res.ok && json?.success && json?.data?.address && (!brokerId || json.data.broker_id === brokerId)) {
6094
+ return {
6095
+ accountId: input,
6096
+ address: json.data.address
6097
+ };
6098
+ }
6099
+ if (res.ok && json?.success && brokerId) {
6100
+ console.log(
6101
+ "This account belongs to a different broker and cannot be used here."
6102
+ );
6103
+ }
6104
+ return null;
6105
+ };
6106
+ const performLookup = useCallback(
6107
+ async (rawInput) => {
6108
+ const input = rawInput.trim();
6109
+ if (!input || input !== latestLookupInputRef.current) {
6110
+ return;
6111
+ }
6112
+ const { valid, network } = validateWalletAddress(input);
6113
+ try {
6114
+ let resolved = null;
6115
+ if (valid) {
6116
+ resolved = await walletLookup(input, network);
6117
+ } else {
6118
+ resolved = await accountLookup(input);
6119
+ }
6120
+ if (!resolved) {
6121
+ setAccountInfo(null);
6122
+ setIsDropdownOpen(false);
6123
+ setInputStatus("error");
6124
+ setHintMessage(t("transfer.withdraw.accountId.invalid"));
6125
+ } else {
6126
+ setAccountInfo(resolved);
6127
+ setIsDropdownOpen(true);
6128
+ setInputStatus("default");
6129
+ setHintMessage("");
6130
+ }
6131
+ } catch (error) {
6132
+ console.log("Failed to search account. Please try again.", error);
6133
+ setAccountInfo(null);
6134
+ setIsDropdownOpen(false);
6135
+ setInputStatus("error");
6136
+ setHintMessage(t("transfer.withdraw.accountId.invalid"));
6137
+ }
6138
+ },
6139
+ [brokerId, t]
6140
+ );
6141
+ const debouncedLookup = useDebouncedCallback((input) => {
6142
+ void performLookup(input);
6143
+ }, 500);
6144
+ const handleAccountIdChange = useCallback(
6145
+ (val) => {
6146
+ setToAccountId(val);
6147
+ const trimmed = val.trim();
6148
+ if (!trimmed) {
6149
+ setAccountInfo(null);
6150
+ setIsDropdownOpen(false);
6151
+ latestLookupInputRef.current = "";
6152
+ return;
6153
+ }
6154
+ latestLookupInputRef.current = trimmed;
6155
+ if (checkIsAccountId(trimmed) && accountInfo?.accountId === trimmed) {
6156
+ setIsDropdownOpen(false);
6157
+ setInputStatus("default");
6158
+ setHintMessage("");
6159
+ return;
6160
+ }
6161
+ debouncedLookup(trimmed);
6162
+ },
6163
+ [debouncedLookup, accountInfo]
6164
+ );
6111
6165
  return {
6112
6166
  toAccountId,
6113
- setToAccountId,
6167
+ setToAccountId: handleAccountIdChange,
6114
6168
  onTransfer,
6115
6169
  internalWithdrawSubmitting: submitting,
6116
6170
  toAccountIdInputStatus: inputStatus,
6117
- toAccountIdHintMessage: hintMessage
6171
+ toAccountIdHintMessage: hintMessage,
6172
+ toAccountInfo: accountInfo,
6173
+ toAccountInfoDropdownOpen: isDropdownOpen,
6174
+ setToAccountInfoDropdownOpen: setIsDropdownOpen
6118
6175
  };
6119
6176
  }
6120
6177
  function useWithdrawFee(options2) {
@@ -6302,6 +6359,19 @@ function useWithdrawToken(params) {
6302
6359
  }
6303
6360
 
6304
6361
  // src/components/withdrawForm/withdrawForm.script.tsx
6362
+ var validateWalletAddress = (address) => {
6363
+ if (ethers.isAddress(address)) {
6364
+ return { valid: true, network: "EVM" };
6365
+ }
6366
+ try {
6367
+ const pubKey = new PublicKey(address);
6368
+ if (PublicKey.isOnCurve(pubKey.toBytes())) {
6369
+ return { valid: true, network: "SOL" };
6370
+ }
6371
+ } catch {
6372
+ }
6373
+ return { valid: false };
6374
+ };
6305
6375
  var markPrice = 1;
6306
6376
  var useWithdrawFormScript = (options2) => {
6307
6377
  const { t } = useTranslation();
@@ -6327,8 +6397,8 @@ var useWithdrawFormScript = (options2) => {
6327
6397
  const [inputStatus, setInputStatus] = useState("default");
6328
6398
  const [hintMessage, setHintMessage] = useState();
6329
6399
  const [withdrawTo, setWithdrawTo] = useState("wallet" /* Wallet */);
6330
- const { wrongNetwork } = useAppContext();
6331
- const { account: account2 } = useAccount();
6400
+ const { wrongNetwork, widgetConfigs } = useAppContext();
6401
+ const { account: account2, state } = useAccount();
6332
6402
  const [chains, { findByChainId }] = useChains(networkId, {
6333
6403
  filter: (chain) => chain.network_infos?.bridge_enable || chain.network_infos?.bridgeless
6334
6404
  });
@@ -6388,6 +6458,7 @@ var useWithdrawFormScript = (options2) => {
6388
6458
  });
6389
6459
  return list;
6390
6460
  }, [chains, sourceToken?.symbol]);
6461
+ const enableWithdrawToExternalWallet = widgetConfigs?.withdraw?.enableWithdrawToExternalWallet ?? false;
6391
6462
  const { walletName, address } = useMemo(
6392
6463
  () => ({
6393
6464
  walletName: wallet?.label,
@@ -6395,6 +6466,39 @@ var useWithdrawFormScript = (options2) => {
6395
6466
  }),
6396
6467
  [wallet]
6397
6468
  );
6469
+ const [externalWallets, setExternalWallets] = useLocalStorage("orderly_external_wallets", []);
6470
+ const [selectedWalletAddress, setSelectedWalletAddress] = useState();
6471
+ useEffect(() => {
6472
+ setSelectedWalletAddress(void 0);
6473
+ }, [currentChain?.namespace]);
6474
+ useEffect(() => {
6475
+ if (address && !selectedWalletAddress) {
6476
+ setSelectedWalletAddress(address);
6477
+ }
6478
+ }, [address, selectedWalletAddress]);
6479
+ const onSelectWallet = (address2) => {
6480
+ setSelectedWalletAddress(address2);
6481
+ };
6482
+ const onAddExternalWallet = (addr, network) => {
6483
+ const normalizedAddr = addr.trim();
6484
+ if (!normalizedAddr)
6485
+ return;
6486
+ const connectedAddress = address?.trim();
6487
+ if (connectedAddress && connectedAddress.toLowerCase() === normalizedAddr.toLowerCase()) {
6488
+ setSelectedWalletAddress(normalizedAddr);
6489
+ return;
6490
+ }
6491
+ const exists = (externalWallets || []).some((w) => {
6492
+ return w.address?.trim().toLowerCase() === normalizedAddr.toLowerCase();
6493
+ });
6494
+ if (!exists) {
6495
+ setExternalWallets([
6496
+ ...externalWallets || [],
6497
+ { address: normalizedAddr, network }
6498
+ ]);
6499
+ }
6500
+ setSelectedWalletAddress(normalizedAddr);
6501
+ };
6398
6502
  const onQuantityChange = (qty) => {
6399
6503
  setQuantity(qty);
6400
6504
  };
@@ -6499,7 +6603,8 @@ var useWithdrawFormScript = (options2) => {
6499
6603
  amount: quantity,
6500
6604
  token: sourceToken?.symbol,
6501
6605
  chainId: currentChain?.id,
6502
- allowCrossChainWithdraw: crossChainWithdraw
6606
+ allowCrossChainWithdraw: crossChainWithdraw,
6607
+ receiver: selectedWalletAddress
6503
6608
  }).then((res) => {
6504
6609
  toast.success(t("transfer.withdraw.requested"));
6505
6610
  ee.emit("withdraw:requested");
@@ -6667,8 +6772,587 @@ var useWithdrawFormScript = (options2) => {
6667
6772
  warningMessage,
6668
6773
  isLoggedIn,
6669
6774
  isTokenUnsupported,
6670
- onSwitchToSupportedNetwork
6775
+ onSwitchToSupportedNetwork,
6776
+ enableWithdrawToExternalWallet,
6777
+ externalWallets,
6778
+ selectedWalletAddress: selectedWalletAddress || address,
6779
+ onSelectWallet,
6780
+ onAddExternalWallet,
6781
+ setExternalWallets,
6782
+ isEnableTrading: state.status >= AccountStatusEnum.EnableTrading || state.status === AccountStatusEnum.EnableTradingWithoutConnected
6783
+ };
6784
+ };
6785
+ var AddWalletDialog = ({
6786
+ open,
6787
+ onOpenChange,
6788
+ onConfirm,
6789
+ chain
6790
+ }) => {
6791
+ const { t } = useTranslation();
6792
+ const [address, setAddress] = useState("");
6793
+ const [isValidating, setIsValidating] = useState(false);
6794
+ const [validationResult, setValidationResult] = useState(null);
6795
+ const checkAddress = useDebouncedCallback((addr) => {
6796
+ if (!addr) {
6797
+ setValidationResult(null);
6798
+ setIsValidating(false);
6799
+ return;
6800
+ }
6801
+ const result = validateWalletAddress(addr);
6802
+ setValidationResult(result);
6803
+ setIsValidating(false);
6804
+ }, 500);
6805
+ const onAddressChange = (val) => {
6806
+ setAddress(val);
6807
+ if (!val) {
6808
+ setValidationResult(null);
6809
+ setIsValidating(false);
6810
+ return;
6811
+ }
6812
+ setIsValidating(true);
6813
+ setValidationResult(null);
6814
+ checkAddress(val);
6815
+ };
6816
+ const onClear = () => {
6817
+ setAddress("");
6818
+ setValidationResult(null);
6819
+ setIsValidating(false);
6671
6820
  };
6821
+ useEffect(() => {
6822
+ if (!open)
6823
+ onClear();
6824
+ }, [open]);
6825
+ const requiredNetwork = chain?.namespace === ChainNamespace.solana ? "SOL" : chain?.namespace === ChainNamespace.evm ? "EVM" : void 0;
6826
+ const requiredNetworkLabel = requiredNetwork === "SOL" ? "Solana" : requiredNetwork === "EVM" ? "EVM" : "";
6827
+ const hasValidation = !!validationResult;
6828
+ const isValid = !!validationResult?.valid;
6829
+ const isInvalidFormat = hasValidation && !validationResult.valid;
6830
+ const isNetworkMismatch = isValid && !!requiredNetwork && validationResult.network !== requiredNetwork;
6831
+ const showBorderDanger = !isValidating && hasValidation && (isInvalidFormat || isNetworkMismatch);
6832
+ const showProtocolLabel = !isValidating && isValid;
6833
+ const showInlineInvalid = !isValidating && isInvalidFormat;
6834
+ const showErrorHint = !isValidating && isNetworkMismatch;
6835
+ const handleConfirm = () => {
6836
+ if (!address || isValidating || !isValid || isNetworkMismatch)
6837
+ return;
6838
+ onConfirm(address, validationResult.network === "SOL" ? "SOL" : "EVM");
6839
+ onOpenChange(false);
6840
+ };
6841
+ return /* @__PURE__ */ jsx(
6842
+ SimpleDialog,
6843
+ {
6844
+ open,
6845
+ onOpenChange,
6846
+ title: t("transfer.withdraw.addExternalWallet"),
6847
+ size: "sm",
6848
+ children: /* @__PURE__ */ jsxs(Box, { className: "oui-flex oui-flex-col oui-gap-6 oui-font-semibold oui-tracking-[0.03em]", children: [
6849
+ /* @__PURE__ */ jsxs(Flex, { justify: "between", children: [
6850
+ /* @__PURE__ */ jsx(Text, { size: "sm", intensity: 54, children: t("common.network") }),
6851
+ /* @__PURE__ */ jsxs(Flex, { gapX: 1, children: [
6852
+ /* @__PURE__ */ jsx(ChainIcon, { chainId: "" + chain?.id, className: "oui-w-4 oui-h-4" }),
6853
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: chain?.info?.network_infos?.shortName })
6854
+ ] })
6855
+ ] }),
6856
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", itemAlign: "start", gapY: 2, children: [
6857
+ /* @__PURE__ */ jsx(Text, { size: "sm", intensity: 54, children: t("transfer.withdraw.addExternalWallet.addressDescription") }),
6858
+ requiredNetworkLabel && /* @__PURE__ */ jsx(Text, { size: "sm", intensity: 54, children: t("transfer.withdraw.addExternalWallet.addressWarning", {
6859
+ networkLabel: requiredNetworkLabel
6860
+ }) })
6861
+ ] }),
6862
+ /* @__PURE__ */ jsxs(Box, { className: "oui-flex oui-flex-col oui-gap-1", children: [
6863
+ /* @__PURE__ */ jsxs(Flex, { justify: "between", children: [
6864
+ /* @__PURE__ */ jsx(Text, { size: "2xs", intensity: 54, children: t("transfer.withdraw.addExternalWallet.label") }),
6865
+ isValidating && /* @__PURE__ */ jsx(Spinner, { className: "oui-w-3.5 oui-h-3.5 oui-text-base-contrast-36" }),
6866
+ showProtocolLabel && /* @__PURE__ */ jsx(
6867
+ Text,
6868
+ {
6869
+ size: "2xs",
6870
+ className: cn(
6871
+ isNetworkMismatch ? "oui-text-danger" : "oui-text-primary-light"
6872
+ ),
6873
+ children: validationResult.network === "EVM" ? "EVM" : "Solana"
6874
+ }
6875
+ ),
6876
+ showInlineInvalid && /* @__PURE__ */ jsx(Text, { size: "2xs", className: "oui-text-danger", children: t("common.invalid") })
6877
+ ] }),
6878
+ /* @__PURE__ */ jsx(
6879
+ Input,
6880
+ {
6881
+ value: address,
6882
+ onValueChange: onAddressChange,
6883
+ autoFocus: true,
6884
+ color: showBorderDanger ? "danger" : void 0,
6885
+ className: cn("oui-bg-transparent oui-bg-base-6"),
6886
+ classNames: { input: "oui-text-white" },
6887
+ suffix: address && /* @__PURE__ */ jsx(Box, { className: "oui-ml-2.5 oui-mr-2 oui-cursor-pointer", children: /* @__PURE__ */ jsx(
6888
+ CloseRoundFillIcon,
6889
+ {
6890
+ size: 16,
6891
+ onClick: onClear,
6892
+ className: "oui-text-base-contrast-20 hover:oui-text-base-contrast-54"
6893
+ }
6894
+ ) })
6895
+ }
6896
+ ),
6897
+ showErrorHint && /* @__PURE__ */ jsx(Flex, { gapX: 1, px: 1, justify: "between", itemAlign: "center", children: /* @__PURE__ */ jsxs(Flex, { gapX: 1, itemAlign: "center", children: [
6898
+ /* @__PURE__ */ jsx(
6899
+ Box,
6900
+ {
6901
+ width: 4,
6902
+ height: 4,
6903
+ r: "full",
6904
+ className: "oui-bg-danger-light"
6905
+ }
6906
+ ),
6907
+ /* @__PURE__ */ jsx(Text, { size: "2xs", className: "oui-text-danger-light", children: t("transfer.withdraw.addExternalWallet.networkMismatch", {
6908
+ networkLabel: requiredNetworkLabel
6909
+ }) })
6910
+ ] }) })
6911
+ ] }),
6912
+ /* @__PURE__ */ jsx(
6913
+ Button,
6914
+ {
6915
+ variant: "contained",
6916
+ fullWidth: true,
6917
+ onClick: handleConfirm,
6918
+ disabled: !address || isValidating || !isValid || isNetworkMismatch,
6919
+ className: "oui-mt-2",
6920
+ children: t("common.confirm")
6921
+ }
6922
+ )
6923
+ ] })
6924
+ }
6925
+ );
6926
+ };
6927
+ var AddIcon = (props) => /* @__PURE__ */ jsx(
6928
+ "svg",
6929
+ {
6930
+ width: "18",
6931
+ height: "18",
6932
+ viewBox: "0 0 18 18",
6933
+ fill: "currentColor",
6934
+ xmlns: "http://www.w3.org/2000/svg",
6935
+ ...props,
6936
+ children: /* @__PURE__ */ jsx("path", { d: "M8.99316 2.19731C8.57916 2.19731 8.24316 2.53331 8.24316 2.94731V8.19731H2.99316C2.57916 8.19731 2.24316 8.53331 2.24316 8.94731C2.24316 9.36131 2.57916 9.69731 2.99316 9.69731H8.24316V14.9473C8.24316 15.3613 8.57916 15.6973 8.99316 15.6973C9.40716 15.6973 9.74316 15.3613 9.74316 14.9473V9.69731H14.9932C15.4072 9.69731 15.7432 9.36131 15.7432 8.94731C15.7432 8.53331 15.4072 8.19731 14.9932 8.19731H9.74316V2.94731C9.74316 2.53331 9.40716 2.19731 8.99316 2.19731Z" })
6937
+ }
6938
+ );
6939
+ var WalletMenuItem = ({
6940
+ onClick,
6941
+ children,
6942
+ className
6943
+ }) => {
6944
+ return /* @__PURE__ */ jsx(
6945
+ "button",
6946
+ {
6947
+ type: "button",
6948
+ onClick,
6949
+ className: cn(
6950
+ "oui-flex oui-items-center oui-gap-2 oui-py-1.5 oui-px-2 hover:oui-bg-base-5",
6951
+ "oui-rounded-[4px]",
6952
+ "oui-font-semibold oui-tracking-[0.03em]",
6953
+ className
6954
+ ),
6955
+ children
6956
+ }
6957
+ );
6958
+ };
6959
+ var WalletSelector = ({
6960
+ connectedWallet,
6961
+ externalWallets,
6962
+ selectedAddress,
6963
+ onSelect,
6964
+ onAddExternalWallet
6965
+ }) => {
6966
+ const { t } = useTranslation();
6967
+ const [isOpen, setIsOpen] = useState(false);
6968
+ const currentNetwork = useMemo(() => {
6969
+ if (!connectedWallet?.namespace)
6970
+ return void 0;
6971
+ const ns = connectedWallet.namespace.toLowerCase();
6972
+ if (ns.includes("sol"))
6973
+ return "SOL";
6974
+ return "EVM";
6975
+ }, [connectedWallet?.namespace]);
6976
+ const filteredExternalWallets = useMemo(() => {
6977
+ if (!currentNetwork)
6978
+ return externalWallets;
6979
+ return externalWallets.filter(
6980
+ (wallet) => wallet.network === currentNetwork
6981
+ );
6982
+ }, [externalWallets, currentNetwork]);
6983
+ const selectedWalletOpt = useMemo(() => {
6984
+ if (connectedWallet && selectedAddress === connectedWallet.address) {
6985
+ return {
6986
+ address: connectedWallet.address,
6987
+ name: connectedWallet.name,
6988
+ network: currentNetwork
6989
+ };
6990
+ }
6991
+ return filteredExternalWallets.find(
6992
+ (w) => w.address === selectedAddress
6993
+ );
6994
+ }, [
6995
+ connectedWallet,
6996
+ currentNetwork,
6997
+ filteredExternalWallets,
6998
+ selectedAddress
6999
+ ]);
7000
+ const hasExternalWallets = filteredExternalWallets.length > 0;
7001
+ const showConnectedItem = !!connectedWallet && hasExternalWallets;
7002
+ const getChainLabel = (network) => {
7003
+ if (!network)
7004
+ return "";
7005
+ if (network === "SOL")
7006
+ return "Solana";
7007
+ return "EVM";
7008
+ };
7009
+ const handleSelectWallet = (address) => {
7010
+ onSelect(address);
7011
+ setIsOpen(false);
7012
+ };
7013
+ const handleAddExternalWalletClick = () => {
7014
+ onAddExternalWallet();
7015
+ setIsOpen(false);
7016
+ };
7017
+ const dropdownContent = /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs(
7018
+ DropdownMenuContent,
7019
+ {
7020
+ align: "end",
7021
+ className: "oui-max-h-[240px] oui-overflow-y-auto oui-custom-scrollbar",
7022
+ children: [
7023
+ showConnectedItem && connectedWallet && /* @__PURE__ */ jsx(
7024
+ WalletMenuItem,
7025
+ {
7026
+ onClick: () => handleSelectWallet(connectedWallet.address),
7027
+ className: "oui-w-[368px]",
7028
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", itemAlign: "start", gapY: 1, children: [
7029
+ /* @__PURE__ */ jsx(Text, { size: "2xs", className: "oui-text-base-contrast-54", children: t("common.myWallet") }),
7030
+ /* @__PURE__ */ jsx(
7031
+ Text,
7032
+ {
7033
+ size: "2xs",
7034
+ intensity: 54,
7035
+ className: "oui-text-base-contrast-36 oui-leading-[15px]",
7036
+ children: `(${getChainLabel(currentNetwork)}) ${connectedWallet.address}`
7037
+ }
7038
+ )
7039
+ ] })
7040
+ }
7041
+ ),
7042
+ hasExternalWallets && /* @__PURE__ */ jsx(Fragment, { children: filteredExternalWallets.map((wallet) => /* @__PURE__ */ jsx(
7043
+ WalletMenuItem,
7044
+ {
7045
+ onClick: () => handleSelectWallet(wallet.address),
7046
+ className: "oui-w-[368px]",
7047
+ children: /* @__PURE__ */ jsxs(Flex, { direction: "column", itemAlign: "start", gapY: 1, children: [
7048
+ /* @__PURE__ */ jsx(Text, { size: "2xs", className: "oui-text-base-contrast-54", children: t("common.externalWallet") }),
7049
+ /* @__PURE__ */ jsx(
7050
+ Text,
7051
+ {
7052
+ size: "2xs",
7053
+ intensity: 54,
7054
+ className: "oui-text-base-contrast-36 oui-leading-[15px]",
7055
+ children: `(${getChainLabel(wallet.network)}) ${wallet.address}`
7056
+ }
7057
+ )
7058
+ ] })
7059
+ },
7060
+ wallet.address
7061
+ )) }),
7062
+ /* @__PURE__ */ jsx(
7063
+ WalletMenuItem,
7064
+ {
7065
+ onClick: handleAddExternalWalletClick,
7066
+ className: cn(
7067
+ "oui-justify-center",
7068
+ hasExternalWallets && "oui-w-full",
7069
+ !hasExternalWallets && "oui-w-[190px]"
7070
+ ),
7071
+ children: /* @__PURE__ */ jsxs(
7072
+ Flex,
7073
+ {
7074
+ itemAlign: "center",
7075
+ gapX: 1,
7076
+ className: "oui-text-primary oui-font-semibold oui-tracking-[0.03em]",
7077
+ children: [
7078
+ /* @__PURE__ */ jsx(AddIcon, { className: "oui-size-[18px]" }),
7079
+ /* @__PURE__ */ jsx(Text, { size: "2xs", children: t("transfer.withdraw.addExternalWallet") })
7080
+ ]
7081
+ }
7082
+ )
7083
+ }
7084
+ )
7085
+ ]
7086
+ }
7087
+ ) });
7088
+ return /* @__PURE__ */ jsxs(Flex, { justify: "between", className: "oui-w-full oui-mb-3", children: [
7089
+ /* @__PURE__ */ jsx(Text, { size: "2xs", intensity: 36, children: t("common.wallet") }),
7090
+ /* @__PURE__ */ jsxs(DropdownMenuRoot, { open: isOpen, onOpenChange: setIsOpen, children: [
7091
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "oui-flex oui-items-center oui-gap-1 oui-cursor-pointer oui-text-base-contrast-54 hover:oui-text-base-contrast-80", children: [
7092
+ selectedWalletOpt?.name && /* @__PURE__ */ jsx(WalletIcon, { name: selectedWalletOpt.name, size: "3xs" }),
7093
+ /* @__PURE__ */ jsx(Text.formatted, { size: "2xs", intensity: 54, rule: "address", children: selectedWalletOpt?.address || "" }),
7094
+ /* @__PURE__ */ jsx(
7095
+ Text,
7096
+ {
7097
+ size: "2xs",
7098
+ intensity: 54,
7099
+ className: "oui-text-base-contrast-36",
7100
+ children: ` (${getChainLabel(selectedWalletOpt?.network)})`
7101
+ }
7102
+ ),
7103
+ isOpen ? /* @__PURE__ */ jsx(CaretUpIcon, { size: 12, className: "oui-text-inherit" }) : /* @__PURE__ */ jsx(CaretDownIcon, { size: 12, className: "oui-text-inherit" })
7104
+ ] }) }),
7105
+ dropdownContent
7106
+ ] })
7107
+ ] });
7108
+ };
7109
+ var WithdrawForm = (props) => {
7110
+ const {
7111
+ address,
7112
+ walletName,
7113
+ loading,
7114
+ disabled,
7115
+ quantity,
7116
+ onQuantityChange,
7117
+ sourceToken,
7118
+ amount,
7119
+ maxQuantity,
7120
+ tokenChains,
7121
+ currentChain,
7122
+ fee,
7123
+ settingChain,
7124
+ crossChainTrans,
7125
+ checkIsBridgeless,
7126
+ withdrawTo,
7127
+ sourceTokens,
7128
+ onSourceTokenChange,
7129
+ vaultBalanceList,
7130
+ qtyGreaterThanMaxAmount,
7131
+ isTokenUnsupported,
7132
+ onSwitchToSupportedNetwork,
7133
+ externalWallets,
7134
+ selectedWalletAddress,
7135
+ onSelectWallet,
7136
+ onAddExternalWallet,
7137
+ isEnableTrading,
7138
+ enableWithdrawToExternalWallet
7139
+ } = props;
7140
+ const { t } = useTranslation();
7141
+ const [addWalletOpen, setAddWalletOpen] = useState(false);
7142
+ const handleAddExternalWallet = (address2, network) => {
7143
+ onAddExternalWallet?.(address2, network);
7144
+ };
7145
+ const internalWithdrawPanel = /* @__PURE__ */ jsxs(
7146
+ TabPanel,
7147
+ {
7148
+ title: t("transfer.withdraw.otherAccount", {
7149
+ brokerName: props.brokerName
7150
+ }),
7151
+ value: "accountId" /* Account */,
7152
+ children: [
7153
+ /* @__PURE__ */ jsx(
7154
+ TextAreaInput,
7155
+ {
7156
+ label: t("common.accountId"),
7157
+ value: props.toAccountId,
7158
+ onChange: props.setToAccountId,
7159
+ status: props.toAccountIdInputStatus,
7160
+ hintMessage: props.toAccountIdHintMessage,
7161
+ disabled: !props.isLoggedIn,
7162
+ placeholder: t("transfer.withdraw.accountIdOrAddress.placeholder"),
7163
+ enableAccountLookup: true,
7164
+ accountInfo: props.toAccountInfo,
7165
+ accountDropdownOpen: props.toAccountInfoDropdownOpen,
7166
+ setAccountDropdownOpen: props.setToAccountInfoDropdownOpen
7167
+ }
7168
+ ),
7169
+ /* @__PURE__ */ jsx(Box, { mb: 1, px: 2, children: /* @__PURE__ */ jsx(Text, { size: "xs", intensity: 54, children: t("transfer.withdraw.accountIdOrAddress.hint") }) })
7170
+ ]
7171
+ }
7172
+ );
7173
+ return /* @__PURE__ */ jsxs(
7174
+ Box,
7175
+ {
7176
+ id: "oui-withdraw-form",
7177
+ className: textVariants({ weight: "semibold" }),
7178
+ children: [
7179
+ /* @__PURE__ */ jsxs(Box, { className: "oui-mb-6 lg:oui-mb-8", children: [
7180
+ /* @__PURE__ */ jsx(BrokerWallet, {}),
7181
+ /* @__PURE__ */ jsx(Box, { mt: 3, mb: 1, children: /* @__PURE__ */ jsx(
7182
+ QuantityInput,
7183
+ {
7184
+ value: quantity,
7185
+ onValueChange: onQuantityChange,
7186
+ token: sourceToken,
7187
+ tokens: sourceTokens,
7188
+ onTokenChange: onSourceTokenChange,
7189
+ status: props.inputStatus,
7190
+ hintMessage: props.hintMessage,
7191
+ hintSuffix: isTokenUnsupported ? /* @__PURE__ */ jsxs(
7192
+ "button",
7193
+ {
7194
+ type: "button",
7195
+ onClick: onSwitchToSupportedNetwork,
7196
+ className: "oui-inline-flex oui-items-center oui-gap-1 oui-text-2xs oui-font-semibold oui-text-primary",
7197
+ children: [
7198
+ t("common.switch"),
7199
+ /* @__PURE__ */ jsx(
7200
+ ArrowLeftRightIcon,
7201
+ {
7202
+ size: 16,
7203
+ className: "oui-text-primary oui-mt-0.5",
7204
+ opacity: 1
7205
+ }
7206
+ )
7207
+ ]
7208
+ }
7209
+ ) : void 0,
7210
+ vaultBalanceList,
7211
+ testId: "oui-testid-withdraw-dialog-quantity-input",
7212
+ displayType: "vaultBalance",
7213
+ disabled: !props.isLoggedIn
7214
+ }
7215
+ ) }),
7216
+ /* @__PURE__ */ jsx(
7217
+ AvailableQuantity,
7218
+ {
7219
+ token: sourceToken,
7220
+ amount,
7221
+ maxQuantity: maxQuantity.toString(),
7222
+ loading: props.balanceRevalidating,
7223
+ onClick: () => {
7224
+ onQuantityChange(maxQuantity.toString());
7225
+ },
7226
+ tooltipContent: t("transfer.withdraw.available.tooltip", {
7227
+ amount: maxQuantity.toString()
7228
+ })
7229
+ }
7230
+ ),
7231
+ /* @__PURE__ */ jsx(Box, { mx: 2, mt: 1, children: /* @__PURE__ */ jsx(
7232
+ UnsettlePnlInfo,
7233
+ {
7234
+ unsettledPnl: props.unsettledPnL,
7235
+ hasPositions: props.hasPositions,
7236
+ onSettlePnl: props.onSettlePnl,
7237
+ tooltipContent: t("settle.unsettled.tooltip"),
7238
+ dialogContent: /* @__PURE__ */ jsx(Trans, { i18nKey: "settle.settlePnl.description" })
7239
+ }
7240
+ ) }),
7241
+ /* @__PURE__ */ jsx(ExchangeDivider, {}),
7242
+ /* @__PURE__ */ jsxs(
7243
+ Tabs,
7244
+ {
7245
+ value: withdrawTo,
7246
+ onValueChange: props.setWithdrawTo,
7247
+ variant: "contained",
7248
+ size: "lg",
7249
+ classNames: {
7250
+ tabsList: "oui-px-0",
7251
+ tabsContent: "oui-pt-3"
7252
+ },
7253
+ children: [
7254
+ /* @__PURE__ */ jsxs(
7255
+ TabPanel,
7256
+ {
7257
+ title: t("transfer.web3Wallet.my"),
7258
+ icon: props.walletName ? /* @__PURE__ */ jsx(WalletIcon, { size: "xs", name: props.walletName ?? "" }) : void 0,
7259
+ value: "wallet" /* Wallet */,
7260
+ children: [
7261
+ isEnableTrading && enableWithdrawToExternalWallet && /* @__PURE__ */ jsx(
7262
+ WalletSelector,
7263
+ {
7264
+ connectedWallet: address ? {
7265
+ name: walletName || t("common.wallet"),
7266
+ address,
7267
+ namespace: currentChain?.namespace
7268
+ } : void 0,
7269
+ externalWallets: externalWallets || [],
7270
+ selectedAddress: selectedWalletAddress ?? "",
7271
+ onSelect: onSelectWallet,
7272
+ onAddExternalWallet: () => setAddWalletOpen(true)
7273
+ }
7274
+ ),
7275
+ /* @__PURE__ */ jsx(Box, { mb: 1, children: /* @__PURE__ */ jsx(
7276
+ ChainSelect,
7277
+ {
7278
+ chains: tokenChains,
7279
+ value: currentChain,
7280
+ onValueChange: props.onChainChange,
7281
+ wrongNetwork: props.wrongNetwork,
7282
+ loading: settingChain,
7283
+ disabled: !props.isLoggedIn
7284
+ }
7285
+ ) }),
7286
+ /* @__PURE__ */ jsx(
7287
+ QuantityInput,
7288
+ {
7289
+ classNames: {
7290
+ root: "oui-mt-[2px] oui-rounded-t-sm oui-rounded-b-xl"
7291
+ },
7292
+ token: sourceToken,
7293
+ value: props.showQty,
7294
+ readOnly: true
7295
+ }
7296
+ )
7297
+ ]
7298
+ }
7299
+ ),
7300
+ internalWithdrawPanel
7301
+ ]
7302
+ }
7303
+ ),
7304
+ /* @__PURE__ */ jsx(Box, { mt: 2, px: 2, children: /* @__PURE__ */ jsx(
7305
+ LtvWidget,
7306
+ {
7307
+ showDiff: typeof quantity !== "undefined" && Number(quantity) > 0,
7308
+ currentLtv: props.currentLTV,
7309
+ nextLTV: props.nextLTV
7310
+ }
7311
+ ) }),
7312
+ /* @__PURE__ */ jsx(Flex, { direction: "column", mt: 1, gapY: 1, px: 2, itemAlign: "start", children: /* @__PURE__ */ jsxs(Text, { size: "xs", intensity: 36, children: [
7313
+ t("common.fee"),
7314
+ withdrawTo === "wallet" /* Wallet */ ? " \u2248 " : " = ",
7315
+ /* @__PURE__ */ jsx(Text, { size: "xs", intensity: 80, children: fee })
7316
+ ] }) })
7317
+ ] }),
7318
+ /* @__PURE__ */ jsx(
7319
+ WithdrawWarningMessage,
7320
+ {
7321
+ checkIsBridgeless,
7322
+ crossChainTrans,
7323
+ qtyGreaterThanMaxAmount,
7324
+ message: props.warningMessage
7325
+ }
7326
+ ),
7327
+ /* @__PURE__ */ jsx(Flex, { justify: "center", children: /* @__PURE__ */ jsx(
7328
+ WithdrawAction,
7329
+ {
7330
+ checkIsBridgeless,
7331
+ networkId: props.networkId,
7332
+ disabled,
7333
+ loading,
7334
+ onWithdraw: props.onWithdraw,
7335
+ crossChainWithdraw: props.crossChainWithdraw,
7336
+ currentChain,
7337
+ address,
7338
+ quantity,
7339
+ fee,
7340
+ withdrawTo,
7341
+ onTransfer: props.onTransfer
7342
+ }
7343
+ ) }),
7344
+ enableWithdrawToExternalWallet && /* @__PURE__ */ jsx(
7345
+ AddWalletDialog,
7346
+ {
7347
+ open: addWalletOpen,
7348
+ onOpenChange: setAddWalletOpen,
7349
+ onConfirm: handleAddExternalWallet,
7350
+ chain: currentChain
7351
+ }
7352
+ )
7353
+ ]
7354
+ }
7355
+ );
6672
7356
  };
6673
7357
  var WithdrawFormWidget = (props) => {
6674
7358
  const state = useWithdrawFormScript(props);