@cofhe/react 0.0.0-beta-20260420143138 → 0.0.0-beta-20260421071014

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.cjs CHANGED
@@ -800,7 +800,7 @@ __export(index_exports, {
800
800
  module.exports = __toCommonJS(index_exports);
801
801
 
802
802
  // src/providers/CofheProvider.tsx
803
- var import_react63 = require("react");
803
+ var import_react64 = require("react");
804
804
 
805
805
  // src/providers/QueryProvider.tsx
806
806
  var import_react_query = require("@tanstack/react-query");
@@ -840,6 +840,8 @@ var ETH_ADDRESS_LOWERCASE = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
840
840
  var TOKEN_CONFIDENTIALITY_SUPPORT = {
841
841
  wrapped: {
842
842
  enabled: true,
843
+ label: "Wrapped confidential token",
844
+ confidentialValueType: "uint128",
843
845
  publicBalanceSource: "erc20Pair",
844
846
  operations: {
845
847
  confidentialBalance: true,
@@ -853,6 +855,8 @@ var TOKEN_CONFIDENTIALITY_SUPPORT = {
853
855
  },
854
856
  pure: {
855
857
  enabled: false,
858
+ label: "Pure confidential token",
859
+ confidentialValueType: "uint64",
856
860
  publicBalanceSource: null,
857
861
  operations: {
858
862
  confidentialBalance: false,
@@ -866,6 +870,8 @@ var TOKEN_CONFIDENTIALITY_SUPPORT = {
866
870
  },
867
871
  dual: {
868
872
  enabled: false,
873
+ label: "Dual-balance confidential token",
874
+ confidentialValueType: "uint64",
869
875
  publicBalanceSource: "token",
870
876
  operations: {
871
877
  confidentialBalance: false,
@@ -892,6 +898,13 @@ function getPublicBalanceSourceType(type) {
892
898
  if (!isTokenConfidentialityType(type)) return null;
893
899
  return TOKEN_CONFIDENTIALITY_SUPPORT[type].publicBalanceSource;
894
900
  }
901
+ function getTokenConfidentialityLabel(type) {
902
+ if (!isTokenConfidentialityType(type)) return null;
903
+ return TOKEN_CONFIDENTIALITY_SUPPORT[type].label;
904
+ }
905
+ function getTokenConfidentialValueType(type) {
906
+ return TOKEN_CONFIDENTIALITY_SUPPORT[type].confidentialValueType;
907
+ }
895
908
  function assertTokenOperationSupported(type, operation) {
896
909
  if (isTokenOperationSupported(type, operation)) return;
897
910
  throw new Error(`${operation} not supported for confidentialityType: ${type ?? "undefined"}`);
@@ -1738,6 +1751,31 @@ var wrappedErc20ApprovalContracts = {
1738
1751
  }
1739
1752
  };
1740
1753
  var WRAPPED_TOKEN_CONTRACTS = {
1754
+ detection: {
1755
+ abi: [
1756
+ {
1757
+ inputs: [
1758
+ {
1759
+ internalType: "address",
1760
+ name: "account",
1761
+ type: "address"
1762
+ }
1763
+ ],
1764
+ name: "encBalanceOf",
1765
+ outputs: [
1766
+ {
1767
+ internalType: "euint128",
1768
+ name: "",
1769
+ type: "uint256"
1770
+ }
1771
+ ],
1772
+ stateMutability: "view",
1773
+ type: "function"
1774
+ }
1775
+ ],
1776
+ functionName: "encBalanceOf",
1777
+ args: [import_viem4.zeroAddress]
1778
+ },
1741
1779
  confidentialBalance: {
1742
1780
  abi: [
1743
1781
  {
@@ -1889,6 +1927,15 @@ function getContractsForType(confidentialityType) {
1889
1927
  function getTokenContractConfig(confidentialityType) {
1890
1928
  return getContractsForType(confidentialityType).confidentialBalance;
1891
1929
  }
1930
+ function getSupportedTokenDetectionConfigs() {
1931
+ return TOKEN_CONFIDENTIALITY_TYPES.filter(
1932
+ (confidentialityType) => isSupportedTokenConfidentialityType(confidentialityType)
1933
+ ).map((confidentialityType) => ({
1934
+ confidentialityType,
1935
+ probe: getContractsForType(confidentialityType).detection,
1936
+ confidentialValueType: getTokenConfidentialValueType(confidentialityType)
1937
+ }));
1938
+ }
1892
1939
  function getTransferContractConfig(confidentialityType) {
1893
1940
  return getContractsForType(confidentialityType).confidentialTransfer;
1894
1941
  }
@@ -1937,10 +1984,225 @@ function getClaimableContractConfig(confidentialityType) {
1937
1984
  // src/hooks/useCofheTokenLists.ts
1938
1985
  var import_react_query3 = require("@tanstack/react-query");
1939
1986
  var import_react5 = require("react");
1987
+
1988
+ // src/stores/customTokensStore.ts
1989
+ var import_zustand2 = require("zustand");
1990
+ var import_middleware2 = require("zustand/middleware");
1991
+ var useCustomTokensStore = (0, import_zustand2.create)()(
1992
+ (0, import_middleware2.persist)(
1993
+ (set) => ({
1994
+ customTokensByChainId: {},
1995
+ addCustomToken: (token) => {
1996
+ set((state) => {
1997
+ const chainKey = token.chainId.toString();
1998
+ const existing = state.customTokensByChainId[chainKey] ?? [];
1999
+ const normalizedAddress = token.address.toLowerCase();
2000
+ return {
2001
+ customTokensByChainId: {
2002
+ ...state.customTokensByChainId,
2003
+ [chainKey]: [token, ...existing.filter((item) => item.address.toLowerCase() !== normalizedAddress)]
2004
+ }
2005
+ };
2006
+ });
2007
+ },
2008
+ removeCustomToken: ({ chainId, address }) => {
2009
+ set((state) => {
2010
+ const chainKey = chainId.toString();
2011
+ const existing = state.customTokensByChainId[chainKey] ?? [];
2012
+ const filtered = existing.filter((item) => item.address.toLowerCase() !== address.toLowerCase());
2013
+ if (filtered.length === existing.length) {
2014
+ return state;
2015
+ }
2016
+ const next = { ...state.customTokensByChainId };
2017
+ if (filtered.length === 0) {
2018
+ delete next[chainKey];
2019
+ } else {
2020
+ next[chainKey] = filtered;
2021
+ }
2022
+ return {
2023
+ customTokensByChainId: next
2024
+ };
2025
+ });
2026
+ }
2027
+ }),
2028
+ {
2029
+ name: "cofhesdk-react-custom-tokens",
2030
+ storage: (0, import_middleware2.createJSONStorage)(() => localStorage)
2031
+ }
2032
+ )
2033
+ );
2034
+
2035
+ // src/hooks/useResolvedCofheToken.ts
2036
+ var import_viem6 = require("viem");
2037
+
2038
+ // src/constants/erc20ABIs.ts
2039
+ var import_viem5 = require("viem");
2040
+ var ERC20_BALANCE_OF_ABI = (0, import_viem5.parseAbi)(["function balanceOf(address owner) view returns (uint256)"]);
2041
+ var ERC20_DECIMALS_ABI = (0, import_viem5.parseAbi)(["function decimals() view returns (uint8)"]);
2042
+ var ERC20_SYMBOL_ABI = (0, import_viem5.parseAbi)(["function symbol() view returns (string)"]);
2043
+ var ERC20_NAME_ABI = (0, import_viem5.parseAbi)(["function name() view returns (string)"]);
2044
+
2045
+ // src/hooks/useResolvedCofheToken.ts
2046
+ var SUPPORTED_TOKEN_DETECTION_CONFIGS = getSupportedTokenDetectionConfigs();
2047
+ var TOKEN_PAIR_GETTER_ABIS = {
2048
+ token: (0, import_viem6.parseAbi)(["function token() view returns (address)"]),
2049
+ underlying: (0, import_viem6.parseAbi)(["function underlying() view returns (address)"]),
2050
+ underlyingToken: (0, import_viem6.parseAbi)(["function underlyingToken() view returns (address)"]),
2051
+ asset: (0, import_viem6.parseAbi)(["function asset() view returns (address)"]),
2052
+ erc20: (0, import_viem6.parseAbi)(["function erc20() view returns (address)"]),
2053
+ erc20Token: (0, import_viem6.parseAbi)(["function erc20Token() view returns (address)"])
2054
+ };
2055
+ var PAIR_GETTER_ENTRIES = [
2056
+ ["token", TOKEN_PAIR_GETTER_ABIS.token],
2057
+ ["underlying", TOKEN_PAIR_GETTER_ABIS.underlying],
2058
+ ["underlyingToken", TOKEN_PAIR_GETTER_ABIS.underlyingToken],
2059
+ ["asset", TOKEN_PAIR_GETTER_ABIS.asset],
2060
+ ["erc20", TOKEN_PAIR_GETTER_ABIS.erc20],
2061
+ ["erc20Token", TOKEN_PAIR_GETTER_ABIS.erc20Token]
2062
+ ];
2063
+ function pickUnderlyingPairAddress(results, tokenAddress) {
2064
+ for (const result of results) {
2065
+ if (!result || typeof result !== "object") continue;
2066
+ const typedResult = result;
2067
+ if (typedResult.status !== "success") continue;
2068
+ const candidate = typedResult.result;
2069
+ if (typeof candidate !== "string" || !(0, import_viem6.isAddress)(candidate)) continue;
2070
+ if (candidate.toLowerCase() === import_viem6.zeroAddress) continue;
2071
+ if (candidate.toLowerCase() === tokenAddress.toLowerCase()) continue;
2072
+ return candidate;
2073
+ }
2074
+ return void 0;
2075
+ }
2076
+ function useResolvedCofheToken({ chainId: _chainId, address }, queryOptions) {
2077
+ const publicClient = useCofhePublicClient();
2078
+ const cofheChainId = useCofheChainId();
2079
+ const chainId = _chainId ?? cofheChainId;
2080
+ return useInternalQuery({
2081
+ queryKey: ["resolvedCofheToken", chainId, address?.toLowerCase()],
2082
+ queryFn: async () => {
2083
+ if (!publicClient) {
2084
+ throw new Error("PublicClient is required to resolve a token");
2085
+ }
2086
+ if (!chainId || !address) {
2087
+ return void 0;
2088
+ }
2089
+ const metadataResults = await publicClient.multicall({
2090
+ contracts: [
2091
+ {
2092
+ address,
2093
+ abi: ERC20_DECIMALS_ABI,
2094
+ functionName: "decimals"
2095
+ },
2096
+ {
2097
+ address,
2098
+ abi: ERC20_SYMBOL_ABI,
2099
+ functionName: "symbol"
2100
+ },
2101
+ {
2102
+ address,
2103
+ abi: ERC20_NAME_ABI,
2104
+ functionName: "name"
2105
+ }
2106
+ ]
2107
+ });
2108
+ const decimals = metadataResults[0].result;
2109
+ const symbol = metadataResults[1].result;
2110
+ const name = metadataResults[2].result;
2111
+ if (decimals == null || symbol == null || name == null) {
2112
+ throw new Error("Failed to fetch token metadata");
2113
+ }
2114
+ const [supportedType, pairGetterResults] = await Promise.all([
2115
+ Promise.all(
2116
+ SUPPORTED_TOKEN_DETECTION_CONFIGS.map(async (entry) => {
2117
+ const detected = await publicClient.readContract({
2118
+ address,
2119
+ abi: entry.probe.abi,
2120
+ functionName: entry.probe.functionName,
2121
+ args: entry.probe.args
2122
+ }).then(() => true).catch(() => false);
2123
+ return detected ? entry : null;
2124
+ })
2125
+ ).then((entries) => entries.find((entry) => entry != null) ?? null),
2126
+ publicClient.multicall({
2127
+ contracts: PAIR_GETTER_ENTRIES.map(([, abi]) => ({
2128
+ address,
2129
+ abi,
2130
+ functionName: abi[0].name
2131
+ })),
2132
+ allowFailure: true
2133
+ })
2134
+ ]);
2135
+ if (!supportedType) {
2136
+ throw new Error("Address is not a supported CoFHE token");
2137
+ }
2138
+ const confidentialityType = supportedType.confidentialityType;
2139
+ const extensions = {
2140
+ fhenix: {
2141
+ confidentialityType,
2142
+ confidentialValueType: supportedType.confidentialValueType
2143
+ }
2144
+ };
2145
+ if (confidentialityType === "wrapped") {
2146
+ const pairAddress = pickUnderlyingPairAddress(pairGetterResults, address);
2147
+ if (pairAddress) {
2148
+ if (pairAddress.toLowerCase() === ETH_ADDRESS_LOWERCASE) {
2149
+ extensions.fhenix.erc20Pair = {
2150
+ address: ETH_ADDRESS_LOWERCASE,
2151
+ symbol: "ETH",
2152
+ decimals: 18
2153
+ };
2154
+ } else {
2155
+ const pairMetadata = await publicClient.multicall({
2156
+ contracts: [
2157
+ {
2158
+ address: pairAddress,
2159
+ abi: ERC20_DECIMALS_ABI,
2160
+ functionName: "decimals"
2161
+ },
2162
+ {
2163
+ address: pairAddress,
2164
+ abi: ERC20_SYMBOL_ABI,
2165
+ functionName: "symbol"
2166
+ }
2167
+ ],
2168
+ allowFailure: true
2169
+ });
2170
+ const pairDecimals = pairMetadata[0]?.status === "success" ? pairMetadata[0].result : void 0;
2171
+ const pairSymbol = pairMetadata[1]?.status === "success" ? pairMetadata[1].result : void 0;
2172
+ if (pairDecimals != null && pairSymbol != null) {
2173
+ extensions.fhenix.erc20Pair = {
2174
+ address: pairAddress,
2175
+ symbol: pairSymbol,
2176
+ decimals: pairDecimals
2177
+ };
2178
+ }
2179
+ }
2180
+ }
2181
+ }
2182
+ return {
2183
+ chainId,
2184
+ address,
2185
+ decimals,
2186
+ symbol,
2187
+ name,
2188
+ extensions
2189
+ };
2190
+ },
2191
+ enabled: (queryOptions?.enabled ?? true) && !!publicClient && !!chainId && !!address,
2192
+ staleTime: Infinity,
2193
+ ...queryOptions
2194
+ });
2195
+ }
2196
+
2197
+ // src/hooks/useCofheTokenLists.ts
1940
2198
  function isSupportedToken(token) {
1941
2199
  const confidentialityType = token.extensions?.fhenix?.confidentialityType;
1942
2200
  return isSupportedTokenConfidentialityType(confidentialityType);
1943
2201
  }
2202
+ function getCustomTokensForChain(customTokensByChainId, chainId) {
2203
+ if (!chainId) return [];
2204
+ return customTokensByChainId[chainId.toString()] ?? [];
2205
+ }
1944
2206
  function useCofheTokenLists({ chainId }, queryOptions) {
1945
2207
  const widgetConfig = useCofheContext().client.config.react;
1946
2208
  const tokensListsUrls = chainId ? widgetConfig.tokenLists?.[chainId] : [];
@@ -1974,6 +2236,8 @@ function useCofheTokenLists({ chainId }, queryOptions) {
1974
2236
  }
1975
2237
  function useCofheTokens(chainId) {
1976
2238
  const tokenLists = useCofheTokenLists({ chainId });
2239
+ const customTokensByChainId = useCustomTokensStore((state) => state.customTokensByChainId);
2240
+ const customTokens = getCustomTokensForChain(customTokensByChainId, chainId);
1977
2241
  const tokens = (0, import_react5.useMemo)(() => {
1978
2242
  const map = /* @__PURE__ */ new Map();
1979
2243
  tokenLists.forEach((result) => {
@@ -1984,8 +2248,13 @@ function useCofheTokens(chainId) {
1984
2248
  map.set(key, token);
1985
2249
  });
1986
2250
  });
2251
+ customTokens.forEach((token) => {
2252
+ const key = `${token.chainId}-${token.address.toLowerCase()}`;
2253
+ if (map.has(key)) return;
2254
+ map.set(key, token);
2255
+ });
1987
2256
  return Array.from(map.values());
1988
- }, [tokenLists]);
2257
+ }, [customTokens, tokenLists]);
1989
2258
  return tokens;
1990
2259
  }
1991
2260
  function useCofheToken({ chainId: _chainId, address }, metdataQueryOptions) {
@@ -1996,21 +2265,22 @@ function useCofheToken({ chainId: _chainId, address }, metdataQueryOptions) {
1996
2265
  if (!address || !chainId) return;
1997
2266
  return tokens.find((t) => t.chainId === chainId && t.address.toLowerCase() === address.toLowerCase());
1998
2267
  }, [address, chainId, tokens]);
1999
- return tokenFromList;
2268
+ const resolvedToken = useResolvedCofheToken(
2269
+ {
2270
+ chainId,
2271
+ address
2272
+ },
2273
+ {
2274
+ ...metdataQueryOptions,
2275
+ enabled: (metdataQueryOptions?.enabled ?? true) && !!address && !!chainId && !tokenFromList
2276
+ }
2277
+ );
2278
+ return tokenFromList ?? resolvedToken.data;
2000
2279
  }
2001
2280
 
2002
2281
  // src/hooks/useCofheTokenPublicBalance.ts
2003
2282
  var import_react_query4 = require("@tanstack/react-query");
2004
- var import_viem6 = require("viem");
2005
-
2006
- // src/constants/erc20ABIs.ts
2007
- var import_viem5 = require("viem");
2008
- var ERC20_BALANCE_OF_ABI = (0, import_viem5.parseAbi)(["function balanceOf(address owner) view returns (uint256)"]);
2009
- var ERC20_DECIMALS_ABI = (0, import_viem5.parseAbi)(["function decimals() view returns (uint8)"]);
2010
- var ERC20_SYMBOL_ABI = (0, import_viem5.parseAbi)(["function symbol() view returns (string)"]);
2011
- var ERC20_NAME_ABI = (0, import_viem5.parseAbi)(["function name() view returns (string)"]);
2012
-
2013
- // src/hooks/useCofheTokenPublicBalance.ts
2283
+ var import_viem7 = require("viem");
2014
2284
  var import_ts_essentials2 = __toESM(require_dist(), 1);
2015
2285
 
2016
2286
  // src/utils/format.ts
@@ -2136,18 +2406,18 @@ function useCofheTokenPublicBalance({ token, accountAddress, displayDecimals = 5
2136
2406
 
2137
2407
  // src/hooks/useCofheTokenClaimable.ts
2138
2408
  var import_react_query6 = require("@tanstack/react-query");
2139
- var import_viem8 = require("viem");
2409
+ var import_viem9 = require("viem");
2140
2410
 
2141
2411
  // src/utils/decryptionAwareReadContract.ts
2142
2412
  var import_react_query5 = require("@tanstack/react-query");
2143
- var import_viem7 = require("viem");
2413
+ var import_viem8 = require("viem");
2144
2414
 
2145
2415
  // src/stores/decryptionWatchingStore.ts
2146
- var import_zustand2 = require("zustand");
2147
- var import_middleware2 = require("zustand/middleware");
2148
- var bigintStorage2 = (0, import_middleware2.createJSONStorage)(() => localStorage, bigintJSONStorageOptions);
2149
- var useDecryptionWatchersStore = (0, import_zustand2.create)()(
2150
- (0, import_middleware2.persist)(
2416
+ var import_zustand3 = require("zustand");
2417
+ var import_middleware3 = require("zustand/middleware");
2418
+ var bigintStorage2 = (0, import_middleware3.createJSONStorage)(() => localStorage, bigintJSONStorageOptions);
2419
+ var useDecryptionWatchersStore = (0, import_zustand3.create)()(
2420
+ (0, import_middleware3.persist)(
2151
2421
  (set, get) => ({
2152
2422
  byKey: {},
2153
2423
  upsert: (input) => {
@@ -2396,7 +2666,7 @@ function useCofheTokenClaimable({ accountAddress: account, token }, queryOptions
2396
2666
 
2397
2667
  // src/hooks/useTokenAllowance.ts
2398
2668
  var import_react_query7 = require("@tanstack/react-query");
2399
- var import_viem9 = require("viem");
2669
+ var import_viem10 = require("viem");
2400
2670
  var import_ts_essentials4 = __toESM(require_dist(), 1);
2401
2671
  function constructTokenAllowanceQueryKey({
2402
2672
  chainId,
@@ -2544,8 +2814,8 @@ function usePendingTransactions() {
2544
2814
  }
2545
2815
 
2546
2816
  // src/stores/portalModalStore.tsx
2547
- var import_zustand3 = require("zustand");
2548
- var usePortalModals = (0, import_zustand3.create)()((set, get) => ({
2817
+ var import_zustand4 = require("zustand");
2818
+ var usePortalModals = (0, import_zustand4.create)()((set, get) => ({
2549
2819
  modalStack: [],
2550
2820
  openModal: (...args) => {
2551
2821
  const [modal, props] = args;
@@ -2563,11 +2833,11 @@ var usePortalModals = (0, import_zustand3.create)()((set, get) => ({
2563
2833
 
2564
2834
  // src/stores/portalUIStore.tsx
2565
2835
  var import_react8 = require("react");
2566
- var import_zustand5 = require("zustand");
2836
+ var import_zustand6 = require("zustand");
2567
2837
 
2568
2838
  // src/stores/portalStatuses.tsx
2569
- var import_zustand4 = require("zustand");
2570
- var usePortalStatuses = (0, import_zustand4.create)()((set, get) => ({
2839
+ var import_zustand5 = require("zustand");
2840
+ var usePortalStatuses = (0, import_zustand5.create)()((set, get) => ({
2571
2841
  statuses: [],
2572
2842
  addStatus: (status) => {
2573
2843
  if (get().hasStatus(status.id)) return;
@@ -2585,7 +2855,7 @@ var usePortalStatuses = (0, import_zustand4.create)()((set, get) => ({
2585
2855
 
2586
2856
  // src/stores/portalUIStore.tsx
2587
2857
  var ANIM_DURATION = 300;
2588
- var usePortalUI = (0, import_zustand5.create)()((set, get) => ({
2858
+ var usePortalUI = (0, import_zustand6.create)()((set, get) => ({
2589
2859
  portalOpen: false,
2590
2860
  statusPanelOpen: false,
2591
2861
  contentPanelOpen: false,
@@ -2656,8 +2926,8 @@ var usePortalUIMaxContentHeight = () => {
2656
2926
  };
2657
2927
 
2658
2928
  // src/stores/portalNavigationStore.tsx
2659
- var import_zustand6 = require("zustand");
2660
- var usePortalNavigation = (0, import_zustand6.create)()((set, get) => {
2929
+ var import_zustand7 = require("zustand");
2930
+ var usePortalNavigation = (0, import_zustand7.create)()((set, get) => {
2661
2931
  function clearNavigationHistory() {
2662
2932
  set({ pageHistory: [{ page: "main" /* Main */ }], overridingPage: null });
2663
2933
  }
@@ -2885,9 +3155,9 @@ var ToastPrimitive = (props) => {
2885
3155
  };
2886
3156
 
2887
3157
  // src/stores/portalToasts.tsx
2888
- var import_zustand7 = require("zustand");
3158
+ var import_zustand8 = require("zustand");
2889
3159
  var import_jsx_runtime5 = require("react/jsx-runtime");
2890
- var usePortalToasts = (0, import_zustand7.create)()((set, get) => ({
3160
+ var usePortalToasts = (0, import_zustand8.create)()((set, get) => ({
2891
3161
  toasts: [],
2892
3162
  addToast: (toast, duration = 5e3) => {
2893
3163
  const content = isReactNode(toast) ? toast : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ToastPrimitive, { ...toast });
@@ -2927,7 +3197,7 @@ var usePortalToasts = (0, import_zustand7.create)()((set, get) => ({
2927
3197
  }));
2928
3198
 
2929
3199
  // src/hooks/useTransactionGlobalLifecycle.ts
2930
- var import_viem10 = require("viem");
3200
+ var import_viem11 = require("viem");
2931
3201
  var TOAST_DELAY_MS = 1e4;
2932
3202
  function useTransactionGlobalToastsLifecycle() {
2933
3203
  const { addToast } = usePortalToasts();
@@ -2950,8 +3220,8 @@ function useTransactionGlobalToastsLifecycle() {
2950
3220
  },
2951
3221
  onTransactionSubmitError: (error, transactionType) => {
2952
3222
  let humanReadableError;
2953
- if (error instanceof import_viem10.ContractFunctionExecutionError) {
2954
- if (error.cause instanceof import_viem10.ContractFunctionRevertedError) {
3223
+ if (error instanceof import_viem11.ContractFunctionExecutionError) {
3224
+ if (error.cause instanceof import_viem11.ContractFunctionRevertedError) {
2955
3225
  const reasonOfRevert = error.cause.raw;
2956
3226
  if (typeof reasonOfRevert === "string") {
2957
3227
  humanReadableError = cofheHumanizeRevertReason(reasonOfRevert);
@@ -3576,13 +3846,13 @@ var useCofheClient = () => {
3576
3846
 
3577
3847
  // src/hooks/useCofheTokenDecryptedBalance.ts
3578
3848
  var import_react_query10 = require("@tanstack/react-query");
3579
- var import_viem12 = require("viem");
3849
+ var import_viem13 = require("viem");
3580
3850
  var import_sdk6 = require("@cofhe/sdk");
3581
3851
  var import_ts_essentials10 = __toESM(require_dist(), 1);
3582
3852
 
3583
3853
  // src/hooks/useCofheReadContractAndDecrypt.ts
3584
3854
  var import_react_query9 = require("@tanstack/react-query");
3585
- var import_viem11 = require("viem");
3855
+ var import_viem12 = require("viem");
3586
3856
  var import_sdk5 = require("@cofhe/sdk");
3587
3857
 
3588
3858
  // src/hooks/useCofheDecrypt.ts
@@ -3695,7 +3965,7 @@ function useCofheTokenDecryptedBalance({ token, accountAddress, displayDecimals
3695
3965
  }
3696
3966
 
3697
3967
  // src/hooks/useCofheTokenTransfer.ts
3698
- var import_viem13 = require("viem");
3968
+ var import_viem14 = require("viem");
3699
3969
  var import_sdk9 = require("@cofhe/sdk");
3700
3970
 
3701
3971
  // src/hooks/useCofheEncryptAndWriteContract.ts
@@ -4005,7 +4275,7 @@ function useCofheTokenApprove(writeMutationOptions) {
4005
4275
 
4006
4276
  // src/hooks/useCofheTokenShield.ts
4007
4277
  var import_react_query11 = require("@tanstack/react-query");
4008
- var import_viem14 = require("viem");
4278
+ var import_viem15 = require("viem");
4009
4279
  var import_ts_essentials13 = __toESM(require_dist(), 1);
4010
4280
  function getCofheTokenShieldCallArgs(params) {
4011
4281
  const { token, amount, account } = params;
@@ -4131,7 +4401,7 @@ function useCofheTokenShield(options) {
4131
4401
 
4132
4402
  // src/hooks/useCofheTokenUnshield.ts
4133
4403
  var import_react_query12 = require("@tanstack/react-query");
4134
- var import_viem15 = require("viem");
4404
+ var import_viem16 = require("viem");
4135
4405
  var import_ts_essentials15 = __toESM(require_dist(), 1);
4136
4406
 
4137
4407
  // src/hooks/useStoredTransaction.ts
@@ -4325,7 +4595,7 @@ function useCofheTokenUnshield(input) {
4325
4595
 
4326
4596
  // src/hooks/useCofheTokenClaimUnshielded.ts
4327
4597
  var import_react_query13 = require("@tanstack/react-query");
4328
- var import_viem16 = require("viem");
4598
+ var import_viem17 = require("viem");
4329
4599
  var import_ts_essentials16 = __toESM(require_dist(), 1);
4330
4600
  function getCofheTokenClaimUnshieldedCallArgs(params) {
4331
4601
  const { token, account } = params;
@@ -4405,7 +4675,7 @@ function useCofheTokenClaimUnshielded(options) {
4405
4675
  // src/hooks/useCofheTokensClaimable.ts
4406
4676
  var import_react_query14 = require("@tanstack/react-query");
4407
4677
  var import_react21 = require("react");
4408
- var import_viem18 = require("viem");
4678
+ var import_viem19 = require("viem");
4409
4679
  var import_ts_essentials18 = __toESM(require_dist(), 1);
4410
4680
 
4411
4681
  // src/hooks/useNormalizedList.ts
@@ -4436,14 +4706,14 @@ function useNormalizedList(items, options) {
4436
4706
 
4437
4707
  // src/hooks/useIsWaitingForDecryptionByAddress.ts
4438
4708
  var import_react20 = require("react");
4439
- var import_viem17 = require("viem");
4709
+ var import_viem18 = require("viem");
4440
4710
  var import_ts_essentials17 = __toESM(require_dist(), 1);
4441
4711
  function useIsWaitingForDecryptionByAddress(entries) {
4442
4712
  const awaitingDecryptionKeySet = useAwaitingDecryptionQueryKeySet();
4443
4713
  return (0, import_react20.useMemo)(() => {
4444
4714
  const map = {};
4445
4715
  for (const entry of entries) {
4446
- (0, import_ts_essentials17.assert)((0, import_viem17.isAddress)(entry.address), "address is valid");
4716
+ (0, import_ts_essentials17.assert)((0, import_viem18.isAddress)(entry.address), "address is valid");
4447
4717
  map[entry.address] = awaitingDecryptionKeySet.has(JSON.stringify(entry.queryKey));
4448
4718
  }
4449
4719
  return map;
@@ -4948,17 +5218,17 @@ function usePermitDuration(options) {
4948
5218
  var import_react25 = require("react");
4949
5219
 
4950
5220
  // src/stores/portalPersisted.tsx
4951
- var import_zustand8 = require("zustand");
4952
- var import_middleware3 = require("zustand/middleware");
4953
- var usePortalPersisted = (0, import_zustand8.create)()(
4954
- (0, import_middleware3.persist)(
5221
+ var import_zustand9 = require("zustand");
5222
+ var import_middleware4 = require("zustand/middleware");
5223
+ var usePortalPersisted = (0, import_zustand9.create)()(
5224
+ (0, import_middleware4.persist)(
4955
5225
  (set, get) => ({
4956
5226
  hasCreatedFirstPermit: false,
4957
5227
  setHasCreatedFirstPermit: (hasCreated) => set({ hasCreatedFirstPermit: hasCreated })
4958
5228
  }),
4959
5229
  {
4960
5230
  name: "cofhesdk-react-persisted",
4961
- storage: (0, import_middleware3.createJSONStorage)(() => localStorage)
5231
+ storage: (0, import_middleware4.createJSONStorage)(() => localStorage)
4962
5232
  }
4963
5233
  )
4964
5234
  );
@@ -5219,7 +5489,7 @@ function useReceivePermit({ onSuccess, onError } = {}) {
5219
5489
 
5220
5490
  // src/hooks/permits/usePermitDetailsAndActions.ts
5221
5491
  var import_react30 = require("react");
5222
- var import_viem19 = require("viem");
5492
+ var import_viem20 = require("viem");
5223
5493
  var import_permits4 = require("@cofhe/sdk/permits");
5224
5494
 
5225
5495
  // src/hooks/useCopyFeedback.ts
@@ -5317,7 +5587,7 @@ var usePermitDetailsAndActions = (permitHash) => {
5317
5587
  const permitLabel = (0, import_react30.useMemo)(() => {
5318
5588
  if (!permit) return void 0;
5319
5589
  if (permit.name?.trim()) return permit.name;
5320
- const fallbackAddress = permit.recipient && permit.recipient !== import_viem19.zeroAddress ? permit.recipient : permit.issuer || import_viem19.zeroAddress;
5590
+ const fallbackAddress = permit.recipient && permit.recipient !== import_viem20.zeroAddress ? permit.recipient : permit.issuer || import_viem20.zeroAddress;
5321
5591
  return truncateAddress(fallbackAddress, 4, 4) ?? fallbackAddress;
5322
5592
  }, [permit]);
5323
5593
  const expirationInfo = (0, import_react30.useMemo)(() => formatExpirationLabel(permit?.expiration), [permit?.expiration]);
@@ -6152,7 +6422,7 @@ var StatusBarContent = () => {
6152
6422
  };
6153
6423
 
6154
6424
  // src/components/CofheFloatingButton/ContentSection.tsx
6155
- var import_react59 = require("react");
6425
+ var import_react60 = require("react");
6156
6426
 
6157
6427
  // src/components/CofheFloatingButton/pages/MainPage/WalletHeader.tsx
6158
6428
  var import_md4 = require("react-icons/md");
@@ -6785,7 +7055,7 @@ var PageContainer = ({ isModal, header, content, footer }) => {
6785
7055
  };
6786
7056
 
6787
7057
  // src/components/CofheFloatingButton/components/TransactionItem.tsx
6788
- var import_viem20 = require("viem");
7058
+ var import_viem21 = require("viem");
6789
7059
  var import_go = require("react-icons/go");
6790
7060
  var import_tb2 = require("react-icons/tb");
6791
7061
  var import_jsx_runtime28 = require("react/jsx-runtime");
@@ -6814,7 +7084,7 @@ var TransactionItem = ({ transaction }) => {
6814
7084
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
6815
7085
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-sm font-semibold cofhe-text-primary", children: actionToString(transaction.actionType) }),
6816
7086
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "text-sm font-semibold cofhe-text-primary", children: [
6817
- (0, import_viem20.formatUnits)(transaction.tokenAmount, transaction.token.decimals),
7087
+ (0, import_viem21.formatUnits)(transaction.tokenAmount, transaction.token.decimals),
6818
7088
  " ",
6819
7089
  transaction.token.symbol
6820
7090
  ] })
@@ -6952,8 +7222,8 @@ var MainPage = () => {
6952
7222
  };
6953
7223
 
6954
7224
  // src/components/CofheFloatingButton/stores/settingsStore.ts
6955
- var import_zustand9 = require("zustand");
6956
- var import_middleware4 = require("zustand/middleware");
7225
+ var import_zustand10 = require("zustand");
7226
+ var import_middleware5 = require("zustand/middleware");
6957
7227
  var ShieldPageVariant = /* @__PURE__ */ ((ShieldPageVariant2) => {
6958
7228
  ShieldPageVariant2["Option1"] = "option1";
6959
7229
  ShieldPageVariant2["Option2"] = "option2";
@@ -6963,8 +7233,8 @@ var SHIELD_PAGE_VARIANT_LABELS = {
6963
7233
  ["option1" /* Option1 */]: "Modern UI",
6964
7234
  ["option2" /* Option2 */]: "Classic UI"
6965
7235
  };
6966
- var useSettingsStore = (0, import_zustand9.create)()(
6967
- (0, import_middleware4.persist)(
7236
+ var useSettingsStore = (0, import_zustand10.create)()(
7237
+ (0, import_middleware5.persist)(
6968
7238
  (set) => ({
6969
7239
  shieldPageVariant: "option1" /* Option1 */,
6970
7240
  setShieldPageVariant: (variant) => set({ shieldPageVariant: variant })
@@ -7143,7 +7413,7 @@ var InfoModalButton = ({ onClick }) => {
7143
7413
 
7144
7414
  // src/components/CofheFloatingButton/components/PermitCard.tsx
7145
7415
  var import_fa63 = require("react-icons/fa6");
7146
- var import_viem21 = require("viem");
7416
+ var import_viem22 = require("viem");
7147
7417
  var import_permits7 = require("@cofhe/sdk/permits");
7148
7418
 
7149
7419
  // src/components/StripedBackground.tsx
@@ -7263,14 +7533,14 @@ var BasePermitCard = ({
7263
7533
  ] })
7264
7534
  ] }),
7265
7535
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("br", {}),
7266
- permit.recipient != null && permit.recipient !== import_viem21.zeroAddress && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
7536
+ permit.recipient != null && permit.recipient !== import_viem22.zeroAddress && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
7267
7537
  "Recipient: ",
7268
7538
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("b", { children: truncateAddress(permit.recipient, 6, 6) }),
7269
7539
  " ",
7270
7540
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CopyButton2, { hash: permit.recipient }),
7271
7541
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("br", {})
7272
7542
  ] }),
7273
- permit.validatorContract != null && permit.validatorContract !== import_viem21.zeroAddress && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
7543
+ permit.validatorContract != null && permit.validatorContract !== import_viem22.zeroAddress && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
7274
7544
  "Validator:",
7275
7545
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("br", {}),
7276
7546
  " ",
@@ -7918,7 +8188,7 @@ var TokenInfoBalanceChart = ({ token, chartPoints }) => {
7918
8188
 
7919
8189
  // src/components/CofheFloatingButton/pages/TokenInfoTransactionHistory.tsx
7920
8190
  var import_react51 = require("react");
7921
- var import_viem22 = require("viem");
8191
+ var import_viem23 = require("viem");
7922
8192
  var import_jsx_runtime47 = require("react/jsx-runtime");
7923
8193
  var TokenInfoTransactionHistoryHeader = ({ token }) => {
7924
8194
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
@@ -7942,7 +8212,7 @@ var TokenInfoTransactionHistory = ({ token, priceUsd }) => {
7942
8212
  });
7943
8213
  const activity = (0, import_react51.useMemo)(() => {
7944
8214
  return tokenTxs.slice().sort((a, b) => b.timestamp - a.timestamp).map((tx) => {
7945
- const amountToken = parseFloat((0, import_viem22.formatUnits)(tx.tokenAmount, tx.token.decimals));
8215
+ const amountToken = parseFloat((0, import_viem23.formatUnits)(tx.tokenAmount, tx.token.decimals));
7946
8216
  const amountUsd = typeof priceUsd === "number" && Number.isFinite(amountToken) ? amountToken * priceUsd : void 0;
7947
8217
  return {
7948
8218
  kind: actionToString(tx.actionType),
@@ -8047,7 +8317,7 @@ var TokenInfoPage = ({ token }) => {
8047
8317
 
8048
8318
  // src/components/CofheFloatingButton/pages/SendPage.tsx
8049
8319
  var import_react53 = require("react");
8050
- var import_viem23 = require("viem");
8320
+ var import_viem24 = require("viem");
8051
8321
  var import_ts_essentials22 = __toESM(require_dist(), 1);
8052
8322
  var import_jsx_runtime49 = require("react/jsx-runtime");
8053
8323
  var SendPage = ({ token: _token }) => {
@@ -8100,12 +8370,12 @@ var SendPage = ({ token: _token }) => {
8100
8370
  const [recipientAddress, setRecipientAddress] = (0, import_react53.useState)("");
8101
8371
  const [error, setError] = (0, import_react53.useState)(null);
8102
8372
  const [success, setSuccess] = (0, import_react53.useState)(null);
8103
- const isValidAddress2 = (0, import_viem23.isAddress)(recipientAddress);
8373
+ const isValidAddress2 = (0, import_viem24.isAddress)(recipientAddress);
8104
8374
  const isValidAmount = (amount.length > 0 && confidentialUnitBalance && confidentialUnitBalance.gte(amount)) ?? false;
8105
8375
  const handleSend = async () => {
8106
- (0, import_ts_essentials22.assert)((0, import_viem23.isAddress)(recipientAddress), "Recipient address is not valid");
8376
+ (0, import_ts_essentials22.assert)((0, import_viem24.isAddress)(recipientAddress), "Recipient address is not valid");
8107
8377
  const amountWei = unitToWei(amount, token.decimals);
8108
- (0, import_ts_essentials22.assert)(amountWei <= import_viem23.maxUint128, "Amount exceeds maximum supported value (uint128 max)");
8378
+ (0, import_ts_essentials22.assert)(amountWei <= import_viem24.maxUint128, "Amount exceeds maximum supported value (uint128 max)");
8109
8379
  (0, import_ts_essentials22.assert)(account, "Sender account is required");
8110
8380
  await encryptAmountAndSendToken({
8111
8381
  input: {
@@ -8247,7 +8517,7 @@ var SendPage = ({ token: _token }) => {
8247
8517
  var import_tb4 = require("react-icons/tb");
8248
8518
  var import_lu2 = require("react-icons/lu");
8249
8519
  var import_react55 = require("react");
8250
- var import_viem24 = require("viem");
8520
+ var import_viem25 = require("viem");
8251
8521
  var import_ts_essentials23 = __toESM(require_dist(), 1);
8252
8522
 
8253
8523
  // src/hooks/useIsUnshieldingMining.ts
@@ -8286,7 +8556,7 @@ function humanizeSimulationError(error, fallbackMessage) {
8286
8556
  if (!error) return null;
8287
8557
  const cofheErrorMessage = cofheHumanizeViemError(error);
8288
8558
  if (cofheErrorMessage) return cofheErrorMessage;
8289
- if (error instanceof import_viem24.ContractFunctionExecutionError) return error.shortMessage;
8559
+ if (error instanceof import_viem25.ContractFunctionExecutionError) return error.shortMessage;
8290
8560
  return fallbackMessage;
8291
8561
  }
8292
8562
  function TxHashWithActions({ hash, chainId }) {
@@ -8497,7 +8767,7 @@ function useShieldWithLifecycle(token) {
8497
8767
  if (!relevantError) return null;
8498
8768
  const cofheErrorMessage = cofheHumanizeViemError(relevantError);
8499
8769
  if (cofheErrorMessage) return cofheErrorMessage;
8500
- if (relevantError instanceof import_viem24.ContractFunctionExecutionError) return relevantError.shortMessage;
8770
+ if (relevantError instanceof import_viem25.ContractFunctionExecutionError) return relevantError.shortMessage;
8501
8771
  return shouldApprove ? "Failed to simulate approval transaction" : "Failed to simulate shield transaction";
8502
8772
  }, [approvalSimulation.error, shieldSimulation.error, shouldApprove]);
8503
8773
  const canShield = isValidShieldAmount && !!shieldCallArgs && isAllowanceKnown && hasSufficientAllowance && !shieldSimulation.isFetching && !shieldSimulation.error;
@@ -8576,7 +8846,7 @@ function useUnshieldWithLifecycle(token) {
8576
8846
  }
8577
8847
  });
8578
8848
  const handleUnshield = async () => {
8579
- const amountWei = (0, import_viem24.parseUnits)(unshieldAmount, token.decimals);
8849
+ const amountWei = (0, import_viem25.parseUnits)(unshieldAmount, token.decimals);
8580
8850
  tokenUnshield.mutateAsync({
8581
8851
  token,
8582
8852
  amount: amountWei,
@@ -8590,7 +8860,7 @@ function useUnshieldWithLifecycle(token) {
8590
8860
  const isValidUnshieldAmount = (unshieldAmount.length > 0 && confidentialBalanceUnit?.gte(unshieldAmount)) ?? false;
8591
8861
  const unshieldCallArgs = (0, import_react55.useMemo)(() => {
8592
8862
  if (!account || !isValidUnshieldAmount) return void 0;
8593
- const amountWei = (0, import_viem24.parseUnits)(unshieldAmount, token.decimals);
8863
+ const amountWei = (0, import_viem25.parseUnits)(unshieldAmount, token.decimals);
8594
8864
  return getCofheTokenUnshieldCallArgs({ token, amount: amountWei, account });
8595
8865
  }, [account, isValidUnshieldAmount, token, unshieldAmount]);
8596
8866
  const unshieldSimulation = useCofheSimulateWriteContract(unshieldCallArgs, {
@@ -8958,7 +9228,7 @@ var ActivityPage = () => {
8958
9228
  // src/components/CofheFloatingButton/pages/DebugPage.tsx
8959
9229
  var import_react56 = require("react");
8960
9230
  var import_accounts = require("viem/accounts");
8961
- var import_viem25 = require("viem");
9231
+ var import_viem26 = require("viem");
8962
9232
  var import_jsx_runtime52 = require("react/jsx-runtime");
8963
9233
  var DebugPage = () => {
8964
9234
  const { navigateBack } = usePortalNavigation();
@@ -9319,7 +9589,7 @@ var FirstPermitDebug = () => {
9319
9589
  };
9320
9590
  var CreateSelfExpiringPermitButton = () => {
9321
9591
  const cofheClient = useCofheClient();
9322
- const create10 = async () => {
9592
+ const create11 = async () => {
9323
9593
  const { account } = cofheClient.getSnapshot();
9324
9594
  if (!account) throw new Error("No connected account found");
9325
9595
  const expiration = Math.floor(Date.now() / 1e3) + 2 * 60;
@@ -9330,7 +9600,7 @@ var CreateSelfExpiringPermitButton = () => {
9330
9600
  });
9331
9601
  usePortalPersisted.getState().setHasCreatedFirstPermit(true);
9332
9602
  };
9333
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("button", { onClick: create10, children: "Create self permit (expires in 2 minutes)" });
9603
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("button", { onClick: create11, children: "Create self permit (expires in 2 minutes)" });
9334
9604
  };
9335
9605
  var CreateAndUseReceivingPermitButton = () => {
9336
9606
  const cofheClient = useCofheClient();
@@ -9339,9 +9609,9 @@ var CreateAndUseReceivingPermitButton = () => {
9339
9609
  if (!account) throw new Error("No connected account found");
9340
9610
  if (!publicClient) throw new Error("No public client found");
9341
9611
  const sharingAccount = (0, import_accounts.privateKeyToAccount)("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80");
9342
- const sharingWalletClient = (0, import_viem25.createWalletClient)({
9612
+ const sharingWalletClient = (0, import_viem26.createWalletClient)({
9343
9613
  chain: publicClient.chain,
9344
- transport: (0, import_viem25.http)(),
9614
+ transport: (0, import_viem26.http)(),
9345
9615
  account: sharingAccount
9346
9616
  });
9347
9617
  const sharedPermit = await cofheClient.permits.createSharing(
@@ -9439,9 +9709,12 @@ var TokenRow = ({ token, onClick, topLabel, balanceType }) => {
9439
9709
  );
9440
9710
  };
9441
9711
 
9442
- // src/components/CofheFloatingButton/modals/TokenListModal.tsx
9712
+ // src/components/CofheFloatingButton/modals/AddCustomTokenButton.tsx
9443
9713
  var import_jsx_runtime54 = require("react/jsx-runtime");
9444
- var AddCustomTokenButton = () => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Button, { variant: "outline", size: "sm", label: "Add custom Token +" });
9714
+ var AddCustomTokenButton = ({ label = "Import token", onClick }) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Button, { variant: "outline", size: "sm", label, onClick });
9715
+
9716
+ // src/components/CofheFloatingButton/modals/TokenListModal.tsx
9717
+ var import_jsx_runtime55 = require("react/jsx-runtime");
9445
9718
  var TokenListModal = ({
9446
9719
  tokens,
9447
9720
  onClose,
@@ -9449,17 +9722,31 @@ var TokenListModal = ({
9449
9722
  onSelectToken,
9450
9723
  balanceType
9451
9724
  }) => {
9452
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
9725
+ const { openModal } = usePortalModals();
9726
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9453
9727
  PageContainer,
9454
9728
  {
9455
- header: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex justify-between flex-row", children: [
9456
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: [
9457
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ArrowBackIcon, { style: { fontSize: 16 } }),
9458
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "text-sm font-medium", children: title })
9729
+ header: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex justify-between flex-row", children: [
9730
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: [
9731
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ArrowBackIcon, { style: { fontSize: 16 } }),
9732
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "text-sm font-medium", children: title })
9459
9733
  ] }),
9460
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AddCustomTokenButton, {})
9734
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9735
+ AddCustomTokenButton,
9736
+ {
9737
+ onClick: () => openModal("importCustomToken" /* ImportCustomToken */, {
9738
+ balanceType,
9739
+ title: "Import token",
9740
+ tokens,
9741
+ onSelectToken: (token) => {
9742
+ onSelectToken(token);
9743
+ onClose();
9744
+ }
9745
+ })
9746
+ }
9747
+ )
9461
9748
  ] }),
9462
- content: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
9749
+ content: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9463
9750
  TokenListContent,
9464
9751
  {
9465
9752
  balanceType,
@@ -9478,8 +9765,8 @@ var TokenListContent = ({ tokens, onSelectToken, balanceType }) => {
9478
9765
  const normalizedPinnedAddress = pinnedTokenAddress?.toLowerCase();
9479
9766
  const pinnedToken = normalizedPinnedAddress ? tokens.find((t) => t.address.toLowerCase() === normalizedPinnedAddress) : void 0;
9480
9767
  const nonPinnedTokens = pinnedToken ? tokens.filter((t) => t.address.toLowerCase() !== normalizedPinnedAddress) : tokens;
9481
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "cofhe-token-list-container", children: tokens.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "text-xs opacity-70 py-4 text-center", children: "No tokens found" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
9482
- pinnedToken && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
9768
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "cofhe-token-list-container", children: tokens.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "text-xs opacity-70 py-4 text-center", children: "No tokens found" }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
9769
+ pinnedToken && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9483
9770
  TokenRow,
9484
9771
  {
9485
9772
  balanceType,
@@ -9491,7 +9778,7 @@ var TokenListContent = ({ tokens, onSelectToken, balanceType }) => {
9491
9778
  },
9492
9779
  `pinned-${pinnedToken.address}`
9493
9780
  ),
9494
- nonPinnedTokens.map((token) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
9781
+ nonPinnedTokens.map((token) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9495
9782
  TokenRow,
9496
9783
  {
9497
9784
  balanceType,
@@ -9506,29 +9793,46 @@ var TokenListContent = ({ tokens, onSelectToken, balanceType }) => {
9506
9793
  };
9507
9794
 
9508
9795
  // src/components/CofheFloatingButton/pages/PortfolioPage.tsx
9509
- var import_jsx_runtime55 = require("react/jsx-runtime");
9796
+ var import_jsx_runtime56 = require("react/jsx-runtime");
9510
9797
  var PortfolioPage = () => {
9511
9798
  const { navigateBack, navigateTo } = usePortalNavigation();
9799
+ const { openModal } = usePortalModals();
9512
9800
  const chainId = useCofheChainId();
9513
9801
  const allTokens = useCofheTokens(chainId);
9514
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9802
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9515
9803
  PageContainer,
9516
9804
  {
9517
- header: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex justify-between flex-row", children: [
9518
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
9805
+ header: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex justify-between flex-row", children: [
9806
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
9519
9807
  "button",
9520
9808
  {
9521
9809
  onClick: navigateBack,
9522
9810
  className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity",
9523
9811
  children: [
9524
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ArrowBackIcon, { style: { fontSize: 16 } }),
9525
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "text-sm font-medium", children: "Tokens list" })
9812
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ArrowBackIcon, { style: { fontSize: 16 } }),
9813
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-sm font-medium", children: "Tokens list" })
9526
9814
  ]
9527
9815
  }
9528
9816
  ),
9529
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(AddCustomTokenButton, {})
9817
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9818
+ AddCustomTokenButton,
9819
+ {
9820
+ onClick: () => openModal("importCustomToken" /* ImportCustomToken */, {
9821
+ balanceType: "confidential" /* Confidential */,
9822
+ title: "Import token",
9823
+ tokens: allTokens,
9824
+ onSelectToken: (token) => {
9825
+ navigateTo("tokeninfo" /* TokenInfo */, {
9826
+ pageProps: {
9827
+ token
9828
+ }
9829
+ });
9830
+ }
9831
+ })
9832
+ }
9833
+ )
9530
9834
  ] }),
9531
- content: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9835
+ content: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9532
9836
  TokenListContent,
9533
9837
  {
9534
9838
  balanceType: "confidential" /* Confidential */,
@@ -9549,7 +9853,7 @@ var PortfolioPage = () => {
9549
9853
  // src/components/CofheFloatingButton/pages/ClaimableTokens.tsx
9550
9854
  var import_react57 = require("react");
9551
9855
  var import_ts_essentials24 = __toESM(require_dist(), 1);
9552
- var import_jsx_runtime56 = require("react/jsx-runtime");
9856
+ var import_jsx_runtime57 = require("react/jsx-runtime");
9553
9857
  function ClaimableTokens() {
9554
9858
  const chainsClaimableTokens = useCofheClaimableTokens();
9555
9859
  const claimableByTokenAddress = chainsClaimableTokens.claimableByTokenAddress;
@@ -9572,30 +9876,30 @@ function ClaimableTokens() {
9572
9876
  (0, import_ts_essentials24.assert)(row, "token not found for claim");
9573
9877
  await claimMutation.mutateAsync({ token: row.token, amount: row.claimableAmount });
9574
9878
  };
9575
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9879
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
9576
9880
  PageContainer,
9577
9881
  {
9578
- header: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-3", children: [
9579
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9882
+ header: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center gap-3", children: [
9883
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
9580
9884
  "button",
9581
9885
  {
9582
9886
  className: "flex items-center gap-2 text-xl font-semibold text-[#0E2F3F] transition-opacity hover:opacity-80 dark:text-white",
9583
9887
  type: "button",
9584
9888
  onClick: navigateBack,
9585
- children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ArrowBackIcon, { fontSize: "small" })
9889
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ArrowBackIcon, { fontSize: "small" })
9586
9890
  }
9587
9891
  ),
9588
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { children: "Claimable Tokens list" })
9892
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { children: "Claimable Tokens list" })
9589
9893
  ] }),
9590
- content: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-col gap-4 pr-1", children: [
9894
+ content: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex flex-col gap-4 pr-1", children: [
9591
9895
  rows.map(({ token, claimableAmount }) => {
9592
9896
  const isDecrypting = waitingByTokenAddress?.[token.address] ?? false;
9593
9897
  const isUnshielding = unshieldingInProgressByTokenAddress?.[token.address.toLowerCase()] ?? false;
9594
9898
  const formatted = formatTokenAmount(claimableAmount, token.decimals, 5).formatted;
9595
9899
  const isClaimingThis = isClaimingByTokenAddress?.[token.address.toLowerCase()] ?? false;
9596
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "grid grid-cols-[1fr,auto,auto] items-center gap-4", children: [
9597
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-3 min-w-0", children: [
9598
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9900
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "grid grid-cols-[1fr,auto,auto] items-center gap-4", children: [
9901
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center gap-3 min-w-0", children: [
9902
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
9599
9903
  TokenIcon,
9600
9904
  {
9601
9905
  logoURI: token.logoURI,
@@ -9609,10 +9913,10 @@ function ClaimableTokens() {
9609
9913
  )
9610
9914
  }
9611
9915
  ),
9612
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "text-xl font-semibold cofhe-text-primary truncate", children: token.name }) })
9916
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "text-xl font-semibold cofhe-text-primary truncate", children: token.name }) })
9613
9917
  ] }),
9614
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "text-2xl font-semibold cofhe-text-primary tabular-nums", children: formatted }),
9615
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9918
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "text-2xl font-semibold cofhe-text-primary tabular-nums", children: formatted }),
9919
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
9616
9920
  Button,
9617
9921
  {
9618
9922
  type: "button",
@@ -9623,7 +9927,7 @@ function ClaimableTokens() {
9623
9927
  )
9624
9928
  ] }, token.address);
9625
9929
  }),
9626
- rows.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "text-sm opacity-70 cofhe-text-primary", children: "No claimable tokens." })
9930
+ rows.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "text-sm opacity-70 cofhe-text-primary", children: "No claimable tokens." })
9627
9931
  ] })
9628
9932
  }
9629
9933
  );
@@ -9647,24 +9951,24 @@ var pages = {
9647
9951
  };
9648
9952
 
9649
9953
  // src/components/CofheFloatingButton/ContentSection.tsx
9650
- var import_react60 = require("motion/react");
9954
+ var import_react61 = require("motion/react");
9651
9955
 
9652
9956
  // src/components/CofheFloatingButton/modals/ExampleSelectionPage.tsx
9653
- var import_jsx_runtime57 = require("react/jsx-runtime");
9957
+ var import_jsx_runtime58 = require("react/jsx-runtime");
9654
9958
  var ExampleSelectionPage = ({
9655
9959
  onClose,
9656
9960
  onSelect
9657
9961
  }) => {
9658
9962
  const options = ["1", "2", "3"];
9659
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
9963
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
9660
9964
  PageContainer,
9661
9965
  {
9662
9966
  isModal: true,
9663
- header: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: [
9664
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(CloseIcon, { style: { fontSize: 16 } }),
9665
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-sm font-medium", children: "Select an option" })
9967
+ header: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: [
9968
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(CloseIcon, { style: { fontSize: 16 } }),
9969
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "text-sm font-medium", children: "Select an option" })
9666
9970
  ] }),
9667
- content: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex flex-1 flex-col gap-3 items-start justify-start", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
9971
+ content: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "flex flex-1 flex-col gap-3 items-start justify-start", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
9668
9972
  "button",
9669
9973
  {
9670
9974
  onClick: () => {
@@ -9678,29 +9982,29 @@ var ExampleSelectionPage = ({
9678
9982
  },
9679
9983
  option
9680
9984
  )) }),
9681
- footer: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex flex-row flex-1 justify-end items-center mt-auto", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { children: "Close" }) }) })
9985
+ footer: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "flex flex-row flex-1 justify-end items-center mt-auto", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { children: "Close" }) }) })
9682
9986
  }
9683
9987
  );
9684
9988
  };
9685
9989
 
9686
9990
  // src/components/CofheFloatingButton/modals/ExampleInfoPage.tsx
9687
- var import_jsx_runtime58 = require("react/jsx-runtime");
9991
+ var import_jsx_runtime59 = require("react/jsx-runtime");
9688
9992
  var ExampleInfoPage = ({ onClose }) => {
9689
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
9993
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
9690
9994
  PageContainer,
9691
9995
  {
9692
9996
  isModal: true,
9693
- header: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: [
9694
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(CloseIcon, { style: { fontSize: 16 } }),
9695
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "text-sm font-medium", children: "More info" })
9997
+ header: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: [
9998
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(CloseIcon, { style: { fontSize: 16 } }),
9999
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "text-sm font-medium", children: "More info" })
9696
10000
  ] }),
9697
- content: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex flex-1 flex-col gap-3 items-start justify-start", children: [
9698
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { children: "Cofhesdk is complex, so we have created this modal to help you understand." }),
9699
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { children: "You probably clicked on a ? button next to some functionality. And in this modal you'll get your information or explanation." }),
9700
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { children: "This is another paragraph of explanation." }),
9701
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { children: `Now that you're done reading, you can click "Got It" at the bottom to close this modal.` })
10001
+ content: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex flex-1 flex-col gap-3 items-start justify-start", children: [
10002
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: "Cofhesdk is complex, so we have created this modal to help you understand." }),
10003
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: "You probably clicked on a ? button next to some functionality. And in this modal you'll get your information or explanation." }),
10004
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: "This is another paragraph of explanation." }),
10005
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: `Now that you're done reading, you can click "Got It" at the bottom to close this modal.` })
9702
10006
  ] }),
9703
- footer: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "flex flex-row flex-1 justify-end items-center mt-auto", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { children: "Got It" }) }) })
10007
+ footer: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "flex flex-row flex-1 justify-end items-center mt-auto", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { children: "Got It" }) }) })
9704
10008
  }
9705
10009
  );
9706
10010
  };
@@ -9708,19 +10012,19 @@ var ExampleInfoPage = ({ onClose }) => {
9708
10012
  // src/components/CofheFloatingButton/modals/PermitDetailsModal.tsx
9709
10013
  var import_fa64 = require("react-icons/fa6");
9710
10014
  var import_react58 = require("react");
9711
- var import_jsx_runtime59 = require("react/jsx-runtime");
10015
+ var import_jsx_runtime60 = require("react/jsx-runtime");
9712
10016
  var PermitTypeLabel2 = {
9713
10017
  self: "Self",
9714
10018
  sharing: "Delegated",
9715
10019
  recipient: "Imported"
9716
10020
  };
9717
10021
  var NoPermitFoundModal = ({ onClose }) => {
9718
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
10022
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9719
10023
  PageContainer,
9720
10024
  {
9721
- header: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "flex items-center gap-2 text-base font-semibold tracking-tight text-[#0E2F3F] transition-opacity hover:opacity-80 dark:text-white", children: "No permit found" }),
9722
- content: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: "No permit found" }) }),
9723
- footer: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { label: "CLOSE", onClick: onClose, variant: "ghost" })
10025
+ header: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex items-center gap-2 text-base font-semibold tracking-tight text-[#0E2F3F] transition-opacity hover:opacity-80 dark:text-white", children: "No permit found" }),
10026
+ content: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { children: "No permit found" }) }),
10027
+ footer: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Button, { label: "CLOSE", onClick: onClose, variant: "ghost" })
9724
10028
  }
9725
10029
  );
9726
10030
  };
@@ -9753,77 +10057,77 @@ var PermitDetailsModal = ({ hash, onClose }) => {
9753
10057
  onClose();
9754
10058
  }, [confirmDelete, onClose, handleRemovePermit]);
9755
10059
  if (permit == null) {
9756
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(NoPermitFoundModal, { onClose });
10060
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(NoPermitFoundModal, { onClose });
9757
10061
  }
9758
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
10062
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9759
10063
  PageContainer,
9760
10064
  {
9761
10065
  isModal: true,
9762
- header: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
10066
+ header: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9763
10067
  PermitCard,
9764
10068
  {
9765
10069
  hash,
9766
10070
  className: "-mt-4 -ml-4 -mr-4",
9767
- header: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
10071
+ header: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
9768
10072
  "button",
9769
10073
  {
9770
10074
  className: "flex items-center gap-2 text-base font-semibold tracking-tight text-[#0E2F3F] transition-opacity hover:opacity-80 dark:text-white",
9771
10075
  onClick: onClose,
9772
10076
  type: "button",
9773
10077
  children: [
9774
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(CloseIcon, { fontSize: "small" }),
9775
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { children: "Permit" })
10078
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(CloseIcon, { fontSize: "small" }),
10079
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: "Permit" })
9776
10080
  ]
9777
10081
  }
9778
10082
  )
9779
10083
  }
9780
10084
  ),
9781
- content: permit != null && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex flex-col gap-3", children: [
9782
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("p", { className: "flex flex-row gap-2 text-sm", children: [
10085
+ content: permit != null && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex flex-col gap-3", children: [
10086
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("p", { className: "flex flex-row gap-2 text-sm", children: [
9783
10087
  "Type: ",
9784
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: PermitTypeLabel2[permit.type] }),
9785
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(InfoModalButton, { onClick: () => openModal("permitTypeInfo" /* PermitTypeInfo */, { type: permit.type }) })
10088
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: PermitTypeLabel2[permit.type] }),
10089
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(InfoModalButton, { onClick: () => openModal("permitTypeInfo" /* PermitTypeInfo */, { type: permit.type }) })
9786
10090
  ] }),
9787
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("p", { className: "text-sm", children: [
10091
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("p", { className: "text-sm", children: [
9788
10092
  "Expires in: ",
9789
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: expirationInfo.label })
10093
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: expirationInfo.label })
9790
10094
  ] }),
9791
- permit.type === "self" && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("p", { className: "text-sm", children: [
10095
+ permit.type === "self" && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("p", { className: "text-sm", children: [
9792
10096
  "To select this permit for usage, click the ",
9793
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: '"SELECT"' }),
10097
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: '"SELECT"' }),
9794
10098
  " button below. When this permit is active, you will be able to view your own encrypted data."
9795
10099
  ] }),
9796
- permit.type === "sharing" && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("p", { className: "text-sm", children: [
10100
+ permit.type === "sharing" && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("p", { className: "text-sm", children: [
9797
10101
  "To share this permit with ",
9798
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: "recipient" }),
10102
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: "recipient" }),
9799
10103
  ", click the ",
9800
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: '"SHARE"' }),
10104
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: '"SHARE"' }),
9801
10105
  " button below to copy the permit data to your clipboard. Share the copied permit data with ",
9802
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: "recipient" }),
10106
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: "recipient" }),
9803
10107
  " to grant them access to your encrypted data.",
9804
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("br", {}),
9805
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("br", {}),
9806
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("i", { children: [
9807
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: "Note:" }),
10108
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("br", {}),
10109
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("br", {}),
10110
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("i", { children: [
10111
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: "Note:" }),
9808
10112
  " The copied permit data is not sensitive and can be sent to recipient via any communication channel."
9809
10113
  ] })
9810
10114
  ] }),
9811
- permit.type === "recipient" && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("p", { className: "text-sm", children: [
10115
+ permit.type === "recipient" && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("p", { className: "text-sm", children: [
9812
10116
  "To select this imported permit for usage, click the ",
9813
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: '"SELECT"' }),
10117
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: '"SELECT"' }),
9814
10118
  " button below. When this permit is active, you will be able to view ",
9815
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("b", { children: "issuer" }),
10119
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("b", { children: "issuer" }),
9816
10120
  "'s (",
9817
10121
  truncateAddress(permit.issuer, 4, 4),
9818
10122
  ") encrypted data."
9819
10123
  ] })
9820
10124
  ] }),
9821
- footer: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex flex-row gap-3 w-full", children: [
9822
- isShareablePermit && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(Button, { variant: "primary", onClick: handlePermitShare, children: [
9823
- isCopyComplete ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_fa64.FaCheck, {}) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_fa64.FaRegCopy, {}),
10125
+ footer: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex flex-row gap-3 w-full", children: [
10126
+ isShareablePermit && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(Button, { variant: "primary", onClick: handlePermitShare, children: [
10127
+ isCopyComplete ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_fa64.FaCheck, {}) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_fa64.FaRegCopy, {}),
9824
10128
  isCopyComplete ? "COPIED" : "SHARE"
9825
10129
  ] }),
9826
- !isShareablePermit && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
10130
+ !isShareablePermit && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9827
10131
  Button,
9828
10132
  {
9829
10133
  variant: "primary",
@@ -9832,53 +10136,53 @@ var PermitDetailsModal = ({ hash, onClose }) => {
9832
10136
  disabled: isActivePermit
9833
10137
  }
9834
10138
  ),
9835
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { label: confirmDelete ? "CONFIRM" : "DELETE", onClick: handlePermitDelete, variant: "error" }),
9836
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { label: "CLOSE", onClick: onClose, variant: "ghost" })
10139
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Button, { label: confirmDelete ? "CONFIRM" : "DELETE", onClick: handlePermitDelete, variant: "error" }),
10140
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Button, { label: "CLOSE", onClick: onClose, variant: "ghost" })
9837
10141
  ] })
9838
10142
  }
9839
10143
  );
9840
10144
  };
9841
10145
 
9842
10146
  // src/components/CofheFloatingButton/modals/BaseInfoModal.tsx
9843
- var import_jsx_runtime60 = require("react/jsx-runtime");
10147
+ var import_jsx_runtime61 = require("react/jsx-runtime");
9844
10148
  var BaseInfoModal = ({ header, content, onClose }) => {
9845
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
10149
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
9846
10150
  PageContainer,
9847
10151
  {
9848
10152
  isModal: true,
9849
- header: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
10153
+ header: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
9850
10154
  "button",
9851
10155
  {
9852
10156
  onClick: onClose,
9853
10157
  className: "flex items-center gap-1 text-base font-semibold tracking-tight text-[#0E2F3F] transition-opacity hover:opacity-80 dark:text-white",
9854
10158
  children: [
9855
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(CloseIcon, { style: { fontSize: 16 } }),
9856
- typeof header === "string" ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-base font-semibold tracking-tight text-[#0E2F3F]", children: header }) : header
10159
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CloseIcon, { style: { fontSize: 16 } }),
10160
+ typeof header === "string" ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "text-base font-semibold tracking-tight text-[#0E2F3F]", children: header }) : header
9857
10161
  ]
9858
10162
  }
9859
10163
  ),
9860
- content: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex flex-1 flex-col w-full gap-3 items-start justify-start", children: content }),
9861
- footer: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex flex-row", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Button, { onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: "Close" }) }) })
10164
+ content: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "flex flex-1 flex-col w-full gap-3 items-start justify-start", children: content }),
10165
+ footer: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "flex flex-row", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Button, { onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { children: "Close" }) }) })
9862
10166
  }
9863
10167
  );
9864
10168
  };
9865
10169
 
9866
10170
  // src/components/CofheFloatingButton/modals/PermitTypeInfoModal.tsx
9867
- var import_jsx_runtime61 = require("react/jsx-runtime");
10171
+ var import_jsx_runtime62 = require("react/jsx-runtime");
9868
10172
  var PermitTypeLabel3 = {
9869
10173
  self: "Self",
9870
10174
  sharing: "Delegated",
9871
10175
  recipient: "Imported"
9872
10176
  };
9873
10177
  var PermitTypeInfoModal = ({ type, onClose }) => {
9874
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
10178
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
9875
10179
  BaseInfoModal,
9876
10180
  {
9877
10181
  header: `${PermitTypeLabel3[type]} Permit`,
9878
- content: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
9879
- type === "self" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { children: '"Self" permits are created by a user to access their own encrypted data. The provided signature is verified on-chain by the ACL (Access Control List).' }),
9880
- type === "sharing" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { children: `"Delegated" permits are created by a user (Issuer) to share their encrypted data with another user (Recipient). Both Issuer and Rceipient must sign as a handshake. Issuer's signature is verified on-chain by the ACL (Access Control List) and grants access to Recipient, and Recipient's signature applies and verifies the re-encryption key.` }),
9881
- type === "recipient" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { children: `"Imported" permits are imported by a user (Recipient) to access encrypted data that has been shared with them by the permit's Issuer. Both Issuer and Rceipient must sign as a handshake. Issuer's signature is verified on-chain by the ACL (Access Control List) and grants access to Recipient, and Recipient's signature applies and verifies the re-encryption key.` })
10182
+ content: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
10183
+ type === "self" && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { children: '"Self" permits are created by a user to access their own encrypted data. The provided signature is verified on-chain by the ACL (Access Control List).' }),
10184
+ type === "sharing" && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { children: `"Delegated" permits are created by a user (Issuer) to share their encrypted data with another user (Recipient). Both Issuer and Rceipient must sign as a handshake. Issuer's signature is verified on-chain by the ACL (Access Control List) and grants access to Recipient, and Recipient's signature applies and verifies the re-encryption key.` }),
10185
+ type === "recipient" && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { children: `"Imported" permits are imported by a user (Recipient) to access encrypted data that has been shared with them by the permit's Issuer. Both Issuer and Rceipient must sign as a handshake. Issuer's signature is verified on-chain by the ACL (Access Control List) and grants access to Recipient, and Recipient's signature applies and verifies the re-encryption key.` })
9882
10186
  ] }),
9883
10187
  onClose
9884
10188
  }
@@ -9886,25 +10190,168 @@ var PermitTypeInfoModal = ({ type, onClose }) => {
9886
10190
  };
9887
10191
 
9888
10192
  // src/components/CofheFloatingButton/modals/PermitInfoModal.tsx
9889
- var import_jsx_runtime62 = require("react/jsx-runtime");
10193
+ var import_jsx_runtime63 = require("react/jsx-runtime");
9890
10194
  var PermitInfoModal = ({ onClose }) => {
9891
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
10195
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
9892
10196
  BaseInfoModal,
9893
10197
  {
9894
10198
  header: "Permit",
9895
- content: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
9896
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex flex-col w-full justify-center items-center gap-3 text-[#0E2F3F] dark:text-white", children: [
9897
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(fhenix_permit_icon_default, { className: "h-7 w-7 fill-black dark:fill-white", "aria-label": "CoFHE permit icon" }),
9898
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "text-lg font-semibold", children: "CoFHE Permits" })
10199
+ content: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
10200
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex flex-col w-full justify-center items-center gap-3 text-[#0E2F3F] dark:text-white", children: [
10201
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(fhenix_permit_icon_default, { className: "h-7 w-7 fill-black dark:fill-white", "aria-label": "CoFHE permit icon" }),
10202
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "text-lg font-semibold", children: "CoFHE Permits" })
9899
10203
  ] }),
9900
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "text-sm leading-relaxed text-[#355366] dark:text-white/80", children: "CoFHE permits are used to authenticate your identity and grant access to your encrypted data." }),
9901
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "text-sm leading-relaxed text-[#355366] dark:text-white/80", children: "Generating a permit requires a signature, which will open your connected wallet to sign a message (EIP712). This signed message contains only info used to authenticate and grant access." })
10204
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "text-sm leading-relaxed text-[#355366] dark:text-white/80", children: "CoFHE permits are used to authenticate your identity and grant access to your encrypted data." }),
10205
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "text-sm leading-relaxed text-[#355366] dark:text-white/80", children: "Generating a permit requires a signature, which will open your connected wallet to sign a message (EIP712). This signed message contains only info used to authenticate and grant access." })
9902
10206
  ] }),
9903
10207
  onClose
9904
10208
  }
9905
10209
  );
9906
10210
  };
9907
10211
 
10212
+ // src/components/CofheFloatingButton/modals/ImportCustomTokenCard.tsx
10213
+ var import_react59 = require("react");
10214
+ var import_viem27 = require("viem");
10215
+ var import_jsx_runtime64 = require("react/jsx-runtime");
10216
+ var ImportCustomTokenCard = ({ tokens, onSelectToken, balanceType }) => {
10217
+ const [addressInput, setAddressInput] = (0, import_react59.useState)("");
10218
+ const chainId = useCofheChainId();
10219
+ const addCustomToken = useCustomTokensStore((state) => state.addCustomToken);
10220
+ const removeCustomToken = useCustomTokensStore((state) => state.removeCustomToken);
10221
+ const customTokensByChainId = useCustomTokensStore((state) => state.customTokensByChainId);
10222
+ const trimmedAddress = addressInput.trim();
10223
+ const normalizedAddress = (0, import_viem27.isAddress)(trimmedAddress) ? trimmedAddress : void 0;
10224
+ const importedCustomTokens = (0, import_react59.useMemo)(() => {
10225
+ if (!chainId) return [];
10226
+ return customTokensByChainId[chainId.toString()] ?? [];
10227
+ }, [chainId, customTokensByChainId]);
10228
+ const existingToken = (0, import_react59.useMemo)(() => {
10229
+ if (!normalizedAddress) return void 0;
10230
+ return tokens.find((token) => token.address.toLowerCase() === normalizedAddress.toLowerCase());
10231
+ }, [normalizedAddress, tokens]);
10232
+ const resolvedToken = useResolvedCofheToken(
10233
+ { address: normalizedAddress },
10234
+ {
10235
+ enabled: !!normalizedAddress && !existingToken,
10236
+ retry: false
10237
+ }
10238
+ );
10239
+ const previewToken = existingToken ?? resolvedToken.data;
10240
+ const canImport = !!previewToken && !resolvedToken.isFetching;
10241
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "fnx-card-bg border fnx-card-border rounded-lg p-3 flex flex-col gap-3", children: [
10242
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex flex-col gap-1", children: [
10243
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("label", { className: "text-xs font-medium opacity-70", children: "Token contract address" }),
10244
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
10245
+ "input",
10246
+ {
10247
+ type: "text",
10248
+ value: addressInput,
10249
+ onChange: (event) => setAddressInput(event.target.value),
10250
+ placeholder: "0x...",
10251
+ className: "w-full bg-transparent fnx-text-primary outline-none border-b pb-2 px-2 text-sm"
10252
+ }
10253
+ )
10254
+ ] }),
10255
+ !normalizedAddress && trimmedAddress.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xxxs text-[#c2410c]", children: "Enter a valid token address." }),
10256
+ resolvedToken.isFetching && !existingToken && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xxxs opacity-70", children: "Checking token metadata and CoFHE support..." }),
10257
+ resolvedToken.error && !existingToken && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xxxs text-[#c2410c]", children: resolvedToken.error.message }),
10258
+ previewToken && /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex flex-col gap-1 text-xs", children: [
10259
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("p", { className: "font-medium fnx-text-primary", children: [
10260
+ previewToken.symbol,
10261
+ " \xB7 ",
10262
+ previewToken.name
10263
+ ] }),
10264
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "opacity-70", children: getTokenConfidentialityLabel(previewToken.extensions.fhenix.confidentialityType) ?? "Confidential token" }),
10265
+ balanceType === "public" && previewToken.extensions.fhenix.confidentialityType === "wrapped" && !previewToken.extensions.fhenix.erc20Pair && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xxxs opacity-70", children: "Public-balance actions may stay unavailable until the token's paired asset can be discovered." })
10266
+ ] }),
10267
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
10268
+ Button,
10269
+ {
10270
+ variant: "primary",
10271
+ size: "sm",
10272
+ disabled: !canImport,
10273
+ label: existingToken ? "Select token" : "Import and select",
10274
+ onClick: () => {
10275
+ if (!previewToken) return;
10276
+ if (!existingToken) {
10277
+ addCustomToken(previewToken);
10278
+ }
10279
+ onSelectToken(previewToken);
10280
+ }
10281
+ }
10282
+ ),
10283
+ importedCustomTokens.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex flex-col gap-2 border-t pt-3", children: [
10284
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xs font-medium opacity-70", children: "Imported tokens" }),
10285
+ importedCustomTokens.map((token) => /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
10286
+ "div",
10287
+ {
10288
+ className: "flex items-center justify-between gap-3 px-3 py-2",
10289
+ children: [
10290
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "min-w-0 flex-1", children: [
10291
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("p", { className: "text-sm font-medium fnx-text-primary truncate", children: [
10292
+ token.symbol,
10293
+ " \xB7 ",
10294
+ token.name
10295
+ ] }),
10296
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xxxs opacity-70 truncate", children: token.address })
10297
+ ] }),
10298
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
10299
+ Button,
10300
+ {
10301
+ variant: "error",
10302
+ size: "sm",
10303
+ label: "Remove",
10304
+ onClick: () => {
10305
+ removeCustomToken({
10306
+ chainId: token.chainId,
10307
+ address: token.address
10308
+ });
10309
+ if (normalizedAddress?.toLowerCase() === token.address.toLowerCase()) {
10310
+ setAddressInput("");
10311
+ }
10312
+ }
10313
+ }
10314
+ )
10315
+ ]
10316
+ },
10317
+ `${token.chainId}-${token.address}`
10318
+ ))
10319
+ ] })
10320
+ ] });
10321
+ };
10322
+
10323
+ // src/components/CofheFloatingButton/modals/ImportCustomTokenModal.tsx
10324
+ var import_jsx_runtime65 = require("react/jsx-runtime");
10325
+ var ImportCustomTokenModal = ({
10326
+ tokens,
10327
+ onClose,
10328
+ title,
10329
+ onSelectToken,
10330
+ balanceType
10331
+ }) => {
10332
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
10333
+ PageContainer,
10334
+ {
10335
+ isModal: true,
10336
+ header: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("button", { onClick: onClose, className: "flex items-center gap-1 text-sm hover:opacity-80 transition-opacity", children: [
10337
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ArrowBackIcon, { style: { fontSize: 16 } }),
10338
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("p", { className: "text-sm font-medium", children: title })
10339
+ ] }),
10340
+ content: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
10341
+ ImportCustomTokenCard,
10342
+ {
10343
+ balanceType,
10344
+ tokens,
10345
+ onSelectToken: (token) => {
10346
+ onSelectToken(token);
10347
+ onClose();
10348
+ }
10349
+ }
10350
+ )
10351
+ }
10352
+ );
10353
+ };
10354
+
9908
10355
  // src/components/CofheFloatingButton/modals/index.ts
9909
10356
  var modals = {
9910
10357
  ["exampleSelection" /* ExampleSelection */]: ExampleSelectionPage,
@@ -9912,15 +10359,16 @@ var modals = {
9912
10359
  ["permitDetails" /* PermitDetails */]: PermitDetailsModal,
9913
10360
  ["permitTypeInfo" /* PermitTypeInfo */]: PermitTypeInfoModal,
9914
10361
  ["permitInfo" /* PermitInfo */]: PermitInfoModal,
9915
- ["tokenList" /* TokenList */]: TokenListModal
10362
+ ["tokenList" /* TokenList */]: TokenListModal,
10363
+ ["importCustomToken" /* ImportCustomToken */]: ImportCustomTokenModal
9916
10364
  };
9917
10365
 
9918
10366
  // src/components/CofheFloatingButton/ContentSection.tsx
9919
- var import_jsx_runtime63 = require("react/jsx-runtime");
10367
+ var import_jsx_runtime66 = require("react/jsx-runtime");
9920
10368
  var MeasuredContentRenderer = ({ children, id, isModal, onModalOverlayClick }) => {
9921
10369
  const { setContentHeight, removeContentHeight } = usePortalUI();
9922
- const contentRef = (0, import_react59.useRef)(null);
9923
- (0, import_react59.useEffect)(() => {
10370
+ const contentRef = (0, import_react60.useRef)(null);
10371
+ (0, import_react60.useEffect)(() => {
9924
10372
  if (!contentRef.current) return;
9925
10373
  const observer = new ResizeObserver((entries) => {
9926
10374
  for (const entry of entries) {
@@ -9934,8 +10382,8 @@ var MeasuredContentRenderer = ({ children, id, isModal, onModalOverlayClick }) =
9934
10382
  removeContentHeight(id);
9935
10383
  };
9936
10384
  }, [id]);
9937
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
9938
- isModal && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
10385
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(import_jsx_runtime66.Fragment, { children: [
10386
+ isModal && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
9939
10387
  "div",
9940
10388
  {
9941
10389
  onClick: (e) => {
@@ -9946,23 +10394,23 @@ var MeasuredContentRenderer = ({ children, id, isModal, onModalOverlayClick }) =
9946
10394
  className: "absolute flex w-full h-full bg-[#0E2F3F]/30 origin-top translate-y-[-8px] scale-[0.95]"
9947
10395
  }
9948
10396
  ),
9949
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "relative flex w-full h-full overflow-y-hidden pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: cn("cofhe-panel absolute flex left-0 w-full p-4 top-0 pointer-events-auto"), ref: contentRef, children }) })
10397
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "relative flex w-full h-full overflow-y-hidden pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: cn("cofhe-panel absolute flex left-0 w-full p-4 top-0 pointer-events-auto"), ref: contentRef, children }) })
9950
10398
  ] });
9951
10399
  };
9952
10400
  var ContentRenderer = ({ page }) => {
9953
- const content = (0, import_react59.useMemo)(() => {
10401
+ const content = (0, import_react60.useMemo)(() => {
9954
10402
  const PageComp = pages[page.page];
9955
10403
  const props = page.props ?? {};
9956
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(PageComp, { ...props });
10404
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(PageComp, { ...props });
9957
10405
  }, [page]);
9958
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(MeasuredContentRenderer, { id: "content", children: content });
10406
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(MeasuredContentRenderer, { id: "content", children: content });
9959
10407
  };
9960
10408
  var ModalRenderer = ({ modal }) => {
9961
- const content = (0, import_react59.useMemo)(() => {
10409
+ const content = (0, import_react60.useMemo)(() => {
9962
10410
  const ModalComp = modals[modal.modal];
9963
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ModalComp, { ...modal });
10411
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ModalComp, { ...modal });
9964
10412
  }, [modal]);
9965
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(MeasuredContentRenderer, { id: `${modal.modal}-modal`, isModal: true, onModalOverlayClick: modal.onClose, children: content });
10413
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(MeasuredContentRenderer, { id: `${modal.modal}-modal`, isModal: true, onModalOverlayClick: modal.onClose, children: content });
9966
10414
  };
9967
10415
  var ContentSection = ({ overriddingPage }) => {
9968
10416
  const { isTopSide } = useCofheFloatingButtonContext();
@@ -9971,17 +10419,17 @@ var ContentSection = ({ overriddingPage }) => {
9971
10419
  const maxContentHeight = usePortalUIMaxContentHeight();
9972
10420
  const currentPage = usePortalCurrentPage();
9973
10421
  const pageOrOverridingPage = overriddingPage ?? currentPage;
9974
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_react60.AnimatePresence, { children: contentPanelOpen && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
9975
- import_react60.motion.div,
10422
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_react61.AnimatePresence, { children: contentPanelOpen && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
10423
+ import_react61.motion.div,
9976
10424
  {
9977
10425
  className: "relative flex w-full z-50",
9978
10426
  initial: { opacity: 0, y: isTopSide ? -10 : 10 },
9979
10427
  animate: { opacity: 1, y: 0, height: `${maxContentHeight}px`, maxHeight: `${maxContentHeight}px` },
9980
10428
  exit: { opacity: 0, y: isTopSide ? -10 : 10 },
9981
- children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(AnimatedZStack, { children: [
9982
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ContentRenderer, { page: pageOrOverridingPage }),
10429
+ children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(AnimatedZStack, { children: [
10430
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ContentRenderer, { page: pageOrOverridingPage }),
9983
10431
  modalStack.map((modal) => {
9984
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ModalRenderer, { modal }, modal.modal);
10432
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ModalRenderer, { modal }, modal.modal);
9985
10433
  })
9986
10434
  ] })
9987
10435
  }
@@ -9989,13 +10437,13 @@ var ContentSection = ({ overriddingPage }) => {
9989
10437
  };
9990
10438
 
9991
10439
  // src/components/CofheFloatingButton/ToastsSection.tsx
9992
- var import_react61 = require("react");
9993
- var import_react62 = require("motion/react");
9994
- var import_jsx_runtime64 = require("react/jsx-runtime");
10440
+ var import_react62 = require("react");
10441
+ var import_react63 = require("motion/react");
10442
+ var import_jsx_runtime67 = require("react/jsx-runtime");
9995
10443
  var ToastClearer = ({ id, paused, remainingMs }) => {
9996
10444
  const { removeToast } = usePortalToasts();
9997
- const timerRef = (0, import_react61.useRef)(null);
9998
- (0, import_react61.useEffect)(() => {
10445
+ const timerRef = (0, import_react62.useRef)(null);
10446
+ (0, import_react62.useEffect)(() => {
9999
10447
  if (remainingMs <= 0) {
10000
10448
  removeToast(id);
10001
10449
  return;
@@ -10031,7 +10479,7 @@ var ToastComponent = ({
10031
10479
  const handleDismiss = () => {
10032
10480
  removeToast(id);
10033
10481
  };
10034
- const injectedContent = (0, import_react61.isValidElement)(content) ? (0, import_react61.cloneElement)(content, {
10482
+ const injectedContent = (0, import_react62.isValidElement)(content) ? (0, import_react62.cloneElement)(content, {
10035
10483
  id,
10036
10484
  paused,
10037
10485
  startMs,
@@ -10041,8 +10489,8 @@ var ToastComponent = ({
10041
10489
  onDismiss: handleDismiss,
10042
10490
  ...content.props
10043
10491
  }) : content;
10044
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
10045
- import_react62.motion.div,
10492
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
10493
+ import_react63.motion.div,
10046
10494
  {
10047
10495
  initial: { opacity: 0, y: isTopSide ? -4 : 4 },
10048
10496
  animate: { opacity: 1, y: 0 },
@@ -10051,7 +10499,7 @@ var ToastComponent = ({
10051
10499
  className: cn("min-h-8 bg-white border items-center justify-start w-full max-w-full"),
10052
10500
  children: [
10053
10501
  injectedContent,
10054
- duration != "infinite" && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ToastClearer, { id, paused, remainingMs })
10502
+ duration != "infinite" && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ToastClearer, { id, paused, remainingMs })
10055
10503
  ]
10056
10504
  },
10057
10505
  id
@@ -10059,11 +10507,11 @@ var ToastComponent = ({
10059
10507
  };
10060
10508
  var ToastsSection = () => {
10061
10509
  const { toasts } = usePortalToasts();
10062
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "flex flex-col gap-3 w-full max-w-full", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react62.AnimatePresence, { children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ToastComponent, { ...toast }, toast.id)) }) });
10510
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "flex flex-col gap-3 w-full max-w-full", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_react63.AnimatePresence, { children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ToastComponent, { ...toast }, toast.id)) }) });
10063
10511
  };
10064
10512
 
10065
10513
  // src/components/CofheFloatingButton/CofheFloatingButtonBase.tsx
10066
- var import_jsx_runtime65 = require("react/jsx-runtime");
10514
+ var import_jsx_runtime68 = require("react/jsx-runtime");
10067
10515
  var positionStyles = {
10068
10516
  "top-left": "top-4 left-4",
10069
10517
  "top-right": "top-4 right-4",
@@ -10082,7 +10530,7 @@ var CofheFloatingButtonBase = ({
10082
10530
  const { clearAllModals } = usePortalModals();
10083
10531
  const { clearNavigationHistory } = usePortalNavigation();
10084
10532
  const darkMode = theme === "dark";
10085
- return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
10533
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
10086
10534
  "div",
10087
10535
  {
10088
10536
  "data-testid": testId,
@@ -10098,10 +10546,10 @@ var CofheFloatingButtonBase = ({
10098
10546
  className
10099
10547
  ),
10100
10548
  children: [
10101
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ToastsSection, {}),
10102
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ContentSection, { overriddingPage }),
10103
- /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: cn("flex w-full gap-3 items-center", isLeftSide ? "flex-row" : "flex-row-reverse"), children: [
10104
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
10549
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ToastsSection, {}),
10550
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContentSection, { overriddingPage }),
10551
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: cn("flex w-full gap-3 items-center", isLeftSide ? "flex-row" : "flex-row-reverse"), children: [
10552
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
10105
10553
  FloatingButtonComponent,
10106
10554
  {
10107
10555
  onClick: () => togglePortal({
@@ -10112,7 +10560,7 @@ var CofheFloatingButtonBase = ({
10112
10560
  })
10113
10561
  }
10114
10562
  ),
10115
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(StatusBarSection, { children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(StatusBarContent, {}) })
10563
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StatusBarSection, { children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StatusBarContent, {}) })
10116
10564
  ] })
10117
10565
  ]
10118
10566
  }
@@ -10120,10 +10568,10 @@ var CofheFloatingButtonBase = ({
10120
10568
  };
10121
10569
 
10122
10570
  // src/components/CofheFloatingButton/CofheFloatingButton.tsx
10123
- var import_jsx_runtime66 = require("react/jsx-runtime");
10571
+ var import_jsx_runtime69 = require("react/jsx-runtime");
10124
10572
  var CofheFloatingButtonWithProvider = (props) => {
10125
- return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(CofheFloatingButtonProvider, { children: [
10126
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CofheFloatingButtonBase, { ...props }),
10573
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(CofheFloatingButtonProvider, { children: [
10574
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(CofheFloatingButtonBase, { ...props }),
10127
10575
  props.children
10128
10576
  ] });
10129
10577
  };
@@ -10132,7 +10580,7 @@ var CofheFloatingButtonWithProvider = (props) => {
10132
10580
  var import_zod = require("zod");
10133
10581
  var import_sdk10 = require("@cofhe/sdk");
10134
10582
  var import_web2 = require("@cofhe/sdk/web");
10135
- var import_viem26 = require("viem");
10583
+ var import_viem28 = require("viem");
10136
10584
  var noopCofheReactLoggerMethod2 = (..._args) => {
10137
10585
  };
10138
10586
  var NOOP_COFHE_REACT_LOGGER = {
@@ -10158,11 +10606,11 @@ function resolveCofheReactLogger(logger) {
10158
10606
  var CofheReactLoggerSchema = import_zod.z.custom((value) => value === null || typeof value === "object" && value !== null, {
10159
10607
  error: "Invalid logger"
10160
10608
  }).optional().default(null).transform((value) => resolveCofheReactLogger(value));
10161
- var addressSchema = import_zod.z.string().refine((val) => (0, import_viem26.isAddress)(val), {
10609
+ var addressSchema = import_zod.z.string().refine((val) => (0, import_viem28.isAddress)(val), {
10162
10610
  error: "Invalid address"
10163
- }).refine((val) => val !== import_viem26.zeroAddress, {
10611
+ }).refine((val) => val !== import_viem28.zeroAddress, {
10164
10612
  error: "Must not be zeroAddress"
10165
- }).transform((val) => (0, import_viem26.getAddress)(val));
10613
+ }).transform((val) => (0, import_viem28.getAddress)(val));
10166
10614
  var CofheReactConfigSchema = import_zod.z.object({
10167
10615
  shareablePermits: import_zod.z.boolean().optional().default(false),
10168
10616
  enableShieldUnshield: import_zod.z.boolean().optional().default(true),
@@ -10208,11 +10656,11 @@ function createCofheConfig(config) {
10208
10656
  // src/providers/CofheProvider.tsx
10209
10657
  var import_chains5 = require("@cofhe/sdk/chains");
10210
10658
  var import_ts_essentials25 = __toESM(require_dist(), 1);
10211
- var import_jsx_runtime67 = require("react/jsx-runtime");
10212
- var CofheContext = (0, import_react63.createContext)(void 0);
10659
+ var import_jsx_runtime70 = require("react/jsx-runtime");
10660
+ var CofheContext = (0, import_react64.createContext)(void 0);
10213
10661
  function CofheProvider(props) {
10214
10662
  const { children, queryClient, publicClient, walletClient } = props;
10215
- const config = (0, import_react63.useMemo)(() => {
10663
+ const config = (0, import_react64.useMemo)(() => {
10216
10664
  if (props.config) return props.config;
10217
10665
  if (props.cofheClient) {
10218
10666
  (0, import_ts_essentials25.assert)(props.cofheClient.config.environment === "react", "Provided cofheClient must have react config");
@@ -10220,10 +10668,10 @@ function CofheProvider(props) {
10220
10668
  }
10221
10669
  return createCofheConfig({ supportedChains: Object.values(import_chains5.chains) });
10222
10670
  }, [props.config, props.cofheClient]);
10223
- const cofheClient = (0, import_react63.useMemo)(() => props.cofheClient ?? (0, import_web3.createCofheClient)(config), [props.cofheClient, config]);
10224
- const [position, setPosition] = (0, import_react63.useState)(config.react.position);
10225
- const [theme, setTheme] = (0, import_react63.useState)(config.react.initialTheme);
10226
- return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
10671
+ const cofheClient = (0, import_react64.useMemo)(() => props.cofheClient ?? (0, import_web3.createCofheClient)(config), [props.cofheClient, config]);
10672
+ const [position, setPosition] = (0, import_react64.useState)(config.react.position);
10673
+ const [theme, setTheme] = (0, import_react64.useState)(config.react.initialTheme);
10674
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
10227
10675
  CofheContext.Provider,
10228
10676
  {
10229
10677
  value: {
@@ -10235,9 +10683,9 @@ function CofheProvider(props) {
10235
10683
  setTheme
10236
10684
  }
10237
10685
  },
10238
- children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(QueryProvider, { queryClient, children: [
10239
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(AutoConnect, { walletClient, publicClient }),
10240
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(CofheFloatingButtonWithProvider, { children })
10686
+ children: /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(QueryProvider, { queryClient, children: [
10687
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(AutoConnect, { walletClient, publicClient }),
10688
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CofheFloatingButtonWithProvider, { children })
10241
10689
  ] })
10242
10690
  }
10243
10691
  );
@@ -10247,7 +10695,7 @@ function AutoConnect({ walletClient, publicClient }) {
10247
10695
  return null;
10248
10696
  }
10249
10697
  function useCofheContext() {
10250
- const context = (0, import_react63.useContext)(CofheContext);
10698
+ const context = (0, import_react64.useContext)(CofheContext);
10251
10699
  if (context === void 0) {
10252
10700
  throw new Error("useCofheContext must be used within a CofheProvider");
10253
10701
  }
@@ -10255,9 +10703,9 @@ function useCofheContext() {
10255
10703
  }
10256
10704
 
10257
10705
  // src/components/CofheEncryptInput.tsx
10258
- var import_react64 = require("react");
10706
+ var import_react65 = require("react");
10259
10707
  var import_sdk11 = require("@cofhe/sdk");
10260
- var import_jsx_runtime68 = require("react/jsx-runtime");
10708
+ var import_jsx_runtime71 = require("react/jsx-runtime");
10261
10709
  var CofheEncryptInput = ({
10262
10710
  className,
10263
10711
  testId,
@@ -10277,30 +10725,30 @@ var CofheEncryptInput = ({
10277
10725
  onEncryptComplete,
10278
10726
  onEncryptError
10279
10727
  }) => {
10280
- const [textValue, setTextValue] = (0, import_react64.useState)(initialValue);
10281
- const [selectedType, setSelectedType] = (0, import_react64.useState)(options[0]?.value || "uint32");
10282
- const [isDropdownOpen, setIsDropdownOpen] = (0, import_react64.useState)(false);
10283
- const [showProgress, setShowProgress] = (0, import_react64.useState)(false);
10284
- const [encryptedResult, setEncryptedResult] = (0, import_react64.useState)(null);
10285
- const [copySuccess, setCopySuccess] = (0, import_react64.useState)(false);
10286
- const dropdownRef = (0, import_react64.useRef)(null);
10728
+ const [textValue, setTextValue] = (0, import_react65.useState)(initialValue);
10729
+ const [selectedType, setSelectedType] = (0, import_react65.useState)(options[0]?.value || "uint32");
10730
+ const [isDropdownOpen, setIsDropdownOpen] = (0, import_react65.useState)(false);
10731
+ const [showProgress, setShowProgress] = (0, import_react65.useState)(false);
10732
+ const [encryptedResult, setEncryptedResult] = (0, import_react65.useState)(null);
10733
+ const [copySuccess, setCopySuccess] = (0, import_react65.useState)(false);
10734
+ const dropdownRef = (0, import_react65.useRef)(null);
10287
10735
  const {
10288
10736
  encryptInputsAsync: encrypt,
10289
10737
  isEncrypting,
10290
10738
  stepsState: { lastStep: lastEncryptionStep }
10291
10739
  } = useCofheEncrypt();
10292
- const { progress: encryptionProgress, label: encryptionProgressLabel } = (0, import_react64.useMemo)(() => {
10740
+ const { progress: encryptionProgress, label: encryptionProgressLabel } = (0, import_react65.useMemo)(() => {
10293
10741
  return lastEncryptionStep ? getStepConfig(lastEncryptionStep) : {
10294
10742
  progress: void 0,
10295
10743
  label: void 0
10296
10744
  };
10297
10745
  }, [lastEncryptionStep]);
10298
- const debouncedValidation = (0, import_react64.useRef)(
10746
+ const debouncedValidation = (0, import_react65.useRef)(
10299
10747
  debounce((value) => {
10300
10748
  cofheLogger.log("Debounced validation for:", value);
10301
10749
  }, debounceMs)
10302
10750
  ).current;
10303
- (0, import_react64.useEffect)(() => {
10751
+ (0, import_react65.useEffect)(() => {
10304
10752
  if (showProgressBar && isEncrypting) {
10305
10753
  setShowProgress(true);
10306
10754
  } else if (!isEncrypting) {
@@ -10308,7 +10756,7 @@ var CofheEncryptInput = ({
10308
10756
  return () => clearTimeout(timer);
10309
10757
  }
10310
10758
  }, [showProgressBar, isEncrypting]);
10311
- (0, import_react64.useEffect)(() => {
10759
+ (0, import_react65.useEffect)(() => {
10312
10760
  if (isEncrypting && lastEncryptionStep && encryptionProgress && encryptionProgressLabel) {
10313
10761
  onEncryptProgress?.({
10314
10762
  step: lastEncryptionStep.step,
@@ -10317,7 +10765,7 @@ var CofheEncryptInput = ({
10317
10765
  });
10318
10766
  }
10319
10767
  }, [encryptionProgress, encryptionProgressLabel, onEncryptProgress, isEncrypting, lastEncryptionStep]);
10320
- (0, import_react64.useEffect)(() => {
10768
+ (0, import_react65.useEffect)(() => {
10321
10769
  const handleClickOutside = (event) => {
10322
10770
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
10323
10771
  setIsDropdownOpen(false);
@@ -10461,12 +10909,12 @@ var CofheEncryptInput = ({
10461
10909
  setIsDropdownOpen(!isDropdownOpen);
10462
10910
  }
10463
10911
  };
10464
- const ShieldIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(SecurityIcon, { style: { fontSize: 14 } });
10465
- const ChevronDownIcon = () => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(KeyboardArrowDownIcon, { style: { fontSize: 14 } });
10466
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "w-full", children: [
10467
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "flex items-start gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex-1", children: [
10468
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: inputContainerClasses, "data-testid": testId, children: [
10469
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
10912
+ const ShieldIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(SecurityIcon, { style: { fontSize: 14 } });
10913
+ const ChevronDownIcon = () => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(KeyboardArrowDownIcon, { style: { fontSize: 14 } });
10914
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "w-full", children: [
10915
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "flex items-start gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "flex-1", children: [
10916
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: inputContainerClasses, "data-testid": testId, children: [
10917
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
10470
10918
  "input",
10471
10919
  {
10472
10920
  type: "text",
@@ -10478,21 +10926,21 @@ var CofheEncryptInput = ({
10478
10926
  "data-testid": testId ? `${testId}-input` : "cofhe-encrypt-input"
10479
10927
  }
10480
10928
  ),
10481
- (isEncrypting || encryptedResult) && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "absolute right-16 top-1/2 transform -translate-y-1/2", children: isEncrypting ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "bg-blue-500 px-2 py-1 text-xs text-white rounded animate-pulse", children: "Encrypting..." }) : encryptedResult ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
10929
+ (isEncrypting || encryptedResult) && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "absolute right-16 top-1/2 transform -translate-y-1/2", children: isEncrypting ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "bg-blue-500 px-2 py-1 text-xs text-white rounded animate-pulse", children: "Encrypting..." }) : encryptedResult ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
10482
10930
  "button",
10483
10931
  {
10484
10932
  onClick: handleCopyResult,
10485
10933
  disabled: copySuccess,
10486
10934
  className: `px-2 py-1 text-xs text-white rounded flex items-center gap-1 transition-all duration-300 ${copySuccess ? "bg-green-600 cursor-default" : "bg-green-500 hover:bg-green-600"}`,
10487
10935
  title: copySuccess ? "Copied to clipboard!" : "Copy encrypted result to clipboard",
10488
- children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
10489
- copySuccess ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(CheckIcon, { style: { fontSize: 12 } }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContentCopyIcon, { style: { fontSize: 12 } }),
10936
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
10937
+ copySuccess ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(CheckIcon, { style: { fontSize: 12 } }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ContentCopyIcon, { style: { fontSize: 12 } }),
10490
10938
  "Copy"
10491
10939
  ] })
10492
10940
  }
10493
10941
  ) : null }),
10494
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "cofhe-dropdown-container", ref: dropdownRef, children: [
10495
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
10942
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "cofhe-dropdown-container", ref: dropdownRef, children: [
10943
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
10496
10944
  "button",
10497
10945
  {
10498
10946
  type: "button",
@@ -10501,29 +10949,29 @@ var CofheEncryptInput = ({
10501
10949
  disabled: disabled || isEncrypting,
10502
10950
  "data-testid": testId ? `${testId}-type-selector` : "cofhe-type-selector",
10503
10951
  children: [
10504
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ShieldIcon2, {}),
10505
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ChevronDownIcon, {})
10952
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ShieldIcon2, {}),
10953
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ChevronDownIcon, {})
10506
10954
  ]
10507
10955
  }
10508
10956
  ),
10509
- isDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "cofhe-dropdown-menu", children: options.map((option) => {
10957
+ isDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "cofhe-dropdown-menu", children: options.map((option) => {
10510
10958
  const isCompatible = isTypeCompatible(option.value, textValue);
10511
10959
  const isSelected = option.value === selectedType;
10512
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
10960
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
10513
10961
  "div",
10514
10962
  {
10515
10963
  className: dropdownItemClasses(isSelected, isCompatible),
10516
10964
  onClick: () => isCompatible && handleTypeSelect(option.value),
10517
10965
  "data-testid": `${testId ? `${testId}-` : ""}type-option-${option.value}`,
10518
10966
  title: !isCompatible ? `Value "${textValue}" is not compatible with ${option.label}` : void 0,
10519
- children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "font-mono", children: option.label })
10967
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "font-mono", children: option.label })
10520
10968
  },
10521
10969
  option.value
10522
10970
  );
10523
10971
  }) })
10524
10972
  ] })
10525
10973
  ] }),
10526
- showProgress && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
10974
+ showProgress && /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
10527
10975
  "div",
10528
10976
  {
10529
10977
  className: "mt-3 overflow-hidden",
@@ -10532,14 +10980,14 @@ var CofheEncryptInput = ({
10532
10980
  },
10533
10981
  "data-testid": testId ? `${testId}-progress` : "cofhe-encrypt-progress",
10534
10982
  children: [
10535
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex justify-between items-center mb-1", children: [
10536
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: encryptionProgressLabel || "Processing..." }),
10537
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
10983
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "flex justify-between items-center mb-1", children: [
10984
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: encryptionProgressLabel || "Processing..." }),
10985
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
10538
10986
  encryptionProgress || 0,
10539
10987
  "%"
10540
10988
  ] })
10541
10989
  ] }),
10542
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: progressContainerClasses, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
10990
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: progressContainerClasses, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
10543
10991
  "div",
10544
10992
  {
10545
10993
  className: progressBarClasses("primary"),
@@ -10554,7 +11002,7 @@ var CofheEncryptInput = ({
10554
11002
  }
10555
11003
  )
10556
11004
  ] }) }),
10557
- hasError && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
11005
+ hasError && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
10558
11006
  "p",
10559
11007
  {
10560
11008
  className: "mt-2 text-sm text-red-600 dark:text-red-400",