@unifold/ui-react 0.1.42 → 0.1.44

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,10 +1,10 @@
1
1
  // src/components/deposits/DepositModal.tsx
2
2
  import {
3
3
  useState as useState27,
4
- useEffect as useEffect21,
4
+ useEffect as useEffect22,
5
5
  useLayoutEffect as useLayoutEffect2,
6
6
  useCallback as useCallback4,
7
- useRef as useRef6,
7
+ useRef as useRef7,
8
8
  useMemo as useMemo9
9
9
  } from "react";
10
10
  import { ChevronRight as ChevronRight11, MapPinOff, AlertTriangle } from "lucide-react";
@@ -1398,6 +1398,7 @@ function interpolate(template, params) {
1398
1398
  import { useState as useState5, useEffect as useEffect3, useRef } from "react";
1399
1399
  import {
1400
1400
  queryExecutions,
1401
+ listPaymentIntentExecutions,
1401
1402
  pollDirectExecutions,
1402
1403
  ExecutionStatus,
1403
1404
  ActionType
@@ -1409,6 +1410,7 @@ var CUTOFF_BUFFER_MS = 6e4;
1409
1410
  function useDepositPolling({
1410
1411
  userId,
1411
1412
  publishableKey,
1413
+ clientSecret,
1412
1414
  depositConfirmationMode = "auto_ui",
1413
1415
  depositWalletId,
1414
1416
  enabled = true,
@@ -1466,11 +1468,12 @@ function useDepositPolling({
1466
1468
  depositWalletId
1467
1469
  ]);
1468
1470
  useEffect3(() => {
1469
- if (!userId || !enabled) return;
1471
+ if (!enabled) return;
1472
+ if (!clientSecret && !userId) return;
1470
1473
  const modalOpenedAt = modalOpenedAtRef.current;
1471
1474
  const poll = async () => {
1472
1475
  try {
1473
- const response = await queryExecutions(userId, publishableKey, ActionType.Deposit);
1476
+ const response = clientSecret ? await listPaymentIntentExecutions(clientSecret, publishableKey) : await queryExecutions(userId, publishableKey, ActionType.Deposit);
1474
1477
  const cutoff = new Date(modalOpenedAt.getTime() - CUTOFF_BUFFER_MS);
1475
1478
  const sortedExecutions = [...response.data].sort((a, b) => {
1476
1479
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
@@ -1554,7 +1557,7 @@ function useDepositPolling({
1554
1557
  clearInterval(pollInterval);
1555
1558
  setIsPolling(false);
1556
1559
  };
1557
- }, [userId, publishableKey, enabled]);
1560
+ }, [userId, publishableKey, clientSecret, enabled]);
1558
1561
  useEffect3(() => {
1559
1562
  if (!pollingEnabled || !depositWalletId) return;
1560
1563
  const triggerPoll = async () => {
@@ -8329,6 +8332,7 @@ var parseChainKey = (chainKey) => {
8329
8332
  function TransferCryptoSingleInput({
8330
8333
  userId,
8331
8334
  publishableKey,
8335
+ clientSecret,
8332
8336
  recipientAddress,
8333
8337
  destinationChainType,
8334
8338
  destinationChainId,
@@ -8341,7 +8345,9 @@ function TransferCryptoSingleInput({
8341
8345
  onExecutionsChange,
8342
8346
  onDepositSuccess,
8343
8347
  onDepositError,
8344
- wallets: externalWallets
8348
+ wallets: externalWallets,
8349
+ onSourceTokenChange,
8350
+ checkoutQuote
8345
8351
  }) {
8346
8352
  const { themeClass, colors: colors2, fonts, components } = useTheme();
8347
8353
  const isDarkMode = themeClass.includes("uf-dark");
@@ -8408,12 +8414,28 @@ function TransferCryptoSingleInput({
8408
8414
  } = useDepositPolling({
8409
8415
  userId,
8410
8416
  publishableKey,
8417
+ clientSecret,
8411
8418
  depositConfirmationMode,
8412
8419
  depositWalletId: currentWallet?.id,
8413
8420
  enabled: true,
8414
8421
  onDepositSuccess,
8415
8422
  onDepositError
8416
8423
  });
8424
+ useEffect17(() => {
8425
+ if (!onSourceTokenChange || !token || !chain || !initialSelectionDone) return;
8426
+ const { chainType, chainId } = parseChainKey(chain);
8427
+ const matchedToken = supportedTokens.find((t11) => t11.symbol === token);
8428
+ const matchedChain = matchedToken?.chains.find(
8429
+ (c) => c.chain_type === chainType && c.chain_id === chainId
8430
+ );
8431
+ onSourceTokenChange({
8432
+ symbol: token,
8433
+ chainType,
8434
+ chainId,
8435
+ tokenAddress: matchedChain?.token_address ?? "",
8436
+ minimumDepositAmountUsd: matchedChain?.minimum_deposit_amount_usd ?? 0
8437
+ });
8438
+ }, [token, chain, initialSelectionDone, onSourceTokenChange, supportedTokens]);
8417
8439
  useEffect17(() => {
8418
8440
  if (onExecutionsChange) {
8419
8441
  onExecutionsChange(depositExecutions);
@@ -8560,6 +8582,53 @@ function TransferCryptoSingleInput({
8560
8582
  /* @__PURE__ */ jsx41("span", { children: "Retrying automatically every 5 seconds..." })
8561
8583
  ] })
8562
8584
  ] }),
8585
+ checkoutQuote && /* @__PURE__ */ jsxs35(
8586
+ "div",
8587
+ {
8588
+ className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
8589
+ style: {
8590
+ backgroundColor: components.card.backgroundColor,
8591
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
8592
+ borderRadius: components.card.borderRadius
8593
+ },
8594
+ children: [
8595
+ /* @__PURE__ */ jsx41(
8596
+ "span",
8597
+ {
8598
+ className: "uf-text-xs",
8599
+ style: { color: components.card.subtitleColor, fontFamily: fonts.regular },
8600
+ children: "You send"
8601
+ }
8602
+ ),
8603
+ /* @__PURE__ */ jsxs35(
8604
+ "span",
8605
+ {
8606
+ className: "uf-text-sm uf-font-semibold",
8607
+ style: { color: components.card.titleColor, fontFamily: fonts.semibold },
8608
+ children: [
8609
+ (Number(checkoutQuote.sourceAmount) / 10 ** checkoutQuote.sourceTokenDecimals).toFixed(
8610
+ Math.min(checkoutQuote.sourceTokenDecimals, 6)
8611
+ ),
8612
+ " ",
8613
+ checkoutQuote.sourceTokenSymbol,
8614
+ checkoutQuote.sourceAmountUsd && /* @__PURE__ */ jsxs35(
8615
+ "span",
8616
+ {
8617
+ className: "uf-text-xs uf-font-normal uf-ml-1.5",
8618
+ style: { color: components.card.subtitleColor },
8619
+ children: [
8620
+ "($",
8621
+ checkoutQuote.sourceAmountUsd,
8622
+ ")"
8623
+ ]
8624
+ }
8625
+ )
8626
+ ]
8627
+ }
8628
+ )
8629
+ ]
8630
+ }
8631
+ ),
8563
8632
  /* @__PURE__ */ jsxs35("div", { className: "uf-flex uf-flex-col uf-items-center uf-pt-2", children: [
8564
8633
  /* @__PURE__ */ jsx41("div", { className: "uf-text-xs uf-mb-2 uf-flex uf-items-center uf-gap-1", style: { color: components.card.labelColor }, children: "Intent address" }),
8565
8634
  /* @__PURE__ */ jsx41("div", { className: "uf-shadow-lg", style: { borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` }, children: loading || tokensLoading || !initialSelectionDone ? (
@@ -9429,9 +9498,16 @@ function SelectTokenView({
9429
9498
  onBack,
9430
9499
  onClose,
9431
9500
  onDisconnectWallet,
9432
- isDisconnectingWallet = false
9501
+ isDisconnectingWallet = false,
9502
+ checkoutAmountUsd,
9503
+ checkoutReceivedUsd
9433
9504
  }) {
9434
9505
  const { colors: colors2, fonts, components } = useTheme();
9506
+ const isCheckout = !!checkoutAmountUsd;
9507
+ const headerSubtitle = isCheckout ? parseFloat(checkoutReceivedUsd || "0") > 0 ? `$${checkoutReceivedUsd} / $${checkoutAmountUsd} received` : `Amount due: $${checkoutAmountUsd}` : formatBalanceDisplay(
9508
+ `$${totalBalanceUsd || "0.00"}`,
9509
+ projectName
9510
+ );
9435
9511
  return /* @__PURE__ */ jsxs38(
9436
9512
  "div",
9437
9513
  {
@@ -9440,11 +9516,8 @@ function SelectTokenView({
9440
9516
  /* @__PURE__ */ jsx45(
9441
9517
  DepositHeader,
9442
9518
  {
9443
- title: "Select Token",
9444
- subtitle: formatBalanceDisplay(
9445
- `$${totalBalanceUsd || "0.00"}`,
9446
- projectName
9447
- ),
9519
+ title: isCheckout ? "Select Token" : "Select Token",
9520
+ subtitle: headerSubtitle,
9448
9521
  showBack: true,
9449
9522
  onBack,
9450
9523
  onClose
@@ -9675,10 +9748,19 @@ function EnterAmountView({
9675
9748
  onReview,
9676
9749
  onBack,
9677
9750
  onClose,
9678
- quickSelectMode
9751
+ quickSelectMode,
9752
+ checkoutAmountUsd,
9753
+ checkoutReceivedUsd
9679
9754
  }) {
9680
9755
  const { colors: colors2, fonts, components } = useTheme();
9756
+ const isCheckout = !!checkoutAmountUsd;
9681
9757
  const balanceSubtitle = selectedBalance?.amount_usd ? `Balance: $${parseFloat(selectedBalance.amount_usd).toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (${formatTokenAmount(selectedBalance.amount, selectedToken.decimals, selectedToken.symbol)} ${selectedToken.symbol})` : `Balance: ${formatTokenAmount(selectedBalance.amount, selectedToken.decimals, selectedToken.symbol)} ${selectedToken.symbol}`;
9758
+ const checkoutRemainingUsd = isCheckout ? Math.max(
9759
+ parseFloat(checkoutAmountUsd) - parseFloat(checkoutReceivedUsd || "0"),
9760
+ 0
9761
+ ).toFixed(2) : null;
9762
+ const headerTitle = isCheckout ? `Pay $${checkoutRemainingUsd}` : "Enter Amount";
9763
+ const headerSubtitle = isCheckout ? parseFloat(checkoutReceivedUsd || "0") > 0 ? `$${checkoutReceivedUsd} / $${checkoutAmountUsd} received` : null : balanceSubtitle;
9682
9764
  const usePercentageChips = quickSelectMode === "percentage" && maxUsdAmount > 0;
9683
9765
  const chipButtonClass = "uf-flex-1 uf-min-w-0 uf-basis-0 uf-py-2 uf-px-1 uf-rounded-lg uf-text-sm uf-font-medium uf-transition-colors hover:uf-opacity-80 uf-whitespace-nowrap";
9684
9766
  return /* @__PURE__ */ jsxs39(
@@ -9692,14 +9774,27 @@ function EnterAmountView({
9692
9774
  /* @__PURE__ */ jsx46(
9693
9775
  DepositHeader,
9694
9776
  {
9695
- title: "Enter Amount",
9696
- subtitle: balanceSubtitle,
9777
+ title: headerTitle,
9778
+ subtitle: headerSubtitle ?? void 0,
9697
9779
  showBack: true,
9698
9780
  onBack,
9699
9781
  onClose
9700
9782
  }
9701
9783
  ),
9702
- walletInfoProp ? /* @__PURE__ */ jsx46("div", { className: "uf-flex uf-w-full uf-justify-center uf-mb-3", children: /* @__PURE__ */ jsx46(WalletWithNetworkBadge, { walletInfo: walletInfoProp }) }) : null,
9784
+ walletInfoProp ? /* @__PURE__ */ jsx46("div", { className: "uf-flex uf-w-full uf-justify-center uf-mb-3", children: /* @__PURE__ */ jsxs39("div", { className: "uf-flex uf-flex-col uf-items-center uf-gap-1", children: [
9785
+ /* @__PURE__ */ jsx46(WalletWithNetworkBadge, { walletInfo: walletInfoProp }),
9786
+ isCheckout && /* @__PURE__ */ jsx46(
9787
+ "span",
9788
+ {
9789
+ className: "uf-text-xs",
9790
+ style: {
9791
+ color: colors2.foregroundMuted,
9792
+ fontFamily: fonts.regular
9793
+ },
9794
+ children: balanceSubtitle
9795
+ }
9796
+ )
9797
+ ] }) }) : null,
9703
9798
  /* @__PURE__ */ jsxs39("div", { className: "uf-flex uf-min-h-0 uf-flex-1 uf-flex-col", children: [
9704
9799
  /* @__PURE__ */ jsxs39("div", { className: "uf-min-h-0 uf-flex-1", children: [
9705
9800
  /* @__PURE__ */ jsxs39("div", { className: "uf-text-center uf-py-8", children: [
@@ -9722,7 +9817,9 @@ function EnterAmountView({
9722
9817
  inputMode: "decimal",
9723
9818
  placeholder: "0",
9724
9819
  value: amountUsd,
9820
+ readOnly: isCheckout,
9725
9821
  onChange: (e) => {
9822
+ if (isCheckout) return;
9726
9823
  const value = e.target.value;
9727
9824
  if (value === "" || /^\d*\.?\d*$/.test(value)) {
9728
9825
  const decimalIndex = value.indexOf(".");
@@ -9733,7 +9830,7 @@ function EnterAmountView({
9733
9830
  onAmountChange(value);
9734
9831
  }
9735
9832
  },
9736
- className: "uf-bg-transparent uf-outline-none uf-text-center uf-font-normal uf-w-auto uf-min-w-[60px]",
9833
+ className: `uf-bg-transparent uf-outline-none uf-text-center uf-font-normal uf-w-auto uf-min-w-[60px] ${isCheckout ? "uf-cursor-default" : ""}`,
9737
9834
  style: {
9738
9835
  fontSize: `${Math.max(3.75 - (amountUsd || "0").length * 0.15, 2)}rem`,
9739
9836
  color: components.input.textColor,
@@ -9755,7 +9852,7 @@ function EnterAmountView({
9755
9852
  }
9756
9853
  )
9757
9854
  ] }),
9758
- /* @__PURE__ */ jsx46("div", { className: "uf-mb-4 uf-flex uf-w-full uf-min-w-0 uf-flex-nowrap uf-gap-1.5 uf-overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: usePercentageChips ? /* @__PURE__ */ jsxs39(Fragment5, { children: [
9855
+ !isCheckout && /* @__PURE__ */ jsx46("div", { className: "uf-mb-4 uf-flex uf-w-full uf-min-w-0 uf-flex-nowrap uf-gap-1.5 uf-overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: usePercentageChips ? /* @__PURE__ */ jsxs39(Fragment5, { children: [
9759
9856
  PERCENT_QUICK_AMOUNTS.map((pct) => /* @__PURE__ */ jsxs39(
9760
9857
  "button",
9761
9858
  {
@@ -9824,7 +9921,46 @@ function EnterAmountView({
9824
9921
  }
9825
9922
  )
9826
9923
  ] }) }),
9827
- tokenChainDetails && tokenChainDetails.minimum_deposit_amount_usd > 0 && /* @__PURE__ */ jsxs39(
9924
+ tokenChainDetails && tokenChainDetails.minimum_deposit_amount_usd > 0 && (isCheckout && checkoutAmountUsd && inputUsdNum > parseFloat(checkoutAmountUsd) - parseFloat(checkoutReceivedUsd || "0") + 5e-3 ? /* @__PURE__ */ jsxs39(
9925
+ "div",
9926
+ {
9927
+ className: "uf-rounded-lg uf-px-3 uf-py-2 uf-mb-3 uf-text-center",
9928
+ style: {
9929
+ backgroundColor: colors2.warning + "15",
9930
+ border: `1px solid ${colors2.warning}30`,
9931
+ borderRadius: components.card.borderRadius,
9932
+ animation: "uf-fadeSlideIn 0.4s ease-out"
9933
+ },
9934
+ children: [
9935
+ /* @__PURE__ */ jsxs39(
9936
+ "div",
9937
+ {
9938
+ className: "uf-text-xs uf-font-medium",
9939
+ style: { color: colors2.warning, fontFamily: fonts.medium },
9940
+ children: [
9941
+ "Minimum for ",
9942
+ selectedToken.symbol,
9943
+ " on ",
9944
+ selectedToken.chain_name,
9945
+ " is $",
9946
+ tokenChainDetails.minimum_deposit_amount_usd.toFixed(2)
9947
+ ]
9948
+ }
9949
+ ),
9950
+ /* @__PURE__ */ jsxs39(
9951
+ "div",
9952
+ {
9953
+ className: "uf-text-xs uf-mt-0.5",
9954
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
9955
+ children: [
9956
+ "Amount adjusted from remaining $",
9957
+ (parseFloat(checkoutAmountUsd) - parseFloat(checkoutReceivedUsd || "0")).toFixed(2)
9958
+ ]
9959
+ }
9960
+ )
9961
+ ]
9962
+ }
9963
+ ) : /* @__PURE__ */ jsxs39(
9828
9964
  "div",
9829
9965
  {
9830
9966
  className: "uf-text-center uf-text-xs uf-mb-3",
@@ -9834,7 +9970,7 @@ function EnterAmountView({
9834
9970
  tokenChainDetails.minimum_deposit_amount_usd.toFixed(2)
9835
9971
  ]
9836
9972
  }
9837
- ),
9973
+ )),
9838
9974
  inputUsdNum > 0 && /* @__PURE__ */ jsx46(Fragment5, { children: inputUsdNum > maxUsdAmount ? /* @__PURE__ */ jsx46(
9839
9975
  "div",
9840
9976
  {
@@ -9849,7 +9985,44 @@ function EnterAmountView({
9849
9985
  style: { color: colors2.error },
9850
9986
  children: error
9851
9987
  }
9852
- ) })
9988
+ ) }),
9989
+ isCheckout && selectedToken.icon_url && /* @__PURE__ */ jsxs39("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-py-2", children: [
9990
+ /* @__PURE__ */ jsxs39("div", { className: "uf-relative", children: [
9991
+ /* @__PURE__ */ jsx46(
9992
+ "img",
9993
+ {
9994
+ src: selectedToken.icon_url,
9995
+ alt: selectedToken.symbol,
9996
+ width: 20,
9997
+ height: 20,
9998
+ className: "uf-w-5 uf-h-5 uf-rounded-full"
9999
+ }
10000
+ ),
10001
+ selectedToken.chain_icon_url && /* @__PURE__ */ jsx46(
10002
+ "img",
10003
+ {
10004
+ src: selectedToken.chain_icon_url,
10005
+ alt: selectedToken.chain_name,
10006
+ width: 10,
10007
+ height: 10,
10008
+ className: "uf-w-2.5 uf-h-2.5 uf-rounded-full uf-absolute -uf-bottom-0.5 -uf-right-0.5 uf-border",
10009
+ style: { borderColor: colors2.background }
10010
+ }
10011
+ )
10012
+ ] }),
10013
+ /* @__PURE__ */ jsxs39(
10014
+ "span",
10015
+ {
10016
+ className: "uf-text-xs",
10017
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
10018
+ children: [
10019
+ selectedToken.symbol,
10020
+ " on ",
10021
+ selectedToken.chain_name
10022
+ ]
10023
+ }
10024
+ )
10025
+ ] })
9853
10026
  ] }),
9854
10027
  /* @__PURE__ */ jsx46("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ jsx46(
9855
10028
  "button",
@@ -9875,8 +10048,20 @@ function EnterAmountView({
9875
10048
  }
9876
10049
 
9877
10050
  // src/components/deposits/browser-wallets/ReviewView.tsx
9878
- import { ChevronDown as ChevronDown6, ChevronUp as ChevronUp5 } from "lucide-react";
10051
+ import { ChevronDown as ChevronDown6, ChevronUp as ChevronUp5, Loader2 as Loader23 } from "lucide-react";
9879
10052
  import { Fragment as Fragment6, jsx as jsx47, jsxs as jsxs40 } from "react/jsx-runtime";
10053
+ var WALLET_ICONS2 = {
10054
+ metamask: MetamaskIcon,
10055
+ phantom: PhantomIcon,
10056
+ coinbase: CoinbaseIcon,
10057
+ trust: TrustIcon,
10058
+ rainbow: RainbowIcon,
10059
+ rabby: RabbyIcon,
10060
+ okx: OkxIcon,
10061
+ solflare: SolflareIcon,
10062
+ backpack: BackpackIcon,
10063
+ glow: GlowIcon
10064
+ };
9880
10065
  function ReviewView({
9881
10066
  walletInfo,
9882
10067
  recipientAddress,
@@ -9911,30 +10096,17 @@ function ReviewView({
9911
10096
  ),
9912
10097
  /* @__PURE__ */ jsxs40("div", { className: "uf-flex uf-min-h-0 uf-flex-1 uf-flex-col", children: [
9913
10098
  /* @__PURE__ */ jsxs40("div", { className: "uf-min-h-0 uf-flex-1 uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: [
9914
- /* @__PURE__ */ jsxs40("div", { className: "uf-text-center", children: [
9915
- /* @__PURE__ */ jsxs40(
9916
- "div",
9917
- {
9918
- className: "uf-text-4xl uf-font-medium",
9919
- style: { color: colors2.foreground, fontFamily: fonts.medium },
9920
- children: [
9921
- "$",
9922
- amountUsd || "0"
9923
- ]
9924
- }
9925
- ),
9926
- formattedTokenAmount && /* @__PURE__ */ jsxs40(
9927
- "div",
9928
- {
9929
- className: "uf-text-sm uf-mt-2",
9930
- style: { color: colors2.foregroundMuted },
9931
- children: [
9932
- "\u2248 ",
9933
- formattedTokenAmount
9934
- ]
9935
- }
9936
- )
9937
- ] }),
10099
+ /* @__PURE__ */ jsx47("div", { className: "uf-text-center", children: /* @__PURE__ */ jsxs40(
10100
+ "div",
10101
+ {
10102
+ className: "uf-text-4xl uf-font-medium",
10103
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
10104
+ children: [
10105
+ "$",
10106
+ amountUsd || "0"
10107
+ ]
10108
+ }
10109
+ ) }),
9938
10110
  /* @__PURE__ */ jsxs40(
9939
10111
  "div",
9940
10112
  {
@@ -9951,7 +10123,31 @@ function ReviewView({
9951
10123
  {
9952
10124
  className: "uf-text-sm",
9953
10125
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
9954
- children: "Source"
10126
+ children: "From"
10127
+ }
10128
+ ),
10129
+ /* @__PURE__ */ jsxs40("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
10130
+ WALLET_ICONS2[walletInfo.icon] && (() => {
10131
+ const Icon2 = WALLET_ICONS2[walletInfo.icon];
10132
+ return /* @__PURE__ */ jsx47("div", { className: "uf-w-5 uf-h-5 uf-rounded-full uf-overflow-hidden uf-flex-shrink-0", children: /* @__PURE__ */ jsx47(Icon2, { size: 20, variant: "color" }) });
10133
+ })(),
10134
+ /* @__PURE__ */ jsx47(
10135
+ "span",
10136
+ {
10137
+ className: "uf-text-sm uf-font-medium",
10138
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
10139
+ children: walletInfo.name
10140
+ }
10141
+ )
10142
+ ] })
10143
+ ] }),
10144
+ /* @__PURE__ */ jsxs40("div", { className: "uf-flex uf-justify-between uf-items-center", children: [
10145
+ /* @__PURE__ */ jsx47(
10146
+ "span",
10147
+ {
10148
+ className: "uf-text-sm",
10149
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
10150
+ children: "You send"
9955
10151
  }
9956
10152
  ),
9957
10153
  /* @__PURE__ */ jsxs40("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
@@ -9963,17 +10159,12 @@ function ReviewView({
9963
10159
  className: "uf-w-5 uf-h-5 uf-rounded-full"
9964
10160
  }
9965
10161
  ),
9966
- /* @__PURE__ */ jsxs40(
10162
+ /* @__PURE__ */ jsx47(
9967
10163
  "span",
9968
10164
  {
9969
10165
  className: "uf-text-sm uf-font-medium",
9970
10166
  style: { color: colors2.foreground, fontFamily: fonts.medium },
9971
- children: [
9972
- walletInfo.name,
9973
- " (",
9974
- truncateAddress2(walletInfo.address),
9975
- ")"
9976
- ]
10167
+ children: formattedTokenAmount || `$${amountUsd}`
9977
10168
  }
9978
10169
  )
9979
10170
  ] })
@@ -10136,7 +10327,10 @@ function ReviewView({
10136
10327
  borderRadius: components.button.borderRadius,
10137
10328
  border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
10138
10329
  },
10139
- children: isConfirming ? "Confirming..." : "Confirm Order"
10330
+ children: isConfirming ? /* @__PURE__ */ jsxs40("span", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2", children: [
10331
+ /* @__PURE__ */ jsx47(Loader23, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
10332
+ "Confirming..."
10333
+ ] }) : "Confirm Order"
10140
10334
  }
10141
10335
  ) })
10142
10336
  ] })
@@ -10147,20 +10341,38 @@ function ReviewView({
10147
10341
  }
10148
10342
 
10149
10343
  // src/components/deposits/browser-wallets/ConfirmingView.tsx
10150
- import { useCallback as useCallback2, useState as useState24 } from "react";
10151
- import { Loader2 as Loader23, CheckCircle2 } from "lucide-react";
10344
+ import { useCallback as useCallback2, useEffect as useEffect19, useState as useState24 } from "react";
10345
+ import { Loader2 as Loader24, CheckCircle2, ArrowRight } from "lucide-react";
10152
10346
  import { Fragment as Fragment7, jsx as jsx48, jsxs as jsxs41 } from "react/jsx-runtime";
10347
+ var SETTLE_FALLBACK_MS = 15e3;
10153
10348
  function ConfirmingView({
10154
10349
  isConfirming,
10155
10350
  onClose,
10156
10351
  executions = [],
10157
- isPolling = false
10352
+ isPolling = false,
10353
+ onNewDeposit,
10354
+ onDone,
10355
+ paymentIntentStatus,
10356
+ amountReceivedUsd,
10357
+ amountReceivedUsdAtSubmission
10158
10358
  }) {
10159
- const { colors: colors2, fonts } = useTheme();
10359
+ const { colors: colors2, fonts, components } = useTheme();
10160
10360
  const [containerEl, setContainerEl] = useState24(null);
10161
10361
  const containerCallbackRef = useCallback2((el) => {
10162
10362
  setContainerEl(el);
10163
10363
  }, []);
10364
+ const [fallbackSettled, setFallbackSettled] = useState24(false);
10365
+ const hasExecution = executions.length > 0;
10366
+ const isCheckoutMode = paymentIntentStatus != null;
10367
+ const isPaymentComplete = paymentIntentStatus === "succeeded";
10368
+ const amountChanged = amountReceivedUsdAtSubmission != null && amountReceivedUsd != null && amountReceivedUsd !== amountReceivedUsdAtSubmission;
10369
+ const piSettled = !isCheckoutMode || isPaymentComplete || amountChanged || fallbackSettled;
10370
+ useEffect19(() => {
10371
+ if (!hasExecution || piSettled) return;
10372
+ const timeout = setTimeout(() => setFallbackSettled(true), SETTLE_FALLBACK_MS);
10373
+ return () => clearTimeout(timeout);
10374
+ }, [hasExecution, piSettled]);
10375
+ const showButtons = hasExecution && piSettled;
10164
10376
  return /* @__PURE__ */ jsx48(PortalContainerProvider, { value: containerEl, children: /* @__PURE__ */ jsxs41(
10165
10377
  "div",
10166
10378
  {
@@ -10173,13 +10385,13 @@ function ConfirmingView({
10173
10385
  /* @__PURE__ */ jsx48(
10174
10386
  DepositHeader,
10175
10387
  {
10176
- title: isConfirming ? "Confirming..." : "Processing",
10177
- onClose
10388
+ title: isConfirming ? "Confirming..." : hasExecution && isPaymentComplete ? "Payment Complete" : hasExecution ? "Deposit Received" : "Processing",
10389
+ onClose: isPaymentComplete && onDone ? onDone : onClose
10178
10390
  }
10179
10391
  ),
10180
10392
  /* @__PURE__ */ jsx48("div", { className: "uf-flex uf-flex-1 uf-flex-col uf-items-center uf-justify-center uf-py-8", children: isConfirming ? /* @__PURE__ */ jsxs41(Fragment7, { children: [
10181
10393
  /* @__PURE__ */ jsx48(
10182
- Loader23,
10394
+ Loader24,
10183
10395
  {
10184
10396
  className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4",
10185
10397
  style: { color: colors2.primary }
@@ -10201,11 +10413,70 @@ function ConfirmingView({
10201
10413
  children: "Please confirm the transaction in your wallet"
10202
10414
  }
10203
10415
  )
10204
- ] }) : /* @__PURE__ */ jsxs41(Fragment7, { children: [
10416
+ ] }) : hasExecution ? /* @__PURE__ */ jsxs41(Fragment7, { children: [
10205
10417
  /* @__PURE__ */ jsx48(
10206
10418
  CheckCircle2,
10207
10419
  {
10208
10420
  className: "uf-w-12 uf-h-12 uf-mb-4",
10421
+ style: { color: "rgb(34, 197, 94)" }
10422
+ }
10423
+ ),
10424
+ /* @__PURE__ */ jsx48(
10425
+ "div",
10426
+ {
10427
+ className: "uf-text-lg uf-font-medium",
10428
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
10429
+ children: isPaymentComplete ? "Payment Complete" : "Deposit Received"
10430
+ }
10431
+ ),
10432
+ /* @__PURE__ */ jsx48(
10433
+ "div",
10434
+ {
10435
+ className: "uf-text-sm uf-mt-2 uf-text-center uf-px-6",
10436
+ style: { color: colors2.foregroundMuted },
10437
+ children: isPaymentComplete ? "Your payment has been fulfilled." : showButtons ? "Your deposit is being processed." : "Checking payment status..."
10438
+ }
10439
+ ),
10440
+ /* @__PURE__ */ jsx48("div", { className: "uf-mt-6 uf-flex uf-flex-col uf-items-center uf-gap-3", children: !showButtons ? /* @__PURE__ */ jsx48(
10441
+ Loader24,
10442
+ {
10443
+ className: "uf-w-5 uf-h-5 uf-animate-spin",
10444
+ style: { color: colors2.foregroundMuted }
10445
+ }
10446
+ ) : isPaymentComplete && onDone ? /* @__PURE__ */ jsx48(
10447
+ "button",
10448
+ {
10449
+ onClick: onDone,
10450
+ className: "uf-w-full uf-py-3 uf-px-8 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
10451
+ style: {
10452
+ backgroundColor: colors2.primary,
10453
+ color: colors2.primaryForeground,
10454
+ fontFamily: fonts.medium,
10455
+ borderRadius: components.button.borderRadius
10456
+ },
10457
+ children: "Done"
10458
+ }
10459
+ ) : onNewDeposit ? /* @__PURE__ */ jsxs41(
10460
+ "button",
10461
+ {
10462
+ onClick: onNewDeposit,
10463
+ className: "uf-flex uf-items-center uf-gap-2 uf-px-5 uf-py-2.5 uf-rounded-lg uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
10464
+ style: {
10465
+ backgroundColor: colors2.primary,
10466
+ color: colors2.primaryForeground,
10467
+ fontFamily: fonts.medium
10468
+ },
10469
+ children: [
10470
+ "Make another deposit",
10471
+ /* @__PURE__ */ jsx48(ArrowRight, { className: "uf-w-4 uf-h-4" })
10472
+ ]
10473
+ }
10474
+ ) : null })
10475
+ ] }) : /* @__PURE__ */ jsxs41(Fragment7, { children: [
10476
+ /* @__PURE__ */ jsx48(
10477
+ Loader24,
10478
+ {
10479
+ className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4",
10209
10480
  style: { color: colors2.primary }
10210
10481
  }
10211
10482
  ),
@@ -10222,7 +10493,7 @@ function ConfirmingView({
10222
10493
  {
10223
10494
  className: "uf-text-sm uf-mt-2 uf-text-center uf-px-6",
10224
10495
  style: { color: colors2.foregroundMuted },
10225
- children: "You can close this window or wait for confirmation."
10496
+ children: "Waiting for your deposit to be detected..."
10226
10497
  }
10227
10498
  )
10228
10499
  ] }) }),
@@ -10249,6 +10520,7 @@ function BrowserWalletModal({
10249
10520
  depositWallet,
10250
10521
  userId,
10251
10522
  publishableKey,
10523
+ clientSecret,
10252
10524
  assetCdnUrl,
10253
10525
  projectName,
10254
10526
  theme = "dark",
@@ -10257,7 +10529,13 @@ function BrowserWalletModal({
10257
10529
  onDepositSuccess,
10258
10530
  onDepositError,
10259
10531
  amountQuickSelect = "percentage",
10260
- onWalletDisconnect
10532
+ onWalletDisconnect,
10533
+ prefillAmountUsd,
10534
+ checkoutAmountUsd,
10535
+ checkoutReceivedUsd,
10536
+ onNewDeposit,
10537
+ onDone,
10538
+ paymentIntentStatus
10261
10539
  }) {
10262
10540
  const { colors: colors2, fonts, components } = useTheme();
10263
10541
  const [step, setStep] = React26.useState("select-token");
@@ -10275,6 +10553,7 @@ function BrowserWalletModal({
10275
10553
  const [tokenChainDetails, setTokenChainDetails] = React26.useState(null);
10276
10554
  const [loadingTokenDetails, setLoadingTokenDetails] = React26.useState(false);
10277
10555
  const [showTransactionDetails, setShowTransactionDetails] = React26.useState(false);
10556
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React26.useState(null);
10278
10557
  const themeClass = theme === "dark" ? "uf-dark" : "";
10279
10558
  const chainType = depositWallet.chain_type;
10280
10559
  const recipientAddress = depositWallet.address;
@@ -10282,15 +10561,19 @@ function BrowserWalletModal({
10282
10561
  const { executions: depositExecutions, isPolling } = useDepositPolling({
10283
10562
  userId,
10284
10563
  publishableKey,
10564
+ clientSecret,
10285
10565
  enabled: open && hasSignedTransaction,
10286
10566
  onDepositSuccess,
10287
10567
  onDepositError
10288
10568
  });
10569
+ const prevOpenRef = React26.useRef(false);
10289
10570
  React26.useEffect(() => {
10290
- if (open) {
10571
+ const wasOpen = prevOpenRef.current;
10572
+ prevOpenRef.current = open;
10573
+ if (open && !wasOpen) {
10291
10574
  setStep("select-token");
10292
10575
  setSelectedBalance(null);
10293
- setAmountUsd("");
10576
+ setAmountUsd(prefillAmountUsd ?? "");
10294
10577
  setError(null);
10295
10578
  setIsConfirming(false);
10296
10579
  setTokenChainDetails(null);
@@ -10298,7 +10581,15 @@ function BrowserWalletModal({
10298
10581
  setHasSignedTransaction(false);
10299
10582
  setIsDisconnectingWallet(false);
10300
10583
  }
10301
- }, [open]);
10584
+ }, [open, prefillAmountUsd]);
10585
+ React26.useEffect(() => {
10586
+ if (!prefillAmountUsd || !tokenChainDetails || step !== "input-amount") return;
10587
+ const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
10588
+ const currentAmount = parseFloat(amountUsd) || 0;
10589
+ if (currentAmount > 0 && currentAmount < minDeposit) {
10590
+ setAmountUsd(minDeposit.toFixed(2));
10591
+ }
10592
+ }, [tokenChainDetails, step, prefillAmountUsd]);
10302
10593
  React26.useEffect(() => {
10303
10594
  if (step === "review") {
10304
10595
  setShowTransactionDetails(false);
@@ -10416,7 +10707,7 @@ function BrowserWalletModal({
10416
10707
  setError(null);
10417
10708
  if (step === "input-amount") {
10418
10709
  setStep("select-token");
10419
- setAmountUsd("");
10710
+ setAmountUsd(prefillAmountUsd ?? "");
10420
10711
  setTokenChainDetails(null);
10421
10712
  } else if (step === "review") {
10422
10713
  setStep("input-amount");
@@ -10502,7 +10793,6 @@ function BrowserWalletModal({
10502
10793
  }
10503
10794
  }
10504
10795
  setIsConfirming(true);
10505
- setStep("confirming");
10506
10796
  setError(null);
10507
10797
  try {
10508
10798
  let txHash;
@@ -10520,16 +10810,17 @@ function BrowserWalletModal({
10520
10810
  } else {
10521
10811
  txHash = await sendEthereumTransaction(token, tokenAmount.toString());
10522
10812
  }
10813
+ setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
10523
10814
  setHasSignedTransaction(true);
10524
- onSuccess?.(txHash);
10525
10815
  setIsConfirming(false);
10816
+ setStep("confirming");
10817
+ onSuccess?.(txHash);
10526
10818
  } catch (err) {
10527
10819
  console.error("[BrowserWalletModal] Transaction error:", err);
10528
10820
  const errorMessage = err instanceof Error ? err.message : "Transaction failed";
10529
10821
  setError(errorMessage);
10530
10822
  onError?.(err instanceof Error ? err : new Error(errorMessage));
10531
10823
  setIsConfirming(false);
10532
- setStep("review");
10533
10824
  }
10534
10825
  };
10535
10826
  const sendEthereumTransaction = async (token, amountStr) => {
@@ -10778,7 +11069,9 @@ function BrowserWalletModal({
10778
11069
  onBack: handleClose,
10779
11070
  onClose: handleFullClose,
10780
11071
  onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnectFromSelectToken() : void 0,
10781
- isDisconnectingWallet
11072
+ isDisconnectingWallet,
11073
+ checkoutAmountUsd,
11074
+ checkoutReceivedUsd
10782
11075
  }
10783
11076
  ),
10784
11077
  step === "input-amount" && selectedToken && selectedBalance && /* @__PURE__ */ jsx49(
@@ -10799,7 +11092,9 @@ function BrowserWalletModal({
10799
11092
  onReview: handleReview,
10800
11093
  onBack: handleBack,
10801
11094
  onClose: handleFullClose,
10802
- quickSelectMode: amountQuickSelect
11095
+ quickSelectMode: amountQuickSelect,
11096
+ checkoutAmountUsd,
11097
+ checkoutReceivedUsd
10803
11098
  }
10804
11099
  ),
10805
11100
  step === "review" && selectedToken && /* @__PURE__ */ jsx49(
@@ -10828,7 +11123,12 @@ function BrowserWalletModal({
10828
11123
  isConfirming,
10829
11124
  onClose: handleFullClose,
10830
11125
  executions: depositExecutions,
10831
- isPolling
11126
+ isPolling,
11127
+ onNewDeposit,
11128
+ onDone,
11129
+ paymentIntentStatus,
11130
+ amountReceivedUsd: checkoutReceivedUsd,
11131
+ amountReceivedUsdAtSubmission: receivedUsdAtSubmission
10832
11132
  }
10833
11133
  )
10834
11134
  ] })
@@ -10840,9 +11140,9 @@ function BrowserWalletModal({
10840
11140
 
10841
11141
  // src/components/deposits/WalletSelectionModal.tsx
10842
11142
  import * as React27 from "react";
10843
- import { ExternalLink as ExternalLink3, Loader2 as Loader24 } from "lucide-react";
11143
+ import { ExternalLink as ExternalLink3, Loader2 as Loader25 } from "lucide-react";
10844
11144
  import { jsx as jsx50, jsxs as jsxs43 } from "react/jsx-runtime";
10845
- var WALLET_ICONS2 = {
11145
+ var WALLET_ICONS3 = {
10846
11146
  metamask: MetamaskIcon,
10847
11147
  phantom: PhantomIcon,
10848
11148
  coinbase: CoinbaseIcon,
@@ -11281,10 +11581,10 @@ function WalletSelectionModal({
11281
11581
  },
11282
11582
  children: [
11283
11583
  /* @__PURE__ */ jsxs43("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
11284
- WALLET_ICONS2[wallet.id] ? /* @__PURE__ */ jsx50(
11584
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ jsx50(
11285
11585
  WalletIconWithNetwork,
11286
11586
  {
11287
- WalletIcon: WALLET_ICONS2[wallet.id],
11587
+ WalletIcon: WALLET_ICONS3[wallet.id],
11288
11588
  networks: wallet.networks,
11289
11589
  size: 40,
11290
11590
  className: "uf-rounded-lg"
@@ -11355,10 +11655,10 @@ function WalletSelectionModal({
11355
11655
  style: { minHeight: WALLET_STEP_BODY_MIN_HEIGHT },
11356
11656
  children: [
11357
11657
  /* @__PURE__ */ jsxs43("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4 uf-shrink-0", children: [
11358
- /* @__PURE__ */ jsx50("div", { className: "uf-mb-2", children: WALLET_ICONS2[selectedWallet.id] ? /* @__PURE__ */ jsx50(
11658
+ /* @__PURE__ */ jsx50("div", { className: "uf-mb-2", children: WALLET_ICONS3[selectedWallet.id] ? /* @__PURE__ */ jsx50(
11359
11659
  WalletIconWithNetwork,
11360
11660
  {
11361
- WalletIcon: WALLET_ICONS2[selectedWallet.id],
11661
+ WalletIcon: WALLET_ICONS3[selectedWallet.id],
11362
11662
  networks: selectedWallet.networks,
11363
11663
  size: 48,
11364
11664
  className: "uf-rounded-lg"
@@ -11433,7 +11733,7 @@ function WalletSelectionModal({
11433
11733
  ] })
11434
11734
  ] }),
11435
11735
  connectingNetwork === network && /* @__PURE__ */ jsx50(
11436
- Loader24,
11736
+ Loader25,
11437
11737
  {
11438
11738
  className: "uf-w-4 uf-h-4 uf-animate-spin",
11439
11739
  style: { color: colors2.primary }
@@ -11456,7 +11756,7 @@ function WalletSelectionModal({
11456
11756
  ),
11457
11757
  step === "connecting" && /* @__PURE__ */ jsx50("div", { className: "uf-flex uf-min-h-0 uf-flex-1 uf-flex-col", children: /* @__PURE__ */ jsxs43("div", { className: "uf-flex uf-flex-1 uf-flex-col uf-items-center uf-justify-center uf-py-8", children: [
11458
11758
  /* @__PURE__ */ jsx50(
11459
- Loader24,
11759
+ Loader25,
11460
11760
  {
11461
11761
  className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4",
11462
11762
  style: { color: colors2.primary }
@@ -11578,7 +11878,7 @@ function DepositModal({
11578
11878
  const [view, setView] = useState27(
11579
11879
  effectiveInitialScreen
11580
11880
  );
11581
- const resetViewTimeoutRef = useRef6(null);
11881
+ const resetViewTimeoutRef = useRef7(null);
11582
11882
  const [cardView, setCardView] = useState27(
11583
11883
  "amount"
11584
11884
  );
@@ -11608,7 +11908,7 @@ function DepositModal({
11608
11908
  const [resolvedTheme, setResolvedTheme] = useState27(
11609
11909
  theme === "auto" ? "dark" : theme
11610
11910
  );
11611
- useEffect21(() => {
11911
+ useEffect22(() => {
11612
11912
  if (theme === "auto") {
11613
11913
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
11614
11914
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -11637,7 +11937,7 @@ function DepositModal({
11637
11937
  chainType: destinationChainType,
11638
11938
  enabled: open
11639
11939
  });
11640
- useEffect21(() => {
11940
+ useEffect22(() => {
11641
11941
  if (view !== "tracker" || !userId) return;
11642
11942
  const fetchExecutions = async () => {
11643
11943
  try {
@@ -11658,7 +11958,7 @@ function DepositModal({
11658
11958
  clearInterval(pollInterval);
11659
11959
  };
11660
11960
  }, [view, userId, publishableKey]);
11661
- useEffect21(() => {
11961
+ useEffect22(() => {
11662
11962
  if (view !== "tracker") {
11663
11963
  setSelectedExecution(null);
11664
11964
  }
@@ -11768,7 +12068,7 @@ function DepositModal({
11768
12068
  setBrowserWalletInfo(null);
11769
12069
  setSelectedExecution(null);
11770
12070
  }, [open, effectiveInitialScreen]);
11771
- useEffect21(
12071
+ useEffect22(
11772
12072
  () => () => {
11773
12073
  if (resetViewTimeoutRef.current) {
11774
12074
  clearTimeout(resetViewTimeoutRef.current);
@@ -12161,73 +12461,755 @@ function DepositModal({
12161
12461
  ) });
12162
12462
  }
12163
12463
 
12164
- // src/components/withdrawals/WithdrawModal.tsx
12464
+ // src/components/checkout/CheckoutModal.tsx
12165
12465
  import {
12166
- useState as useState31,
12167
- useEffect as useEffect25,
12466
+ useState as useState28,
12467
+ useEffect as useEffect23,
12168
12468
  useLayoutEffect as useLayoutEffect3,
12169
- useCallback as useCallback6,
12170
- useRef as useRef8
12469
+ useCallback as useCallback5,
12470
+ useRef as useRef8,
12471
+ useMemo as useMemo10
12171
12472
  } from "react";
12172
- import { AlertTriangle as AlertTriangle3, ChevronRight as ChevronRight13, Clock as Clock5 } from "lucide-react";
12473
+ import { AlertTriangle as AlertTriangle2, ChevronRight as ChevronRight12 } from "lucide-react";
12173
12474
 
12174
- // src/hooks/use-supported-destination-tokens.ts
12475
+ // src/hooks/use-payment-intent.ts
12175
12476
  import { useQuery as useQuery9 } from "@tanstack/react-query";
12176
- import {
12177
- getSupportedDestinationTokens
12178
- } from "@unifold/core";
12179
- function useSupportedDestinationTokens(publishableKey, enabled = true) {
12477
+ import { retrievePaymentIntent } from "@unifold/core";
12478
+ function usePaymentIntent(params) {
12479
+ const {
12480
+ clientSecret,
12481
+ publishableKey,
12482
+ enabled = true,
12483
+ pollingInterval = 5e3
12484
+ } = params;
12180
12485
  return useQuery9({
12181
- queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
12182
- queryFn: () => getSupportedDestinationTokens(publishableKey),
12183
- staleTime: 1e3 * 60 * 5,
12184
- gcTime: 1e3 * 60 * 30,
12185
- refetchOnMount: false,
12186
- refetchOnWindowFocus: false,
12187
- enabled
12486
+ queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
12487
+ queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
12488
+ enabled: enabled && !!clientSecret && !!publishableKey,
12489
+ staleTime: 0,
12490
+ refetchInterval: pollingInterval || false,
12491
+ refetchOnWindowFocus: true,
12492
+ retry: 3,
12493
+ retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
12188
12494
  });
12189
12495
  }
12190
12496
 
12191
- // src/hooks/use-source-token-validation.ts
12497
+ // src/hooks/use-deposit-quote.ts
12192
12498
  import { useQuery as useQuery10 } from "@tanstack/react-query";
12193
- import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
12194
- function useSourceTokenValidation(params) {
12499
+ import {
12500
+ getDepositQuote
12501
+ } from "@unifold/core";
12502
+ function useDepositQuote(params) {
12195
12503
  const {
12504
+ publishableKey,
12196
12505
  sourceChainType,
12197
12506
  sourceChainId,
12198
12507
  sourceTokenAddress,
12199
- sourceTokenSymbol,
12200
- publishableKey,
12508
+ destinationAmount,
12509
+ destinationChainType,
12510
+ destinationChainId,
12511
+ destinationTokenAddress,
12201
12512
  enabled = true
12202
12513
  } = params;
12203
- const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
12514
+ const request = {
12515
+ source_chain_type: sourceChainType,
12516
+ source_chain_id: sourceChainId,
12517
+ source_token_address: sourceTokenAddress,
12518
+ destination_amount: destinationAmount,
12519
+ destination_chain_type: destinationChainType,
12520
+ destination_chain_id: destinationChainId,
12521
+ destination_token_address: destinationTokenAddress
12522
+ };
12204
12523
  return useQuery10({
12205
12524
  queryKey: [
12206
12525
  "unifold",
12207
- "sourceTokenValidation",
12208
- sourceChainType ?? null,
12209
- sourceChainId ?? null,
12210
- sourceTokenAddress ?? null,
12526
+ "depositQuote",
12527
+ sourceChainType,
12528
+ sourceChainId,
12529
+ sourceTokenAddress,
12530
+ destinationAmount,
12531
+ destinationChainType,
12532
+ destinationChainId,
12533
+ destinationTokenAddress,
12211
12534
  publishableKey
12212
12535
  ],
12213
- queryFn: async () => {
12214
- const res = await getSupportedDepositTokens3(publishableKey);
12215
- let matchedMinUsd = null;
12216
- let matchedProcessingTime = null;
12217
- let matchedSlippage = null;
12218
- let matchedPriceImpact = null;
12219
- const found = res.data.some(
12220
- (token) => token.chains.some((chain) => {
12221
- const match = chain.chain_type === sourceChainType && chain.chain_id === sourceChainId && chain.token_address.toLowerCase() === sourceTokenAddress.toLowerCase();
12222
- if (match) {
12223
- matchedMinUsd = chain.minimum_deposit_amount_usd;
12224
- matchedProcessingTime = chain.estimated_processing_time;
12225
- matchedSlippage = chain.max_slippage_percent;
12226
- matchedPriceImpact = chain.estimated_price_impact_percent;
12227
- }
12228
- return match;
12229
- })
12230
- );
12536
+ queryFn: () => getDepositQuote(request, publishableKey),
12537
+ enabled: enabled && !!publishableKey && !!sourceChainType && !!sourceChainId && !!sourceTokenAddress && !!destinationAmount && destinationAmount !== "0" && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress,
12538
+ staleTime: 6e4,
12539
+ gcTime: 5 * 6e4,
12540
+ refetchOnWindowFocus: false,
12541
+ retry: 2,
12542
+ retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
12543
+ });
12544
+ }
12545
+
12546
+ // src/components/checkout/CheckoutModal.tsx
12547
+ import { Fragment as Fragment10, jsx as jsx52, jsxs as jsxs45 } from "react/jsx-runtime";
12548
+ function mapDepositAddressesToWallets(depositAddresses, pi) {
12549
+ return depositAddresses.map((da, idx) => ({
12550
+ id: da.id,
12551
+ chain_type: da.chain_type,
12552
+ address_type: da.address_type,
12553
+ address: da.address,
12554
+ destination_chain_type: pi.destination_chain_type,
12555
+ destination_chain_id: pi.destination_chain_id,
12556
+ destination_token_address: pi.destination_token_address,
12557
+ recipient_address: pi.recipient_address,
12558
+ is_primary: idx === 0
12559
+ }));
12560
+ }
12561
+ function SkeletonButton2() {
12562
+ return /* @__PURE__ */ jsxs45("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-animate-pulse", children: [
12563
+ /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
12564
+ /* @__PURE__ */ jsx52("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
12565
+ /* @__PURE__ */ jsxs45("div", { className: "uf-space-y-1.5", children: [
12566
+ /* @__PURE__ */ jsx52("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
12567
+ /* @__PURE__ */ jsx52("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
12568
+ ] })
12569
+ ] }),
12570
+ /* @__PURE__ */ jsx52("div", { className: "uf-flex uf-items-center uf-gap-2", children: /* @__PURE__ */ jsx52(ChevronRight12, { className: "uf-w-4 uf-h-4 uf-text-muted" }) })
12571
+ ] });
12572
+ }
12573
+ function CheckoutModal({
12574
+ open,
12575
+ onOpenChange,
12576
+ clientSecret,
12577
+ publishableKey,
12578
+ modalTitle,
12579
+ enableConnectWallet = false,
12580
+ theme = "dark",
12581
+ onCheckoutSuccess,
12582
+ onCheckoutError
12583
+ }) {
12584
+ const { colors: colors2, fonts, components } = useTheme();
12585
+ const [view, setView] = useState28("main");
12586
+ const resetViewTimeoutRef = useRef8(
12587
+ null
12588
+ );
12589
+ const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState28(false);
12590
+ const [browserWalletInfo, setBrowserWalletInfo] = useState28(null);
12591
+ const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState28(false);
12592
+ const [browserWalletChainType, setBrowserWalletChainType] = useState28(() => getStoredWalletChainType());
12593
+ const isMobileView = useIsMobileViewport();
12594
+ const [resolvedTheme, setResolvedTheme] = useState28(
12595
+ theme === "auto" ? "dark" : theme
12596
+ );
12597
+ useEffect23(() => {
12598
+ if (theme === "auto") {
12599
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
12600
+ setResolvedTheme(mediaQuery.matches ? "dark" : "light");
12601
+ const handler = (e) => {
12602
+ setResolvedTheme(e.matches ? "dark" : "light");
12603
+ };
12604
+ mediaQuery.addEventListener("change", handler);
12605
+ return () => mediaQuery.removeEventListener("change", handler);
12606
+ } else {
12607
+ setResolvedTheme(theme);
12608
+ }
12609
+ }, [theme]);
12610
+ const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
12611
+ const {
12612
+ data: paymentIntent,
12613
+ isLoading: piLoading,
12614
+ error: piError
12615
+ } = usePaymentIntent({
12616
+ clientSecret,
12617
+ publishableKey,
12618
+ enabled: open && !!clientSecret,
12619
+ pollingInterval: 5e3
12620
+ });
12621
+ const { projectConfig } = useProjectConfig({
12622
+ publishableKey,
12623
+ enabled: open
12624
+ });
12625
+ const prevStatusRef = useRef8(null);
12626
+ useEffect23(() => {
12627
+ if (!paymentIntent) return;
12628
+ const prev = prevStatusRef.current;
12629
+ prevStatusRef.current = paymentIntent.status;
12630
+ if (prev && prev !== paymentIntent.status && paymentIntent.status === "succeeded") {
12631
+ if (!browserWalletModalOpen) {
12632
+ setView("main");
12633
+ }
12634
+ onCheckoutSuccess?.({
12635
+ paymentIntentId: paymentIntent.id,
12636
+ status: paymentIntent.status
12637
+ });
12638
+ }
12639
+ }, [paymentIntent, onCheckoutSuccess, browserWalletModalOpen]);
12640
+ const wallets = useMemo10(() => {
12641
+ if (!paymentIntent) return [];
12642
+ return mapDepositAddressesToWallets(
12643
+ paymentIntent.deposit_addresses,
12644
+ paymentIntent
12645
+ );
12646
+ }, [paymentIntent]);
12647
+ const formatCryptoAmount = useMemo10(() => {
12648
+ if (!paymentIntent) return (_) => "";
12649
+ const decimals = paymentIntent.destination_token_decimals ?? 6;
12650
+ const symbol = paymentIntent.currency.toUpperCase();
12651
+ return (baseUnits) => {
12652
+ const num = Number(baseUnits) / 10 ** decimals;
12653
+ const formatted = num % 1 === 0 ? num.toFixed(0) : num.toFixed(2);
12654
+ return `${formatted} ${symbol}`;
12655
+ };
12656
+ }, [paymentIntent]);
12657
+ const remainingAmountUsd = useMemo10(() => {
12658
+ if (!paymentIntent) return void 0;
12659
+ const total = parseFloat(paymentIntent.amount_usd);
12660
+ const received = parseFloat(paymentIntent.amount_received_usd);
12661
+ if (isNaN(total) || isNaN(received)) return paymentIntent.amount_usd;
12662
+ const remaining = total - received;
12663
+ return remaining > 0 ? remaining.toFixed(2) : "0.00";
12664
+ }, [paymentIntent]);
12665
+ const remainingCrypto = useMemo10(() => {
12666
+ if (!paymentIntent) return void 0;
12667
+ const total = BigInt(paymentIntent.amount);
12668
+ const received = BigInt(paymentIntent.amount_received);
12669
+ const remaining = total - received;
12670
+ return remaining > 0n ? remaining.toString() : "0";
12671
+ }, [paymentIntent]);
12672
+ const [selectedSource, setSelectedSource] = useState28(null);
12673
+ const quoteDestinationAmount = useMemo10(() => {
12674
+ if (!paymentIntent || !selectedSource) return "0";
12675
+ const remaining = BigInt(paymentIntent.amount) - BigInt(paymentIntent.amount_received);
12676
+ const totalBaseUnits = Number(paymentIntent.amount);
12677
+ const totalUsd = parseFloat(paymentIntent.amount_usd);
12678
+ const baseUnitsPerUsd = totalUsd > 0 ? totalBaseUnits / totalUsd : 0;
12679
+ const minUsd = Math.max(selectedSource.minimumDepositAmountUsd, 3);
12680
+ const minDepositBaseUnits = BigInt(Math.ceil(minUsd * baseUnitsPerUsd));
12681
+ const effective = remaining > minDepositBaseUnits ? remaining : minDepositBaseUnits;
12682
+ return effective > 0n ? effective.toString() : "0";
12683
+ }, [paymentIntent, selectedSource]);
12684
+ const { data: sourceQuote } = useDepositQuote({
12685
+ publishableKey,
12686
+ sourceChainType: selectedSource?.chainType ?? "",
12687
+ sourceChainId: selectedSource?.chainId ?? "",
12688
+ sourceTokenAddress: selectedSource?.tokenAddress ?? "",
12689
+ destinationAmount: quoteDestinationAmount,
12690
+ destinationChainType: paymentIntent?.destination_chain_type ?? "",
12691
+ destinationChainId: paymentIntent?.destination_chain_id ?? "",
12692
+ destinationTokenAddress: paymentIntent?.destination_token_address ?? "",
12693
+ enabled: open && view === "transfer" && !!paymentIntent && !!selectedSource && quoteDestinationAmount !== "0"
12694
+ });
12695
+ const handleBrowserWalletClick = useCallback5(
12696
+ (walletInfo) => {
12697
+ const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
12698
+ setStoredWalletChainType(walletChainType);
12699
+ setBrowserWalletChainType(walletChainType);
12700
+ const matchingDepositWallet = wallets.find(
12701
+ (w) => w.chain_type === walletChainType
12702
+ );
12703
+ if (!matchingDepositWallet) {
12704
+ onCheckoutError?.({
12705
+ message: `Unable to pay from ${walletChainType}. Please try a different wallet.`,
12706
+ code: "NO_DEPOSIT_ADDRESS"
12707
+ });
12708
+ return;
12709
+ }
12710
+ setBrowserWalletInfo({
12711
+ ...walletInfo,
12712
+ depositWallet: matchingDepositWallet
12713
+ });
12714
+ setBrowserWalletModalOpen(true);
12715
+ },
12716
+ [wallets, onCheckoutError]
12717
+ );
12718
+ const handleWalletConnectClick = useCallback5(() => {
12719
+ setWalletSelectionModalOpen(true);
12720
+ }, []);
12721
+ const handleWalletConnected = useCallback5(
12722
+ (walletInfo) => {
12723
+ const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
12724
+ setStoredWalletChainType(walletChainType);
12725
+ setBrowserWalletChainType(walletChainType);
12726
+ const matchingDepositWallet = wallets.find(
12727
+ (w) => w.chain_type === walletChainType
12728
+ );
12729
+ if (!matchingDepositWallet) {
12730
+ onCheckoutError?.({
12731
+ message: `Unable to pay from ${walletChainType}. Please try a different wallet.`,
12732
+ code: "NO_DEPOSIT_ADDRESS"
12733
+ });
12734
+ setWalletSelectionModalOpen(false);
12735
+ return;
12736
+ }
12737
+ setBrowserWalletInfo({
12738
+ ...walletInfo,
12739
+ depositWallet: matchingDepositWallet
12740
+ });
12741
+ setWalletSelectionModalOpen(false);
12742
+ setBrowserWalletModalOpen(true);
12743
+ },
12744
+ [wallets, onCheckoutError]
12745
+ );
12746
+ const handleWalletDisconnect = useCallback5(() => {
12747
+ setUserDisconnectedWallet(true);
12748
+ clearStoredWalletChainType();
12749
+ setBrowserWalletChainType(void 0);
12750
+ setBrowserWalletInfo(null);
12751
+ setBrowserWalletModalOpen(false);
12752
+ }, []);
12753
+ const handleClose = useCallback5(() => {
12754
+ onOpenChange(false);
12755
+ if (resetViewTimeoutRef.current) {
12756
+ clearTimeout(resetViewTimeoutRef.current);
12757
+ }
12758
+ resetViewTimeoutRef.current = setTimeout(() => {
12759
+ setView("main");
12760
+ setBrowserWalletInfo(null);
12761
+ resetViewTimeoutRef.current = null;
12762
+ }, 200);
12763
+ }, [onOpenChange]);
12764
+ useLayoutEffect3(() => {
12765
+ if (!open) return;
12766
+ if (resetViewTimeoutRef.current) {
12767
+ clearTimeout(resetViewTimeoutRef.current);
12768
+ resetViewTimeoutRef.current = null;
12769
+ }
12770
+ setView("main");
12771
+ setBrowserWalletInfo(null);
12772
+ }, [open]);
12773
+ useEffect23(
12774
+ () => () => {
12775
+ if (resetViewTimeoutRef.current) {
12776
+ clearTimeout(resetViewTimeoutRef.current);
12777
+ }
12778
+ },
12779
+ []
12780
+ );
12781
+ const handleBack = useCallback5(() => {
12782
+ setView("main");
12783
+ }, []);
12784
+ const poweredByFooter = /* @__PURE__ */ jsx52("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx52(
12785
+ PoweredByUnifold,
12786
+ {
12787
+ color: colors2.foregroundMuted,
12788
+ className: "uf-flex uf-justify-center uf-shrink-0"
12789
+ }
12790
+ ) });
12791
+ const progressSection = paymentIntent ? (() => {
12792
+ const received = parseFloat(paymentIntent.amount_received_usd);
12793
+ const total = parseFloat(paymentIntent.amount_usd);
12794
+ const remaining = Math.max(total - received, 0);
12795
+ const pct = total > 0 ? Math.min(received / total * 100, 100) : 0;
12796
+ const hasPartial = received > 0;
12797
+ const amountStr = paymentIntent.amount_usd;
12798
+ const dynamicFontSize = `${Math.max(3.75 - amountStr.length * 0.15, 2)}rem`;
12799
+ return /* @__PURE__ */ jsxs45("div", { className: "uf-text-center uf-py-2 uf-space-y-1", children: [
12800
+ paymentIntent.description && /* @__PURE__ */ jsx52(
12801
+ "div",
12802
+ {
12803
+ className: "uf-text-xs",
12804
+ style: {
12805
+ color: colors2.foregroundMuted,
12806
+ fontFamily: fonts.regular
12807
+ },
12808
+ children: paymentIntent.description
12809
+ }
12810
+ ),
12811
+ /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-items-center uf-justify-center", children: [
12812
+ /* @__PURE__ */ jsx52(
12813
+ "span",
12814
+ {
12815
+ className: "uf-mr-1",
12816
+ style: {
12817
+ fontSize: `calc(${dynamicFontSize} * 0.6)`,
12818
+ color: colors2.foregroundMuted,
12819
+ fontFamily: fonts.regular
12820
+ },
12821
+ children: "$"
12822
+ }
12823
+ ),
12824
+ /* @__PURE__ */ jsx52(
12825
+ "span",
12826
+ {
12827
+ style: {
12828
+ fontSize: dynamicFontSize,
12829
+ color: colors2.foreground,
12830
+ fontFamily: fonts.regular,
12831
+ lineHeight: 1.1
12832
+ },
12833
+ children: amountStr
12834
+ }
12835
+ )
12836
+ ] }),
12837
+ /* @__PURE__ */ jsx52(
12838
+ "div",
12839
+ {
12840
+ className: "uf-text-xs",
12841
+ style: {
12842
+ color: colors2.foregroundMuted,
12843
+ fontFamily: fonts.regular
12844
+ },
12845
+ children: paymentIntent.currency.toUpperCase()
12846
+ }
12847
+ ),
12848
+ hasPartial && /* @__PURE__ */ jsxs45("div", { className: "uf-pt-2 uf-space-y-1.5", children: [
12849
+ /* @__PURE__ */ jsx52(
12850
+ "div",
12851
+ {
12852
+ className: "uf-w-full uf-h-1.5 uf-rounded-full uf-overflow-hidden",
12853
+ style: { backgroundColor: colors2.border },
12854
+ children: /* @__PURE__ */ jsx52(
12855
+ "div",
12856
+ {
12857
+ className: "uf-h-full uf-rounded-full uf-transition-all uf-duration-500",
12858
+ style: {
12859
+ width: `${pct}%`,
12860
+ backgroundColor: paymentIntent.status === "succeeded" ? "rgb(34, 197, 94)" : colors2.primary
12861
+ }
12862
+ }
12863
+ )
12864
+ }
12865
+ ),
12866
+ /* @__PURE__ */ jsxs45(
12867
+ "div",
12868
+ {
12869
+ className: "uf-text-xs",
12870
+ style: {
12871
+ color: colors2.foregroundMuted,
12872
+ fontFamily: fonts.regular
12873
+ },
12874
+ children: [
12875
+ "$",
12876
+ paymentIntent.amount_received_usd,
12877
+ " / $",
12878
+ amountStr,
12879
+ " received",
12880
+ remaining > 0 && paymentIntent.status !== "succeeded" && /* @__PURE__ */ jsxs45("span", { style: { color: colors2.foreground, fontFamily: fonts.medium }, children: [
12881
+ " ",
12882
+ "\xB7 $",
12883
+ remaining.toFixed(2),
12884
+ " remaining"
12885
+ ] })
12886
+ ]
12887
+ }
12888
+ )
12889
+ ] }),
12890
+ paymentIntent.status !== "requires_payment" && /* @__PURE__ */ jsx52("div", { className: "uf-pt-1", children: /* @__PURE__ */ jsx52(
12891
+ "span",
12892
+ {
12893
+ className: "uf-text-xs uf-font-medium uf-px-2.5 uf-py-1 uf-rounded-full uf-inline-block",
12894
+ style: {
12895
+ backgroundColor: paymentIntent.status === "succeeded" ? "rgba(34, 197, 94, 0.15)" : paymentIntent.status === "processing" ? "rgba(59, 130, 246, 0.15)" : "rgba(239, 68, 68, 0.15)",
12896
+ color: paymentIntent.status === "succeeded" ? "rgb(34, 197, 94)" : paymentIntent.status === "processing" ? "rgb(59, 130, 246)" : "rgb(239, 68, 68)",
12897
+ fontFamily: fonts.medium
12898
+ },
12899
+ children: paymentIntent.status === "succeeded" ? "Payment Complete" : paymentIntent.status === "processing" ? "Partial Payment Received" : paymentIntent.status === "canceled" ? "Canceled" : paymentIntent.status === "expired" ? "Expired" : paymentIntent.status
12900
+ }
12901
+ ) })
12902
+ ] });
12903
+ })() : null;
12904
+ return /* @__PURE__ */ jsx52(PortalContainerProvider, { value: null, children: /* @__PURE__ */ jsxs45(Dialog, { open, onOpenChange: handleClose, modal: true, children: [
12905
+ /* @__PURE__ */ jsx52(
12906
+ DialogContent,
12907
+ {
12908
+ className: `sm:uf-max-w-[400px] uf-border-secondary uf-text-foreground uf-gap-0 [&>button]:uf-hidden uf-p-0 uf-overflow-visible ${view === "main" ? "!uf-top-auto !uf-h-auto !uf-max-h-[60vh] sm:!uf-max-h-none sm:!uf-top-[50%]" : "!uf-top-0 !uf-h-full sm:!uf-h-auto sm:!uf-top-[50%]"} ${themeClass}`,
12909
+ style: { backgroundColor: colors2.background },
12910
+ onPointerDownOutside: (e) => e.preventDefault(),
12911
+ onInteractOutside: (e) => e.preventDefault(),
12912
+ children: /* @__PURE__ */ jsx52(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs45(Fragment10, { children: [
12913
+ /* @__PURE__ */ jsx52(
12914
+ DepositHeader,
12915
+ {
12916
+ title: modalTitle || "Checkout",
12917
+ showClose: true,
12918
+ onClose: handleClose
12919
+ }
12920
+ ),
12921
+ /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
12922
+ piLoading ? /* @__PURE__ */ jsxs45("div", { className: "uf-space-y-3", children: [
12923
+ /* @__PURE__ */ jsx52(
12924
+ "div",
12925
+ {
12926
+ className: "uf-rounded-xl uf-p-4 uf-animate-pulse",
12927
+ style: {
12928
+ backgroundColor: components.card.backgroundColor,
12929
+ borderRadius: components.card.borderRadius,
12930
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
12931
+ },
12932
+ children: /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-flex-col uf-items-center uf-gap-2", children: [
12933
+ /* @__PURE__ */ jsx52(
12934
+ "div",
12935
+ {
12936
+ className: "uf-h-8 uf-w-24 uf-rounded",
12937
+ style: {
12938
+ backgroundColor: components.card.borderColor
12939
+ }
12940
+ }
12941
+ ),
12942
+ /* @__PURE__ */ jsx52(
12943
+ "div",
12944
+ {
12945
+ className: "uf-h-4 uf-w-16 uf-rounded",
12946
+ style: {
12947
+ backgroundColor: components.card.borderColor
12948
+ }
12949
+ }
12950
+ )
12951
+ ] })
12952
+ }
12953
+ ),
12954
+ /* @__PURE__ */ jsx52(SkeletonButton2, {}),
12955
+ /* @__PURE__ */ jsx52(SkeletonButton2, {})
12956
+ ] }) : piError ? /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
12957
+ /* @__PURE__ */ jsx52("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx52(AlertTriangle2, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
12958
+ /* @__PURE__ */ jsx52(
12959
+ "h3",
12960
+ {
12961
+ className: "uf-text-lg uf-font-semibold uf-mb-2",
12962
+ style: {
12963
+ color: colors2.foreground,
12964
+ fontFamily: fonts.semibold
12965
+ },
12966
+ children: "Unable to Load Checkout"
12967
+ }
12968
+ ),
12969
+ /* @__PURE__ */ jsx52(
12970
+ "p",
12971
+ {
12972
+ className: "uf-text-sm uf-max-w-[280px]",
12973
+ style: {
12974
+ color: colors2.foregroundMuted,
12975
+ fontFamily: fonts.regular
12976
+ },
12977
+ children: piError instanceof Error ? piError.message : "Something went wrong. Please try again."
12978
+ }
12979
+ )
12980
+ ] }) : paymentIntent ? /* @__PURE__ */ jsxs45("div", { className: "uf-space-y-3", children: [
12981
+ progressSection,
12982
+ (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ jsxs45(Fragment10, { children: [
12983
+ /* @__PURE__ */ jsx52(
12984
+ TransferCryptoButton,
12985
+ {
12986
+ onClick: () => setView("transfer"),
12987
+ title: "Transfer Crypto",
12988
+ subtitle: "Send from any wallet or exchange",
12989
+ featuredTokens: projectConfig?.transfer_crypto.networks
12990
+ }
12991
+ ),
12992
+ enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx52(
12993
+ BrowserWalletButton,
12994
+ {
12995
+ onClick: handleBrowserWalletClick,
12996
+ onConnectClick: handleWalletConnectClick,
12997
+ onDisconnect: handleWalletDisconnect,
12998
+ chainType: browserWalletChainType,
12999
+ publishableKey
13000
+ }
13001
+ )
13002
+ ] })
13003
+ ] }) : null,
13004
+ poweredByFooter
13005
+ ] })
13006
+ ] }) : view === "transfer" ? /* @__PURE__ */ jsxs45(Fragment10, { children: [
13007
+ /* @__PURE__ */ jsx52(
13008
+ DepositHeader,
13009
+ {
13010
+ title: `Pay $${remainingAmountUsd ?? paymentIntent?.amount_usd ?? ""}`,
13011
+ showBack: true,
13012
+ onBack: handleBack,
13013
+ onClose: handleClose
13014
+ }
13015
+ ),
13016
+ /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
13017
+ paymentIntent ? /* @__PURE__ */ jsxs45(Fragment10, { children: [
13018
+ /* @__PURE__ */ jsxs45(
13019
+ "div",
13020
+ {
13021
+ className: "uf-rounded-lg uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
13022
+ style: {
13023
+ backgroundColor: components.card.backgroundColor,
13024
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
13025
+ borderRadius: components.card.borderRadius
13026
+ },
13027
+ children: [
13028
+ /* @__PURE__ */ jsx52(
13029
+ "span",
13030
+ {
13031
+ className: "uf-text-xs",
13032
+ style: {
13033
+ color: colors2.foregroundMuted,
13034
+ fontFamily: fonts.regular
13035
+ },
13036
+ children: parseFloat(paymentIntent.amount_received_usd) > 0 ? `$${paymentIntent.amount_received_usd} / $${paymentIntent.amount_usd} received` : "Amount due"
13037
+ }
13038
+ ),
13039
+ /* @__PURE__ */ jsxs45(
13040
+ "span",
13041
+ {
13042
+ className: "uf-text-sm uf-font-semibold",
13043
+ style: {
13044
+ color: colors2.foreground,
13045
+ fontFamily: fonts.semibold
13046
+ },
13047
+ children: [
13048
+ formatCryptoAmount(remainingCrypto ?? paymentIntent.amount),
13049
+ /* @__PURE__ */ jsxs45(
13050
+ "span",
13051
+ {
13052
+ className: "uf-text-xs uf-font-normal uf-ml-1",
13053
+ style: { color: colors2.foregroundMuted },
13054
+ children: [
13055
+ "($",
13056
+ remainingAmountUsd ?? paymentIntent.amount_usd,
13057
+ ")"
13058
+ ]
13059
+ }
13060
+ )
13061
+ ]
13062
+ }
13063
+ )
13064
+ ]
13065
+ }
13066
+ ),
13067
+ /* @__PURE__ */ jsx52(
13068
+ TransferCryptoSingleInput,
13069
+ {
13070
+ userId: paymentIntent.user_id || "",
13071
+ publishableKey,
13072
+ clientSecret,
13073
+ recipientAddress: paymentIntent.recipient_address,
13074
+ destinationChainType: paymentIntent.destination_chain_type,
13075
+ destinationChainId: paymentIntent.destination_chain_id,
13076
+ destinationTokenAddress: paymentIntent.destination_token_address,
13077
+ depositConfirmationMode: "auto_ui",
13078
+ wallets,
13079
+ onSourceTokenChange: setSelectedSource,
13080
+ checkoutQuote: sourceQuote ? {
13081
+ sourceAmount: sourceQuote.source_amount,
13082
+ sourceTokenDecimals: sourceQuote.source_token_decimals,
13083
+ sourceTokenSymbol: sourceQuote.source_token_symbol,
13084
+ sourceAmountUsd: sourceQuote.source_amount_usd
13085
+ } : null
13086
+ }
13087
+ )
13088
+ ] }) : /* @__PURE__ */ jsx52(SkeletonButton2, {}),
13089
+ poweredByFooter
13090
+ ] })
13091
+ ] }) : null })
13092
+ }
13093
+ ),
13094
+ /* @__PURE__ */ jsx52(
13095
+ WalletSelectionModal,
13096
+ {
13097
+ open: walletSelectionModalOpen,
13098
+ onOpenChange: setWalletSelectionModalOpen,
13099
+ onWalletConnected: handleWalletConnected,
13100
+ onClose: () => setWalletSelectionModalOpen(false),
13101
+ theme: resolvedTheme
13102
+ }
13103
+ ),
13104
+ browserWalletInfo && browserWalletInfo.depositWallet && /* @__PURE__ */ jsx52(
13105
+ BrowserWalletModal,
13106
+ {
13107
+ open: browserWalletModalOpen,
13108
+ onOpenChange: setBrowserWalletModalOpen,
13109
+ onFullClose: handleClose,
13110
+ walletInfo: browserWalletInfo,
13111
+ depositWallet: browserWalletInfo.depositWallet,
13112
+ userId: paymentIntent?.user_id || "",
13113
+ publishableKey,
13114
+ clientSecret,
13115
+ theme: resolvedTheme,
13116
+ prefillAmountUsd: remainingAmountUsd,
13117
+ checkoutAmountUsd: paymentIntent?.amount_usd,
13118
+ checkoutReceivedUsd: paymentIntent?.amount_received_usd,
13119
+ onSuccess: (txHash) => {
13120
+ onCheckoutSuccess?.({
13121
+ paymentIntentId: paymentIntent?.id || "",
13122
+ status: "processing"
13123
+ });
13124
+ },
13125
+ onError: (error) => {
13126
+ onCheckoutError?.({
13127
+ message: error.message,
13128
+ error
13129
+ });
13130
+ },
13131
+ onWalletDisconnect: handleWalletDisconnect,
13132
+ onNewDeposit: () => {
13133
+ setBrowserWalletModalOpen(false);
13134
+ setView("main");
13135
+ },
13136
+ onDone: () => {
13137
+ setBrowserWalletModalOpen(false);
13138
+ setView("main");
13139
+ },
13140
+ paymentIntentStatus: paymentIntent?.status
13141
+ }
13142
+ )
13143
+ ] }) });
13144
+ }
13145
+
13146
+ // src/components/withdrawals/WithdrawModal.tsx
13147
+ import {
13148
+ useState as useState32,
13149
+ useEffect as useEffect27,
13150
+ useLayoutEffect as useLayoutEffect4,
13151
+ useCallback as useCallback7,
13152
+ useRef as useRef10
13153
+ } from "react";
13154
+ import { AlertTriangle as AlertTriangle4, ChevronRight as ChevronRight14, Clock as Clock5 } from "lucide-react";
13155
+
13156
+ // src/hooks/use-supported-destination-tokens.ts
13157
+ import { useQuery as useQuery11 } from "@tanstack/react-query";
13158
+ import {
13159
+ getSupportedDestinationTokens
13160
+ } from "@unifold/core";
13161
+ function useSupportedDestinationTokens(publishableKey, enabled = true) {
13162
+ return useQuery11({
13163
+ queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
13164
+ queryFn: () => getSupportedDestinationTokens(publishableKey),
13165
+ staleTime: 1e3 * 60 * 5,
13166
+ gcTime: 1e3 * 60 * 30,
13167
+ refetchOnMount: false,
13168
+ refetchOnWindowFocus: false,
13169
+ enabled
13170
+ });
13171
+ }
13172
+
13173
+ // src/hooks/use-source-token-validation.ts
13174
+ import { useQuery as useQuery12 } from "@tanstack/react-query";
13175
+ import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
13176
+ function useSourceTokenValidation(params) {
13177
+ const {
13178
+ sourceChainType,
13179
+ sourceChainId,
13180
+ sourceTokenAddress,
13181
+ sourceTokenSymbol,
13182
+ publishableKey,
13183
+ enabled = true
13184
+ } = params;
13185
+ const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
13186
+ return useQuery12({
13187
+ queryKey: [
13188
+ "unifold",
13189
+ "sourceTokenValidation",
13190
+ sourceChainType ?? null,
13191
+ sourceChainId ?? null,
13192
+ sourceTokenAddress ?? null,
13193
+ publishableKey
13194
+ ],
13195
+ queryFn: async () => {
13196
+ const res = await getSupportedDepositTokens3(publishableKey);
13197
+ let matchedMinUsd = null;
13198
+ let matchedProcessingTime = null;
13199
+ let matchedSlippage = null;
13200
+ let matchedPriceImpact = null;
13201
+ const found = res.data.some(
13202
+ (token) => token.chains.some((chain) => {
13203
+ const match = chain.chain_type === sourceChainType && chain.chain_id === sourceChainId && chain.token_address.toLowerCase() === sourceTokenAddress.toLowerCase();
13204
+ if (match) {
13205
+ matchedMinUsd = chain.minimum_deposit_amount_usd;
13206
+ matchedProcessingTime = chain.estimated_processing_time;
13207
+ matchedSlippage = chain.max_slippage_percent;
13208
+ matchedPriceImpact = chain.estimated_price_impact_percent;
13209
+ }
13210
+ return match;
13211
+ })
13212
+ );
12231
13213
  return {
12232
13214
  isSupported: found,
12233
13215
  minimumAmountUsd: matchedMinUsd,
@@ -12246,7 +13228,7 @@ function useSourceTokenValidation(params) {
12246
13228
  }
12247
13229
 
12248
13230
  // src/hooks/use-address-balance.ts
12249
- import { useQuery as useQuery11 } from "@tanstack/react-query";
13231
+ import { useQuery as useQuery13 } from "@tanstack/react-query";
12250
13232
  import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
12251
13233
  function useAddressBalance(params) {
12252
13234
  const {
@@ -12258,7 +13240,7 @@ function useAddressBalance(params) {
12258
13240
  enabled = true
12259
13241
  } = params;
12260
13242
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
12261
- return useQuery11({
13243
+ return useQuery13({
12262
13244
  queryKey: [
12263
13245
  "unifold",
12264
13246
  "addressBalance",
@@ -12307,11 +13289,11 @@ function useAddressBalance(params) {
12307
13289
  }
12308
13290
 
12309
13291
  // src/hooks/use-executions.ts
12310
- import { useQuery as useQuery12 } from "@tanstack/react-query";
13292
+ import { useQuery as useQuery14 } from "@tanstack/react-query";
12311
13293
  import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
12312
13294
  function useExecutions(userId, publishableKey, options) {
12313
13295
  const actionType = options?.actionType ?? ActionType4.Deposit;
12314
- return useQuery12({
13296
+ return useQuery14({
12315
13297
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
12316
13298
  queryFn: () => queryExecutions4(userId, publishableKey, actionType),
12317
13299
  enabled: (options?.enabled ?? true) && !!userId,
@@ -12323,7 +13305,7 @@ function useExecutions(userId, publishableKey, options) {
12323
13305
  }
12324
13306
 
12325
13307
  // src/hooks/use-withdraw-polling.ts
12326
- import { useState as useState28, useEffect as useEffect22, useRef as useRef7 } from "react";
13308
+ import { useState as useState29, useEffect as useEffect24, useRef as useRef9 } from "react";
12327
13309
  import {
12328
13310
  queryExecutions as queryExecutions5,
12329
13311
  pollDirectExecutions as pollDirectExecutions2,
@@ -12341,20 +13323,20 @@ function useWithdrawPolling({
12341
13323
  onWithdrawSuccess,
12342
13324
  onWithdrawError
12343
13325
  }) {
12344
- const [executions, setExecutions] = useState28([]);
12345
- const [isPolling, setIsPolling] = useState28(false);
12346
- const enabledAtRef = useRef7(/* @__PURE__ */ new Date());
12347
- const trackedRef = useRef7(/* @__PURE__ */ new Map());
12348
- const prevEnabledRef = useRef7(false);
12349
- const onSuccessRef = useRef7(onWithdrawSuccess);
12350
- const onErrorRef = useRef7(onWithdrawError);
12351
- useEffect22(() => {
13326
+ const [executions, setExecutions] = useState29([]);
13327
+ const [isPolling, setIsPolling] = useState29(false);
13328
+ const enabledAtRef = useRef9(/* @__PURE__ */ new Date());
13329
+ const trackedRef = useRef9(/* @__PURE__ */ new Map());
13330
+ const prevEnabledRef = useRef9(false);
13331
+ const onSuccessRef = useRef9(onWithdrawSuccess);
13332
+ const onErrorRef = useRef9(onWithdrawError);
13333
+ useEffect24(() => {
12352
13334
  onSuccessRef.current = onWithdrawSuccess;
12353
13335
  }, [onWithdrawSuccess]);
12354
- useEffect22(() => {
13336
+ useEffect24(() => {
12355
13337
  onErrorRef.current = onWithdrawError;
12356
13338
  }, [onWithdrawError]);
12357
- useEffect22(() => {
13339
+ useEffect24(() => {
12358
13340
  if (enabled && !prevEnabledRef.current) {
12359
13341
  enabledAtRef.current = /* @__PURE__ */ new Date();
12360
13342
  trackedRef.current.clear();
@@ -12364,7 +13346,7 @@ function useWithdrawPolling({
12364
13346
  }
12365
13347
  prevEnabledRef.current = enabled;
12366
13348
  }, [enabled]);
12367
- useEffect22(() => {
13349
+ useEffect24(() => {
12368
13350
  if (!userId || !enabled) return;
12369
13351
  const enabledAt = enabledAtRef.current;
12370
13352
  const poll = async () => {
@@ -12426,7 +13408,7 @@ function useWithdrawPolling({
12426
13408
  setIsPolling(false);
12427
13409
  };
12428
13410
  }, [userId, publishableKey, enabled]);
12429
- useEffect22(() => {
13411
+ useEffect24(() => {
12430
13412
  if (!enabled || !depositWalletId) return;
12431
13413
  const trigger = async () => {
12432
13414
  try {
@@ -12442,7 +13424,7 @@ function useWithdrawPolling({
12442
13424
  }
12443
13425
 
12444
13426
  // src/components/withdrawals/WithdrawDoubleInput.tsx
12445
- import { jsx as jsx52, jsxs as jsxs45 } from "react/jsx-runtime";
13427
+ import { jsx as jsx53, jsxs as jsxs46 } from "react/jsx-runtime";
12446
13428
  var t7 = i18n.withdrawModal;
12447
13429
  var getChainKey4 = (chainId, chainType) => `${chainType}:${chainId}`;
12448
13430
  function WithdrawDoubleInput({
@@ -12457,8 +13439,8 @@ function WithdrawDoubleInput({
12457
13439
  const isDarkMode = useTheme().themeClass.includes("uf-dark");
12458
13440
  const selectedToken = selectedTokenSymbol ? tokens.find((t11) => t11.symbol === selectedTokenSymbol) : void 0;
12459
13441
  const availableChainsForToken = selectedToken?.chains || [];
12460
- const renderTokenItem = (tokenData) => /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
12461
- /* @__PURE__ */ jsx52(
13442
+ const renderTokenItem = (tokenData) => /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
13443
+ /* @__PURE__ */ jsx53(
12462
13444
  "img",
12463
13445
  {
12464
13446
  src: tokenData.icon_url,
@@ -12469,10 +13451,10 @@ function WithdrawDoubleInput({
12469
13451
  className: "uf-rounded-full uf-flex-shrink-0"
12470
13452
  }
12471
13453
  ),
12472
- /* @__PURE__ */ jsx52("span", { className: "uf-text-xs uf-font-normal", children: tokenData.symbol })
13454
+ /* @__PURE__ */ jsx53("span", { className: "uf-text-xs uf-font-normal", children: tokenData.symbol })
12473
13455
  ] });
12474
- const renderChainItem = (chainData) => /* @__PURE__ */ jsxs45("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
12475
- /* @__PURE__ */ jsx52(
13456
+ const renderChainItem = (chainData) => /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
13457
+ /* @__PURE__ */ jsx53(
12476
13458
  "img",
12477
13459
  {
12478
13460
  src: chainData.icon_url,
@@ -12483,14 +13465,14 @@ function WithdrawDoubleInput({
12483
13465
  className: "uf-rounded-full uf-flex-shrink-0"
12484
13466
  }
12485
13467
  ),
12486
- /* @__PURE__ */ jsx52("span", { className: "uf-text-xs uf-font-normal", children: chainData.chain_name })
13468
+ /* @__PURE__ */ jsx53("span", { className: "uf-text-xs uf-font-normal", children: chainData.chain_name })
12487
13469
  ] });
12488
13470
  const currentChainData = selectedChainKey ? availableChainsForToken.find(
12489
13471
  (c) => getChainKey4(c.chain_id, c.chain_type) === selectedChainKey
12490
13472
  ) : void 0;
12491
- return /* @__PURE__ */ jsxs45("div", { className: "uf-grid uf-grid-cols-2 uf-gap-2.5", children: [
12492
- /* @__PURE__ */ jsxs45("div", { children: [
12493
- /* @__PURE__ */ jsx52(
13473
+ return /* @__PURE__ */ jsxs46("div", { className: "uf-grid uf-grid-cols-2 uf-gap-2.5", children: [
13474
+ /* @__PURE__ */ jsxs46("div", { children: [
13475
+ /* @__PURE__ */ jsx53(
12494
13476
  "div",
12495
13477
  {
12496
13478
  className: "uf-text-xs uf-mb-2 uf-flex uf-items-center uf-gap-1",
@@ -12498,14 +13480,14 @@ function WithdrawDoubleInput({
12498
13480
  children: t7.receiveToken
12499
13481
  }
12500
13482
  ),
12501
- /* @__PURE__ */ jsxs45(
13483
+ /* @__PURE__ */ jsxs46(
12502
13484
  Select,
12503
13485
  {
12504
13486
  value: selectedTokenSymbol ?? "",
12505
13487
  onValueChange: onTokenChange,
12506
13488
  disabled: isLoading || tokens.length === 0,
12507
13489
  children: [
12508
- /* @__PURE__ */ jsx52(
13490
+ /* @__PURE__ */ jsx53(
12509
13491
  SelectTrigger,
12510
13492
  {
12511
13493
  className: "uf-h-10 hover:uf-opacity-90 uf-text-foreground disabled:uf-opacity-50",
@@ -12513,10 +13495,10 @@ function WithdrawDoubleInput({
12513
13495
  backgroundColor: components.card.backgroundColor,
12514
13496
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
12515
13497
  },
12516
- children: /* @__PURE__ */ jsx52(SelectValue, { children: isLoading || !selectedTokenSymbol ? /* @__PURE__ */ jsx52("span", { className: "uf-text-xs uf-font-light uf-text-muted-foreground", children: t7.loading }) : selectedToken ? renderTokenItem(selectedToken) : /* @__PURE__ */ jsx52("span", { className: "uf-text-xs uf-font-normal", children: selectedTokenSymbol }) })
13498
+ children: /* @__PURE__ */ jsx53(SelectValue, { children: isLoading || !selectedTokenSymbol ? /* @__PURE__ */ jsx53("span", { className: "uf-text-xs uf-font-light uf-text-muted-foreground", children: t7.loading }) : selectedToken ? renderTokenItem(selectedToken) : /* @__PURE__ */ jsx53("span", { className: "uf-text-xs uf-font-normal", children: selectedTokenSymbol }) })
12517
13499
  }
12518
13500
  ),
12519
- /* @__PURE__ */ jsx52(
13501
+ /* @__PURE__ */ jsx53(
12520
13502
  SelectContent,
12521
13503
  {
12522
13504
  className: "uf-bg-secondary uf-border uf-text-foreground uf-max-h-[300px]",
@@ -12524,7 +13506,7 @@ function WithdrawDoubleInput({
12524
13506
  border: `1px solid ${isDarkMode ? "rgba(255,255,255,0.15)" : "rgba(0,0,0,0.15)"}`,
12525
13507
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
12526
13508
  },
12527
- children: tokens.map((tokenData) => /* @__PURE__ */ jsx52(
13509
+ children: tokens.map((tokenData) => /* @__PURE__ */ jsx53(
12528
13510
  SelectItem,
12529
13511
  {
12530
13512
  value: tokenData.symbol,
@@ -12539,8 +13521,8 @@ function WithdrawDoubleInput({
12539
13521
  }
12540
13522
  )
12541
13523
  ] }),
12542
- /* @__PURE__ */ jsxs45("div", { children: [
12543
- /* @__PURE__ */ jsx52(
13524
+ /* @__PURE__ */ jsxs46("div", { children: [
13525
+ /* @__PURE__ */ jsx53(
12544
13526
  "div",
12545
13527
  {
12546
13528
  className: "uf-text-xs uf-mb-2 uf-flex uf-items-center uf-gap-1",
@@ -12548,14 +13530,14 @@ function WithdrawDoubleInput({
12548
13530
  children: t7.receiveChain
12549
13531
  }
12550
13532
  ),
12551
- /* @__PURE__ */ jsxs45(
13533
+ /* @__PURE__ */ jsxs46(
12552
13534
  Select,
12553
13535
  {
12554
13536
  value: selectedChainKey ?? "",
12555
13537
  onValueChange: onChainChange,
12556
13538
  disabled: isLoading || availableChainsForToken.length === 0,
12557
13539
  children: [
12558
- /* @__PURE__ */ jsx52(
13540
+ /* @__PURE__ */ jsx53(
12559
13541
  SelectTrigger,
12560
13542
  {
12561
13543
  className: "uf-h-10 hover:uf-opacity-90 uf-text-foreground disabled:uf-opacity-50",
@@ -12563,10 +13545,10 @@ function WithdrawDoubleInput({
12563
13545
  backgroundColor: components.card.backgroundColor,
12564
13546
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
12565
13547
  },
12566
- children: /* @__PURE__ */ jsx52(SelectValue, { children: isLoading || !selectedChainKey ? /* @__PURE__ */ jsx52("span", { className: "uf-text-xs uf-font-light uf-text-muted-foreground", children: t7.loading }) : currentChainData ? renderChainItem(currentChainData) : /* @__PURE__ */ jsx52("span", { className: "uf-text-xs uf-font-normal", children: selectedChainKey }) })
13548
+ children: /* @__PURE__ */ jsx53(SelectValue, { children: isLoading || !selectedChainKey ? /* @__PURE__ */ jsx53("span", { className: "uf-text-xs uf-font-light uf-text-muted-foreground", children: t7.loading }) : currentChainData ? renderChainItem(currentChainData) : /* @__PURE__ */ jsx53("span", { className: "uf-text-xs uf-font-normal", children: selectedChainKey }) })
12567
13549
  }
12568
13550
  ),
12569
- /* @__PURE__ */ jsx52(
13551
+ /* @__PURE__ */ jsx53(
12570
13552
  SelectContent,
12571
13553
  {
12572
13554
  align: "end",
@@ -12575,9 +13557,9 @@ function WithdrawDoubleInput({
12575
13557
  border: `1px solid ${isDarkMode ? "rgba(255,255,255,0.15)" : "rgba(0,0,0,0.15)"}`,
12576
13558
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
12577
13559
  },
12578
- children: availableChainsForToken.length === 0 ? /* @__PURE__ */ jsx52("div", { className: "uf-px-2 uf-py-3 uf-text-xs uf-text-muted-foreground uf-text-center", children: "No chains available" }) : availableChainsForToken.map((chainData) => {
13560
+ children: availableChainsForToken.length === 0 ? /* @__PURE__ */ jsx53("div", { className: "uf-px-2 uf-py-3 uf-text-xs uf-text-muted-foreground uf-text-center", children: "No chains available" }) : availableChainsForToken.map((chainData) => {
12579
13561
  const chainKey = getChainKey4(chainData.chain_id, chainData.chain_type);
12580
- return /* @__PURE__ */ jsx52(
13562
+ return /* @__PURE__ */ jsx53(
12581
13563
  SelectItem,
12582
13564
  {
12583
13565
  value: chainKey,
@@ -12597,22 +13579,25 @@ function WithdrawDoubleInput({
12597
13579
  }
12598
13580
 
12599
13581
  // src/components/withdrawals/WithdrawForm.tsx
12600
- import { useState as useState29, useCallback as useCallback5, useMemo as useMemo10, useEffect as useEffect23 } from "react";
13582
+ import { useState as useState30, useCallback as useCallback6, useMemo as useMemo11, useEffect as useEffect25 } from "react";
12601
13583
  import {
12602
- AlertTriangle as AlertTriangle2,
13584
+ AlertTriangle as AlertTriangle3,
12603
13585
  ArrowUpDown,
12604
13586
  ChevronDown as ChevronDown7,
12605
13587
  ChevronUp as ChevronUp6,
12606
13588
  Clock as Clock4,
12607
13589
  ClipboardPaste,
12608
13590
  DollarSign as DollarSign3,
12609
- Loader2 as Loader25,
13591
+ Loader2 as Loader26,
12610
13592
  ShieldCheck as ShieldCheck3,
12611
13593
  Wallet as Wallet3
12612
13594
  } from "lucide-react";
13595
+ import {
13596
+ checkHypercoreActivation
13597
+ } from "@unifold/core";
12613
13598
 
12614
13599
  // src/hooks/use-verify-recipient-address.ts
12615
- import { useQuery as useQuery13 } from "@tanstack/react-query";
13600
+ import { useQuery as useQuery15 } from "@tanstack/react-query";
12616
13601
  import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
12617
13602
  function useVerifyRecipientAddress(params) {
12618
13603
  const {
@@ -12625,7 +13610,7 @@ function useVerifyRecipientAddress(params) {
12625
13610
  } = params;
12626
13611
  const trimmedAddress = recipientAddress?.trim() || "";
12627
13612
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
12628
- return useQuery13({
13613
+ return useQuery15({
12629
13614
  queryKey: [
12630
13615
  "unifold",
12631
13616
  "verifyRecipientAddress",
@@ -12656,7 +13641,9 @@ function useVerifyRecipientAddress(params) {
12656
13641
  // src/components/withdrawals/send-withdraw.ts
12657
13642
  import {
12658
13643
  buildSolanaTransaction as buildSolanaTransaction2,
12659
- sendSolanaTransaction as sendSolanaTransactionToBackend2
13644
+ sendSolanaTransaction as sendSolanaTransactionToBackend2,
13645
+ buildHypercoreTransaction as buildHypercoreTransactionFromBackend,
13646
+ sendHypercoreTransaction as sendHypercoreTransactionToBackend
12660
13647
  } from "@unifold/core";
12661
13648
  async function sendEvmWithdraw(params) {
12662
13649
  const {
@@ -12767,9 +13754,56 @@ async function sendSolanaWithdraw(params) {
12767
13754
  );
12768
13755
  return sendResponse.signature;
12769
13756
  }
13757
+ var HYPERCORE_CHAIN_ID = "1337";
13758
+ var HYPERCORE_SPOT_USDC_ADDRESS = "0x6d1e7cde53ba9467b783cb7c530ce054";
13759
+ function isHypercoreChain(chainId) {
13760
+ return chainId === HYPERCORE_CHAIN_ID;
13761
+ }
13762
+ async function sendHypercoreWithdraw(params) {
13763
+ const {
13764
+ provider,
13765
+ fromAddress,
13766
+ depositWalletAddress,
13767
+ sourceTokenAddress,
13768
+ amount,
13769
+ tokenSymbol,
13770
+ publishableKey
13771
+ } = params;
13772
+ const isSpot = sourceTokenAddress.toLowerCase() === HYPERCORE_SPOT_USDC_ADDRESS;
13773
+ const currentChainHex = await provider.request({
13774
+ method: "eth_chainId",
13775
+ params: []
13776
+ });
13777
+ const activeChainId = String(parseInt(currentChainHex, 16));
13778
+ const buildResult = await buildHypercoreTransactionFromBackend(
13779
+ {
13780
+ action_type: isSpot ? "spot_send" : "usd_send",
13781
+ signature_chain_type: "ethereum",
13782
+ signature_chain_id: activeChainId,
13783
+ recipient_address: depositWalletAddress,
13784
+ token_address: sourceTokenAddress,
13785
+ token_symbol: tokenSymbol || void 0,
13786
+ amount
13787
+ },
13788
+ publishableKey
13789
+ );
13790
+ const signature = await provider.request({
13791
+ method: "eth_signTypedData_v4",
13792
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
13793
+ });
13794
+ await sendHypercoreTransactionToBackend(
13795
+ {
13796
+ action_payload: buildResult.action_payload,
13797
+ signature,
13798
+ nonce: buildResult.nonce
13799
+ },
13800
+ publishableKey
13801
+ );
13802
+ }
12770
13803
  async function detectBrowserWallet(chainType, senderAddress) {
12771
13804
  const win = typeof window !== "undefined" ? window : null;
12772
13805
  if (!win || !senderAddress) return null;
13806
+ if (getUserDisconnectedWallet()) return null;
12773
13807
  const anyWin = win;
12774
13808
  if (chainType === "solana") {
12775
13809
  const solProviders = [];
@@ -12803,28 +13837,44 @@ async function detectBrowserWallet(chainType, senderAddress) {
12803
13837
  evmProviders.push({ provider: p, name });
12804
13838
  }
12805
13839
  };
12806
- add(anyWin.phantom?.ethereum, "Phantom");
12807
- add(anyWin.coinbaseWalletExtension, "Coinbase");
12808
- add(anyWin.trustwallet?.ethereum, "Trust Wallet");
12809
- add(anyWin.okxwallet, "OKX Wallet");
12810
- if (anyWin.__eip6963Providers) {
12811
- for (const detail of anyWin.__eip6963Providers) {
12812
- const rdns = detail.info?.rdns || "";
12813
- let name = detail.info?.name || "Wallet";
12814
- if (rdns.includes("metamask")) name = "MetaMask";
12815
- else if (rdns.includes("rabby")) name = "Rabby";
12816
- else if (rdns.includes("rainbow")) name = "Rainbow";
12817
- add(detail.provider, name);
12818
- }
13840
+ if (!anyWin.__eip6963Providers) {
13841
+ anyWin.__eip6963Providers = [];
12819
13842
  }
12820
- if (win.ethereum) {
12821
- const eth = win.ethereum;
12822
- let name = "Wallet";
12823
- if (eth.isMetaMask && !eth.isPhantom && !eth.isRabby) name = "MetaMask";
12824
- else if (eth.isRabby) name = "Rabby";
12825
- else if (eth.isRainbow) name = "Rainbow";
12826
- else if (eth.isCoinbaseWallet) name = "Coinbase";
12827
- add(eth, name);
13843
+ const handleAnnouncement = (event) => {
13844
+ const { detail } = event;
13845
+ if (!detail?.info || !detail?.provider) return;
13846
+ const exists = anyWin.__eip6963Providers.some((p) => p.info.uuid === detail.info.uuid);
13847
+ if (!exists) anyWin.__eip6963Providers.push(detail);
13848
+ };
13849
+ win.addEventListener("eip6963:announceProvider", handleAnnouncement);
13850
+ win.dispatchEvent(new Event("eip6963:requestProvider"));
13851
+ win.removeEventListener("eip6963:announceProvider", handleAnnouncement);
13852
+ for (const detail of anyWin.__eip6963Providers) {
13853
+ const rdns = detail.info?.rdns || "";
13854
+ let name = detail.info?.name || "Wallet";
13855
+ if (rdns.includes("metamask")) name = "MetaMask";
13856
+ else if (rdns.includes("phantom")) name = "Phantom";
13857
+ else if (rdns.includes("coinbase")) name = "Coinbase";
13858
+ else if (rdns.includes("rabby")) name = "Rabby";
13859
+ else if (rdns.includes("rainbow")) name = "Rainbow";
13860
+ else if (rdns.includes("okx")) name = "OKX Wallet";
13861
+ else if (rdns.includes("trust")) name = "Trust Wallet";
13862
+ add(detail.provider, name);
13863
+ }
13864
+ if (evmProviders.length === 0) {
13865
+ add(anyWin.phantom?.ethereum, "Phantom");
13866
+ add(anyWin.coinbaseWalletExtension, "Coinbase");
13867
+ add(anyWin.trustwallet?.ethereum, "Trust Wallet");
13868
+ add(anyWin.okxwallet, "OKX Wallet");
13869
+ if (evmProviders.length === 0 && win.ethereum) {
13870
+ const eth = win.ethereum;
13871
+ let name = "Wallet";
13872
+ if (eth.isMetaMask && !eth.isPhantom && !eth.isRabby) name = "MetaMask";
13873
+ else if (eth.isRabby) name = "Rabby";
13874
+ else if (eth.isRainbow) name = "Rainbow";
13875
+ else if (eth.isCoinbaseWallet) name = "Coinbase";
13876
+ add(eth, name);
13877
+ }
12828
13878
  }
12829
13879
  for (const { provider, name } of evmProviders) {
12830
13880
  try {
@@ -12840,7 +13890,7 @@ async function detectBrowserWallet(chainType, senderAddress) {
12840
13890
  }
12841
13891
 
12842
13892
  // src/components/withdrawals/WithdrawForm.tsx
12843
- import { Fragment as Fragment10, jsx as jsx53, jsxs as jsxs46 } from "react/jsx-runtime";
13893
+ import { Fragment as Fragment11, jsx as jsx54, jsxs as jsxs47 } from "react/jsx-runtime";
12844
13894
  var t8 = i18n.withdrawModal;
12845
13895
  var tCrypto = i18n.transferCrypto;
12846
13896
  function formatProcessingTime2(seconds) {
@@ -12880,12 +13930,9 @@ function WithdrawForm({
12880
13930
  estimatedProcessingTime,
12881
13931
  maxSlippagePercent,
12882
13932
  priceImpactPercent,
12883
- detectedWallet,
13933
+ senderAddress,
12884
13934
  sourceChainId,
12885
13935
  sourceTokenAddress,
12886
- isWalletMatch,
12887
- connectedWalletName,
12888
- canWithdraw,
12889
13936
  onWithdraw,
12890
13937
  onWithdrawError,
12891
13938
  onDepositWalletCreation,
@@ -12893,22 +13940,22 @@ function WithdrawForm({
12893
13940
  footerLeft
12894
13941
  }) {
12895
13942
  const { colors: colors2, fonts, components } = useTheme();
12896
- const [recipientAddress, setRecipientAddress] = useState29(recipientAddressProp || "");
12897
- const [amount, setAmount] = useState29("");
12898
- const [inputUnit, setInputUnit] = useState29("crypto");
12899
- const [isSubmitting, setIsSubmitting] = useState29(false);
12900
- const [submitError, setSubmitError] = useState29(null);
12901
- const [detailsExpanded, setDetailsExpanded] = useState29(false);
12902
- const [glossaryOpen, setGlossaryOpen] = useState29(false);
12903
- useEffect23(() => {
13943
+ const [recipientAddress, setRecipientAddress] = useState30(recipientAddressProp || "");
13944
+ const [amount, setAmount] = useState30("");
13945
+ const [inputUnit, setInputUnit] = useState30("crypto");
13946
+ const [isSubmitting, setIsSubmitting] = useState30(false);
13947
+ const [submitError, setSubmitError] = useState30(null);
13948
+ const [detailsExpanded, setDetailsExpanded] = useState30(false);
13949
+ const [glossaryOpen, setGlossaryOpen] = useState30(false);
13950
+ useEffect25(() => {
12904
13951
  setRecipientAddress(recipientAddressProp || "");
12905
13952
  setAmount("");
12906
13953
  setInputUnit("crypto");
12907
13954
  setSubmitError(null);
12908
13955
  }, [recipientAddressProp]);
12909
13956
  const trimmedAddress = recipientAddress.trim();
12910
- const [debouncedAddress, setDebouncedAddress] = useState29(trimmedAddress);
12911
- useEffect23(() => {
13957
+ const [debouncedAddress, setDebouncedAddress] = useState30(trimmedAddress);
13958
+ useEffect25(() => {
12912
13959
  const id = setTimeout(() => setDebouncedAddress(trimmedAddress), 500);
12913
13960
  return () => clearTimeout(id);
12914
13961
  }, [trimmedAddress]);
@@ -12925,7 +13972,7 @@ function WithdrawForm({
12925
13972
  enabled: debouncedAddress.length > 5 && !!selectedChain
12926
13973
  });
12927
13974
  const isDebouncing = trimmedAddress !== debouncedAddress;
12928
- const addressError = useMemo10(() => {
13975
+ const addressError = useMemo11(() => {
12929
13976
  if (!trimmedAddress || trimmedAddress.length <= 5) return null;
12930
13977
  if (isDebouncing || isVerifyingAddress) return null;
12931
13978
  if (verifyError) return t8.invalidAddress;
@@ -12939,47 +13986,47 @@ function WithdrawForm({
12939
13986
  return null;
12940
13987
  }, [trimmedAddress, isDebouncing, isVerifyingAddress, verifyError, addressVerification, selectedChain, selectedToken]);
12941
13988
  const isAddressValid = !isDebouncing && !!addressVerification?.valid && !addressError;
12942
- const exchangeRate = useMemo10(() => {
13989
+ const exchangeRate = useMemo11(() => {
12943
13990
  if (!balanceData?.exchangeRate) return 0;
12944
13991
  return parseFloat(balanceData.exchangeRate);
12945
13992
  }, [balanceData]);
12946
- const balanceCrypto = useMemo10(() => {
13993
+ const balanceCrypto = useMemo11(() => {
12947
13994
  if (!balanceData?.balanceHuman) return 0;
12948
13995
  return parseFloat(balanceData.balanceHuman);
12949
13996
  }, [balanceData]);
12950
- const balanceUsdNum = useMemo10(() => {
13997
+ const balanceUsdNum = useMemo11(() => {
12951
13998
  if (!balanceData?.balanceUsd) return 0;
12952
13999
  return parseFloat(balanceData.balanceUsd);
12953
14000
  }, [balanceData]);
12954
14001
  const tokenSymbol = sourceTokenSymbol || balanceData?.symbol || "TOKEN";
12955
14002
  const sourceDecimals = balanceData?.decimals ?? 6;
12956
- const cryptoAmountFromInput = useMemo10(() => {
14003
+ const cryptoAmountFromInput = useMemo11(() => {
12957
14004
  const val = parseFloat(amount);
12958
14005
  if (!val || val <= 0) return 0;
12959
14006
  if (inputUnit === "crypto") return val;
12960
14007
  return exchangeRate > 0 ? val / exchangeRate : 0;
12961
14008
  }, [amount, inputUnit, exchangeRate]);
12962
- const fiatAmountFromInput = useMemo10(() => {
14009
+ const fiatAmountFromInput = useMemo11(() => {
12963
14010
  const val = parseFloat(amount);
12964
14011
  if (!val || val <= 0) return 0;
12965
14012
  if (inputUnit === "fiat") return val;
12966
14013
  return val * exchangeRate;
12967
14014
  }, [amount, inputUnit, exchangeRate]);
12968
- const convertedDisplay = useMemo10(() => {
14015
+ const convertedDisplay = useMemo11(() => {
12969
14016
  if (!amount || parseFloat(amount) <= 0) return null;
12970
14017
  if (inputUnit === "crypto") {
12971
14018
  return `$${fiatAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
12972
14019
  }
12973
14020
  return `${cryptoAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 6 })} ${tokenSymbol}`;
12974
14021
  }, [amount, inputUnit, fiatAmountFromInput, cryptoAmountFromInput, tokenSymbol]);
12975
- const balanceDisplay = useMemo10(() => {
14022
+ const balanceDisplay = useMemo11(() => {
12976
14023
  if (isLoadingBalance || !balanceData) return null;
12977
14024
  if (inputUnit === "crypto") {
12978
14025
  return `${balanceCrypto.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${tokenSymbol}`;
12979
14026
  }
12980
14027
  return `$${balanceUsdNum.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
12981
14028
  }, [isLoadingBalance, balanceData, inputUnit, balanceCrypto, balanceUsdNum, tokenSymbol]);
12982
- const handleSwitchUnit = useCallback5(() => {
14029
+ const handleSwitchUnit = useCallback6(() => {
12983
14030
  const val = parseFloat(amount);
12984
14031
  if (!val || val <= 0 || exchangeRate <= 0) {
12985
14032
  setInputUnit((u) => u === "crypto" ? "fiat" : "crypto");
@@ -12996,7 +14043,7 @@ function WithdrawForm({
12996
14043
  setInputUnit("crypto");
12997
14044
  }
12998
14045
  }, [amount, inputUnit, exchangeRate, sourceDecimals]);
12999
- const handleMaxClick = useCallback5(() => {
14046
+ const handleMaxClick = useCallback6(() => {
13000
14047
  if (inputUnit === "crypto") {
13001
14048
  if (balanceCrypto <= 0) return;
13002
14049
  setAmount(balanceData?.balanceHuman ?? "0");
@@ -13008,7 +14055,7 @@ function WithdrawForm({
13008
14055
  const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && fiatAmountFromInput < minimumWithdrawAmountUsd;
13009
14056
  const isOverBalance = inputUnit === "crypto" ? cryptoAmountFromInput > 0 && balanceCrypto > 0 && cryptoAmountFromInput > balanceCrypto : fiatAmountFromInput > 0 && balanceUsdNum > 0 && fiatAmountFromInput > balanceUsdNum;
13010
14057
  const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !!balanceData;
13011
- const handleWithdraw = useCallback5(async () => {
14058
+ const handleWithdraw = useCallback6(async () => {
13012
14059
  if (!selectedToken || !selectedChain) return;
13013
14060
  if (!isFormValid) return;
13014
14061
  setIsSubmitting(true);
@@ -13020,12 +14067,43 @@ function WithdrawForm({
13020
14067
  destinationTokenAddress: selectedChain.token_address,
13021
14068
  recipientAddress: trimmedAddress
13022
14069
  });
13023
- const amountBaseUnit = computeBaseUnit(
14070
+ let amountBaseUnit = computeBaseUnit(
13024
14071
  balanceData.balanceBaseUnit,
13025
14072
  parseFloat(amount),
13026
14073
  inputUnit === "crypto" ? balanceCrypto : balanceUsdNum
13027
14074
  );
13028
- const humanAmount = toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
14075
+ let humanAmount = toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
14076
+ if (isHypercoreChain(sourceChainId)) {
14077
+ try {
14078
+ const check = await checkHypercoreActivation(
14079
+ {
14080
+ source_address: senderAddress,
14081
+ recipient_address: depositWallet.address
14082
+ },
14083
+ publishableKey
14084
+ );
14085
+ if (!check.user_exists) {
14086
+ const fee = check.activation_fee;
14087
+ const maxSendable = balanceCrypto - fee;
14088
+ if (maxSendable <= 0) {
14089
+ throw new Error(
14090
+ `Insufficient balance. A ${fee} USDC activation fee is required for the first transfer to this address.`
14091
+ );
14092
+ }
14093
+ const requestedAmount = parseFloat(humanAmount);
14094
+ if (requestedAmount > maxSendable) {
14095
+ humanAmount = toSafeDecimalString(maxSendable, sourceDecimals);
14096
+ amountBaseUnit = computeBaseUnit(
14097
+ balanceData.balanceBaseUnit,
14098
+ maxSendable,
14099
+ balanceCrypto
14100
+ );
14101
+ }
14102
+ }
14103
+ } catch (e) {
14104
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
14105
+ }
14106
+ }
13029
14107
  const txInfo = {
13030
14108
  sourceChainType,
13031
14109
  sourceChainId,
@@ -13040,33 +14118,67 @@ function WithdrawForm({
13040
14118
  withdrawIntentAddress: depositWallet.address,
13041
14119
  recipientAddress: trimmedAddress
13042
14120
  };
13043
- if (detectedWallet) {
13044
- if (detectedWallet.chainFamily === "evm") {
13045
- await sendEvmWithdraw({
13046
- provider: detectedWallet.provider,
13047
- fromAddress: detectedWallet.address,
13048
- depositWalletAddress: depositWallet.address,
13049
- sourceTokenAddress,
14121
+ const wallet = await detectBrowserWallet(sourceChainType, senderAddress);
14122
+ console.log("browser wallet", wallet);
14123
+ if (wallet) {
14124
+ try {
14125
+ if (wallet.chainFamily === "evm" && isHypercoreChain(sourceChainId)) {
14126
+ await sendHypercoreWithdraw({
14127
+ provider: wallet.provider,
14128
+ fromAddress: wallet.address,
14129
+ depositWalletAddress: depositWallet.address,
14130
+ sourceTokenAddress,
14131
+ amount: humanAmount,
14132
+ tokenSymbol,
14133
+ publishableKey
14134
+ });
14135
+ } else if (wallet.chainFamily === "evm") {
14136
+ await sendEvmWithdraw({
14137
+ provider: wallet.provider,
14138
+ fromAddress: wallet.address,
14139
+ depositWalletAddress: depositWallet.address,
14140
+ sourceTokenAddress,
14141
+ sourceChainId,
14142
+ amountBaseUnit
14143
+ });
14144
+ } else if (wallet.chainFamily === "solana") {
14145
+ await sendSolanaWithdraw({
14146
+ provider: wallet.provider,
14147
+ fromAddress: wallet.address,
14148
+ depositWalletAddress: depositWallet.address,
14149
+ sourceTokenAddress,
14150
+ amountBaseUnit,
14151
+ publishableKey
14152
+ });
14153
+ }
14154
+ } catch (walletErr) {
14155
+ console.error("[Unifold] Browser wallet send failed:", walletErr, {
14156
+ wallet: `${wallet.name} (${wallet.chainFamily})`,
13050
14157
  sourceChainId,
13051
- amountBaseUnit
13052
- });
13053
- } else if (detectedWallet.chainFamily === "solana") {
13054
- await sendSolanaWithdraw({
13055
- provider: detectedWallet.provider,
13056
- fromAddress: detectedWallet.address,
13057
- depositWalletAddress: depositWallet.address,
13058
- sourceTokenAddress,
14158
+ amount: humanAmount,
13059
14159
  amountBaseUnit,
13060
- publishableKey
14160
+ depositWallet: depositWallet.address
13061
14161
  });
14162
+ throw walletErr;
13062
14163
  }
13063
14164
  } else if (onWithdraw) {
13064
- await onWithdraw(txInfo);
14165
+ try {
14166
+ await onWithdraw(txInfo);
14167
+ } catch (callbackErr) {
14168
+ console.error("[Unifold] onWithdraw callback failed:", callbackErr, {
14169
+ sourceChainId,
14170
+ amount: humanAmount,
14171
+ amountBaseUnit,
14172
+ depositWallet: depositWallet.address
14173
+ });
14174
+ throw callbackErr;
14175
+ }
13065
14176
  } else {
13066
14177
  throw new Error("No withdrawal method available. Please connect a wallet.");
13067
14178
  }
13068
14179
  onWithdrawSubmitted?.(txInfo);
13069
14180
  } catch (err) {
14181
+ console.error("[Unifold] Withdrawal failed:", err);
13070
14182
  const raw = err instanceof Error ? err.message : "Withdrawal failed. Please try again.";
13071
14183
  setSubmitError(raw.length > 120 ? "Withdrawal failed. Please try again." : raw);
13072
14184
  onWithdrawError?.({
@@ -13077,10 +14189,10 @@ function WithdrawForm({
13077
14189
  } finally {
13078
14190
  setIsSubmitting(false);
13079
14191
  }
13080
- }, [selectedToken, selectedChain, isFormValid, cryptoAmountFromInput, sourceDecimals, trimmedAddress, publishableKey, onWithdraw, detectedWallet, sourceTokenAddress, sourceChainId, onWithdrawError, onDepositWalletCreation, onWithdrawSubmitted, amount, inputUnit, balanceCrypto, balanceUsdNum, balanceData]);
13081
- return /* @__PURE__ */ jsxs46(Fragment10, { children: [
13082
- /* @__PURE__ */ jsxs46("div", { children: [
13083
- /* @__PURE__ */ jsx53(
14192
+ }, [selectedToken, selectedChain, isFormValid, cryptoAmountFromInput, sourceDecimals, trimmedAddress, publishableKey, onWithdraw, sourceChainType, senderAddress, sourceTokenAddress, sourceChainId, onWithdrawError, onDepositWalletCreation, onWithdrawSubmitted, amount, inputUnit, balanceCrypto, balanceUsdNum, balanceData]);
14193
+ return /* @__PURE__ */ jsxs47(Fragment11, { children: [
14194
+ /* @__PURE__ */ jsxs47("div", { children: [
14195
+ /* @__PURE__ */ jsx54(
13084
14196
  "div",
13085
14197
  {
13086
14198
  className: "uf-text-xs uf-mb-1.5",
@@ -13088,7 +14200,7 @@ function WithdrawForm({
13088
14200
  children: t8.recipientAddress
13089
14201
  }
13090
14202
  ),
13091
- /* @__PURE__ */ jsx53(
14203
+ /* @__PURE__ */ jsx54(
13092
14204
  "style",
13093
14205
  {
13094
14206
  dangerouslySetInnerHTML: {
@@ -13096,7 +14208,7 @@ function WithdrawForm({
13096
14208
  }
13097
14209
  }
13098
14210
  ),
13099
- /* @__PURE__ */ jsxs46(
14211
+ /* @__PURE__ */ jsxs47(
13100
14212
  "div",
13101
14213
  {
13102
14214
  className: "uf-flex uf-items-center uf-gap-1 uf-pr-2",
@@ -13106,7 +14218,7 @@ function WithdrawForm({
13106
14218
  border: `${components.input.borderWidth}px solid ${addressError ? colors2.error : components.input.borderColor}`
13107
14219
  },
13108
14220
  children: [
13109
- /* @__PURE__ */ jsx53(
14221
+ /* @__PURE__ */ jsx54(
13110
14222
  "input",
13111
14223
  {
13112
14224
  type: "text",
@@ -13123,7 +14235,7 @@ function WithdrawForm({
13123
14235
  }
13124
14236
  }
13125
14237
  ),
13126
- /* @__PURE__ */ jsx53(
14238
+ /* @__PURE__ */ jsx54(
13127
14239
  "button",
13128
14240
  {
13129
14241
  type: "button",
@@ -13140,27 +14252,27 @@ function WithdrawForm({
13140
14252
  className: "uf-flex-shrink-0 uf-p-1 uf-rounded uf-transition-colors hover:uf-opacity-70",
13141
14253
  style: { color: colors2.foregroundMuted },
13142
14254
  title: "Paste from clipboard",
13143
- children: /* @__PURE__ */ jsx53(ClipboardPaste, { className: "uf-w-4 uf-h-4" })
14255
+ children: /* @__PURE__ */ jsx54(ClipboardPaste, { className: "uf-w-4 uf-h-4" })
13144
14256
  }
13145
14257
  )
13146
14258
  ]
13147
14259
  }
13148
14260
  ),
13149
- (isDebouncing || isVerifyingAddress) && trimmedAddress.length > 5 && /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-1.5", children: [
13150
- /* @__PURE__ */ jsx53(Loader25, { className: "uf-w-3 uf-h-3 uf-animate-spin", style: { color: colors2.foregroundMuted } }),
13151
- /* @__PURE__ */ jsx53("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: t8.verifyingAddress })
14261
+ (isDebouncing || isVerifyingAddress) && trimmedAddress.length > 5 && /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-1.5", children: [
14262
+ /* @__PURE__ */ jsx54(Loader26, { className: "uf-w-3 uf-h-3 uf-animate-spin", style: { color: colors2.foregroundMuted } }),
14263
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: t8.verifyingAddress })
13152
14264
  ] }),
13153
- addressError && /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-1.5", children: [
13154
- /* @__PURE__ */ jsx53(AlertTriangle2, { className: "uf-w-3 uf-h-3", style: { color: colors2.error } }),
13155
- /* @__PURE__ */ jsx53("span", { className: "uf-text-xs", style: { color: colors2.error, fontFamily: fonts.regular }, children: addressError })
14265
+ addressError && /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-1.5", children: [
14266
+ /* @__PURE__ */ jsx54(AlertTriangle3, { className: "uf-w-3 uf-h-3", style: { color: colors2.error } }),
14267
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.error, fontFamily: fonts.regular }, children: addressError })
13156
14268
  ] })
13157
14269
  ] }),
13158
- /* @__PURE__ */ jsxs46("div", { children: [
13159
- /* @__PURE__ */ jsxs46("div", { className: "uf-text-xs uf-mb-1.5", style: { color: components.card.labelColor, fontFamily: fonts.medium }, children: [
14270
+ /* @__PURE__ */ jsxs47("div", { children: [
14271
+ /* @__PURE__ */ jsxs47("div", { className: "uf-text-xs uf-mb-1.5", style: { color: components.card.labelColor, fontFamily: fonts.medium }, children: [
13160
14272
  t8.amount,
13161
- minimumWithdrawAmountUsd != null && minimumWithdrawAmountUsd > 0 && /* @__PURE__ */ jsx53("span", { style: { color: colors2.warning, fontFamily: fonts.regular }, children: ` ($${minimumWithdrawAmountUsd.toFixed(2)} min)` })
14273
+ minimumWithdrawAmountUsd != null && minimumWithdrawAmountUsd > 0 && /* @__PURE__ */ jsx54("span", { style: { color: colors2.warning, fontFamily: fonts.regular }, children: ` ($${minimumWithdrawAmountUsd.toFixed(2)} min)` })
13162
14274
  ] }),
13163
- /* @__PURE__ */ jsx53(
14275
+ /* @__PURE__ */ jsx54(
13164
14276
  "style",
13165
14277
  {
13166
14278
  dangerouslySetInnerHTML: {
@@ -13168,7 +14280,7 @@ function WithdrawForm({
13168
14280
  }
13169
14281
  }
13170
14282
  ),
13171
- /* @__PURE__ */ jsxs46(
14283
+ /* @__PURE__ */ jsxs47(
13172
14284
  "div",
13173
14285
  {
13174
14286
  className: "uf-flex uf-items-center uf-gap-2 uf-px-3 uf-py-2.5",
@@ -13178,7 +14290,7 @@ function WithdrawForm({
13178
14290
  border: `${components.input.borderWidth}px solid ${components.input.borderColor}`
13179
14291
  },
13180
14292
  children: [
13181
- /* @__PURE__ */ jsx53(
14293
+ /* @__PURE__ */ jsx54(
13182
14294
  "input",
13183
14295
  {
13184
14296
  type: "text",
@@ -13199,8 +14311,8 @@ function WithdrawForm({
13199
14311
  }
13200
14312
  }
13201
14313
  ),
13202
- /* @__PURE__ */ jsx53("span", { className: "uf-text-sm uf-shrink-0", style: { color: colors2.foregroundMuted, fontFamily: fonts.medium }, children: inputUnit === "crypto" ? tokenSymbol : "USD" }),
13203
- /* @__PURE__ */ jsx53(
14314
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-sm uf-shrink-0", style: { color: colors2.foregroundMuted, fontFamily: fonts.medium }, children: inputUnit === "crypto" ? tokenSymbol : "USD" }),
14315
+ /* @__PURE__ */ jsx54(
13204
14316
  "button",
13205
14317
  {
13206
14318
  type: "button",
@@ -13213,10 +14325,10 @@ function WithdrawForm({
13213
14325
  ]
13214
14326
  }
13215
14327
  ),
13216
- /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-justify-between uf-mt-1.5 uf-px-3", children: [
13217
- /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
13218
- /* @__PURE__ */ jsx53("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: convertedDisplay || (inputUnit === "crypto" ? "$0.00" : `0.00 ${tokenSymbol}`) }),
13219
- exchangeRate > 0 && /* @__PURE__ */ jsx53(
14328
+ /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-justify-between uf-mt-1.5 uf-px-3", children: [
14329
+ /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
14330
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: convertedDisplay || (inputUnit === "crypto" ? "$0.00" : `0.00 ${tokenSymbol}`) }),
14331
+ exchangeRate > 0 && /* @__PURE__ */ jsx54(
13220
14332
  "button",
13221
14333
  {
13222
14334
  type: "button",
@@ -13224,49 +14336,49 @@ function WithdrawForm({
13224
14336
  className: "uf-p-0.5 uf-rounded uf-transition-colors hover:uf-opacity-70",
13225
14337
  style: { color: colors2.foregroundMuted },
13226
14338
  title: "Switch unit",
13227
- children: /* @__PURE__ */ jsx53(ArrowUpDown, { className: "uf-w-3 uf-h-3" })
14339
+ children: /* @__PURE__ */ jsx54(ArrowUpDown, { className: "uf-w-3 uf-h-3" })
13228
14340
  }
13229
14341
  )
13230
14342
  ] }),
13231
- /* @__PURE__ */ jsxs46("div", { children: [
13232
- balanceDisplay && /* @__PURE__ */ jsxs46("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: [
14343
+ /* @__PURE__ */ jsxs47("div", { children: [
14344
+ balanceDisplay && /* @__PURE__ */ jsxs47("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: [
13233
14345
  t8.balance,
13234
14346
  ": ",
13235
14347
  balanceDisplay
13236
14348
  ] }),
13237
- isLoadingBalance && /* @__PURE__ */ jsx53("div", { className: "uf-h-3 uf-w-16 uf-bg-muted uf-rounded uf-animate-pulse" })
14349
+ isLoadingBalance && /* @__PURE__ */ jsx54("div", { className: "uf-h-3 uf-w-16 uf-bg-muted uf-rounded uf-animate-pulse" })
13238
14350
  ] })
13239
14351
  ] })
13240
14352
  ] }),
13241
- /* @__PURE__ */ jsxs46("div", { className: "uf-px-2.5", style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` }, children: [
13242
- /* @__PURE__ */ jsxs46(
14353
+ /* @__PURE__ */ jsxs47("div", { className: "uf-px-2.5", style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` }, children: [
14354
+ /* @__PURE__ */ jsxs47(
13243
14355
  "button",
13244
14356
  {
13245
14357
  type: "button",
13246
14358
  onClick: () => setDetailsExpanded(!detailsExpanded),
13247
14359
  className: "uf-w-full uf-flex uf-items-center uf-justify-between uf-py-2.5",
13248
14360
  children: [
13249
- /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
13250
- /* @__PURE__ */ jsx53("div", { className: "uf-rounded-full uf-p-1", style: { backgroundColor: components.card.iconBackgroundColor }, children: /* @__PURE__ */ jsx53(Clock4, { className: "uf-w-3 uf-h-3", style: { color: components.card.iconColor } }) }),
13251
- /* @__PURE__ */ jsxs46("span", { className: "uf-text-xs", style: { color: components.card.labelColor, fontFamily: fonts.regular }, children: [
14361
+ /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
14362
+ /* @__PURE__ */ jsx54("div", { className: "uf-rounded-full uf-p-1", style: { backgroundColor: components.card.iconBackgroundColor }, children: /* @__PURE__ */ jsx54(Clock4, { className: "uf-w-3 uf-h-3", style: { color: components.card.iconColor } }) }),
14363
+ /* @__PURE__ */ jsxs47("span", { className: "uf-text-xs", style: { color: components.card.labelColor, fontFamily: fonts.regular }, children: [
13252
14364
  tCrypto.processingTime.label,
13253
14365
  ":",
13254
14366
  " ",
13255
- /* @__PURE__ */ jsx53("span", { style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: formatProcessingTime2(estimatedProcessingTime) })
14367
+ /* @__PURE__ */ jsx54("span", { style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: formatProcessingTime2(estimatedProcessingTime) })
13256
14368
  ] })
13257
14369
  ] }),
13258
- detailsExpanded ? /* @__PURE__ */ jsx53(ChevronUp6, { className: "uf-w-4 uf-h-4", style: { color: components.card.actionColor } }) : /* @__PURE__ */ jsx53(ChevronDown7, { className: "uf-w-4 uf-h-4", style: { color: components.card.actionColor } })
14370
+ detailsExpanded ? /* @__PURE__ */ jsx54(ChevronUp6, { className: "uf-w-4 uf-h-4", style: { color: components.card.actionColor } }) : /* @__PURE__ */ jsx54(ChevronDown7, { className: "uf-w-4 uf-h-4", style: { color: components.card.actionColor } })
13259
14371
  ]
13260
14372
  }
13261
14373
  ),
13262
- detailsExpanded && /* @__PURE__ */ jsxs46("div", { className: "uf-pb-3 uf-space-y-2.5", children: [
13263
- /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
13264
- /* @__PURE__ */ jsx53("div", { className: "uf-rounded-full uf-p-1", style: { backgroundColor: components.card.iconBackgroundColor }, children: /* @__PURE__ */ jsx53(ShieldCheck3, { className: "uf-w-3 uf-h-3", style: { color: components.card.iconColor } }) }),
13265
- /* @__PURE__ */ jsxs46("span", { className: "uf-text-xs", style: { color: components.card.labelColor, fontFamily: fonts.regular }, children: [
14374
+ detailsExpanded && /* @__PURE__ */ jsxs47("div", { className: "uf-pb-3 uf-space-y-2.5", children: [
14375
+ /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
14376
+ /* @__PURE__ */ jsx54("div", { className: "uf-rounded-full uf-p-1", style: { backgroundColor: components.card.iconBackgroundColor }, children: /* @__PURE__ */ jsx54(ShieldCheck3, { className: "uf-w-3 uf-h-3", style: { color: components.card.iconColor } }) }),
14377
+ /* @__PURE__ */ jsxs47("span", { className: "uf-text-xs", style: { color: components.card.labelColor, fontFamily: fonts.regular }, children: [
13266
14378
  tCrypto.slippage.label,
13267
14379
  ":",
13268
14380
  " ",
13269
- /* @__PURE__ */ jsxs46("span", { style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: [
14381
+ /* @__PURE__ */ jsxs47("span", { style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: [
13270
14382
  tCrypto.slippage.auto,
13271
14383
  " \u2022 ",
13272
14384
  (maxSlippagePercent ?? 0.25).toFixed(2),
@@ -13274,13 +14386,13 @@ function WithdrawForm({
13274
14386
  ] })
13275
14387
  ] })
13276
14388
  ] }),
13277
- /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
13278
- /* @__PURE__ */ jsx53("div", { className: "uf-rounded-full uf-p-1", style: { backgroundColor: components.card.iconBackgroundColor }, children: /* @__PURE__ */ jsx53(DollarSign3, { className: "uf-w-3 uf-h-3", style: { color: components.card.iconColor } }) }),
13279
- /* @__PURE__ */ jsxs46("span", { className: "uf-text-xs", style: { color: components.card.labelColor, fontFamily: fonts.regular }, children: [
14389
+ /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
14390
+ /* @__PURE__ */ jsx54("div", { className: "uf-rounded-full uf-p-1", style: { backgroundColor: components.card.iconBackgroundColor }, children: /* @__PURE__ */ jsx54(DollarSign3, { className: "uf-w-3 uf-h-3", style: { color: components.card.iconColor } }) }),
14391
+ /* @__PURE__ */ jsxs47("span", { className: "uf-text-xs", style: { color: components.card.labelColor, fontFamily: fonts.regular }, children: [
13280
14392
  tCrypto.priceImpact.label,
13281
14393
  ":",
13282
14394
  " ",
13283
- /* @__PURE__ */ jsxs46("span", { style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: [
14395
+ /* @__PURE__ */ jsxs47("span", { style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: [
13284
14396
  (priceImpactPercent ?? 0).toFixed(2),
13285
14397
  "%"
13286
14398
  ] })
@@ -13288,23 +14400,12 @@ function WithdrawForm({
13288
14400
  ] })
13289
14401
  ] })
13290
14402
  ] }),
13291
- !canWithdraw && !submitError && /* @__PURE__ */ jsxs46(
13292
- "div",
13293
- {
13294
- className: "uf-flex uf-items-start uf-gap-2.5 uf-p-3 uf-rounded-xl",
13295
- style: { backgroundColor: colors2.card, border: `1px solid ${colors2.border}` },
13296
- children: [
13297
- /* @__PURE__ */ jsx53(Wallet3, { className: "uf-w-4 uf-h-4 uf-flex-shrink-0 uf-mt-0.5", style: { color: colors2.warning } }),
13298
- /* @__PURE__ */ jsx53("div", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "No connected wallet detected. Please connect a wallet that matches your account to withdraw." })
13299
- ]
13300
- }
13301
- ),
13302
- isWalletMatch && connectedWalletName ? /* @__PURE__ */ jsx53(
14403
+ /* @__PURE__ */ jsx54(
13303
14404
  "button",
13304
14405
  {
13305
14406
  type: "button",
13306
14407
  onClick: handleWithdraw,
13307
- disabled: !isFormValid || !canWithdraw || isSubmitting || !selectedToken || !selectedChain,
14408
+ disabled: !isFormValid || isSubmitting || !selectedToken || !selectedChain,
13308
14409
  className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed uf-flex uf-items-center uf-justify-center uf-gap-2",
13309
14410
  style: {
13310
14411
  backgroundColor: colors2.primary,
@@ -13313,40 +14414,20 @@ function WithdrawForm({
13313
14414
  borderRadius: components.button.borderRadius,
13314
14415
  border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
13315
14416
  },
13316
- children: isSubmitting ? /* @__PURE__ */ jsxs46(Fragment10, { children: [
13317
- /* @__PURE__ */ jsx53(Loader25, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
14417
+ children: isSubmitting ? /* @__PURE__ */ jsxs47(Fragment11, { children: [
14418
+ /* @__PURE__ */ jsx54(Loader26, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
13318
14419
  "Processing..."
13319
- ] }) : isOverBalance ? /* @__PURE__ */ jsx53(Fragment10, { children: "Insufficient balance" }) : isBelowMinimum ? /* @__PURE__ */ jsx53(Fragment10, { children: "Minimum amount not met" }) : submitError ? /* @__PURE__ */ jsx53(Fragment10, { children: "Withdrawal failed. Try again" }) : /* @__PURE__ */ jsxs46(Fragment10, { children: [
13320
- /* @__PURE__ */ jsx53(Wallet3, { className: "uf-w-4 uf-h-4" }),
13321
- "Withdraw from ",
13322
- connectedWalletName
14420
+ ] }) : isOverBalance ? /* @__PURE__ */ jsx54(Fragment11, { children: "Insufficient balance" }) : isBelowMinimum ? /* @__PURE__ */ jsx54(Fragment11, { children: "Minimum amount not met" }) : submitError ? /* @__PURE__ */ jsx54(Fragment11, { children: "Withdrawal failed. Try again" }) : /* @__PURE__ */ jsxs47(Fragment11, { children: [
14421
+ /* @__PURE__ */ jsx54(Wallet3, { className: "uf-w-4 uf-h-4" }),
14422
+ t8.withdraw
13323
14423
  ] })
13324
14424
  }
13325
- ) : /* @__PURE__ */ jsx53(
13326
- "button",
13327
- {
13328
- type: "button",
13329
- onClick: handleWithdraw,
13330
- disabled: !isFormValid || !canWithdraw || isSubmitting || !selectedToken || !selectedChain,
13331
- className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
13332
- style: {
13333
- backgroundColor: colors2.primary,
13334
- color: colors2.primaryForeground,
13335
- fontFamily: fonts.medium,
13336
- borderRadius: components.button.borderRadius,
13337
- border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
13338
- },
13339
- children: isSubmitting ? /* @__PURE__ */ jsxs46("span", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2", children: [
13340
- /* @__PURE__ */ jsx53(Loader25, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
13341
- "Processing..."
13342
- ] }) : isOverBalance ? "Insufficient balance" : isBelowMinimum ? "Minimum amount not met" : submitError ? "Withdrawal failed. Try again" : t8.withdraw
13343
- }
13344
14425
  ),
13345
- /* @__PURE__ */ jsxs46("div", { className: "uf-flex uf-items-center uf-justify-between uf-text-xs uf-pt-1", children: [
13346
- /* @__PURE__ */ jsx53("div", { children: footerLeft }),
13347
- /* @__PURE__ */ jsx53(DepositFooterLinks, { onGlossaryClick: () => setGlossaryOpen(true) })
14426
+ /* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-justify-between uf-text-xs uf-pt-1", children: [
14427
+ /* @__PURE__ */ jsx54("div", { children: footerLeft }),
14428
+ /* @__PURE__ */ jsx54(DepositFooterLinks, { onGlossaryClick: () => setGlossaryOpen(true) })
13348
14429
  ] }),
13349
- /* @__PURE__ */ jsx53(
14430
+ /* @__PURE__ */ jsx54(
13350
14431
  GlossaryModal,
13351
14432
  {
13352
14433
  open: glossaryOpen,
@@ -13357,12 +14438,12 @@ function WithdrawForm({
13357
14438
  }
13358
14439
 
13359
14440
  // src/components/withdrawals/WithdrawExecutionItem.tsx
13360
- import { ChevronRight as ChevronRight12 } from "lucide-react";
14441
+ import { ChevronRight as ChevronRight13 } from "lucide-react";
13361
14442
  import {
13362
14443
  ExecutionStatus as ExecutionStatus6,
13363
14444
  getIconUrl as getIconUrl5
13364
14445
  } from "@unifold/core";
13365
- import { jsx as jsx54, jsxs as jsxs47 } from "react/jsx-runtime";
14446
+ import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
13366
14447
  function WithdrawExecutionItem({
13367
14448
  execution,
13368
14449
  onClick
@@ -13400,7 +14481,7 @@ function WithdrawExecutionItem({
13400
14481
  return "$0.00";
13401
14482
  }
13402
14483
  };
13403
- return /* @__PURE__ */ jsxs47(
14484
+ return /* @__PURE__ */ jsxs48(
13404
14485
  "button",
13405
14486
  {
13406
14487
  onClick,
@@ -13411,8 +14492,8 @@ function WithdrawExecutionItem({
13411
14492
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
13412
14493
  },
13413
14494
  children: [
13414
- /* @__PURE__ */ jsxs47("div", { className: "uf-relative uf-flex-shrink-0 uf-w-9 uf-h-9", children: [
13415
- /* @__PURE__ */ jsx54(
14495
+ /* @__PURE__ */ jsxs48("div", { className: "uf-relative uf-flex-shrink-0 uf-w-9 uf-h-9", children: [
14496
+ /* @__PURE__ */ jsx55(
13416
14497
  "img",
13417
14498
  {
13418
14499
  src: execution.destination_token_metadata?.icon_url || getIconUrl5("/icons/tokens/svg/usdc.svg"),
@@ -13423,12 +14504,12 @@ function WithdrawExecutionItem({
13423
14504
  className: "uf-rounded-full uf-w-9 uf-h-9"
13424
14505
  }
13425
14506
  ),
13426
- isPending ? /* @__PURE__ */ jsx54(
14507
+ isPending ? /* @__PURE__ */ jsx55(
13427
14508
  "div",
13428
14509
  {
13429
14510
  className: "uf-absolute -uf-bottom-0.5 -uf-right-0.5 uf-rounded-full uf-p-0.5",
13430
14511
  style: { backgroundColor: colors2.warning },
13431
- children: /* @__PURE__ */ jsx54(
14512
+ children: /* @__PURE__ */ jsx55(
13432
14513
  "svg",
13433
14514
  {
13434
14515
  width: "10",
@@ -13436,7 +14517,7 @@ function WithdrawExecutionItem({
13436
14517
  viewBox: "0 0 12 12",
13437
14518
  fill: "none",
13438
14519
  className: "uf-animate-spin uf-block",
13439
- children: /* @__PURE__ */ jsx54(
14520
+ children: /* @__PURE__ */ jsx55(
13440
14521
  "path",
13441
14522
  {
13442
14523
  d: "M6 1V3M6 9V11M1 6H3M9 6H11M2.5 2.5L4 4M8 8L9.5 9.5M2.5 9.5L4 8M8 4L9.5 2.5",
@@ -13448,12 +14529,12 @@ function WithdrawExecutionItem({
13448
14529
  }
13449
14530
  )
13450
14531
  }
13451
- ) : /* @__PURE__ */ jsx54(
14532
+ ) : /* @__PURE__ */ jsx55(
13452
14533
  "div",
13453
14534
  {
13454
14535
  className: "uf-absolute -uf-bottom-0.5 -uf-right-0.5 uf-rounded-full uf-p-0.5",
13455
14536
  style: { backgroundColor: colors2.success },
13456
- children: /* @__PURE__ */ jsx54(
14537
+ children: /* @__PURE__ */ jsx55(
13457
14538
  "svg",
13458
14539
  {
13459
14540
  width: "10",
@@ -13461,7 +14542,7 @@ function WithdrawExecutionItem({
13461
14542
  viewBox: "0 0 12 12",
13462
14543
  fill: "none",
13463
14544
  className: "uf-block",
13464
- children: /* @__PURE__ */ jsx54(
14545
+ children: /* @__PURE__ */ jsx55(
13465
14546
  "path",
13466
14547
  {
13467
14548
  d: "M10 3L4.5 8.5L2 6",
@@ -13476,8 +14557,8 @@ function WithdrawExecutionItem({
13476
14557
  }
13477
14558
  )
13478
14559
  ] }),
13479
- /* @__PURE__ */ jsxs47("div", { className: "uf-flex-1 uf-min-w-0", children: [
13480
- /* @__PURE__ */ jsx54(
14560
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex-1 uf-min-w-0", children: [
14561
+ /* @__PURE__ */ jsx55(
13481
14562
  "h3",
13482
14563
  {
13483
14564
  className: "uf-font-medium uf-text-sm uf-leading-tight",
@@ -13488,7 +14569,7 @@ function WithdrawExecutionItem({
13488
14569
  children: isPending ? "Withdrawal processing" : "Withdrawal completed"
13489
14570
  }
13490
14571
  ),
13491
- /* @__PURE__ */ jsx54(
14572
+ /* @__PURE__ */ jsx55(
13492
14573
  "p",
13493
14574
  {
13494
14575
  className: "uf-text-xs uf-leading-tight",
@@ -13500,7 +14581,7 @@ function WithdrawExecutionItem({
13500
14581
  }
13501
14582
  )
13502
14583
  ] }),
13503
- /* @__PURE__ */ jsx54(
14584
+ /* @__PURE__ */ jsx55(
13504
14585
  "span",
13505
14586
  {
13506
14587
  className: "uf-font-medium uf-text-sm uf-flex-shrink-0",
@@ -13511,8 +14592,8 @@ function WithdrawExecutionItem({
13511
14592
  children: formatUsdAmount2(execution.source_amount_usd || "0")
13512
14593
  }
13513
14594
  ),
13514
- /* @__PURE__ */ jsx54(
13515
- ChevronRight12,
14595
+ /* @__PURE__ */ jsx55(
14596
+ ChevronRight13,
13516
14597
  {
13517
14598
  className: "uf-w-4 uf-h-4 uf-flex-shrink-0",
13518
14599
  style: { color: components.card.actionColor }
@@ -13524,8 +14605,8 @@ function WithdrawExecutionItem({
13524
14605
  }
13525
14606
 
13526
14607
  // src/components/withdrawals/WithdrawConfirmingView.tsx
13527
- import { useState as useState30, useEffect as useEffect24 } from "react";
13528
- import { Fragment as Fragment11, jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
14608
+ import { useState as useState31, useEffect as useEffect26 } from "react";
14609
+ import { Fragment as Fragment12, jsx as jsx56, jsxs as jsxs49 } from "react/jsx-runtime";
13529
14610
  function truncateAddress4(addr) {
13530
14611
  if (addr.length <= 12) return addr;
13531
14612
  return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
@@ -13538,9 +14619,9 @@ function WithdrawConfirmingView({
13538
14619
  onViewTracker
13539
14620
  }) {
13540
14621
  const { colors: colors2, fonts, components } = useTheme();
13541
- const [showButton, setShowButton] = useState30(false);
14622
+ const [showButton, setShowButton] = useState31(false);
13542
14623
  const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
13543
- useEffect24(() => {
14624
+ useEffect26(() => {
13544
14625
  if (latestExecution) return;
13545
14626
  const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
13546
14627
  return () => clearTimeout(timer);
@@ -13548,11 +14629,11 @@ function WithdrawConfirmingView({
13548
14629
  const btnRadius = components.button.borderRadius;
13549
14630
  const btnBorder = `${components.button.borderWidth}px solid ${components.button.borderColor}`;
13550
14631
  if (latestExecution) {
13551
- return /* @__PURE__ */ jsxs48(Fragment11, { children: [
13552
- /* @__PURE__ */ jsx55(DepositHeader, { title: "Withdrawal Details", showClose: true, onClose }),
13553
- /* @__PURE__ */ jsx55(DepositDetailContent, { execution: latestExecution, variant: "withdraw" }),
13554
- /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-2", children: [
13555
- /* @__PURE__ */ jsx55(
14632
+ return /* @__PURE__ */ jsxs49(Fragment12, { children: [
14633
+ /* @__PURE__ */ jsx56(DepositHeader, { title: "Withdrawal Details", showClose: true, onClose }),
14634
+ /* @__PURE__ */ jsx56(DepositDetailContent, { execution: latestExecution, variant: "withdraw" }),
14635
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-2", children: [
14636
+ /* @__PURE__ */ jsx56(
13556
14637
  "button",
13557
14638
  {
13558
14639
  type: "button",
@@ -13568,7 +14649,7 @@ function WithdrawConfirmingView({
13568
14649
  children: "Withdrawal History"
13569
14650
  }
13570
14651
  ),
13571
- /* @__PURE__ */ jsx55(
14652
+ /* @__PURE__ */ jsx56(
13572
14653
  "button",
13573
14654
  {
13574
14655
  type: "button",
@@ -13585,7 +14666,7 @@ function WithdrawConfirmingView({
13585
14666
  }
13586
14667
  )
13587
14668
  ] }),
13588
- /* @__PURE__ */ jsx55("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx55(
14669
+ /* @__PURE__ */ jsx56("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx56(
13589
14670
  PoweredByUnifold,
13590
14671
  {
13591
14672
  color: colors2.foregroundMuted,
@@ -13594,15 +14675,15 @@ function WithdrawConfirmingView({
13594
14675
  ) })
13595
14676
  ] });
13596
14677
  }
13597
- return /* @__PURE__ */ jsxs48(Fragment11, { children: [
13598
- /* @__PURE__ */ jsx55(DepositHeader, { title: "Withdrawal Status", showClose: true, onClose }),
13599
- /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16 uf-px-4", children: [
13600
- /* @__PURE__ */ jsx55(
14678
+ return /* @__PURE__ */ jsxs49(Fragment12, { children: [
14679
+ /* @__PURE__ */ jsx56(DepositHeader, { title: "Withdrawal Status", showClose: true, onClose }),
14680
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16 uf-px-4", children: [
14681
+ /* @__PURE__ */ jsx56(
13601
14682
  "div",
13602
14683
  {
13603
14684
  className: "uf-w-20 uf-h-20 uf-rounded-full uf-flex uf-items-center uf-justify-center uf-mb-6",
13604
14685
  style: { backgroundColor: `${colors2.primary}20` },
13605
- children: /* @__PURE__ */ jsx55(
14686
+ children: /* @__PURE__ */ jsx56(
13606
14687
  "svg",
13607
14688
  {
13608
14689
  width: "40",
@@ -13610,7 +14691,7 @@ function WithdrawConfirmingView({
13610
14691
  viewBox: "0 0 24 24",
13611
14692
  fill: "none",
13612
14693
  className: "uf-animate-spin",
13613
- children: /* @__PURE__ */ jsx55(
14694
+ children: /* @__PURE__ */ jsx56(
13614
14695
  "path",
13615
14696
  {
13616
14697
  d: "M21 12a9 9 0 1 1-6.22-8.56",
@@ -13623,7 +14704,7 @@ function WithdrawConfirmingView({
13623
14704
  )
13624
14705
  }
13625
14706
  ),
13626
- /* @__PURE__ */ jsx55(
14707
+ /* @__PURE__ */ jsx56(
13627
14708
  "h3",
13628
14709
  {
13629
14710
  className: "uf-text-xl uf-mb-2",
@@ -13631,7 +14712,7 @@ function WithdrawConfirmingView({
13631
14712
  children: "Checking Withdrawal"
13632
14713
  }
13633
14714
  ),
13634
- /* @__PURE__ */ jsxs48(
14715
+ /* @__PURE__ */ jsxs49(
13635
14716
  "p",
13636
14717
  {
13637
14718
  className: "uf-text-sm uf-text-center",
@@ -13647,7 +14728,7 @@ function WithdrawConfirmingView({
13647
14728
  }
13648
14729
  )
13649
14730
  ] }),
13650
- showButton && /* @__PURE__ */ jsx55("div", { className: "uf-px-1 uf-pb-1", children: /* @__PURE__ */ jsx55(
14731
+ showButton && /* @__PURE__ */ jsx56("div", { className: "uf-px-1 uf-pb-1", children: /* @__PURE__ */ jsx56(
13651
14732
  "button",
13652
14733
  {
13653
14734
  type: "button",
@@ -13663,7 +14744,7 @@ function WithdrawConfirmingView({
13663
14744
  children: "Withdrawal History"
13664
14745
  }
13665
14746
  ) }),
13666
- /* @__PURE__ */ jsx55("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx55(
14747
+ /* @__PURE__ */ jsx56("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx56(
13667
14748
  PoweredByUnifold,
13668
14749
  {
13669
14750
  color: colors2.foregroundMuted,
@@ -13679,7 +14760,7 @@ import {
13679
14760
  getWalletByChainType as getWalletByChainType4,
13680
14761
  ActionType as ActionType6
13681
14762
  } from "@unifold/core";
13682
- import { Fragment as Fragment12, jsx as jsx56, jsxs as jsxs49 } from "react/jsx-runtime";
14763
+ import { Fragment as Fragment13, jsx as jsx57, jsxs as jsxs50 } from "react/jsx-runtime";
13683
14764
  var t9 = i18n.withdrawModal;
13684
14765
  var getChainKey5 = (chainId, chainType) => `${chainType}:${chainId}`;
13685
14766
  function WithdrawModal({
@@ -13701,14 +14782,14 @@ function WithdrawModal({
13701
14782
  hideOverlay = false
13702
14783
  }) {
13703
14784
  const { colors: colors2, fonts, components } = useTheme();
13704
- const [containerEl, setContainerEl] = useState31(null);
13705
- const containerCallbackRef = useCallback6((el) => {
14785
+ const [containerEl, setContainerEl] = useState32(null);
14786
+ const containerCallbackRef = useCallback7((el) => {
13706
14787
  setContainerEl(el);
13707
14788
  }, []);
13708
- const [resolvedTheme, setResolvedTheme] = useState31(
14789
+ const [resolvedTheme, setResolvedTheme] = useState32(
13709
14790
  theme === "auto" ? "dark" : theme
13710
14791
  );
13711
- useEffect25(() => {
14792
+ useEffect27(() => {
13712
14793
  if (theme === "auto") {
13713
14794
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
13714
14795
  setResolvedTheme(mq.matches ? "dark" : "light");
@@ -13737,28 +14818,12 @@ function WithdrawModal({
13737
14818
  publishableKey,
13738
14819
  enabled: open
13739
14820
  });
13740
- const [selectedToken, setSelectedToken] = useState31(null);
13741
- const [selectedChain, setSelectedChain] = useState31(null);
13742
- const [detectedWallet, setDetectedWallet] = useState31(null);
13743
- const connectedWalletName = detectedWallet?.name ?? null;
13744
- const isWalletMatch = !!detectedWallet;
13745
- useEffect25(() => {
13746
- if (!senderAddress || !open) {
13747
- setDetectedWallet(null);
13748
- return;
13749
- }
13750
- let cancelled = false;
13751
- detectBrowserWallet(sourceChainType, senderAddress).then((wallet) => {
13752
- if (!cancelled) setDetectedWallet(wallet);
13753
- });
13754
- return () => {
13755
- cancelled = true;
13756
- };
13757
- }, [senderAddress, sourceChainType, open]);
13758
- const [view, setView] = useState31("form");
13759
- const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState31();
13760
- const [selectedExecution, setSelectedExecution] = useState31(null);
13761
- const [submittedTxInfo, setSubmittedTxInfo] = useState31(null);
14821
+ const [selectedToken, setSelectedToken] = useState32(null);
14822
+ const [selectedChain, setSelectedChain] = useState32(null);
14823
+ const [view, setView] = useState32("form");
14824
+ const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState32();
14825
+ const [selectedExecution, setSelectedExecution] = useState32(null);
14826
+ const [submittedTxInfo, setSubmittedTxInfo] = useState32(null);
13762
14827
  const { executions: realtimeExecutions } = useWithdrawPolling({
13763
14828
  userId: externalUserId,
13764
14829
  publishableKey,
@@ -13773,7 +14838,7 @@ function WithdrawModal({
13773
14838
  refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
13774
14839
  });
13775
14840
  const allWithdrawals = allWithdrawalsData?.data ?? [];
13776
- const handleDepositWalletCreation = useCallback6(async (params) => {
14841
+ const handleDepositWalletCreation = useCallback7(async (params) => {
13777
14842
  const { data: wallets } = await createDepositAddress2(
13778
14843
  {
13779
14844
  external_user_id: externalUserId,
@@ -13792,11 +14857,11 @@ function WithdrawModal({
13792
14857
  setWithdrawDepositWalletId(depositWallet.id);
13793
14858
  return depositWallet;
13794
14859
  }, [externalUserId, publishableKey, sourceChainType]);
13795
- const handleWithdrawSubmitted = useCallback6((txInfo) => {
14860
+ const handleWithdrawSubmitted = useCallback7((txInfo) => {
13796
14861
  setSubmittedTxInfo(txInfo);
13797
14862
  setView("confirming");
13798
14863
  }, []);
13799
- useEffect25(() => {
14864
+ useEffect27(() => {
13800
14865
  if (!destinationTokens.length || selectedToken) return;
13801
14866
  const first = destinationTokens[0];
13802
14867
  if (first?.chains.length > 0) {
@@ -13804,8 +14869,8 @@ function WithdrawModal({
13804
14869
  setSelectedChain(first.chains[0]);
13805
14870
  }
13806
14871
  }, [destinationTokens, selectedToken]);
13807
- const resetViewTimeoutRef = useRef8(null);
13808
- const handleClose = useCallback6(() => {
14872
+ const resetViewTimeoutRef = useRef10(null);
14873
+ const handleClose = useCallback7(() => {
13809
14874
  onOpenChange(false);
13810
14875
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
13811
14876
  resetViewTimeoutRef.current = setTimeout(() => {
@@ -13818,7 +14883,7 @@ function WithdrawModal({
13818
14883
  resetViewTimeoutRef.current = null;
13819
14884
  }, 200);
13820
14885
  }, [onOpenChange]);
13821
- useLayoutEffect3(() => {
14886
+ useLayoutEffect4(() => {
13822
14887
  if (!open) return;
13823
14888
  if (resetViewTimeoutRef.current) {
13824
14889
  clearTimeout(resetViewTimeoutRef.current);
@@ -13831,26 +14896,25 @@ function WithdrawModal({
13831
14896
  setSubmittedTxInfo(null);
13832
14897
  setWithdrawDepositWalletId(void 0);
13833
14898
  }, [open]);
13834
- useEffect25(() => () => {
14899
+ useEffect27(() => () => {
13835
14900
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
13836
14901
  }, []);
13837
- const handleTokenSymbolChange = useCallback6((symbol) => {
14902
+ const handleTokenSymbolChange = useCallback7((symbol) => {
13838
14903
  const tok = destinationTokens.find((t11) => t11.symbol === symbol);
13839
14904
  if (tok) {
13840
14905
  setSelectedToken(tok);
13841
14906
  if (tok.chains.length > 0) setSelectedChain(tok.chains[0]);
13842
14907
  }
13843
14908
  }, [destinationTokens]);
13844
- const handleChainKeyChange = useCallback6((chainKey) => {
14909
+ const handleChainKeyChange = useCallback7((chainKey) => {
13845
14910
  if (!selectedToken) return;
13846
14911
  const chain = selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === chainKey);
13847
14912
  if (chain) setSelectedChain(chain);
13848
14913
  }, [selectedToken]);
13849
14914
  const isSourceSupported = sourceValidation?.isSupported ?? null;
13850
- const canWithdraw = !!onWithdraw || isWalletMatch;
13851
14915
  const isAnyLoading = tokensLoading || isCheckingSourceToken;
13852
- const withdrawPoweredByFooter = /* @__PURE__ */ jsx56("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx56(PoweredByUnifold, { color: colors2.foregroundMuted, className: "uf-flex uf-justify-center uf-shrink-0" }) });
13853
- return /* @__PURE__ */ jsx56(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ jsx56(Dialog, { open: hideOverlay || open, onOpenChange: hideOverlay ? void 0 : handleClose, modal: !hideOverlay, children: /* @__PURE__ */ jsx56(
14916
+ const withdrawPoweredByFooter = /* @__PURE__ */ jsx57("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx57(PoweredByUnifold, { color: colors2.foregroundMuted, className: "uf-flex uf-justify-center uf-shrink-0" }) });
14917
+ return /* @__PURE__ */ jsx57(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ jsx57(Dialog, { open: hideOverlay || open, onOpenChange: hideOverlay ? void 0 : handleClose, modal: !hideOverlay, children: /* @__PURE__ */ jsx57(
13854
14918
  DialogContent,
13855
14919
  {
13856
14920
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -13859,7 +14923,7 @@ function WithdrawModal({
13859
14923
  style: { backgroundColor: colors2.background },
13860
14924
  onPointerDownOutside: (e) => e.preventDefault(),
13861
14925
  onInteractOutside: (e) => e.preventDefault(),
13862
- children: /* @__PURE__ */ jsx56(ThemeStyleInjector, { children: view === "confirming" && submittedTxInfo ? /* @__PURE__ */ jsx56(
14926
+ children: /* @__PURE__ */ jsx57(ThemeStyleInjector, { children: view === "confirming" && submittedTxInfo ? /* @__PURE__ */ jsx57(
13863
14927
  WithdrawConfirmingView,
13864
14928
  {
13865
14929
  txInfo: submittedTxInfo,
@@ -13867,18 +14931,18 @@ function WithdrawModal({
13867
14931
  onClose: handleClose,
13868
14932
  onViewTracker: () => setView("tracker")
13869
14933
  }
13870
- ) : view === "detail" && selectedExecution ? /* @__PURE__ */ jsxs49(Fragment12, { children: [
13871
- /* @__PURE__ */ jsx56(DepositHeader, { title: "Withdrawal Details", showBack: true, showClose: !hideOverlay, onBack: () => {
14934
+ ) : view === "detail" && selectedExecution ? /* @__PURE__ */ jsxs50(Fragment13, { children: [
14935
+ /* @__PURE__ */ jsx57(DepositHeader, { title: "Withdrawal Details", showBack: true, showClose: !hideOverlay, onBack: () => {
13872
14936
  setSelectedExecution(null);
13873
14937
  setView("tracker");
13874
14938
  }, onClose: handleClose }),
13875
- /* @__PURE__ */ jsx56(DepositDetailContent, { execution: selectedExecution, variant: "withdraw" }),
14939
+ /* @__PURE__ */ jsx57(DepositDetailContent, { execution: selectedExecution, variant: "withdraw" }),
13876
14940
  withdrawPoweredByFooter
13877
14941
  ] }) : view === "tracker" ? (
13878
14942
  /* ---------- Tracker view: execution list ---------- */
13879
- /* @__PURE__ */ jsxs49(Fragment12, { children: [
13880
- /* @__PURE__ */ jsx56(DepositHeader, { title: "Withdrawal History", showBack: true, showClose: !hideOverlay, onBack: () => setView("form"), onClose: handleClose }),
13881
- /* @__PURE__ */ jsx56("div", { className: "uf-flex uf-flex-col uf-gap-2", style: { minHeight: 200 }, children: allWithdrawals.length === 0 ? /* @__PURE__ */ jsx56("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-8", children: /* @__PURE__ */ jsx56("p", { className: "uf-text-sm", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "No withdrawals to track yet" }) }) : allWithdrawals.map((ex) => /* @__PURE__ */ jsx56(
14943
+ /* @__PURE__ */ jsxs50(Fragment13, { children: [
14944
+ /* @__PURE__ */ jsx57(DepositHeader, { title: "Withdrawal History", showBack: true, showClose: !hideOverlay, onBack: () => setView("form"), onClose: handleClose }),
14945
+ /* @__PURE__ */ jsx57("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ jsx57("div", { className: "uf-flex uf-flex-col uf-gap-2", children: allWithdrawals.length === 0 ? /* @__PURE__ */ jsx57("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-8", children: /* @__PURE__ */ jsx57("p", { className: "uf-text-sm", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "No withdrawals to track yet" }) }) : allWithdrawals.map((ex) => /* @__PURE__ */ jsx57(
13882
14946
  WithdrawExecutionItem,
13883
14947
  {
13884
14948
  execution: ex,
@@ -13888,20 +14952,20 @@ function WithdrawModal({
13888
14952
  }
13889
14953
  },
13890
14954
  ex.id
13891
- )) }),
14955
+ )) }) }),
13892
14956
  withdrawPoweredByFooter
13893
14957
  ] })
13894
14958
  ) : (
13895
14959
  /* ---------- Form view (default) ---------- */
13896
- /* @__PURE__ */ jsxs49(Fragment12, { children: [
13897
- /* @__PURE__ */ jsx56(DepositHeader, { title: modalTitle || t9.title, showClose: !hideOverlay, onClose: handleClose }),
13898
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-3", children: [
13899
- isAnyLoading ? /* @__PURE__ */ jsx56("div", { className: "uf-space-y-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx56("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-animate-pulse", children: /* @__PURE__ */ jsx56("div", { className: "uf-bg-muted uf-rounded-lg uf-w-full uf-h-10" }) }, i)) }) : isSourceSupported === false ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
13900
- /* @__PURE__ */ jsx56("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx56(AlertTriangle3, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
13901
- /* @__PURE__ */ jsx56("h3", { className: "uf-text-lg uf-font-semibold uf-mb-2", style: { color: colors2.foreground, fontFamily: fonts.medium }, children: "Unsupported Source Token" }),
13902
- /* @__PURE__ */ jsx56("p", { className: "uf-text-sm uf-max-w-[280px]", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: sourceValidation?.errorMessage })
13903
- ] }) : /* @__PURE__ */ jsxs49(Fragment12, { children: [
13904
- /* @__PURE__ */ jsx56(
14960
+ /* @__PURE__ */ jsxs50(Fragment13, { children: [
14961
+ /* @__PURE__ */ jsx57(DepositHeader, { title: modalTitle || t9.title, showClose: !hideOverlay, onClose: handleClose }),
14962
+ /* @__PURE__ */ jsxs50("div", { className: "uf-flex uf-flex-col uf-gap-3", children: [
14963
+ isAnyLoading ? /* @__PURE__ */ jsx57("div", { className: "uf-space-y-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx57("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-animate-pulse", children: /* @__PURE__ */ jsx57("div", { className: "uf-bg-muted uf-rounded-lg uf-w-full uf-h-10" }) }, i)) }) : isSourceSupported === false ? /* @__PURE__ */ jsxs50("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
14964
+ /* @__PURE__ */ jsx57("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx57(AlertTriangle4, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
14965
+ /* @__PURE__ */ jsx57("h3", { className: "uf-text-lg uf-font-semibold uf-mb-2", style: { color: colors2.foreground, fontFamily: fonts.medium }, children: "Unsupported Source Token" }),
14966
+ /* @__PURE__ */ jsx57("p", { className: "uf-text-sm uf-max-w-[280px]", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: sourceValidation?.errorMessage })
14967
+ ] }) : /* @__PURE__ */ jsxs50(Fragment13, { children: [
14968
+ /* @__PURE__ */ jsx57(
13905
14969
  WithdrawDoubleInput,
13906
14970
  {
13907
14971
  tokens: destinationTokens,
@@ -13912,7 +14976,7 @@ function WithdrawModal({
13912
14976
  isLoading: tokensLoading
13913
14977
  }
13914
14978
  ),
13915
- /* @__PURE__ */ jsx56(
14979
+ /* @__PURE__ */ jsx57(
13916
14980
  WithdrawForm,
13917
14981
  {
13918
14982
  publishableKey,
@@ -13928,26 +14992,23 @@ function WithdrawModal({
13928
14992
  estimatedProcessingTime: sourceValidation?.estimatedProcessingTime ?? null,
13929
14993
  maxSlippagePercent: sourceValidation?.maxSlippagePercent ?? null,
13930
14994
  priceImpactPercent: sourceValidation?.priceImpactPercent ?? null,
13931
- detectedWallet,
14995
+ senderAddress,
13932
14996
  sourceChainId,
13933
14997
  sourceTokenAddress,
13934
- isWalletMatch,
13935
- connectedWalletName,
13936
- canWithdraw,
13937
14998
  onWithdraw,
13938
14999
  onWithdrawError,
13939
15000
  onDepositWalletCreation: handleDepositWalletCreation,
13940
15001
  onWithdrawSubmitted: handleWithdrawSubmitted,
13941
- footerLeft: /* @__PURE__ */ jsxs49(
15002
+ footerLeft: /* @__PURE__ */ jsxs50(
13942
15003
  "button",
13943
15004
  {
13944
15005
  onClick: () => setView("tracker"),
13945
15006
  className: "uf-flex uf-items-center uf-gap-1 uf-transition-colors hover:uf-opacity-70",
13946
15007
  style: { color: colors2.foregroundMuted },
13947
15008
  children: [
13948
- /* @__PURE__ */ jsx56(Clock5, { className: "uf-w-3.5 uf-h-3.5" }),
15009
+ /* @__PURE__ */ jsx57(Clock5, { className: "uf-w-3.5 uf-h-3.5" }),
13949
15010
  "Withdrawal History",
13950
- /* @__PURE__ */ jsx56(ChevronRight13, { className: "uf-w-3 uf-h-3" })
15011
+ /* @__PURE__ */ jsx57(ChevronRight14, { className: "uf-w-3 uf-h-3" })
13951
15012
  ]
13952
15013
  }
13953
15014
  )
@@ -13963,9 +15024,9 @@ function WithdrawModal({
13963
15024
  }
13964
15025
 
13965
15026
  // src/components/withdrawals/WithdrawTokenSelector.tsx
13966
- import { useState as useState32, useMemo as useMemo11 } from "react";
15027
+ import { useState as useState33, useMemo as useMemo12 } from "react";
13967
15028
  import { Search } from "lucide-react";
13968
- import { jsx as jsx57, jsxs as jsxs50 } from "react/jsx-runtime";
15029
+ import { jsx as jsx58, jsxs as jsxs51 } from "react/jsx-runtime";
13969
15030
  var t10 = i18n.withdrawModal;
13970
15031
  function WithdrawTokenSelector({
13971
15032
  tokens,
@@ -13973,9 +15034,9 @@ function WithdrawTokenSelector({
13973
15034
  onBack
13974
15035
  }) {
13975
15036
  const { themeClass, colors: colors2, fonts, components } = useTheme();
13976
- const [searchQuery, setSearchQuery] = useState32("");
13977
- const [hoveredKey, setHoveredKey] = useState32(null);
13978
- const allOptions = useMemo11(() => {
15037
+ const [searchQuery, setSearchQuery] = useState33("");
15038
+ const [hoveredKey, setHoveredKey] = useState33(null);
15039
+ const allOptions = useMemo12(() => {
13979
15040
  const options = [];
13980
15041
  tokens.forEach((token) => {
13981
15042
  token.chains.forEach((chain) => {
@@ -13984,21 +15045,21 @@ function WithdrawTokenSelector({
13984
15045
  });
13985
15046
  return options;
13986
15047
  }, [tokens]);
13987
- const filteredOptions = useMemo11(() => {
15048
+ const filteredOptions = useMemo12(() => {
13988
15049
  if (!searchQuery.trim()) return allOptions;
13989
15050
  const query = searchQuery.toLowerCase();
13990
15051
  return allOptions.filter(
13991
15052
  ({ token, chain }) => token.symbol.toLowerCase().includes(query) || token.name.toLowerCase().includes(query) || chain.chain_name.toLowerCase().includes(query)
13992
15053
  );
13993
15054
  }, [allOptions, searchQuery]);
13994
- return /* @__PURE__ */ jsxs50(
15055
+ return /* @__PURE__ */ jsxs51(
13995
15056
  "div",
13996
15057
  {
13997
15058
  className: "uf-flex uf-flex-col",
13998
15059
  style: { minHeight: 0, flex: 1 },
13999
15060
  children: [
14000
- /* @__PURE__ */ jsxs50("div", { className: "uf-pb-3", children: [
14001
- /* @__PURE__ */ jsx57(
15061
+ /* @__PURE__ */ jsxs51("div", { className: "uf-pb-3", children: [
15062
+ /* @__PURE__ */ jsx58(
14002
15063
  "style",
14003
15064
  {
14004
15065
  dangerouslySetInnerHTML: {
@@ -14006,15 +15067,15 @@ function WithdrawTokenSelector({
14006
15067
  }
14007
15068
  }
14008
15069
  ),
14009
- /* @__PURE__ */ jsxs50("div", { style: { position: "relative" }, children: [
14010
- /* @__PURE__ */ jsx57(
15070
+ /* @__PURE__ */ jsxs51("div", { style: { position: "relative" }, children: [
15071
+ /* @__PURE__ */ jsx58(
14011
15072
  Search,
14012
15073
  {
14013
15074
  className: "uf-absolute uf-left-3 uf-top-1/2 uf--translate-y-1/2 uf-w-4 uf-h-4",
14014
15075
  style: { color: components.search.placeholderColor }
14015
15076
  }
14016
15077
  ),
14017
- /* @__PURE__ */ jsx57(
15078
+ /* @__PURE__ */ jsx58(
14018
15079
  "input",
14019
15080
  {
14020
15081
  type: "text",
@@ -14033,7 +15094,7 @@ function WithdrawTokenSelector({
14033
15094
  )
14034
15095
  ] })
14035
15096
  ] }),
14036
- /* @__PURE__ */ jsx57(
15097
+ /* @__PURE__ */ jsx58(
14037
15098
  "div",
14038
15099
  {
14039
15100
  className: "uf-text-xs uf-mb-2",
@@ -14044,12 +15105,12 @@ function WithdrawTokenSelector({
14044
15105
  children: t10.selectToken
14045
15106
  }
14046
15107
  ),
14047
- /* @__PURE__ */ jsx57(
15108
+ /* @__PURE__ */ jsx58(
14048
15109
  "div",
14049
15110
  {
14050
15111
  className: "uf-flex-1 uf-overflow-y-auto uf-min-h-0 uf--mx-6 uf-px-6 uf-pb-3",
14051
15112
  style: { scrollbarWidth: "none" },
14052
- children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx57(
15113
+ children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx58(
14053
15114
  "div",
14054
15115
  {
14055
15116
  style: {
@@ -14061,9 +15122,9 @@ function WithdrawTokenSelector({
14061
15122
  },
14062
15123
  children: t10.noTokensAvailable
14063
15124
  }
14064
- ) : /* @__PURE__ */ jsx57("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: filteredOptions.map(({ token, chain }) => {
15125
+ ) : /* @__PURE__ */ jsx58("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: filteredOptions.map(({ token, chain }) => {
14065
15126
  const key = `${token.symbol}-${chain.chain_type}:${chain.chain_id}`;
14066
- return /* @__PURE__ */ jsxs50(
15127
+ return /* @__PURE__ */ jsxs51(
14067
15128
  "button",
14068
15129
  {
14069
15130
  type: "button",
@@ -14084,8 +15145,8 @@ function WithdrawTokenSelector({
14084
15145
  backgroundColor: hoveredKey === key ? colors2.cardHover : "transparent"
14085
15146
  },
14086
15147
  children: [
14087
- /* @__PURE__ */ jsxs50("div", { style: { position: "relative", flexShrink: 0 }, children: [
14088
- /* @__PURE__ */ jsx57(
15148
+ /* @__PURE__ */ jsxs51("div", { style: { position: "relative", flexShrink: 0 }, children: [
15149
+ /* @__PURE__ */ jsx58(
14089
15150
  "img",
14090
15151
  {
14091
15152
  src: token.icon_url,
@@ -14096,7 +15157,7 @@ function WithdrawTokenSelector({
14096
15157
  className: "uf-rounded-full"
14097
15158
  }
14098
15159
  ),
14099
- /* @__PURE__ */ jsx57(
15160
+ /* @__PURE__ */ jsx58(
14100
15161
  "div",
14101
15162
  {
14102
15163
  style: {
@@ -14104,7 +15165,7 @@ function WithdrawTokenSelector({
14104
15165
  bottom: -4,
14105
15166
  right: -4
14106
15167
  },
14107
- children: /* @__PURE__ */ jsx57(
15168
+ children: /* @__PURE__ */ jsx58(
14108
15169
  "img",
14109
15170
  {
14110
15171
  src: chain.icon_url,
@@ -14118,8 +15179,8 @@ function WithdrawTokenSelector({
14118
15179
  }
14119
15180
  )
14120
15181
  ] }),
14121
- /* @__PURE__ */ jsxs50("div", { style: { flex: 1, minWidth: 0 }, children: [
14122
- /* @__PURE__ */ jsx57(
15182
+ /* @__PURE__ */ jsxs51("div", { style: { flex: 1, minWidth: 0 }, children: [
15183
+ /* @__PURE__ */ jsx58(
14123
15184
  "div",
14124
15185
  {
14125
15186
  style: {
@@ -14131,7 +15192,7 @@ function WithdrawTokenSelector({
14131
15192
  children: token.symbol
14132
15193
  }
14133
15194
  ),
14134
- /* @__PURE__ */ jsxs50(
15195
+ /* @__PURE__ */ jsxs51(
14135
15196
  "div",
14136
15197
  {
14137
15198
  style: {
@@ -14154,7 +15215,7 @@ function WithdrawTokenSelector({
14154
15215
  }) })
14155
15216
  }
14156
15217
  ),
14157
- /* @__PURE__ */ jsx57("div", { className: "uf-pt-3 uf-pb-2 uf-shrink-0", children: /* @__PURE__ */ jsx57(
15218
+ /* @__PURE__ */ jsx58("div", { className: "uf-pt-3 uf-pb-2 uf-shrink-0", children: /* @__PURE__ */ jsx58(
14158
15219
  PoweredByUnifold,
14159
15220
  {
14160
15221
  color: colors2.foregroundMuted,
@@ -14168,6 +15229,7 @@ function WithdrawTokenSelector({
14168
15229
  export {
14169
15230
  Button,
14170
15231
  BuyWithCard,
15232
+ CheckoutModal,
14171
15233
  ConfirmingView,
14172
15234
  CurrencyListItem,
14173
15235
  CurrencyListSection,
@@ -14191,6 +15253,7 @@ export {
14191
15253
  DialogPortal,
14192
15254
  DialogTitle,
14193
15255
  DialogTrigger,
15256
+ HYPERCORE_CHAIN_ID,
14194
15257
  Select,
14195
15258
  SelectContent,
14196
15259
  SelectGroup,
@@ -14222,14 +15285,18 @@ export {
14222
15285
  defaultColors,
14223
15286
  detectBrowserWallet,
14224
15287
  getColors,
15288
+ isHypercoreChain,
14225
15289
  mergeColors,
14226
15290
  resolveComponentTokens,
14227
15291
  sendEvmWithdraw,
15292
+ sendHypercoreWithdraw,
14228
15293
  sendSolanaWithdraw,
14229
15294
  truncateAddress,
14230
15295
  useAddressBalance,
14231
15296
  useAllowedCountry,
14232
15297
  useDepositPolling,
15298
+ useDepositQuote,
15299
+ usePaymentIntent,
14233
15300
  useSourceTokenValidation,
14234
15301
  useSupportedDestinationTokens,
14235
15302
  useTheme,