@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.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +431 -335
- package/dist/index.mjs +375 -278
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useLayoutEffect as useLayoutEffect2,
|
|
6
6
|
useCallback as useCallback6,
|
|
7
7
|
useRef as useRef8,
|
|
8
|
-
useMemo as
|
|
8
|
+
useMemo as useMemo10
|
|
9
9
|
} from "react";
|
|
10
10
|
import { ChevronRight as ChevronRight14, MapPinOff, AlertTriangle as AlertTriangle2 } from "lucide-react";
|
|
11
11
|
|
|
@@ -1431,7 +1431,8 @@ var en_default = {
|
|
|
1431
1431
|
title: "Transfer Failed",
|
|
1432
1432
|
tryAgain: "Try Again"
|
|
1433
1433
|
},
|
|
1434
|
-
continue: "Continue"
|
|
1434
|
+
continue: "Continue",
|
|
1435
|
+
disconnect: "Disconnect"
|
|
1435
1436
|
},
|
|
1436
1437
|
buyWithCard: {
|
|
1437
1438
|
onramp: {
|
|
@@ -4786,6 +4787,7 @@ import { Link2, ChevronRight as ChevronRight7 } from "lucide-react";
|
|
|
4786
4787
|
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4787
4788
|
function ConnectExchangeButton({
|
|
4788
4789
|
onClick,
|
|
4790
|
+
onDisconnect,
|
|
4789
4791
|
title,
|
|
4790
4792
|
subtitle,
|
|
4791
4793
|
exchanges,
|
|
@@ -4798,6 +4800,109 @@ function ConnectExchangeButton({
|
|
|
4798
4800
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
4799
4801
|
}, []);
|
|
4800
4802
|
const isConnected = connectedExchange != null;
|
|
4803
|
+
const handleDisconnectClick = (e) => {
|
|
4804
|
+
e.preventDefault();
|
|
4805
|
+
e.stopPropagation();
|
|
4806
|
+
onDisconnect?.();
|
|
4807
|
+
};
|
|
4808
|
+
const rowSurfaceStyle = {
|
|
4809
|
+
backgroundColor: isHovered ? colors2.cardHover : components.card.backgroundColor,
|
|
4810
|
+
borderRadius: components.card.borderRadius,
|
|
4811
|
+
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
4812
|
+
};
|
|
4813
|
+
const iconBlock = isConnected ? connectedExchange.iconUrl ? /* @__PURE__ */ jsx19(
|
|
4814
|
+
"img",
|
|
4815
|
+
{
|
|
4816
|
+
src: connectedExchange.iconUrl,
|
|
4817
|
+
alt: connectedExchange.name,
|
|
4818
|
+
width: 36,
|
|
4819
|
+
height: 36,
|
|
4820
|
+
className: "uf-rounded-lg"
|
|
4821
|
+
}
|
|
4822
|
+
) : /* @__PURE__ */ jsx19(
|
|
4823
|
+
"div",
|
|
4824
|
+
{
|
|
4825
|
+
className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
|
|
4826
|
+
style: { backgroundColor: colors2.card },
|
|
4827
|
+
children: /* @__PURE__ */ jsx19(
|
|
4828
|
+
"span",
|
|
4829
|
+
{
|
|
4830
|
+
className: "uf-text-xs uf-font-medium",
|
|
4831
|
+
style: { color: components.card.iconColor },
|
|
4832
|
+
children: connectedExchange.name.slice(0, 2).toUpperCase()
|
|
4833
|
+
}
|
|
4834
|
+
)
|
|
4835
|
+
}
|
|
4836
|
+
) : /* @__PURE__ */ jsx19("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ jsx19(
|
|
4837
|
+
Link2,
|
|
4838
|
+
{
|
|
4839
|
+
className: "uf-w-5 uf-h-5",
|
|
4840
|
+
style: { color: components.card.iconColor }
|
|
4841
|
+
}
|
|
4842
|
+
) });
|
|
4843
|
+
const titleSubtitleBlock = /* @__PURE__ */ jsxs16("div", { className: "uf-text-left", children: [
|
|
4844
|
+
/* @__PURE__ */ jsx19(
|
|
4845
|
+
"div",
|
|
4846
|
+
{
|
|
4847
|
+
className: "uf-text-sm uf-font-light uf-mb-0.5",
|
|
4848
|
+
style: {
|
|
4849
|
+
color: components.card.titleColor,
|
|
4850
|
+
fontFamily: fonts.regular
|
|
4851
|
+
},
|
|
4852
|
+
children: isConnected ? connectedExchange.name : title
|
|
4853
|
+
}
|
|
4854
|
+
),
|
|
4855
|
+
isConnected && connectedExchange.isLoading ? /* @__PURE__ */ jsx19("div", { className: "uf-h-3 uf-w-24 uf-bg-muted uf-rounded uf-animate-pulse" }) : /* @__PURE__ */ jsx19(
|
|
4856
|
+
"div",
|
|
4857
|
+
{
|
|
4858
|
+
className: "uf-text-xs uf-font-light",
|
|
4859
|
+
style: {
|
|
4860
|
+
color: components.card.subtitleColor,
|
|
4861
|
+
fontFamily: fonts.regular
|
|
4862
|
+
},
|
|
4863
|
+
children: isConnected ? connectedExchange.balanceUsd ? `$${connectedExchange.balanceUsd} \u2022 2 min` : "Deposit from exchange" : subtitle
|
|
4864
|
+
}
|
|
4865
|
+
)
|
|
4866
|
+
] });
|
|
4867
|
+
if (isConnected && onDisconnect) {
|
|
4868
|
+
return /* @__PURE__ */ jsxs16(
|
|
4869
|
+
"div",
|
|
4870
|
+
{
|
|
4871
|
+
onMouseEnter: () => !isTouchDevice && setIsHovered(true),
|
|
4872
|
+
onMouseLeave: () => setIsHovered(false),
|
|
4873
|
+
onTouchStart: () => setIsHovered(false),
|
|
4874
|
+
className: "uf-w-full uf-transition-colors uf-flex uf-items-stretch uf-group",
|
|
4875
|
+
style: rowSurfaceStyle,
|
|
4876
|
+
children: [
|
|
4877
|
+
/* @__PURE__ */ jsxs16(
|
|
4878
|
+
"button",
|
|
4879
|
+
{
|
|
4880
|
+
type: "button",
|
|
4881
|
+
onClick,
|
|
4882
|
+
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",
|
|
4883
|
+
children: [
|
|
4884
|
+
iconBlock,
|
|
4885
|
+
titleSubtitleBlock
|
|
4886
|
+
]
|
|
4887
|
+
}
|
|
4888
|
+
),
|
|
4889
|
+
/* @__PURE__ */ jsx19("div", { className: "uf-flex uf-items-center uf-gap-1 uf-shrink-0 uf-pr-2 uf-pl-0", children: /* @__PURE__ */ jsx19(
|
|
4890
|
+
"button",
|
|
4891
|
+
{
|
|
4892
|
+
type: "button",
|
|
4893
|
+
onClick: handleDisconnectClick,
|
|
4894
|
+
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",
|
|
4895
|
+
style: {
|
|
4896
|
+
color: colors2.error,
|
|
4897
|
+
fontFamily: fonts.regular
|
|
4898
|
+
},
|
|
4899
|
+
children: i18n.connectExchange.disconnect
|
|
4900
|
+
}
|
|
4901
|
+
) })
|
|
4902
|
+
]
|
|
4903
|
+
}
|
|
4904
|
+
);
|
|
4905
|
+
}
|
|
4801
4906
|
return /* @__PURE__ */ jsxs16(
|
|
4802
4907
|
"button",
|
|
4803
4908
|
{
|
|
@@ -4806,67 +4911,11 @@ function ConnectExchangeButton({
|
|
|
4806
4911
|
onMouseLeave: () => setIsHovered(false),
|
|
4807
4912
|
onTouchStart: () => setIsHovered(false),
|
|
4808
4913
|
className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between uf-group",
|
|
4809
|
-
style:
|
|
4810
|
-
backgroundColor: isHovered ? colors2.cardHover : components.card.backgroundColor,
|
|
4811
|
-
borderRadius: components.card.borderRadius,
|
|
4812
|
-
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
4813
|
-
},
|
|
4914
|
+
style: rowSurfaceStyle,
|
|
4814
4915
|
children: [
|
|
4815
4916
|
/* @__PURE__ */ jsxs16("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
{
|
|
4819
|
-
src: connectedExchange.iconUrl,
|
|
4820
|
-
alt: connectedExchange.name,
|
|
4821
|
-
width: 36,
|
|
4822
|
-
height: 36,
|
|
4823
|
-
className: "uf-rounded-lg"
|
|
4824
|
-
}
|
|
4825
|
-
) : /* @__PURE__ */ jsx19(
|
|
4826
|
-
"div",
|
|
4827
|
-
{
|
|
4828
|
-
className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
|
|
4829
|
-
style: { backgroundColor: colors2.card },
|
|
4830
|
-
children: /* @__PURE__ */ jsx19(
|
|
4831
|
-
"span",
|
|
4832
|
-
{
|
|
4833
|
-
className: "uf-text-xs uf-font-medium",
|
|
4834
|
-
style: { color: components.card.iconColor },
|
|
4835
|
-
children: connectedExchange.name.slice(0, 2).toUpperCase()
|
|
4836
|
-
}
|
|
4837
|
-
)
|
|
4838
|
-
}
|
|
4839
|
-
) : /* @__PURE__ */ jsx19("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ jsx19(
|
|
4840
|
-
Link2,
|
|
4841
|
-
{
|
|
4842
|
-
className: "uf-w-5 uf-h-5",
|
|
4843
|
-
style: { color: components.card.iconColor }
|
|
4844
|
-
}
|
|
4845
|
-
) }),
|
|
4846
|
-
/* @__PURE__ */ jsxs16("div", { className: "uf-text-left", children: [
|
|
4847
|
-
/* @__PURE__ */ jsx19(
|
|
4848
|
-
"div",
|
|
4849
|
-
{
|
|
4850
|
-
className: "uf-text-sm uf-font-light uf-mb-0.5",
|
|
4851
|
-
style: {
|
|
4852
|
-
color: components.card.titleColor,
|
|
4853
|
-
fontFamily: fonts.regular
|
|
4854
|
-
},
|
|
4855
|
-
children: isConnected ? connectedExchange.name : title
|
|
4856
|
-
}
|
|
4857
|
-
),
|
|
4858
|
-
isConnected && connectedExchange.isLoading ? /* @__PURE__ */ jsx19("div", { className: "uf-h-3 uf-w-24 uf-bg-muted uf-rounded uf-animate-pulse" }) : /* @__PURE__ */ jsx19(
|
|
4859
|
-
"div",
|
|
4860
|
-
{
|
|
4861
|
-
className: "uf-text-xs uf-font-light",
|
|
4862
|
-
style: {
|
|
4863
|
-
color: components.card.subtitleColor,
|
|
4864
|
-
fontFamily: fonts.regular
|
|
4865
|
-
},
|
|
4866
|
-
children: isConnected ? connectedExchange.balanceUsd ? `$${connectedExchange.balanceUsd} \u2022 2 min` : "Deposit from exchange" : subtitle
|
|
4867
|
-
}
|
|
4868
|
-
)
|
|
4869
|
-
] })
|
|
4917
|
+
iconBlock,
|
|
4918
|
+
titleSubtitleBlock
|
|
4870
4919
|
] }),
|
|
4871
4920
|
/* @__PURE__ */ jsxs16("div", { className: "uf-flex uf-items-center uf-gap-1.5", children: [
|
|
4872
4921
|
!isConnected && exchanges && exchanges.length > 0 ? exchanges.slice(0, 4).map((ex, i) => {
|
|
@@ -7736,7 +7785,7 @@ function BrowserWalletButton({
|
|
|
7736
7785
|
}
|
|
7737
7786
|
|
|
7738
7787
|
// src/components/deposits/CoinbaseConnect.tsx
|
|
7739
|
-
import { useState as useState20, useEffect as useEffect16, useCallback as useCallback2, useRef as useRef5 } from "react";
|
|
7788
|
+
import { useState as useState20, useEffect as useEffect16, useCallback as useCallback2, useMemo as useMemo3, useRef as useRef5 } from "react";
|
|
7740
7789
|
import {
|
|
7741
7790
|
ChevronRight as ChevronRight11,
|
|
7742
7791
|
ChevronDown as ChevronDown3,
|
|
@@ -7755,8 +7804,6 @@ import {
|
|
|
7755
7804
|
getIntegrationHoldings,
|
|
7756
7805
|
createIntegrationTransfer,
|
|
7757
7806
|
confirmIntegrationTransfer,
|
|
7758
|
-
getIntegrationTransferDefaultToken,
|
|
7759
|
-
getSupportedDepositTokens,
|
|
7760
7807
|
IntegrationProvider
|
|
7761
7808
|
} from "@unifold/core";
|
|
7762
7809
|
|
|
@@ -7778,6 +7825,77 @@ function useProjectConfig({
|
|
|
7778
7825
|
return { projectConfig, isLoading };
|
|
7779
7826
|
}
|
|
7780
7827
|
|
|
7828
|
+
// src/hooks/use-supported-deposit-tokens.ts
|
|
7829
|
+
import { useQuery as useQuery5 } from "@tanstack/react-query";
|
|
7830
|
+
import {
|
|
7831
|
+
getSupportedDepositTokens
|
|
7832
|
+
} from "@unifold/core";
|
|
7833
|
+
function useSupportedDepositTokens(publishableKey, options) {
|
|
7834
|
+
const hasDestination = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type;
|
|
7835
|
+
const filteredOptions = {
|
|
7836
|
+
...hasDestination ? {
|
|
7837
|
+
destination_token_address: options.destination_token_address,
|
|
7838
|
+
destination_chain_id: options.destination_chain_id,
|
|
7839
|
+
destination_chain_type: options.destination_chain_type
|
|
7840
|
+
} : {},
|
|
7841
|
+
...options?.product_type ? { product_type: options.product_type } : {}
|
|
7842
|
+
};
|
|
7843
|
+
const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
|
|
7844
|
+
return useQuery5({
|
|
7845
|
+
queryKey: [
|
|
7846
|
+
"unifold",
|
|
7847
|
+
"supportedDepositTokens",
|
|
7848
|
+
publishableKey,
|
|
7849
|
+
filteredOptions?.destination_token_address ?? null,
|
|
7850
|
+
filteredOptions?.destination_chain_id ?? null,
|
|
7851
|
+
filteredOptions?.destination_chain_type ?? null,
|
|
7852
|
+
filteredOptions?.product_type ?? null
|
|
7853
|
+
],
|
|
7854
|
+
queryFn: () => getSupportedDepositTokens(
|
|
7855
|
+
publishableKey,
|
|
7856
|
+
hasFilteredOptions ? filteredOptions : void 0
|
|
7857
|
+
),
|
|
7858
|
+
staleTime: 1e3 * 60 * 5,
|
|
7859
|
+
// 5 minutes — token list rarely changes
|
|
7860
|
+
gcTime: 1e3 * 60 * 30,
|
|
7861
|
+
// 30 minutes in cache
|
|
7862
|
+
refetchOnMount: false,
|
|
7863
|
+
refetchOnWindowFocus: false
|
|
7864
|
+
});
|
|
7865
|
+
}
|
|
7866
|
+
|
|
7867
|
+
// src/hooks/use-integration-transfer-default-token.ts
|
|
7868
|
+
import { useQuery as useQuery6 } from "@tanstack/react-query";
|
|
7869
|
+
import {
|
|
7870
|
+
getIntegrationTransferDefaultToken
|
|
7871
|
+
} from "@unifold/core";
|
|
7872
|
+
function useIntegrationTransferDefaultToken({
|
|
7873
|
+
params,
|
|
7874
|
+
publishableKey,
|
|
7875
|
+
enabled = true
|
|
7876
|
+
}) {
|
|
7877
|
+
return useQuery6({
|
|
7878
|
+
queryKey: [
|
|
7879
|
+
"unifold",
|
|
7880
|
+
"integrationTransferDefaultToken",
|
|
7881
|
+
publishableKey,
|
|
7882
|
+
params?.integration_provider ?? null,
|
|
7883
|
+
params?.source_currency ?? null,
|
|
7884
|
+
params?.destination_token_address ?? null,
|
|
7885
|
+
params?.destination_chain_id ?? null,
|
|
7886
|
+
params?.destination_chain_type ?? null,
|
|
7887
|
+
params?.country_code ?? null,
|
|
7888
|
+
params?.subdivision_code ?? null
|
|
7889
|
+
],
|
|
7890
|
+
queryFn: () => getIntegrationTransferDefaultToken(params, publishableKey),
|
|
7891
|
+
enabled: enabled && !!params,
|
|
7892
|
+
staleTime: 1e3 * 60 * 5,
|
|
7893
|
+
gcTime: 1e3 * 60 * 30,
|
|
7894
|
+
refetchOnMount: false,
|
|
7895
|
+
refetchOnWindowFocus: false
|
|
7896
|
+
});
|
|
7897
|
+
}
|
|
7898
|
+
|
|
7781
7899
|
// src/lib/integrations.ts
|
|
7782
7900
|
var INTEGRATIONS_STORAGE_KEY = "unifold:integrations:connected";
|
|
7783
7901
|
function getStoredIntegrations() {
|
|
@@ -7826,6 +7944,23 @@ function CoinbaseConnect({
|
|
|
7826
7944
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7827
7945
|
const { projectConfig } = useProjectConfig({ publishableKey });
|
|
7828
7946
|
const { userIpInfo } = useUserIp();
|
|
7947
|
+
const { data: supportedTokensData, isLoading: supportedTokensLoading } = useSupportedDepositTokens(publishableKey, {
|
|
7948
|
+
destination_token_address: destinationTokenAddress,
|
|
7949
|
+
destination_chain_id: destinationChainId,
|
|
7950
|
+
destination_chain_type: destinationChainType
|
|
7951
|
+
});
|
|
7952
|
+
const supportedSymbols = useMemo3(() => {
|
|
7953
|
+
const set = /* @__PURE__ */ new Set();
|
|
7954
|
+
supportedTokensData?.data.forEach((token) => set.add(token.symbol.toLowerCase()));
|
|
7955
|
+
return set;
|
|
7956
|
+
}, [supportedTokensData]);
|
|
7957
|
+
const stablecoinSymbols = useMemo3(() => {
|
|
7958
|
+
const set = /* @__PURE__ */ new Set();
|
|
7959
|
+
supportedTokensData?.data.forEach((token) => {
|
|
7960
|
+
if (token.is_stablecoin) set.add(token.symbol.toLowerCase());
|
|
7961
|
+
});
|
|
7962
|
+
return set;
|
|
7963
|
+
}, [supportedTokensData]);
|
|
7829
7964
|
const appName = projectConfig?.project_name ?? "Unifold";
|
|
7830
7965
|
const t12 = i18n.connectExchange;
|
|
7831
7966
|
const initialView = skipToHoldings && getStoredIntegrationToken(IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
|
|
@@ -7848,7 +7983,43 @@ function CoinbaseConnect({
|
|
|
7848
7983
|
const [confirmResult, setConfirmResult] = useState20(null);
|
|
7849
7984
|
const [showTransferDetails, setShowTransferDetails] = useState20(false);
|
|
7850
7985
|
const [transferDepositWalletId, setTransferDepositWalletId] = useState20(void 0);
|
|
7851
|
-
const
|
|
7986
|
+
const exchangeSupportedCurrencies = useMemo3(() => {
|
|
7987
|
+
const set = /* @__PURE__ */ new Set();
|
|
7988
|
+
selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
|
|
7989
|
+
return set;
|
|
7990
|
+
}, [selectedExchange]);
|
|
7991
|
+
const defaultTokenParams = useMemo3(
|
|
7992
|
+
() => selectedAsset ? {
|
|
7993
|
+
integration_provider: IntegrationProvider.COINBASE,
|
|
7994
|
+
source_currency: selectedAsset.currency.toLowerCase(),
|
|
7995
|
+
destination_token_address: destinationTokenAddress,
|
|
7996
|
+
destination_chain_id: destinationChainId,
|
|
7997
|
+
destination_chain_type: destinationChainType,
|
|
7998
|
+
country_code: userIpInfo?.alpha2,
|
|
7999
|
+
subdivision_code: userIpInfo?.subdivisionCode ?? void 0
|
|
8000
|
+
} : null,
|
|
8001
|
+
[selectedAsset, destinationTokenAddress, destinationChainId, destinationChainType, userIpInfo?.alpha2, userIpInfo?.subdivisionCode]
|
|
8002
|
+
);
|
|
8003
|
+
const { data: defaultTokenData, isLoading: defaultTokenLoading } = useIntegrationTransferDefaultToken({
|
|
8004
|
+
params: defaultTokenParams,
|
|
8005
|
+
publishableKey
|
|
8006
|
+
});
|
|
8007
|
+
const sortedHoldings = useMemo3(() => {
|
|
8008
|
+
const supported = [];
|
|
8009
|
+
const unsupported = [];
|
|
8010
|
+
holdings.forEach((account) => {
|
|
8011
|
+
const currencyLower = account.currency.toLowerCase();
|
|
8012
|
+
const isSupported = (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
|
|
8013
|
+
if (isSupported) supported.push(account);
|
|
8014
|
+
else unsupported.push(account);
|
|
8015
|
+
});
|
|
8016
|
+
return [...supported, ...unsupported];
|
|
8017
|
+
}, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
|
|
8018
|
+
const selectedHoldingIsSupported = useMemo3(() => {
|
|
8019
|
+
if (!selectedHolding) return false;
|
|
8020
|
+
const currencyLower = selectedHolding.currency.toLowerCase();
|
|
8021
|
+
return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
|
|
8022
|
+
}, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
|
|
7852
8023
|
const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
|
|
7853
8024
|
const {
|
|
7854
8025
|
executions: depositExecutions,
|
|
@@ -7964,53 +8135,17 @@ function CoinbaseConnect({
|
|
|
7964
8135
|
if (pollRef.current) clearInterval(pollRef.current);
|
|
7965
8136
|
};
|
|
7966
8137
|
}, []);
|
|
7967
|
-
|
|
7968
|
-
if (
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
destination_chain_id: destinationChainId,
|
|
7979
|
-
destination_chain_type: destinationChainType,
|
|
7980
|
-
country_code: userIpInfo?.alpha2,
|
|
7981
|
-
subdivision_code: userIpInfo?.subdivisionCode ?? void 0
|
|
7982
|
-
},
|
|
7983
|
-
publishableKey
|
|
7984
|
-
),
|
|
7985
|
-
getSupportedDepositTokens(publishableKey, {
|
|
7986
|
-
destination_token_address: destinationTokenAddress,
|
|
7987
|
-
destination_chain_id: destinationChainId,
|
|
7988
|
-
destination_chain_type: destinationChainType
|
|
7989
|
-
})
|
|
7990
|
-
]);
|
|
7991
|
-
if (cancelled) return;
|
|
7992
|
-
const supportedToken = supportedTokens.data.find(
|
|
7993
|
-
(t13) => t13.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
7994
|
-
);
|
|
7995
|
-
if (supportedToken && supportedToken.chains.length > 0) {
|
|
7996
|
-
const matchingChain = supportedToken.chains.find(
|
|
7997
|
-
(c) => c.chain_name.toLowerCase() === defaultToken.source_network.toLowerCase()
|
|
7998
|
-
);
|
|
7999
|
-
setMinDepositUsd(
|
|
8000
|
-
matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd))
|
|
8001
|
-
);
|
|
8002
|
-
} else {
|
|
8003
|
-
setMinDepositUsd(0);
|
|
8004
|
-
}
|
|
8005
|
-
} catch {
|
|
8006
|
-
if (!cancelled) setMinDepositUsd(0);
|
|
8007
|
-
}
|
|
8008
|
-
};
|
|
8009
|
-
fetchMinDeposit();
|
|
8010
|
-
return () => {
|
|
8011
|
-
cancelled = true;
|
|
8012
|
-
};
|
|
8013
|
-
}, [view, selectedAsset, publishableKey, destinationTokenAddress, destinationChainId, destinationChainType, userIpInfo?.alpha2, userIpInfo?.subdivisionCode]);
|
|
8138
|
+
const minDepositUsd = useMemo3(() => {
|
|
8139
|
+
if (!selectedAsset || !defaultTokenData) return 0;
|
|
8140
|
+
const supportedToken = supportedTokensData?.data.find(
|
|
8141
|
+
(t13) => t13.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
8142
|
+
);
|
|
8143
|
+
if (!supportedToken || supportedToken.chains.length === 0) return 0;
|
|
8144
|
+
const matchingChain = supportedToken.chains.find(
|
|
8145
|
+
(c) => c.chain_name.toLowerCase() === defaultTokenData.source_network.toLowerCase()
|
|
8146
|
+
);
|
|
8147
|
+
return matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd));
|
|
8148
|
+
}, [selectedAsset, supportedTokensData, defaultTokenData]);
|
|
8014
8149
|
const handleSelectExchange = (exchange) => {
|
|
8015
8150
|
if (!exchange.enabled) return;
|
|
8016
8151
|
setSelectedExchange(exchange);
|
|
@@ -8055,7 +8190,6 @@ function CoinbaseConnect({
|
|
|
8055
8190
|
const handleSelectAsset = (asset) => {
|
|
8056
8191
|
setSelectedAsset(asset);
|
|
8057
8192
|
setSendAmount("");
|
|
8058
|
-
setMinDepositUsd(0);
|
|
8059
8193
|
transitionTo("enter_amount");
|
|
8060
8194
|
};
|
|
8061
8195
|
const handleCreateTransfer = async () => {
|
|
@@ -8067,18 +8201,10 @@ function CoinbaseConnect({
|
|
|
8067
8201
|
const cryptoAmount = (usdAmount / rate).toFixed(8);
|
|
8068
8202
|
setIsLoading(true);
|
|
8069
8203
|
try {
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
destination_token_address: destinationTokenAddress,
|
|
8075
|
-
destination_chain_id: destinationChainId,
|
|
8076
|
-
destination_chain_type: destinationChainType,
|
|
8077
|
-
country_code: userIpInfo?.alpha2,
|
|
8078
|
-
subdivision_code: userIpInfo?.subdivisionCode ?? void 0
|
|
8079
|
-
},
|
|
8080
|
-
publishableKey
|
|
8081
|
-
);
|
|
8204
|
+
if (!defaultTokenData) {
|
|
8205
|
+
throw new Error("Transfer details not ready. Please try again.");
|
|
8206
|
+
}
|
|
8207
|
+
const { source_network, source_chain_type } = defaultTokenData;
|
|
8082
8208
|
const matchingWallet = wallets.find((w) => w.chain_type === source_chain_type);
|
|
8083
8209
|
const depositAddress = matchingWallet?.address ?? recipientAddress ?? "";
|
|
8084
8210
|
if (!depositAddress) {
|
|
@@ -8230,13 +8356,12 @@ function CoinbaseConnect({
|
|
|
8230
8356
|
break;
|
|
8231
8357
|
}
|
|
8232
8358
|
};
|
|
8233
|
-
const STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USDT", "DAI", "BUSD", "TUSD", "USDP", "GUSD", "FRAX", "LUSD", "PYUSD", "EURC", "USDS"]);
|
|
8234
8359
|
const formatCryptoAmount = (amount, currency) => {
|
|
8235
8360
|
const num = parseFloat(amount);
|
|
8236
8361
|
if (isNaN(num)) return `${amount} ${currency.toUpperCase()}`;
|
|
8237
|
-
const isStable =
|
|
8238
|
-
const maxDecimals = isStable ? 2 :
|
|
8239
|
-
return `${num.toLocaleString(void 0, { minimumFractionDigits:
|
|
8362
|
+
const isStable = stablecoinSymbols.has(currency.toLowerCase());
|
|
8363
|
+
const maxDecimals = isStable ? 2 : 6;
|
|
8364
|
+
return `${num.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: maxDecimals })} ${currency.toUpperCase()}`;
|
|
8240
8365
|
};
|
|
8241
8366
|
const viewTransitionStyle = {
|
|
8242
8367
|
opacity: isTransitioning ? 0 : 1,
|
|
@@ -8838,7 +8963,7 @@ function CoinbaseConnect({
|
|
|
8838
8963
|
className: "uf-w-6 uf-h-6 uf-animate-spin",
|
|
8839
8964
|
style: { color: colors2.foregroundMuted }
|
|
8840
8965
|
}
|
|
8841
|
-
) }) :
|
|
8966
|
+
) }) : sortedHoldings.length === 0 ? /* @__PURE__ */ jsx37("div", { className: "uf-text-center uf-py-8", children: /* @__PURE__ */ jsx37(
|
|
8842
8967
|
"div",
|
|
8843
8968
|
{
|
|
8844
8969
|
className: "uf-text-sm",
|
|
@@ -8848,17 +8973,19 @@ function CoinbaseConnect({
|
|
|
8848
8973
|
},
|
|
8849
8974
|
children: "No holdings found"
|
|
8850
8975
|
}
|
|
8851
|
-
) }) :
|
|
8976
|
+
) }) : sortedHoldings.map((account) => {
|
|
8852
8977
|
const iconUrl = account.icon_urls?.find((u) => u.format === "svg")?.url || account.icon_urls?.find((u) => u.format === "png")?.url || account.icon_url;
|
|
8853
|
-
const
|
|
8978
|
+
const currencyLower = account.currency.toLowerCase();
|
|
8979
|
+
const isSupported = (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
|
|
8980
|
+
const isSelected = isSupported && selectedHolding?.id === account.id;
|
|
8854
8981
|
const usdValue = account.amount_usd ? parseFloat(account.amount_usd) : null;
|
|
8855
|
-
const formattedUsd = usdValue != null && usdValue
|
|
8982
|
+
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";
|
|
8856
8983
|
return /* @__PURE__ */ jsxs33(
|
|
8857
8984
|
"button",
|
|
8858
8985
|
{
|
|
8859
8986
|
onClick: () => setSelectedHolding(account),
|
|
8860
|
-
disabled: isLoading,
|
|
8861
|
-
className:
|
|
8987
|
+
disabled: isLoading || !isSupported,
|
|
8988
|
+
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" : ""}`,
|
|
8862
8989
|
style: {
|
|
8863
8990
|
backgroundColor: isSelected ? colors2.primary + "20" : components.card.backgroundColor,
|
|
8864
8991
|
borderRadius: components.list.rowBorderRadius,
|
|
@@ -8948,9 +9075,9 @@ function CoinbaseConnect({
|
|
|
8948
9075
|
"button",
|
|
8949
9076
|
{
|
|
8950
9077
|
onClick: () => {
|
|
8951
|
-
if (selectedHolding) handleSelectAsset(selectedHolding);
|
|
9078
|
+
if (selectedHolding && selectedHoldingIsSupported) handleSelectAsset(selectedHolding);
|
|
8952
9079
|
},
|
|
8953
|
-
disabled: !selectedHolding || isLoading,
|
|
9080
|
+
disabled: !selectedHolding || isLoading || supportedTokensLoading || exchangesLoading || !selectedHoldingIsSupported,
|
|
8954
9081
|
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",
|
|
8955
9082
|
style: {
|
|
8956
9083
|
backgroundColor: colors2.primary,
|
|
@@ -8974,22 +9101,16 @@ function CoinbaseConnect({
|
|
|
8974
9101
|
const isValidAmount = inputUsdNum > 0 && (maxUsdAmount == null || inputUsdNum <= maxUsdAmount) && inputUsdNum >= minDepositUsd;
|
|
8975
9102
|
const displayValue = sendAmount || "0";
|
|
8976
9103
|
const formattedBalance = formatCryptoAmount(selectedAsset.amount, selectedAsset.currency);
|
|
8977
|
-
const
|
|
9104
|
+
const balanceSubtitle = maxUsdAmount != null && maxUsdAmount > 0 ? `Balance: $${maxUsdAmount.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (${formattedBalance})` : `Balance: ${formattedBalance}`;
|
|
8978
9105
|
return /* @__PURE__ */ jsxs33(Fragment4, { children: [
|
|
8979
9106
|
/* @__PURE__ */ jsx37(
|
|
8980
9107
|
DepositHeader,
|
|
8981
9108
|
{
|
|
8982
9109
|
title: "Enter Amount",
|
|
9110
|
+
subtitle: balanceSubtitle,
|
|
8983
9111
|
showBack: true,
|
|
8984
9112
|
onBack: handleBack,
|
|
8985
|
-
onClose
|
|
8986
|
-
showBalance: true,
|
|
8987
|
-
balanceAddress: recipientAddress,
|
|
8988
|
-
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
|
|
8989
|
-
balanceChainId: destinationChainId,
|
|
8990
|
-
balanceTokenAddress: destinationTokenAddress,
|
|
8991
|
-
projectName: projectConfig?.project_name,
|
|
8992
|
-
publishableKey
|
|
9113
|
+
onClose
|
|
8993
9114
|
}
|
|
8994
9115
|
),
|
|
8995
9116
|
/* @__PURE__ */ jsxs33("div", { className: "uf-flex uf-flex-col uf-pb-4", style: viewTransitionStyle, children: [
|
|
@@ -9111,7 +9232,7 @@ function CoinbaseConnect({
|
|
|
9111
9232
|
"button",
|
|
9112
9233
|
{
|
|
9113
9234
|
onClick: handleCreateTransfer,
|
|
9114
|
-
disabled: !isValidAmount || isLoading,
|
|
9235
|
+
disabled: !isValidAmount || isLoading || defaultTokenLoading || !defaultTokenData,
|
|
9115
9236
|
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",
|
|
9116
9237
|
style: {
|
|
9117
9238
|
backgroundColor: colors2.primary,
|
|
@@ -9120,7 +9241,7 @@ function CoinbaseConnect({
|
|
|
9120
9241
|
borderRadius: components.button.borderRadius,
|
|
9121
9242
|
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
9122
9243
|
},
|
|
9123
|
-
children: isLoading ? /* @__PURE__ */ jsx37(Loader24, { className: "uf-w-4 uf-h-4 uf-animate-spin" }) : "Review"
|
|
9244
|
+
children: isLoading || defaultTokenLoading ? /* @__PURE__ */ jsx37(Loader24, { className: "uf-w-4 uf-h-4 uf-animate-spin" }) : "Review"
|
|
9124
9245
|
}
|
|
9125
9246
|
)
|
|
9126
9247
|
] })
|
|
@@ -9589,13 +9710,13 @@ function CoinbaseConnect({
|
|
|
9589
9710
|
CoinbaseConnect.displayName = "CoinbaseConnect";
|
|
9590
9711
|
|
|
9591
9712
|
// src/hooks/use-exchanges.ts
|
|
9592
|
-
import { useQuery as
|
|
9713
|
+
import { useQuery as useQuery7 } from "@tanstack/react-query";
|
|
9593
9714
|
import { getExchanges } from "@unifold/core";
|
|
9594
9715
|
function useExchanges({
|
|
9595
9716
|
publishableKey,
|
|
9596
9717
|
enabled = true
|
|
9597
9718
|
}) {
|
|
9598
|
-
const { data: exchanges = [], isLoading } =
|
|
9719
|
+
const { data: exchanges = [], isLoading } = useQuery7({
|
|
9599
9720
|
queryKey: ["unifold", "exchanges", publishableKey],
|
|
9600
9721
|
queryFn: () => getExchanges(void 0, publishableKey).then((res) => res.data),
|
|
9601
9722
|
enabled,
|
|
@@ -9607,7 +9728,7 @@ function useExchanges({
|
|
|
9607
9728
|
}
|
|
9608
9729
|
|
|
9609
9730
|
// src/hooks/use-default-onramp-token.ts
|
|
9610
|
-
import { useQuery as
|
|
9731
|
+
import { useQuery as useQuery8 } from "@tanstack/react-query";
|
|
9611
9732
|
import {
|
|
9612
9733
|
getDefaultOnrampToken as getDefaultOnrampToken2
|
|
9613
9734
|
} from "@unifold/core";
|
|
@@ -9620,7 +9741,7 @@ function useDefaultOnrampToken({
|
|
|
9620
9741
|
subdivisionCode,
|
|
9621
9742
|
enabled = true
|
|
9622
9743
|
}) {
|
|
9623
|
-
const { data: defaultToken, isLoading } =
|
|
9744
|
+
const { data: defaultToken, isLoading } = useQuery8({
|
|
9624
9745
|
queryKey: [
|
|
9625
9746
|
"unifold",
|
|
9626
9747
|
"defaultOnrampToken",
|
|
@@ -9655,12 +9776,13 @@ import {
|
|
|
9655
9776
|
getIntegrationExchanges as getIntegrationExchanges2,
|
|
9656
9777
|
getIntegrationHoldings as getIntegrationHoldings2,
|
|
9657
9778
|
refreshIntegrationToken as refreshIntegrationToken2,
|
|
9779
|
+
revokeIntegrationToken,
|
|
9658
9780
|
IntegrationProvider as IntegrationProvider2,
|
|
9659
9781
|
ActionType as ActionType3
|
|
9660
9782
|
} from "@unifold/core";
|
|
9661
9783
|
|
|
9662
9784
|
// src/hooks/use-allowed-country.ts
|
|
9663
|
-
import { useQuery as
|
|
9785
|
+
import { useQuery as useQuery9 } from "@tanstack/react-query";
|
|
9664
9786
|
import {
|
|
9665
9787
|
getIpAddress as getIpAddress2,
|
|
9666
9788
|
getProjectConfig as getProjectConfig2
|
|
@@ -9670,7 +9792,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
9670
9792
|
data: ipData,
|
|
9671
9793
|
isLoading: isIpLoading,
|
|
9672
9794
|
error: ipError
|
|
9673
|
-
} =
|
|
9795
|
+
} = useQuery9({
|
|
9674
9796
|
queryKey: ["unifold", "ipAddress"],
|
|
9675
9797
|
queryFn: () => getIpAddress2(),
|
|
9676
9798
|
refetchOnMount: false,
|
|
@@ -9685,7 +9807,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
9685
9807
|
data: configData,
|
|
9686
9808
|
isLoading: isConfigLoading,
|
|
9687
9809
|
error: configError
|
|
9688
|
-
} =
|
|
9810
|
+
} = useQuery9({
|
|
9689
9811
|
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
9690
9812
|
queryFn: () => getProjectConfig2(publishableKey),
|
|
9691
9813
|
refetchOnMount: false,
|
|
@@ -9728,7 +9850,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
9728
9850
|
}
|
|
9729
9851
|
|
|
9730
9852
|
// src/hooks/use-address-validation.ts
|
|
9731
|
-
import { useQuery as
|
|
9853
|
+
import { useQuery as useQuery10 } from "@tanstack/react-query";
|
|
9732
9854
|
import {
|
|
9733
9855
|
verifyRecipientAddress
|
|
9734
9856
|
} from "@unifold/core";
|
|
@@ -9742,7 +9864,7 @@ function useAddressValidation({
|
|
|
9742
9864
|
refetchOnMount = false
|
|
9743
9865
|
}) {
|
|
9744
9866
|
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
9745
|
-
const { data, isLoading, error } =
|
|
9867
|
+
const { data, isLoading, error } = useQuery10({
|
|
9746
9868
|
queryKey: [
|
|
9747
9869
|
"unifold",
|
|
9748
9870
|
"addressValidation",
|
|
@@ -9787,47 +9909,8 @@ function useAddressValidation({
|
|
|
9787
9909
|
};
|
|
9788
9910
|
}
|
|
9789
9911
|
|
|
9790
|
-
// src/hooks/use-supported-deposit-tokens.ts
|
|
9791
|
-
import { useQuery as useQuery9 } from "@tanstack/react-query";
|
|
9792
|
-
import {
|
|
9793
|
-
getSupportedDepositTokens as getSupportedDepositTokens2
|
|
9794
|
-
} from "@unifold/core";
|
|
9795
|
-
function useSupportedDepositTokens(publishableKey, options) {
|
|
9796
|
-
const hasDestination = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type;
|
|
9797
|
-
const filteredOptions = {
|
|
9798
|
-
...hasDestination ? {
|
|
9799
|
-
destination_token_address: options.destination_token_address,
|
|
9800
|
-
destination_chain_id: options.destination_chain_id,
|
|
9801
|
-
destination_chain_type: options.destination_chain_type
|
|
9802
|
-
} : {},
|
|
9803
|
-
...options?.product_type ? { product_type: options.product_type } : {}
|
|
9804
|
-
};
|
|
9805
|
-
const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
|
|
9806
|
-
return useQuery9({
|
|
9807
|
-
queryKey: [
|
|
9808
|
-
"unifold",
|
|
9809
|
-
"supportedDepositTokens",
|
|
9810
|
-
publishableKey,
|
|
9811
|
-
filteredOptions?.destination_token_address ?? null,
|
|
9812
|
-
filteredOptions?.destination_chain_id ?? null,
|
|
9813
|
-
filteredOptions?.destination_chain_type ?? null,
|
|
9814
|
-
filteredOptions?.product_type ?? null
|
|
9815
|
-
],
|
|
9816
|
-
queryFn: () => getSupportedDepositTokens2(
|
|
9817
|
-
publishableKey,
|
|
9818
|
-
hasFilteredOptions ? filteredOptions : void 0
|
|
9819
|
-
),
|
|
9820
|
-
staleTime: 1e3 * 60 * 5,
|
|
9821
|
-
// 5 minutes — token list rarely changes
|
|
9822
|
-
gcTime: 1e3 * 60 * 30,
|
|
9823
|
-
// 30 minutes in cache
|
|
9824
|
-
refetchOnMount: false,
|
|
9825
|
-
refetchOnWindowFocus: false
|
|
9826
|
-
});
|
|
9827
|
-
}
|
|
9828
|
-
|
|
9829
9912
|
// src/components/deposits/TransferCryptoSingleInput.tsx
|
|
9830
|
-
import { useState as useState26, useEffect as useEffect21, useMemo as
|
|
9913
|
+
import { useState as useState26, useEffect as useEffect21, useMemo as useMemo6 } from "react";
|
|
9831
9914
|
import {
|
|
9832
9915
|
ChevronDown as ChevronDown4,
|
|
9833
9916
|
ChevronUp as ChevronUp3,
|
|
@@ -10101,7 +10184,7 @@ function DepositsModal({
|
|
|
10101
10184
|
}
|
|
10102
10185
|
|
|
10103
10186
|
// src/components/deposits/TokenSelectorSheet.tsx
|
|
10104
|
-
import { useState as useState22, useMemo as
|
|
10187
|
+
import { useState as useState22, useMemo as useMemo5, useEffect as useEffect19 } from "react";
|
|
10105
10188
|
import { ArrowLeft as ArrowLeft2, X as X4 } from "lucide-react";
|
|
10106
10189
|
import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
10107
10190
|
var STORAGE_KEY = "unifold_recent_tokens";
|
|
@@ -10166,7 +10249,7 @@ function TokenSelectorSheet({
|
|
|
10166
10249
|
useEffect19(() => {
|
|
10167
10250
|
setRecentTokens(getRecentTokens());
|
|
10168
10251
|
}, []);
|
|
10169
|
-
const allOptions =
|
|
10252
|
+
const allOptions = useMemo5(() => {
|
|
10170
10253
|
const options = [];
|
|
10171
10254
|
tokens.forEach((token) => {
|
|
10172
10255
|
token.chains.forEach((chain) => {
|
|
@@ -10175,7 +10258,7 @@ function TokenSelectorSheet({
|
|
|
10175
10258
|
});
|
|
10176
10259
|
return options;
|
|
10177
10260
|
}, [tokens]);
|
|
10178
|
-
const quickSelectOptions =
|
|
10261
|
+
const quickSelectOptions = useMemo5(() => {
|
|
10179
10262
|
const result = [];
|
|
10180
10263
|
const seen = /* @__PURE__ */ new Set();
|
|
10181
10264
|
const addOption = (symbol, chainType, chainId, isRecent) => {
|
|
@@ -10207,7 +10290,7 @@ function TokenSelectorSheet({
|
|
|
10207
10290
|
});
|
|
10208
10291
|
setRecentTokens(updated);
|
|
10209
10292
|
};
|
|
10210
|
-
const filteredOptions =
|
|
10293
|
+
const filteredOptions = useMemo5(() => {
|
|
10211
10294
|
if (!searchQuery.trim()) return allOptions;
|
|
10212
10295
|
const query = searchQuery.toLowerCase();
|
|
10213
10296
|
return allOptions.filter(
|
|
@@ -10957,7 +11040,7 @@ import {
|
|
|
10957
11040
|
} from "@unifold/core";
|
|
10958
11041
|
|
|
10959
11042
|
// src/hooks/use-hypercore-activation.ts
|
|
10960
|
-
import { useQuery as
|
|
11043
|
+
import { useQuery as useQuery11 } from "@tanstack/react-query";
|
|
10961
11044
|
import {
|
|
10962
11045
|
checkHypercoreActivation
|
|
10963
11046
|
} from "@unifold/core";
|
|
@@ -10978,7 +11061,7 @@ function useHypercoreActivation(params) {
|
|
|
10978
11061
|
const recipient = recipientAddress?.trim() ?? "";
|
|
10979
11062
|
const source = sourceAddress?.trim() ?? "";
|
|
10980
11063
|
const hasAddresses = !!recipient && !!source;
|
|
10981
|
-
const { data, isLoading } =
|
|
11064
|
+
const { data, isLoading } = useQuery11({
|
|
10982
11065
|
queryKey: [
|
|
10983
11066
|
"unifold",
|
|
10984
11067
|
"hypercoreActivation",
|
|
@@ -11114,7 +11197,7 @@ function TransferCryptoSingleInput({
|
|
|
11114
11197
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
11115
11198
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
11116
11199
|
const error = walletsError?.message ?? null;
|
|
11117
|
-
const allAvailableChains =
|
|
11200
|
+
const allAvailableChains = useMemo6(() => {
|
|
11118
11201
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
11119
11202
|
supportedTokens.forEach((t12) => {
|
|
11120
11203
|
t12.chains.forEach((c) => {
|
|
@@ -11584,7 +11667,7 @@ function TransferCryptoSingleInput({
|
|
|
11584
11667
|
}
|
|
11585
11668
|
|
|
11586
11669
|
// src/components/deposits/TransferCryptoDoubleInput.tsx
|
|
11587
|
-
import { useState as useState27, useEffect as useEffect22, useMemo as
|
|
11670
|
+
import { useState as useState27, useEffect as useEffect22, useMemo as useMemo7 } from "react";
|
|
11588
11671
|
import {
|
|
11589
11672
|
ChevronDown as ChevronDown6,
|
|
11590
11673
|
ChevronUp as ChevronUp5,
|
|
@@ -11799,7 +11882,7 @@ function TransferCryptoDoubleInput({
|
|
|
11799
11882
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
11800
11883
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
11801
11884
|
const error = walletsError?.message ?? null;
|
|
11802
|
-
const allAvailableChains =
|
|
11885
|
+
const allAvailableChains = useMemo7(() => {
|
|
11803
11886
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
11804
11887
|
supportedTokens.forEach((t12) => {
|
|
11805
11888
|
t12.chains.forEach((c) => {
|
|
@@ -12210,13 +12293,13 @@ function TransferCryptoDoubleInput({
|
|
|
12210
12293
|
import * as React29 from "react";
|
|
12211
12294
|
import {
|
|
12212
12295
|
getAddressBalances as getAddressBalances2,
|
|
12213
|
-
getSupportedDepositTokens as
|
|
12296
|
+
getSupportedDepositTokens as getSupportedDepositTokens2,
|
|
12214
12297
|
buildSolanaTransaction,
|
|
12215
12298
|
sendSolanaTransaction as sendSolanaTransactionToBackend
|
|
12216
12299
|
} from "@unifold/core";
|
|
12217
12300
|
|
|
12218
12301
|
// src/hooks/use-deposit-quote.ts
|
|
12219
|
-
import { useQuery as
|
|
12302
|
+
import { useQuery as useQuery12 } from "@tanstack/react-query";
|
|
12220
12303
|
import {
|
|
12221
12304
|
getDepositQuote
|
|
12222
12305
|
} from "@unifold/core";
|
|
@@ -12245,7 +12328,7 @@ function useDepositQuote(params) {
|
|
|
12245
12328
|
...adjustForSlippage ? { adjust_for_slippage: true } : {},
|
|
12246
12329
|
...stablecoinParity ? { stablecoin_parity: true } : {}
|
|
12247
12330
|
};
|
|
12248
|
-
return
|
|
12331
|
+
return useQuery12({
|
|
12249
12332
|
queryKey: [
|
|
12250
12333
|
"unifold",
|
|
12251
12334
|
"depositQuote",
|
|
@@ -12364,7 +12447,7 @@ function SelectTokenView({
|
|
|
12364
12447
|
),
|
|
12365
12448
|
walletInfoProp ? /* @__PURE__ */ jsx50("div", { className: "uf-flex uf-w-full uf-justify-center uf-mb-6", children: /* @__PURE__ */ jsx50(WalletWithNetworkBadge, { walletInfo: walletInfoProp }) }) : null,
|
|
12366
12449
|
/* @__PURE__ */ jsxs43("div", { className: "uf-flex uf-min-h-0 uf-flex-1 uf-flex-col", children: [
|
|
12367
|
-
/* @__PURE__ */ jsx50("div", { className: "uf-h-[
|
|
12450
|
+
/* @__PURE__ */ jsx50("div", { className: "uf-h-[300px] uf-shrink-0 uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ jsx50("div", { className: "uf-space-y-2", children: isLoading ? /* @__PURE__ */ jsx50("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-12", children: /* @__PURE__ */ jsx50(
|
|
12368
12451
|
Loader25,
|
|
12369
12452
|
{
|
|
12370
12453
|
className: "uf-w-6 uf-h-6 uf-animate-spin",
|
|
@@ -13499,7 +13582,7 @@ function BrowserWalletModal({
|
|
|
13499
13582
|
destination_chain_type: depositWallet.destination_chain_type,
|
|
13500
13583
|
...productType ? { product_type: productType } : {}
|
|
13501
13584
|
};
|
|
13502
|
-
const response = await
|
|
13585
|
+
const response = await getSupportedDepositTokens2(
|
|
13503
13586
|
publishableKey,
|
|
13504
13587
|
options
|
|
13505
13588
|
);
|
|
@@ -14767,7 +14850,7 @@ function DepositModal({
|
|
|
14767
14850
|
depositTrackerSubTitle = t7.depositTracker.subtitle
|
|
14768
14851
|
}) {
|
|
14769
14852
|
const { colors: colors2, fonts, components } = useTheme();
|
|
14770
|
-
const effectiveInitialScreen =
|
|
14853
|
+
const effectiveInitialScreen = useMemo10(() => {
|
|
14771
14854
|
const s = initialScreen ?? "main";
|
|
14772
14855
|
if (s === "tracker" && hideDepositTracker) return "main";
|
|
14773
14856
|
if (s === "cashapp" && !enableCashApp) return "main";
|
|
@@ -14826,11 +14909,12 @@ function DepositModal({
|
|
|
14826
14909
|
return sum + (isNaN(usd) ? 0 : usd);
|
|
14827
14910
|
}, 0);
|
|
14828
14911
|
const balanceUsd = totalUsd > 0 ? totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : null;
|
|
14829
|
-
setConnectedExchange((prev) =>
|
|
14912
|
+
setConnectedExchange((prev) => prev ? { ...prev, balanceUsd, isLoading: false } : null);
|
|
14830
14913
|
};
|
|
14831
14914
|
getIntegrationHoldings2(IntegrationProvider2.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
|
|
14832
14915
|
try {
|
|
14833
14916
|
const refreshResult = await refreshIntegrationToken2(stored.access_token, publishableKey);
|
|
14917
|
+
if (!getStoredIntegrationToken(IntegrationProvider2.COINBASE)) return;
|
|
14834
14918
|
setStoredIntegrationToken({
|
|
14835
14919
|
integration_provider: IntegrationProvider2.COINBASE,
|
|
14836
14920
|
access_token: refreshResult.access_token,
|
|
@@ -14839,6 +14923,7 @@ function DepositModal({
|
|
|
14839
14923
|
const retryResult = await getIntegrationHoldings2(IntegrationProvider2.COINBASE, refreshResult.access_token, publishableKey);
|
|
14840
14924
|
processHoldings(retryResult);
|
|
14841
14925
|
} catch {
|
|
14926
|
+
if (!getStoredIntegrationToken(IntegrationProvider2.COINBASE)) return;
|
|
14842
14927
|
clearStoredIntegrationToken(IntegrationProvider2.COINBASE);
|
|
14843
14928
|
setConnectedExchange(null);
|
|
14844
14929
|
}
|
|
@@ -15006,6 +15091,14 @@ function DepositModal({
|
|
|
15006
15091
|
setBrowserWalletInfo(null);
|
|
15007
15092
|
setBrowserWalletModalOpen(false);
|
|
15008
15093
|
};
|
|
15094
|
+
const handleExchangeDisconnect = () => {
|
|
15095
|
+
const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
|
|
15096
|
+
if (stored) {
|
|
15097
|
+
revokeIntegrationToken(stored.access_token, publishableKey);
|
|
15098
|
+
}
|
|
15099
|
+
clearStoredIntegrationToken(IntegrationProvider2.COINBASE);
|
|
15100
|
+
setConnectedExchange(null);
|
|
15101
|
+
};
|
|
15009
15102
|
const handleClose = () => {
|
|
15010
15103
|
onOpenChange(false);
|
|
15011
15104
|
if (resetViewTimeoutRef.current) {
|
|
@@ -15211,6 +15304,7 @@ function DepositModal({
|
|
|
15211
15304
|
setCoinbaseSkipToHoldings(true);
|
|
15212
15305
|
setView("coinbase_connect");
|
|
15213
15306
|
},
|
|
15307
|
+
onDisconnect: handleExchangeDisconnect,
|
|
15214
15308
|
title: i18n.connectExchange.title,
|
|
15215
15309
|
subtitle: i18n.connectExchange.subtitle,
|
|
15216
15310
|
exchanges: integrationExchanges,
|
|
@@ -15415,34 +15509,37 @@ function DepositModal({
|
|
|
15415
15509
|
),
|
|
15416
15510
|
depositPoweredByFooter
|
|
15417
15511
|
] })
|
|
15418
|
-
] }) : view === "coinbase_connect" ? /* @__PURE__ */
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
|
|
15433
|
-
|
|
15434
|
-
|
|
15435
|
-
|
|
15436
|
-
|
|
15437
|
-
|
|
15438
|
-
|
|
15439
|
-
|
|
15440
|
-
|
|
15441
|
-
|
|
15442
|
-
|
|
15443
|
-
|
|
15444
|
-
|
|
15445
|
-
|
|
15512
|
+
] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
15513
|
+
/* @__PURE__ */ jsx56(
|
|
15514
|
+
CoinbaseConnect,
|
|
15515
|
+
{
|
|
15516
|
+
publishableKey,
|
|
15517
|
+
userId,
|
|
15518
|
+
wallets,
|
|
15519
|
+
recipientAddress,
|
|
15520
|
+
destinationTokenAddress: destinationTokenAddress ?? "",
|
|
15521
|
+
destinationChainId: destinationChainId ?? "",
|
|
15522
|
+
destinationChainType: destinationChainType ?? "",
|
|
15523
|
+
onTransferSuccess: (result) => {
|
|
15524
|
+
onDepositSuccess?.({
|
|
15525
|
+
message: "Transfer completed via Coinbase Connect",
|
|
15526
|
+
transaction: result
|
|
15527
|
+
});
|
|
15528
|
+
},
|
|
15529
|
+
onTransferError: (error) => {
|
|
15530
|
+
onDepositError?.({
|
|
15531
|
+
message: error.message,
|
|
15532
|
+
error
|
|
15533
|
+
});
|
|
15534
|
+
},
|
|
15535
|
+
onBack: handleBack,
|
|
15536
|
+
onClose: handleClose,
|
|
15537
|
+
skipToHoldings: coinbaseSkipToHoldings,
|
|
15538
|
+
onExecutionsChange: setDepositExecutions
|
|
15539
|
+
}
|
|
15540
|
+
),
|
|
15541
|
+
depositPoweredByFooter
|
|
15542
|
+
] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment12, { children: [
|
|
15446
15543
|
/* @__PURE__ */ jsx56(
|
|
15447
15544
|
DepositHeader,
|
|
15448
15545
|
{
|
|
@@ -15530,12 +15627,12 @@ import {
|
|
|
15530
15627
|
useLayoutEffect as useLayoutEffect3,
|
|
15531
15628
|
useCallback as useCallback7,
|
|
15532
15629
|
useRef as useRef9,
|
|
15533
|
-
useMemo as
|
|
15630
|
+
useMemo as useMemo11
|
|
15534
15631
|
} from "react";
|
|
15535
15632
|
import { AlertTriangle as AlertTriangle3, ChevronRight as ChevronRight15 } from "lucide-react";
|
|
15536
15633
|
|
|
15537
15634
|
// src/hooks/use-payment-intent.ts
|
|
15538
|
-
import { useQuery as
|
|
15635
|
+
import { useQuery as useQuery13 } from "@tanstack/react-query";
|
|
15539
15636
|
import { retrievePaymentIntent } from "@unifold/core";
|
|
15540
15637
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
15541
15638
|
"succeeded",
|
|
@@ -15550,7 +15647,7 @@ function usePaymentIntent(params) {
|
|
|
15550
15647
|
enabled = true,
|
|
15551
15648
|
pollingInterval = 3e3
|
|
15552
15649
|
} = params;
|
|
15553
|
-
return
|
|
15650
|
+
return useQuery13({
|
|
15554
15651
|
queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
|
|
15555
15652
|
queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
|
|
15556
15653
|
enabled: enabled && !!clientSecret && !!publishableKey,
|
|
@@ -15665,14 +15762,14 @@ function CheckoutModal({
|
|
|
15665
15762
|
});
|
|
15666
15763
|
}
|
|
15667
15764
|
}, [paymentIntent, onCheckoutSuccess, browserWalletModalOpen]);
|
|
15668
|
-
const wallets =
|
|
15765
|
+
const wallets = useMemo11(() => {
|
|
15669
15766
|
if (!paymentIntent) return [];
|
|
15670
15767
|
return mapDepositAddressesToWallets(
|
|
15671
15768
|
paymentIntent.deposit_addresses,
|
|
15672
15769
|
paymentIntent
|
|
15673
15770
|
);
|
|
15674
15771
|
}, [paymentIntent]);
|
|
15675
|
-
const formatCryptoAmount =
|
|
15772
|
+
const formatCryptoAmount = useMemo11(() => {
|
|
15676
15773
|
if (!paymentIntent) return (_) => "";
|
|
15677
15774
|
const decimals = paymentIntent.destination_token_decimals ?? 6;
|
|
15678
15775
|
const symbol = paymentIntent.currency.toUpperCase();
|
|
@@ -15682,7 +15779,7 @@ function CheckoutModal({
|
|
|
15682
15779
|
return `${formatted} ${symbol}`;
|
|
15683
15780
|
};
|
|
15684
15781
|
}, [paymentIntent]);
|
|
15685
|
-
const remainingAmountUsd =
|
|
15782
|
+
const remainingAmountUsd = useMemo11(() => {
|
|
15686
15783
|
if (!paymentIntent) return void 0;
|
|
15687
15784
|
const total = parseFloat(paymentIntent.destination_amount_usd || paymentIntent.amount_usd);
|
|
15688
15785
|
const received = parseFloat(paymentIntent.destination_amount_received_usd || paymentIntent.amount_received_usd);
|
|
@@ -15690,7 +15787,7 @@ function CheckoutModal({
|
|
|
15690
15787
|
const remaining = total - received;
|
|
15691
15788
|
return remaining > 0 ? remaining.toFixed(2) : "0.00";
|
|
15692
15789
|
}, [paymentIntent]);
|
|
15693
|
-
const remainingCrypto =
|
|
15790
|
+
const remainingCrypto = useMemo11(() => {
|
|
15694
15791
|
if (!paymentIntent) return void 0;
|
|
15695
15792
|
const total = BigInt(paymentIntent.destination_amount || paymentIntent.amount);
|
|
15696
15793
|
const received = BigInt(paymentIntent.destination_amount_received || paymentIntent.amount_received);
|
|
@@ -15698,7 +15795,7 @@ function CheckoutModal({
|
|
|
15698
15795
|
return remaining > 0n ? remaining.toString() : "0";
|
|
15699
15796
|
}, [paymentIntent]);
|
|
15700
15797
|
const [selectedSource, setSelectedSource] = useState32(null);
|
|
15701
|
-
const remainingDestinationAmount =
|
|
15798
|
+
const remainingDestinationAmount = useMemo11(() => {
|
|
15702
15799
|
if (!paymentIntent) return "0";
|
|
15703
15800
|
const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
|
|
15704
15801
|
return remaining > 0n ? remaining.toString() : "0";
|
|
@@ -15716,7 +15813,7 @@ function CheckoutModal({
|
|
|
15716
15813
|
stablecoinParity: paymentIntent?.stablecoin_parity ?? false,
|
|
15717
15814
|
enabled: open && view === "transfer" && !!paymentIntent && !!selectedSource && remainingDestinationAmount !== "0"
|
|
15718
15815
|
});
|
|
15719
|
-
const effectiveCheckoutQuote =
|
|
15816
|
+
const effectiveCheckoutQuote = useMemo11(() => {
|
|
15720
15817
|
if (!sourceQuote || !selectedSource) return null;
|
|
15721
15818
|
const baseQuote = {
|
|
15722
15819
|
sourceAmount: sourceQuote.source_amount,
|
|
@@ -16213,12 +16310,12 @@ import {
|
|
|
16213
16310
|
import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight17, Clock as Clock6 } from "lucide-react";
|
|
16214
16311
|
|
|
16215
16312
|
// src/hooks/use-supported-destination-tokens.ts
|
|
16216
|
-
import { useQuery as
|
|
16313
|
+
import { useQuery as useQuery14 } from "@tanstack/react-query";
|
|
16217
16314
|
import {
|
|
16218
16315
|
getSupportedDestinationTokens
|
|
16219
16316
|
} from "@unifold/core";
|
|
16220
16317
|
function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
16221
|
-
return
|
|
16318
|
+
return useQuery14({
|
|
16222
16319
|
queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
|
|
16223
16320
|
queryFn: () => getSupportedDestinationTokens(publishableKey),
|
|
16224
16321
|
staleTime: 1e3 * 60 * 5,
|
|
@@ -16247,8 +16344,8 @@ function useDefaultDestinationToken({
|
|
|
16247
16344
|
}
|
|
16248
16345
|
|
|
16249
16346
|
// src/hooks/use-source-token-validation.ts
|
|
16250
|
-
import { useQuery as
|
|
16251
|
-
import { getSupportedDepositTokens as
|
|
16347
|
+
import { useQuery as useQuery15 } from "@tanstack/react-query";
|
|
16348
|
+
import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
|
|
16252
16349
|
function useSourceTokenValidation(params) {
|
|
16253
16350
|
const {
|
|
16254
16351
|
sourceChainType,
|
|
@@ -16259,7 +16356,7 @@ function useSourceTokenValidation(params) {
|
|
|
16259
16356
|
enabled = true
|
|
16260
16357
|
} = params;
|
|
16261
16358
|
const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
|
|
16262
|
-
return
|
|
16359
|
+
return useQuery15({
|
|
16263
16360
|
queryKey: [
|
|
16264
16361
|
"unifold",
|
|
16265
16362
|
"sourceTokenValidation",
|
|
@@ -16269,7 +16366,7 @@ function useSourceTokenValidation(params) {
|
|
|
16269
16366
|
publishableKey
|
|
16270
16367
|
],
|
|
16271
16368
|
queryFn: async () => {
|
|
16272
|
-
const res = await
|
|
16369
|
+
const res = await getSupportedDepositTokens3(publishableKey);
|
|
16273
16370
|
let matchedMinUsd = null;
|
|
16274
16371
|
let matchedProcessingTime = null;
|
|
16275
16372
|
let matchedSlippage = null;
|
|
@@ -16307,7 +16404,7 @@ function useSourceTokenValidation(params) {
|
|
|
16307
16404
|
}
|
|
16308
16405
|
|
|
16309
16406
|
// src/hooks/use-address-balance.ts
|
|
16310
|
-
import { useQuery as
|
|
16407
|
+
import { useQuery as useQuery16 } from "@tanstack/react-query";
|
|
16311
16408
|
import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
|
|
16312
16409
|
function useAddressBalance(params) {
|
|
16313
16410
|
const {
|
|
@@ -16319,7 +16416,7 @@ function useAddressBalance(params) {
|
|
|
16319
16416
|
enabled = true
|
|
16320
16417
|
} = params;
|
|
16321
16418
|
const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
|
|
16322
|
-
return
|
|
16419
|
+
return useQuery16({
|
|
16323
16420
|
queryKey: [
|
|
16324
16421
|
"unifold",
|
|
16325
16422
|
"addressBalance",
|
|
@@ -16368,11 +16465,11 @@ function useAddressBalance(params) {
|
|
|
16368
16465
|
}
|
|
16369
16466
|
|
|
16370
16467
|
// src/hooks/use-executions.ts
|
|
16371
|
-
import { useQuery as
|
|
16468
|
+
import { useQuery as useQuery17 } from "@tanstack/react-query";
|
|
16372
16469
|
import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
|
|
16373
16470
|
function useExecutions(userId, publishableKey, options) {
|
|
16374
16471
|
const actionType = options?.actionType ?? ActionType4.Deposit;
|
|
16375
|
-
return
|
|
16472
|
+
return useQuery17({
|
|
16376
16473
|
queryKey: ["unifold", "executions", actionType, userId, publishableKey],
|
|
16377
16474
|
queryFn: () => queryExecutions4(userId, publishableKey, actionType),
|
|
16378
16475
|
enabled: (options?.enabled ?? true) && !!userId,
|
|
@@ -16658,7 +16755,7 @@ function WithdrawDoubleInput({
|
|
|
16658
16755
|
}
|
|
16659
16756
|
|
|
16660
16757
|
// src/components/withdrawals/WithdrawForm.tsx
|
|
16661
|
-
import { useState as useState34, useCallback as useCallback8, useMemo as
|
|
16758
|
+
import { useState as useState34, useCallback as useCallback8, useMemo as useMemo13, useEffect as useEffect29 } from "react";
|
|
16662
16759
|
import {
|
|
16663
16760
|
AlertTriangle as AlertTriangle4,
|
|
16664
16761
|
ArrowUpDown,
|
|
@@ -16676,7 +16773,7 @@ import {
|
|
|
16676
16773
|
} from "@unifold/core";
|
|
16677
16774
|
|
|
16678
16775
|
// src/hooks/use-verify-recipient-address.ts
|
|
16679
|
-
import { useQuery as
|
|
16776
|
+
import { useQuery as useQuery18 } from "@tanstack/react-query";
|
|
16680
16777
|
import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
|
|
16681
16778
|
function useVerifyRecipientAddress(params) {
|
|
16682
16779
|
const {
|
|
@@ -16689,7 +16786,7 @@ function useVerifyRecipientAddress(params) {
|
|
|
16689
16786
|
} = params;
|
|
16690
16787
|
const trimmedAddress = recipientAddress?.trim() || "";
|
|
16691
16788
|
const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
|
|
16692
|
-
return
|
|
16789
|
+
return useQuery18({
|
|
16693
16790
|
queryKey: [
|
|
16694
16791
|
"unifold",
|
|
16695
16792
|
"verifyRecipientAddress",
|
|
@@ -16968,11 +17065,11 @@ async function detectBrowserWallet(chainType, senderAddress) {
|
|
|
16968
17065
|
}
|
|
16969
17066
|
|
|
16970
17067
|
// src/hooks/use-hypercore-withdraw-activation.ts
|
|
16971
|
-
import { useMemo as
|
|
17068
|
+
import { useMemo as useMemo12 } from "react";
|
|
16972
17069
|
import { ActionType as ActionType6 } from "@unifold/core";
|
|
16973
17070
|
|
|
16974
17071
|
// src/hooks/use-get-deposit-address.ts
|
|
16975
|
-
import { useQuery as
|
|
17072
|
+
import { useQuery as useQuery19 } from "@tanstack/react-query";
|
|
16976
17073
|
import {
|
|
16977
17074
|
getDepositAddress
|
|
16978
17075
|
} from "@unifold/core";
|
|
@@ -16988,7 +17085,7 @@ function useGetDepositAddress(params) {
|
|
|
16988
17085
|
enabled = true
|
|
16989
17086
|
} = params;
|
|
16990
17087
|
const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
16991
|
-
return
|
|
17088
|
+
return useQuery19({
|
|
16992
17089
|
queryKey: [
|
|
16993
17090
|
"unifold",
|
|
16994
17091
|
"getDepositAddress",
|
|
@@ -17057,7 +17154,7 @@ function useHypercoreWithdrawActivation(params) {
|
|
|
17057
17154
|
actionType: ActionType6.Withdraw,
|
|
17058
17155
|
enabled: enabled && isHypercore(sourceChainId)
|
|
17059
17156
|
});
|
|
17060
|
-
const depositWalletAddress =
|
|
17157
|
+
const depositWalletAddress = useMemo12(() => {
|
|
17061
17158
|
const wallets = depositWalletLookup.data?.data ?? [];
|
|
17062
17159
|
return wallets.find((w) => w.chain_type === sourceChainType)?.address;
|
|
17063
17160
|
}, [depositWalletLookup.data, sourceChainType]);
|
|
@@ -17183,7 +17280,7 @@ function WithdrawForm({
|
|
|
17183
17280
|
enabled: debouncedAddress.length > 5 && !!selectedChain
|
|
17184
17281
|
});
|
|
17185
17282
|
const isDebouncing = trimmedAddress !== debouncedAddress;
|
|
17186
|
-
const addressError =
|
|
17283
|
+
const addressError = useMemo13(() => {
|
|
17187
17284
|
if (!trimmedAddress || trimmedAddress.length <= 5) return null;
|
|
17188
17285
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
17189
17286
|
if (verifyError) return t9.invalidAddress;
|
|
@@ -17209,33 +17306,33 @@ function WithdrawForm({
|
|
|
17209
17306
|
destinationTokenAddress: selectedChain?.token_address,
|
|
17210
17307
|
enabled: isAddressValid
|
|
17211
17308
|
});
|
|
17212
|
-
const exchangeRate =
|
|
17309
|
+
const exchangeRate = useMemo13(() => {
|
|
17213
17310
|
if (!balanceData?.exchangeRate) return 0;
|
|
17214
17311
|
return parseFloat(balanceData.exchangeRate);
|
|
17215
17312
|
}, [balanceData]);
|
|
17216
|
-
const balanceCrypto =
|
|
17313
|
+
const balanceCrypto = useMemo13(() => {
|
|
17217
17314
|
if (!balanceData?.balanceHuman) return 0;
|
|
17218
17315
|
return parseFloat(balanceData.balanceHuman);
|
|
17219
17316
|
}, [balanceData]);
|
|
17220
|
-
const balanceUsdNum =
|
|
17317
|
+
const balanceUsdNum = useMemo13(() => {
|
|
17221
17318
|
if (!balanceData?.balanceUsd) return 0;
|
|
17222
17319
|
return parseFloat(balanceData.balanceUsd);
|
|
17223
17320
|
}, [balanceData]);
|
|
17224
17321
|
const tokenSymbol = sourceTokenSymbol || balanceData?.symbol || "TOKEN";
|
|
17225
17322
|
const sourceDecimals = balanceData?.decimals ?? 6;
|
|
17226
|
-
const cryptoAmountFromInput =
|
|
17323
|
+
const cryptoAmountFromInput = useMemo13(() => {
|
|
17227
17324
|
const val = parseFloat(amount);
|
|
17228
17325
|
if (!val || val <= 0) return 0;
|
|
17229
17326
|
if (inputUnit === "crypto") return val;
|
|
17230
17327
|
return exchangeRate > 0 ? val / exchangeRate : 0;
|
|
17231
17328
|
}, [amount, inputUnit, exchangeRate]);
|
|
17232
|
-
const fiatAmountFromInput =
|
|
17329
|
+
const fiatAmountFromInput = useMemo13(() => {
|
|
17233
17330
|
const val = parseFloat(amount);
|
|
17234
17331
|
if (!val || val <= 0) return 0;
|
|
17235
17332
|
if (inputUnit === "fiat") return val;
|
|
17236
17333
|
return val * exchangeRate;
|
|
17237
17334
|
}, [amount, inputUnit, exchangeRate]);
|
|
17238
|
-
const convertedDisplay =
|
|
17335
|
+
const convertedDisplay = useMemo13(() => {
|
|
17239
17336
|
if (!amount || parseFloat(amount) <= 0) return null;
|
|
17240
17337
|
if (inputUnit === "crypto") {
|
|
17241
17338
|
return `$${fiatAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
@@ -17244,7 +17341,7 @@ function WithdrawForm({
|
|
|
17244
17341
|
const displayDecimals = isStablecoin ? 2 : 6;
|
|
17245
17342
|
return `${cryptoDisplay.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: displayDecimals })} ${tokenSymbol}`;
|
|
17246
17343
|
}, [amount, inputUnit, fiatAmountFromInput, cryptoAmountFromInput, balanceCrypto, balanceData, tokenSymbol, isMaxed, isStablecoin]);
|
|
17247
|
-
const balanceDisplay =
|
|
17344
|
+
const balanceDisplay = useMemo13(() => {
|
|
17248
17345
|
if (isLoadingBalance || !balanceData) return null;
|
|
17249
17346
|
if (inputUnit === "crypto") {
|
|
17250
17347
|
const displayDecimals = isStablecoin ? 2 : 6;
|
|
@@ -18226,7 +18323,7 @@ function WithdrawModal({
|
|
|
18226
18323
|
}
|
|
18227
18324
|
|
|
18228
18325
|
// src/components/withdrawals/WithdrawTokenSelector.tsx
|
|
18229
|
-
import { useState as useState37, useMemo as
|
|
18326
|
+
import { useState as useState37, useMemo as useMemo14 } from "react";
|
|
18230
18327
|
import { Search } from "lucide-react";
|
|
18231
18328
|
import { jsx as jsx63, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
18232
18329
|
var t11 = i18n.withdrawModal;
|
|
@@ -18238,7 +18335,7 @@ function WithdrawTokenSelector({
|
|
|
18238
18335
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
18239
18336
|
const [searchQuery, setSearchQuery] = useState37("");
|
|
18240
18337
|
const [hoveredKey, setHoveredKey] = useState37(null);
|
|
18241
|
-
const allOptions =
|
|
18338
|
+
const allOptions = useMemo14(() => {
|
|
18242
18339
|
const options = [];
|
|
18243
18340
|
tokens.forEach((token) => {
|
|
18244
18341
|
token.chains.forEach((chain) => {
|
|
@@ -18247,7 +18344,7 @@ function WithdrawTokenSelector({
|
|
|
18247
18344
|
});
|
|
18248
18345
|
return options;
|
|
18249
18346
|
}, [tokens]);
|
|
18250
|
-
const filteredOptions =
|
|
18347
|
+
const filteredOptions = useMemo14(() => {
|
|
18251
18348
|
if (!searchQuery.trim()) return allOptions;
|
|
18252
18349
|
const query = searchQuery.toLowerCase();
|
|
18253
18350
|
return allOptions.filter(
|