@unifold/ui-react 0.1.56 → 0.1.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1525,7 +1525,8 @@ var en_default = {
1525
1525
  title: "Transfer Failed",
1526
1526
  tryAgain: "Try Again"
1527
1527
  },
1528
- continue: "Continue"
1528
+ continue: "Continue",
1529
+ disconnect: "Disconnect"
1529
1530
  },
1530
1531
  buyWithCard: {
1531
1532
  onramp: {
@@ -4856,6 +4857,7 @@ var import_lucide_react14 = require("lucide-react");
4856
4857
  var import_jsx_runtime19 = require("react/jsx-runtime");
4857
4858
  function ConnectExchangeButton({
4858
4859
  onClick,
4860
+ onDisconnect,
4859
4861
  title,
4860
4862
  subtitle,
4861
4863
  exchanges,
@@ -4868,6 +4870,109 @@ function ConnectExchangeButton({
4868
4870
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
4869
4871
  }, []);
4870
4872
  const isConnected = connectedExchange != null;
4873
+ const handleDisconnectClick = (e) => {
4874
+ e.preventDefault();
4875
+ e.stopPropagation();
4876
+ onDisconnect?.();
4877
+ };
4878
+ const rowSurfaceStyle = {
4879
+ backgroundColor: isHovered ? colors2.cardHover : components.card.backgroundColor,
4880
+ borderRadius: components.card.borderRadius,
4881
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
4882
+ };
4883
+ const iconBlock = isConnected ? connectedExchange.iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4884
+ "img",
4885
+ {
4886
+ src: connectedExchange.iconUrl,
4887
+ alt: connectedExchange.name,
4888
+ width: 36,
4889
+ height: 36,
4890
+ className: "uf-rounded-lg"
4891
+ }
4892
+ ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4893
+ "div",
4894
+ {
4895
+ className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
4896
+ style: { backgroundColor: colors2.card },
4897
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4898
+ "span",
4899
+ {
4900
+ className: "uf-text-xs uf-font-medium",
4901
+ style: { color: components.card.iconColor },
4902
+ children: connectedExchange.name.slice(0, 2).toUpperCase()
4903
+ }
4904
+ )
4905
+ }
4906
+ ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4907
+ import_lucide_react14.Link2,
4908
+ {
4909
+ className: "uf-w-5 uf-h-5",
4910
+ style: { color: components.card.iconColor }
4911
+ }
4912
+ ) });
4913
+ const titleSubtitleBlock = /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "uf-text-left", children: [
4914
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4915
+ "div",
4916
+ {
4917
+ className: "uf-text-sm uf-font-light uf-mb-0.5",
4918
+ style: {
4919
+ color: components.card.titleColor,
4920
+ fontFamily: fonts.regular
4921
+ },
4922
+ children: isConnected ? connectedExchange.name : title
4923
+ }
4924
+ ),
4925
+ isConnected && connectedExchange.isLoading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-h-3 uf-w-24 uf-bg-muted uf-rounded uf-animate-pulse" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4926
+ "div",
4927
+ {
4928
+ className: "uf-text-xs uf-font-light",
4929
+ style: {
4930
+ color: components.card.subtitleColor,
4931
+ fontFamily: fonts.regular
4932
+ },
4933
+ children: isConnected ? connectedExchange.balanceUsd ? `$${connectedExchange.balanceUsd} \u2022 2 min` : "Deposit from exchange" : subtitle
4934
+ }
4935
+ )
4936
+ ] });
4937
+ if (isConnected && onDisconnect) {
4938
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4939
+ "div",
4940
+ {
4941
+ onMouseEnter: () => !isTouchDevice && setIsHovered(true),
4942
+ onMouseLeave: () => setIsHovered(false),
4943
+ onTouchStart: () => setIsHovered(false),
4944
+ className: "uf-w-full uf-transition-colors uf-flex uf-items-stretch uf-group",
4945
+ style: rowSurfaceStyle,
4946
+ children: [
4947
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4948
+ "button",
4949
+ {
4950
+ type: "button",
4951
+ onClick,
4952
+ className: "uf-min-w-0 uf-flex-1 uf-flex uf-items-center uf-gap-3 uf-p-3 uf-pr-1 uf-text-left uf-border-0 uf-bg-transparent hover:uf-bg-transparent",
4953
+ children: [
4954
+ iconBlock,
4955
+ titleSubtitleBlock
4956
+ ]
4957
+ }
4958
+ ),
4959
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1 uf-shrink-0 uf-pr-2 uf-pl-0", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4960
+ "button",
4961
+ {
4962
+ type: "button",
4963
+ onClick: handleDisconnectClick,
4964
+ className: "uf-h-auto uf-min-h-8 uf-py-1.5 uf-px-2 uf-text-xs uf-font-light uf-shrink-0 uf-border-0 uf-bg-transparent uf-cursor-pointer hover:uf-opacity-80 uf-transition-opacity",
4965
+ style: {
4966
+ color: colors2.error,
4967
+ fontFamily: fonts.regular
4968
+ },
4969
+ children: i18n.connectExchange.disconnect
4970
+ }
4971
+ ) })
4972
+ ]
4973
+ }
4974
+ );
4975
+ }
4871
4976
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4872
4977
  "button",
4873
4978
  {
@@ -4876,67 +4981,11 @@ function ConnectExchangeButton({
4876
4981
  onMouseLeave: () => setIsHovered(false),
4877
4982
  onTouchStart: () => setIsHovered(false),
4878
4983
  className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between uf-group",
4879
- style: {
4880
- backgroundColor: isHovered ? colors2.cardHover : components.card.backgroundColor,
4881
- borderRadius: components.card.borderRadius,
4882
- border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
4883
- },
4984
+ style: rowSurfaceStyle,
4884
4985
  children: [
4885
4986
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
4886
- isConnected ? connectedExchange.iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4887
- "img",
4888
- {
4889
- src: connectedExchange.iconUrl,
4890
- alt: connectedExchange.name,
4891
- width: 36,
4892
- height: 36,
4893
- className: "uf-rounded-lg"
4894
- }
4895
- ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4896
- "div",
4897
- {
4898
- className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
4899
- style: { backgroundColor: colors2.card },
4900
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4901
- "span",
4902
- {
4903
- className: "uf-text-xs uf-font-medium",
4904
- style: { color: components.card.iconColor },
4905
- children: connectedExchange.name.slice(0, 2).toUpperCase()
4906
- }
4907
- )
4908
- }
4909
- ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4910
- import_lucide_react14.Link2,
4911
- {
4912
- className: "uf-w-5 uf-h-5",
4913
- style: { color: components.card.iconColor }
4914
- }
4915
- ) }),
4916
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "uf-text-left", children: [
4917
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4918
- "div",
4919
- {
4920
- className: "uf-text-sm uf-font-light uf-mb-0.5",
4921
- style: {
4922
- color: components.card.titleColor,
4923
- fontFamily: fonts.regular
4924
- },
4925
- children: isConnected ? connectedExchange.name : title
4926
- }
4927
- ),
4928
- isConnected && connectedExchange.isLoading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "uf-h-3 uf-w-24 uf-bg-muted uf-rounded uf-animate-pulse" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4929
- "div",
4930
- {
4931
- className: "uf-text-xs uf-font-light",
4932
- style: {
4933
- color: components.card.subtitleColor,
4934
- fontFamily: fonts.regular
4935
- },
4936
- children: isConnected ? connectedExchange.balanceUsd ? `$${connectedExchange.balanceUsd} \u2022 2 min` : "Deposit from exchange" : subtitle
4937
- }
4938
- )
4939
- ] })
4987
+ iconBlock,
4988
+ titleSubtitleBlock
4940
4989
  ] }),
4941
4990
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5", children: [
4942
4991
  !isConnected && exchanges && exchanges.length > 0 ? exchanges.slice(0, 4).map((ex, i) => {
@@ -7808,7 +7857,7 @@ function BrowserWalletButton({
7808
7857
  // src/components/deposits/CoinbaseConnect.tsx
7809
7858
  var import_react12 = require("react");
7810
7859
  var import_lucide_react18 = require("lucide-react");
7811
- var import_core16 = require("@unifold/core");
7860
+ var import_core18 = require("@unifold/core");
7812
7861
 
7813
7862
  // src/hooks/use-project-config.ts
7814
7863
  var import_react_query4 = require("@tanstack/react-query");
@@ -7828,6 +7877,73 @@ function useProjectConfig({
7828
7877
  return { projectConfig, isLoading };
7829
7878
  }
7830
7879
 
7880
+ // src/hooks/use-supported-deposit-tokens.ts
7881
+ var import_react_query5 = require("@tanstack/react-query");
7882
+ var import_core16 = require("@unifold/core");
7883
+ function useSupportedDepositTokens(publishableKey, options) {
7884
+ const hasDestination = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type;
7885
+ const filteredOptions = {
7886
+ ...hasDestination ? {
7887
+ destination_token_address: options.destination_token_address,
7888
+ destination_chain_id: options.destination_chain_id,
7889
+ destination_chain_type: options.destination_chain_type
7890
+ } : {},
7891
+ ...options?.product_type ? { product_type: options.product_type } : {}
7892
+ };
7893
+ const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
7894
+ return (0, import_react_query5.useQuery)({
7895
+ queryKey: [
7896
+ "unifold",
7897
+ "supportedDepositTokens",
7898
+ publishableKey,
7899
+ filteredOptions?.destination_token_address ?? null,
7900
+ filteredOptions?.destination_chain_id ?? null,
7901
+ filteredOptions?.destination_chain_type ?? null,
7902
+ filteredOptions?.product_type ?? null
7903
+ ],
7904
+ queryFn: () => (0, import_core16.getSupportedDepositTokens)(
7905
+ publishableKey,
7906
+ hasFilteredOptions ? filteredOptions : void 0
7907
+ ),
7908
+ staleTime: 1e3 * 60 * 5,
7909
+ // 5 minutes — token list rarely changes
7910
+ gcTime: 1e3 * 60 * 30,
7911
+ // 30 minutes in cache
7912
+ refetchOnMount: false,
7913
+ refetchOnWindowFocus: false
7914
+ });
7915
+ }
7916
+
7917
+ // src/hooks/use-integration-transfer-default-token.ts
7918
+ var import_react_query6 = require("@tanstack/react-query");
7919
+ var import_core17 = require("@unifold/core");
7920
+ function useIntegrationTransferDefaultToken({
7921
+ params,
7922
+ publishableKey,
7923
+ enabled = true
7924
+ }) {
7925
+ return (0, import_react_query6.useQuery)({
7926
+ queryKey: [
7927
+ "unifold",
7928
+ "integrationTransferDefaultToken",
7929
+ publishableKey,
7930
+ params?.integration_provider ?? null,
7931
+ params?.source_currency ?? null,
7932
+ params?.destination_token_address ?? null,
7933
+ params?.destination_chain_id ?? null,
7934
+ params?.destination_chain_type ?? null,
7935
+ params?.country_code ?? null,
7936
+ params?.subdivision_code ?? null
7937
+ ],
7938
+ queryFn: () => (0, import_core17.getIntegrationTransferDefaultToken)(params, publishableKey),
7939
+ enabled: enabled && !!params,
7940
+ staleTime: 1e3 * 60 * 5,
7941
+ gcTime: 1e3 * 60 * 30,
7942
+ refetchOnMount: false,
7943
+ refetchOnWindowFocus: false
7944
+ });
7945
+ }
7946
+
7831
7947
  // src/lib/integrations.ts
7832
7948
  var INTEGRATIONS_STORAGE_KEY = "unifold:integrations:connected";
7833
7949
  function getStoredIntegrations() {
@@ -7876,9 +7992,26 @@ function CoinbaseConnect({
7876
7992
  const { colors: colors2, fonts, components } = useTheme();
7877
7993
  const { projectConfig } = useProjectConfig({ publishableKey });
7878
7994
  const { userIpInfo } = useUserIp();
7995
+ const { data: supportedTokensData, isLoading: supportedTokensLoading } = useSupportedDepositTokens(publishableKey, {
7996
+ destination_token_address: destinationTokenAddress,
7997
+ destination_chain_id: destinationChainId,
7998
+ destination_chain_type: destinationChainType
7999
+ });
8000
+ const supportedSymbols = (0, import_react12.useMemo)(() => {
8001
+ const set = /* @__PURE__ */ new Set();
8002
+ supportedTokensData?.data.forEach((token) => set.add(token.symbol.toLowerCase()));
8003
+ return set;
8004
+ }, [supportedTokensData]);
8005
+ const stablecoinSymbols = (0, import_react12.useMemo)(() => {
8006
+ const set = /* @__PURE__ */ new Set();
8007
+ supportedTokensData?.data.forEach((token) => {
8008
+ if (token.is_stablecoin) set.add(token.symbol.toLowerCase());
8009
+ });
8010
+ return set;
8011
+ }, [supportedTokensData]);
7879
8012
  const appName = projectConfig?.project_name ?? "Unifold";
7880
8013
  const t12 = i18n.connectExchange;
7881
- const initialView = skipToHoldings && getStoredIntegrationToken(import_core16.IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
8014
+ const initialView = skipToHoldings && getStoredIntegrationToken(import_core18.IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
7882
8015
  const [view, setView] = (0, import_react12.useState)(initialView);
7883
8016
  const [prevView, setPrevView] = (0, import_react12.useState)(initialView);
7884
8017
  const [isTransitioning, setIsTransitioning] = (0, import_react12.useState)(false);
@@ -7898,7 +8031,43 @@ function CoinbaseConnect({
7898
8031
  const [confirmResult, setConfirmResult] = (0, import_react12.useState)(null);
7899
8032
  const [showTransferDetails, setShowTransferDetails] = (0, import_react12.useState)(false);
7900
8033
  const [transferDepositWalletId, setTransferDepositWalletId] = (0, import_react12.useState)(void 0);
7901
- const [minDepositUsd, setMinDepositUsd] = (0, import_react12.useState)(0);
8034
+ const exchangeSupportedCurrencies = (0, import_react12.useMemo)(() => {
8035
+ const set = /* @__PURE__ */ new Set();
8036
+ selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
8037
+ return set;
8038
+ }, [selectedExchange]);
8039
+ const defaultTokenParams = (0, import_react12.useMemo)(
8040
+ () => selectedAsset ? {
8041
+ integration_provider: import_core18.IntegrationProvider.COINBASE,
8042
+ source_currency: selectedAsset.currency.toLowerCase(),
8043
+ destination_token_address: destinationTokenAddress,
8044
+ destination_chain_id: destinationChainId,
8045
+ destination_chain_type: destinationChainType,
8046
+ country_code: userIpInfo?.alpha2,
8047
+ subdivision_code: userIpInfo?.subdivisionCode ?? void 0
8048
+ } : null,
8049
+ [selectedAsset, destinationTokenAddress, destinationChainId, destinationChainType, userIpInfo?.alpha2, userIpInfo?.subdivisionCode]
8050
+ );
8051
+ const { data: defaultTokenData, isLoading: defaultTokenLoading } = useIntegrationTransferDefaultToken({
8052
+ params: defaultTokenParams,
8053
+ publishableKey
8054
+ });
8055
+ const sortedHoldings = (0, import_react12.useMemo)(() => {
8056
+ const supported = [];
8057
+ const unsupported = [];
8058
+ holdings.forEach((account) => {
8059
+ const currencyLower = account.currency.toLowerCase();
8060
+ const isSupported = (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8061
+ if (isSupported) supported.push(account);
8062
+ else unsupported.push(account);
8063
+ });
8064
+ return [...supported, ...unsupported];
8065
+ }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
8066
+ const selectedHoldingIsSupported = (0, import_react12.useMemo)(() => {
8067
+ if (!selectedHolding) return false;
8068
+ const currencyLower = selectedHolding.currency.toLowerCase();
8069
+ return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8070
+ }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
7902
8071
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
7903
8072
  const {
7904
8073
  executions: depositExecutions,
@@ -7935,16 +8104,16 @@ function CoinbaseConnect({
7935
8104
  const tryRefreshToken = (0, import_react12.useCallback)(
7936
8105
  async (currentToken) => {
7937
8106
  try {
7938
- const result = await (0, import_core16.refreshIntegrationToken)(currentToken, publishableKey);
8107
+ const result = await (0, import_core18.refreshIntegrationToken)(currentToken, publishableKey);
7939
8108
  setStoredIntegrationToken({
7940
- integration_provider: import_core16.IntegrationProvider.COINBASE,
8109
+ integration_provider: import_core18.IntegrationProvider.COINBASE,
7941
8110
  access_token: result.access_token,
7942
8111
  expires_at: result.expires_at
7943
8112
  });
7944
8113
  setAccessToken(result.access_token);
7945
8114
  return result.access_token;
7946
8115
  } catch {
7947
- clearStoredIntegrationToken(import_core16.IntegrationProvider.COINBASE);
8116
+ clearStoredIntegrationToken(import_core18.IntegrationProvider.COINBASE);
7948
8117
  setAccessToken(null);
7949
8118
  return null;
7950
8119
  }
@@ -7952,17 +8121,17 @@ function CoinbaseConnect({
7952
8121
  [publishableKey]
7953
8122
  );
7954
8123
  (0, import_react12.useEffect)(() => {
7955
- (0, import_core16.getIntegrationExchanges)(publishableKey).then((res) => {
8124
+ (0, import_core18.getIntegrationExchanges)(publishableKey).then((res) => {
7956
8125
  setExchanges(res.data);
7957
8126
  if (!selectedExchange) {
7958
8127
  const coinbase = res.data.find(
7959
- (e) => e.service_provider === import_core16.IntegrationProvider.COINBASE
8128
+ (e) => e.service_provider === import_core18.IntegrationProvider.COINBASE
7960
8129
  );
7961
8130
  if (coinbase) setSelectedExchange(coinbase);
7962
8131
  }
7963
8132
  }).catch(() => {
7964
8133
  }).finally(() => setExchangesLoading(false));
7965
- const stored = getStoredIntegrationToken(import_core16.IntegrationProvider.COINBASE);
8134
+ const stored = getStoredIntegrationToken(import_core18.IntegrationProvider.COINBASE);
7966
8135
  if (stored) {
7967
8136
  setAccessToken(stored.access_token);
7968
8137
  if (skipToHoldings) {
@@ -7974,7 +8143,7 @@ function CoinbaseConnect({
7974
8143
  async (token) => {
7975
8144
  setIsLoading(true);
7976
8145
  try {
7977
- const result = await (0, import_core16.getIntegrationHoldings)(import_core16.IntegrationProvider.COINBASE, token, publishableKey);
8146
+ const result = await (0, import_core18.getIntegrationHoldings)(import_core18.IntegrationProvider.COINBASE, token, publishableKey);
7978
8147
  const sorted = result.data.filter((a) => parseFloat(a.amount) > 0).sort((a, b) => {
7979
8148
  const aUsd = a.amount_usd ? parseFloat(a.amount_usd) : 0;
7980
8149
  const bUsd = b.amount_usd ? parseFloat(b.amount_usd) : 0;
@@ -7987,7 +8156,7 @@ function CoinbaseConnect({
7987
8156
  const refreshed = await tryRefreshToken(token);
7988
8157
  if (refreshed) {
7989
8158
  try {
7990
- const retryResult = await (0, import_core16.getIntegrationHoldings)(import_core16.IntegrationProvider.COINBASE, refreshed, publishableKey);
8159
+ const retryResult = await (0, import_core18.getIntegrationHoldings)(import_core18.IntegrationProvider.COINBASE, refreshed, publishableKey);
7991
8160
  const sorted = retryResult.data.filter((a) => parseFloat(a.amount) > 0).sort((a, b) => {
7992
8161
  const aUsd = a.amount_usd ? parseFloat(a.amount_usd) : 0;
7993
8162
  const bUsd = b.amount_usd ? parseFloat(b.amount_usd) : 0;
@@ -8000,7 +8169,7 @@ function CoinbaseConnect({
8000
8169
  } catch {
8001
8170
  }
8002
8171
  }
8003
- clearStoredIntegrationToken(import_core16.IntegrationProvider.COINBASE);
8172
+ clearStoredIntegrationToken(import_core18.IntegrationProvider.COINBASE);
8004
8173
  setAccessToken(null);
8005
8174
  transitionTo("select_exchange");
8006
8175
  } finally {
@@ -8014,58 +8183,22 @@ function CoinbaseConnect({
8014
8183
  if (pollRef.current) clearInterval(pollRef.current);
8015
8184
  };
8016
8185
  }, []);
8017
- (0, import_react12.useEffect)(() => {
8018
- if (view !== "enter_amount" || !selectedAsset) return;
8019
- let cancelled = false;
8020
- const fetchMinDeposit = async () => {
8021
- try {
8022
- const [defaultToken, supportedTokens] = await Promise.all([
8023
- (0, import_core16.getIntegrationTransferDefaultToken)(
8024
- {
8025
- integration_provider: import_core16.IntegrationProvider.COINBASE,
8026
- source_currency: selectedAsset.currency.toLowerCase(),
8027
- destination_token_address: destinationTokenAddress,
8028
- destination_chain_id: destinationChainId,
8029
- destination_chain_type: destinationChainType,
8030
- country_code: userIpInfo?.alpha2,
8031
- subdivision_code: userIpInfo?.subdivisionCode ?? void 0
8032
- },
8033
- publishableKey
8034
- ),
8035
- (0, import_core16.getSupportedDepositTokens)(publishableKey, {
8036
- destination_token_address: destinationTokenAddress,
8037
- destination_chain_id: destinationChainId,
8038
- destination_chain_type: destinationChainType
8039
- })
8040
- ]);
8041
- if (cancelled) return;
8042
- const supportedToken = supportedTokens.data.find(
8043
- (t13) => t13.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
8044
- );
8045
- if (supportedToken && supportedToken.chains.length > 0) {
8046
- const matchingChain = supportedToken.chains.find(
8047
- (c) => c.chain_name.toLowerCase() === defaultToken.source_network.toLowerCase()
8048
- );
8049
- setMinDepositUsd(
8050
- matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd))
8051
- );
8052
- } else {
8053
- setMinDepositUsd(0);
8054
- }
8055
- } catch {
8056
- if (!cancelled) setMinDepositUsd(0);
8057
- }
8058
- };
8059
- fetchMinDeposit();
8060
- return () => {
8061
- cancelled = true;
8062
- };
8063
- }, [view, selectedAsset, publishableKey, destinationTokenAddress, destinationChainId, destinationChainType, userIpInfo?.alpha2, userIpInfo?.subdivisionCode]);
8186
+ const minDepositUsd = (0, import_react12.useMemo)(() => {
8187
+ if (!selectedAsset || !defaultTokenData) return 0;
8188
+ const supportedToken = supportedTokensData?.data.find(
8189
+ (t13) => t13.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
8190
+ );
8191
+ if (!supportedToken || supportedToken.chains.length === 0) return 0;
8192
+ const matchingChain = supportedToken.chains.find(
8193
+ (c) => c.chain_name.toLowerCase() === defaultTokenData.source_network.toLowerCase()
8194
+ );
8195
+ return matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd));
8196
+ }, [selectedAsset, supportedTokensData, defaultTokenData]);
8064
8197
  const handleSelectExchange = (exchange) => {
8065
8198
  if (!exchange.enabled) return;
8066
8199
  setSelectedExchange(exchange);
8067
- if (exchange.service_provider === import_core16.IntegrationProvider.COINBASE) {
8068
- const stored = getStoredIntegrationToken(import_core16.IntegrationProvider.COINBASE);
8200
+ if (exchange.service_provider === import_core18.IntegrationProvider.COINBASE) {
8201
+ const stored = getStoredIntegrationToken(import_core18.IntegrationProvider.COINBASE);
8069
8202
  if (stored) {
8070
8203
  setAccessToken(stored.access_token);
8071
8204
  transitionTo("connecting");
@@ -8078,16 +8211,16 @@ function CoinbaseConnect({
8078
8211
  const handleStartOAuth = async () => {
8079
8212
  transitionTo("connecting");
8080
8213
  try {
8081
- const { redirect_url, state } = await (0, import_core16.startIntegrationOAuth)(publishableKey);
8214
+ const { redirect_url, state } = await (0, import_core18.startIntegrationOAuth)(publishableKey);
8082
8215
  popupRef.current = window.open(redirect_url, "_blank", "width=500,height=700");
8083
8216
  pollRef.current = setInterval(async () => {
8084
8217
  try {
8085
- const result = await (0, import_core16.authenticateIntegrationOAuth)({ state }, publishableKey);
8218
+ const result = await (0, import_core18.authenticateIntegrationOAuth)({ state }, publishableKey);
8086
8219
  if (result.status === "completed") {
8087
8220
  if (pollRef.current) clearInterval(pollRef.current);
8088
8221
  pollRef.current = null;
8089
8222
  setStoredIntegrationToken({
8090
- integration_provider: import_core16.IntegrationProvider.COINBASE,
8223
+ integration_provider: import_core18.IntegrationProvider.COINBASE,
8091
8224
  access_token: result.access_token,
8092
8225
  expires_at: result.expires_at
8093
8226
  });
@@ -8105,7 +8238,6 @@ function CoinbaseConnect({
8105
8238
  const handleSelectAsset = (asset) => {
8106
8239
  setSelectedAsset(asset);
8107
8240
  setSendAmount("");
8108
- setMinDepositUsd(0);
8109
8241
  transitionTo("enter_amount");
8110
8242
  };
8111
8243
  const handleCreateTransfer = async () => {
@@ -8117,18 +8249,10 @@ function CoinbaseConnect({
8117
8249
  const cryptoAmount = (usdAmount / rate).toFixed(8);
8118
8250
  setIsLoading(true);
8119
8251
  try {
8120
- const { source_network, source_chain_type } = await (0, import_core16.getIntegrationTransferDefaultToken)(
8121
- {
8122
- integration_provider: import_core16.IntegrationProvider.COINBASE,
8123
- source_currency: selectedAsset.currency.toLowerCase(),
8124
- destination_token_address: destinationTokenAddress,
8125
- destination_chain_id: destinationChainId,
8126
- destination_chain_type: destinationChainType,
8127
- country_code: userIpInfo?.alpha2,
8128
- subdivision_code: userIpInfo?.subdivisionCode ?? void 0
8129
- },
8130
- publishableKey
8131
- );
8252
+ if (!defaultTokenData) {
8253
+ throw new Error("Transfer details not ready. Please try again.");
8254
+ }
8255
+ const { source_network, source_chain_type } = defaultTokenData;
8132
8256
  const matchingWallet = wallets.find((w) => w.chain_type === source_chain_type);
8133
8257
  const depositAddress = matchingWallet?.address ?? recipientAddress ?? "";
8134
8258
  if (!depositAddress) {
@@ -8137,9 +8261,9 @@ function CoinbaseConnect({
8137
8261
  if (matchingWallet?.id) {
8138
8262
  setTransferDepositWalletId(matchingWallet.id);
8139
8263
  }
8140
- const createTransfer = async (token) => (0, import_core16.createIntegrationTransfer)(
8264
+ const createTransfer = async (token) => (0, import_core18.createIntegrationTransfer)(
8141
8265
  {
8142
- integration_provider: import_core16.IntegrationProvider.COINBASE,
8266
+ integration_provider: import_core18.IntegrationProvider.COINBASE,
8143
8267
  access_token: token,
8144
8268
  currency: selectedAsset.currency.toLowerCase(),
8145
8269
  amount: cryptoAmount,
@@ -8175,7 +8299,7 @@ function CoinbaseConnect({
8175
8299
  setIsLoading(true);
8176
8300
  try {
8177
8301
  let token = accessToken;
8178
- let result = await (0, import_core16.confirmIntegrationTransfer)(
8302
+ let result = await (0, import_core18.confirmIntegrationTransfer)(
8179
8303
  transferIntent.id,
8180
8304
  token,
8181
8305
  void 0,
@@ -8184,7 +8308,7 @@ function CoinbaseConnect({
8184
8308
  const refreshed = await tryRefreshToken(token);
8185
8309
  if (refreshed) {
8186
8310
  token = refreshed;
8187
- return (0, import_core16.confirmIntegrationTransfer)(transferIntent.id, refreshed, void 0, publishableKey);
8311
+ return (0, import_core18.confirmIntegrationTransfer)(transferIntent.id, refreshed, void 0, publishableKey);
8188
8312
  }
8189
8313
  throw err;
8190
8314
  });
@@ -8214,7 +8338,7 @@ function CoinbaseConnect({
8214
8338
  setIsLoading(true);
8215
8339
  setMfaError(false);
8216
8340
  try {
8217
- const result = await (0, import_core16.confirmIntegrationTransfer)(
8341
+ const result = await (0, import_core18.confirmIntegrationTransfer)(
8218
8342
  transferIntent.id,
8219
8343
  accessToken,
8220
8344
  mfaCode,
@@ -8280,13 +8404,12 @@ function CoinbaseConnect({
8280
8404
  break;
8281
8405
  }
8282
8406
  };
8283
- const STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USDT", "DAI", "BUSD", "TUSD", "USDP", "GUSD", "FRAX", "LUSD", "PYUSD", "EURC", "USDS"]);
8284
8407
  const formatCryptoAmount = (amount, currency) => {
8285
8408
  const num = parseFloat(amount);
8286
8409
  if (isNaN(num)) return `${amount} ${currency.toUpperCase()}`;
8287
- const isStable = STABLECOIN_SYMBOLS.has(currency.toUpperCase());
8288
- const maxDecimals = isStable ? 2 : 8;
8289
- return `${num.toLocaleString(void 0, { minimumFractionDigits: isStable ? 2 : 0, maximumFractionDigits: maxDecimals })} ${currency.toUpperCase()}`;
8410
+ const isStable = stablecoinSymbols.has(currency.toLowerCase());
8411
+ const maxDecimals = isStable ? 2 : 6;
8412
+ return `${num.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: maxDecimals })} ${currency.toUpperCase()}`;
8290
8413
  };
8291
8414
  const viewTransitionStyle = {
8292
8415
  opacity: isTransitioning ? 0 : 1,
@@ -8372,7 +8495,7 @@ function CoinbaseConnect({
8372
8495
  },
8373
8496
  children: t12.comingSoon
8374
8497
  }
8375
- ) : accessToken && exchange.service_provider === import_core16.IntegrationProvider.COINBASE ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8498
+ ) : accessToken && exchange.service_provider === import_core18.IntegrationProvider.COINBASE ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8376
8499
  "span",
8377
8500
  {
8378
8501
  className: "uf-text-xs uf-px-2.5 uf-py-1 uf-rounded-full",
@@ -8888,7 +9011,7 @@ function CoinbaseConnect({
8888
9011
  className: "uf-w-6 uf-h-6 uf-animate-spin",
8889
9012
  style: { color: colors2.foregroundMuted }
8890
9013
  }
8891
- ) }) : holdings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "uf-text-center uf-py-8", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
9014
+ ) }) : sortedHoldings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "uf-text-center uf-py-8", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8892
9015
  "div",
8893
9016
  {
8894
9017
  className: "uf-text-sm",
@@ -8898,17 +9021,19 @@ function CoinbaseConnect({
8898
9021
  },
8899
9022
  children: "No holdings found"
8900
9023
  }
8901
- ) }) : holdings.map((account) => {
9024
+ ) }) : sortedHoldings.map((account) => {
8902
9025
  const iconUrl = account.icon_urls?.find((u) => u.format === "svg")?.url || account.icon_urls?.find((u) => u.format === "png")?.url || account.icon_url;
8903
- const isSelected = selectedHolding?.id === account.id;
9026
+ const currencyLower = account.currency.toLowerCase();
9027
+ const isSupported = (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
9028
+ const isSelected = isSupported && selectedHolding?.id === account.id;
8904
9029
  const usdValue = account.amount_usd ? parseFloat(account.amount_usd) : null;
8905
- const formattedUsd = usdValue != null && usdValue > 0 ? `$${usdValue.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : null;
9030
+ const formattedUsd = usdValue != null && usdValue >= 0.01 ? `$${usdValue.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : usdValue != null && usdValue < 0.01 && usdValue > 0 ? "< $0.01" : "$0.00";
8906
9031
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
8907
9032
  "button",
8908
9033
  {
8909
9034
  onClick: () => setSelectedHolding(account),
8910
- disabled: isLoading,
8911
- className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between",
9035
+ disabled: isLoading || !isSupported,
9036
+ className: `uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between ${!isSupported ? "uf-cursor-not-allowed uf-opacity-50" : ""}`,
8912
9037
  style: {
8913
9038
  backgroundColor: isSelected ? colors2.primary + "20" : components.card.backgroundColor,
8914
9039
  borderRadius: components.list.rowBorderRadius,
@@ -8998,9 +9123,9 @@ function CoinbaseConnect({
8998
9123
  "button",
8999
9124
  {
9000
9125
  onClick: () => {
9001
- if (selectedHolding) handleSelectAsset(selectedHolding);
9126
+ if (selectedHolding && selectedHoldingIsSupported) handleSelectAsset(selectedHolding);
9002
9127
  },
9003
- disabled: !selectedHolding || isLoading,
9128
+ disabled: !selectedHolding || isLoading || supportedTokensLoading || exchangesLoading || !selectedHoldingIsSupported,
9004
9129
  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",
9005
9130
  style: {
9006
9131
  backgroundColor: colors2.primary,
@@ -9024,22 +9149,16 @@ function CoinbaseConnect({
9024
9149
  const isValidAmount = inputUsdNum > 0 && (maxUsdAmount == null || inputUsdNum <= maxUsdAmount) && inputUsdNum >= minDepositUsd;
9025
9150
  const displayValue = sendAmount || "0";
9026
9151
  const formattedBalance = formatCryptoAmount(selectedAsset.amount, selectedAsset.currency);
9027
- const balanceDisplay = maxUsdAmount != null && maxUsdAmount > 0 ? `$${maxUsdAmount.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (${formattedBalance})` : formattedBalance;
9152
+ const balanceSubtitle = maxUsdAmount != null && maxUsdAmount > 0 ? `Balance: $${maxUsdAmount.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (${formattedBalance})` : `Balance: ${formattedBalance}`;
9028
9153
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
9029
9154
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
9030
9155
  DepositHeader,
9031
9156
  {
9032
9157
  title: "Enter Amount",
9158
+ subtitle: balanceSubtitle,
9033
9159
  showBack: true,
9034
9160
  onBack: handleBack,
9035
- onClose,
9036
- showBalance: true,
9037
- balanceAddress: recipientAddress,
9038
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
9039
- balanceChainId: destinationChainId,
9040
- balanceTokenAddress: destinationTokenAddress,
9041
- projectName: projectConfig?.project_name,
9042
- publishableKey
9161
+ onClose
9043
9162
  }
9044
9163
  ),
9045
9164
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-4", style: viewTransitionStyle, children: [
@@ -9161,7 +9280,7 @@ function CoinbaseConnect({
9161
9280
  "button",
9162
9281
  {
9163
9282
  onClick: handleCreateTransfer,
9164
- disabled: !isValidAmount || isLoading,
9283
+ disabled: !isValidAmount || isLoading || defaultTokenLoading || !defaultTokenData,
9165
9284
  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",
9166
9285
  style: {
9167
9286
  backgroundColor: colors2.primary,
@@ -9170,7 +9289,7 @@ function CoinbaseConnect({
9170
9289
  borderRadius: components.button.borderRadius,
9171
9290
  border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
9172
9291
  },
9173
- children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react18.Loader2, { className: "uf-w-4 uf-h-4 uf-animate-spin" }) : "Review"
9292
+ children: isLoading || defaultTokenLoading ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react18.Loader2, { className: "uf-w-4 uf-h-4 uf-animate-spin" }) : "Review"
9174
9293
  }
9175
9294
  )
9176
9295
  ] })
@@ -9639,15 +9758,15 @@ function CoinbaseConnect({
9639
9758
  CoinbaseConnect.displayName = "CoinbaseConnect";
9640
9759
 
9641
9760
  // src/hooks/use-exchanges.ts
9642
- var import_react_query5 = require("@tanstack/react-query");
9643
- var import_core17 = require("@unifold/core");
9761
+ var import_react_query7 = require("@tanstack/react-query");
9762
+ var import_core19 = require("@unifold/core");
9644
9763
  function useExchanges({
9645
9764
  publishableKey,
9646
9765
  enabled = true
9647
9766
  }) {
9648
- const { data: exchanges = [], isLoading } = (0, import_react_query5.useQuery)({
9767
+ const { data: exchanges = [], isLoading } = (0, import_react_query7.useQuery)({
9649
9768
  queryKey: ["unifold", "exchanges", publishableKey],
9650
- queryFn: () => (0, import_core17.getExchanges)(void 0, publishableKey).then((res) => res.data),
9769
+ queryFn: () => (0, import_core19.getExchanges)(void 0, publishableKey).then((res) => res.data),
9651
9770
  enabled,
9652
9771
  staleTime: 1e3 * 60 * 30,
9653
9772
  refetchOnMount: false,
@@ -9657,8 +9776,8 @@ function useExchanges({
9657
9776
  }
9658
9777
 
9659
9778
  // src/hooks/use-default-onramp-token.ts
9660
- var import_react_query6 = require("@tanstack/react-query");
9661
- var import_core18 = require("@unifold/core");
9779
+ var import_react_query8 = require("@tanstack/react-query");
9780
+ var import_core20 = require("@unifold/core");
9662
9781
  function useDefaultOnrampToken({
9663
9782
  publishableKey,
9664
9783
  tokenAddress,
@@ -9668,7 +9787,7 @@ function useDefaultOnrampToken({
9668
9787
  subdivisionCode,
9669
9788
  enabled = true
9670
9789
  }) {
9671
- const { data: defaultToken, isLoading } = (0, import_react_query6.useQuery)({
9790
+ const { data: defaultToken, isLoading } = (0, import_react_query8.useQuery)({
9672
9791
  queryKey: [
9673
9792
  "unifold",
9674
9793
  "defaultOnrampToken",
@@ -9679,7 +9798,7 @@ function useDefaultOnrampToken({
9679
9798
  countryCode,
9680
9799
  subdivisionCode
9681
9800
  ],
9682
- queryFn: () => (0, import_core18.getDefaultOnrampToken)(
9801
+ queryFn: () => (0, import_core20.getDefaultOnrampToken)(
9683
9802
  {
9684
9803
  token_address: tokenAddress,
9685
9804
  chain_id: chainId,
@@ -9698,19 +9817,19 @@ function useDefaultOnrampToken({
9698
9817
  }
9699
9818
 
9700
9819
  // src/components/deposits/DepositModal.tsx
9701
- var import_core28 = require("@unifold/core");
9820
+ var import_core29 = require("@unifold/core");
9702
9821
 
9703
9822
  // src/hooks/use-allowed-country.ts
9704
- var import_react_query7 = require("@tanstack/react-query");
9705
- var import_core19 = require("@unifold/core");
9823
+ var import_react_query9 = require("@tanstack/react-query");
9824
+ var import_core21 = require("@unifold/core");
9706
9825
  function useAllowedCountry(publishableKey) {
9707
9826
  const {
9708
9827
  data: ipData,
9709
9828
  isLoading: isIpLoading,
9710
9829
  error: ipError
9711
- } = (0, import_react_query7.useQuery)({
9830
+ } = (0, import_react_query9.useQuery)({
9712
9831
  queryKey: ["unifold", "ipAddress"],
9713
- queryFn: () => (0, import_core19.getIpAddress)(),
9832
+ queryFn: () => (0, import_core21.getIpAddress)(),
9714
9833
  refetchOnMount: false,
9715
9834
  refetchOnReconnect: true,
9716
9835
  refetchOnWindowFocus: false,
@@ -9723,9 +9842,9 @@ function useAllowedCountry(publishableKey) {
9723
9842
  data: configData,
9724
9843
  isLoading: isConfigLoading,
9725
9844
  error: configError
9726
- } = (0, import_react_query7.useQuery)({
9845
+ } = (0, import_react_query9.useQuery)({
9727
9846
  queryKey: ["unifold", "projectConfig", publishableKey],
9728
- queryFn: () => (0, import_core19.getProjectConfig)(publishableKey),
9847
+ queryFn: () => (0, import_core21.getProjectConfig)(publishableKey),
9729
9848
  refetchOnMount: false,
9730
9849
  refetchOnReconnect: true,
9731
9850
  refetchOnWindowFocus: false,
@@ -9766,8 +9885,8 @@ function useAllowedCountry(publishableKey) {
9766
9885
  }
9767
9886
 
9768
9887
  // src/hooks/use-address-validation.ts
9769
- var import_react_query8 = require("@tanstack/react-query");
9770
- var import_core20 = require("@unifold/core");
9888
+ var import_react_query10 = require("@tanstack/react-query");
9889
+ var import_core22 = require("@unifold/core");
9771
9890
  function useAddressValidation({
9772
9891
  recipientAddress,
9773
9892
  destinationChainType,
@@ -9778,7 +9897,7 @@ function useAddressValidation({
9778
9897
  refetchOnMount = false
9779
9898
  }) {
9780
9899
  const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
9781
- const { data, isLoading, error } = (0, import_react_query8.useQuery)({
9900
+ const { data, isLoading, error } = (0, import_react_query10.useQuery)({
9782
9901
  queryKey: [
9783
9902
  "unifold",
9784
9903
  "addressValidation",
@@ -9787,7 +9906,7 @@ function useAddressValidation({
9787
9906
  destinationChainId,
9788
9907
  destinationTokenAddress
9789
9908
  ],
9790
- queryFn: () => (0, import_core20.verifyRecipientAddress)(
9909
+ queryFn: () => (0, import_core22.verifyRecipientAddress)(
9791
9910
  {
9792
9911
  chain_type: destinationChainType,
9793
9912
  chain_id: destinationChainId,
@@ -9823,43 +9942,6 @@ function useAddressValidation({
9823
9942
  };
9824
9943
  }
9825
9944
 
9826
- // src/hooks/use-supported-deposit-tokens.ts
9827
- var import_react_query9 = require("@tanstack/react-query");
9828
- var import_core21 = require("@unifold/core");
9829
- function useSupportedDepositTokens(publishableKey, options) {
9830
- const hasDestination = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type;
9831
- const filteredOptions = {
9832
- ...hasDestination ? {
9833
- destination_token_address: options.destination_token_address,
9834
- destination_chain_id: options.destination_chain_id,
9835
- destination_chain_type: options.destination_chain_type
9836
- } : {},
9837
- ...options?.product_type ? { product_type: options.product_type } : {}
9838
- };
9839
- const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
9840
- return (0, import_react_query9.useQuery)({
9841
- queryKey: [
9842
- "unifold",
9843
- "supportedDepositTokens",
9844
- publishableKey,
9845
- filteredOptions?.destination_token_address ?? null,
9846
- filteredOptions?.destination_chain_id ?? null,
9847
- filteredOptions?.destination_chain_type ?? null,
9848
- filteredOptions?.product_type ?? null
9849
- ],
9850
- queryFn: () => (0, import_core21.getSupportedDepositTokens)(
9851
- publishableKey,
9852
- hasFilteredOptions ? filteredOptions : void 0
9853
- ),
9854
- staleTime: 1e3 * 60 * 5,
9855
- // 5 minutes — token list rarely changes
9856
- gcTime: 1e3 * 60 * 30,
9857
- // 30 minutes in cache
9858
- refetchOnMount: false,
9859
- refetchOnWindowFocus: false
9860
- });
9861
- }
9862
-
9863
9945
  // src/components/deposits/TransferCryptoSingleInput.tsx
9864
9946
  var import_react17 = require("react");
9865
9947
  var import_lucide_react22 = require("lucide-react");
@@ -10012,7 +10094,7 @@ function PoweredByUnifold({
10012
10094
  }
10013
10095
 
10014
10096
  // src/components/deposits/DepositsModal.tsx
10015
- var import_core22 = require("@unifold/core");
10097
+ var import_core23 = require("@unifold/core");
10016
10098
  var import_jsx_runtime40 = require("react/jsx-runtime");
10017
10099
  function DepositsModal({
10018
10100
  open,
@@ -10030,7 +10112,7 @@ function DepositsModal({
10030
10112
  if (!open || !userId) return;
10031
10113
  const fetchExecutions = async () => {
10032
10114
  try {
10033
- const response = await (0, import_core22.queryExecutions)(userId, publishableKey, import_core22.ActionType.Deposit);
10115
+ const response = await (0, import_core23.queryExecutions)(userId, publishableKey, import_core23.ActionType.Deposit);
10034
10116
  const sorted = [...response.data].sort((a, b) => {
10035
10117
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
10036
10118
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -10974,11 +11056,11 @@ var TooltipContent = React27.forwardRef(({ className, sideOffset = 4, ...props }
10974
11056
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
10975
11057
 
10976
11058
  // src/components/deposits/TransferCryptoSingleInput.tsx
10977
- var import_core24 = require("@unifold/core");
11059
+ var import_core25 = require("@unifold/core");
10978
11060
 
10979
11061
  // src/hooks/use-hypercore-activation.ts
10980
- var import_react_query10 = require("@tanstack/react-query");
10981
- var import_core23 = require("@unifold/core");
11062
+ var import_react_query11 = require("@tanstack/react-query");
11063
+ var import_core24 = require("@unifold/core");
10982
11064
 
10983
11065
  // src/lib/constants.ts
10984
11066
  var HYPERCORE_CHAIN_ID = "1337";
@@ -10996,7 +11078,7 @@ function useHypercoreActivation(params) {
10996
11078
  const recipient = recipientAddress?.trim() ?? "";
10997
11079
  const source = sourceAddress?.trim() ?? "";
10998
11080
  const hasAddresses = !!recipient && !!source;
10999
- const { data, isLoading } = (0, import_react_query10.useQuery)({
11081
+ const { data, isLoading } = (0, import_react_query11.useQuery)({
11000
11082
  queryKey: [
11001
11083
  "unifold",
11002
11084
  "hypercoreActivation",
@@ -11004,7 +11086,7 @@ function useHypercoreActivation(params) {
11004
11086
  recipient,
11005
11087
  publishableKey
11006
11088
  ],
11007
- queryFn: () => (0, import_core23.checkHypercoreActivation)(
11089
+ queryFn: () => (0, import_core24.checkHypercoreActivation)(
11008
11090
  {
11009
11091
  source_address: source,
11010
11092
  recipient_address: recipient
@@ -11149,7 +11231,7 @@ function TransferCryptoSingleInput({
11149
11231
  (c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
11150
11232
  ) : void 0;
11151
11233
  const currentChainType = currentChainData?.chain_type || "ethereum";
11152
- const currentWallet = (0, import_core24.getWalletByChainType)(wallets, currentChainType);
11234
+ const currentWallet = (0, import_core25.getWalletByChainType)(wallets, currentChainType);
11153
11235
  const depositAddress = currentWallet?.address || "";
11154
11236
  const {
11155
11237
  executions: depositExecutions,
@@ -11360,7 +11442,7 @@ function TransferCryptoSingleInput({
11360
11442
  className: "uf-text-sm uf-font-semibold",
11361
11443
  style: { color: components.card.titleColor, fontFamily: fonts.semibold },
11362
11444
  children: [
11363
- checkoutQuote.isStablecoin ? (0, import_core24.formatStablecoinAmount)(checkoutQuote.sourceAmount, checkoutQuote.sourceTokenDecimals) : (Number(checkoutQuote.sourceAmount) / 10 ** checkoutQuote.sourceTokenDecimals).toFixed(
11445
+ checkoutQuote.isStablecoin ? (0, import_core25.formatStablecoinAmount)(checkoutQuote.sourceAmount, checkoutQuote.sourceTokenDecimals) : (Number(checkoutQuote.sourceAmount) / 10 ** checkoutQuote.sourceTokenDecimals).toFixed(
11364
11446
  Math.min(checkoutQuote.sourceTokenDecimals, 6)
11365
11447
  ),
11366
11448
  " ",
@@ -11740,7 +11822,7 @@ var SelectSeparator = React28.forwardRef(({ className, ...props }, ref) => /* @_
11740
11822
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
11741
11823
 
11742
11824
  // src/components/deposits/TransferCryptoDoubleInput.tsx
11743
- var import_core25 = require("@unifold/core");
11825
+ var import_core26 = require("@unifold/core");
11744
11826
  var import_jsx_runtime48 = require("react/jsx-runtime");
11745
11827
  var t6 = i18n.transferCrypto;
11746
11828
  var getChainKey3 = (chainId, chainType) => {
@@ -11821,7 +11903,7 @@ function TransferCryptoDoubleInput({
11821
11903
  (c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
11822
11904
  ) : void 0;
11823
11905
  const currentChainType = currentChainData?.chain_type || "ethereum";
11824
- const currentWallet = (0, import_core25.getWalletByChainType)(wallets, currentChainType);
11906
+ const currentWallet = (0, import_core26.getWalletByChainType)(wallets, currentChainType);
11825
11907
  const depositAddress = currentWallet?.address || "";
11826
11908
  const {
11827
11909
  executions: depositExecutions,
@@ -12213,11 +12295,11 @@ function TransferCryptoDoubleInput({
12213
12295
 
12214
12296
  // src/components/deposits/BrowserWalletModal.tsx
12215
12297
  var React29 = __toESM(require("react"));
12216
- var import_core27 = require("@unifold/core");
12298
+ var import_core28 = require("@unifold/core");
12217
12299
 
12218
12300
  // src/hooks/use-deposit-quote.ts
12219
- var import_react_query11 = require("@tanstack/react-query");
12220
- var import_core26 = require("@unifold/core");
12301
+ var import_react_query12 = require("@tanstack/react-query");
12302
+ var import_core27 = require("@unifold/core");
12221
12303
  function useDepositQuote(params) {
12222
12304
  const {
12223
12305
  publishableKey,
@@ -12243,7 +12325,7 @@ function useDepositQuote(params) {
12243
12325
  ...adjustForSlippage ? { adjust_for_slippage: true } : {},
12244
12326
  ...stablecoinParity ? { stablecoin_parity: true } : {}
12245
12327
  };
12246
- return (0, import_react_query11.useQuery)({
12328
+ return (0, import_react_query12.useQuery)({
12247
12329
  queryKey: [
12248
12330
  "unifold",
12249
12331
  "depositQuote",
@@ -12258,7 +12340,7 @@ function useDepositQuote(params) {
12258
12340
  stablecoinParity,
12259
12341
  publishableKey
12260
12342
  ],
12261
- queryFn: () => (0, import_core26.getDepositQuote)(request, publishableKey),
12343
+ queryFn: () => (0, import_core27.getDepositQuote)(request, publishableKey),
12262
12344
  enabled: enabled && !!publishableKey && !!sourceChainType && !!sourceChainId && !!sourceTokenAddress && !!destinationAmount && destinationAmount !== "0" && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress,
12263
12345
  staleTime: 3e4,
12264
12346
  gcTime: 5 * 6e4,
@@ -12362,7 +12444,7 @@ function SelectTokenView({
12362
12444
  ),
12363
12445
  walletInfoProp ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uf-flex uf-w-full uf-justify-center uf-mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(WalletWithNetworkBadge, { walletInfo: walletInfoProp }) }) : null,
12364
12446
  /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "uf-flex uf-min-h-0 uf-flex-1 uf-flex-col", children: [
12365
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uf-h-[220px] uf-shrink-0 uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uf-space-y-2", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-12", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
12447
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uf-h-[300px] uf-shrink-0 uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uf-space-y-2", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-12", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
12366
12448
  import_lucide_react25.Loader2,
12367
12449
  {
12368
12450
  className: "uf-w-6 uf-h-6 uf-animate-spin",
@@ -13497,7 +13579,7 @@ function BrowserWalletModal({
13497
13579
  destination_chain_type: depositWallet.destination_chain_type,
13498
13580
  ...productType ? { product_type: productType } : {}
13499
13581
  };
13500
- const response = await (0, import_core27.getSupportedDepositTokens)(
13582
+ const response = await (0, import_core28.getSupportedDepositTokens)(
13501
13583
  publishableKey,
13502
13584
  options
13503
13585
  );
@@ -13534,7 +13616,7 @@ function BrowserWalletModal({
13534
13616
  let cancelled = false;
13535
13617
  setIsLoading(true);
13536
13618
  setError(null);
13537
- (0, import_core27.getAddressBalances)(walletInfo.address, supportedChainType, publishableKey).then((response) => {
13619
+ (0, import_core28.getAddressBalances)(walletInfo.address, supportedChainType, publishableKey).then((response) => {
13538
13620
  if (cancelled) return;
13539
13621
  const nonZeroBalances = response.balances.filter(
13540
13622
  (b) => b.amount !== "0"
@@ -13858,7 +13940,7 @@ function BrowserWalletModal({
13858
13940
  amountInSmallestUnit = decimalToSmallestUnit(amountStr, token.decimals);
13859
13941
  }
13860
13942
  try {
13861
- const buildResponse = await (0, import_core27.buildSolanaTransaction)(
13943
+ const buildResponse = await (0, import_core28.buildSolanaTransaction)(
13862
13944
  {
13863
13945
  chain_id: "mainnet",
13864
13946
  token_address: token.token_address === "" ? "native" : token.token_address,
@@ -13885,7 +13967,7 @@ function BrowserWalletModal({
13885
13967
  binaryStr += String.fromCharCode(serialized[i]);
13886
13968
  }
13887
13969
  const signedTransactionBase64 = btoa(binaryStr);
13888
- const sendResponse = await (0, import_core27.sendSolanaTransaction)(
13970
+ const sendResponse = await (0, import_core28.sendSolanaTransaction)(
13889
13971
  {
13890
13972
  chain_id: "mainnet",
13891
13973
  signed_transaction: signedTransactionBase64
@@ -14798,18 +14880,18 @@ function DepositModal({
14798
14880
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react20.useState)([]);
14799
14881
  (0, import_react20.useEffect)(() => {
14800
14882
  if (!enableConnectExchange || !open) return;
14801
- (0, import_core28.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14883
+ (0, import_core29.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14802
14884
  });
14803
14885
  }, [enableConnectExchange, open, publishableKey]);
14804
14886
  const [connectedExchange, setConnectedExchange] = (0, import_react20.useState)(() => {
14805
14887
  if (!enableConnectExchange) return null;
14806
- const stored = getStoredIntegrationToken(import_core28.IntegrationProvider.COINBASE);
14888
+ const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
14807
14889
  if (!stored) return null;
14808
14890
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14809
14891
  });
14810
14892
  (0, import_react20.useEffect)(() => {
14811
14893
  if (!enableConnectExchange || !open || view !== "main") return;
14812
- const stored = getStoredIntegrationToken(import_core28.IntegrationProvider.COINBASE);
14894
+ const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
14813
14895
  if (!stored) {
14814
14896
  setConnectedExchange(null);
14815
14897
  return;
@@ -14824,20 +14906,22 @@ function DepositModal({
14824
14906
  return sum + (isNaN(usd) ? 0 : usd);
14825
14907
  }, 0);
14826
14908
  const balanceUsd = totalUsd > 0 ? totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : null;
14827
- setConnectedExchange((prev) => ({ ...prev, balanceUsd, isLoading: false }));
14909
+ setConnectedExchange((prev) => prev ? { ...prev, balanceUsd, isLoading: false } : null);
14828
14910
  };
14829
- (0, import_core28.getIntegrationHoldings)(import_core28.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
14911
+ (0, import_core29.getIntegrationHoldings)(import_core29.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
14830
14912
  try {
14831
- const refreshResult = await (0, import_core28.refreshIntegrationToken)(stored.access_token, publishableKey);
14913
+ const refreshResult = await (0, import_core29.refreshIntegrationToken)(stored.access_token, publishableKey);
14914
+ if (!getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE)) return;
14832
14915
  setStoredIntegrationToken({
14833
- integration_provider: import_core28.IntegrationProvider.COINBASE,
14916
+ integration_provider: import_core29.IntegrationProvider.COINBASE,
14834
14917
  access_token: refreshResult.access_token,
14835
14918
  expires_at: refreshResult.expires_at
14836
14919
  });
14837
- const retryResult = await (0, import_core28.getIntegrationHoldings)(import_core28.IntegrationProvider.COINBASE, refreshResult.access_token, publishableKey);
14920
+ const retryResult = await (0, import_core29.getIntegrationHoldings)(import_core29.IntegrationProvider.COINBASE, refreshResult.access_token, publishableKey);
14838
14921
  processHoldings(retryResult);
14839
14922
  } catch {
14840
- clearStoredIntegrationToken(import_core28.IntegrationProvider.COINBASE);
14923
+ if (!getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE)) return;
14924
+ clearStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
14841
14925
  setConnectedExchange(null);
14842
14926
  }
14843
14927
  });
@@ -14845,7 +14929,7 @@ function DepositModal({
14845
14929
  (0, import_react20.useEffect)(() => {
14846
14930
  if (!connectedExchange || integrationExchanges.length === 0) return;
14847
14931
  const cbExchange = integrationExchanges.find(
14848
- (e) => e.service_provider === import_core28.IntegrationProvider.COINBASE
14932
+ (e) => e.service_provider === import_core29.IntegrationProvider.COINBASE
14849
14933
  );
14850
14934
  const iconUrl = cbExchange?.icon_urls?.find((u) => u.format === "svg")?.url || cbExchange?.icon_urls?.find((u) => u.format === "png")?.url || cbExchange?.icon_url;
14851
14935
  if (iconUrl && iconUrl !== connectedExchange.iconUrl) {
@@ -14902,7 +14986,7 @@ function DepositModal({
14902
14986
  if (view !== "tracker" || !userId) return;
14903
14987
  const fetchExecutions = async () => {
14904
14988
  try {
14905
- const response = await (0, import_core28.queryExecutions)(userId, publishableKey, import_core28.ActionType.Deposit);
14989
+ const response = await (0, import_core29.queryExecutions)(userId, publishableKey, import_core29.ActionType.Deposit);
14906
14990
  const sorted = [...response.data].sort((a, b) => {
14907
14991
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
14908
14992
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -15004,6 +15088,14 @@ function DepositModal({
15004
15088
  setBrowserWalletInfo(null);
15005
15089
  setBrowserWalletModalOpen(false);
15006
15090
  };
15091
+ const handleExchangeDisconnect = () => {
15092
+ const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
15093
+ if (stored) {
15094
+ (0, import_core29.revokeIntegrationToken)(stored.access_token, publishableKey);
15095
+ }
15096
+ clearStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
15097
+ setConnectedExchange(null);
15098
+ };
15007
15099
  const handleClose = () => {
15008
15100
  onOpenChange(false);
15009
15101
  if (resetViewTimeoutRef.current) {
@@ -15209,6 +15301,7 @@ function DepositModal({
15209
15301
  setCoinbaseSkipToHoldings(true);
15210
15302
  setView("coinbase_connect");
15211
15303
  },
15304
+ onDisconnect: handleExchangeDisconnect,
15212
15305
  title: i18n.connectExchange.title,
15213
15306
  subtitle: i18n.connectExchange.subtitle,
15214
15307
  exchanges: integrationExchanges,
@@ -15413,34 +15506,37 @@ function DepositModal({
15413
15506
  ),
15414
15507
  depositPoweredByFooter
15415
15508
  ] })
15416
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15417
- CoinbaseConnect,
15418
- {
15419
- publishableKey,
15420
- userId,
15421
- wallets,
15422
- recipientAddress,
15423
- destinationTokenAddress: destinationTokenAddress ?? "",
15424
- destinationChainId: destinationChainId ?? "",
15425
- destinationChainType: destinationChainType ?? "",
15426
- onTransferSuccess: (result) => {
15427
- onDepositSuccess?.({
15428
- message: "Transfer completed via Coinbase Connect",
15429
- transaction: result
15430
- });
15431
- },
15432
- onTransferError: (error) => {
15433
- onDepositError?.({
15434
- message: error.message,
15435
- error
15436
- });
15437
- },
15438
- onBack: handleBack,
15439
- onClose: handleClose,
15440
- skipToHoldings: coinbaseSkipToHoldings,
15441
- onExecutionsChange: setDepositExecutions
15442
- }
15443
- ) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
15509
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15510
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15511
+ CoinbaseConnect,
15512
+ {
15513
+ publishableKey,
15514
+ userId,
15515
+ wallets,
15516
+ recipientAddress,
15517
+ destinationTokenAddress: destinationTokenAddress ?? "",
15518
+ destinationChainId: destinationChainId ?? "",
15519
+ destinationChainType: destinationChainType ?? "",
15520
+ onTransferSuccess: (result) => {
15521
+ onDepositSuccess?.({
15522
+ message: "Transfer completed via Coinbase Connect",
15523
+ transaction: result
15524
+ });
15525
+ },
15526
+ onTransferError: (error) => {
15527
+ onDepositError?.({
15528
+ message: error.message,
15529
+ error
15530
+ });
15531
+ },
15532
+ onBack: handleBack,
15533
+ onClose: handleClose,
15534
+ skipToHoldings: coinbaseSkipToHoldings,
15535
+ onExecutionsChange: setDepositExecutions
15536
+ }
15537
+ ),
15538
+ depositPoweredByFooter
15539
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
15444
15540
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15445
15541
  DepositHeader,
15446
15542
  {
@@ -15526,8 +15622,8 @@ var import_react21 = require("react");
15526
15622
  var import_lucide_react30 = require("lucide-react");
15527
15623
 
15528
15624
  // src/hooks/use-payment-intent.ts
15529
- var import_react_query12 = require("@tanstack/react-query");
15530
- var import_core29 = require("@unifold/core");
15625
+ var import_react_query13 = require("@tanstack/react-query");
15626
+ var import_core30 = require("@unifold/core");
15531
15627
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
15532
15628
  "succeeded",
15533
15629
  "expired",
@@ -15541,9 +15637,9 @@ function usePaymentIntent(params) {
15541
15637
  enabled = true,
15542
15638
  pollingInterval = 3e3
15543
15639
  } = params;
15544
- return (0, import_react_query12.useQuery)({
15640
+ return (0, import_react_query13.useQuery)({
15545
15641
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
15546
- queryFn: () => (0, import_core29.retrievePaymentIntent)(clientSecret, publishableKey),
15642
+ queryFn: () => (0, import_core30.retrievePaymentIntent)(clientSecret, publishableKey),
15547
15643
  enabled: enabled && !!clientSecret && !!publishableKey,
15548
15644
  staleTime: 0,
15549
15645
  refetchInterval: (query) => {
@@ -16198,12 +16294,12 @@ var import_react26 = require("react");
16198
16294
  var import_lucide_react33 = require("lucide-react");
16199
16295
 
16200
16296
  // src/hooks/use-supported-destination-tokens.ts
16201
- var import_react_query13 = require("@tanstack/react-query");
16202
- var import_core30 = require("@unifold/core");
16297
+ var import_react_query14 = require("@tanstack/react-query");
16298
+ var import_core31 = require("@unifold/core");
16203
16299
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
16204
- return (0, import_react_query13.useQuery)({
16300
+ return (0, import_react_query14.useQuery)({
16205
16301
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
16206
- queryFn: () => (0, import_core30.getSupportedDestinationTokens)(publishableKey),
16302
+ queryFn: () => (0, import_core31.getSupportedDestinationTokens)(publishableKey),
16207
16303
  staleTime: 1e3 * 60 * 5,
16208
16304
  gcTime: 1e3 * 60 * 30,
16209
16305
  refetchOnMount: false,
@@ -16230,8 +16326,8 @@ function useDefaultDestinationToken({
16230
16326
  }
16231
16327
 
16232
16328
  // src/hooks/use-source-token-validation.ts
16233
- var import_react_query14 = require("@tanstack/react-query");
16234
- var import_core31 = require("@unifold/core");
16329
+ var import_react_query15 = require("@tanstack/react-query");
16330
+ var import_core32 = require("@unifold/core");
16235
16331
  function useSourceTokenValidation(params) {
16236
16332
  const {
16237
16333
  sourceChainType,
@@ -16242,7 +16338,7 @@ function useSourceTokenValidation(params) {
16242
16338
  enabled = true
16243
16339
  } = params;
16244
16340
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
16245
- return (0, import_react_query14.useQuery)({
16341
+ return (0, import_react_query15.useQuery)({
16246
16342
  queryKey: [
16247
16343
  "unifold",
16248
16344
  "sourceTokenValidation",
@@ -16252,7 +16348,7 @@ function useSourceTokenValidation(params) {
16252
16348
  publishableKey
16253
16349
  ],
16254
16350
  queryFn: async () => {
16255
- const res = await (0, import_core31.getSupportedDepositTokens)(publishableKey);
16351
+ const res = await (0, import_core32.getSupportedDepositTokens)(publishableKey);
16256
16352
  let matchedMinUsd = null;
16257
16353
  let matchedProcessingTime = null;
16258
16354
  let matchedSlippage = null;
@@ -16290,8 +16386,8 @@ function useSourceTokenValidation(params) {
16290
16386
  }
16291
16387
 
16292
16388
  // src/hooks/use-address-balance.ts
16293
- var import_react_query15 = require("@tanstack/react-query");
16294
- var import_core32 = require("@unifold/core");
16389
+ var import_react_query16 = require("@tanstack/react-query");
16390
+ var import_core33 = require("@unifold/core");
16295
16391
  function useAddressBalance(params) {
16296
16392
  const {
16297
16393
  address,
@@ -16302,7 +16398,7 @@ function useAddressBalance(params) {
16302
16398
  enabled = true
16303
16399
  } = params;
16304
16400
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
16305
- return (0, import_react_query15.useQuery)({
16401
+ return (0, import_react_query16.useQuery)({
16306
16402
  queryKey: [
16307
16403
  "unifold",
16308
16404
  "addressBalance",
@@ -16313,7 +16409,7 @@ function useAddressBalance(params) {
16313
16409
  publishableKey
16314
16410
  ],
16315
16411
  queryFn: async () => {
16316
- const res = await (0, import_core32.getAddressBalance)(
16412
+ const res = await (0, import_core33.getAddressBalance)(
16317
16413
  address,
16318
16414
  chainType,
16319
16415
  chainId,
@@ -16351,13 +16447,13 @@ function useAddressBalance(params) {
16351
16447
  }
16352
16448
 
16353
16449
  // src/hooks/use-executions.ts
16354
- var import_react_query16 = require("@tanstack/react-query");
16355
- var import_core33 = require("@unifold/core");
16450
+ var import_react_query17 = require("@tanstack/react-query");
16451
+ var import_core34 = require("@unifold/core");
16356
16452
  function useExecutions(userId, publishableKey, options) {
16357
- const actionType = options?.actionType ?? import_core33.ActionType.Deposit;
16358
- return (0, import_react_query16.useQuery)({
16453
+ const actionType = options?.actionType ?? import_core34.ActionType.Deposit;
16454
+ return (0, import_react_query17.useQuery)({
16359
16455
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
16360
- queryFn: () => (0, import_core33.queryExecutions)(userId, publishableKey, actionType),
16456
+ queryFn: () => (0, import_core34.queryExecutions)(userId, publishableKey, actionType),
16361
16457
  enabled: (options?.enabled ?? true) && !!userId,
16362
16458
  refetchInterval: options?.refetchInterval ?? 3e3,
16363
16459
  staleTime: 0,
@@ -16368,7 +16464,7 @@ function useExecutions(userId, publishableKey, options) {
16368
16464
 
16369
16465
  // src/hooks/use-withdraw-polling.ts
16370
16466
  var import_react22 = require("react");
16371
- var import_core34 = require("@unifold/core");
16467
+ var import_core35 = require("@unifold/core");
16372
16468
  var POLL_INTERVAL_MS3 = 2500;
16373
16469
  var POLL_ENDPOINT_INTERVAL_MS2 = 3e3;
16374
16470
  var CUTOFF_BUFFER_MS2 = 6e4;
@@ -16408,15 +16504,15 @@ function useWithdrawPolling({
16408
16504
  const enabledAt = enabledAtRef.current;
16409
16505
  const poll = async () => {
16410
16506
  try {
16411
- const response = await (0, import_core34.queryExecutions)(userId, publishableKey, import_core34.ActionType.Withdraw);
16507
+ const response = await (0, import_core35.queryExecutions)(userId, publishableKey, import_core35.ActionType.Withdraw);
16412
16508
  const cutoff = new Date(enabledAt.getTime() - CUTOFF_BUFFER_MS2);
16413
16509
  const sorted = [...response.data].sort((a, b) => {
16414
16510
  const tA = a.created_at ? new Date(a.created_at).getTime() : 0;
16415
16511
  const tB = b.created_at ? new Date(b.created_at).getTime() : 0;
16416
16512
  return tB - tA;
16417
16513
  });
16418
- const inProgress = [import_core34.ExecutionStatus.PENDING, import_core34.ExecutionStatus.WAITING, import_core34.ExecutionStatus.DELAYED];
16419
- const terminal = [import_core34.ExecutionStatus.SUCCEEDED, import_core34.ExecutionStatus.FAILED];
16514
+ const inProgress = [import_core35.ExecutionStatus.PENDING, import_core35.ExecutionStatus.WAITING, import_core35.ExecutionStatus.DELAYED];
16515
+ const terminal = [import_core35.ExecutionStatus.SUCCEEDED, import_core35.ExecutionStatus.FAILED];
16420
16516
  let target = null;
16421
16517
  for (const ex of sorted) {
16422
16518
  const t12 = ex.created_at ? new Date(ex.created_at) : null;
@@ -16446,9 +16542,9 @@ function useWithdrawPolling({
16446
16542
  }
16447
16543
  return [...list, ex];
16448
16544
  });
16449
- if (ex.status === import_core34.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16545
+ if (ex.status === import_core35.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16450
16546
  onSuccessRef.current?.({ message: "Withdrawal completed successfully", executionId: ex.id, transaction: ex });
16451
- } else if (ex.status === import_core34.ExecutionStatus.FAILED && prev !== import_core34.ExecutionStatus.FAILED) {
16547
+ } else if (ex.status === import_core35.ExecutionStatus.FAILED && prev !== import_core35.ExecutionStatus.FAILED) {
16452
16548
  onErrorRef.current?.({ message: "Withdrawal failed", code: "WITHDRAW_FAILED", error: ex });
16453
16549
  }
16454
16550
  }
@@ -16469,7 +16565,7 @@ function useWithdrawPolling({
16469
16565
  if (!enabled || !depositWalletId) return;
16470
16566
  const trigger = async () => {
16471
16567
  try {
16472
- await (0, import_core34.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
16568
+ await (0, import_core35.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
16473
16569
  } catch {
16474
16570
  }
16475
16571
  };
@@ -16638,11 +16734,11 @@ function WithdrawDoubleInput({
16638
16734
  // src/components/withdrawals/WithdrawForm.tsx
16639
16735
  var import_react24 = require("react");
16640
16736
  var import_lucide_react31 = require("lucide-react");
16641
- var import_core39 = require("@unifold/core");
16737
+ var import_core40 = require("@unifold/core");
16642
16738
 
16643
16739
  // src/hooks/use-verify-recipient-address.ts
16644
- var import_react_query17 = require("@tanstack/react-query");
16645
- var import_core35 = require("@unifold/core");
16740
+ var import_react_query18 = require("@tanstack/react-query");
16741
+ var import_core36 = require("@unifold/core");
16646
16742
  function useVerifyRecipientAddress(params) {
16647
16743
  const {
16648
16744
  chainType,
@@ -16654,7 +16750,7 @@ function useVerifyRecipientAddress(params) {
16654
16750
  } = params;
16655
16751
  const trimmedAddress = recipientAddress?.trim() || "";
16656
16752
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
16657
- return (0, import_react_query17.useQuery)({
16753
+ return (0, import_react_query18.useQuery)({
16658
16754
  queryKey: [
16659
16755
  "unifold",
16660
16756
  "verifyRecipientAddress",
@@ -16664,7 +16760,7 @@ function useVerifyRecipientAddress(params) {
16664
16760
  trimmedAddress,
16665
16761
  publishableKey
16666
16762
  ],
16667
- queryFn: () => (0, import_core35.verifyRecipientAddress)(
16763
+ queryFn: () => (0, import_core36.verifyRecipientAddress)(
16668
16764
  {
16669
16765
  chain_type: chainType,
16670
16766
  chain_id: chainId,
@@ -16683,7 +16779,7 @@ function useVerifyRecipientAddress(params) {
16683
16779
  }
16684
16780
 
16685
16781
  // src/components/withdrawals/send-withdraw.ts
16686
- var import_core36 = require("@unifold/core");
16782
+ var import_core37 = require("@unifold/core");
16687
16783
  async function sendEvmWithdraw(params) {
16688
16784
  const {
16689
16785
  provider,
@@ -16761,7 +16857,7 @@ async function sendSolanaWithdraw(params) {
16761
16857
  if (!provider.publicKey) {
16762
16858
  await provider.connect();
16763
16859
  }
16764
- const buildResponse = await (0, import_core36.buildSolanaTransaction)(
16860
+ const buildResponse = await (0, import_core37.buildSolanaTransaction)(
16765
16861
  {
16766
16862
  chain_id: "mainnet",
16767
16863
  token_address: sourceTokenAddress === "" ? "native" : sourceTokenAddress,
@@ -16787,7 +16883,7 @@ async function sendSolanaWithdraw(params) {
16787
16883
  for (let i = 0; i < serialized.length; i++) {
16788
16884
  binaryStr += String.fromCharCode(serialized[i]);
16789
16885
  }
16790
- const sendResponse = await (0, import_core36.sendSolanaTransaction)(
16886
+ const sendResponse = await (0, import_core37.sendSolanaTransaction)(
16791
16887
  { chain_id: "mainnet", signed_transaction: btoa(binaryStr) },
16792
16888
  publishableKey
16793
16889
  );
@@ -16813,7 +16909,7 @@ async function sendHypercoreWithdraw(params) {
16813
16909
  params: []
16814
16910
  });
16815
16911
  const activeChainId = String(parseInt(currentChainHex, 16));
16816
- const buildResult = await (0, import_core36.buildHypercoreTransaction)(
16912
+ const buildResult = await (0, import_core37.buildHypercoreTransaction)(
16817
16913
  {
16818
16914
  action_type: isSpot ? "spot_send" : "usd_send",
16819
16915
  signature_chain_type: "ethereum",
@@ -16829,7 +16925,7 @@ async function sendHypercoreWithdraw(params) {
16829
16925
  method: "eth_signTypedData_v4",
16830
16926
  params: [fromAddress, JSON.stringify(buildResult.typed_data)]
16831
16927
  });
16832
- await (0, import_core36.sendHypercoreTransaction)(
16928
+ await (0, import_core37.sendHypercoreTransaction)(
16833
16929
  {
16834
16930
  action_payload: buildResult.action_payload,
16835
16931
  signature,
@@ -16929,11 +17025,11 @@ async function detectBrowserWallet(chainType, senderAddress) {
16929
17025
 
16930
17026
  // src/hooks/use-hypercore-withdraw-activation.ts
16931
17027
  var import_react23 = require("react");
16932
- var import_core38 = require("@unifold/core");
17028
+ var import_core39 = require("@unifold/core");
16933
17029
 
16934
17030
  // src/hooks/use-get-deposit-address.ts
16935
- var import_react_query18 = require("@tanstack/react-query");
16936
- var import_core37 = require("@unifold/core");
17031
+ var import_react_query19 = require("@tanstack/react-query");
17032
+ var import_core38 = require("@unifold/core");
16937
17033
  function useGetDepositAddress(params) {
16938
17034
  const {
16939
17035
  userId,
@@ -16946,7 +17042,7 @@ function useGetDepositAddress(params) {
16946
17042
  enabled = true
16947
17043
  } = params;
16948
17044
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
16949
- return (0, import_react_query18.useQuery)({
17045
+ return (0, import_react_query19.useQuery)({
16950
17046
  queryKey: [
16951
17047
  "unifold",
16952
17048
  "getDepositAddress",
@@ -16958,7 +17054,7 @@ function useGetDepositAddress(params) {
16958
17054
  actionType ?? null,
16959
17055
  publishableKey
16960
17056
  ],
16961
- queryFn: () => (0, import_core37.getDepositAddress)(
17057
+ queryFn: () => (0, import_core38.getDepositAddress)(
16962
17058
  {
16963
17059
  external_user_id: userId,
16964
17060
  recipient_address: recipientAddress,
@@ -17012,7 +17108,7 @@ function useHypercoreWithdrawActivation(params) {
17012
17108
  destinationChainType,
17013
17109
  destinationChainId,
17014
17110
  destinationTokenAddress,
17015
- actionType: import_core38.ActionType.Withdraw,
17111
+ actionType: import_core39.ActionType.Withdraw,
17016
17112
  enabled: enabled && isHypercore(sourceChainId)
17017
17113
  });
17018
17114
  const depositWalletAddress = (0, import_react23.useMemo)(() => {
@@ -17281,7 +17377,7 @@ function WithdrawForm({
17281
17377
  let humanAmount = isMaxed ? balanceData.balanceHuman : toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
17282
17378
  if (isHypercoreChain(sourceChainId)) {
17283
17379
  try {
17284
- const check = await (0, import_core39.checkHypercoreActivation)(
17380
+ const check = await (0, import_core40.checkHypercoreActivation)(
17285
17381
  {
17286
17382
  source_address: senderAddress,
17287
17383
  recipient_address: depositWallet.address
@@ -17598,14 +17694,14 @@ function WithdrawForm({
17598
17694
 
17599
17695
  // src/components/withdrawals/WithdrawExecutionItem.tsx
17600
17696
  var import_lucide_react32 = require("lucide-react");
17601
- var import_core40 = require("@unifold/core");
17697
+ var import_core41 = require("@unifold/core");
17602
17698
  var import_jsx_runtime60 = require("react/jsx-runtime");
17603
17699
  function WithdrawExecutionItem({
17604
17700
  execution,
17605
17701
  onClick
17606
17702
  }) {
17607
17703
  const { colors: colors2, fonts, components } = useTheme();
17608
- const isPending = execution.status === import_core40.ExecutionStatus.PENDING || execution.status === import_core40.ExecutionStatus.WAITING || execution.status === import_core40.ExecutionStatus.DELAYED;
17704
+ const isPending = execution.status === import_core41.ExecutionStatus.PENDING || execution.status === import_core41.ExecutionStatus.WAITING || execution.status === import_core41.ExecutionStatus.DELAYED;
17609
17705
  const formatDateTime = (timestamp) => {
17610
17706
  try {
17611
17707
  const date = new Date(timestamp);
@@ -17652,7 +17748,7 @@ function WithdrawExecutionItem({
17652
17748
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
17653
17749
  "img",
17654
17750
  {
17655
- src: execution.destination_token_metadata?.icon_url || (0, import_core40.getIconUrl)("/icons/tokens/svg/usdc.svg"),
17751
+ src: execution.destination_token_metadata?.icon_url || (0, import_core41.getIconUrl)("/icons/tokens/svg/usdc.svg"),
17656
17752
  alt: "Token",
17657
17753
  width: 36,
17658
17754
  height: 36,
@@ -17911,7 +18007,7 @@ function WithdrawConfirmingView({
17911
18007
  }
17912
18008
 
17913
18009
  // src/components/withdrawals/WithdrawModal.tsx
17914
- var import_core41 = require("@unifold/core");
18010
+ var import_core42 = require("@unifold/core");
17915
18011
  var import_jsx_runtime62 = require("react/jsx-runtime");
17916
18012
  var t10 = i18n.withdrawModal;
17917
18013
  var getChainKey5 = (chainId, chainType) => `${chainType}:${chainId}`;
@@ -18002,25 +18098,25 @@ function WithdrawModal({
18002
18098
  onWithdrawError
18003
18099
  });
18004
18100
  const { data: allWithdrawalsData } = useExecutions(externalUserId, publishableKey, {
18005
- actionType: import_core41.ActionType.Withdraw,
18101
+ actionType: import_core42.ActionType.Withdraw,
18006
18102
  enabled: open,
18007
18103
  refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
18008
18104
  });
18009
18105
  const allWithdrawals = allWithdrawalsData?.data ?? [];
18010
18106
  const handleDepositWalletCreation = (0, import_react26.useCallback)(async (params) => {
18011
- const { data: wallets } = await (0, import_core41.createDepositAddress)(
18107
+ const { data: wallets } = await (0, import_core42.createDepositAddress)(
18012
18108
  {
18013
18109
  external_user_id: externalUserId,
18014
18110
  destination_chain_type: params.destinationChainType,
18015
18111
  destination_chain_id: params.destinationChainId,
18016
18112
  destination_token_address: params.destinationTokenAddress,
18017
18113
  recipient_address: params.recipientAddress,
18018
- action_type: import_core41.ActionType.Withdraw,
18114
+ action_type: import_core42.ActionType.Withdraw,
18019
18115
  source_chain_type: sourceChainType
18020
18116
  },
18021
18117
  publishableKey
18022
18118
  );
18023
- const depositWallet = (0, import_core41.getWalletByChainType)(wallets, sourceChainType);
18119
+ const depositWallet = (0, import_core42.getWalletByChainType)(wallets, sourceChainType);
18024
18120
  if (!depositWallet) {
18025
18121
  throw new Error(`No deposit wallet available for ${sourceChainType}`);
18026
18122
  }