@orderly.network/ui-transfer 2.8.8 → 2.8.9

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