@naculus/connect-appkit-react 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/chain-abstraction/useCompareCosts.ts","../src/chain-abstraction/useExecuteRoute.ts","../src/chain-abstraction/useRouteQuote.ts","../src/client.ts","../src/hooks/useAccount.ts","../src/provider/Web3ConnectProvider.tsx","../src/core/siwx-flow.ts","../src/hooks/siwx-accounts.ts","../src/utils/chains.ts","../src/hooks/useAuthorizations.ts","../src/hooks/useBalance.ts","../src/hooks/useCapabilities.ts","../src/hooks/client-resolver.ts","../src/hooks/useChain.ts","../src/hooks/useConnect.ts","../src/hooks/useDelegate.ts","../src/hooks/useViemClient.ts","../src/hooks/usePaymentFetch.ts","../src/hooks/useX402Signer.ts","../src/hooks/useMppSession.ts","../src/hooks/useSolanaSessionKey.ts","../src/hooks/useDelegation.ts","../src/hooks/useDelegationPolicy.ts","../src/hooks/useExecuteCalls.ts","../src/hooks/useSendCalls.ts","../src/hooks/transaction-hash.ts","../src/hooks/useSessionKeys.ts","../src/hooks/useSignMessage.ts","../src/hooks/useDisconnect.ts","../src/hooks/useEmbeddedWallet.ts","../src/hooks/useERC20Allowance.ts","../src/hooks/useERC20Context.ts","../src/hooks/useERC20Approve.ts","../src/hooks/useSendTransaction.ts","../src/hooks/useERC20Transfer.ts","../src/hooks/useERC20TransferSimulation.ts","../src/hooks/useTransactionSimulation.ts","../src/hooks/useLastTx.ts","../src/hooks/useTxMonitor.ts","../src/hooks/useLookupAddress.ts","../src/core/name-lookup.ts","../src/hooks/useNotification.ts","../src/hooks/usePassphraseGate.ts","../src/hooks/useResolveName.ts","../src/hooks/useSendUserOperation.ts","../src/hooks/useSession.ts","../src/hooks/useSIWxLogin.ts","../src/hooks/useSIWxSession.ts","../src/hooks/useSignInWithX.ts","../src/hooks/useSignInWithEthereum.ts","../src/hooks/useSimulateTransfer.ts","../src/hooks/useSiwxAuthSession.ts","../src/hooks/useSmartAccount.ts","../src/hooks/useSolanaAccount.ts","../src/hooks/useSolanaBalance.ts","../src/hooks/useSolanaRoles.ts","../src/hooks/useSolanaTransaction.ts","../src/hooks/useSwitchChain.ts","../src/hooks/useTokenBalance.ts","../src/hooks/useTxHistory.ts","../src/hooks/useUserOpStatus.ts","../src/hooks/useValidateDestination.ts","../src/utils/i18n.ts","../src/hooks/useWallet.ts","../src/hooks/useWeb3ErrorHandler.ts","../src/utils/errorMessages.ts","../src/token-list/useTokenList.ts","../src/token-list/useTokenSearch.ts","../src/token-list/defaults.ts","../src/token-list/TokenSelector.tsx","../src/wc-generated/components.ts"],"sourcesContent":["export type {\n PassphraseIntent,\n PassphraseRequest,\n SolanaBalance,\n SolanaConfirmationStatus,\n} from \"@naculus/connect-core\";\n// Re-exported from connect-core, where it lives so the Vue layer can use the\n// same object. Kept exported here so a React consumer never has to know that.\n// Re-exported from connect-core, where the framework-neutral half lives so a\n// Vue composable can use it unchanged. A React consumer never has to know.\nexport {\n formatSol,\n getLatestBlockhash,\n getSignatureStatus,\n getSolanaBalance,\n LAMPORTS_PER_SOL,\n PassphraseCancelledError,\n PassphraseGate,\n parseSol,\n SolanaRpcError,\n} from \"@naculus/connect-core\";\n// Re-exported so a UI package can name what the hook returns without taking a\n// direct dependency on the connector layer.\nexport type {\n StorageSecurityFinding,\n StorageSecurityReport,\n WalletAccount,\n WalletData,\n WalletNamespace,\n} from \"@naculus/connector-embedded\";\nexport type {\n CostComparison,\n CostComparisonOperation,\n CostComparisonOptions,\n ExecuteError,\n ExecuteOptions,\n ExecuteRouteResult,\n Quote,\n QuoteOptions,\n UseCompareCostsInput,\n UseCompareCostsReturn,\n UseExecuteRouteReturn,\n UseRouteQuoteInput,\n UseRouteQuoteReturn,\n} from \"./chain-abstraction\";\nexport {\n useCompareCosts,\n useExecuteRoute,\n useRouteQuote,\n} from \"./chain-abstraction\";\nexport type {\n ClientConfig,\n InjectedProviderRegistration,\n NativeWalletConnectOptions,\n Web3Client,\n} from \"./client\";\nexport { clearClient, createClient, getClient } from \"./client\";\nexport { useAccount } from \"./hooks/useAccount\";\nexport type {\n UseAuthorizationsOptions,\n UseAuthorizationsReturn,\n} from \"./hooks/useAuthorizations\";\nexport { useAuthorizations } from \"./hooks/useAuthorizations\";\nexport { useBalance } from \"./hooks/useBalance\";\nexport type {\n AtomicSupport,\n ChainCapabilities,\n UseCapabilitiesReturn,\n} from \"./hooks/useCapabilities\";\nexport { useCapabilities } from \"./hooks/useCapabilities\";\nexport { useChain } from \"./hooks/useChain\";\nexport { useConnect } from \"./hooks/useConnect\";\nexport type {\n UseDelegateOptions,\n UseDelegateReturn,\n} from \"./hooks/useDelegate\";\nexport { useDelegate } from \"./hooks/useDelegate\";\nexport type {\n UsePaymentFetchOptions,\n UsePaymentFetchReturn,\n} from \"./hooks/usePaymentFetch\";\nexport { usePaymentFetch } from \"./hooks/usePaymentFetch\";\nexport { useX402Signer } from \"./hooks/useX402Signer\";\nexport type { UseX402SignerReturn } from \"./hooks/useX402Signer\";\nexport type { UseMppSessionReturn } from \"./hooks/useMppSession\";\nexport { useMppSession } from \"./hooks/useMppSession\";\nexport type { UseSolanaSessionKeyReturn } from \"./hooks/useSolanaSessionKey\";\nexport { useSolanaSessionKey } from \"./hooks/useSolanaSessionKey\";\nexport type { UseDelegationReturn } from \"./hooks/useDelegation\";\nexport { useDelegation } from \"./hooks/useDelegation\";\nexport type {\n DelegationPolicyPreview,\n PolicyExecutionAdapter,\n PolicyExecutionCheck,\n PolicyExecutionRoute,\n PolicyExecutionSubmission,\n PreparedPolicyExecution,\n UseDelegationPolicyOptions,\n UseDelegationPolicyReturn,\n} from \"./hooks/useDelegationPolicy\";\nexport {\n buildDelegationPolicyMessage,\n useDelegationPolicy,\n} from \"./hooks/useDelegationPolicy\";\nexport { useDisconnect } from \"./hooks/useDisconnect\";\nexport type {\n EmbeddedWalletAccountView,\n EmbeddedWalletView,\n UseEmbeddedWalletReturn,\n} from \"./hooks/useEmbeddedWallet\";\nexport { useEmbeddedWallet } from \"./hooks/useEmbeddedWallet\";\nexport type {\n UseERC20AllowanceOptions,\n UseERC20AllowanceReturn,\n} from \"./hooks/useERC20Allowance\";\nexport { useERC20Allowance } from \"./hooks/useERC20Allowance\";\nexport type {\n UseERC20ApproveOptions,\n UseERC20ApproveReturn,\n} from \"./hooks/useERC20Approve\";\nexport { useERC20Approve } from \"./hooks/useERC20Approve\";\nexport type {\n UseERC20TransferOptions,\n UseERC20TransferReturn,\n} from \"./hooks/useERC20Transfer\";\nexport { useERC20Transfer } from \"./hooks/useERC20Transfer\";\nexport type {\n UseERC20TransferSimulationOptions,\n UseERC20TransferSimulationReturn,\n} from \"./hooks/useERC20TransferSimulation\";\nexport { useERC20TransferSimulation } from \"./hooks/useERC20TransferSimulation\";\nexport type {\n ExecutionPreview,\n ExecutionRoute,\n UseExecuteCallsOptions,\n UseExecuteCallsReturn,\n} from \"./hooks/useExecuteCalls\";\nexport { useExecuteCalls } from \"./hooks/useExecuteCalls\";\nexport type { UseLastTxResult } from \"./hooks/useLastTx\";\nexport { useLastTx } from \"./hooks/useLastTx\";\nexport type {\n UseLookupAddressOptions,\n UseLookupAddressResult,\n} from \"./hooks/useLookupAddress\";\nexport { useLookupAddress } from \"./hooks/useLookupAddress\";\nexport { useNotification } from \"./hooks/useNotification\";\nexport type { UsePassphraseGateReturn } from \"./hooks/usePassphraseGate\";\nexport { usePassphraseGate } from \"./hooks/usePassphraseGate\";\nexport type {\n UseResolveNameOptions,\n UseResolveNameResult,\n} from \"./hooks/useResolveName\";\nexport { useResolveName } from \"./hooks/useResolveName\";\nexport type { SendCallsStatus } from \"./hooks/useSendCalls\";\nexport { useSendCalls } from \"./hooks/useSendCalls\";\nexport { useSendTransaction } from \"./hooks/useSendTransaction\";\nexport type {\n UseSendUserOperationOptions,\n UseSendUserOperationReturn,\n} from \"./hooks/useSendUserOperation\";\nexport { useSendUserOperation } from \"./hooks/useSendUserOperation\";\nexport type { UseSessionReturn } from \"./hooks/useSession\";\nexport { useSession } from \"./hooks/useSession\";\nexport type {\n UseCreateSessionKeyReturn,\n UseRevokeSessionReturn,\n UseSendWithSessionReturn,\n UseSessionKeysReturn,\n} from \"./hooks/useSessionKeys\";\nexport {\n resetSessionKeyManager,\n useCreateSessionKey,\n useRevokeSession,\n useSendWithSession,\n useSessionKeys,\n} from \"./hooks/useSessionKeys\";\nexport type {\n UseSIWxLoginOptions,\n UseSIWxLoginReturn,\n} from \"./hooks/useSIWxLogin\";\nexport { useSIWxLogin } from \"./hooks/useSIWxLogin\";\nexport type {\n UseSIWxSessionOptions,\n UseSIWxSessionReturn,\n} from \"./hooks/useSIWxSession\";\nexport { useSIWxSession } from \"./hooks/useSIWxSession\";\nexport type {\n UseSignInWithEthereumOptions,\n UseSignInWithEthereumReturn,\n} from \"./hooks/useSignInWithEthereum\";\nexport { useSignInWithEthereum } from \"./hooks/useSignInWithEthereum\";\nexport type {\n UseSignInWithXOptions,\n UseSignInWithXReturn,\n} from \"./hooks/useSignInWithX\";\nexport { useSignInWithX } from \"./hooks/useSignInWithX\";\nexport { useSignMessage } from \"./hooks/useSignMessage\";\nexport type {\n UseSimulateTransferOptions,\n UseSimulateTransferReturn,\n} from \"./hooks/useSimulateTransfer\";\nexport { useSimulateTransfer } from \"./hooks/useSimulateTransfer\";\nexport type {\n UseSiwxAuthSessionOptions,\n UseSiwxAuthSessionReturn,\n} from \"./hooks/useSiwxAuthSession\";\nexport { useSiwxAuthSession } from \"./hooks/useSiwxAuthSession\";\nexport type {\n UseSmartAccountOptions,\n UseSmartAccountReturn,\n} from \"./hooks/useSmartAccount\";\nexport { useSmartAccount } from \"./hooks/useSmartAccount\";\nexport type { UseSolanaAccountReturn } from \"./hooks/useSolanaAccount\";\n// ── Solana ────────────────────────────────────────────────────────\nexport { useSolanaAccount } from \"./hooks/useSolanaAccount\";\nexport type {\n UseSolanaBalanceOptions,\n UseSolanaBalanceReturn,\n} from \"./hooks/useSolanaBalance\";\nexport { useSolanaBalance } from \"./hooks/useSolanaBalance\";\nexport type {\n SolanaIdentity,\n SolanaPayer,\n SolanaRoles,\n SolanaRolesAbsence,\n SolanaSigner,\n SolanaWalletFeatures,\n UseSolanaRolesReturn,\n} from \"./hooks/useSolanaRoles\";\nexport { useSolanaRoles } from \"./hooks/useSolanaRoles\";\nexport type { UseSolanaTransactionReturn } from \"./hooks/useSolanaTransaction\";\nexport { useSolanaTransaction } from \"./hooks/useSolanaTransaction\";\nexport type { UseSwitchChainReturn } from \"./hooks/useSwitchChain\";\nexport { useSwitchChain } from \"./hooks/useSwitchChain\";\nexport type {\n TokenBalanceResult,\n TokenInfo,\n UseTokenBalanceOptions,\n} from \"./hooks/useTokenBalance\";\nexport { useTokenBalance } from \"./hooks/useTokenBalance\";\nexport type {\n ApprovalChange,\n BalanceChange,\n GasInfo,\n RiskAssessment,\n RiskLevel,\n RiskWarning,\n SimulationResult,\n SimulationStatus,\n UseTransactionSimulationReturn,\n} from \"./hooks/useTransactionSimulation\";\nexport { useTransactionSimulation } from \"./hooks/useTransactionSimulation\";\nexport type { UseTxHistoryResult } from \"./hooks/useTxHistory\";\nexport { useTxHistory } from \"./hooks/useTxHistory\";\nexport type {\n TxMonitorLike,\n TxStatus,\n TxStatusEntry,\n UseTxMonitorResult,\n} from \"./hooks/useTxMonitor\";\nexport { TxMonitorContext, useTxMonitor } from \"./hooks/useTxMonitor\";\nexport type {\n UserOpStatus,\n UseUserOpStatusOptions,\n UseUserOpStatusReturn,\n} from \"./hooks/useUserOpStatus\";\nexport { useUserOpStatus } from \"./hooks/useUserOpStatus\";\nexport type {\n AddressValidationLevel,\n AddressValidationResult,\n UseValidateDestinationOptions,\n UseValidateDestinationReturn,\n} from \"./hooks/useValidateDestination\";\nexport {\n useValidateDestination,\n validateDestination,\n} from \"./hooks/useValidateDestination\";\nexport { useViemClient } from \"./hooks/useViemClient\";\nexport { useWallet } from \"./hooks/useWallet\";\nexport type {\n UserFriendlyError,\n UseWeb3ErrorHandlerReturn,\n} from \"./hooks/useWeb3ErrorHandler\";\nexport { useWeb3ErrorHandler } from \"./hooks/useWeb3ErrorHandler\";\nexport type { Web3ConnectProviderProps } from \"./provider/Web3ConnectProvider\";\nexport {\n useWeb3,\n Web3ConnectProvider,\n Web3Context,\n} from \"./provider/Web3ConnectProvider\";\nexport type {\n TokenSelectorProps,\n UseTokenListOptions,\n UseTokenListReturn,\n UseTokenSearchReturn,\n} from \"./token-list\";\nexport { TokenSelector, useTokenList, useTokenSearch } from \"./token-list\";\nexport type {\n ChainInfo,\n ConnectionStatus,\n EvmTransaction,\n SIWxConfig,\n UseWalletReturn,\n WalletChain,\n Web3Actions,\n Web3ConnectConfig,\n Web3State,\n} from \"./types\";\nexport {\n DEFAULT_EVM_CHAINS,\n getChainById,\n getDefaultChains,\n} from \"./utils/chains\";\nexport {\n getUserFriendlyError,\n isRetryableError,\n WALLET_ERROR_DESCRIPTIONS,\n WALLET_ERROR_TITLES,\n} from \"./utils/errorMessages\";\nexport type { Locale } from \"./utils/i18n\";\nexport { getLocale, setLocale, t } from \"./utils/i18n\";\n\n// ── Stencil WC React wrappers ───────────────────────────────────\n\nexport type {\n AppkitAccordionEvents,\n AppkitAccountButtonEvents,\n AppkitAlertDialogEvents,\n AppkitAvatarEvents,\n AppkitBadgeEvents,\n AppkitButtonEvents,\n AppkitCardContentEvents,\n AppkitCardDescriptionEvents,\n AppkitCardEvents,\n AppkitCardFooterEvents,\n AppkitCardHeaderEvents,\n AppkitCardTitleEvents,\n AppkitCheckboxEvents,\n AppkitCollapsibleEvents,\n AppkitConnectButtonEvents,\n AppkitDialogEvents,\n AppkitDropdownMenuEvents,\n AppkitInputEvents,\n AppkitPopoverEvents,\n AppkitProgressEvents,\n AppkitScrollAreaEvents,\n AppkitSelectEvents,\n AppkitSeparatorEvents,\n AppkitSkeletonEvents,\n AppkitSwitchEvents,\n AppkitTabsEvents,\n AppkitToggleGroupEvents,\n AppkitTooltipEvents,\n} from \"./wc-generated/components\";\nexport {\n AppkitAccordion,\n AppkitAccountButton,\n AppkitAlertDialog,\n AppkitAvatar,\n AppkitBadge,\n AppkitButton,\n AppkitCard,\n AppkitCardContent,\n AppkitCardDescription,\n AppkitCardFooter,\n AppkitCardHeader,\n AppkitCardTitle,\n AppkitCheckbox,\n AppkitCollapsible,\n AppkitConnectButton,\n AppkitDialog,\n AppkitDropdownMenu,\n AppkitInput,\n AppkitPopover,\n AppkitProgress,\n AppkitScrollArea,\n AppkitSelect,\n AppkitSeparator,\n AppkitSkeleton,\n AppkitSwitch,\n AppkitTabs,\n AppkitToggleGroup,\n AppkitTooltip,\n} from \"./wc-generated/components\";\n","/**\n * useCompareCosts — compare an operation's cost across chains.\n *\n * Types and the value-key for the input live in\n * `@naculus/connect-appkit-core` (`routing`), shared with the Vue composable.\n */\n\nimport {\n type CompareCosts,\n type CompareCostsInput,\n type CostComparison,\n type CostComparisonOperation,\n type CostComparisonOptions,\n compareCostsKey,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type { CostComparison, CostComparisonOperation, CostComparisonOptions };\nexport type UseCompareCostsInput = CompareCostsInput;\n\nexport interface UseCompareCostsReturn {\n comparisons: CostComparison[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n}\n\nexport function useCompareCosts(\n input: UseCompareCostsInput,\n compareCostsFn?: CompareCosts,\n): UseCompareCostsReturn {\n const { operation, chains, options } = input;\n const [comparisons, setComparisons] = useState<CostComparison[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n const generationRef = useRef(0);\n\n // Keyed on the values, not the array/object identity — see compareCostsKey.\n const inputKey = compareCostsKey(input);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on inputKey (the inputs by value), not on the array/object identities that change every render; see compareCostsKey\n const fetchComparisons = useCallback(async () => {\n if (!chains || chains.length === 0) {\n setComparisons([]);\n return;\n }\n if (!compareCostsFn) return;\n\n // Only the newest request may write. A comparison for a previous chain set\n // resolving last would otherwise decide which route the user is shown as\n // cheapest, using costs for chains they are no longer looking at.\n const generation = ++generationRef.current;\n setLoading(true);\n setError(null);\n try {\n const result = await compareCostsFn(operation, chains, options);\n if (mountedRef.current && generation === generationRef.current) {\n setComparisons(result);\n }\n } catch (err) {\n if (mountedRef.current && generation === generationRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setComparisons([]);\n }\n } finally {\n if (mountedRef.current && generation === generationRef.current) {\n setLoading(false);\n }\n }\n }, [inputKey, compareCostsFn]);\n\n useEffect(() => {\n fetchComparisons();\n }, [fetchComparisons]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const refresh = useCallback(async () => {\n await fetchComparisons();\n }, [fetchComparisons]);\n\n return { comparisons, loading, error, refresh };\n}\n","/**\n * useExecuteRoute — execute a quoted cross-chain route once.\n *\n * Types, the recipient check and error normalization live in\n * `@naculus/connect-appkit-core` (`routing`), shared with the Vue composable.\n */\n\nimport {\n type ExecutableQuote,\n type ExecuteRoute,\n type ExecuteRouteError,\n type ExecuteRouteOptions,\n type ExecuteRouteResult,\n toExecuteRouteError,\n validateRouteRecipient,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type Quote = ExecutableQuote;\nexport type ExecuteOptions = ExecuteRouteOptions;\nexport type ExecuteError = ExecuteRouteError;\nexport type { ExecuteRouteResult };\n\nexport interface UseExecuteRouteReturn {\n execute: (\n quote: Quote,\n recipient: string,\n options?: ExecuteOptions,\n ) => Promise<ExecuteRouteResult | null>;\n executing: boolean;\n result: ExecuteRouteResult | null;\n error: ExecuteError | null;\n reset: () => void;\n}\n\nexport function useExecuteRoute(\n executeRouteFn?: ExecuteRoute,\n): UseExecuteRouteReturn {\n const [executing, setExecuting] = useState(false);\n const [result, setResult] = useState<ExecuteRouteResult | null>(null);\n const [error, setError] = useState<ExecuteError | null>(null);\n const mountedRef = useRef(true);\n const inFlightRef = useRef(false);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const execute = useCallback(\n async (\n quote: Quote,\n recipient: string,\n options?: ExecuteOptions,\n ): Promise<ExecuteRouteResult | null> => {\n if (!executeRouteFn) {\n setError({\n code: \"no_executor\",\n message: \"No executeRoute function provided\",\n });\n // Clear any earlier success too. A UI showing last run's transaction\n // hash next to this error reads as though something was sent.\n setResult(null);\n return null;\n }\n\n const recipientError = validateRouteRecipient(quote, recipient);\n if (recipientError) {\n setError(recipientError);\n setResult(null);\n return null;\n }\n\n // A cross-chain transfer must not be submitted twice because a button was\n // pressed twice. Matches useSendUserOperation.\n if (inFlightRef.current) {\n setError({\n code: \"execution_in_progress\",\n message: \"A route execution is already in progress\",\n });\n return null;\n }\n\n inFlightRef.current = true;\n setExecuting(true);\n setError(null);\n setResult(null);\n try {\n const execResult = await executeRouteFn(quote, recipient, options);\n if (mountedRef.current) setResult(execResult);\n return execResult;\n } catch (err) {\n if (mountedRef.current) setError(toExecuteRouteError(err));\n return null;\n } finally {\n inFlightRef.current = false;\n if (mountedRef.current) setExecuting(false);\n }\n },\n [executeRouteFn],\n );\n\n const reset = useCallback(() => {\n // Deliberately does not clear inFlightRef: a request already sent to the\n // executor is still out there, and letting reset() unlock the guard would\n // permit exactly the double submission it exists to prevent.\n setResult(null);\n setError(null);\n setExecuting(false);\n }, []);\n\n return { execute, executing, result, error, reset };\n}\n","/**\n * useRouteQuote — debounced cross-chain route quotes.\n *\n * Types and the \"is this amount quotable\" decision live in\n * `@naculus/connect-appkit-core` (`routing`), shared with the Vue composable.\n */\n\nimport {\n type GetRouteQuotes,\n isQuotableInput,\n type RouteQuote,\n type RouteQuoteInput,\n type RouteQuoteOptions,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type Quote = RouteQuote;\nexport type QuoteOptions = RouteQuoteOptions;\nexport type UseRouteQuoteInput = RouteQuoteInput;\n\nexport interface UseRouteQuoteReturn {\n quotes: Quote[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n clear: () => void;\n}\n\nexport function useRouteQuote(\n input: UseRouteQuoteInput,\n getQuoteFn?: GetRouteQuotes,\n): UseRouteQuoteReturn {\n const { fromChain, toChain, fromToken, toToken, amount, options } = input;\n const [quotes, setQuotes] = useState<Quote[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const mountedRef = useRef(true);\n\n const fetchQuotes = useCallback(async () => {\n if (!isQuotableInput({ fromChain, toChain, fromToken, amount })) {\n setQuotes([]);\n return;\n }\n if (!getQuoteFn) return;\n\n setLoading(true);\n setError(null);\n try {\n const result = await getQuoteFn(\n fromChain,\n toChain,\n fromToken,\n amount,\n options,\n toToken,\n );\n if (mountedRef.current) setQuotes(result);\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setQuotes([]);\n }\n } finally {\n if (mountedRef.current) setLoading(false);\n }\n }, [fromChain, toChain, fromToken, toToken, amount, options, getQuoteFn]);\n\n // Debounced auto-fetch on input change\n useEffect(() => {\n if (debounceTimer.current) clearTimeout(debounceTimer.current);\n if (!fromChain || !toChain || !fromToken || !amount) {\n setQuotes([]);\n return;\n }\n debounceTimer.current = setTimeout(() => {\n fetchQuotes();\n }, 300);\n return () => {\n if (debounceTimer.current) clearTimeout(debounceTimer.current);\n };\n }, [fetchQuotes, fromChain, toChain, fromToken, amount]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const refresh = useCallback(async () => {\n await fetchQuotes();\n }, [fetchQuotes]);\n\n const clear = useCallback(() => {\n setQuotes([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { quotes, loading, error, refresh, clear };\n}\n","import type {\n BatchCall,\n CallsStatus,\n SendCallsOptions,\n UniversalConnector,\n UniversalWalletSession,\n WalletCapabilities,\n} from \"@naculus/connect-core\";\nimport { logger, WalletError } from \"@naculus/connect-core\";\nimport type {\n PocketConnectorClass as EmbeddedWalletConnector,\n PocketConfig,\n} from \"@naculus/connector-embedded\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport type PasskeysConnectorImpl from \"@naculus/connector-passkeys\";\nimport { PassphraseGate } from \"@naculus/connect-core\";\nimport {\n createWalletConnectConnector,\n type WalletConnectConnector,\n} from \"@naculus/connector-walletconnect\";\n\n/** App-supplied WalletConnect pieces (see `ClientConfig.walletConnect`). */\nexport type NativeWalletConnectOptions = {\n /** A pre-built `@walletconnect/sign-client` SignClient. */\n client?: unknown;\n openUrl?: (url: string) => void | Promise<void>;\n};\n\n/** An EIP-1193 provider announced to the injected-wallet connector. */\nexport type InjectedProviderRegistration = {\n info: { uuid: string; name: string; icon: string; rdns: string };\n provider: unknown;\n};\n\nexport type ClientConfig = {\n projectId: string;\n metadata: {\n name: string;\n description: string;\n url: string;\n icons: string[];\n };\n /** Enable embedded (self-custodial) wallet */\n enableEmbedded?: boolean;\n /** Configuration forwarded to the embedded wallet engine. */\n embeddedConfig?: PocketConfig;\n\n /**\n * Ask the user for the storage passphrase through the UI instead of\n * supplying `embeddedConfig.encryptionPassphrase` yourself.\n *\n * Creates a `PassphraseGate` on the client and wires it in. Mount\n * `<PassphraseDialog />` from `@naculus/connect-appkit-ui` — or drive\n * `usePassphraseGate()` yourself — and the wallet's encrypted storage has\n * somewhere to ask.\n *\n * A callback you supply in `embeddedConfig` wins: your own prompt is a\n * deliberate choice, not something to override.\n */\n passphrasePrompt?: boolean;\n\n /** Enable passkeys (WebAuthn) connector */\n enablePasskeys?: boolean;\n\n /** Enable Solana injected wallet connector (Phantom, Solflare) */\n enableSolana?: boolean;\n /** Default Solana chain (e.g. \"solana:0\"). Only used when enableSolana is true. */\n solanaDefaultChain?: string;\n /**\n * WalletConnect wiring the app supplies — on React Native, a SignClient\n * built with native storage and `Linking.openURL` for deep links.\n */\n walletConnect?: NativeWalletConnectOptions;\n /**\n * Wallet Standard wallets to register with the Solana connector (React\n * Native's Mobile Wallet Adapter wallet). Needs `enableSolana`.\n */\n solanaWallets?: readonly unknown[];\n /**\n * EIP-1193 providers to register as injected wallets (React Native's\n * Coinbase Mobile Wallet Protocol provider); connect with\n * `connectInjected(info.uuid)`.\n */\n injectedProviders?: readonly InjectedProviderRegistration[];\n /**\n * Solana JSON-RPC endpoint, for reading balances and submitting\n * transactions.\n *\n * Kept separate from any EVM endpoint: pointing Solana traffic at an\n * EIP-155 node fails with an error that blames the request.\n */\n solanaRpcUrl?: string;\n};\n\n/**\n * What a transaction looks like on the way in.\n *\n * An EVM transaction is a set of named fields the wallet assembles; a Solana\n * one is bytes the application has already built and serialized. Typing this\n * as `Record<string, unknown>` made the second impossible to express, so a\n * Solana transaction could not be sent through the client even once the\n * connector below it knew how.\n */\nexport type TransactionInput = {\n transaction: Record<string, unknown> | Uint8Array | string;\n chainId?: string;\n};\n\nexport interface Web3Client {\n connector: WalletConnectConnector;\n embeddedConnector: EmbeddedWalletConnector | null;\n /** Wait for the lazily imported embedded connector to become available. */\n getEmbeddedConnector: () => Promise<EmbeddedWalletConnector | null>;\n /** The Passkeys connector if enabled */\n passkeysConnector: PasskeysConnectorImpl | null;\n /**\n * Where encrypted storage asks for a passphrase, when `passphrasePrompt` is\n * on. Null otherwise, including when the app supplies its own callback.\n */\n passphraseGate: PassphraseGate | null;\n /** Solana JSON-RPC endpoint from config, or null when none was given. */\n solanaRpcUrl: string | null;\n /** The Solana injected wallet connector if enabled */\n solanaConnector: UniversalConnector | null;\n connect: () => Promise<UniversalWalletSession>;\n /** Connect via EIP-6963 injected wallet */\n connectInjected: (walletId?: string) => Promise<UniversalWalletSession>;\n connectEmbedded: () => Promise<UniversalWalletSession>;\n /** Connect via passkeys (WebAuthn) */\n connectPasskeys: () => Promise<UniversalWalletSession>;\n reconnect: (\n session: UniversalWalletSession,\n ) => Promise<UniversalWalletSession>;\n disconnect: (session: UniversalWalletSession) => Promise<void>;\n /** Sign a message via the appropriate connector for the session */\n signMessage: (\n session: UniversalWalletSession,\n input: { message: string; address?: string; chainId?: string },\n ) => Promise<unknown>;\n /** Send a transaction via the appropriate connector for the session */\n sendTransaction: (\n session: UniversalWalletSession,\n input: TransactionInput,\n ) => Promise<unknown>;\n /**\n * Sign without broadcasting.\n *\n * Present because a Solana application routinely signs a transaction it\n * submits itself, or hands to a relayer. There was no way to ask for that\n * through the client at all.\n */\n signTransaction: (\n session: UniversalWalletSession,\n input: TransactionInput,\n ) => Promise<unknown>;\n /** Send batched calls (EIP-5792 wallet_sendCalls) via the appropriate connector */\n sendCalls: (\n session: UniversalWalletSession,\n calls: BatchCall[],\n chainId?: string,\n options?: SendCallsOptions,\n ) => Promise<string>;\n /**\n * Ask the wallet what the account can do, keyed by CAIP-2 chain.\n *\n * Undefined when the active connector has no way to answer, which is a\n * different fact from \"the account supports nothing\" — see\n * getAccountCapabilities in @naculus/connect-core.\n */\n getCapabilities?: (\n session: UniversalWalletSession,\n ) => Promise<Record<string, WalletCapabilities>> | undefined;\n /**\n * Subscribe to in-wallet account switches, whatever the namespace.\n *\n * Dispatches to the connector carrying the session, so a consumer never has\n * to know whether the wallet reports EIP-1193 `accountsChanged`, Solana's\n * `accountChanged`, or a WalletConnect session update. Returns an\n * unsubscribe function; returns a no-op when the connector cannot report.\n */\n onAccountsChanged?: (\n session: UniversalWalletSession,\n handler: (accounts: string[]) => void,\n ) => () => void;\n /** Counterpart to onAccountsChanged for in-wallet chain switches. */\n onChainChanged?: (\n session: UniversalWalletSession,\n handler: (chainId: string) => void,\n ) => () => void;\n /**\n * EIP-5792 `wallet_showCallsStatus`: ask the wallet to display a bundle.\n *\n * Optional because most wallets do not implement it, and a refusal is\n * cosmetic — the bundle is unaffected.\n */\n showCallsStatus?: (\n session: UniversalWalletSession,\n bundleHash: string,\n ) => Promise<void>;\n getCallsStatus: (\n session: UniversalWalletSession,\n bundleHash: string,\n ) => Promise<CallsStatus>;\n startPairing: () => Promise<string>;\n completePairing: () => Promise<UniversalWalletSession>;\n /** Abandon an in-flight pairing; a session that still arrives is torn down. */\n cancelPairing: () => void;\n getAllConnectors: () => UniversalConnector[];\n /** @internal set embedded connector after lazy init */\n _setEmbeddedConnector: (conn: EmbeddedWalletConnector) => void;\n /** @internal set passkeys connector after lazy init */\n _setPasskeysConnector: (conn: PasskeysConnectorImpl) => void;\n /** @internal set solana connector after lazy init */\n _setSolanaConnector: (conn: UniversalConnector) => void;\n}\n\nlet clientInstance: Web3Client | null = null;\n\nexport function createClient(config: ClientConfig): Web3Client {\n // A provider owns its client. Keeping a process-wide singleton here causes\n // the first provider's projectId, metadata, and feature flags to leak into\n // every later provider. `getClient()` remains as a legacy last-created\n // accessor; provider hooks use the client carried by context.\n let clientRef: Web3Client | null = null;\n\n const connector = createWalletConnectConnector({\n projectId: config.projectId,\n metadata: config.metadata,\n ...(config.walletConnect?.client\n ? { client: config.walletConnect.client as never }\n : {}),\n ...(config.walletConnect?.openUrl\n ? { openUrl: config.walletConnect.openUrl }\n : {}),\n });\n\n let _embeddedConnector: EmbeddedWalletConnector | null = null;\n let embeddedInit: Promise<void> | null = null;\n\n // Declared before the passkeys connector exists, because the embedded\n // wallet is constructed from it and the two load independently.\n let _passkeysConnector: PasskeysConnectorImpl | null = null;\n let passkeysInit: Promise<void> | null = null;\n\n // Only when asked for, and never over a callback the app already supplied.\n const _passphraseGate =\n config.passphrasePrompt &&\n config.enableEmbedded &&\n !config.embeddedConfig?.encryptionPassphrase\n ? new PassphraseGate()\n : null;\n\n if (config.enableEmbedded) {\n embeddedInit = import(\"@naculus/connector-embedded\")\n .then((mod) => {\n const embeddedConfig: PocketConfig = { ...config.embeddedConfig };\n if (_passphraseGate) {\n embeddedConfig.encryptionPassphrase = _passphraseGate.request;\n }\n // Passkey unlock turns itself on where the platform supports it: a\n // protection that has to be switched on protects only the people who\n // already knew to look for it. Where the authenticator cannot answer\n // this returns null and the record stays passphrase-only, which is\n // why it is safe to wire without asking.\n //\n // Requires encryption to be on at all — there is no key to wrap\n // otherwise — and never replaces a provider the app supplied.\n if (\n config.enablePasskeys &&\n embeddedConfig.encryptionPassphrase &&\n !embeddedConfig.prfUnlock\n ) {\n embeddedConfig.prfUnlock = {\n async derive(salt: Uint8Array) {\n if (passkeysInit) await passkeysInit;\n const passkeys = _passkeysConnector;\n if (!passkeys?.hasCredential()) return null;\n return passkeys.derivePrfKey(salt);\n },\n };\n }\n const conn = mod.createPocketConnector(embeddedConfig);\n _embeddedConnector = conn;\n clientRef?._setEmbeddedConnector(_embeddedConnector);\n })\n .catch((err) => {\n logger.warn(\n \"react/client\",\n \"Embedded wallet connector not available:\",\n err,\n );\n _embeddedConnector = null;\n });\n }\n\n if (config.enablePasskeys) {\n passkeysInit = import(\"@naculus/connector-passkeys\")\n .then((mod) => {\n const conn = mod.createPasskeysConnector();\n _passkeysConnector = conn;\n clientRef?._setPasskeysConnector(_passkeysConnector);\n })\n .catch((err) => {\n logger.warn(\"react/client\", \"Passkeys connector not available:\", err);\n _passkeysConnector = null;\n });\n }\n\n let _solanaConnector: UniversalConnector | null = null;\n let solanaInit: Promise<void> | null = null;\n\n if (config.enableSolana) {\n solanaInit = import(\"@naculus/connector-solana\")\n .then((mod: any) => {\n // Use the singleton instance so hooks (useSolanaAccount, etc.) and\n // the client routing share the same activeSession state.\n const conn = mod.solanaConnector as UniversalConnector;\n if (config.solanaDefaultChain && \"configure\" in conn) {\n (conn as any).configure({ defaultChain: config.solanaDefaultChain });\n }\n _solanaConnector = conn;\n if (typeof window !== \"undefined\" && \"startDiscovery\" in conn) {\n (conn as any).startDiscovery();\n }\n for (const wallet of config.solanaWallets ?? []) {\n (conn as any).registerWallet?.(wallet);\n }\n clientRef?._setSolanaConnector(_solanaConnector);\n })\n .catch((err) => {\n logger.warn(\"react/client\", \"Solana connector not available:\", err);\n _solanaConnector = null;\n });\n }\n\n // Start EIP-6963 discovery eagerly so wallets are available when user clicks connect\n if (typeof window !== \"undefined\") {\n eip6963Connector.startDiscovery();\n }\n for (const { info, provider } of config.injectedProviders ?? []) {\n eip6963Connector.registerProvider(info, provider as never);\n }\n\n const client: Web3Client = {\n connector,\n get embeddedConnector() {\n return _embeddedConnector;\n },\n getEmbeddedConnector: async () => {\n if (embeddedInit) await embeddedInit;\n return _embeddedConnector;\n },\n get passkeysConnector() {\n return _passkeysConnector;\n },\n passphraseGate: _passphraseGate,\n solanaRpcUrl: config.solanaRpcUrl ?? null,\n get solanaConnector() {\n return _solanaConnector;\n },\n connect: () => connector.connect(),\n connectInjected: async (walletId?: string) => {\n return eip6963Connector.connect(walletId);\n },\n connectEmbedded: async () => {\n if (embeddedInit) await embeddedInit;\n if (!_embeddedConnector) {\n throw new Error(\n \"Embedded wallet not enabled. Set enableEmbedded: true in config.\",\n );\n }\n return _embeddedConnector.connect();\n },\n connectPasskeys: async () => {\n if (passkeysInit) await passkeysInit;\n if (!_passkeysConnector) {\n throw new Error(\n \"Passkeys connector not enabled. Set enablePasskeys: true in config.\",\n );\n }\n return _passkeysConnector.connect();\n },\n startPairing: () => connector.startPairing(),\n completePairing: () => connector.completePairing(),\n cancelPairing: () => connector.cancelPairing?.(),\n signMessage: async (session, input) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.signMessage(session as any, input);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.signMessage(session as any, input);\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet connector not available.\",\n );\n }\n return _embeddedConnector.signMessage(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).signMessage(session as any, input);\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.signMessage(session, input);\n },\n signTransaction: async (session, input) => {\n // Same dispatch as sendTransaction; only the connector method differs.\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.signTransaction(session as any, input);\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet connector not available.\",\n );\n }\n return _embeddedConnector.signTransaction(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).signTransaction(\n session as any,\n input,\n );\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.signTransaction(session as any, input);\n },\n sendTransaction: async (session, input) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet connector not available.\",\n );\n }\n return _embeddedConnector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).sendTransaction(\n session as any,\n input,\n );\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.sendTransaction(session, input);\n },\n onAccountsChanged: (session, handler) => {\n // Same dispatch as every other session-routed call.\n const noop = () => {};\n if (session.id?.startsWith(\"eip6963-\")) {\n return (\n eip6963Connector.onAccountsChanged?.(session as never, handler) ??\n noop\n );\n }\n if (session.walletType === \"embedded\") {\n // The embedded wallet does rotate its active account, through\n // `setActiveNamespace` and `backfillAccounts`. This used to return a\n // no-op on the reasoning that a local key \"only rotates through an\n // explicit call\" — which is exactly the case that now exists, and\n // left the provider publishing the connect-time account while a\n // different key signed.\n return (\n _embeddedConnector?.onAccountsChanged?.(session, handler) ?? noop\n );\n }\n if (session.walletType === \"passkeys\") {\n // A passkey connector holds no account to rotate: it cannot even\n // produce an address without a deployed smart account.\n return noop;\n }\n if (session.walletType === \"solana\") {\n return (\n (_solanaConnector as UniversalConnector | null)?.onAccountsChanged?.(\n session,\n handler,\n ) ?? noop\n );\n }\n return connector.onAccountsChanged?.(session, handler) ?? noop;\n },\n onChainChanged: (session, handler) => {\n const noop = () => {};\n if (session.id?.startsWith(\"eip6963-\")) {\n return (\n eip6963Connector.onChainChanged?.(session as never, handler) ?? noop\n );\n }\n if (\n session.walletType === \"passkeys\" ||\n session.walletType === \"embedded\"\n ) {\n return noop;\n }\n if (session.walletType === \"solana\") {\n return (\n (_solanaConnector as UniversalConnector | null)?.onChainChanged?.(\n session,\n handler,\n ) ?? noop\n );\n }\n return connector.onChainChanged?.(session, handler) ?? noop;\n },\n getCapabilities: (session) => {\n // Same dispatch as sendCalls, so the capability answer always comes from\n // the connector that would carry out the send. Asking one connector and\n // sending through another is how a caller ends up promised atomicity\n // that the executing wallet never claimed.\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.getCapabilities?.(session as never);\n }\n if (session.walletType === \"passkeys\") {\n return _passkeysConnector?.getCapabilities?.(session as never);\n }\n if (session.walletType === \"solana\") {\n // The Solana connector answers nothing today. Returning undefined\n // reports that rather than a fabricated \"no support\".\n return (\n _solanaConnector as UniversalConnector | null\n )?.getCapabilities?.(session);\n }\n if (session.walletType === \"embedded\") {\n return _embeddedConnector?.getCapabilities?.(session as never);\n }\n // Undefined rather than an empty object: \"cannot be asked\" has to stay\n // distinguishable from \"asked, and answered nothing\".\n return connector.getCapabilities?.(session);\n },\n sendCalls: async (session, calls, chainId, options) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.sendCalls!(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.sendCalls!(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).sendCalls(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector?.sendCalls) {\n throw new WalletError(\n \"method_not_allowed\",\n \"Embedded wallet does not support sendCalls\",\n );\n }\n return _embeddedConnector.sendCalls!(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n if (!connector.sendCalls) {\n throw new WalletError(\n \"method_not_allowed\",\n \"sendCalls not supported by this connector\",\n );\n }\n return connector.sendCalls(session, calls, chainId, options);\n },\n showCallsStatus: async (session, bundleHash) => {\n // Same dispatch as sendCalls, so the wallet asked to display the bundle\n // is the one that sent it.\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.showCallsStatus!(session as never, bundleHash);\n }\n if (\n session.walletType === \"passkeys\" ||\n session.walletType === \"embedded\"\n ) {\n throw new WalletError(\n \"method_unsupported\",\n `${session.walletType} wallets have no UI to display a call bundle.`,\n );\n }\n if (!connector.showCallsStatus) {\n throw new WalletError(\n \"method_unsupported\",\n \"This connector cannot display call status.\",\n );\n }\n return connector.showCallsStatus(session, bundleHash);\n },\n getCallsStatus: async (session, bundleHash) => {\n if (\n session.id?.startsWith(\"eip6963-\") &&\n eip6963Connector.getCallsStatus\n ) {\n return eip6963Connector.getCallsStatus(session as any, bundleHash);\n }\n if (\n session.walletType === \"passkeys\" &&\n _passkeysConnector?.getCallsStatus\n ) {\n return _passkeysConnector.getCallsStatus(session as any, bundleHash);\n }\n if (session.walletType === \"embedded\") {\n throw new WalletError(\n \"method_not_allowed\",\n \"Embedded wallet does not support getCallsStatus\",\n );\n }\n if (!connector.getCallsStatus) {\n throw new WalletError(\n \"method_not_allowed\",\n \"getCallsStatus not supported by this connector\",\n );\n }\n return connector.getCallsStatus(session, bundleHash);\n },\n reconnect: async (session) => {\n if (session.walletType === \"eip6963\") {\n return eip6963Connector.reconnect(session);\n }\n if (session.walletType === \"embedded\") {\n if (_embeddedConnector) {\n return _embeddedConnector.reconnect(session);\n }\n return session;\n }\n if (session.walletType === \"solana\") {\n // Solana injected wallet doesn't support reconnect (no persisted session).\n // Return the saved session as-is; signing ops require wallet reconnection.\n return session;\n }\n return connector.reconnect(session);\n },\n disconnect: async (session) => {\n if (\n session.id?.startsWith(\"eip6963-\") ||\n session.walletType === \"eip6963\"\n ) {\n return eip6963Connector.disconnect(session as any);\n }\n if (session.walletType === \"embedded\" && _embeddedConnector) {\n return _embeddedConnector.disconnect();\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.disconnect(session as any);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return _solanaConnector.disconnect(session);\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.disconnect(session);\n },\n getAllConnectors: () => {\n const connectors: UniversalConnector[] = [connector];\n if (_embeddedConnector) connectors.push(_embeddedConnector);\n if (_passkeysConnector) connectors.push(_passkeysConnector);\n if (_solanaConnector) connectors.push(_solanaConnector);\n return connectors;\n },\n _setEmbeddedConnector: (conn: EmbeddedWalletConnector) => {\n _embeddedConnector = conn;\n },\n _setPasskeysConnector: (conn: PasskeysConnectorImpl) => {\n _passkeysConnector = conn;\n },\n _setSolanaConnector: (conn: UniversalConnector) => {\n _solanaConnector = conn;\n },\n };\n\n clientRef = client;\n clientInstance = client;\n return client;\n}\n\nexport function getClient(): Web3Client | null {\n return clientInstance;\n}\n\nexport function clearClient(): void {\n clientInstance = null;\n}\n","import { isEvmAddress, parseCaip10 } from \"@naculus/connect-core\";\nimport { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface AccountEntry {\n /** As the session reports it: CAIP-10 for most wallets, bare hex for some. */\n address: string;\n /** The namespace, when the entry was CAIP-10. Null for a bare address. */\n namespace: string | null;\n isEVM: boolean;\n}\n\n/**\n * The connected accounts, split by what they actually are.\n *\n * Reads the namespace from the CAIP-10 form rather than inferring it from\n * address shape wherever it can, and falls back to shape only for a bare\n * address. A bare 0x-40-hex value is unambiguously EVM; a bare base58 string\n * is not unambiguously anything.\n */\nexport function useAccount() {\n const { accounts, isConnected } = useWeb3();\n\n const accountData = useMemo<AccountEntry[] | null>(() => {\n if (!isConnected || accounts.length === 0) return null;\n\n return accounts.map((address) => {\n const parsed = parseCaip10(address);\n if (parsed) {\n return {\n address,\n namespace: parsed.namespace,\n // The namespace decides, not the shape. A wallet that reports\n // `solana:...:0x...` is telling us something about the account that\n // its characters do not.\n isEVM: parsed.namespace === \"eip155\" && isEvmAddress(parsed.address),\n };\n }\n return {\n address,\n namespace: null,\n isEVM: isEvmAddress(address),\n };\n });\n }, [accounts, isConnected]);\n\n const evmAccount = accountData?.find((a) => a.isEVM)?.address ?? null;\n\n return {\n accounts: accountData,\n evmAccount,\n primaryAccount: accounts[0] ?? null,\n isConnected,\n count: accounts.length,\n };\n}\n","\"use client\";\n\nimport type {\n ActiveSessionBundle,\n SessionManager,\n UniversalWalletSession,\n} from \"@naculus/connect-core\";\nimport {\n createConnectorManager,\n createSessionManager,\n LocalStorageSessionStorage,\n logger,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport type React from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n} from \"react\";\nimport { createClient, type Web3Client } from \"../client\";\nimport { runSiwxFlow } from \"../core/siwx-flow\";\nimport {\n initialWeb3State,\n web3Reducer,\n withRetry,\n withTimeout,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n WalletChain,\n Web3Actions,\n Web3ConnectConfig,\n Web3State,\n} from \"../types\";\nimport { getDefaultChains } from \"../utils/chains\";\n\n// ── Timeout Helper ────────────────────────────────────────────────\n\nexport interface Web3ContextValue extends Web3State, Web3Actions {\n isConnected: boolean;\n chains: WalletChain[];\n /** Client owned by this provider instance. */\n client: Web3Client;\n /** SessionManager instance for multi-chain session management */\n sessionManager: SessionManager | null;\n}\n\nexport const Web3Context = createContext<Web3ContextValue | null>(null);\n\nexport interface Web3ConnectProviderProps {\n children: React.ReactNode;\n config: Web3ConnectConfig;\n autoConnect?: boolean;\n}\n\nexport function Web3ConnectProvider({\n children,\n config,\n autoConnect = true,\n}: Web3ConnectProviderProps) {\n const [state, dispatch] = useReducer(web3Reducer, initialWeb3State);\n\n const chains = useMemo(\n () => config.chains ?? getDefaultChains(),\n [config.chains],\n );\n\n const connectionTimeout = config.connectionTimeout ?? 30000;\n const maxRetries = config.maxRetries ?? 2;\n\n const storage = useMemo(\n () =>\n config.sessionStorage ??\n new LocalStorageSessionStorage(\n config.storageKey ?? \"naculus_web3_session\",\n config.encryptionKey,\n ),\n [config.sessionStorage, config.storageKey, config.encryptionKey],\n );\n\n const client = useMemo(() => {\n return createClient({\n projectId: config.projectId,\n metadata: config.metadata,\n enableEmbedded: config.enableEmbedded,\n embeddedConfig: config.embeddedConfig,\n enablePasskeys: config.enablePasskeys,\n enableSolana: config.enableSolana,\n solanaDefaultChain: config.solanaDefaultChain,\n walletConnect: config.walletConnect,\n solanaWallets: config.solanaWallets,\n injectedProviders: config.injectedProviders,\n });\n }, [\n config.projectId,\n config.metadata,\n config.enableEmbedded,\n config.embeddedConfig,\n config.enablePasskeys,\n config.enableSolana,\n config.solanaDefaultChain,\n config.walletConnect,\n config.solanaWallets,\n config.injectedProviders,\n ]);\n\n // ── SessionManager ───────────────────────────────────────────────\n\n const sessionManagerRef = useRef<SessionManager | null>(null);\n // EIP-1193 chain events and an imperative switch can arrive in the same\n // tick. Keep the external synchronization promise visible to switchChain so\n // it cannot observe the old SessionManager chain and incorrectly no-op.\n const pendingExternalChainSyncRef = useRef<Promise<void> | null>(null);\n\n const sessionManager = useMemo(() => {\n // Build a connector manager that shares the client's connectors\n const cm = createConnectorManager();\n for (const connector of [eip6963Connector, ...client.getAllConnectors()]) {\n cm.register(connector.id, connector);\n }\n\n // Build default RPC/currency configs from the configured chains\n const defaultRpcUrls: Record<string, string> = {};\n const defaultCurrencies: Record<\n string,\n { name: string; symbol: string; decimals: number }\n > = {};\n\n for (const chain of chains) {\n const caip2Id = chain.caip2;\n if (chain.rpcUrl) {\n defaultRpcUrls[caip2Id] = chain.rpcUrl;\n }\n if (chain.token) {\n defaultCurrencies[caip2Id] = {\n name: chain.name,\n symbol: chain.token,\n decimals: 18,\n };\n }\n }\n\n const sm = createSessionManager(cm, {\n autoRefreshFeeOnSwitch: config.autoRefreshFeeOnSwitch ?? true,\n defaultRpcUrls,\n defaultCurrencies,\n encryptionKey: config.encryptionKey,\n });\n\n sessionManagerRef.current = sm;\n return sm;\n }, [client, chains, config.autoRefreshFeeOnSwitch, config.encryptionKey]);\n\n // Sync SessionManager events to provider state\n useEffect(() => {\n const onConnected = (payload: { bundle: any }) => {\n const { walletSession } = payload.bundle;\n dispatch({ type: \"SET_SESSION\", payload: walletSession });\n\n const accounts: string[] = [];\n Object.values(walletSession.namespaces).forEach((ns: any) => {\n accounts.push(...ns.accounts);\n });\n dispatch({ type: \"SET_ACCOUNTS\", payload: accounts });\n dispatch({ type: \"SET_CHAIN\", payload: payload.bundle.activeChainId });\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n };\n\n const onDisconnected = () => {\n dispatch({ type: \"RESET\" });\n };\n\n const onChainChanged = (payload: { newChainId: string }) => {\n dispatch({ type: \"SET_CHAIN\", payload: payload.newChainId });\n };\n\n // The wallet narrowed the scope: re-read accounts and active chain from\n // the bundle rather than keeping what the wider session had.\n const onScopeChanged = (payload: { bundle: ActiveSessionBundle }) =>\n onConnected(payload);\n // The wallet ended the session (revoked, expired, or scope emptied).\n // Covers the persisted-session-cleared case for every connector,\n // replacing WalletConnect's connector-private onSessionExpiry.\n const onRevoked = () => {\n storage.clear();\n dispatch({ type: \"RESET\" });\n };\n\n sessionManager.on(\"sessionConnected\", onConnected);\n sessionManager.on(\"sessionDisconnected\", onDisconnected);\n sessionManager.on(\"chainChanged\", onChainChanged);\n sessionManager.on(\"sessionScopeChanged\", onScopeChanged);\n sessionManager.on(\"sessionRevoked\", onRevoked);\n\n return () => {\n sessionManager.off(\"sessionConnected\", onConnected);\n sessionManager.off(\"sessionDisconnected\", onDisconnected);\n sessionManager.off(\"chainChanged\", onChainChanged);\n sessionManager.off(\"sessionScopeChanged\", onScopeChanged);\n sessionManager.off(\"sessionRevoked\", onRevoked);\n };\n }, [sessionManager, storage]);\n\n useEffect(() => {\n const handler = () => {\n storage.clear();\n dispatch({ type: \"RESET\" });\n };\n client.connector.onSessionExpiry(handler);\n }, [client, storage]);\n\n const syncSessionManagerConnectors = useCallback(() => {\n for (const connector of [eip6963Connector, ...client.getAllConnectors()]) {\n sessionManager.registerConnector(connector);\n }\n }, [client, sessionManager]);\n\n const attachSession = useCallback(\n async (session: UniversalWalletSession) => {\n syncSessionManagerConnectors();\n const connector = [eip6963Connector, ...client.getAllConnectors()].find(\n (candidate) =>\n candidate.id === session.walletType ||\n candidate.kind === session.walletType,\n );\n if (connector && !session.connectorId) session.connectorId = connector.id;\n const chainId =\n session.namespaces.eip155?.chains?.[0] ??\n session.namespaces.solana?.chains?.[0] ??\n session.namespaces.xrpl?.chains?.[0];\n if (chainId) await sessionManager.attach(session, chainId);\n },\n [client, sessionManager, syncSessionManagerConnectors],\n );\n\n const updateStateFromSession = useCallback(\n (session: typeof state.session) => {\n dispatch({ type: \"SET_SESSION\", payload: session });\n\n if (session) {\n const accounts: string[] = [];\n Object.values(session.namespaces).forEach((ns) => {\n accounts.push(...ns.accounts);\n });\n dispatch({ type: \"SET_ACCOUNTS\", payload: accounts });\n\n const evmChain = session.namespaces.eip155?.chains?.[0];\n const solChain = session.namespaces.solana?.chains?.[0];\n const xrplChain = session.namespaces.xrpl?.chains?.[0];\n dispatch({\n type: \"SET_CHAIN\",\n payload: evmChain ?? solChain ?? xrplChain ?? null,\n });\n } else {\n dispatch({ type: \"SET_ACCOUNTS\", payload: [] });\n dispatch({ type: \"SET_CHAIN\", payload: null });\n }\n },\n [],\n );\n\n // Wallets can change accounts without a reconnect call, and every namespace\n // has its own way of saying so: EIP-1193 `accountsChanged`, Solana's\n // `accountChanged`, a WalletConnect session update. This used to subscribe by\n // reaching through `eip6963Connector.getDiscoveredWallets()` into the raw\n // provider, which meant it re-implemented the CAIP-10 re-keying the connector\n // already did and worked for exactly one wallet kind — a Solana or\n // WalletConnect account switch was never noticed at all.\n //\n // The connector reports it now, so this subscribes once, namespace-agnostic,\n // and only mirrors the session the connector has already updated.\n useEffect(() => {\n const session = state.session;\n const activeClient = client;\n if (!session || !activeClient?.onAccountsChanged) return;\n\n const unsubscribe = activeClient.onAccountsChanged(session, (accounts) => {\n if (accounts.length === 0) {\n // The wallet is no longer authorizing this dApp.\n void storage.clear().finally(() => dispatch({ type: \"RESET\" }));\n return;\n }\n updateStateFromSession(session);\n void storage.save(session);\n });\n\n return unsubscribe;\n }, [state.session, client, storage, updateStateFromSession]);\n\n // Chain switches made in the wallet. The connector re-keys the session's\n // accounts to the new chain; what only the provider can do is drive the\n // SessionManager's external-chain sync, which other operations await.\n useEffect(() => {\n const session = state.session;\n const activeClient = client;\n if (!session || !activeClient?.onChainChanged) return;\n\n return activeClient.onChainChanged(session, (chainId) => {\n updateStateFromSession(session);\n void storage.save(session);\n\n const syncExternalChain = (\n sessionManager as SessionManager & {\n syncExternalChain?: (nextChainId: string) => Promise<void>;\n }\n ).syncExternalChain;\n if (!syncExternalChain) return;\n\n const syncPromise = syncExternalChain\n .call(sessionManager, chainId)\n .catch((error) => {\n logger.warn(\"react/provider\", \"External chain sync error:\", error);\n });\n pendingExternalChainSyncRef.current = syncPromise;\n void syncPromise.finally(() => {\n if (pendingExternalChainSyncRef.current === syncPromise) {\n pendingExternalChainSyncRef.current = null;\n }\n });\n });\n }, [state.session, client, storage, updateStateFromSession, sessionManager]);\n\n // ── SIWx post-connection helper ──────────────────────────────────\n // Run after any connect method succeeds. Returns false if SIWx is\n // configured, required, and failed — the caller should abort without\n // setting status to \"connected\".\n // The sequence itself lives in core/siwx-flow so every binding shares it;\n // this only maps the outcome onto React state and storage.\n const runSiwx = useCallback(\n async (session: UniversalWalletSession | null): Promise<boolean> => {\n if (!config.siwx || !session) return true;\n dispatch({ type: \"SET_STATUS\", payload: \"authenticating\" });\n\n const outcome = await runSiwxFlow({\n session,\n siwx: config.siwx,\n signMessage: (s, args) => client.signMessage(s, args),\n });\n\n if (outcome.kind === \"failed\" && outcome.fatal) {\n await storage.clear();\n dispatch({ type: \"RESET\" });\n dispatch({ type: \"SET_ERROR\", payload: outcome.error });\n return false;\n }\n return true;\n },\n [config.siwx, client, storage],\n );\n\n const connect = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await withTimeout(\n client.connect(),\n connectionTimeout,\n \"Wallet connect\",\n );\n await storage.save(session);\n updateStateFromSession(session);\n\n try {\n await attachSession(session);\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager sync error:\", smError);\n }\n\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [\n client,\n storage,\n updateStateFromSession,\n connectionTimeout,\n runSiwx,\n attachSession,\n ]);\n\n const connectEmbedded = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await client.connectEmbedded();\n await storage.save(session);\n updateStateFromSession(session);\n await attachSession(session);\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Embedded wallet connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, runSiwx, attachSession]);\n\n const connectPasskeys = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await client.connectPasskeys();\n await storage.save(session);\n updateStateFromSession(session);\n await attachSession(session);\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Passkeys connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, runSiwx, attachSession]);\n\n const disconnect = useCallback(async () => {\n if (!state.session) {\n dispatch({ type: \"RESET\" });\n return;\n }\n\n try {\n await client.disconnect(state.session);\n } catch (error) {\n logger.error(\"react/provider\", \"Disconnect error:\", error);\n }\n\n // Also disconnect via SessionManager\n try {\n const sm = sessionManagerRef.current;\n if (sm) {\n await sm.disconnect();\n }\n } catch (smError) {\n logger.warn(\n \"react/provider\",\n \"SessionManager disconnect error:\",\n smError,\n );\n }\n\n await storage.clear();\n dispatch({ type: \"RESET\" });\n }, [client, state.session, storage]);\n\n const connectInjected = useCallback(\n async (walletId?: string): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await withTimeout(\n client.connectInjected(walletId),\n connectionTimeout,\n \"Injected wallet connect\",\n );\n await storage.save(session);\n updateStateFromSession(session);\n\n try {\n await attachSession(session);\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager sync error:\", smError);\n }\n\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n },\n [\n client,\n storage,\n updateStateFromSession,\n connectionTimeout,\n runSiwx,\n attachSession,\n ],\n );\n\n const startPairing = useCallback(async () => {\n return client.startPairing();\n }, [client]);\n\n const cancelPairing = useCallback(() => {\n client.cancelPairing?.();\n }, [client]);\n\n const completePairing = useCallback(async () => {\n const session = await client.completePairing();\n await storage.save(session);\n updateStateFromSession(session);\n await attachSession(session);\n if (!(await runSiwx(session))) return session;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n return session;\n }, [client, storage, updateStateFromSession, runSiwx, attachSession]);\n\n /**\n * SIWx on the reconnect path.\n *\n * Every other entry point runs `runSiwx` before reporting `connected`;\n * this one did not, and `autoConnect` makes it the path taken on every page\n * load. An application configured with `required: true` therefore had the\n * setting enforced once and bypassed on every refresh.\n *\n * Optional SIWx is left alone: prompting for a signature the application\n * said it can live without, on every reload, is the wrong trade.\n */\n const runSiwxOnReconnect = useCallback(\n async (session: UniversalWalletSession): Promise<boolean> => {\n const siwx = config.siwx;\n if (!siwx || siwx.required === false) return true;\n try {\n if (await siwx.hasValidSession?.()) return true;\n } catch (err) {\n // A session check that throws has not established a session. Fall\n // through and ask for a signature rather than assuming one.\n logger.warn(\"react/provider\", \"siwx.hasValidSession failed\", err);\n }\n return runSiwx(session);\n },\n [config.siwx, runSiwx],\n );\n\n const reconnect = useCallback(async () => {\n const savedSession = await storage.load();\n if (!savedSession) {\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n return;\n }\n\n dispatch({ type: \"SET_STATUS\", payload: \"reconnecting\" });\n\n try {\n const session = await withRetry(() => client.reconnect(savedSession), {\n maxRetries,\n baseDelay: 1000,\n label: \"reconnect\",\n });\n updateStateFromSession(session);\n\n // Restore SessionManager from persistence\n try {\n const sm = sessionManagerRef.current;\n if (sm) {\n syncSessionManagerConnectors();\n await sm.restoreFromPersistence();\n }\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager restore error:\", smError);\n }\n\n if (!(await runSiwxOnReconnect(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n logger.error(\"react/provider\", \"Reconnect error:\", error);\n await storage.clear();\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n dispatch({ type: \"SET_SESSION\", payload: null });\n }\n }, [\n client,\n storage,\n updateStateFromSession,\n maxRetries,\n syncSessionManagerConnectors,\n runSiwxOnReconnect,\n ]);\n\n const switchChain = useCallback(\n async (chainId: string) => {\n if (pendingExternalChainSyncRef.current) {\n await pendingExternalChainSyncRef.current;\n }\n const sm = sessionManagerRef.current;\n if (sm?.getActiveBundle()) {\n // Use SessionManager's switchChain which handles fee sync + events\n await sm.switchChain(chainId);\n updateStateFromSession(state.session);\n return;\n }\n\n // Fallback to direct connector switching (no SessionManager)\n if (!state.session) {\n throw new Error(\"No active session\");\n }\n\n try {\n if (\n state.session.walletType === \"eip6963\" ||\n state.session.id?.startsWith(\"eip6963-\")\n ) {\n await eip6963Connector.switchChain(state.session, chainId);\n } else if (\n state.session.walletType === \"embedded\" &&\n client.embeddedConnector\n ) {\n await client.embeddedConnector.switchChain?.(state.session, chainId);\n } else if (\n state.session.walletType === \"passkeys\" &&\n client.passkeysConnector\n ) {\n await client.passkeysConnector.switchChain?.(state.session, chainId);\n } else if (\n state.session.walletType === \"solana\" &&\n client.solanaConnector\n ) {\n await client.solanaConnector.switchChain?.(state.session, chainId);\n } else {\n await client.connector.switchChain(state.session, chainId);\n }\n updateStateFromSession(state.session);\n } catch (error) {\n throw new WalletError(\n \"chain_unsupported\",\n \"Failed to switch chain\",\n error,\n );\n }\n },\n [client, state.session, updateStateFromSession],\n );\n\n useEffect(() => {\n if (autoConnect) {\n reconnect();\n }\n }, [autoConnect, reconnect]);\n\n const clearError = useCallback(() => {\n dispatch({ type: \"SET_ERROR\", payload: null });\n }, []);\n\n const value = useMemo<Web3ContextValue>(\n () => ({\n ...state,\n connect,\n connectEmbedded,\n connectPasskeys,\n disconnect,\n reconnect,\n switchChain,\n startPairing,\n completePairing,\n cancelPairing,\n connectInjected,\n clearError,\n isConnected: state.status === \"connected\",\n chains,\n client,\n sessionManager,\n }),\n [\n state,\n connect,\n connectEmbedded,\n connectPasskeys,\n disconnect,\n reconnect,\n switchChain,\n startPairing,\n completePairing,\n cancelPairing,\n connectInjected,\n clearError,\n chains,\n client,\n sessionManager,\n ],\n );\n\n return <Web3Context.Provider value={value}>{children}</Web3Context.Provider>;\n}\n\nexport function useWeb3(): Web3ContextValue {\n const context = useContext(Web3Context);\n if (!context) {\n throw new Error(\"useWeb3 must be used within a Web3ConnectProvider\");\n }\n return context;\n}\n","/**\n * Framework-agnostic SIWx orchestration.\n *\n * The sign-in sequence — pick the chain, pick the account in that chain's\n * namespace, build the message, register its nonce, sign, hand the signature\n * back — has nothing React-specific in it. Only the reaction to failure does\n * (clearing storage, resetting reducer state), so this returns a description\n * of what happened and lets the binding decide what to do about it.\n *\n * Keeping the decision here means Vue, Svelte and native bindings get the same\n * authentication behavior instead of each re-deriving it.\n */\nimport { logger } from \"@naculus/connect-core\";\nimport type { UniversalWalletSession } from \"@naculus/connect-core\";\nimport { issueNonce, parseSiwxMessage } from \"@naculus/siwx\";\nimport { selectSiwxAccount } from \"../hooks/siwx-accounts\";\n\nexport interface SiwxHandlers {\n createMessage: (input: {\n address: string;\n chainId: string;\n }) => Promise<string>;\n handleSignComplete?: (input: {\n message: string;\n signature: string;\n }) => Promise<void> | void;\n /** When false, a failed sign-in leaves the connection intact. */\n required?: boolean;\n}\n\nexport type SiwxOutcome =\n | { kind: \"skipped\" }\n | { kind: \"authenticated\"; address: string; chainId: string }\n /** `fatal` means the caller must tear the connection down. */\n | { kind: \"failed\"; error: Error; fatal: boolean };\n\n/**\n * Resolve the chain a SIWx message should be scoped to.\n *\n * `chains[0]` is the active chain by convention across every connector, so the\n * first namespace present wins in a fixed order rather than by object key\n * enumeration, which is not guaranteed to be stable.\n */\nexport function resolveSiwxChainId(session: UniversalWalletSession): string {\n return (\n session.namespaces.eip155?.chains?.[0] ??\n session.namespaces.solana?.chains?.[0] ??\n session.namespaces.xrpl?.chains?.[0] ??\n \"eip155:1\"\n );\n}\n\nexport async function runSiwxFlow(input: {\n session: UniversalWalletSession | null;\n siwx: SiwxHandlers | undefined;\n signMessage: (\n session: UniversalWalletSession,\n args: { message: string; address: string; chainId: string },\n ) => Promise<unknown>;\n}): Promise<SiwxOutcome> {\n const { session, siwx, signMessage } = input;\n if (!siwx || !session) return { kind: \"skipped\" };\n\n try {\n const chainId = resolveSiwxChainId(session);\n const account = selectSiwxAccount(session, chainId);\n if (!account) throw new Error(\"No account found in session\");\n const { address } = account;\n\n const message = await siwx.createMessage({ address, chainId });\n const parsed = parseSiwxMessage(message);\n if (!parsed?.nonce) {\n // A message the verifier cannot parse would be signed and then rejected\n // server-side, so refuse before asking the user to sign anything.\n throw new Error(\"SIWx message must contain a nonce\");\n }\n await issueNonce(parsed.nonce);\n\n const signature = (await signMessage(session, {\n message,\n address,\n chainId,\n })) as string;\n\n await siwx.handleSignComplete?.({ message, signature });\n return { kind: \"authenticated\", address, chainId };\n } catch (cause) {\n const error =\n cause instanceof Error\n ? cause\n : new Error(\"Wallet authentication failed\");\n logger.error(\"appkit/core\", \"SIWx authentication failed:\", cause);\n return { kind: \"failed\", error, fatal: siwx.required !== false };\n }\n}\n","import type { UniversalWalletSession } from \"@naculus/connect-core\";\n\nexport interface SiwxAccount {\n namespace: string;\n caip10: string;\n address: string;\n}\n\n/**\n * Pick an account from the namespace selected by the SIWx chain.\n * SIWx messages contain a bare account address; CAIP-10 accounts are only\n * used as the source of truth for selecting the right namespace.\n */\nexport function selectSiwxAccount(\n session: UniversalWalletSession,\n chainId: string,\n): SiwxAccount | undefined {\n const namespace = chainId.split(\":\", 1)[0];\n // SIWx chain and account must come from the same CAIP namespace. Falling\n // back to another namespace can sign an EVM message with a Solana/XRPL\n // address (or vice versa), which is an authentication identity mismatch.\n const preferred = session.namespaces[namespace]?.accounts ?? [];\n const candidate = preferred\n .filter((caip10) => caip10.startsWith(`${namespace}:`))\n .map((caip10) => ({ namespace, caip10 }))[0];\n if (!candidate) return undefined;\n\n return {\n ...candidate,\n address: candidate.caip10.split(\":\").pop() ?? candidate.caip10,\n };\n}\n","import { resolveChain } from \"@naculus/connect-appkit-core\";\nimport type { WalletChain } from \"../types\";\nimport {\n CHAINS,\n DEFAULT_RPC_URLS,\n eip155Reference,\n getRpcUrl,\n} from \"@naculus/connect-core\";\n\n// ─── Static Overrides ──────────────────────────────────────────────\n// Chains that exist in the old default list but are NOT in chain-registry.\n// These are deprecated testnets; keep for backward compatibility.\n\nconst STATIC_TESTNETS: WalletChain[] = [\n {\n caip2: \"eip155:5\",\n name: \"Goerli\",\n rpcUrl: \"https://goerli.blockpi.network/v1/rpc/public\",\n explorerUrl: \"https://goerli.etherscan.io\",\n token: \"ETH\",\n },\n {\n caip2: \"eip155:80001\",\n name: \"Mumbai\",\n rpcUrl: \"https://rpc-mumbai.maticvigil.com\",\n explorerUrl: \"https://mumbai.polygonscan.com\",\n token: \"MATIC\",\n },\n {\n caip2: \"eip155:421613\",\n name: \"Arbitrum Goerli\",\n rpcUrl: \"https://goerli-rollup.arbitrum.io/rpc\",\n explorerUrl: \"https://goerli.arbiscan.io\",\n token: \"ETH\",\n },\n {\n caip2: \"eip155:420\",\n name: \"Optimism Goerli\",\n rpcUrl: \"https://goerli.optimism.io\",\n explorerUrl: \"https://goerli-optimism.etherscan.io\",\n token: \"ETH\",\n },\n];\n\n// ─── Build from Registry ───────────────────────────────────────────\n// Derive WalletChain entries from the single-source-of-truth chain-registry\n// and the RPC URL defaults from rpc.ts.\n\nfunction toWalletChain(chainId: number): WalletChain | null {\n const info = CHAINS[chainId];\n if (!info) return null;\n\n // Only include chains with an explorer URL (meaningful for UI display)\n if (!info.explorerUrl) return null;\n\n const caip2Id = info.caip2Id;\n\n return {\n caip2: caip2Id,\n name: info.name,\n rpcUrl: getRpcUrl(caip2Id, DEFAULT_RPC_URLS[caip2Id] ?? \"\"),\n explorerUrl: info.explorerUrl,\n token: info.nativeCurrency.symbol,\n };\n}\n\nfunction buildDefaultChains(): WalletChain[] {\n if (!CHAINS) return [];\n\n const registryChains: WalletChain[] = [];\n\n // Order by chain ID for deterministic output\n const chainIds = Object.keys(CHAINS)\n .map(Number)\n .sort((a, b) => a - b);\n\n for (const id of chainIds) {\n const chain = toWalletChain(id);\n if (chain) {\n registryChains.push(chain);\n }\n }\n\n // Append static testnets that aren't in the registry\n for (const testnet of STATIC_TESTNETS) {\n // eip155Reference rather than a split: the registry is keyed by an\n // EIP-155 number, and only a chain that has one can collide with it.\n const reference = eip155Reference(testnet.caip2);\n if (reference === null || !CHAINS[reference]) {\n registryChains.push(testnet);\n }\n }\n\n return registryChains;\n}\n\nexport const DEFAULT_EVM_CHAINS: WalletChain[] = buildDefaultChains();\n\n// ─── Helpers ───────────────────────────────────────────────────────\n\n/**\n * The configured chain for a CAIP-2 id.\n *\n * Delegates rather than parsing again. The version this replaces did\n * `parseInt(chainId.split(\":\")[1])`, which answers 5 for\n * `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`.\n */\nexport function getChainById(chains: WalletChain[], chainId: string): WalletChain | undefined {\n return resolveChain(chains, chainId) ?? undefined;\n}\n\nexport function getDefaultChains(): WalletChain[] {\n return [...DEFAULT_EVM_CHAINS];\n}\n","import {\n type AuthorizationManagers,\n type ListedAuthorization,\n listAuthorizations,\n type RevokeListedAuthorizationResult,\n revokeListedAuthorization,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UseAuthorizationsOptions {\n managers: AuthorizationManagers;\n}\n\nexport interface UseAuthorizationsReturn {\n entries: ListedAuthorization[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n revoke: (\n entry: ListedAuthorization,\n ) => Promise<RevokeListedAuthorizationResult>;\n}\n\n/** Reactive shell over the caller-owned authorization managers. */\nexport function useAuthorizations({\n managers,\n}: UseAuthorizationsOptions): UseAuthorizationsReturn {\n const managersRef = useRef(managers);\n managersRef.current = managers;\n const generationRef = useRef(0);\n const mountedRef = useRef(true);\n const [entries, setEntries] = useState<ListedAuthorization[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(\n () => () => {\n mountedRef.current = false;\n generationRef.current += 1;\n },\n [],\n );\n\n const refresh = useCallback(async () => {\n const own = ++generationRef.current;\n setLoading(true);\n setError(null);\n try {\n const next = await listAuthorizations(managersRef.current);\n if (mountedRef.current && own === generationRef.current) setEntries(next);\n } catch (cause) {\n if (mountedRef.current && own === generationRef.current) {\n setError(\n cause instanceof Error\n ? cause\n : new Error(\"Failed to list authorizations\"),\n );\n }\n } finally {\n if (mountedRef.current && own === generationRef.current)\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const revoke = useCallback(\n async (entry: ListedAuthorization) => {\n try {\n const result = await revokeListedAuthorization(\n managersRef.current,\n entry,\n );\n await refresh();\n return result;\n } catch (cause) {\n const normalized =\n cause instanceof Error\n ? cause\n : new Error(\"Failed to revoke authorization\");\n if (mountedRef.current) setError(normalized);\n throw normalized;\n }\n },\n [refresh],\n );\n\n return { entries, loading, error, refresh, revoke };\n}\n","import type { WalletChain } from \"../types\";\nimport {\n chainNumber,\n resolveChain,\n toViemChain,\n} from \"@naculus/connect-appkit-core\";\nimport { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport { createPublicClient, http, formatEther, type PublicClient, type Address } from \"viem\";\nimport { getNativeTokenPriceUsd } from \"@naculus/connect-core\";\n\nexport interface UseBalanceOptions {\n /** Auto-refresh interval in milliseconds. Default: undefined (no auto-refresh). */\n refreshInterval?: number;\n}\n\nexport interface UseBalanceResult {\n /** Raw balance in wei (string), or null if not connected / error */\n balance: string | null;\n /** Human-readable formatted balance in ETH (or native token), or null */\n formatted: string | null;\n /** Native token symbol (e.g. \"ETH\", \"MATIC\") */\n /**\n * The native currency symbol, or null when it is not known.\n *\n * Null rather than \"ETH\". This is rendered beside the number, so a fallback\n * labels 1.5 MATIC or 1.5 SOL as ether. Show the amount without a unit, or\n * hide it, but do not name the wrong one.\n */\n symbol: string | null;\n /** USD price of one native token, or null if unavailable */\n usdPrice: number | null;\n /** Formatted USD value of the balance (e.g. \"$1,234.56\"), or null */\n usdValue: string | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n chain: WalletChain | null;\n}\n\nexport function useBalance(options?: UseBalanceOptions): UseBalanceResult {\n const { evmAccount, isConnected } = useAccount();\n const { chainId, chains } = useWeb3();\n const [balance, setBalance] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [usdPrice, setUsdPrice] = useState<number | null>(null);\n const refreshInterval = options?.refreshInterval;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const currentChain = useMemo(\n () => resolveChain(chains, chainId),\n [chainId, chains],\n );\n const evmChainNumber = currentChain ? chainNumber(currentChain) : null;\n // Memoized: `toViemChain` builds a fresh object per call, and an unmemoized\n // one would change identity every render — which drives the client effects\n // below into a loop that never settles.\n const viemChain = useMemo(\n () => (currentChain ? toViemChain(currentChain, evmChainNumber) : null),\n [currentChain, evmChainNumber],\n );\n\n // No `?? \"ETH\"`. This label is rendered directly beside the number, so a\n // fallback shows \"1.5 ETH\" to someone holding 1.5 MATIC or 1.5 SOL. When\n // the chain is unknown or its native symbol was never configured, the\n // honest answer is that we do not know it.\n const tokenSymbol = useMemo(\n () => currentChain?.token ?? null,\n [currentChain],\n );\n\n const [client, setClient] = useState<PublicClient | null>(null);\n\n useEffect(() => {\n if (!viemChain || !currentChain?.rpcUrl) {\n setClient(null);\n return;\n }\n\n const publicClient = createPublicClient({\n transport: http(currentChain.rpcUrl),\n chain: viemChain,\n });\n\n setClient(publicClient);\n\n // H10: Cleanup previous client on chain change\n return () => {\n // viem PublicClient doesn't have a close method, but we clear the reference\n // to prevent stale state from being used in fetchBalance\n };\n }, [currentChain, viemChain]);\n\n const fetchBalance = useCallback(async () => {\n if (!evmAccount || !client) {\n setBalance(null);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const address = evmAccount.includes(\":\") ? evmAccount.split(\":\").pop()! : evmAccount;\n const address_ = address as Address;\n const [balanceResult, price] = await Promise.all([\n client.getBalance({ address: address_ }),\n chainId ? getNativeTokenPriceUsd(chainId, currentChain?.rpcUrl).catch(() => null) : Promise.resolve(null),\n ]);\n setBalance(balanceResult.toString());\n setUsdPrice(price);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to fetch balance\"));\n setBalance(null);\n setUsdPrice(null);\n } finally {\n setIsLoading(false);\n }\n }, [evmAccount, client, chainId, currentChain?.rpcUrl]);\n\n // Initial fetch on connect / account change\n useEffect(() => {\n if (isConnected && evmAccount) {\n fetchBalance();\n }\n }, [isConnected, evmAccount, fetchBalance]);\n\n // Auto-refresh interval\n useEffect(() => {\n if (refreshInterval && refreshInterval > 0 && isConnected && evmAccount) {\n intervalRef.current = setInterval(fetchBalance, refreshInterval);\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [refreshInterval, isConnected, evmAccount, fetchBalance]);\n\n const formatted = useMemo(() => {\n if (balance === null) return null;\n try {\n return formatEther(BigInt(balance));\n } catch {\n return null;\n }\n }, [balance]);\n\n const usdValue = useMemo(() => {\n if (usdPrice === null || formatted === null) return null;\n const numericBalance = parseFloat(formatted);\n if (Number.isNaN(numericBalance)) return null;\n const totalUsd = numericBalance * usdPrice;\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(totalUsd);\n }, [usdPrice, formatted]);\n\n return {\n balance,\n formatted,\n symbol: tokenSymbol,\n usdPrice,\n usdValue,\n isLoading,\n error,\n refetch: fetchBalance,\n chain: currentChain,\n };\n}\n","import {\n atomicSupportFor,\n type AtomicSupport,\n type ChainCapabilities,\n normalizeCapabilities,\n selectChainCapabilities,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\n// `AtomicSupport` and `ChainCapabilities` are re-exported rather than declared\n// here: Vue needs the same two, and a second declaration of \"three values, not\n// two\" is the one that quietly becomes two.\nexport type { AtomicSupport, ChainCapabilities };\n\nexport interface UseCapabilitiesReturn {\n /** Per-chain, keyed by CAIP-2. Null until a query has actually returned. */\n capabilities: Record<string, ChainCapabilities> | null;\n /** The connected chain's entry, for the common case. */\n current: ChainCapabilities | null;\n /**\n * Atomic support on the connected chain.\n *\n * `\"unknown\"` while loading, when the wallet does not implement the method,\n * and when the query failed — all three are \"we have not been told\", and a\n * caller deciding between an atomic and a sequential path needs to know that\n * rather than be handed a confident `false`.\n */\n atomic: AtomicSupport;\n isFetching: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\n/**\n * What the connected wallet says it can do — EIP-5792\n * `wallet_getCapabilities`.\n *\n * This is the query a dApp makes *before* choosing how to execute: ask whether\n * the wallet batches atomically, then send one batch or a sequence, rather\n * than sending a batch and discovering the answer from a rejection.\n */\nexport function useCapabilities(): UseCapabilitiesReturn {\n const { client, session, chainId } = useWeb3();\n const [capabilities, setCapabilities] = useState<Record<\n string,\n ChainCapabilities\n > | null>(null);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n // Guards a slow answer for a previous session overwriting a newer one.\n const generationRef = useRef(0);\n\n const refetch = useCallback(async () => {\n const generation = ++generationRef.current;\n const activeClient = resolveClient(client);\n if (!activeClient?.getCapabilities || !session) {\n setCapabilities(null);\n setIsFetching(false);\n setError(null);\n return;\n }\n setIsFetching(true);\n setError(null);\n try {\n const raw = await activeClient.getCapabilities(session);\n if (generation !== generationRef.current) return;\n setCapabilities(normalizeCapabilities(raw as Record<string, unknown>));\n } catch (err) {\n if (generation !== generationRef.current) return;\n // Cleared rather than left stale. A capability map from a previous\n // wallet is a worse answer than no answer.\n setCapabilities(null);\n setError(\n err instanceof Error ? err : new Error(\"Capability query failed\"),\n );\n } finally {\n if (generation === generationRef.current) setIsFetching(false);\n }\n }, [client, session]);\n\n useEffect(() => {\n void refetch();\n }, [refetch]);\n\n return {\n capabilities,\n current: selectChainCapabilities(capabilities, chainId),\n atomic: atomicSupportFor(capabilities, chainId),\n isFetching,\n error,\n refetch,\n };\n}\n","import { getClient } from \"../client\";\nimport type { Web3Client } from \"../client\";\n\n/**\n * Resolve the provider-owned client while retaining compatibility with older\n * hook consumers that rendered outside Web3ConnectProvider.\n *\n * The provider value is always authoritative. The legacy accessor is only a\n * fallback for isolated hooks/tests and is never used when a provider client\n * is present, so multiple providers cannot share routing state accidentally.\n */\nexport function resolveClient(client?: Web3Client | null): Web3Client | null {\n return client ?? getClient();\n}\n","import { useMemo } from \"react\";\nimport {\n chainsForNamespace,\n describeChain,\n resolveChain,\n} from \"@naculus/connect-appkit-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { ChainInfo, WalletChain } from \"../types\";\n\n/**\n * The connected chain, and the chains it is possible to switch to.\n *\n * All the judgement lives in `core/chain-selection.ts`, which imports no\n * framework — the Vue binding for this is the same three calls.\n */\nexport function useChain() {\n const { chainId, session, switchChain, chains } = useWeb3();\n\n const currentChain = useMemo<WalletChain | null>(\n () => resolveChain(chains, chainId),\n [chains, chainId],\n );\n\n // Gated on the session, unlike `currentChain`. The two answer different\n // questions: `currentChain` is the chain this client is pointed at,\n // `chainInfo` is the chain of the connection that exists. A consumer\n // rendering chain details only while connected depends on the difference.\n const chainInfo = useMemo<ChainInfo | null>(\n () => (session ? describeChain(chains, chainId) : null),\n [chains, chainId, session],\n );\n\n // Only the chains the connected wallet could actually switch to. Offering\n // an EVM chain to a Solana wallet presents an action that cannot work.\n const availableChains = useMemo<WalletChain[]>(\n () => chainsForNamespace(chains, chainId),\n [chains, chainId],\n );\n\n return {\n chainId,\n currentChain,\n chainInfo,\n availableChains,\n chains: availableChains,\n isEvm: chainId?.startsWith(\"eip155:\") ?? false,\n switchChain,\n };\n}\n","import { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { WalletError } from \"@naculus/connect-core\";\n\nexport function useConnect() {\n const { connect, status } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleConnect = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n await connect();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Connection failed\";\n setError(err instanceof WalletError ? err : new Error(errorMessage));\n } finally {\n setIsLoading(false);\n }\n }, [connect]);\n\n return {\n connect: handleConnect,\n isConnecting: isLoading || status === \"connecting\",\n error\n };\n}","import { bareEvmAddress } from \"@naculus/connect-appkit-core\";\nimport {\n delegateAccount,\n eip155Reference,\n REVOKE_DELEGATE,\n type SentDelegation,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\nimport { useViemClient } from \"./useViemClient\";\n\nexport interface UseDelegateOptions {\n /**\n * Implementations this app trusts to run with full control of the\n * account. Required and empty by default: which contract an EOA runs is the\n * security decision, and nothing is allowed unless listed. Revoking is\n * always allowed.\n */\n allowlist: readonly string[];\n}\n\nexport interface UseDelegateReturn {\n /** Delegate the connected account to `delegate` (must be allowlisted). */\n delegate: (delegate: `0x${string}`) => Promise<SentDelegation | null>;\n /** Clear the account's delegation. */\n revoke: () => Promise<SentDelegation | null>;\n /** The last sent type-4 transaction and the authorization it carried. */\n result: SentDelegation | null;\n isPending: boolean;\n error: Error | null;\n reset: () => void;\n}\n\n/**\n * EIP-7702 owner path: delegate or revoke the connected account by sending\n * a type-4 transaction from it.\n *\n * Embedded wallet only. Browser and WalletConnect wallets upgrade accounts\n * through `wallet_sendCalls`; for them this fails with `method_unsupported`\n * before anything is read or signed. Core's `delegateAccount` applies the\n * allowlist and computes both nonces; this hook only wires the session and\n * the pending-nonce read. Pair with `useDelegation().refetch()` once the\n * transaction is included.\n */\nexport function useDelegate(options: UseDelegateOptions): UseDelegateReturn {\n const { evmAccount } = useAccount();\n const { session, chainId, client } = useWeb3();\n const { publicClient } = useViemClient();\n const [result, setResult] = useState<SentDelegation | null>(null);\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const requestIdRef = useRef(0);\n const inFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n requestIdRef.current += 1;\n };\n }, []);\n\n // A new wallet context invalidates what is on screen; an operation already\n // handed to the wallet keeps the single-flight slot until it settles.\n // biome-ignore lint/correctness/useExhaustiveDependencies: resets state when the wallet context changes.\n useEffect(() => {\n requestIdRef.current += 1;\n setResult(null);\n setIsPending(false);\n setError(null);\n }, [session, chainId, evmAccount]);\n\n const run = useCallback(\n async (\n target: `0x${string}`,\n allowlist: readonly string[],\n ): Promise<SentDelegation | null> => {\n const fail = (nextError: Error): null => {\n setError(nextError);\n return null;\n };\n if (inFlightRef.current) {\n return fail(new Error(\"A delegation is already in progress\"));\n }\n const account = bareEvmAddress(evmAccount);\n if (!session || !account || !chainId) {\n return fail(\n new WalletError(\"wallet_unavailable\", \"No connected EVM account\"),\n );\n }\n // The nonce must come from the chain the wallet will send on.\n if (\n !publicClient ||\n publicClient.chain?.id !== eip155Reference(chainId)\n ) {\n return fail(\n new WalletError(\n \"chain_mismatch\",\n `No RPC client for ${chainId}; refusing to read the nonce elsewhere.`,\n ),\n );\n }\n const connector =\n session.walletType === \"embedded\"\n ? (resolveClient(client)?.embeddedConnector ?? {})\n : {};\n\n const requestId = ++requestIdRef.current;\n inFlightRef.current = true;\n setIsPending(true);\n setError(null);\n setResult(null);\n try {\n const sent = await delegateAccount({\n connector,\n session,\n account,\n chainId,\n delegate: target,\n allowlist,\n getTransactionCount: (address, blockTag) =>\n publicClient.getTransactionCount({ address, blockTag }),\n });\n if (requestId !== requestIdRef.current) return null;\n setResult(sent);\n return sent;\n } catch (err) {\n if (requestId !== requestIdRef.current) return null;\n return fail(\n err instanceof Error ? err : new Error(\"Failed to send delegation\"),\n );\n } finally {\n inFlightRef.current = false;\n if (requestId === requestIdRef.current) setIsPending(false);\n }\n },\n [chainId, client, evmAccount, publicClient, session],\n );\n\n const delegate = useCallback(\n (target: `0x${string}`) => run(target, options.allowlist),\n [run, options.allowlist],\n );\n const revoke = useCallback(() => run(REVOKE_DELEGATE, []), [run]);\n\n // Does not unlock single-flight: the transaction may still be signing or\n // broadcasting, and a second one meanwhile would be a second side effect.\n const reset = useCallback(() => {\n requestIdRef.current += 1;\n setResult(null);\n setIsPending(false);\n setError(null);\n }, []);\n\n return { delegate, revoke, result, isPending, error, reset };\n}\n","import { chainNumber, toViemChain } from \"@naculus/connect-appkit-core\";\nimport { useMemo } from \"react\";\nimport { createPublicClient, http, createWalletClient, type PublicClient, type WalletClient } from \"viem\";\nimport type { WalletChain } from \"../types\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\n\nexport function useViemClient(): {\n publicClient: PublicClient | null;\n walletClient: WalletClient | null;\n chains: WalletChain[];\n} {\n const { evmAccount, isConnected } = useAccount();\n const { currentChain, chains } = useChain();\n\n // Null for anything that is not EIP-155. viem speaks to EVM nodes, and a\n // client built with a stand-in number would address a real chain that is\n // not the one connected.\n const evmChainNumber = currentChain ? chainNumber(currentChain) : null;\n // Memoized: `toViemChain` builds a fresh object per call, and an unmemoized\n // one would change identity every render — which drives the client effects\n // below into a loop that never settles.\n const viemChain = useMemo(\n () => (currentChain ? toViemChain(currentChain, evmChainNumber) : null),\n [currentChain, evmChainNumber],\n );\n\n const publicClient = useMemo<PublicClient | null>(() => {\n if (!viemChain) return null;\n\n return createPublicClient({\n transport: http(viemChain.rpcUrls.default.http[0]),\n chain: viemChain,\n });\n }, [viemChain]);\n\n const walletClient = useMemo<WalletClient | null>(() => {\n if (!isConnected || !evmAccount || !viemChain) return null;\n\n const address = evmAccount.includes(\":\") ? evmAccount.split(\":\").pop()! : evmAccount;\n\n return createWalletClient({\n transport: http(viemChain.rpcUrls.default.http[0]),\n chain: viemChain,\n account: address as `0x${string}`\n });\n }, [isConnected, evmAccount, viemChain]);\n\n return {\n publicClient,\n walletClient,\n chains\n };\n}","import {\n applySettlementVerification,\n DEFAULT_VERIFY_RETRY,\n describePayment,\n type PaymentFetch,\n type PaymentFetchResult,\n type PaymentRecord,\n type VerifyRetryOptions,\n} from \"@naculus/connect-appkit-core\";\nimport type { SettlementVerification } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UsePaymentFetchReturn {\n /** Fetch through the paying fetch; resolves to its full result. */\n payFetch: PaymentFetch;\n /** True while any request is in flight. */\n isPending: boolean;\n /**\n * The most recently completed payment. Every paid request is recorded, in\n * completion order, until `reset()`.\n */\n lastPayment: PaymentRecord | null;\n error: Error | null;\n reset: () => void;\n}\n\nexport interface UsePaymentFetchOptions {\n verify?: (result: PaymentFetchResult) => Promise<SettlementVerification>;\n verifyRetry?: VerifyRetryOptions;\n}\n\n/**\n * State around a caller-owned paying fetch — `createX402Fetch`\n * (`@naculus/payments-x402`) or `createMppFetch` (`@naculus/payments-mpp`),\n * built with the session key and limits the app chooses. What may be paid is\n * decided there and by the session key's policy, not here.\n */\nexport function usePaymentFetch(\n pay: PaymentFetch,\n options: UsePaymentFetchOptions = {},\n): UsePaymentFetchReturn {\n const [inFlight, setInFlight] = useState(0);\n const [lastPayment, setLastPayment] = useState<PaymentRecord | null>(null);\n const [error, setError] = useState<Error | null>(null);\n // Newest request publishes errors; any paid request records its payment\n // (money was spent) until reset() or unmount bumps the epoch.\n const generationRef = useRef(0);\n const epochRef = useRef(0);\n const payRef = useRef(pay);\n payRef.current = pay;\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const verificationRef = useRef(0);\n\n useEffect(() => {\n return () => {\n generationRef.current += 1;\n epochRef.current += 1;\n verificationRef.current += 1;\n };\n }, []);\n\n const payFetch = useCallback<PaymentFetch>(async (input, init) => {\n const own = ++generationRef.current;\n const epoch = epochRef.current;\n setInFlight((n) => n + 1);\n setError(null);\n try {\n const result = await payRef.current(input, init);\n let payment = describePayment(input, result);\n if (payment && epoch === epochRef.current) {\n const verify = optionsRef.current.verify;\n if (!verify) {\n setLastPayment(payment);\n } else {\n payment = applySettlementVerification(payment, { status: \"pending\" });\n setLastPayment(payment);\n const verification = ++verificationRef.current;\n const retry = optionsRef.current.verifyRetry ?? DEFAULT_VERIFY_RETRY;\n void Promise.resolve().then(async () => {\n let outcome: SettlementVerification = { status: \"pending\" };\n for (let attempt = 0; attempt < retry.attempts; attempt += 1) {\n if (attempt > 0) {\n await new Promise((resolve) =>\n setTimeout(resolve, retry.delayMs),\n );\n }\n if (\n epoch !== epochRef.current ||\n verification !== verificationRef.current\n )\n return;\n try {\n outcome = await verify(result);\n } catch (cause) {\n outcome = {\n status: \"unavailable\",\n reason:\n cause instanceof Error\n ? cause.message\n : \"Settlement verification failed\",\n };\n }\n if (outcome.status !== \"pending\") break;\n }\n if (\n epoch === epochRef.current &&\n verification === verificationRef.current\n ) {\n setLastPayment((current) =>\n current\n ? applySettlementVerification(current, outcome)\n : current,\n );\n }\n });\n }\n }\n return result;\n } catch (cause) {\n const normalized =\n cause instanceof Error ? cause : new Error(\"Paid request failed\");\n if (own === generationRef.current) setError(normalized);\n throw normalized;\n } finally {\n setInFlight((n) => n - 1);\n }\n }, []);\n\n const reset = useCallback(() => {\n generationRef.current += 1;\n epochRef.current += 1;\n verificationRef.current += 1;\n setLastPayment(null);\n setError(null);\n }, []);\n\n return { payFetch, isPending: inFlight > 0, lastPayment, error, reset };\n}\n","import {\n createX402WalletSigner,\n findX402Provider,\n type X402SignerUnavailableReason,\n type X402TypedDataSigner,\n} from \"@naculus/connect-appkit-core\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface UseX402SignerReturn {\n signer: X402TypedDataSigner | null;\n reason: X402SignerUnavailableReason | null;\n}\n\n/** Build an x402 signer for the currently connected external EVM wallet. */\nexport function useX402Signer(): UseX402SignerReturn {\n const { session, accounts, chainId, client, switchChain } = useWeb3();\n const accountKey = accounts.join(\"\\0\");\n\n return useMemo(() => {\n void accountKey;\n void chainId;\n const provider = findX402Provider(session, {\n injected: eip6963Connector.getDiscoveredWallets(),\n walletConnect: client.connector,\n });\n return createX402WalletSigner(session, provider, switchChain);\n }, [session, accountKey, chainId, client.connector, switchChain]);\n}\n","import {\n type MppSessionChannel,\n type MppSessionFetch,\n type MppSessionFetchResult,\n type MppSessionForceCloseResult,\n type MppSessionReceipt,\n type MppSessionRequest,\n readCurrentMppSessionChannel,\n readMppRecoveryChannelId,\n readMppSessionReceipt,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nexport interface UseMppSessionReturn {\n fetch: MppSessionRequest;\n meter: { add(units: bigint): void };\n pending: bigint;\n channel: MppSessionChannel | null;\n lastReceipt: MppSessionReceipt | null;\n recoveryChannelId: string | null;\n isPending: boolean;\n error: Error | null;\n close(): Promise<MppSessionFetchResult>;\n forceClose(): Promise<MppSessionForceCloseResult>;\n reset(): void;\n}\n\nfunction normalizeError(cause: unknown): Error {\n return cause instanceof Error\n ? cause\n : new Error(\"MPP session operation failed\");\n}\n\n/** Reactive state around an MPP session fetch built and owned by the app. */\nexport function useMppSession(session: MppSessionFetch): UseMppSessionReturn {\n const [inFlight, setInFlight] = useState(0);\n const [pending, setPending] = useState(() => session.meter.pending);\n const [channel, setChannel] = useState<MppSessionChannel | null>(() =>\n readCurrentMppSessionChannel(session),\n );\n const [lastReceipt, setLastReceipt] = useState<MppSessionReceipt | null>(\n null,\n );\n const [recoveryChannelId, setRecoveryChannelId] = useState<string | null>(\n null,\n );\n const [error, setError] = useState<Error | null>(null);\n const generationRef = useRef(0);\n const epochRef = useRef(0);\n const mountedRef = useRef(true);\n const sessionRef = useRef(session);\n sessionRef.current = session;\n\n useEffect(() => {\n generationRef.current += 1;\n epochRef.current += 1;\n setInFlight(0);\n setPending(session.meter.pending);\n setChannel(readCurrentMppSessionChannel(session));\n setLastReceipt(null);\n setRecoveryChannelId(null);\n setError(null);\n }, [session]);\n\n useEffect(\n () => () => {\n mountedRef.current = false;\n generationRef.current += 1;\n epochRef.current += 1;\n },\n [],\n );\n\n const run = useCallback(\n async <T>(\n operation: (current: MppSessionFetch) => Promise<T>,\n publish?: (value: T) => void,\n clearsRecovery = false,\n ): Promise<T> => {\n const own = ++generationRef.current;\n const epoch = epochRef.current;\n const invokedSession = sessionRef.current;\n setInFlight((count) => count + 1);\n setError(null);\n try {\n const result = await operation(invokedSession);\n if (mountedRef.current && epoch === epochRef.current) {\n publish?.(result);\n const currentChannel = readCurrentMppSessionChannel(invokedSession);\n setChannel(currentChannel);\n setPending(invokedSession.meter.pending);\n if (clearsRecovery || !currentChannel) setRecoveryChannelId(null);\n }\n return result;\n } catch (cause) {\n const normalized = normalizeError(cause);\n if (mountedRef.current && epoch === epochRef.current) {\n const currentChannel = readCurrentMppSessionChannel(invokedSession);\n setChannel(currentChannel);\n setPending(invokedSession.meter.pending);\n const recovery = readMppRecoveryChannelId(cause);\n if (recovery) setRecoveryChannelId(recovery);\n else if (!currentChannel) setRecoveryChannelId(null);\n if (own === generationRef.current) setError(normalized);\n }\n throw normalized;\n } finally {\n if (mountedRef.current && epoch === epochRef.current) {\n setInFlight((count) => count - 1);\n }\n }\n },\n [],\n );\n\n const fetch = useCallback<MppSessionRequest>(\n (input, init) =>\n run(\n (current) => current(input, init),\n (result) => {\n const receipt = readMppSessionReceipt(result.receipt);\n if (receipt) setLastReceipt(receipt);\n },\n ),\n [run],\n );\n\n const close = useCallback(\n () =>\n run(\n (current) => current.close(),\n (result) => {\n const receipt = readMppSessionReceipt(result.receipt);\n if (receipt) setLastReceipt(receipt);\n },\n true,\n ),\n [run],\n );\n\n const forceClose = useCallback(\n () => run((current) => current.forceClose(), undefined, true),\n [run],\n );\n\n const add = useCallback((units: bigint) => {\n try {\n sessionRef.current.meter.add(units);\n setPending(sessionRef.current.meter.pending);\n setError(null);\n } catch (cause) {\n const normalized = normalizeError(cause);\n setError(normalized);\n setRecoveryChannelId(readMppRecoveryChannelId(cause));\n throw normalized;\n }\n }, []);\n\n const reset = useCallback(() => {\n generationRef.current += 1;\n epochRef.current += 1;\n // Calls from the old epoch no longer decrement the counter.\n setInFlight(0);\n setPending(sessionRef.current.meter.pending);\n setChannel(readCurrentMppSessionChannel(sessionRef.current));\n setLastReceipt(null);\n setRecoveryChannelId(null);\n setError(null);\n }, []);\n\n const meter = useMemo(() => ({ add }), [add]);\n\n return {\n fetch,\n meter,\n pending,\n channel,\n lastReceipt,\n recoveryChannelId,\n isPending: inFlight > 0,\n error,\n close,\n forceClose,\n reset,\n };\n}\n","import {\n createSolanaSessionKeyFlow,\n type SolanaSessionKeyFlowDeps,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n SolanaSessionKeyInfo,\n SolanaSessionKeyScope,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nfunction unavailable(): Promise<never> {\n return Promise.reject(\n new Error(\"No Solana session key manager is connected\"),\n );\n}\n\nexport interface UseSolanaSessionKeyReturn {\n /** The connected owner's keys, newest first. */\n keys: SolanaSessionKeyInfo[];\n /** Create a key; the owner's wallet approves it once. */\n create: (\n scope: SolanaSessionKeyScope,\n ) => Promise<{ key: SolanaSessionKeyInfo; signature: string }>;\n /** Stop a key; the owner's wallet signs the on-chain Revoke. */\n revoke: (id: string) => Promise<{ signature: string }>;\n refresh: () => Promise<void>;\n isPending: boolean;\n error: Error | null;\n}\n\n/**\n * Solana session keys that pay x402 / MPP without a prompt (pass\n * `{ sessionKey: { manager, id }, rpc }` to the paying fetch). The app owns\n * the `SolanaSessionKeyManager` and the RPC; `owner` is the connected\n * wallet's Solana signer role. Keep `manager`, `rpc` and `owner` stable\n * (module scope or `useMemo`): a new object each render rebuilds the flow\n * and refetches the keys every render.\n */\nexport function useSolanaSessionKey(\n deps: SolanaSessionKeyFlowDeps | null,\n): UseSolanaSessionKeyReturn {\n const [keys, setKeys] = useState<SolanaSessionKeyInfo[]>([]);\n const [inFlight, setInFlight] = useState(0);\n const [error, setError] = useState<Error | null>(null);\n const generationRef = useRef(0);\n const manager = deps?.manager;\n const rpc = deps?.rpc;\n const owner = deps?.owner;\n const flow = useMemo(\n () =>\n manager && rpc && owner\n ? createSolanaSessionKeyFlow({ manager, rpc, owner })\n : null,\n [manager, rpc, owner],\n );\n\n const run = useCallback(\n async <T>(action: () => Promise<T>, fallback: string): Promise<T> => {\n const own = ++generationRef.current;\n setInFlight((n) => n + 1);\n setError(null);\n try {\n return await action();\n } catch (cause) {\n const normalized = cause instanceof Error ? cause : new Error(fallback);\n if (own === generationRef.current) setError(normalized);\n throw normalized;\n } finally {\n // Whatever happened, show the stored state before settling (a failed\n // create is revoked, a revoke is local at once) — as the Vue shell.\n if (flow && own === generationRef.current) {\n const next = await flow.list().catch(() => null);\n if (next && own === generationRef.current) setKeys(next);\n }\n setInFlight((n) => n - 1);\n }\n },\n [flow],\n );\n\n const refresh = useCallback(async () => {\n if (!flow) {\n setKeys([]);\n return;\n }\n const own = generationRef.current;\n const next = await flow.list();\n if (own === generationRef.current) setKeys(next);\n }, [flow]);\n\n useEffect(() => {\n generationRef.current += 1;\n void refresh().catch(() => {});\n return () => {\n generationRef.current += 1;\n };\n }, [refresh]);\n\n const create = useCallback(\n (scope: SolanaSessionKeyScope) =>\n flow\n ? run(() => flow.create(scope), \"Could not create the key\")\n : unavailable(),\n [flow, run],\n );\n const revoke = useCallback(\n (id: string) =>\n flow\n ? run(() => flow.revoke(id), \"Could not revoke the key\")\n : unavailable(),\n [flow, run],\n );\n\n return { keys, create, revoke, refresh, isPending: inFlight > 0, error };\n}\n","import {\n readDelegation,\n UNKNOWN_DELEGATION,\n type DelegationStatus,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useAccount } from \"./useAccount\";\nimport { useViemClient } from \"./useViemClient\";\n\nexport interface UseDelegationReturn extends DelegationStatus {\n isFetching: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\n/**\n * Whether the connected EOA currently delegates to contract code — EIP-7702.\n *\n * A delegated account executes like a contract account: it can run several\n * calls in one transaction, which is the thing that decides whether batching\n * is possible at all for an ordinary address.\n *\n * `delegated` is `null` until the code has actually been read, and stays null\n * when the read fails. That is not the same as `false`: treating a failed RPC\n * as \"no delegation\" is how an account that can batch gets sent down the path\n * for one that cannot.\n */\nexport function useDelegation(): UseDelegationReturn {\n const { publicClient } = useViemClient();\n const { evmAccount } = useAccount();\n const [status, setStatus] = useState<DelegationStatus>(UNKNOWN_DELEGATION);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const generationRef = useRef(0);\n\n const address = evmAccount?.includes(\":\")\n ? evmAccount.split(\":\").pop()\n : evmAccount;\n\n const refetch = useCallback(async () => {\n const generation = ++generationRef.current;\n if (!publicClient || !address) {\n setStatus(UNKNOWN_DELEGATION);\n setIsFetching(false);\n setError(null);\n return;\n }\n setIsFetching(true);\n setError(null);\n try {\n const code = await publicClient.getCode({\n address: address as `0x${string}`,\n });\n if (generation !== generationRef.current) return;\n // viem answers `undefined` for an account with no code; the reader wants\n // the RPC's own \"0x\" so that \"no code\" stays distinct from \"not read\".\n setStatus(readDelegation(code ?? \"0x\"));\n } catch (err) {\n if (generation !== generationRef.current) return;\n setStatus(UNKNOWN_DELEGATION);\n setError(err instanceof Error ? err : new Error(\"Code read failed\"));\n } finally {\n if (generation === generationRef.current) setIsFetching(false);\n }\n }, [publicClient, address]);\n\n useEffect(() => {\n void refetch();\n }, [refetch]);\n\n return { ...status, isFetching, error, refetch };\n}\n","\"use client\";\n\nimport {\n bareEvmAddress,\n createDelegationPolicyFlow,\n type DelegationPolicyPreview,\n type DelegationTypedData,\n isVerifiablePolicy,\n type PolicyExecutionAdapter,\n type PolicyExecutionCheck,\n type PolicyExecutionRoute,\n type PolicyExecutionSubmission,\n type PreparedPolicyExecution,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n AtomicityRequirement,\n SessionKeyInfo,\n SessionKeyManagerConfig,\n SessionKeyScope,\n SessionKeyTransaction,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { recoverMessageAddress } from \"viem\";\nimport { useAccount } from \"./useAccount\";\nimport { useDelegation } from \"./useDelegation\";\nimport {\n type UseExecuteCallsOptions,\n useExecuteCalls,\n} from \"./useExecuteCalls\";\nimport { getSessionKeyManagerForHooks, useSessionKeys } from \"./useSessionKeys\";\nimport { useSignMessage } from \"./useSignMessage\";\n\n// The decisions — message format, verification, create/preview/sign/execute\n// ordering and every refusal — live in appkit-core (delegation-policy.ts),\n// shared with the Vue composable. This file wires them to React state and\n// the provider hooks.\nexport { buildDelegationPolicyMessage } from \"@naculus/connect-appkit-core\";\nexport type {\n DelegationPolicyPreview,\n PolicyExecutionAdapter,\n PolicyExecutionCheck,\n PolicyExecutionRoute,\n PolicyExecutionSubmission,\n PreparedPolicyExecution,\n};\n\nexport interface UseDelegationPolicyOptions {\n /** Must include a host-provided encryptionKey before a policy can be created. */\n managerConfig?: SessionKeyManagerConfig;\n execution?: UseExecuteCallsOptions;\n /** Domain shown in the signed policy. Defaults to the browser origin. */\n origin?: string;\n /** Concrete AA-module or EIP-7702 executor for promptless submissions. */\n adapter?: PolicyExecutionAdapter;\n /**\n * For `eip7702` policies: the wallet's EIP-712 signer. `message.salt` is a\n * decimal string (JSON-safe, as `eth_signTypedData_v4` takes it); for viem's\n * `signTypedData`, pass `{ ...t, message: { ...t.message, salt: BigInt(t.message.salt) } }`.\n */\n signTypedData?: (typedData: DelegationTypedData) => Promise<string>;\n /** For `eip7702` policies: the connected EVM chain number. */\n chainId?: number | null;\n}\n\nexport interface UseDelegationPolicyReturn {\n policies: SessionKeyInfo[];\n /** Active policies whose persisted signature still verifies. */\n activePolicies: SessionKeyInfo[];\n storageAvailable: boolean;\n loading: boolean;\n isBusy: boolean;\n error: Error | null;\n delegation: ReturnType<typeof useDelegation>;\n createPolicy: (scope: Partial<SessionKeyScope>) => Promise<SessionKeyInfo>;\n revokePolicy: (policyId: string) => Promise<void>;\n previewPolicyExecution: (\n policyId: string,\n tx: SessionKeyTransaction,\n callCount?: number,\n atomicity?: AtomicityRequirement,\n ) => Promise<DelegationPolicyPreview>;\n /**\n * Sign one 32-byte execution digest after enforcing the persisted policy.\n * This returns a signature only; an AA/7702 adapter must still broadcast it.\n */\n signPolicyDigest: (\n policyId: string,\n digest: `0x${string}`,\n tx: SessionKeyTransaction,\n ) => Promise<`0x${string}`>;\n /** Prepare, policy-check, session-sign, and submit one exact operation. */\n executePolicy: (\n policyId: string,\n tx: SessionKeyTransaction,\n ) => Promise<PolicyExecutionSubmission>;\n refresh: () => Promise<void>;\n clearError: () => void;\n}\n\n/**\n * Complete product flow for local, signed, persistent session policies.\n *\n * This intentionally supports `offchain` mode only. Creating an EIP-7702 or\n * AA-module policy requires a real on-chain executor; accepting those modes\n * here would turn a local record into a false delegation claim.\n */\nexport function useDelegationPolicy(\n options: UseDelegationPolicyOptions = {},\n): UseDelegationPolicyReturn {\n const { evmAccount } = useAccount();\n const signer = bareEvmAddress(evmAccount);\n const delegation = useDelegation();\n const execution = useExecuteCalls(options.execution);\n const { signMessage } = useSignMessage();\n const sessionKeys = useSessionKeys(options.managerConfig);\n const manager = getSessionKeyManagerForHooks(options.managerConfig);\n\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [verifiedPolicyIds, setVerifiedPolicyIds] = useState<Set<string>>(\n () => new Set(),\n );\n const [isVerifying, setIsVerifying] = useState(false);\n\n const policyOrigin =\n options.origin ??\n (typeof window !== \"undefined\" ? window.location.origin : \"unknown\");\n const encryptionKeyConfigured = Boolean(options.managerConfig?.encryptionKey);\n const sponsorship = options.execution?.sponsorship;\n const { refresh, storageAvailable } = sessionKeys;\n const { preview } = execution;\n const { delegated, delegate } = delegation;\n\n const flow = useMemo(\n () =>\n createDelegationPolicyFlow({\n manager,\n origin: policyOrigin,\n signer: () => signer,\n signMessage,\n verifySignature: async ({ message, signature, signerAddress }) => {\n const recovered = await recoverMessageAddress({ message, signature });\n return recovered.toLowerCase() === signerAddress.toLowerCase();\n },\n previewExecution: preview,\n sponsorship,\n adapter: options.adapter,\n signTypedData: options.signTypedData,\n chainId: () => options.chainId ?? null,\n delegation: () => ({ delegated, delegate }),\n encryptionKeyConfigured,\n storageAvailable: () => storageAvailable,\n refresh,\n }),\n [\n manager,\n policyOrigin,\n signer,\n signMessage,\n preview,\n sponsorship,\n options.adapter,\n options.signTypedData,\n options.chainId,\n delegated,\n delegate,\n encryptionKeyConfigured,\n storageAvailable,\n refresh,\n ],\n );\n\n // Verify every candidate policy whenever the list changes; a stale\n // verification for a previous list must not mark the current one.\n useEffect(() => {\n let cancelled = false;\n const candidates = sessionKeys.sessions.filter(isVerifiablePolicy);\n if (candidates.length === 0) {\n setVerifiedPolicyIds(new Set());\n setIsVerifying(false);\n return () => {\n cancelled = true;\n };\n }\n setIsVerifying(true);\n void Promise.all(\n candidates.map(\n async (policy) =>\n [policy.id, await flow.verifyStoredPolicy(policy)] as const,\n ),\n )\n .then((results) => {\n if (!cancelled) {\n setVerifiedPolicyIds(\n new Set(\n results\n .filter(([, verified]) => verified)\n .map(([policyId]) => policyId),\n ),\n );\n }\n })\n .catch((cause) => {\n if (!cancelled) {\n setVerifiedPolicyIds(new Set());\n setError(\n cause instanceof Error\n ? cause\n : new Error(\"Policy verification failed\"),\n );\n }\n })\n .finally(() => {\n if (!cancelled) setIsVerifying(false);\n });\n return () => {\n cancelled = true;\n };\n }, [sessionKeys.sessions, flow]);\n\n const clearError = useCallback(() => {\n setError(null);\n sessionKeys.clearError();\n }, [sessionKeys]);\n\n /** Busy/error state around a flow step; the error is rethrown as before. */\n const track = useCallback(\n async <T>(step: () => Promise<T>, fallback: string): Promise<T> => {\n setIsBusy(true);\n setError(null);\n try {\n return await step();\n } catch (cause) {\n const next = cause instanceof Error ? cause : new Error(fallback);\n setError(next);\n throw next;\n } finally {\n setIsBusy(false);\n }\n },\n [],\n );\n\n const createPolicy = useCallback(\n (scope: Partial<SessionKeyScope>) =>\n track(() => flow.createPolicy(scope), \"Policy creation failed\"),\n [flow, track],\n );\n const revokePolicy = useCallback(\n (policyId: string) =>\n track(() => flow.revokePolicy(policyId), \"Policy revocation failed\"),\n [flow, track],\n );\n const executePolicy = useCallback(\n (policyId: string, tx: SessionKeyTransaction) =>\n track(() => flow.executePolicy(policyId, tx), \"Policy execution failed\"),\n [flow, track],\n );\n\n const activePolicies = sessionKeys.activeSessions.filter((policy) =>\n verifiedPolicyIds.has(policy.id),\n );\n\n return {\n policies: sessionKeys.sessions,\n activePolicies,\n storageAvailable: sessionKeys.storageAvailable,\n loading: sessionKeys.loading || isVerifying,\n isBusy,\n error: error ?? sessionKeys.error,\n delegation,\n createPolicy,\n revokePolicy,\n previewPolicyExecution: flow.previewPolicyExecution,\n signPolicyDigest: flow.signPolicyDigest,\n executePolicy,\n refresh: sessionKeys.refresh,\n clearError,\n };\n}\n","import {\n type AtomicityRequirement,\n type BatchCall,\n type ExecutionPlan,\n planExecution,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useDelegation } from \"./useDelegation\";\nimport { useCallback, useState } from \"react\";\nimport { useCapabilities } from \"./useCapabilities\";\nimport { useSendCalls } from \"./useSendCalls\";\n\n/** Which executor actually runs the calls. */\nexport type ExecutionRoute = \"wallet-batch\" | \"user-operation\" | \"sequential\";\n\nexport interface ExecutionPreview extends ExecutionPlan {\n route: ExecutionRoute | null;\n}\n\nexport interface UseExecuteCallsOptions {\n /** Default requirement for `execute`. Per-call override is also accepted. */\n atomicity?: AtomicityRequirement;\n /**\n * Whether gas must be covered by a paymaster.\n *\n * A separate axis from atomicity: it answers who pays, not whether the calls\n * land together, and either can end in a refusal on its own. A route that\n * executes perfectly but charges a user who was promised sponsored gas is\n * still the wrong route, and signing is too late to find out.\n */\n sponsorship?: AtomicityRequirement;\n /**\n * ERC-7677 service passed to `wallet_sendCalls` when the wallet advertises\n * paymaster support. Advertising support alone does not sponsor a call: the\n * service URL (and optional context) is the executable configuration.\n */\n paymasterService?: {\n url: string;\n context?: Record<string, unknown>;\n };\n /**\n * A smart-account executor, typically `sendUserOp` from\n * `useSendUserOperation`.\n *\n * A UserOperation carries its calls in one on-chain execution, so it is\n * atomic by construction. Supplying this gives a wallet that cannot batch a\n * route that still satisfies `\"required\"` instead of a refusal.\n */\n userOperation?: (calls: BatchCall[]) => Promise<string>;\n /** Whether the supplied UserOperation executor is configured to sponsor gas. */\n userOperationSponsored?: boolean;\n}\n\nexport interface UseExecuteCallsReturn {\n /**\n * What would happen for this many calls, without sending anything.\n *\n * This is the query EIP-5792 exists for. An application can show \"these two\n * will land together\" or \"these will be sent one by one\" before the user\n * commits, rather than discovering it from a half-executed batch.\n */\n preview: (\n callCount: number,\n atomicity?: AtomicityRequirement,\n ) => ExecutionPreview;\n execute: (\n calls: BatchCall[],\n atomicity?: AtomicityRequirement,\n ) => Promise<string>;\n isExecuting: boolean;\n error: Error | null;\n /** The route the last `execute` took. */\n lastRoute: ExecutionRoute | null;\n reset: () => void;\n}\n\n/**\n * Route a set of calls to whichever executor can honour the caller's\n * atomicity requirement — and refuse when none can.\n *\n * `useSendCalls` already picks between an EIP-5792 batch and a sequential\n * fallback, but it picks silently and always sends something. A caller that\n * batched an approve with the swap it pays for cannot tell the difference\n * between \"these landed together\" and \"the approve landed and the swap did\n * not\", which is the outcome that leaves an approval standing to a contract\n * the user never transacted with.\n */\nexport function useExecuteCalls(\n options: UseExecuteCallsOptions = {},\n): UseExecuteCallsReturn {\n const { current, atomic } = useCapabilities();\n const { delegated, delegate } = useDelegation();\n const { sendCalls } = useSendCalls();\n const [isExecuting, setIsExecuting] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [lastRoute, setLastRoute] = useState<ExecutionRoute | null>(null);\n\n const defaultAtomicity = options.atomicity ?? \"preferred\";\n const defaultSponsorship = options.sponsorship ?? \"any\";\n const paymasterService = options.paymasterService;\n const userOperation = options.userOperation;\n const userOperationSponsored = options.userOperationSponsored ?? false;\n const walletPaymasterAvailable = Boolean(\n current?.raw?.paymasterService?.supported && paymasterService,\n );\n\n const preview = useCallback(\n (callCount: number, atomicity = defaultAtomicity): ExecutionPreview => {\n const plan = planExecution(\n {\n atomicBatch: atomic === \"supported\",\n // \"The wallet said no\" and \"the wallet has no way to say\" are\n // different facts, and the planner treats them differently.\n discovered: atomic !== \"unknown\",\n // ERC-7677 explicitly says an app MUST NOT assume the paymaster it\n // supplies is ultimately used. A supported capability plus a URL is\n // therefore a requestable route, not proof that the user will not\n // pay. Only an app-controlled sponsored executor can satisfy the\n // strict preflight guarantee.\n sponsoredTransactions: false,\n ...(current?.maxBatchSize === undefined\n ? {}\n : { maxBatchSize: current.maxBatchSize }),\n },\n callCount,\n { atomicity, sponsorship: defaultSponsorship },\n );\n\n // Capability advertising plus a paymaster URL is only a request for\n // sponsorship; EIP-7677 does not guarantee who ultimately paid. Keep a\n // strict sponsorship requirement fail-closed unless the app controls a\n // sponsored UserOperation route.\n const sponsorshipRefused =\n defaultSponsorship === \"required\" && !userOperationSponsored;\n if (plan.strategy === \"atomic-batch\" && !sponsorshipRefused) {\n return {\n ...plan,\n reason:\n plan.reason +\n (walletPaymasterAvailable\n ? \" A paymaster service will be requested, but the wallet's final fee payer must be checked after execution.\"\n : \"\"),\n route: \"wallet-batch\",\n };\n }\n // Delegation is evidence about the account, not about the wallet's RPC\n // surface, so it never upgrades a capability — a delegated EOA behind a\n // wallet that does not expose wallet_sendCalls still cannot be asked to\n // batch. It is said out loud because it is the difference between \"this\n // cannot work\" and \"this wallet has not wired it up\".\n const delegationNote =\n delegated && atomic !== \"supported\"\n ? ` This account does delegate to ${delegate} under EIP-7702, so it is capable of batching even though the wallet has not offered to.`\n : \"\";\n // A UserOperation executes its calls in one transaction, so it rescues\n // both a refusal and a non-atomic fallback the caller did not want.\n const needsUserOperation =\n (atomicity !== \"any\" && !plan.atomic) ||\n defaultSponsorship === \"required\";\n if (userOperation && needsUserOperation && !sponsorshipRefused) {\n return {\n strategy: \"atomic-batch\",\n atomic: true,\n sponsored: userOperationSponsored,\n reason:\n defaultSponsorship === \"required\" && !plan.sponsored\n ? \"The wallet batch is not configured for sponsored gas, so the calls are executed through the configured sponsored UserOperation route.\"\n : \"This wallet cannot batch, so the calls are executed as a single UserOperation through the smart account, which lands as one transaction.\",\n route: \"user-operation\",\n };\n }\n if (sponsorshipRefused) {\n return {\n strategy: \"refuse\",\n atomic: plan.atomic,\n sponsored: false,\n reason:\n \"Sponsored gas was required, but there is no executable sponsored route: no paymaster is configured for a wallet batch, and capability advertising alone cannot pay for a sequential transaction.\",\n route: null,\n };\n }\n if (plan.strategy === \"refuse\") {\n return { ...plan, reason: plan.reason + delegationNote, route: null };\n }\n return {\n ...plan,\n reason: plan.reason + delegationNote,\n route: \"sequential\",\n };\n },\n [\n atomic,\n current,\n walletPaymasterAvailable,\n userOperation,\n userOperationSponsored,\n defaultAtomicity,\n defaultSponsorship,\n delegated,\n delegate,\n ],\n );\n\n const execute = useCallback(\n async (calls: BatchCall[], atomicity = defaultAtomicity) => {\n setIsExecuting(true);\n setError(null);\n try {\n const chosen = preview(calls.length, atomicity);\n if (chosen.route === null) {\n // Refused before anything is sent. The alternative is a partial\n // execution the caller explicitly said it could not accept.\n throw new WalletError(\"method_not_allowed\", chosen.reason);\n }\n setLastRoute(chosen.route);\n\n if (chosen.route === \"user-operation\") {\n return await userOperation!(calls);\n }\n return await sendCalls(calls, {\n strategy:\n chosen.route === \"wallet-batch\" ? \"atomic-batch\" : \"sequential\",\n ...(chosen.route === \"wallet-batch\" && walletPaymasterAvailable\n ? { paymasterService }\n : {}),\n });\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Execution failed\");\n setError(e);\n throw e;\n } finally {\n setIsExecuting(false);\n }\n },\n [\n preview,\n sendCalls,\n userOperation,\n defaultAtomicity,\n paymasterService,\n walletPaymasterAvailable,\n ],\n );\n\n return {\n preview,\n execute,\n isExecuting,\n error,\n lastRoute,\n reset: () => {\n setError(null);\n setLastRoute(null);\n },\n };\n}\n","import { errorMessage } from \"@naculus/connect-appkit-core\";\nimport type {\n BatchCall,\n CallsStatus,\n ExecutionStrategy,\n} from \"@naculus/connect-core\";\nimport {\n chooseExecutionStrategy,\n getAccountCapabilities,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { extractTransactionHash } from \"./transaction-hash\";\n\n/**\n * Where a batch has got to.\n *\n * `\"submitted\"` was `\"confirmed\"`, which this hook is two steps away from\n * knowing. `wallet_sendCalls` answers with a bundle identifier, and a bundle\n * identifier does not even promise the calls were broadcast — EIP-5792 lets a\n * wallet accept them and send later. The sequential fallback returns the last\n * transaction hash, which promises broadcast and nothing more.\n *\n * `getCallsStatus` is what turns a bundle identifier into an outcome.\n */\nexport type SendCallsStatus =\n | \"idle\"\n | \"awaiting_approval\"\n | \"submitted\"\n | \"failed\";\n\nexport function useSendCalls() {\n const { session, chainId, client } = useWeb3();\n const [status, setStatus] = useState<SendCallsStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n const [batchHash, setBatchHash] = useState<string | null>(null);\n const [callsStatus, setCallsStatus] = useState<CallsStatus | null>(null);\n const [execution, setExecution] = useState<ExecutionStrategy | null>(null);\n\n const sendCalls = useCallback(\n async (\n calls: BatchCall[],\n options?: {\n chainId?: string;\n strategy?: ExecutionStrategy;\n paymasterService?: {\n url: string;\n context?: Record<string, unknown>;\n };\n },\n ): Promise<string> => {\n if (!session) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n if (calls.length === 0) {\n setStatus(\"failed\");\n const err = new WalletError(\n \"invalid_input\",\n \"At least one call is required\",\n );\n setError(err);\n throw err;\n }\n\n setStatus(\"awaiting_approval\");\n setError(null);\n setBatchHash(null);\n\n try {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const targetChain = options?.chainId ?? chainId ?? undefined;\n\n // Ask what the account can actually do before assuming it can batch.\n // A wallet with no answer, or one that says no, gets the sequential\n // path instead of an outright failure — the caller asked to send\n // these calls, not specifically to use EIP-5792.\n const strategy =\n options?.strategy ??\n chooseExecutionStrategy(\n await getAccountCapabilities(activeClient, session, targetChain),\n calls.length,\n );\n setExecution(strategy);\n\n if (strategy === \"atomic-batch\") {\n // This path was chosen because the wallet said it can execute the\n // calls atomically, so require it. Without the flag EIP-5792 lets\n // the wallet split the batch anyway, and the caller would be told\n // \"atomic-batch\" for an execution that was not.\n const result = await activeClient.sendCalls(\n session,\n calls,\n targetChain,\n {\n atomicRequired: true,\n ...(options?.paymasterService\n ? { paymasterService: options.paymasterService }\n : {}),\n },\n );\n setStatus(\"submitted\");\n setBatchHash(result);\n return result;\n }\n\n // Sequential fallback. These calls are NOT atomic: an earlier one can\n // land while a later one fails, so the returned hash is the last\n // transaction and `execution` says how it was sent. A caller that\n // needs all-or-nothing must check `capabilities.atomicBatch` first.\n let lastHash = \"\";\n for (let i = 0; i < calls.length; i++) {\n const call = calls[i];\n try {\n lastHash = extractTransactionHash(\n await activeClient.sendTransaction(session, {\n transaction: {\n to: call.to,\n data: call.data,\n value: call.value,\n },\n chainId: targetChain,\n }),\n );\n } catch (err) {\n // The dangerous case for this path: an approve landed and the swap\n // it was for did not. Say how far it got, because the caller now\n // has on-chain state it did not ask for and cannot infer the count\n // from a bare wallet error.\n throw new WalletError(\n \"tx_failed\",\n `Call ${i + 1} of ${calls.length} failed after ${i} already landed ` +\n `(sent sequentially — this wallet cannot batch atomically): ` +\n `${errorMessage(err)}`,\n );\n }\n }\n setStatus(\"submitted\");\n setBatchHash(lastHash);\n return lastHash;\n } catch (err) {\n setStatus(\"failed\");\n setError(err instanceof Error ? err : new Error(errorMessage(err)));\n throw err;\n }\n },\n [session, chainId, client],\n );\n\n const getCallsStatus = useCallback(\n async (hash?: string): Promise<CallsStatus> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n const bundleHash = hash ?? batchHash;\n if (!bundleHash) {\n throw new WalletError(\"invalid_input\", \"No bundle hash available\");\n }\n // After a sequential send the stored handle is a transaction hash, not an\n // EIP-5792 bundle identifier. Querying the wallet with it returns an\n // opaque error at best; refusing here names the actual reason.\n if (!hash && execution === \"sequential\") {\n throw new WalletError(\n \"invalid_input\",\n \"Calls were sent sequentially, so there is no bundle to query. \" +\n \"Track the returned transaction hash instead.\",\n );\n }\n\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const result = await activeClient.getCallsStatus(session, bundleHash);\n setCallsStatus(result);\n return result;\n },\n [session, batchHash, client, execution],\n );\n\n /**\n * Ask the wallet to display the bundle.\n *\n * Cosmetic: a wallet that refuses, or has no such screen, leaves the bundle\n * exactly as it was. Returns whether the wallet showed it, so a caller can\n * fall back to its own UI rather than surfacing a transaction error for\n * something that is not one.\n */\n const showCallsStatus = useCallback(\n async (hash?: string): Promise<boolean> => {\n if (!session) return false;\n const bundleHash = hash ?? batchHash;\n if (!bundleHash) return false;\n // After a sequential send the handle is a transaction hash, not a\n // bundle, so there is nothing for the wallet to look up.\n if (!hash && execution === \"sequential\") return false;\n\n const activeClient = resolveClient(client);\n if (!activeClient?.showCallsStatus) return false;\n try {\n await activeClient.showCallsStatus(session, bundleHash);\n return true;\n } catch {\n return false;\n }\n },\n [session, batchHash, client, execution],\n );\n\n const reset = useCallback(() => {\n setStatus(\"idle\");\n setError(null);\n setBatchHash(null);\n setCallsStatus(null);\n setExecution(null);\n }, []);\n\n return {\n sendCalls,\n getCallsStatus,\n showCallsStatus,\n status,\n error,\n batchHash,\n callsStatus,\n /**\n * How the last send was actually executed, or null before one runs.\n *\n * \"sequential\" means the calls were sent one at a time and are NOT atomic:\n * an earlier call can land while a later one fails. Surfaced rather than\n * hidden because a caller batching an approve + swap needs to know which\n * guarantee it got.\n */\n execution,\n reset,\n isSending: status === \"awaiting_approval\",\n };\n}\n","import { WalletError } from \"@naculus/connect-core\";\n\n/** Normalize connector-specific send results without accepting fake success. */\nexport function extractTransactionHash(result: unknown): string {\n const candidate =\n typeof result === \"string\"\n ? result\n : result && typeof result === \"object\" && \"hash\" in result\n ? (result as { hash?: unknown }).hash\n : undefined;\n\n if (typeof candidate === \"string\" && /^0x[0-9a-fA-F]{64}$/.test(candidate)) {\n return candidate;\n }\n\n throw new WalletError(\n \"tx_failed\",\n \"Wallet did not return a valid 32-byte transaction hash\",\n );\n}\n","\"use client\";\n\nimport {\n checkSessionKeyRailGrant,\n type Eip3009SessionKeyRail,\n getSharedSessionKeyManager,\n resetSharedSessionKeyManager,\n type SessionKeyRailGrantCheck,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n SessionKeyInfo,\n SessionKeyManagerConfig,\n SessionKeyScope,\n SessionKeyTransaction,\n} from \"@naculus/connect-core\";\nimport { type SessionKeyManager, WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\n// The process-wide manager and its config guard live in appkit-core so the\n// React hooks and the Vue composables share one instance and one policy.\nexport function getSessionKeyManagerForHooks(\n config?: SessionKeyManagerConfig,\n): SessionKeyManager {\n return getSharedSessionKeyManager(config);\n}\n\n/** @internal test helper */\nexport function __resetSessionKeyManagerForTests(): void {\n resetSharedSessionKeyManager();\n}\n\n// ─── useSessionKeys ────────────────────────────────────────────────────\n\nexport interface UseSessionKeysReturn {\n /** All session keys (active, revoked, expired) */\n sessions: SessionKeyInfo[];\n /** Only active session keys */\n activeSessions: SessionKeyInfo[];\n /** Whether data is loading */\n loading: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Refresh the session list from storage */\n refresh: () => Promise<void>;\n /** Clear any error */\n clearError: () => void;\n /** Whether the storage backend is available */\n storageAvailable: boolean;\n /** Fail-closed check for whether a stored scope grants EIP-3009 signing. */\n checkRailGrant: (\n scope: SessionKeyScope | null | undefined,\n rail: Eip3009SessionKeyRail,\n ) => SessionKeyRailGrantCheck;\n}\n\n/**\n * Hook to list and manage session keys.\n *\n * @example\n * ```tsx\n * const { sessions, activeSessions, refresh } = useSessionKeys();\n * ```\n */\nexport function useSessionKeys(\n config?: SessionKeyManagerConfig,\n): UseSessionKeysReturn {\n const { session } = useWeb3();\n const [sessions, setSessions] = useState<SessionKeyInfo[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n const storageAvailable = manager.isStorageAvailable();\n\n const refresh = useCallback(async () => {\n if (!session) {\n setSessions([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const keys = await manager.listSessions();\n if (mountedRef.current) {\n setSessions(keys);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to load session keys\"),\n );\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [session, manager]);\n\n // Load sessions on mount and on session change\n useEffect(() => {\n mountedRef.current = true;\n refresh();\n return () => {\n mountedRef.current = false;\n };\n }, [refresh]);\n\n const activeSessions = sessions.filter((s) => s.status === \"active\");\n\n return {\n sessions,\n activeSessions,\n loading,\n error,\n refresh,\n clearError,\n storageAvailable,\n checkRailGrant: checkSessionKeyRailGrant,\n };\n}\n\n// ─── useCreateSessionKey ───────────────────────────────────────────────\n\nexport interface UseCreateSessionKeyReturn {\n /** Create a new session key */\n createSessionKey: (\n scope?: Partial<SessionKeyScope>,\n signerAddress?: `0x${string}`,\n ) => Promise<SessionKeyInfo>;\n /** The last created session key info */\n lastCreated: SessionKeyInfo | null;\n /** Whether creation is in progress */\n isCreating: boolean;\n /** Error from last creation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to create new session keys.\n *\n * @example\n * ```tsx\n * const { createSessionKey, lastCreated, isCreating } = useCreateSessionKey();\n *\n * const handleCreate = async () => {\n * const session = await createSessionKey({\n * expiry: Math.floor(Date.now() / 1000) + 1800, // 30 min\n * maxTotalValue: parseEther(\"0.1\"),\n * });\n * };\n * ```\n */\nexport function useCreateSessionKey(\n config?: SessionKeyManagerConfig,\n): UseCreateSessionKeyReturn {\n const { session } = useWeb3();\n const [lastCreated, setLastCreated] = useState<SessionKeyInfo | null>(null);\n const [isCreating, setIsCreating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n\n const createSessionKey = useCallback(\n async (\n scope?: Partial<SessionKeyScope>,\n signerAddress?: `0x${string}`,\n ): Promise<SessionKeyInfo> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active wallet session\");\n }\n\n setIsCreating(true);\n setError(null);\n try {\n const resolvedSigner = signerAddress ?? undefined;\n const info = await manager.createSessionKey(scope, resolvedSigner);\n setLastCreated(info);\n return info;\n } catch (err) {\n const errorObj =\n err instanceof Error\n ? err\n : new Error(\"Failed to create session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsCreating(false);\n }\n },\n [session, manager],\n );\n\n return {\n createSessionKey,\n lastCreated,\n isCreating,\n error,\n clearError,\n };\n}\n\n// ─── useRevokeSession ──────────────────────────────────────────────────\n\nexport interface UseRevokeSessionReturn {\n /** Revoke a session key by ID */\n revokeSession: (sessionId: string) => Promise<void>;\n /** Whether revoking is in progress */\n isRevoking: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to revoke a session key.\n *\n * @example\n * ```tsx\n * const { revokeSession, isRevoking } = useRevokeSession();\n * await revokeSession(sessionId);\n * ```\n */\nexport function useRevokeSession(\n config?: SessionKeyManagerConfig,\n): UseRevokeSessionReturn {\n const [isRevoking, setIsRevoking] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n\n const revokeSession = useCallback(\n async (sessionId: string): Promise<void> => {\n setIsRevoking(true);\n setError(null);\n try {\n await manager.revokeSession(sessionId);\n } catch (err) {\n const errorObj =\n err instanceof Error\n ? err\n : new Error(\"Failed to revoke session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsRevoking(false);\n }\n },\n [manager],\n );\n\n return {\n revokeSession,\n isRevoking,\n error,\n clearError,\n };\n}\n\n// ─── useSendWithSession ────────────────────────────────────────────────\n\nexport interface UseSendWithSessionReturn {\n /** Sign a transaction hash after enforcing the transaction scope */\n signWithSession: (\n sessionId: string,\n messageHash: `0x${string}`,\n tx: SessionKeyTransaction,\n ) => Promise<`0x${string}`>;\n /** Check if a transaction is within a session's scope */\n checkScope: (\n sessionId: string,\n tx: {\n to?: string;\n value?: string;\n data?: string;\n chainId?: number;\n gas?: string;\n },\n ) => Promise<{\n valid: boolean;\n reason?: string;\n remainingGas?: bigint;\n remainingValue?: bigint;\n remainingTxCount?: number;\n }>;\n /** Whether an operation is in progress */\n isBusy: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to sign transactions using session keys and check scope.\n *\n * @example\n * ```tsx\n * const { signWithSession, checkScope } = useSendWithSession();\n *\n * const check = await checkScope(sessionId, tx);\n * if (check.valid) {\n * const sig = await signWithSession(sessionId, messageHash, tx);\n * }\n * ```\n */\nexport function useSendWithSession(\n config?: SessionKeyManagerConfig,\n): UseSendWithSessionReturn {\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n\n const signWithSession = useCallback(\n async (\n sessionId: string,\n messageHash: `0x${string}`,\n tx: SessionKeyTransaction,\n ): Promise<`0x${string}`> => {\n setIsBusy(true);\n setError(null);\n try {\n return await manager.signWithSessionKey(sessionId, messageHash, tx);\n } catch (err) {\n const errorObj =\n err instanceof Error\n ? err\n : new Error(\"Failed to sign with session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsBusy(false);\n }\n },\n [manager],\n );\n\n const checkScope = useCallback(\n async (\n sessionId: string,\n tx: {\n to?: string;\n value?: string;\n data?: string;\n chainId?: number;\n gas?: string;\n },\n ) => {\n setIsBusy(true);\n setError(null);\n try {\n return await manager.checkSessionScope(sessionId, tx);\n } catch (err) {\n const errorObj =\n err instanceof Error\n ? err\n : new Error(\"Failed to check session scope\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsBusy(false);\n }\n },\n [manager],\n );\n\n return {\n signWithSession,\n checkScope,\n isBusy,\n error,\n clearError,\n };\n}\n\n/**\n * Reset the global session key manager (useful for testing / cleanup).\n */\nexport function resetSessionKeyManager(): void {\n resetSharedSessionKeyManager();\n}\n","import { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { resolveClient } from \"./client-resolver\";\n\nexport function useSignMessage() {\n const { session, chainId, client } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const signMessage = useCallback(\n async (message: string): Promise<string> => {\n // Precondition checks — set error state before throwing (consistent with useSendTransaction pattern)\n if (!session) {\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n const address = session.namespaces.eip155?.accounts[0]\n ?? Object.values(session.namespaces)[0]?.accounts[0];\n\n if (!address) {\n const err = new WalletError(\"wallet_unavailable\", \"No account found\");\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const result = (await activeClient.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined\n })) as string;\n\n return result;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Signing failed\";\n const error = err instanceof Error ? err : new Error(errorMessage);\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [session, chainId, client]\n );\n\n return {\n signMessage,\n isSigning: isLoading,\n error\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport function useDisconnect() {\n const { disconnect, status } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const handleDisconnect = useCallback(async () => {\n if (status === \"disconnected\") return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await disconnect();\n } catch (err) {\n if (!mountedRef.current) return;\n setError(err instanceof Error ? err : new Error(\"Disconnect failed\"));\n } finally {\n if (mountedRef.current) setIsLoading(false);\n }\n }, [disconnect, status]);\n\n return {\n disconnect: handleDisconnect,\n isDisconnecting: isLoading,\n error,\n cleanup: () => { mountedRef.current = false; },\n };\n}","import { WalletError } from \"@naculus/connect-core\";\nimport type {\n StorageSecurityReport,\n WalletAccount,\n WalletData,\n WalletNamespace,\n} from \"@naculus/connector-embedded\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\n/** Public account metadata. Signing material never enters React state. */\nexport type EmbeddedWalletAccountView = Omit<WalletAccount, \"privateKey\">;\n\n/**\n * Public wallet metadata safe to render or pass through application state.\n *\n * `WalletData` is deliberately still returned by explicit create/import\n * calls because those are recovery workflows. The long-lived `wallet` state\n * must never retain the mnemonic or account private keys.\n */\nexport interface EmbeddedWalletView {\n accounts: EmbeddedWalletAccountView[];\n activeNamespace: WalletNamespace;\n createdAt: number;\n chainId?: string;\n version?: 2;\n /** Whether the stored record can derive missing namespace accounts. */\n recoveryAvailable: boolean;\n readonly address?: string;\n}\n\nfunction toWalletView(data: WalletData): EmbeddedWalletView {\n const activeNamespace = data.activeNamespace ?? \"eip155\";\n const accounts = Array.isArray(data.accounts)\n ? data.accounts.map(({ namespace, address, derivationPath }) => ({\n namespace,\n address,\n ...(derivationPath ? { derivationPath } : {}),\n }))\n : data.address\n ? [{ namespace: activeNamespace, address: data.address }]\n : [];\n\n return {\n accounts,\n activeNamespace,\n createdAt: data.createdAt ?? 0,\n ...(data.chainId ? { chainId: data.chainId } : {}),\n ...(data.version ? { version: data.version } : {}),\n recoveryAvailable: Boolean(data.mnemonic),\n address:\n accounts.find((account) => account.namespace === activeNamespace)\n ?.address ?? data.address,\n };\n}\n\nexport interface UseEmbeddedWalletReturn {\n connectEmbedded: () => Promise<void>;\n /** Load an existing wallet without creating or connecting a new one. */\n restoreWallet: () => Promise<boolean>;\n generateWallet: () => Promise<WalletData | null>;\n importFromMnemonic: (mnemonic: string) => Promise<WalletData | null>;\n /**\n * Import a raw key in whatever form the user has it.\n *\n * Accepts the forms MetaMask, Phantom and `solana-keygen` export, and works\n * out which chain it belongs to rather than asking. Only that namespace is\n * enabled: a key is on exactly one curve, so an account for the other would\n * be an address the key cannot control and the user cannot recover.\n */\n importFromPrivateKey: (pk: string) => Promise<WalletData | null>;\n wipe: () => Promise<void>;\n wallet: EmbeddedWalletView | null;\n hasWallet: boolean;\n /** The active account's address. See `accounts` for the rest. */\n address: string | null;\n /**\n * Every account this wallet holds, one per namespace.\n *\n * A phrase derives an independent key per BIP-44 coin type, so a wallet\n * created from one holds both an EVM and a Solana account. They are not\n * variants of one key — holding one does not reveal the other.\n */\n accounts: EmbeddedWalletAccountView[];\n /** Which account signs when no namespace is named. */\n activeNamespace: WalletNamespace | null;\n /**\n * Choose which account signs.\n *\n * Rejects a namespace this wallet holds no account for, rather than leaving\n * it pointing at nothing — a wallet imported from a raw key has only the\n * namespace that key belongs to.\n */\n setActiveNamespace: (namespace: WalletNamespace) => void;\n /**\n * Derive accounts the phrase produces but this record does not yet hold.\n *\n * A wallet created before multi-namespace support already owns its Solana\n * account — the same phrase in Phantom shows the balance — so this makes it\n * visible here rather than leaving funds reachable everywhere except in this\n * app. Leaves the active namespace alone: someone who had an Ethereum wallet\n * yesterday should not find themselves on Solana today.\n */\n backfillAccounts: () => Promise<EmbeddedWalletAccountView[]>;\n /** @deprecated Use getSeedPhrase() instead. This field will be removed. */\n seedPhrase: string | null;\n /** Get seed phrase once and clear from memory. Returns mnemonic or null. */\n getSeedPhrase: () => string | null;\n /** Read the active private key only for an explicit backup/export action. */\n getPrivateKey: () => string | null;\n backupPending: boolean;\n confirmBackup: () => void;\n isBusy: boolean;\n error: Error | null;\n clearError: () => void;\n /**\n * Storage security tier (1-4).\n * 1 = IndexedDB + AES-GCM, 2 = IndexedDB,\n * 3 = localStorage + AES-GCM, 4 = localStorage plaintext\n */\n storageSecurityLevel: number;\n /**\n * The same tier as a score with the findings behind it, or null before a\n * wallet exists.\n *\n * Null rather than a worst-case report: the storage backend is chosen when\n * the wallet is created, so warning about it beforehand would describe a\n * state that has not happened.\n */\n securityReport: StorageSecurityReport | null;\n}\n\nexport function useEmbeddedWallet(): UseEmbeddedWalletReturn {\n const { connectEmbedded: providerConnectEmbedded, client } = useWeb3();\n const [wallet, setWallet] = useState<EmbeddedWalletView | null>(null);\n const seedPhraseRef = useRef<string | null>(null);\n const storageSecurityLevelRef = useRef(4);\n const restoreErroredRef = useRef(false);\n // The connector builds a fresh report object on every call, so returning it\n // straight through would hand consumers a new identity each render and make\n // it unusable as an effect dependency. Reuse the previous object while the\n // content is unchanged.\n const reportRef = useRef<{\n json: string;\n value: StorageSecurityReport;\n } | null>(null);\n const [backupPending, setBackupPending] = useState(false);\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = () => setError(null);\n\n /** Get seed phrase once and immediately clear from memory */\n const getSeedPhrase = useCallback(() => {\n const phrase = seedPhraseRef.current;\n seedPhraseRef.current = null; // Clear immediately\n return phrase;\n }, []);\n\n const getEmbeddedConnector = useCallback(() => {\n const activeClient = resolveClient(client);\n if (!activeClient?.embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet not enabled.\",\n );\n }\n return activeClient.embeddedConnector;\n }, [client]);\n\n const getPrivateKey = useCallback(() => {\n try {\n return getEmbeddedConnector().getWallet()?.privateKey ?? null;\n } catch {\n return null;\n }\n }, [getEmbeddedConnector]);\n\n const getReadyEmbeddedConnector = useCallback(async () => {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet not enabled.\",\n );\n }\n const connector = activeClient.getEmbeddedConnector\n ? await activeClient.getEmbeddedConnector()\n : activeClient.embeddedConnector;\n if (!connector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet not enabled.\",\n );\n }\n return connector;\n }, [client]);\n\n const getPassphraseGate = useCallback(() => {\n try {\n return resolveClient(client)?.passphraseGate ?? null;\n } catch {\n return null;\n }\n }, [client]);\n\n /**\n * Drop a passphrase that did not open the wallet.\n *\n * Without this the gate keeps handing the same wrong value to every retry:\n * the user is told their passphrase is wrong and is never asked for a\n * different one, which reads as a wallet that will not open at all.\n */\n const forgetOnDecryptionFailure = useCallback(\n (err: unknown) => {\n const code = (err as { code?: unknown } | null)?.code;\n if (code !== \"decryption_failed\") return;\n getPassphraseGate()?.forget(\"That passphrase did not open the wallet.\");\n },\n [getPassphraseGate],\n );\n\n const restoreWallet = useCallback(async (): Promise<boolean> => {\n restoreErroredRef.current = false;\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n const loaded = await connector.load();\n if (!loaded) return false;\n const restored = connector.getWallet();\n if (!restored) return false;\n // Restoring signing material must not re-expose recovery material.\n seedPhraseRef.current = null;\n setBackupPending(false);\n setWallet(toWalletView(restored));\n return true;\n } catch (err) {\n restoreErroredRef.current = true;\n forgetOnDecryptionFailure(err);\n setError(\n err instanceof Error\n ? err\n : new Error(\"Failed to restore embedded wallet\"),\n );\n return false;\n }\n }, [forgetOnDecryptionFailure, getReadyEmbeddedConnector]);\n\n useEffect(() => {\n let cancelled = false;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n void restoreWallet().then((restored) => {\n if (cancelled || restored || restoreErroredRef.current) return;\n // In real production hydration the connector import and the first\n // IndexedDB open can settle in the opposite order. One bounded retry\n // closes that race without polling, prompting twice, or ever creating a\n // replacement wallet.\n retryTimer = setTimeout(() => {\n if (!cancelled) void restoreWallet();\n }, 100);\n });\n\n return () => {\n cancelled = true;\n if (retryTimer) clearTimeout(retryTimer);\n };\n }, [restoreWallet]);\n\n const handleConnectEmbedded = async () => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n const loaded = await connector.load();\n const w = connector.getWallet();\n if (loaded && w) {\n setWallet(toWalletView(w));\n seedPhraseRef.current = w.mnemonic || null;\n setBackupPending(!w.mnemonic);\n }\n await providerConnectEmbedded();\n const w2 = connector.getWallet();\n if (w2) {\n setWallet(toWalletView(w2));\n if (w2.mnemonic && !loaded) {\n seedPhraseRef.current = w2.mnemonic;\n setBackupPending(true);\n }\n }\n } catch (err) {\n forgetOnDecryptionFailure(err);\n setError(\n err instanceof Error\n ? err\n : new Error(\"Embedded wallet connection failed\"),\n );\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleGenerateWallet = async (): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n // The first save will ask for a passphrase. Say which question to put\n // to the user: prompting \"enter your passphrase\" for a wallet that does\n // not exist yet has no right answer.\n getPassphraseGate()?.expect(\"create\");\n const w = await connector.generateWallet();\n setWallet(toWalletView(w));\n seedPhraseRef.current = w.mnemonic;\n setBackupPending(true);\n return w;\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to generate wallet\"),\n );\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleImportFromMnemonic = async (\n mnemonic: string,\n ): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n // The first save will ask for a passphrase. Say which question to put\n // to the user: prompting \"enter your passphrase\" for a wallet that does\n // not exist yet has no right answer.\n getPassphraseGate()?.expect(\"create\");\n const w = await connector.importFromMnemonic(mnemonic);\n setWallet(toWalletView(w));\n seedPhraseRef.current = null;\n setBackupPending(false);\n return w;\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to import wallet\"),\n );\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleImportFromPrivateKey = async (\n pk: string,\n ): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n getPassphraseGate()?.expect(\"create\");\n const w = await connector.importFromPrivateKey(pk);\n setWallet(toWalletView(w));\n seedPhraseRef.current = null;\n setBackupPending(false);\n return w;\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to import wallet\"),\n );\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleWipe = async () => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n await connector.wipe();\n setWallet(null);\n seedPhraseRef.current = null;\n setBackupPending(false);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to wipe wallet\"));\n } finally {\n setIsBusy(false);\n }\n };\n\n /**\n * Switch namespaces and re-render.\n *\n * The wallet record is mutated in place by the connector, so a new object\n * has to be published for React to notice — without it the switch happens\n * and the UI keeps showing the previous address, which is the kind of\n * mismatch a user acts on before anyone notices.\n */\n const handleSetActiveNamespace = useCallback(\n (namespace: WalletNamespace) => {\n const connector = getEmbeddedConnector();\n connector.setActiveNamespace(namespace);\n const next = connector.getWallet();\n setWallet(next ? toWalletView(next) : null);\n },\n [getEmbeddedConnector],\n );\n\n const handleBackfillAccounts = useCallback(async () => {\n const connector = await getReadyEmbeddedConnector();\n // The connector persists what it adds, so this only has to publish it.\n const added = await connector.backfillAccounts();\n if (added.length > 0) {\n const next = connector.getWallet();\n setWallet(next ? toWalletView(next) : null);\n }\n return added.map(({ namespace, address, derivationPath }) => ({\n namespace,\n address,\n ...(derivationPath ? { derivationPath } : {}),\n }));\n }, [getReadyEmbeddedConnector]);\n\n const handleConfirmBackup = () => {\n seedPhraseRef.current = null;\n setBackupPending(false);\n };\n\n return {\n connectEmbedded: handleConnectEmbedded,\n restoreWallet,\n generateWallet: handleGenerateWallet,\n importFromMnemonic: handleImportFromMnemonic,\n importFromPrivateKey: handleImportFromPrivateKey,\n wipe: handleWipe,\n wallet,\n hasWallet: wallet !== null,\n address: wallet?.address ?? null,\n accounts: wallet?.accounts ?? [],\n activeNamespace: wallet?.activeNamespace ?? null,\n setActiveNamespace: handleSetActiveNamespace,\n backfillAccounts: handleBackfillAccounts,\n seedPhrase: seedPhraseRef.current, // backward compat (deprecated)\n getSeedPhrase,\n getPrivateKey,\n backupPending,\n confirmBackup: handleConfirmBackup,\n isBusy,\n error,\n clearError,\n storageSecurityLevel: (() => {\n try {\n const connector = getEmbeddedConnector();\n const level = connector.getStorageSecurityLevel?.() ?? 4;\n if (connector.getWallet()) {\n storageSecurityLevelRef.current = level;\n return level;\n }\n return wallet ? storageSecurityLevelRef.current : level;\n } catch {\n return wallet ? storageSecurityLevelRef.current : 4;\n }\n })(),\n securityReport: (() => {\n let next: StorageSecurityReport | null = null;\n try {\n next = getEmbeddedConnector().getStorageSecurityReport?.() ?? null;\n } catch {\n next = null;\n }\n if (!next) {\n reportRef.current = null;\n return null;\n }\n const json = JSON.stringify(next);\n if (reportRef.current?.json === json) return reportRef.current.value;\n reportRef.current = { json, value: next };\n return next;\n })(),\n };\n}\n","import { chainNumber } from \"@naculus/connect-appkit-core\";\nimport { useState, useCallback, useEffect, useRef, useMemo } from \"react\";\nimport { useViemClient } from \"./useViemClient\";\nimport { useChain } from \"./useChain\";\nimport { useERC20Context } from \"./useERC20Context\";\nimport { ERC20_MIN_ABI, formatUnits } from \"@naculus/connect-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport type { Address } from \"viem\";\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20AllowanceOptions {\n token: TokenConfig;\n owner: Address;\n spender: Address;\n refreshInterval?: number;\n}\n\nexport interface UseERC20AllowanceReturn {\n allowance: string | null;\n allowanceRaw: bigint | null;\n isFetching: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Allowance(\n options: UseERC20AllowanceOptions,\n): UseERC20AllowanceReturn {\n const { publicClient } = useViemClient();\n const { currentChain } = useChain();\n const { identity, isCurrent, assertCurrent } = useERC20Context({\n token: options.token,\n chainId: currentChain ? (chainNumber(currentChain) ?? undefined) : undefined,\n owner: options.owner,\n spender: options.spender,\n publicClient,\n });\n const [read, setRead] = useState<{\n identity: object;\n raw: bigint | null;\n fetching: boolean;\n error: Error | null;\n } | null>(null);\n const allowanceRaw = read?.identity === identity ? read.raw : null;\n const isFetching = read?.identity === identity && read.fetching;\n const error = read?.identity === identity ? read.error : null;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const generationRef = useRef(0);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: chainId keeps the callback per chain, so the refetch effect keyed on it runs when only the chain changes\n const fetchAllowance = useCallback(async () => {\n if (!isCurrent()) return;\n const generation = ++generationRef.current;\n const stillCurrent = () =>\n isCurrent() && generation === generationRef.current;\n setRead({ identity, raw: null, fetching: !!publicClient, error: null });\n if (!publicClient) return;\n try {\n assertCurrent();\n const raw = await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"allowance\",\n args: [options.owner, options.spender],\n });\n if (!stillCurrent()) return;\n setRead({ identity, raw: raw as bigint, fetching: false, error: null });\n } catch (err) {\n if (!stillCurrent()) return;\n setRead({\n identity,\n raw: null,\n fetching: false,\n error:\n err instanceof Error ? err : new Error(\"Failed to fetch allowance\"),\n });\n }\n }, [\n publicClient,\n options.token.address,\n options.token.chainId,\n options.owner,\n options.spender,\n identity,\n isCurrent,\n assertCurrent,\n ]);\n\n // Initial fetch\n useEffect(() => {\n fetchAllowance().catch((e) =>\n console.warn(\"useERC20Allowance: initial fetch failed:\", e),\n );\n }, [fetchAllowance]);\n\n // Auto-refresh interval\n useEffect(() => {\n if (options.refreshInterval && options.refreshInterval > 0) {\n intervalRef.current = setInterval(\n fetchAllowance,\n options.refreshInterval,\n );\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [options.refreshInterval, fetchAllowance]);\n\n const allowance = useMemo(() => {\n if (allowanceRaw === null) return null;\n // No `?? 18`. This string is what a user reads when auditing what they\n // have approved: formatting a 6-decimal allowance with 18 turns\n // 1,000,000 USDC into \"0.000001\", which reads as safe. Return null and let\n // the caller show the raw value and say the precision is unknown.\n const decimals = options.token.decimals;\n if (decimals === undefined) return null;\n return formatUnits(allowanceRaw, decimals);\n }, [allowanceRaw, options.token.decimals]);\n\n return {\n allowance,\n allowanceRaw,\n isFetching,\n error,\n refetch: fetchAllowance,\n };\n}\n","import type { TokenConfig } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { tokenChainMismatch } from \"@naculus/connect-appkit-core\";\n\ninterface ERC20ContextOptions {\n token: TokenConfig;\n chainId: number | undefined;\n owner: string | null;\n spender?: string;\n connected?: boolean;\n publicClient: unknown;\n walletClient?: unknown;\n session?: unknown;\n client?: unknown;\n}\n\nexport interface ERC20Context {\n /**\n * Stable token for the current context.\n *\n * Changes only when the context itself changes, so it is safe to compare\n * cached results against with `===`.\n */\n identity: object;\n /** Whether the caller's captured context is still the mounted one. */\n isCurrent: () => boolean;\n /** Throw unless the context still holds and the token is on the active chain. */\n assertCurrent: () => void;\n}\n\n/**\n * Identify the wallet/token context by value, not by object reference.\n *\n * The reference form was hostage to consumer prop hygiene. `publicClient` is\n * memoized on `currentChain`, which is memoized on `config.chains` — and a\n * consumer writing `config={{ chains: [...] }}` inline, which is ordinary\n * React, produces a new array every render. That churned the identity every\n * render, which made `isCurrent()` false for work that was in fact still\n * current and re-fired the effects keyed on these callbacks.\n *\n * What identifies the context is the values an operation targets: the token,\n * the chain, the parties, and whether a client exists at all. Two different\n * `publicClient` objects pointing at the same chain describe the same\n * operation, so they must compare equal. The client facade is deliberately not\n * part of it: which object routes the call does not change what the call does.\n */\nfunction contextKey(options: ERC20ContextOptions): string {\n return [\n options.token.address.toLowerCase(),\n options.token.chainId ?? \"\",\n options.token.decimals ?? \"\",\n options.chainId ?? \"\",\n options.owner ?? \"\",\n options.spender ?? \"\",\n options.connected ? \"1\" : \"0\",\n options.publicClient ? \"1\" : \"0\",\n options.walletClient ? \"1\" : \"0\",\n // Session identity, not the object: a re-created wrapper around the same\n // session is the same session.\n (options.session as { id?: string } | undefined)?.id ?? \"\",\n ].join(\"|\");\n}\n\n/** Bind reads and pre-signing work to the wallet/token context that started it. */\nexport function useERC20Context(options: ERC20ContextOptions): ERC20Context {\n const { token, chainId } = options;\n const address = token.address.toLowerCase() as TokenConfig[\"address\"];\n const key = contextKey(options);\n\n // One object per distinct context. Callers compare cached results against it.\n const identity = useMemo(() => ({ key }), [key]);\n\n const latestKey = useRef(key);\n const mounted = useRef(true);\n\n useLayoutEffect(() => {\n latestKey.current = key;\n }, [key]);\n\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n // Compares the key captured when the callback was created against the newest\n // one, so work started under a previous account, token, or chain can tell\n // that it no longer speaks for the component.\n const isCurrent = useCallback(\n () => mounted.current && latestKey.current === key,\n [key],\n );\n\n const assertCurrent = useCallback(() => {\n if (!isCurrent()) {\n throw new WalletError(\n \"session_inactive\",\n \"Wallet or token context changed. Retry the operation with the current account and chain.\",\n );\n }\n // Checked here rather than only at the call sites: every path that signs or\n // reads goes through this, and a token on another chain resolves to a\n // different contract at the same address.\n const mismatch = tokenChainMismatch(\n { address, chainId: token.chainId },\n chainId,\n );\n if (mismatch) throw mismatch;\n }, [isCurrent, address, token.chainId, chainId]);\n\n return { identity, isCurrent, assertCurrent };\n}\n","import {\n chainNumber,\n createDecimalsCache,\n encodeErc20Approve,\n readDecimals,\n writeDecimals,\n} from \"@naculus/connect-appkit-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport {\n ERC20_MIN_ABI,\n formatUnits,\n parseUnits,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useCallback, useRef, useState } from \"react\";\nimport type { Address } from \"viem\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport { useERC20Context } from \"./useERC20Context\";\nimport { useSendTransaction } from \"./useSendTransaction\";\nimport { useViemClient } from \"./useViemClient\";\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction toBareAddress(addr: string): Address {\n return (addr.includes(\":\") ? addr.split(\":\").pop()! : addr) as Address;\n}\n\n// ── Constants ─────────────────────────────────────────────────────\n\nconst MAX_UINT256 = 2n ** 256n - 1n;\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20ApproveOptions {\n token: TokenConfig;\n spender: Address;\n}\n\nexport interface UseERC20ApproveReturn {\n /** Approve a specific amount */\n approve: (amount: string) => Promise<`0x${string}`>;\n /** Approve max (type(uint256).max — infinite approval) */\n approveMax: () => Promise<`0x${string}`>;\n /** Current allowance as raw bigint */\n allowanceRaw: bigint | null;\n /** Current allowance as human-readable string */\n allowance: string | null;\n /** Check if allowance >= required amount */\n hasAllowance: (required: string) => Promise<boolean>;\n isApproving: boolean;\n isFetchingAllowance: boolean;\n error: Error | null;\n /**\n * Re-read the allowance and return it.\n *\n * The value is returned because reading `allowanceRaw` immediately after\n * awaiting this does not work: that binding belongs to the render that\n * created the callback, and setState does not rewrite it.\n */\n refetchAllowance: () => Promise<bigint | null>;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Approve(\n options: UseERC20ApproveOptions,\n): UseERC20ApproveReturn {\n const { publicClient, walletClient } = useViemClient();\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n const { session, client } = useWeb3();\n const {\n sendTransaction,\n isSending,\n error: sendTxError,\n reset,\n } = useSendTransaction();\n const [localError, setLocalError] = useState<Error | null>(null);\n const { identity, isCurrent, assertCurrent } = useERC20Context({\n token: options.token,\n chainId: currentChain\n ? (chainNumber(currentChain) ?? undefined)\n : undefined,\n owner: evmAccount,\n spender: options.spender,\n connected: isConnected,\n publicClient,\n walletClient,\n session,\n client,\n });\n const [read, setRead] = useState<{\n identity: object;\n raw: bigint | null;\n fetching: boolean;\n } | null>(null);\n const allowanceRaw = read?.identity === identity ? read.raw : null;\n const isFetchingAllowance = read?.identity === identity && read.fetching;\n\n const decimalsRef = useRef(\n createDecimalsCache(options.token, options.token.decimals),\n );\n const allowanceGenerationRef = useRef(0);\n const error = localError ?? sendTxError;\n\n const ownerAddress = (() => {\n if (!evmAccount) return null;\n return toBareAddress(evmAccount);\n })();\n\n // Returns what it read. Callers that need the value cannot get it from\n // `allowanceRaw` right after awaiting: that binding is the one captured at\n // render, and a setState does not rewrite it.\n // biome-ignore lint/correctness/useExhaustiveDependencies: chainId keeps the callback per chain, so the refetch effect keyed on it runs when only the chain changes\n const fetchAllowance = useCallback(async (): Promise<bigint | null> => {\n if (!isCurrent()) return null;\n const generation = ++allowanceGenerationRef.current;\n const stillCurrent = () =>\n isCurrent() && generation === allowanceGenerationRef.current;\n setRead({\n identity,\n raw: null,\n fetching: !!publicClient && !!ownerAddress && isConnected,\n });\n setLocalError(null);\n if (!publicClient || !ownerAddress || !isConnected) return null;\n try {\n assertCurrent();\n const raw = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"allowance\",\n args: [ownerAddress, options.spender],\n })) as bigint;\n if (!stillCurrent()) return null;\n setRead({ identity, raw, fetching: false });\n return raw;\n } catch (err) {\n if (stillCurrent()) {\n setRead({ identity, raw: null, fetching: false });\n setLocalError(\n err instanceof Error ? err : new Error(\"Failed to fetch allowance\"),\n );\n }\n return null;\n }\n }, [\n publicClient,\n ownerAddress,\n options.token.address,\n options.token.chainId,\n options.spender,\n identity,\n isCurrent,\n assertCurrent,\n isConnected,\n ]);\n\n const allowance = (() => {\n if (allowanceRaw === null) return null;\n // No `?? 18`: guessing a token's precision misstates every amount derived\n // from it, and 18 is only right for the tokens that happen to use it.\n const decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) return null;\n return formatUnits(allowanceRaw, decimals);\n })();\n\n const doApprove = useCallback(\n async (rawAmount: bigint): Promise<`0x${string}`> => {\n setLocalError(null);\n reset();\n\n if (!isConnected || !evmAccount) {\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No connected account\",\n );\n setLocalError(err);\n throw err;\n }\n\n if (!publicClient) {\n const err = new WalletError(\"wallet_unavailable\", \"No public client\");\n setLocalError(err);\n throw err;\n }\n\n // Approving on the wrong chain grants a spender rights over whatever\n // contract sits at this address there, which is not the token the user\n // was shown.\n try {\n assertCurrent();\n const data = encodeErc20Approve(options.spender, rawAmount);\n const activeClient = resolveClient(client);\n if (session) {\n if (activeClient) {\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n fetchAllowance();\n return txHash as `0x${string}`;\n }\n }\n\n if (walletClient) {\n const { request } = await publicClient.simulateContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"approve\",\n args: [options.spender, rawAmount],\n account: ownerAddress!,\n });\n assertCurrent();\n const txHash = await walletClient.writeContract(request);\n fetchAllowance();\n return txHash;\n }\n\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n fetchAllowance();\n return txHash as `0x${string}`;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Approve failed\");\n if (isCurrent()) setLocalError(error);\n throw error;\n }\n },\n [\n options,\n publicClient,\n walletClient,\n evmAccount,\n isConnected,\n session,\n client,\n ownerAddress,\n sendTransaction,\n reset,\n fetchAllowance,\n assertCurrent,\n isCurrent,\n ],\n );\n\n const approveAmount = useCallback(\n async (amount: string): Promise<`0x${string}`> => {\n try {\n assertCurrent();\n if (!publicClient)\n throw new WalletError(\"wallet_unavailable\", \"No public client\");\n\n let decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) {\n decimals = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n })) as number;\n assertCurrent();\n writeDecimals(decimalsRef.current, options.token, decimals);\n }\n\n const rawAmount = parseUnits(amount, decimals);\n return await doApprove(rawAmount);\n } catch (err) {\n if (isCurrent())\n setLocalError(\n err instanceof Error ? err : new Error(\"Approve failed\"),\n );\n throw err;\n }\n },\n [options.token, publicClient, doApprove, assertCurrent, isCurrent],\n );\n\n const approveMaxAmount = useCallback(async (): Promise<`0x${string}`> => {\n return doApprove(MAX_UINT256);\n }, [doApprove]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on the token fields it reads (address, chainId, decimals); the token object identity changes every render\n const checkAllowance = useCallback(\n async (required: string): Promise<boolean> => {\n if (!isCurrent() || !isConnected || !ownerAddress || !publicClient)\n return false;\n try {\n assertCurrent();\n } catch (err) {\n setLocalError(\n err instanceof Error ? err : new Error(\"Cannot check allowance\"),\n );\n return false;\n }\n // `allowanceRaw` is the render-time binding, so awaiting a refetch never\n // changed it — the second null check below used to always hit, and this\n // gate answered false on every first call. Callers reading it as \"no\n // approval yet\" prompted for an approval the user had already granted.\n const current = allowanceRaw ?? (await fetchAllowance());\n if (current === null) return false;\n\n // No `decimals = 18` fallback. This is a gate: a caller does\n // `if (await hasAllowance(x)) skipApprove()`, so a wrong precision here\n // is a wrong answer to \"is it safe to skip the approval\", not a\n // misformatted string. Read the token instead, and refuse if that fails.\n let decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) {\n if (!publicClient) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Cannot check allowance: no public client to read token decimals.\",\n );\n }\n decimals = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n })) as number;\n if (!isCurrent()) return false;\n writeDecimals(decimalsRef.current, options.token, decimals);\n }\n\n const requiredRaw = parseUnits(required, decimals);\n return isCurrent() && current >= requiredRaw;\n },\n [\n allowanceRaw,\n fetchAllowance,\n options.token.address,\n options.token.chainId,\n options.token.decimals,\n publicClient,\n isCurrent,\n assertCurrent,\n isConnected,\n ownerAddress,\n ],\n );\n\n return {\n approve: approveAmount,\n approveMax: approveMaxAmount,\n allowance,\n allowanceRaw,\n hasAllowance: checkAllowance,\n isApproving: isSending,\n isFetchingAllowance,\n error,\n refetchAllowance: fetchAllowance,\n };\n}\n","import { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { EvmTransaction } from \"../types\";\nimport { resolveClient } from \"./client-resolver\";\nimport { extractTransactionHash } from \"./transaction-hash\";\n\n/**\n * Where a send has got to.\n *\n * `\"submitted\"` was `\"confirmed\"`, which was a claim the hook could not\n * support: `sendTransaction` resolves with a transaction hash, and a hash\n * means the wallet broadcast it — not that it was mined, and not that it\n * succeeded. An interface showing \"confirmed\" at that moment tells someone\n * their payment went through while it can still revert or never be included.\n *\n * To reach an actual confirmation, watch the returned hash with\n * `useTxMonitor`, where `\"confirmed\"` is established by a receipt.\n */\nexport type SendTransactionStatus =\n | \"idle\"\n | \"awaiting_approval\"\n | \"submitted\"\n | \"failed\";\n\nexport function useSendTransaction() {\n const { session, chainId, client } = useWeb3();\n const [status, setStatus] = useState<SendTransactionStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n\n const sendTransaction = useCallback(\n async (transaction: EvmTransaction): Promise<string> => {\n if (!session) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n const evmAccount = session.namespaces.eip155?.accounts.find(\n (account) =>\n /^eip155:\\d+:0x[0-9a-fA-F]{40}$/.test(account) ||\n /^0x[0-9a-fA-F]{40}$/.test(account),\n );\n\n if (!evmAccount) {\n setStatus(\"failed\");\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No EVM account found\",\n );\n setError(err);\n throw err;\n }\n\n setStatus(\"awaiting_approval\");\n setError(null);\n\n try {\n const txWithFrom = {\n ...transaction,\n from: transaction.from ?? evmAccount.split(\":\").pop(),\n };\n\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const result = await activeClient.sendTransaction(session, {\n transaction: txWithFrom,\n chainId: chainId ?? undefined,\n });\n const hash = extractTransactionHash(result);\n\n setStatus(\"submitted\");\n return hash;\n } catch (err) {\n setStatus(\"failed\");\n const errorMessage =\n err instanceof Error ? err.message : \"Transaction failed\";\n setError(err instanceof Error ? err : new Error(errorMessage));\n throw err;\n }\n },\n [session, chainId, client],\n );\n\n const reset = useCallback(() => {\n setStatus(\"idle\");\n setError(null);\n }, []);\n\n return {\n sendTransaction,\n status,\n error,\n reset,\n isSending: status === \"awaiting_approval\",\n };\n}\n","import {\n chainNumber,\n createDecimalsCache,\n encodeErc20Transfer,\n readDecimals,\n writeDecimals,\n} from \"@naculus/connect-appkit-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport { ERC20_MIN_ABI, parseUnits, WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useRef, useState } from \"react\";\nimport type { Address } from \"viem\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport { useERC20Context } from \"./useERC20Context\";\nimport { useSendTransaction } from \"./useSendTransaction\";\nimport { useViemClient } from \"./useViemClient\";\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction toBareAddress(addr: string): Address {\n return (addr.includes(\":\") ? addr.split(\":\").pop()! : addr) as Address;\n}\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20TransferOptions {\n token: TokenConfig;\n}\n\nexport interface UseERC20TransferReturn {\n /** Send a transfer. Returns tx hash on success. */\n sendTransfer: (to: Address, amount: string) => Promise<`0x${string}`>;\n isSending: boolean;\n error: Error | null;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Transfer(\n options: UseERC20TransferOptions,\n): UseERC20TransferReturn {\n const { publicClient, walletClient } = useViemClient();\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n const { session, client } = useWeb3();\n const {\n sendTransaction,\n isSending,\n error: sendTxError,\n reset,\n } = useSendTransaction();\n const [localError, setLocalError] = useState<Error | null>(null);\n const { isCurrent, assertCurrent } = useERC20Context({\n token: options.token,\n chainId: currentChain\n ? (chainNumber(currentChain) ?? undefined)\n : undefined,\n owner: evmAccount,\n connected: isConnected,\n publicClient,\n walletClient,\n session,\n client,\n });\n\n // Keyed by token: a bare ref kept the first token's precision when the user\n // switched tokens, and converted the amount with the wrong scale.\n const decimalsRef = useRef(\n createDecimalsCache(options.token, options.token.decimals),\n );\n const error = localError ?? sendTxError;\n\n const sendTransfer = useCallback(\n async (to: Address, amount: string): Promise<`0x${string}`> => {\n setLocalError(null);\n reset();\n\n if (!isConnected || !evmAccount) {\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No connected account\",\n );\n setLocalError(err);\n throw err;\n }\n\n if (!publicClient) {\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No public client available\",\n );\n setLocalError(err);\n throw err;\n }\n\n // Transferring on the wrong chain sends the call to whatever contract\n // occupies this address there. The decimals read below would come from\n // that contract too, so the amount would be wrong as well.\n try {\n assertCurrent();\n\n const address = toBareAddress(evmAccount);\n\n // Fetch decimals if not cached\n let decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) {\n decimals = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n })) as number;\n assertCurrent();\n writeDecimals(decimalsRef.current, options.token, decimals);\n }\n\n const rawAmount = parseUnits(amount, decimals);\n const data = encodeErc20Transfer(to, rawAmount);\n\n const activeClient = resolveClient(client);\n // Strategy 1: session-based connector\n if (session) {\n if (activeClient) {\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n return txHash as `0x${string}`;\n }\n }\n\n // Strategy 2: embedded wallet via viem wallet client\n if (walletClient) {\n const { request } = await publicClient.simulateContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"transfer\",\n args: [to, rawAmount],\n account: address,\n });\n assertCurrent();\n const txHash = await walletClient.writeContract(request);\n return txHash;\n }\n\n // Strategy 3: fallback to sendTransaction hook\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n return txHash as `0x${string}`;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Transfer failed\");\n if (isCurrent()) setLocalError(error);\n throw error;\n }\n },\n [\n options.token,\n publicClient,\n walletClient,\n evmAccount,\n isConnected,\n session,\n client,\n sendTransaction,\n reset,\n assertCurrent,\n isCurrent,\n ],\n );\n\n return {\n sendTransfer,\n isSending,\n error,\n };\n}\n","import { chainNumber, encodeErc20Transfer } from \"@naculus/connect-appkit-core\";\n/**\n * useERC20TransferSimulation — React hook for simulating ERC-20 token\n * transfers before signing/submitting.\n *\n * Wraps useTransactionSimulation with ERC-20 transfer calldata building,\n * so callers only need the token, recipient, and amount.\n *\n * @see /docs/features/transaction-simulation.md\n */\n\nimport { parseUnits, type TokenConfig } from \"@naculus/connect-core\";\nimport { useMemo } from \"react\";\nimport type { EvmTransaction } from \"../types\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport {\n type SimulationResult,\n type UseTransactionSimulationReturn,\n useTransactionSimulation,\n} from \"./useTransactionSimulation\";\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20TransferSimulationOptions {\n /** Token configuration (address, decimals, chainId) */\n token: TokenConfig;\n /** Recipient address */\n to: `0x${string}`;\n /** Amount in human-readable units (e.g. \"1.50\" for 1.5 USDC) */\n amount: string;\n}\n\nexport interface UseERC20TransferSimulationReturn\n extends Omit<UseTransactionSimulationReturn, \"simulate\"> {\n /** Simulation result for the built ERC-20 transfer */\n result: SimulationResult | undefined;\n /** Whether a simulation is in progress */\n isSimulating: boolean;\n /** Error from the last simulation attempt */\n error: Error | null;\n /** Re-run the simulation with current parameters */\n reSimulate: () => Promise<SimulationResult>;\n /** Reset simulation state */\n reset: () => void;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20TransferSimulation(\n options: UseERC20TransferSimulationOptions,\n): UseERC20TransferSimulationReturn {\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n // No `?? 1`. TokenConfig.chainId says where the token lives; falling back to\n // mainnet simulates against whatever contract occupies that address there.\n const chainId =\n options.token.chainId ??\n (currentChain ? (chainNumber(currentChain) ?? undefined) : undefined);\n\n // Build the transaction descriptor from ERC-20 transfer params\n const tx: EvmTransaction | undefined = useMemo(() => {\n if (!isConnected || !evmAccount) return undefined;\n\n try {\n // No `?? 18`. A simulation built with the wrong precision previews a\n // different transfer than the one that will be sent, which is worse\n // than showing no preview at all.\n const decimals = options.token.decimals;\n if (decimals === undefined) return undefined;\n const rawAmount = parseUnits(options.amount, decimals);\n const data = encodeErc20Transfer(options.to, rawAmount);\n\n return {\n to: options.token.address,\n data,\n value: \"0\",\n };\n } catch {\n // Fail closed: never preview calldata different from what sendTransfer accepts.\n return undefined;\n }\n }, [\n options.token.address,\n options.token.decimals,\n options.to,\n options.amount,\n evmAccount,\n isConnected,\n ]);\n\n // Use the base transaction simulation hook\n const sim = useTransactionSimulation(tx, chainId);\n\n // Alias simulate → reSimulate for semantic clarity\n return {\n // The base hook may still hold (or later receive) the previous transaction's\n // result. Never display it for inputs that cannot produce sendable calldata.\n result: tx ? sim.result : undefined,\n isSimulating: !!tx && sim.isSimulating,\n error: tx ? sim.error : null,\n reSimulate: sim.simulate,\n reset: sim.reset,\n };\n}\n","/** React state shell for the framework-neutral eth_call revert preview. */\nimport { simulateTransactionPreview } from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { EvmTransaction } from \"../types\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport { useViemClient } from \"./useViemClient\";\n\nexport type {\n ApprovalChange,\n BalanceChange,\n GasInfo,\n RiskAssessment,\n RiskLevel,\n RiskWarning,\n SimulationResult,\n SimulationStatus,\n} from \"@naculus/wallet-engine\";\n\nimport type { SimulationResult } from \"@naculus/wallet-engine\";\n\nexport interface UseTransactionSimulationReturn {\n result: SimulationResult | undefined;\n isSimulating: boolean;\n error: Error | null;\n simulate: () => Promise<SimulationResult>;\n reset: () => void;\n}\n\nexport function useTransactionSimulation(\n tx: EvmTransaction | undefined,\n chainId?: number,\n): UseTransactionSimulationReturn {\n useWeb3();\n const { evmAccount } = useAccount();\n const { currentChain } = useChain();\n const { publicClient } = useViemClient();\n const [result, setResult] = useState<SimulationResult | undefined>(undefined);\n const [isSimulating, setIsSimulating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n\n const simulate = useCallback(async (): Promise<SimulationResult> => {\n if (tx) {\n setIsSimulating(true);\n setError(null);\n }\n try {\n const simResult = await simulateTransactionPreview(tx, {\n chainId,\n currentChain,\n publicClient,\n evmAccount,\n });\n setResult(simResult);\n return simResult;\n } catch (cause) {\n const err =\n cause instanceof Error ? cause : new Error(\"Simulation failed\");\n setError(err);\n throw err;\n } finally {\n if (tx) setIsSimulating(false);\n }\n }, [tx, chainId, currentChain, publicClient, evmAccount]);\n\n useEffect(() => {\n if (!tx) return;\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n simulate().catch(() => {\n // Error is captured in state.\n });\n }, 300);\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [tx, simulate]);\n\n const reset = useCallback(() => {\n setResult(undefined);\n setError(null);\n setIsSimulating(false);\n }, []);\n\n return { result, isSimulating, error, simulate, reset };\n}\n","import { useState, useCallback, useRef } from \"react\";\nimport type { TxMonitorLike, TxStatusEntry } from \"./useTxMonitor\";\nimport { useTxMonitorProvider } from \"./useTxMonitor\";\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseLastTxResult {\n /** Most recent transaction by createdAt */\n lastTx: TxStatusEntry | null;\n /** Most recent confirmed transaction */\n lastConfirmedTx: TxStatusEntry | null;\n /** Most recent failed transaction */\n lastFailedTx: TxStatusEntry | null;\n /** Clear cached lastTx state */\n clear: () => void;\n}\n\n/**\n * Track the most recent transaction.\n * Automatically updates when a new transaction is sent (via statusChange events).\n */\nexport function useLastTx(monitor?: TxMonitorLike): UseLastTxResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [lastTx, setLastTx] = useState<TxStatusEntry | null>(null);\n const [lastConfirmedTx, setLastConfirmedTx] = useState<TxStatusEntry | null>(null);\n const [lastFailedTx, setLastFailedTx] = useState<TxStatusEntry | null>(null);\n const lastTxRef = useRef<{ createdAt: number } | null>(null);\n\n // Track confirmed and failed events\n const confirmedHandlerRef = useRef<((entry: TxStatusEntry) => void) | null>(null);\n const failedHandlerRef = useRef<((entry: TxStatusEntry) => void) | null>(null);\n\n // Set up listeners\n if (effectiveMonitor) {\n if (!confirmedHandlerRef.current) {\n confirmedHandlerRef.current = (entry: TxStatusEntry) => {\n setLastConfirmedTx(entry);\n if (!lastTxRef.current || entry.createdAt >= lastTxRef.current.createdAt) {\n setLastTx(entry);\n lastTxRef.current = entry;\n }\n };\n effectiveMonitor.on(\"confirmed\", confirmedHandlerRef.current);\n }\n\n if (!failedHandlerRef.current) {\n failedHandlerRef.current = (entry: TxStatusEntry) => {\n setLastFailedTx(entry);\n if (!lastTxRef.current || entry.createdAt >= lastTxRef.current.createdAt) {\n setLastTx(entry);\n lastTxRef.current = entry;\n }\n };\n effectiveMonitor.on(\"failed\", failedHandlerRef.current);\n }\n }\n\n const clear = useCallback(() => {\n setLastTx(null);\n setLastConfirmedTx(null);\n setLastFailedTx(null);\n lastTxRef.current = null;\n }, []);\n\n return {\n lastTx,\n lastConfirmedTx,\n lastFailedTx,\n clear,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\n\n// ── Types (standalone, to avoid dependency on wallet-engine) ──────\n\nexport type TxStatus =\n | \"pending\"\n | \"mined\"\n | \"confirmed\"\n | \"failed\"\n | \"unknown\";\n\nexport interface TxStatusEntry {\n hash: string;\n chainId: number;\n from: string;\n to: string;\n value: string;\n data?: string;\n nonce?: number;\n status: TxStatus;\n blockNumber?: number;\n blockHash?: string;\n gasUsed?: string;\n effectiveGasPrice?: string;\n createdAt: number;\n confirmedAt?: number;\n updatedAt: number;\n error?: string;\n label?: string;\n memo?: string;\n replacementCount?: number;\n}\n\n/** Minimal TxMonitor interface for React hooks */\nexport interface TxMonitorLike {\n watchTx(hash: string, chainId: number, options?: {\n requiredConfirmations?: number;\n pollInterval?: number;\n label?: string;\n memo?: string;\n initialEntry?: Partial<TxStatusEntry>;\n }): Promise<TxStatusEntry>;\n\n stopWatching(hash: string, chainId?: number): void;\n getTxStatus(hash: string, chainId?: number): TxStatusEntry | null;\n getTxHistory(address?: string, chainId?: number): Promise<TxStatusEntry[]>;\n refreshTx(hash: string, chainId?: number): Promise<void>;\n\n on(event: \"statusChange\", listener: (entry: TxStatusEntry) => void): this;\n on(event: \"confirmed\", listener: (entry: TxStatusEntry) => void): this;\n on(event: \"failed\", listener: (entry: TxStatusEntry) => void): this;\n off(event: string, listener: (entry: TxStatusEntry) => void): this;\n}\n\n// ── Context for providing TxMonitor ───────────────────────────────\n\nimport { createContext, useContext } from \"react\";\n\nexport const TxMonitorContext = createContext<TxMonitorLike | null>(null);\n\nexport function useTxMonitorProvider(): TxMonitorLike | null {\n return useContext(TxMonitorContext);\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseTxMonitorResult {\n entry: TxStatusEntry | null;\n status: TxStatus | \"idle\";\n isLoading: boolean;\n isWatching: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n stopWatching: () => void;\n}\n\n/**\n * Monitor a single transaction's lifecycle.\n * When hash changes, automatically stops old watch and starts new one.\n */\nexport function useTxMonitor(\n hash?: string,\n chainId?: number,\n monitor?: TxMonitorLike,\n): UseTxMonitorResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [entry, setEntry] = useState<TxStatusEntry | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isWatching, setIsWatching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const prevHashRef = useRef<string | undefined>(undefined);\n\n const refresh = useCallback(async () => {\n if (!effectiveMonitor || !hash) return;\n setIsLoading(true);\n setError(null);\n try {\n await effectiveMonitor.refreshTx(hash, chainId);\n const current = effectiveMonitor.getTxStatus(hash, chainId);\n if (current) setEntry(current);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [effectiveMonitor, hash, chainId]);\n\n const stopWatching = useCallback(() => {\n if (!effectiveMonitor || !hash) return;\n effectiveMonitor.stopWatching(hash, chainId);\n setIsWatching(false);\n }, [effectiveMonitor, hash, chainId]);\n\n useEffect(() => {\n if (!effectiveMonitor || !hash || !chainId) {\n setEntry(null);\n setIsWatching(false);\n return;\n }\n\n // Stop previous watch if hash changed\n if (prevHashRef.current && prevHashRef.current !== hash) {\n effectiveMonitor.stopWatching(prevHashRef.current);\n }\n prevHashRef.current = hash;\n\n let cancelled = false;\n setIsWatching(true);\n setIsLoading(true);\n setError(null);\n\n // Check if we already have status\n const current = effectiveMonitor.getTxStatus(hash, chainId);\n if (current) {\n setEntry(current);\n setIsLoading(false);\n }\n\n // Start watching\n effectiveMonitor.watchTx(hash, chainId, {}).then((initial) => {\n if (!cancelled) {\n setEntry(initial);\n setIsLoading(false);\n }\n }).catch((err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n }\n });\n\n // Listen for status changes\n const onStatusChange = (updated: TxStatusEntry) => {\n if (!cancelled) setEntry({ ...updated });\n };\n effectiveMonitor.on(\"statusChange\", onStatusChange);\n\n return () => {\n cancelled = true;\n setIsWatching(false);\n effectiveMonitor.off(\"statusChange\", onStatusChange);\n };\n }, [effectiveMonitor, hash, chainId]);\n\n const status: TxStatus | \"idle\" = entry?.status ?? \"idle\";\n\n return {\n entry,\n status,\n isLoading,\n isWatching,\n error,\n refresh,\n stopWatching,\n };\n}\n","import type {\n NameResolver,\n NameResolverConfig,\n NameResult,\n} from \"@naculus/connect-core\";\nimport { useCallback } from \"react\";\nimport { useNameLookup } from \"../core/name-lookup\";\n\n/**\n * Result of a reverse resolution query.\n */\nexport interface UseLookupAddressResult {\n /** Resolved name, or null if not found / not started. */\n data: NameResult | null;\n /** Whether the lookup is in progress. */\n isLoading: boolean;\n /** Error that occurred during lookup, if any. */\n error: Error | null;\n /** Manually trigger re-lookup of the current address. */\n refetch: () => void;\n}\n\n/**\n * Options for the useLookupAddress hook.\n */\nexport interface UseLookupAddressOptions {\n /** Chain to resolve against, CAIP-2. */\n chainId?: string;\n /** Whether to skip the lookup (e.g. if the input is incomplete). */\n skip?: boolean;\n /** Custom resolver configuration (overrides default RPC URLs). */\n resolverConfig?: NameResolverConfig;\n}\n\n/**\n * React hook to resolve a blockchain address to a human-readable name.\n *\n * Reverse resolution for ENS and SNS.\n *\n * @example\n * ```tsx\n * function AccountLabel({ address }) {\n * const { data } = useLookupAddress(address);\n * return <span>{data?.name ?? address}</span>;\n * }\n * ```\n */\nexport function useLookupAddress(\n address: string,\n options?: UseLookupAddressOptions,\n): UseLookupAddressResult {\n const query = useCallback(\n (resolver: NameResolver, input: string, scope?: string) =>\n resolver.lookupAddress(input, scope),\n [],\n );\n\n return useNameLookup<NameResult>({\n input: address,\n skip: options?.skip,\n resolverConfig: options?.resolverConfig,\n scope: options?.chainId,\n query,\n });\n}\n","/**\n * The shared half of the two name-resolution hooks.\n *\n * `useResolveName` (name to address) and `useLookupAddress` (address to name)\n * were near-identical copies, and carried identical defects:\n *\n * - No request-generation guard. Typing quickly meant two lookups in flight,\n * and if the earlier one resolved last it overwrote the later result — the\n * UI then showed one address's name next to a different address, which is\n * exactly the pairing a user reads before deciding where to send funds.\n * - The resolver was captured into a ref on first render and never rebuilt, so\n * a caller changing `resolverConfig` kept querying through the old one.\n * - The de-duplication guard closed over `data` without listing it as a\n * dependency, so it tested a value from an earlier render.\n *\n * Keeping the logic here means fixing it once. The two hooks differ only in\n * which resolver method they call and what they call the input.\n */\n\nimport type { NameResolver, NameResolverConfig } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getResolver } from \"@naculus/connect-appkit-core\";\n\nexport interface NameLookupState<T> {\n data: T | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport interface NameLookupOptions<T> {\n /** The name or address being looked up. */\n input: string;\n /** Skip entirely, e.g. while the input is known to be incomplete. */\n skip?: boolean;\n /** Overrides the shared resolver when supplied. */\n resolverConfig?: NameResolverConfig;\n /** Extra value that changes the query's meaning, such as a chain ID. */\n scope?: string;\n /**\n * Performs the lookup. Must be stable or wrapped by the caller.\n *\n * Resolves null for \"no such name\", which is an answer rather than a\n * failure and is reported as `data: null` with no error.\n */\n query: (\n resolver: NameResolver,\n input: string,\n scope?: string,\n ) => Promise<T | null>;\n}\n\nexport function useNameLookup<T>({\n input,\n skip = false,\n resolverConfig,\n scope,\n query,\n}: NameLookupOptions<T>): NameLookupState<T> {\n const [data, setData] = useState<T | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const generationRef = useRef(0);\n const mountedRef = useRef(true);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n // Rebuilt when the config changes rather than pinned to the first render.\n // getResolver returns a dedicated instance for a config and the shared one\n // otherwise, so this stays a single instance for the common case.\n const resolver = useMemo(() => getResolver(resolverConfig), [resolverConfig]);\n\n const run = useCallback(() => {\n const trimmed = input.trim();\n if (!trimmed || skip) {\n // Bump the generation so a lookup already in flight cannot land after\n // the caller has cleared the field.\n generationRef.current += 1;\n setData(null);\n setIsLoading(false);\n setError(null);\n return;\n }\n\n const generation = ++generationRef.current;\n setIsLoading(true);\n setError(null);\n\n query(resolver, trimmed, scope)\n .then((result) => {\n if (!mountedRef.current || generation !== generationRef.current) return;\n setData(result);\n setIsLoading(false);\n })\n .catch((err: unknown) => {\n if (!mountedRef.current || generation !== generationRef.current) return;\n setError(err instanceof Error ? err : new Error(String(err)));\n setData(null);\n setIsLoading(false);\n });\n }, [input, skip, scope, resolver, query]);\n\n useEffect(() => {\n run();\n }, [run]);\n\n return { data, isLoading, error, refetch: run };\n}\n","/**\n * useNotification — React hook for push notification state.\n *\n * Provides notifications, settings, and control methods for the\n * in-app notification center.\n *\n * @example\n * ```tsx\n * import { useNotification } from \"@naculus/connect-appkit-react\";\n *\n * function NotificationCenter() {\n * const { notifications, unreadCount, clear, markAsRead } = useNotification();\n * return (\n * <div>\n * <span>Unread: {unreadCount}</span>\n * <ul>\n * {notifications.map(n => (\n * <li key={n.id} onClick={() => markAsRead(n.id)}>\n * {n.title} — {n.body}\n * </li>\n * ))}\n * </ul>\n * <button onClick={clear}>Clear all</button>\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from \"react\";\nimport {\n addInAppNotification,\n channelsUpdate,\n clearOneInAppNotification,\n createNotificationSettingsStorage,\n DEFAULT_NOTIFICATION_SETTINGS,\n loadNotificationSettings,\n mutedChainSettings,\n saveNotificationSettings,\n replayNotificationSettings,\n updateNotificationSettings,\n type NotificationSettingsStorage,\n type NotificationSettingsUpdate,\n} from \"@naculus/connect-appkit-core\";\nimport {\n InAppChannel,\n type NotificationItem,\n type NotificationSettings,\n} from \"@naculus/connect-core\";\n\n// ─── Hook ──────────────────────────────────────────────────────────────\n\n/**\n * Hook for consuming in-app notifications in React components.\n *\n * Uses InAppChannel internally to manage the notification queue.\n * All persistent state is stored via localStorage.\n */\nexport function useNotification(options?: {\n /** External InAppChannel instance (for sharing between hooks). If omitted, creates one. */\n channel?: InAppChannel;\n /** Custom storage for settings (defaults to localStorage) */\n storage?: NotificationSettingsStorage;\n}) {\n // ── Channel ──────────────────────────────────────────────────────\n\n const channelRef = useRef<InAppChannel | null>(null);\n\n if (!channelRef.current) {\n channelRef.current = options?.channel ?? new InAppChannel();\n }\n\n const channel = channelRef.current;\n\n // ── State ────────────────────────────────────────────────────────\n\n const [notifications, setNotifications] = useState<NotificationItem[]>(() =>\n channel.getHistory(),\n );\n\n const [settings, setSettingsState] = useState<NotificationSettings>(() => {\n // Try to load from storage, fall back to default\n return DEFAULT_NOTIFICATION_SETTINGS;\n });\n\n // ── Load persisted settings on mount ──────────────────────────────\n\n // Changes made before the persisted settings load are queued and replayed\n // on top of them (replayNotificationSettings); null once loaded.\n const pendingRef = useRef<NotificationSettingsUpdate[] | null>([]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: loads persisted settings once, on mount; later storage changes are written, not re-read\n useEffect(() => {\n const storage = options?.storage ?? createNotificationSettingsStorage();\n const settle = (saved: NotificationSettings | null) => {\n const pending = pendingRef.current ?? [];\n pendingRef.current = null;\n if (pending.length === 0) {\n if (saved) setSettingsState(saved);\n return;\n }\n setSettingsState(() => {\n const next = replayNotificationSettings(saved, pending);\n saveNotificationSettings(storage, next);\n return next;\n });\n };\n loadNotificationSettings(storage).then(settle, () => settle(null));\n }, []);\n\n // ── Sync notifications with channel ──────────────────────────────\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: channel comes from a ref and never changes; wired once on mount\n useEffect(() => {\n // Set up callback to reactively update state when new notifications arrive\n channel.onNotification = (item) => {\n setNotifications((prev) => [...prev, item]);\n };\n\n // Restore persisted history\n channel.restore().then(() => {\n setNotifications(channel.getHistory());\n });\n\n return () => {\n // Cleanup: deregister callback on unmount\n channel.onNotification = undefined;\n };\n }, []);\n\n // ── Computed ─────────────────────────────────────────────────────\n\n const unreadCount = useMemo(() => {\n return notifications.filter((n) => !n.read).length;\n }, [notifications]);\n\n // ── Actions ──────────────────────────────────────────────────────\n\n const clear = useCallback(() => {\n channel.clear();\n setNotifications([]);\n }, [channel]);\n\n const clearOne = useCallback(\n (id: string) => {\n clearOneInAppNotification(channel, id).then(() => {\n // Force re-sync\n setNotifications(channel.getHistory());\n });\n },\n [channel],\n );\n\n const markAsRead = useCallback(\n (id: string) => {\n channel.markAsRead(id);\n setNotifications((prev) =>\n prev.map((n) => (n.id === id ? { ...n, read: true } : n)),\n );\n },\n [channel],\n );\n\n const markAllAsRead = useCallback(() => {\n channel.markAllAsRead();\n setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));\n }, [channel]);\n\n // ── Add single notification ──────────────────────────────────────\n\n const addNotification = useCallback(\n (item: Omit<NotificationItem, \"id\" | \"timestamp\">) => {\n addInAppNotification(channel, item);\n // The onNotification callback will update state\n },\n [channel],\n );\n\n // ── Settings ──────────────────────────────────────────────────────\n\n // Every change is computed from the latest state inside the updater, never\n // from the `settings` captured at render: two calls in one tick (mute A,\n // mute B) would otherwise both start from the same list, and the second\n // would drop the first.\n const applySettings = useCallback(\n (compute: NotificationSettingsUpdate) => {\n pendingRef.current?.push(compute);\n setSettingsState((prev) => {\n const next = updateNotificationSettings(prev, compute(prev));\n const storage = options?.storage ?? createNotificationSettingsStorage();\n saveNotificationSettings(storage, next);\n return next;\n });\n },\n [options?.storage],\n );\n\n const updateSettings = useCallback(\n (update: Partial<NotificationSettings>) => applySettings(() => update),\n [applySettings],\n );\n\n const setChannels = useCallback(\n (channels: string[]) => {\n updateSettings(channelsUpdate(channels));\n },\n [updateSettings],\n );\n\n const muteChain = useCallback(\n (chainId: string) => {\n applySettings((prev) => mutedChainSettings(prev, chainId, true));\n },\n [applySettings],\n );\n\n const unmuteChain = useCallback(\n (chainId: string) => {\n applySettings((prev) => mutedChainSettings(prev, chainId, false));\n },\n [applySettings],\n );\n\n // ── Return ───────────────────────────────────────────────────────\n\n return {\n /** All in-app notifications (newest last) */\n notifications,\n /** Number of unread notifications */\n unreadCount,\n /** Add a single notification manually */\n addNotification,\n /** Clear all in-app notifications */\n clear,\n /** Clear a single notification */\n clearOne,\n /** Mark a notification as read */\n markAsRead,\n /** Mark all as read */\n markAllAsRead,\n /** Current notification settings */\n settings,\n /** Update notification settings */\n updateSettings,\n /** Set active channels by id */\n setChannels,\n /** Mute a chain */\n muteChain,\n /** Unmute a chain */\n unmuteChain,\n };\n}\n","import { useCallback, useSyncExternalStore } from \"react\";\nimport type {\n PassphraseGate,\n PassphraseRequest,\n} from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\nexport interface UsePassphraseGateReturn {\n /**\n * The open request, or null when nothing is being asked.\n *\n * Also null when no gate exists — an app that supplies its own\n * `encryptionPassphrase`, or one with encryption off entirely. A dialog can\n * render against this unconditionally.\n */\n request: PassphraseRequest | null;\n /** Answer the open request. */\n submit: (passphrase: string) => void;\n /** Abandon it, failing the load or save that asked. */\n cancel: () => void;\n /** Drop the held passphrase, so the next operation asks again. */\n forget: (reason?: string) => void;\n /** Whether a passphrase is held for this session. */\n isUnlocked: boolean;\n gate: PassphraseGate | null;\n}\n\nconst NO_REQUEST = () => null;\nconst NEVER = () => () => {};\n\n/**\n * Drives the passphrase prompt for the embedded wallet's encrypted storage.\n *\n * The gate belongs to the client, so a dialog mounted anywhere under the\n * provider answers whichever load or save is currently blocked on it.\n */\nexport function usePassphraseGate(): UsePassphraseGateReturn {\n const { client } = useWeb3();\n const gate = resolveClient(client)?.passphraseGate ?? null;\n\n const request = useSyncExternalStore(\n gate?.subscribe ?? NEVER,\n gate?.getSnapshot ?? NO_REQUEST,\n // Server renders have no gate state. Returning null rather than reading\n // the live one keeps hydration from flashing a dialog the server never\n // rendered.\n NO_REQUEST,\n );\n\n const submit = useCallback(\n (passphrase: string) => gate?.submit(passphrase),\n [gate],\n );\n const cancel = useCallback(() => gate?.cancel(), [gate]);\n const forget = useCallback((reason?: string) => gate?.forget(reason), [gate]);\n\n return {\n request,\n submit,\n cancel,\n forget,\n isUnlocked: gate?.isUnlocked ?? false,\n gate,\n };\n}\n","import type {\n AddressResult,\n NameResolver,\n NameResolverConfig,\n} from \"@naculus/connect-core\";\nimport { useCallback } from \"react\";\nimport { useNameLookup } from \"../core/name-lookup\";\n\n/**\n * Result of a name resolution query.\n */\nexport interface UseResolveNameResult {\n /** Resolved address, or null if not found / not started. */\n data: AddressResult | null;\n /** Whether the resolution is in progress. */\n isLoading: boolean;\n /** Error that occurred during resolution, if any. */\n error: Error | null;\n /** Manually trigger re-resolution of the current name. */\n refetch: () => void;\n}\n\n/**\n * Options for the useResolveName hook.\n */\nexport interface UseResolveNameOptions {\n /** Whether to skip resolution (e.g. if input is invalid). Default: false. */\n skip?: boolean;\n /** Custom resolver configuration (overrides default RPC URLs). */\n resolverConfig?: NameResolverConfig;\n}\n\n/**\n * React hook to resolve a human-readable name to a blockchain address.\n *\n * Supports ENS (.eth) and SNS (.sol) names.\n * Automatically detects the name service from the suffix.\n *\n * @example\n * ```tsx\n * function AddressInput() {\n * const { data, isLoading, error } = useResolveName('vitalik.eth');\n * return <div>{data?.address ?? 'Enter a name'}</div>;\n * }\n * ```\n */\nexport function useResolveName(\n name: string,\n options?: UseResolveNameOptions,\n): UseResolveNameResult {\n const query = useCallback(\n (resolver: NameResolver, input: string) => resolver.resolveName(input),\n [],\n );\n\n return useNameLookup<AddressResult>({\n input: name,\n skip: options?.skip,\n resolverConfig: options?.resolverConfig,\n query,\n });\n}\n","/**\n * useSendUserOperation\n *\n * React hook for sending ERC-4337 UserOperations.\n * Uses the core SmartAccountManager so address derivation, deployment,\n * nonce reads, gas estimation, signing, and bundler serialization stay on one\n * implementation path.\n */\n\nimport {\n assertHexSignature,\n bareEvmAddress,\n buildSmartAccountConfig,\n resolveUserOpChain,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n Address,\n Call,\n Hex,\n SendUserOpOptions,\n UniversalWalletSession,\n UserOperationReceipt,\n UserOperationResponse,\n} from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\n\nasync function signHashWithSession(\n session: NonNullable<ReturnType<typeof useWeb3>[\"session\"]>,\n client: ReturnType<typeof useWeb3>[\"client\"],\n hash: Hex,\n address: Address,\n chainId: string,\n): Promise<Hex> {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n\n const params = [hash, address];\n if (session.walletType === \"eip6963\" || session.id?.startsWith(\"eip6963-\")) {\n // `signMessage` accepts text and encodes it before personal_sign. A\n // UserOperation hash must instead reach the wallet as the original 32\n // bytes, so use the connector's raw EIP-1193 request here.\n const { eip6963Connector } = await import(\n \"@naculus/connector-evm-injected\"\n );\n const wallet = eip6963Connector\n .getDiscoveredWallets()\n .find((candidate) => candidate.id === session.walletId);\n const result = wallet\n ? await wallet.provider.request({ method: \"personal_sign\", params })\n : await eip6963Connector.request({\n method: \"personal_sign\",\n params,\n });\n return assertHexSignature(result);\n }\n\n if (session.walletType === \"walletconnect\") {\n return assertHexSignature(\n await activeClient.connector.request({\n method: \"personal_sign\",\n params,\n }),\n );\n }\n\n if (session.walletType === \"embedded\") {\n const embedded = activeClient.embeddedConnector as {\n signHash?: (\n session: UniversalWalletSession,\n hash: Hex,\n ) => Promise<`0x${string}`>;\n } | null;\n if (!embedded?.signHash) {\n throw new WalletError(\n \"method_unsupported\",\n \"This embedded wallet build cannot sign a raw digest. Upgrade @naculus/connector-embedded or pass an explicit signer.\",\n );\n }\n return assertHexSignature(await embedded.signHash(session, hash));\n }\n\n if (session.walletType === \"passkeys\") {\n // Not a missing primitive: a passkey signs with P-256 (COSE alg -7) and a\n // SimpleAccount recovers a secp256k1 key, so no wiring here can make the\n // two agree. It needs an account implementation that verifies P-256 on\n // chain — a WebAuthn validator, or RIP-7212 where the precompile exists.\n // Saying so is the difference between a fixable gap and an impossible one.\n throw new WalletError(\n \"method_unsupported\",\n \"Passkeys sign with P-256, which a SimpleAccount cannot verify. Use a smart account with a WebAuthn validator, or pass an explicit signer.\",\n );\n }\n\n throw new WalletError(\n \"method_unsupported\",\n `Raw UserOperation signing is not available for ${session.walletType} on ${chainId}. Pass a signer that signs the raw 32-byte hash.`,\n );\n}\n\nexport interface UseSendUserOperationOptions {\n /** RPC URL for the target chain */\n rpcUrl?: string;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Chain ID (CAIP-2 format) */\n chainId?: string;\n /** EntryPoint contract address */\n entryPoint?: Address;\n /** Smart account implementation type (default: \"simple\") */\n accountType?: \"simple\" | \"light\" | \"kernel\" | \"safe\";\n /** Optional salt for deterministic smart account address */\n salt?: bigint;\n /** Override the connected EVM account as the smart account owner */\n owner?: Address;\n /**\n * Optional signer for the UserOperation hash. A custom signer is assumed to\n * apply the signature scheme selected by `signerMode`.\n */\n signer?: (hash: Hex) => Promise<Hex> | Hex;\n /** Signature hash format expected by the account implementation */\n signerMode?: \"raw\" | \"eip191\";\n}\n\nexport interface UseSendUserOperationReturn {\n /** Send a UserOperation with the given calls */\n sendUserOp: (\n calls: Call[],\n options?: SendUserOpOptions,\n ) => Promise<UserOperationResponse | null>;\n /** The userOpHash from the last send */\n userOpHash: Hex | null;\n /** The receipt from the last UserOperation (null while pending) */\n receipt: UserOperationReceipt | null;\n /** Whether a UserOperation is currently being sent */\n isPending: boolean;\n /** Loading state for gas estimation and submission */\n isEstimating: boolean;\n /** Error state */\n error: Error | null;\n /** Reset state */\n reset: () => void;\n}\n\n/**\n * Hook for sending ERC-4337 UserOperations to a bundler.\n *\n * The connected EVM account is used as the smart-account owner. The hook uses\n * the active wallet's raw `personal_sign` request for WalletConnect and\n * injected wallets; embedded/passkey users must provide a raw-hash signer until\n * those connectors expose one.\n */\nexport function useSendUserOperation(\n options?: UseSendUserOperationOptions,\n): UseSendUserOperationReturn {\n const { evmAccount } = useAccount();\n const { session, chainId: connectedChainId, client } = useWeb3();\n const [userOpHash, setUserOpHash] = useState<Hex | null>(null);\n const [receipt, setReceipt] = useState<UserOperationReceipt | null>(null);\n const [isPending, setIsPending] = useState(false);\n const [isEstimating, setIsEstimating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const requestIdRef = useRef(0);\n const inFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n // Receipt polling can outlive the component. Invalidate its callbacks so\n // an unmounted hook cannot publish stale state.\n requestIdRef.current += 1;\n inFlightRef.current = false;\n };\n }, []);\n\n // A context change invalidates an in-flight operation. The manager captures\n // the old owner, chain, and signer in its closure, so its result must not be\n // published after React has rendered a new wallet context.\n // biome-ignore lint/correctness/useExhaustiveDependencies: The effect intentionally resets operation state when the wallet context changes.\n useEffect(() => {\n requestIdRef.current += 1;\n inFlightRef.current = false;\n setUserOpHash(null);\n setReceipt(null);\n setIsPending(false);\n setIsEstimating(false);\n setError(null);\n }, [\n client,\n connectedChainId,\n evmAccount,\n options?.accountType,\n options?.bundlerUrl,\n options?.chainId,\n options?.entryPoint,\n options?.owner,\n options?.rpcUrl,\n options?.salt,\n options?.signerMode,\n session,\n ]);\n\n const sendUserOp = useCallback(\n async (\n calls: Call[],\n opts?: SendUserOpOptions,\n ): Promise<UserOperationResponse | null> => {\n const fail = (nextError: Error): null => {\n setError(nextError);\n return null;\n };\n\n if (!options?.rpcUrl) return fail(new Error(\"RPC URL not configured\"));\n if (!options.bundlerUrl)\n return fail(new Error(\"Bundler URL not configured\"));\n if (!calls.length)\n return fail(new Error(\"At least one call is required\"));\n if (inFlightRef.current) {\n return fail(new Error(\"A UserOperation is already in progress\"));\n }\n\n const owner = bareEvmAddress(options.owner ?? evmAccount);\n if (!owner)\n return fail(\n new WalletError(\"wallet_unavailable\", \"No EVM account found\"),\n );\n\n // No mainnet default. The mismatch check below is skipped when there is\n // no connected chain, so defaulting there would build and sign a\n // UserOperation for chain 1 with nothing to contradict it — and the\n // chain ID is part of the hash the user approves.\n let targetChainId: string;\n try {\n targetChainId = resolveUserOpChain(options.chainId, connectedChainId);\n } catch (chainError) {\n return fail(chainError as Error);\n }\n if (!options.signer && !session) {\n return fail(new WalletError(\"wallet_unavailable\", \"No active session\"));\n }\n\n const requestId = ++requestIdRef.current;\n inFlightRef.current = true;\n setIsPending(true);\n setIsEstimating(true);\n setError(null);\n setUserOpHash(null);\n setReceipt(null);\n\n try {\n const { SmartAccountManager } = await import(\"@naculus/connect-core\");\n const signer =\n options.signer ??\n ((hash: Hex) =>\n signHashWithSession(session!, client, hash, owner, targetChainId));\n const manager = new SmartAccountManager({\n rpcUrl: options.rpcUrl,\n bundlerClient: { url: options.bundlerUrl },\n chainId: targetChainId,\n signer,\n // The wallet's personal_sign request applies EIP-191 itself. A\n // caller-supplied signer retains the core's historical default.\n signerMode: options.signer ? (options.signerMode ?? \"eip191\") : \"raw\",\n });\n const config = buildSmartAccountConfig(owner, targetChainId, options);\n\n const response = await manager.sendUserOperation(config, calls, opts);\n if (requestId !== requestIdRef.current) return null;\n\n setIsEstimating(false);\n setUserOpHash(response.userOpHash);\n\n // The core manager owns the receipt polling policy and validates the\n // receipt shape. A timeout should leave the submitted hash available;\n // callers can decide how to surface that pending state.\n void manager\n .getUserOperationReceipt(response.userOpHash)\n .then((nextReceipt) => {\n if (requestId === requestIdRef.current) setReceipt(nextReceipt);\n })\n .catch(() => undefined);\n\n return response;\n } catch (err) {\n if (requestId !== requestIdRef.current) return null;\n const nextError =\n err instanceof Error\n ? err\n : new Error(\"Failed to send UserOperation\");\n setError(nextError);\n return null;\n } finally {\n // The operation that took the single-flight slot has settled, whether\n // or not its result is still wanted.\n inFlightRef.current = false;\n if (requestId === requestIdRef.current) {\n setIsPending(false);\n setIsEstimating(false);\n }\n }\n },\n [client, connectedChainId, evmAccount, options, session],\n );\n\n // reset() does not unlock single-flight: an operation already handed to\n // the manager may still sign and broadcast, and a second sendUserOp in the\n // meantime would be a second on-chain side effect. The flag clears when\n // that operation settles.\n const reset = useCallback(() => {\n requestIdRef.current += 1;\n setUserOpHash(null);\n setReceipt(null);\n setIsPending(false);\n setIsEstimating(false);\n setError(null);\n }, []);\n\n return {\n sendUserOp,\n userOpHash,\n receipt,\n isPending,\n isEstimating,\n error,\n reset,\n };\n}\n","/**\n * useSession Hook\n *\n * Provides access to the complete session state from SessionManager,\n * including all active chain sessions, the active chain ID, and\n * connection status.\n *\n * @see SRS-009 §7.2\n */\n\nimport { useSyncExternalStore, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { ChainSession, ActiveSessionBundle } from \"@naculus/connect-core\";\n\nexport interface UseSessionReturn {\n /** The raw wallet session (from the active bundle) */\n session: ActiveSessionBundle[\"walletSession\"] | null;\n /** All chain sessions within the active bundle */\n chainSessions: ChainSession[];\n /** The currently active chain ID */\n activeChainId: string | null;\n /** Whether a wallet is connected */\n isConnected: boolean;\n /** The connector/wallet type (e.g., \"eip6963\", \"walletconnect\") */\n connectorId: string | null;\n}\n\nfunction subscribeToSessionManager(\n sm: import(\"@naculus/connect-core\").SessionManager | null,\n callback: () => void,\n): () => void {\n if (!sm) return () => {};\n\n const handler = () => callback();\n sm.on(\"sessionConnected\", handler);\n sm.on(\"sessionDisconnected\", handler);\n sm.on(\"chainChanged\", handler);\n // CAIP-25 lifecycle (connect-core >= 0.2.6): the wallet narrowed or\n // ended the session without the app asking.\n sm.on(\"sessionScopeChanged\", handler);\n sm.on(\"sessionRevoked\", handler);\n\n return () => {\n sm.off(\"sessionConnected\", handler);\n sm.off(\"sessionDisconnected\", handler);\n sm.off(\"chainChanged\", handler);\n sm.off(\"sessionScopeChanged\", handler);\n sm.off(\"sessionRevoked\", handler);\n };\n}\n\nconst EMPTY_SESSION: UseSessionReturn = Object.freeze({\n session: null,\n chainSessions: [],\n activeChainId: null,\n isConnected: false,\n connectorId: null,\n}) as UseSessionReturn;\n\n/**\n * Last snapshot handed to React, per SessionManager.\n *\n * useSyncExternalStore compares snapshots with Object.is and re-renders when\n * they differ, so returning a fresh object literal on every call meant the\n * comparison never succeeded: React re-rendered, called getSnapshot again, got\n * another new object, and threw \"Maximum update depth exceeded\". Any component\n * calling useSession() crashed on first render, which is also why this file\n * had no coverage — it had never actually run.\n *\n * The bundle is mutated in place rather than replaced, so identity alone is\n * not a usable signal; the derived fields are compared instead and a new\n * object is produced only when one of them actually changed.\n */\nconst snapshotCache = new WeakMap<object, UseSessionReturn>();\n\nfunction sameChainSessions(a: ChainSession[], b: ChainSession[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\nfunction getSessionSnapshot(\n sm: import(\"@naculus/connect-core\").SessionManager | null,\n): UseSessionReturn {\n if (!sm) return EMPTY_SESSION;\n\n const bundle = sm.getActiveBundle();\n const previous = snapshotCache.get(sm as unknown as object);\n\n if (!bundle) {\n if (previous && previous.session === null) return previous;\n snapshotCache.set(sm as unknown as object, EMPTY_SESSION);\n return EMPTY_SESSION;\n }\n\n const chainSessions = Array.from(bundle.chainSessions.values());\n if (\n previous &&\n previous.session === bundle.walletSession &&\n previous.activeChainId === bundle.activeChainId &&\n sameChainSessions(previous.chainSessions, chainSessions)\n ) {\n return previous;\n }\n\n const next: UseSessionReturn = {\n session: bundle.walletSession,\n chainSessions,\n activeChainId: bundle.activeChainId,\n isConnected: true,\n connectorId: bundle.walletSession.walletType,\n };\n snapshotCache.set(sm as unknown as object, next);\n return next;\n}\n\nexport function useSession(\n sessionManager?: import(\"@naculus/connect-core\").SessionManager | null,\n): UseSessionReturn {\n const web3 = useWeb3();\n const sm = sessionManager ?? web3.sessionManager ?? null;\n\n const subscribe = useCallback(\n (callback: () => void) => subscribeToSessionManager(sm, callback),\n [sm],\n );\n\n const getSnapshot = useCallback(() => getSessionSnapshot(sm), [sm]);\n\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","/**\n * useSIWxLogin — Trigger a SIWx sign-in flow.\n *\n * A simplified hook for initiating wallet sign-in.\n * Returns a `signIn()` function and loading/error state.\n */\n\nimport {\n defaultSiwxDomain,\n defaultSiwxUri,\n} from \"@naculus/connect-appkit-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n createSiwxMessage,\n generateNonce,\n getBlockchainName,\n issueNonce,\n nowISO,\n type SiwxResult,\n} from \"@naculus/siwx\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { selectSiwxAccount } from \"./siwx-accounts\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSIWxLoginOptions {\n /** Originating domain (default: window.location.host) */\n domain?: string;\n /** Human-readable statement */\n statement?: string;\n /** RFC 3986 URI (default: window.location.origin) */\n uri?: string;\n /** CAIP-2 chain ID (default: current chain from Web3 context) */\n chainId?: string;\n /** Session lifetime in seconds (default: 86400 = 24h) */\n expirySeconds?: number;\n /** URIs of resources the identity wishes to access */\n resources?: string[];\n /** CAIP-74 request ID */\n requestId?: string;\n}\n\nexport interface UseSIWxLoginReturn {\n /** Trigger the SIWx sign-in flow */\n signIn: (options?: UseSIWxLoginOptions) => Promise<SiwxResult>;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Last sign-in error */\n error: Error | null;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Defaults ─────────────────────────────────────────────────────\n\nconst DEFAULT_EXPIRY_SECONDS = 86_400; // 24h\n\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSIWxLogin(): UseSIWxLoginReturn {\n const { session, chainId: currentChainId, client } = useWeb3();\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const signIn = useCallback(\n async (options?: UseSIWxLoginOptions): Promise<SiwxResult> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n // No mainnet default. This value becomes the `Chain ID:` field of the\n // CAIP-122 message the user signs, so an assumed chain is an assertion\n // the user never made — and on a wallet sitting on another chain, a\n // signature that binds to the wrong one.\n const chainId = options?.chainId ?? currentChainId;\n if (!chainId) {\n throw new WalletError(\n \"invalid_chain\",\n \"No chain to sign for. Connect a wallet or pass options.chainId.\",\n );\n }\n const account = selectSiwxAccount(session, chainId);\n if (!account) {\n throw new WalletError(\"wallet_unavailable\", \"No account found\");\n }\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const { address } = account;\n const location =\n typeof window === \"undefined\" ? undefined : window.location;\n const domain = options?.domain ?? defaultSiwxDomain(location);\n const uri = options?.uri ?? defaultSiwxUri(location);\n setIsSigningIn(true);\n setError(null);\n\n try {\n const nonce = generateNonce();\n await issueNonce(nonce);\n const issuedAt = nowISO();\n const expirySeconds = options?.expirySeconds ?? DEFAULT_EXPIRY_SECONDS;\n const expirationTime = new Date(\n Date.now() + expirySeconds * 1000,\n ).toISOString();\n\n // Build the CAIP-122 message string\n const message = createSiwxMessage({\n domain,\n address,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n expirationTime,\n statement: options?.statement,\n resources: options?.resources,\n requestId: options?.requestId,\n });\n\n const signature = (await activeClient.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined,\n })) as string;\n\n const siwxResult: SiwxResult = {\n message: {\n raw: message,\n domain,\n address,\n statement: options?.statement ?? null,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n blockchain: getBlockchainName(chainId),\n expirationTime,\n notBefore: null,\n resources: options?.resources ?? [],\n requestId: options?.requestId ?? null,\n },\n signature,\n };\n\n setIsSigningIn(false);\n return siwxResult;\n } catch (err) {\n const wrappedErr =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrappedErr);\n setIsSigningIn(false);\n throw wrappedErr;\n }\n },\n [session, currentChainId, client],\n );\n\n return { signIn, isSigningIn, error, clearError };\n}\n","/**\n * useSIWxSession — Unified SIWx session management hook.\n *\n * Combines the sign-in flow with session persistence, expiry tracking,\n * and automatic restoration. Replaces the older useSiwxAuthSession.\n *\n * Provides:\n * - signIn / signOut / refresh lifecycle\n * - Auto-restore from storage on mount\n * - isExpired / timeUntilExpiry query\n * - Loading/error state\n */\n\nimport { siwxResultToSession } from \"@naculus/connect-appkit-core\";\nimport { logger } from \"@naculus/connect-core\";\nimport type { SiwxSession } from \"@naculus/siwx\";\nimport {\n checkSessionExpired,\n createLocalStorageSiwxSessionStorage,\n} from \"@naculus/siwx\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { UseSIWxLoginOptions } from \"./useSIWxLogin\";\nimport { useSIWxLogin } from \"./useSIWxLogin\";\n\n// ── Constants ────────────────────────────────────────────────────\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSIWxSessionOptions {\n /** Storage key prefix (default: \"naculus_\") */\n storagePrefix?: string;\n /** Auto-restore session from storage on mount (default: true) */\n autoRestore?: boolean;\n /** Default chain ID when signing in (default: current chain from context) */\n defaultChainId?: string;\n /** Default session lifetime in seconds (default: 86400 = 24h) */\n defaultExpirySeconds?: number;\n}\n\nexport interface UseSIWxSessionReturn {\n /** The current SIWx session, or null */\n session: SiwxSession | null;\n /** Whether a valid session exists */\n isAuthenticated: boolean;\n /** Whether we're still checking persisted auth on mount */\n isRestoring: boolean;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Whether the current session has expired */\n isExpired: boolean;\n /** Milliseconds until session expires, or null */\n timeUntilExpiry: number | null;\n\n /** Sign in with optional overrides */\n signIn: (options?: UseSIWxLoginOptions) => Promise<SiwxSession>;\n /** Sign out: clears session from memory and storage */\n signOut: () => Promise<void>;\n /** Refresh the current session */\n refresh: () => Promise<SiwxSession>;\n\n /** Last error */\n error: Error | null;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\n/**\n * Random suffix for a session record ID.\n *\n * `Math.random` gave roughly 31 predictable bits. The signature, not this ID,\n * is what authenticates a SIWx session, so this was not an authentication\n * bypass — but an ID a consumer may key storage or a request on should not be\n * guessable, and the CSPRNG is already the convention everywhere else here.\n */\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSIWxSession(\n options?: UseSIWxSessionOptions,\n): UseSIWxSessionReturn {\n const {\n storagePrefix = \"naculus_\",\n autoRestore = true,\n defaultExpirySeconds = 86_400,\n } = options ?? {};\n\n const [session, setSession] = useState<SiwxSession | null>(null);\n const [isRestoring, setIsRestoring] = useState(autoRestore);\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const { chainId: currentChainId } = useWeb3();\n const login = useSIWxLogin();\n const storageRef = useRef(\n createLocalStorageSiwxSessionStorage(`${storagePrefix}siwx_session`),\n );\n\n const clearError = useCallback(() => setError(null), []);\n\n // ── Restore from storage on mount ──────────────────────────────\n\n useEffect(() => {\n if (!autoRestore) {\n setIsRestoring(false);\n return;\n }\n\n let cancelled = false;\n\n (async () => {\n try {\n const storage = storageRef.current;\n const saved = await storage.get();\n\n if (cancelled) return;\n\n if (saved) {\n logger.info(\n \"react/useSIWxSession\",\n \"Restored persisted SIWx session\",\n );\n setSession(saved);\n setError(null);\n } else {\n // No valid session in storage\n setSession(null);\n }\n } catch (err) {\n logger.warn(\n \"react/useSIWxSession\",\n \"Failed to restore SIWx session:\",\n err,\n );\n setSession(null);\n } finally {\n if (!cancelled) setIsRestoring(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [autoRestore]);\n\n // ── Expiry refresh timer ───────────────────────────────────────\n\n useEffect(() => {\n if (!session?.expiresAt) return;\n\n const timeUntilExpiry = new Date(session.expiresAt).getTime() - Date.now();\n if (timeUntilExpiry <= 0) {\n // Already expired — clear session\n setSession(null);\n return;\n }\n\n // Schedule clearing when expired\n const timer = setTimeout(() => {\n setSession((prev) => {\n if (prev && prev.id === session.id) {\n return null;\n }\n return prev;\n });\n }, timeUntilExpiry);\n\n return () => clearTimeout(timer);\n }, [session?.id, session?.expiresAt]);\n\n // ── Sign In ────────────────────────────────────────────────────\n\n const signIn = useCallback(\n async (signOptions?: UseSIWxLoginOptions): Promise<SiwxSession> => {\n setIsSigningIn(true);\n setError(null);\n\n try {\n // Merge default options with provided overrides\n const effectiveOptions: UseSIWxLoginOptions = {\n expirySeconds: defaultExpirySeconds,\n chainId: currentChainId ?? undefined,\n ...signOptions,\n };\n\n const result = await login.signIn(effectiveOptions);\n\n // Convert SiwxResult to SiwxSession\n const siwxSession = siwxResultToSession(result);\n\n // Persist to storage\n const storage = storageRef.current;\n await storage.set(siwxSession);\n\n setSession(siwxSession);\n setIsSigningIn(false);\n return siwxSession;\n } catch (err) {\n const wrapped =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n },\n [login, currentChainId, defaultExpirySeconds],\n );\n\n // ── Sign Out ───────────────────────────────────────────────────\n\n const signOut = useCallback(async () => {\n try {\n const storage = storageRef.current;\n await storage.remove();\n } catch (err) {\n logger.warn(\"react/useSIWxSession\", \"Failed to clear session:\", err);\n }\n setSession(null);\n setError(null);\n }, []);\n\n // ── Refresh ────────────────────────────────────────────────────\n\n const refresh = useCallback(async (): Promise<SiwxSession> => {\n if (!session) {\n throw new Error(\"No active session to refresh\");\n }\n\n setIsSigningIn(true);\n setError(null);\n\n try {\n // Re-sign with updated timestamps\n const result = await login.signIn({\n domain: session.domain,\n statement: session.message.statement ?? undefined,\n uri: session.message.uri,\n chainId: session.chainId,\n expirySeconds: defaultExpirySeconds,\n resources:\n session.message.resources.length > 0\n ? session.message.resources\n : undefined,\n requestId: session.message.requestId ?? undefined,\n });\n\n const refreshedSession: SiwxSession = {\n ...siwxResultToSession(result),\n id: session.id, // preserve the original session ID\n refreshedAt: new Date().toISOString(),\n };\n\n // Persist\n const storage = storageRef.current;\n await storage.set(refreshedSession);\n\n setSession(refreshedSession);\n setIsSigningIn(false);\n return refreshedSession;\n } catch (err) {\n const wrapped =\n err instanceof Error ? err : new Error(\"Session refresh failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n }, [session, login, defaultExpirySeconds]);\n\n // ── Computed state ─────────────────────────────────────────────\n\n const isAuthenticated = session !== null && !checkSessionExpired(session);\n const expired = checkSessionExpired(session);\n const timeUntilExpiry = session?.expiresAt\n ? Math.max(0, new Date(session.expiresAt).getTime() - Date.now())\n : null;\n\n return {\n session: isAuthenticated ? session : null,\n isAuthenticated,\n isRestoring,\n isSigningIn,\n isExpired: expired,\n timeUntilExpiry,\n\n signIn,\n signOut,\n refresh,\n\n error,\n clearError,\n };\n}\n","import {\n defaultSiwxDomain,\n defaultSiwxUri,\n} from \"@naculus/connect-appkit-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n createSiwxMessage,\n generateNonce,\n getBlockchainName,\n issueNonce,\n nowISO,\n type SiwxResult,\n} from \"@naculus/siwx\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { selectSiwxAccount } from \"./siwx-accounts\";\n\nexport interface UseSignInWithXOptions {\n domain?: string;\n statement?: string;\n uri?: string;\n chainId?: string;\n expirySeconds?: number;\n resources?: string[];\n requestId?: string;\n}\n\nexport interface UseSignInWithXReturn {\n signIn: (options?: UseSignInWithXOptions) => Promise<SiwxResult>;\n isSigningIn: boolean;\n result: SiwxResult | null;\n error: Error | null;\n clearError: () => void;\n}\n\nexport function useSignInWithX(): UseSignInWithXReturn {\n const { session, chainId: currentChainId, client } = useWeb3();\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [result, setResult] = useState<SiwxResult | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const signIn = useCallback(\n async (options?: UseSignInWithXOptions): Promise<SiwxResult> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n // No mainnet default. This value becomes the `Chain ID:` field of the\n // CAIP-122 message the user signs, so an assumed chain is an assertion\n // the user never made — and on a wallet sitting on another chain, a\n // signature that binds to the wrong one.\n const chainId = options?.chainId ?? currentChainId;\n if (!chainId) {\n throw new WalletError(\n \"invalid_chain\",\n \"No chain to sign for. Connect a wallet or pass options.chainId.\",\n );\n }\n const account = selectSiwxAccount(session, chainId);\n if (!account) {\n throw new WalletError(\"wallet_unavailable\", \"No account found\");\n }\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const { address } = account;\n const location =\n typeof window === \"undefined\" ? undefined : window.location;\n const domain = options?.domain ?? defaultSiwxDomain(location);\n const uri = options?.uri ?? defaultSiwxUri(location);\n setIsSigningIn(true);\n setError(null);\n\n try {\n const nonce = generateNonce();\n await issueNonce(nonce);\n const issuedAt = nowISO();\n\n const message = createSiwxMessage({\n domain,\n address,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n statement: options?.statement,\n expirationTime: options?.expirySeconds\n ? new Date(Date.now() + options.expirySeconds * 1000).toISOString()\n : undefined,\n resources: options?.resources,\n requestId: options?.requestId,\n });\n\n const signature = (await activeClient.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined,\n })) as string;\n\n const expirationTime = options?.expirySeconds\n ? new Date(Date.now() + options.expirySeconds * 1000).toISOString()\n : null;\n\n const siwxResult: SiwxResult = {\n message: {\n raw: message,\n domain,\n address,\n statement: options?.statement ?? null,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n blockchain: getBlockchainName(chainId),\n expirationTime,\n notBefore: null,\n resources: options?.resources ?? [],\n requestId: options?.requestId ?? null,\n },\n signature,\n };\n\n setResult(siwxResult);\n return siwxResult;\n } catch (err) {\n const wrappedErr =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrappedErr);\n throw wrappedErr;\n } finally {\n setIsSigningIn(false);\n }\n },\n [session, currentChainId, client],\n );\n\n return { signIn, isSigningIn, result, error, clearError };\n}\n","import { useSignInWithX } from \"./useSignInWithX\";\nimport type { UseSignInWithXOptions, UseSignInWithXReturn } from \"./useSignInWithX\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useCallback } from \"react\";\n\nexport interface UseSignInWithEthereumOptions extends UseSignInWithXOptions {}\n\nexport interface UseSignInWithEthereumReturn extends UseSignInWithXReturn {}\n\nfunction useEip155SessionGuard(): (chainId?: string) => void {\n const { session, chainId: activeChainId } = useWeb3();\n return useCallback((chainId?: string) => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n const requestedChainId = chainId ?? activeChainId;\n if (requestedChainId && !requestedChainId.startsWith(\"eip155:\")) {\n throw new WalletError(\n \"namespace_mismatch\",\n `Ethereum SIWx requires an eip155 chain, received ${requestedChainId}`,\n );\n }\n const evmNamespace = session.namespaces.eip155;\n if (!evmNamespace || evmNamespace.accounts.length === 0) {\n throw new WalletError(\n \"namespace_mismatch\",\n \"No EVM (eip155) accounts found in session\"\n );\n }\n }, [session, activeChainId]);\n}\n\nexport function useSignInWithEthereum(): UseSignInWithEthereumReturn {\n const guard = useEip155SessionGuard();\n const siwx = useSignInWithX();\n\n const signIn = useCallback(\n async (options?: UseSignInWithEthereumOptions) => {\n guard(options?.chainId);\n return siwx.signIn(options);\n },\n [guard, siwx.signIn]\n );\n\n return {\n signIn,\n isSigningIn: siwx.isSigningIn,\n result: siwx.result,\n error: siwx.error,\n clearError: siwx.clearError,\n };\n}\n","import { resolveSimulationEndpoint } from \"@naculus/connect-appkit-core\";\n\n/**\n * useSimulateTransfer — React hook for simulating ERC-20 token transfers.\n *\n * Wraps SimulationManager.simulateERC20Transfer in a React hook with\n * reactive state for loading, result, and error.\n *\n * @example\n * ```tsx\n * import { useSimulateTransfer } from \"@naculus/connect-appkit-react\";\n *\n * function SendForm({ token, to, amount }) {\n * const { result, simulate, loading } = useSimulateTransfer({\n * rpcUrl: \"https://eth.llamarpc.com\",\n * });\n *\n * return (\n * <div>\n * <button onClick={() => simulate(token, to, amount)} disabled={loading}>\n * Simulate Transfer\n * </button>\n * {result && <p>Result: {result.status}</p>}\n * </div>\n * );\n * }\n * ```\n */\n\nimport type { SimulationResult } from \"@naculus/wallet-engine\";\nimport { SimulationManager } from \"@naculus/wallet-engine\";\nimport { useCallback, useRef, useState } from \"react\";\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface UseSimulateTransferOptions {\n /** RPC URL for eth_call simulation */\n rpcUrl?: string;\n /** Default chain ID */\n chainId?: number;\n}\n\nexport interface UseSimulateTransferReturn {\n /** Current simulation result */\n result: SimulationResult | null;\n /** Whether a simulation is in progress */\n loading: boolean;\n /** Last error (null if no error) */\n error: Error | null;\n /**\n * Simulate an ERC-20 transfer.\n *\n * @param tokenAddress - ERC-20 token contract address\n * @param from - Sender address\n * @param to - Recipient address\n * @param amount - Human-readable amount (e.g. \"1.50\")\n * @param options - Optional chainId, rpcUrl, decimals override\n */\n simulate: (\n tokenAddress: `0x${string}`,\n from: `0x${string}`,\n to: `0x${string}`,\n amount: string,\n options?: {\n chainId?: number;\n rpcUrl?: string;\n decimals?: number;\n },\n ) => Promise<SimulationResult>;\n /** Reset result and error state */\n reset: () => void;\n}\n\n// ── Hook ───────────────────────────────────────────────────────────\n\n/**\n * Hook for simulating an ERC-20 token transfer.\n *\n * Creates a SimulationManager internally and provides a `simulate`\n * function that builds transfer calldata automatically.\n *\n * @param options - Configuration for the underlying SimulationManager\n */\nexport function useSimulateTransfer(\n options?: UseSimulateTransferOptions,\n): UseSimulateTransferReturn {\n const rpcUrl = options?.rpcUrl;\n const chainId = options?.chainId;\n\n // ── SimulationManager ref (lazy init) ──────────────────────────\n\n const managerRef = useRef<SimulationManager | null>(null);\n\n const getManager = useCallback((): SimulationManager => {\n if (!managerRef.current) {\n managerRef.current = new SimulationManager({\n enabled: true,\n rpcUrl,\n autoSimulate: false,\n });\n }\n return managerRef.current;\n }, [rpcUrl]);\n\n // ── State ──────────────────────────────────────────────────────\n\n const [result, setResult] = useState<SimulationResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // ── Simulate ───────────────────────────────────────────────────\n\n const simulate = useCallback(\n async (\n tokenAddress: `0x${string}`,\n from: `0x${string}`,\n to: `0x${string}`,\n amount: string,\n simOptions?: {\n chainId?: number;\n rpcUrl?: string;\n decimals?: number;\n },\n ): Promise<SimulationResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const manager = getManager();\n // No `?? 1`. Simulating an ERC-20 transfer on the wrong chain reads a\n // different contract at the same address, so the preview describes a\n // transfer that will not happen.\n const endpoint = resolveSimulationEndpoint(\n simOptions?.chainId,\n chainId,\n simOptions?.rpcUrl,\n rpcUrl,\n );\n // Forwarded rather than computed and dropped. Without it a caller's\n // per-call endpoint did nothing, and the simulation ran against\n // whichever URL happened to be baked into the manager on first use.\n const simResult = await manager.simulateERC20Transfer(\n tokenAddress,\n from,\n to,\n amount,\n endpoint.chainId,\n simOptions?.decimals,\n endpoint.rpcUrl,\n );\n\n setResult(simResult);\n return simResult;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n } finally {\n setLoading(false);\n }\n },\n [rpcUrl, chainId, getManager],\n );\n\n // ── Reset ──────────────────────────────────────────────────────\n\n const reset = useCallback(() => {\n setResult(null);\n setError(null);\n setLoading(false);\n }, []);\n\n // ── Return ─────────────────────────────────────────────────────\n\n return { result, loading, error, simulate, reset };\n}\n","import {\n isSiwxExpired,\n isSiwxNotBeforeValid,\n} from \"@naculus/connect-appkit-core\";\nimport { LocalStorageAdapter, logger } from \"@naculus/connect-core\";\nimport type { SiwxResult } from \"@naculus/siwx\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseSignInWithXOptions } from \"./useSignInWithX\";\nimport { useSignInWithX } from \"./useSignInWithX\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSiwxAuthSessionOptions {\n /** Storage key prefix (default: \"naculus_\") */\n storagePrefix?: string;\n /** Auto-restore auth from storage on mount (default: true) */\n autoRestore?: boolean;\n}\n\nexport interface UseSiwxAuthSessionReturn {\n /** Whether a valid SIWx auth session exists */\n isSignedIn: boolean;\n /** Whether we're still checking persisted auth on mount */\n isRestoring: boolean;\n /** The persisted SIWx result, or null if not signed in */\n siwxResult: SiwxResult | null;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Last sign-in error */\n error: Error | null;\n /** Sign in with optional overrides. Persists result to storage on success. */\n signIn: (options?: UseSignInWithXOptions) => Promise<SiwxResult>;\n /** Sign out: clears persisted auth and resets state */\n signOut: () => void;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Constants ────────────────────────────────────────────────────\n\nconst SIWX_AUTH_KEY = \"siwx_auth\";\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction getStorage(prefix: string): LocalStorageAdapter {\n return new LocalStorageAdapter(prefix);\n}\n\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSiwxAuthSession(\n options?: UseSiwxAuthSessionOptions,\n): UseSiwxAuthSessionReturn {\n const { storagePrefix = \"naculus_\", autoRestore = true } = options ?? {};\n\n const [siwxResult, setSiwxResult] = useState<SiwxResult | null>(null);\n const [isRestoring, setIsRestoring] = useState(autoRestore);\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Use the generic SIWx hook for the underlying signing flow.\n const signInWithX = useSignInWithX();\n const storageRef = useRef(getStorage(storagePrefix));\n\n const clearError = useCallback(() => setError(null), []);\n\n // ── Restore persisted auth on mount ────────────────────────────\n\n useEffect(() => {\n if (!autoRestore) {\n setIsRestoring(false);\n return;\n }\n\n let cancelled = false;\n\n (async () => {\n try {\n const storage = storageRef.current;\n const saved = await storage.get<SiwxResult>(SIWX_AUTH_KEY);\n\n if (cancelled) return;\n\n if (\n saved &&\n !isSiwxExpired(saved, new Date()) &&\n isSiwxNotBeforeValid(saved, new Date())\n ) {\n logger.info(\n \"react/useSiwxAuthSession\",\n \"Restored persisted SIWx auth session\",\n );\n setSiwxResult(saved);\n setError(null);\n } else if (saved) {\n // Expired or not-yet-valid — clean up stale entry\n logger.info(\n \"react/useSiwxAuthSession\",\n \"Persisted SIWx auth expired, clearing\",\n );\n await storage.remove(SIWX_AUTH_KEY);\n }\n } catch (err) {\n logger.warn(\n \"react/useSiwxAuthSession\",\n \"Failed to restore SIWx auth:\",\n err,\n );\n } finally {\n if (!cancelled) setIsRestoring(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [autoRestore]);\n\n // ── Sign In ────────────────────────────────────────────────────\n\n const signIn = useCallback(\n async (signOptions?: UseSignInWithXOptions): Promise<SiwxResult> => {\n setIsSigningIn(true);\n setError(null);\n\n try {\n const result = await signInWithX.signIn(signOptions);\n\n // Persist to storage\n const storage = storageRef.current;\n await storage.set(SIWX_AUTH_KEY, result);\n\n setSiwxResult(result);\n setIsSigningIn(false);\n return result;\n } catch (err) {\n const wrapped =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n },\n [signInWithX],\n );\n\n // ── Sign Out ───────────────────────────────────────────────────\n\n const signOut = useCallback(async () => {\n try {\n const storage = storageRef.current;\n await storage.remove(SIWX_AUTH_KEY);\n } catch (err) {\n logger.warn(\n \"react/useSiwxAuthSession\",\n \"Failed to clear SIWx auth:\",\n err,\n );\n }\n setSiwxResult(null);\n setError(null);\n }, []);\n\n // ── Result ─────────────────────────────────────────────────────\n\n return {\n isSignedIn: siwxResult !== null,\n isRestoring,\n siwxResult,\n isSigningIn,\n error,\n signIn,\n signOut,\n clearError,\n };\n}\n","/**\n * useSmartAccount\n *\n * React hook for ERC-4337 Smart Account lifecycle management.\n * Provides create, deploy, and address lookup for smart contract wallets.\n *\n * @example\n * ```tsx\n * const { address, isDeployed, createWallet, deployWallet, isLoading } = useSmartAccount({\n * rpcUrl: \"https://eth.llamarpc.com\",\n * bundlerUrl: \"https://api.pimlico.io/v2/1/rpc?apikey=...\",\n * });\n * ```\n */\n\nimport {\n bareEvmAddress,\n buildSmartAccountConfig,\n resolveEvmChainId,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n Address,\n SmartAccountConfig,\n SmartAccountInfo,\n} from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\n\nfunction accountError(message: string): WalletError {\n return new WalletError(\"wallet_unavailable\", message);\n}\n\nexport interface UseSmartAccountOptions {\n /** RPC URL for the target chain */\n rpcUrl?: string;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Chain ID (CAIP-2 format) */\n chainId?: string;\n /** ERC-4337 EntryPoint address for the selected supported chain */\n entryPoint?: Address;\n /** Account type (default: \"simple\") */\n accountType?: \"simple\" | \"light\" | \"kernel\" | \"safe\";\n /** Optional salt for deterministic address */\n salt?: bigint;\n}\n\nexport interface UseSmartAccountReturn {\n /** Smart account address (null if not created) */\n address: Address | null;\n /** Whether the account is deployed on-chain */\n isDeployed: boolean;\n /** Smart account info object */\n accountInfo: SmartAccountInfo | null;\n /** Loading state */\n isLoading: boolean;\n /** Error state */\n error: Error | null;\n /** Create a new smart account (compute address) */\n createWallet: () => Promise<SmartAccountInfo | null>;\n /** Deploy the smart account to chain */\n deployWallet: () => Promise<Address | null>;\n /** Get the counterfactual address without creating */\n getAddress: () => Promise<Address | null>;\n}\n\n/**\n * Hook for managing a ERC-4337 Smart Contract Wallet lifecycle.\n *\n * @param options - Smart account configuration options\n * @returns Smart account state and actions\n */\nexport function useSmartAccount(\n options?: UseSmartAccountOptions,\n): UseSmartAccountReturn {\n const { evmAccount } = useAccount();\n const { session, chainId: connectedChainId, client } = useWeb3();\n const [address, setAddress] = useState<Address | null>(null);\n const [isDeployed, setIsDeployed] = useState(false);\n const [accountInfo, setAccountInfo] = useState<SmartAccountInfo | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const managerRef = useRef<\n import(\"@naculus/connect-core\").SmartAccountManager | null\n >(null);\n const generationRef = useRef(0);\n const inFlightRef = useRef(false);\n\n // Initialize SmartAccountManager on config change (with cleanup to prevent race conditions)\n useEffect(() => {\n managerRef.current = null;\n if (!options?.rpcUrl) {\n return;\n }\n\n let cancelled = false;\n\n import(\"@naculus/connect-core\")\n .then(({ SmartAccountManager }) => {\n if (cancelled) return; // prevent stale state update\n // No mainnet default: a manager built for the wrong chain reads the\n // wrong EntryPoint and derives an address the user never sees.\n const chainId = resolveEvmChainId(options.chainId, connectedChainId);\n if (!chainId) return;\n managerRef.current = new SmartAccountManager({\n rpcUrl: options.rpcUrl!,\n chainId,\n bundlerClient: {\n url: options.bundlerUrl ?? \"\",\n },\n });\n })\n .catch((err) => {\n if (cancelled) return; // prevent stale state update\n setError(\n err instanceof Error\n ? err\n : new Error(\"Failed to load account-abstraction module\"),\n );\n });\n\n return () => {\n cancelled = true;\n };\n }, [\n connectedChainId,\n options?.rpcUrl,\n options?.bundlerUrl,\n options?.chainId,\n ]);\n\n // Account and chain changes invalidate derived state. A result from the\n // previous owner must never remain visible as the current smart account.\n // biome-ignore lint/correctness/useExhaustiveDependencies: The effect intentionally resets derived state when any account configuration value changes.\n useEffect(() => {\n generationRef.current += 1;\n inFlightRef.current = false;\n setAddress(null);\n setIsDeployed(false);\n setAccountInfo(null);\n setIsLoading(false);\n setError(null);\n }, [\n evmAccount,\n connectedChainId,\n options?.rpcUrl,\n options?.bundlerUrl,\n options?.chainId,\n options?.entryPoint,\n options?.accountType,\n options?.salt,\n ]);\n\n // Get account config from options + connected EOA\n const getConfig = useCallback((): SmartAccountConfig | null => {\n const owner = bareEvmAddress(evmAccount);\n if (!owner || !managerRef.current) return null;\n // Returning null rather than assuming a chain. getConfig already has a\n // null contract, and every caller checks it.\n const chainId = resolveEvmChainId(options?.chainId, connectedChainId);\n if (!chainId) return null;\n\n return buildSmartAccountConfig(owner, chainId, {\n accountType: options?.accountType,\n entryPoint: options?.entryPoint,\n salt: options?.salt,\n });\n }, [\n evmAccount,\n connectedChainId,\n options?.accountType,\n options?.chainId,\n options?.entryPoint,\n options?.salt,\n ]);\n\n const fail = useCallback((nextError: Error): null => {\n setError(nextError);\n return null;\n }, []);\n\n const ensureOperation = useCallback((): number | null => {\n if (inFlightRef.current) {\n return null;\n }\n inFlightRef.current = true;\n return generationRef.current;\n }, []);\n\n const finishOperation = useCallback((operation: number): void => {\n if (generationRef.current === operation) inFlightRef.current = false;\n }, []);\n\n // Create wallet (compute counterfactual address)\n const createWallet =\n useCallback(async (): Promise<SmartAccountInfo | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) {\n return fail(new Error(\"Smart account not configured\"));\n }\n\n const operation = ensureOperation();\n if (operation === null)\n return fail(new Error(\"Smart account operation already in progress\"));\n\n setIsLoading(true);\n setError(null);\n\n try {\n const manager = managerRef.current;\n const info = await manager.createAccount(config);\n if (generationRef.current !== operation) return null;\n setAddress(info.address);\n setIsDeployed(info.isDeployed);\n setAccountInfo(info);\n return info;\n } catch (err) {\n if (generationRef.current !== operation) return null;\n const e =\n err instanceof Error\n ? err\n : new Error(\"Failed to create smart account\");\n setError(e);\n return null;\n } finally {\n if (generationRef.current === operation) setIsLoading(false);\n finishOperation(operation);\n }\n }, [ensureOperation, fail, finishOperation, getConfig]);\n\n // Deploy wallet\n const deployWallet = useCallback(async (): Promise<Address | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) {\n return fail(new Error(\"Smart account not configured\"));\n }\n\n if (!session) return fail(accountError(\"No active session\"));\n const activeClient = resolveClient(client);\n if (!activeClient) return fail(accountError(\"Client not initialized\"));\n if (connectedChainId && connectedChainId !== config.chainId) {\n return fail(\n new WalletError(\n \"chain_mismatch\",\n `Connected chain ${connectedChainId} does not match smart account chain ${config.chainId}.`,\n ),\n );\n }\n\n const operation = ensureOperation();\n if (operation === null)\n return fail(new Error(\"Smart account operation already in progress\"));\n\n setIsLoading(true);\n setError(null);\n\n try {\n const manager = managerRef.current;\n const before = await manager.createAccount(config);\n if (generationRef.current !== operation) return null;\n if (before.isDeployed) {\n setAddress(before.address);\n setIsDeployed(true);\n setAccountInfo(before);\n return before.address;\n }\n\n // SmartAccountManager.deployAccount intentionally refuses to broadcast\n // an account that is not deployed. Build the factory transaction and route it\n // through the active wallet instead.\n const deployTx = await manager.getDeployCallData(config);\n const deployResult = (await activeClient.sendTransaction(session, {\n transaction: {\n to: deployTx.to,\n data: deployTx.data,\n value: deployTx.value.toString(),\n },\n chainId: config.chainId,\n })) as Address;\n\n if (generationRef.current !== operation) return null;\n const after = await manager.createAccount(config);\n setAddress(after.address);\n setIsDeployed(after.isDeployed);\n setAccountInfo(after);\n return deployResult;\n } catch (err) {\n if (generationRef.current !== operation) return null;\n const e =\n err instanceof Error\n ? err\n : new Error(\"Failed to deploy smart account\");\n setError(e);\n return null;\n } finally {\n if (generationRef.current === operation) setIsLoading(false);\n finishOperation(operation);\n }\n }, [\n client,\n connectedChainId,\n ensureOperation,\n fail,\n finishOperation,\n getConfig,\n session,\n ]);\n\n // Get counterfactual address\n const getAddress = useCallback(async (): Promise<Address | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) return null;\n const generation = generationRef.current;\n\n try {\n const addr = await managerRef.current.getAccountAddress(config);\n if (generationRef.current !== generation) return null;\n setAddress(addr);\n return addr;\n } catch (err) {\n if (generationRef.current !== generation) return null;\n setError(\n err instanceof Error\n ? err\n : new Error(\"Failed to get smart account address\"),\n );\n return null;\n }\n }, [getConfig]);\n\n return {\n address,\n isDeployed,\n accountInfo,\n isLoading,\n error,\n createWallet,\n deployWallet,\n getAddress,\n };\n}\n","import { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface UseSolanaAccountReturn {\n /** The bare base58 address, or null when no Solana account is connected. */\n address: string | null;\n /** The CAIP-10 form, which carries which cluster it is on. */\n caip10: string | null;\n /** The CAIP-2 cluster, e.g. `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`. */\n chainId: string | null;\n isConnected: boolean;\n}\n\n/**\n * The connected Solana account, whichever wallet supplied it.\n *\n * Read off the session's namespaces rather than from the embedded connector,\n * so an injected wallet (Phantom, Solflare) and the embedded wallet answer the\n * same way.\n *\n * Matched on the `solana:` namespace, never on address shape. A base58 string\n * is not distinguishable from other base58 strings by inspection, and guessing\n * would eventually call something a Solana address that is not one.\n */\nexport function useSolanaAccount(): UseSolanaAccountReturn {\n const { accounts, isConnected } = useWeb3();\n\n return useMemo(() => {\n if (!isConnected) {\n return { address: null, caip10: null, chainId: null, isConnected: false };\n }\n const caip10 = accounts.find((a) => a.startsWith(\"solana:\")) ?? null;\n if (!caip10) {\n return { address: null, caip10: null, chainId: null, isConnected };\n }\n // `solana:<reference>:<address>` — the address is the last segment and the\n // reference may itself contain no colon, so splitting from the end is safe.\n const parts = caip10.split(\":\");\n const address = parts.length >= 3 ? parts[parts.length - 1] : null;\n const chainId = parts.length >= 3 ? parts.slice(0, -1).join(\":\") : null;\n return { address, caip10, chainId, isConnected };\n }, [accounts, isConnected]);\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n getSolanaBalance,\n type SolanaBalance,\n} from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useSolanaAccount } from \"./useSolanaAccount\";\n\nexport interface UseSolanaBalanceOptions {\n /** Defaults to the connected Solana account. */\n address?: string;\n /** Defaults to the client's `solanaRpcUrl`. */\n rpcUrl?: string;\n /** Milliseconds between refreshes. Off by default. */\n refreshInterval?: number;\n}\n\nexport interface UseSolanaBalanceReturn {\n /** Null until a balance has actually been read. Never a fabricated zero. */\n balance: SolanaBalance | null;\n isFetching: boolean;\n error: Error | null;\n /** Absent when no RPC endpoint is configured — a different fact from a\n * balance of zero, and the only one a caller can act on. */\n isConfigured: boolean;\n refetch: () => Promise<void>;\n}\n\n/**\n * The SOL balance of the connected Solana account.\n *\n * `balance` stays null until a read succeeds. A zero placeholder while\n * loading, or after a failure, is a number a user reads as their balance.\n */\nexport function useSolanaBalance(\n options: UseSolanaBalanceOptions = {},\n): UseSolanaBalanceReturn {\n const { client } = useWeb3();\n const { address: connectedAddress } = useSolanaAccount();\n const address = options.address ?? connectedAddress;\n const rpcUrl = options.rpcUrl ?? resolveClient(client)?.solanaRpcUrl ?? null;\n\n const [balance, setBalance] = useState<SolanaBalance | null>(null);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n // Guards against a slow response for a previous address overwriting the\n // balance of the one now on screen.\n const generationRef = useRef(0);\n\n const refetch = useCallback(async () => {\n if (!address || !rpcUrl) {\n setBalance(null);\n return;\n }\n const generation = ++generationRef.current;\n setIsFetching(true);\n setError(null);\n try {\n const next = await getSolanaBalance(rpcUrl, address);\n if (generation !== generationRef.current) return;\n setBalance(next);\n } catch (err) {\n if (generation !== generationRef.current) return;\n // Cleared rather than left stale: a balance shown next to an error is\n // read as the current balance, and it is not.\n setBalance(null);\n setError(err instanceof Error ? err : new Error(\"Balance read failed\"));\n } finally {\n if (generation === generationRef.current) setIsFetching(false);\n }\n }, [address, rpcUrl]);\n\n useEffect(() => {\n void refetch();\n }, [refetch]);\n\n useEffect(() => {\n if (!options.refreshInterval || options.refreshInterval <= 0) return;\n const id = setInterval(() => void refetch(), options.refreshInterval);\n return () => clearInterval(id);\n }, [options.refreshInterval, refetch]);\n\n return {\n balance,\n isFetching,\n error,\n isConfigured: Boolean(rpcUrl),\n refetch,\n };\n}\n","import {\n readSolanaRoles,\n type SolanaIdentity,\n type SolanaPayer,\n type SolanaRoles,\n type SolanaRolesAbsence,\n type SolanaRolesSource,\n type SolanaSigner,\n type SolanaWalletFeatures,\n} from \"@naculus/connect-appkit-core\";\nimport { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\n// Re-exported rather than declared here, for the same reason as\n// `AtomicSupport`: Vue needs the same shapes, and the declaration that\n// `signer` is `null` rather than a throwing stub must exist exactly once.\nexport type {\n SolanaIdentity,\n SolanaPayer,\n SolanaRoles,\n SolanaRolesAbsence,\n SolanaSigner,\n SolanaWalletFeatures,\n};\n\nexport interface UseSolanaRolesReturn {\n /** The roles the connected account can fill, or null with a reason. */\n roles: SolanaRoles | null;\n /** Why `roles` is null. Null when it is not. */\n absence: SolanaRolesAbsence | null;\n /** Which account this is. Never null while `roles` is present. */\n identity: SolanaIdentity | null;\n /**\n * Signs without submitting. Null when the wallet declared it cannot — a\n * send-only wallet, the usual shape behind Mobile Wallet Adapter — *and*\n * null when nothing is known; check `absence` to tell those apart.\n */\n signer: SolanaSigner | null;\n /** Signs and broadcasts itself. Null under the same two conditions. */\n payer: SolanaPayer | null;\n}\n\n/**\n * Which roles the connected Solana account can actually fill.\n *\n * Ask before building a flow. A multisig proposal, a co-signed escrow or a\n * relayer-submitted transaction needs `signer`; an ordinary transfer needs\n * `payer`; filling an `authority` field needs only `identity`. A wallet can\n * answer yes to one and no to another, and finding out here is what keeps\n * the answer from arriving at the approval prompt instead.\n *\n * Synchronous: the connector recorded what the wallet declared at discovery,\n * so this never prompts. Recomputed when the session or its accounts change,\n * which is how an in-wallet account switch reaches `identity.address`.\n */\nexport function useSolanaRoles(): UseSolanaRolesReturn {\n const { client, session, accounts } = useWeb3();\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `accounts` is a dependency for its identity only. The connector mutates the session in place on an account switch, so `session` alone would not change, but `accounts` is re-derived from it and does.\n return useMemo(() => {\n const connector = resolveClient(client)?.solanaConnector as\n | SolanaRolesSource\n | null\n | undefined;\n const { roles, absence } = readSolanaRoles(connector, session);\n return {\n roles,\n absence,\n identity: roles?.identity ?? null,\n signer: roles?.signer ?? null,\n payer: roles?.payer ?? null,\n };\n }, [client, session, accounts]);\n}\n","import { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useState } from \"react\";\nimport {\n getSignatureStatus,\n type SolanaConfirmationStatus,\n} from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\nexport interface UseSolanaTransactionReturn {\n /**\n * Sign a serialized transaction and return the signed bytes.\n *\n * Build and serialize it with `@solana/kit` or `@solana/web3.js` first —\n * the wallet's job is the signature, not the instructions. base64 or raw\n * bytes both work.\n */\n signTransaction: (\n transaction: Uint8Array | string,\n ) => Promise<Uint8Array>;\n /** Sign and submit, returning the base58 signature the cluster reports. */\n sendTransaction: (transaction: Uint8Array | string) => Promise<string>;\n /** Poll a signature. `\"unknown\"` is its own answer, not a failure. */\n getStatus: (\n signature: string,\n ) => Promise<{ status: SolanaConfirmationStatus; error: string | null }>;\n isSigning: boolean;\n isSending: boolean;\n error: Error | null;\n reset: () => void;\n}\n\n/**\n * Sign and send Solana transactions through whichever wallet is connected.\n *\n * The wallet is not asked to understand the transaction. It fills its own\n * signature slot and, for send, hands the bytes to a cluster.\n */\nexport function useSolanaTransaction(): UseSolanaTransactionReturn {\n const { client, session } = useWeb3();\n const [isSigning, setIsSigning] = useState(false);\n const [isSending, setIsSending] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const requireSession = () => {\n const activeClient = resolveClient(client);\n if (!activeClient || !session) {\n throw new WalletError(\"wallet_unavailable\", \"No connected wallet.\");\n }\n return activeClient;\n };\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: requireSession reads client and session, which are the dependencies\n const signTransaction = useCallback(\n async (transaction: Uint8Array | string) => {\n setIsSigning(true);\n setError(null);\n try {\n const activeClient = requireSession();\n const signed = await activeClient.signTransaction(session!, {\n transaction,\n });\n return signed as Uint8Array;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Signing failed\");\n setError(e);\n throw e;\n } finally {\n setIsSigning(false);\n }\n },\n [client, session],\n );\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: requireSession reads client and session, which are the dependencies\n const sendTransaction = useCallback(\n async (transaction: Uint8Array | string) => {\n setIsSending(true);\n setError(null);\n try {\n const activeClient = requireSession();\n const signature = await activeClient.sendTransaction(session!, {\n transaction,\n });\n return signature as string;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Send failed\");\n setError(e);\n throw e;\n } finally {\n setIsSending(false);\n }\n },\n [client, session],\n );\n\n const getStatus = useCallback(\n async (signature: string) => {\n const rpcUrl = resolveClient(client)?.solanaRpcUrl;\n if (!rpcUrl) {\n throw new WalletError(\n \"no_rpc\",\n \"Set solanaRpcUrl on the client to read a signature's status.\",\n );\n }\n return getSignatureStatus(rpcUrl, signature);\n },\n [client],\n );\n\n return {\n signTransaction,\n sendTransaction,\n getStatus,\n isSigning,\n isSending,\n error,\n reset: () => setError(null),\n };\n}\n","/**\n * useSwitchChain Hook\n *\n * Provides the switchChain method with loading/error state tracking.\n *\n * @see SRS-009 §7.2\n */\n\nimport { useCallback, useState } from \"react\";\nimport { toChainSwitchError } from \"@naculus/connect-appkit-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface UseSwitchChainReturn {\n /** Switch the active chain for the current session */\n switchChain: (chainId: string) => Promise<void>;\n /** Whether a chain switch is in progress */\n isSwitching: boolean;\n /** The currently active chain ID */\n currentChainId: string | null;\n /** The last error that occurred during chain switch (if any) */\n error: Error | null;\n /** Clear the error state */\n clearError: () => void;\n}\n\nexport function useSwitchChain(): UseSwitchChainReturn {\n const { switchChain: providerSwitchChain, chainId } = useWeb3();\n const [isSwitching, setIsSwitching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleSwitchChain = useCallback(\n async (targetChainId: string) => {\n setIsSwitching(true);\n setError(null);\n\n try {\n await providerSwitchChain(targetChainId);\n } catch (err) {\n // Every failure used to become chain_unsupported, so a user pressing\n // Cancel was reported as the chain being unavailable — two states a UI\n // must treat differently, since one is worth offering to retry.\n const walletError = toChainSwitchError(err);\n setError(walletError);\n throw walletError;\n } finally {\n setIsSwitching(false);\n }\n },\n [providerSwitchChain],\n );\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n return {\n switchChain: handleSwitchChain,\n isSwitching,\n currentChainId: chainId,\n error,\n clearError,\n };\n}\n","import {\n chainNumber,\n resolveChain,\n toViemChain,\n} from \"@naculus/connect-appkit-core\";\nimport { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport {\n createPublicClient,\n http,\n formatUnits,\n type PublicClient,\n type Address,\n} from \"viem\";\n\nexport interface TokenInfo {\n /** ERC-20 token contract address */\n address: Address;\n /** Token symbol (e.g. \"USDC\", \"LINK\") */\n symbol: string;\n /** Token decimals (e.g. 6 for USDC, 18 for most) */\n decimals: number;\n /** Optional display name */\n name?: string;\n}\n\nexport interface UseTokenBalanceOptions {\n /** ERC-20 token(s) to query */\n tokens: TokenInfo[];\n /** Auto-refresh interval in milliseconds. Default: undefined (no auto-refresh). */\n refreshInterval?: number;\n}\n\nexport interface TokenBalanceResult {\n address: Address;\n symbol: string;\n decimals: number;\n name?: string;\n /** Raw balance as string (in smallest unit), or null if not loaded */\n balance: string | null;\n /** Human-readable formatted balance, or null if not loaded */\n formatted: string | null;\n}\n\n// ERC-20 ABI fragment for balanceOf\nconst erc20Abi = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"owner\", type: \"address\" }],\n outputs: [{ name: \"balance\", type: \"uint256\" }],\n },\n] as const;\n\nexport function useTokenBalance(options: UseTokenBalanceOptions) {\n const { evmAccount, isConnected } = useAccount();\n const { chainId, chains } = useWeb3();\n const [tokenBalances, setTokenBalances] = useState<TokenBalanceResult[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const { tokens, refreshInterval } = options;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n // Stable key for tokens to avoid infinite loops when array reference changes\n const tokensKey = useMemo(\n () => tokens.map(t => t.address.toLowerCase() + \"|\" + t.decimals + \"|\" + t.symbol).join(\",\"),\n [tokens]\n );\n\n const currentChain = useMemo(\n () => resolveChain(chains, chainId),\n [chainId, chains],\n );\n // Null for a non-EVM chain, and a viem client must not be built for one.\n const evmChainNumber = currentChain ? chainNumber(currentChain) : null;\n // Memoized: `toViemChain` builds a fresh object per call, and an unmemoized\n // one would change identity every render — which drives the client effects\n // below into a loop that never settles.\n const viemChain = useMemo(\n () => (currentChain ? toViemChain(currentChain, evmChainNumber) : null),\n [currentChain, evmChainNumber],\n );\n\n const [client, setClient] = useState<PublicClient | null>(null);\n\n useEffect(() => {\n if (!viemChain || !currentChain?.rpcUrl) {\n setClient(null);\n return;\n }\n\n const publicClient = createPublicClient({\n transport: http(currentChain.rpcUrl),\n chain: viemChain,\n });\n\n setClient(publicClient);\n }, [currentChain, viemChain]);\n\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on tokensKey (the token list by value), not on the array identity that changes every render\n const fetchTokenBalances = useCallback(async () => {\n if (!evmAccount || !client || tokens.length === 0) {\n setTokenBalances([]);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const address = evmAccount.includes(\":\")\n ? (evmAccount.split(\":\").pop() as Address)\n : (evmAccount as Address);\n\n // Query all token balances with individual error handling\n const results = await Promise.allSettled(\n tokens.map(async (token) => {\n try {\n const balance = await client.readContract({\n address: token.address,\n abi: erc20Abi,\n functionName: \"balanceOf\",\n args: [address],\n });\n return {\n address: token.address,\n symbol: token.symbol,\n decimals: token.decimals,\n name: token.name,\n balance: balance.toString(),\n formatted: formatUnits(balance, token.decimals),\n } as TokenBalanceResult;\n } catch {\n return {\n address: token.address,\n symbol: token.symbol,\n decimals: token.decimals,\n name: token.name,\n balance: null,\n formatted: null,\n } as TokenBalanceResult;\n }\n })\n );\n\n const balances: TokenBalanceResult[] = results.map((r) => {\n if (r.status === \"fulfilled\") {\n return r.value;\n }\n // Fallback for rejected promises (shouldn't happen with inner catch)\n return {\n address: \"\" as Address,\n symbol: \"?\",\n decimals: 0,\n balance: null,\n formatted: null,\n };\n });\n\n setTokenBalances(balances);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to fetch token balances\"));\n } finally {\n setIsLoading(false);\n }\n }, [evmAccount, client, tokensKey]);\n\n // Initial fetch\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on tokensKey (the token list by value), not on the array identity that changes every render\n useEffect(() => {\n if (isConnected && evmAccount && tokens.length > 0) {\n fetchTokenBalances();\n }\n }, [isConnected, evmAccount, tokensKey, fetchTokenBalances]);\n\n // Auto-refresh interval\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on tokensKey (the token list by value), not on the array identity that changes every render\n useEffect(() => {\n if (refreshInterval && refreshInterval > 0 && isConnected && evmAccount && tokens.length > 0) {\n intervalRef.current = setInterval(fetchTokenBalances, refreshInterval);\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [refreshInterval, isConnected, evmAccount, tokensKey, fetchTokenBalances]);\n\n // Helper: get a single token balance by address\n const getTokenBalance = useCallback(\n (tokenAddress: Address): TokenBalanceResult | undefined => {\n return tokenBalances.find(\n (tb) => tb.address.toLowerCase() === tokenAddress.toLowerCase()\n );\n },\n [tokenBalances]\n );\n\n return {\n /** Array of token balance results */\n tokenBalances,\n isLoading,\n error,\n /** Re-fetch all token balances */\n refetch: fetchTokenBalances,\n /** Get a specific token balance by contract address */\n getTokenBalance,\n chain: currentChain,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\nimport type { TxMonitorLike, TxStatusEntry } from \"./useTxMonitor\";\nimport { useTxMonitorProvider } from \"./useTxMonitor\";\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseTxHistoryResult {\n entries: TxStatusEntry[];\n isLoading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n summary: {\n pending: number;\n confirmed: number;\n failed: number;\n };\n}\n\n/**\n * Query transaction history.\n * address defaults to current wallet address; chainId defaults to current chain.\n */\nexport function useTxHistory(\n address?: string,\n chainId?: number,\n monitor?: TxMonitorLike,\n): UseTxHistoryResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [entries, setEntries] = useState<TxStatusEntry[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const refreshCounter = useRef(0);\n\n const refresh = useCallback(async () => {\n if (!effectiveMonitor) return;\n setIsLoading(true);\n setError(null);\n refreshCounter.current++;\n try {\n const results = await effectiveMonitor.getTxHistory(address, chainId);\n setEntries(results);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [effectiveMonitor, address, chainId]);\n\n useEffect(() => {\n refresh().catch(() => {});\n }, [refresh]);\n\n // Listen for status changes to update entries reactively\n useEffect(() => {\n if (!effectiveMonitor) return;\n\n const onStatusChange = () => {\n // Re-fetch on any status change\n refresh().catch(() => {});\n };\n effectiveMonitor.on(\"statusChange\", onStatusChange);\n\n return () => {\n effectiveMonitor.off(\"statusChange\", onStatusChange as any);\n };\n }, [effectiveMonitor, refresh]);\n\n const summary = {\n pending: entries.filter(e => e.status === \"pending\").length,\n confirmed: entries.filter(e => e.status === \"confirmed\").length,\n failed: entries.filter(e => e.status === \"failed\").length,\n };\n\n return {\n entries,\n isLoading,\n error,\n refresh,\n summary,\n };\n}\n","/**\n * useUserOpStatus\n *\n * React hook for tracking ERC-4337 UserOperation lifecycle.\n * Polls the bundler for UserOperation receipt and reports status transitions.\n *\n * @example\n * ```tsx\n * const { userOpHash, status, receipt, error } = useUserOpStatus({\n * userOpHash: \"0x...\",\n * bundlerUrl: \"https://api.pimlico.io/v2/1/rpc?apikey=...\",\n * pollInterval: 2000,\n * });\n *\n * if (status === \"confirmed\") {\n * console.log(\"UserOp included in block!\");\n * }\n * ```\n */\n\nimport {\n fetchUserOperationReceipt,\n InvalidUserOperationReceiptError,\n} from \"@naculus/connect-appkit-core\";\nimport type { Hex, UserOperationReceipt } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type UserOpStatus =\n | \"idle\"\n | \"pending\"\n | \"confirmed\"\n | \"failed\"\n | \"not_found\";\n\nexport interface UseUserOpStatusOptions {\n /** The UserOperation hash to track */\n userOpHash?: Hex | null;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Polling interval in milliseconds (default: 2000) */\n pollInterval?: number;\n /** Maximum number of retries (default: 30) */\n maxRetries?: number;\n /** Auto-start polling when userOpHash is provided */\n autoStart?: boolean;\n}\n\nexport interface UseUserOpStatusReturn {\n /** Current status of the UserOperation */\n status: UserOpStatus;\n /** UserOperation receipt (available when confirmed or failed) */\n receipt: UserOperationReceipt | null;\n /** The userOpHash being tracked */\n userOpHash: Hex | null;\n /** Error state */\n error: Error | null;\n /** Whether polling is active */\n isPolling: boolean;\n /** Time elapsed since tracking started (ms) */\n elapsedMs: number;\n /** Number of poll attempts made */\n attempts: number;\n /** Start tracking a UserOperation */\n start: (hash: Hex) => void;\n /** Stop tracking */\n stop: () => void;\n /** Reset state */\n reset: () => void;\n}\n\nexport function useUserOpStatus(\n options?: UseUserOpStatusOptions,\n): UseUserOpStatusReturn {\n const bundlerUrl = options?.bundlerUrl;\n const pollInterval = options?.pollInterval ?? 2000;\n const maxRetries = options?.maxRetries ?? 30;\n\n const [status, setStatus] = useState<UserOpStatus>(\"idle\");\n const [receipt, setReceipt] = useState<UserOperationReceipt | null>(null);\n const [userOpHash, setUserOpHash] = useState<Hex | null>(\n options?.userOpHash ?? null,\n );\n const [error, setError] = useState<Error | null>(null);\n const [isPolling, setIsPolling] = useState(false);\n const [attempts, setAttempts] = useState(0);\n\n const startTimeRef = useRef<number>(0);\n const [elapsedMs, setElapsedMs] = useState(0);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const requestGenerationRef = useRef(0);\n const attemptsRef = useRef(0);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n // Clear all timers\n const clearTimers = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n if (pollTimerRef.current) {\n clearTimeout(pollTimerRef.current);\n pollTimerRef.current = null;\n }\n }, []);\n\n // Poll the bundler for receipt\n const poll = useCallback(\n async (hash: Hex, generation: number) => {\n if (!bundlerUrl || generation !== requestGenerationRef.current) return;\n\n const currentAttempt = attemptsRef.current + 1;\n attemptsRef.current = currentAttempt;\n setAttempts(currentAttempt);\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n const finishUnavailable = (nextError: Error): void => {\n if (generation !== requestGenerationRef.current) return;\n setStatus(\"not_found\");\n setIsPolling(false);\n clearTimers();\n setError(nextError);\n };\n\n const retryOrFinish = (nextError: Error): void => {\n if (generation !== requestGenerationRef.current) return;\n if (currentAttempt <= maxRetries) {\n pollTimerRef.current = setTimeout(\n () => void poll(hash, generation),\n pollInterval,\n );\n return;\n }\n finishUnavailable(nextError);\n };\n\n try {\n const receiptData = await fetchUserOperationReceipt(\n bundlerUrl,\n hash,\n controller.signal,\n );\n if (generation !== requestGenerationRef.current) return;\n if (receiptData) {\n setReceipt(receiptData);\n setStatus(receiptData.success ? \"confirmed\" : \"failed\");\n setIsPolling(false);\n clearTimers();\n return;\n }\n setStatus(\"pending\");\n retryOrFinish(\n new Error(\"UserOperation not included after maximum retries\"),\n );\n } catch (networkError) {\n if (\n generation !== requestGenerationRef.current ||\n controller.signal.aborted\n ) {\n return;\n }\n const nextError =\n networkError instanceof Error\n ? networkError\n : new Error(\"Unknown bundler response failure\");\n if (nextError instanceof InvalidUserOperationReceiptError) {\n finishUnavailable(nextError);\n return;\n }\n retryOrFinish(\n new Error(\n `UserOperation status unavailable after ${currentAttempt} attempt${currentAttempt === 1 ? \"\" : \"s\"}: ${nextError.message}`,\n ),\n );\n } finally {\n if (abortControllerRef.current === controller) {\n abortControllerRef.current = null;\n }\n }\n },\n [bundlerUrl, pollInterval, maxRetries, clearTimers],\n );\n\n // Start tracking\n const start = useCallback(\n (hash: Hex) => {\n requestGenerationRef.current += 1;\n const generation = requestGenerationRef.current;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n setUserOpHash(hash);\n setReceipt(null);\n setError(null);\n attemptsRef.current = 0;\n setAttempts(0);\n setElapsedMs(0);\n startTimeRef.current = Date.now();\n\n if (!bundlerUrl) {\n setStatus(\"not_found\");\n setIsPolling(false);\n setError(new Error(\"Bundler URL not configured\"));\n return;\n }\n\n setStatus(\"pending\");\n setIsPolling(true);\n\n // Start elapsed timer\n intervalRef.current = setInterval(() => {\n setElapsedMs(Date.now() - startTimeRef.current);\n }, 1000);\n\n // Start polling\n void poll(hash, generation);\n },\n [bundlerUrl, clearTimers, poll],\n );\n\n // Stop tracking\n const stop = useCallback(() => {\n requestGenerationRef.current += 1;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n setIsPolling(false);\n }, [clearTimers]);\n\n // Reset state\n const reset = useCallback(() => {\n requestGenerationRef.current += 1;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n setUserOpHash(null);\n setStatus(\"idle\");\n setReceipt(null);\n setError(null);\n setIsPolling(false);\n attemptsRef.current = 0;\n setAttempts(0);\n setElapsedMs(0);\n }, [clearTimers]);\n\n // Auto-start whenever a userOpHash is provided: at mount, or later when\n // the hash arrives after sending (the usual case). This ran only on mount,\n // so a hash passed after the first render was never tracked.\n const autoHash = options?.userOpHash ?? null;\n const autoStart = options?.autoStart !== false;\n useEffect(() => {\n if (autoHash && autoStart) start(autoHash);\n }, [autoHash, autoStart, start]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n requestGenerationRef.current += 1;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n };\n }, [clearTimers]);\n\n return {\n status,\n receipt,\n userOpHash,\n error,\n isPolling,\n elapsedMs,\n attempts,\n start,\n stop,\n reset,\n };\n}\n","/**\n * useValidateDestination — address blackhole prevention hook.\n *\n * The checks live in `@naculus/connect-appkit-core` (`validateDestination`),\n * shared with the Vue composable. This file only adds React and the\n * user-facing string for the machine-readable issue.\n *\n * Level: \"ok\" | \"warning\" | \"blocked\". \"ok\" means nothing wrong was found —\n * not that the destination is safe; see the core module for why.\n */\n\nimport {\n type AddressValidationLevel,\n validateDestination as validateDestinationCore,\n} from \"@naculus/connect-appkit-core\";\nimport { useMemo } from \"react\";\nimport { t } from \"../utils/i18n\";\n\nexport type { AddressValidationLevel };\n\nexport interface AddressValidationResult {\n isValid: boolean;\n level: AddressValidationLevel;\n warning: string | null;\n}\n\nexport function validateDestination(address: string): AddressValidationResult {\n const { isValid, level, issue } = validateDestinationCore(address);\n return { isValid, level, warning: issue ? t(`address.${issue}`) : null };\n}\n\nexport interface UseValidateDestinationOptions {\n address: string;\n}\n\nexport interface UseValidateDestinationReturn {\n validation: AddressValidationResult;\n}\n\nexport function useValidateDestination({\n address,\n}: UseValidateDestinationOptions): UseValidateDestinationReturn {\n const validation = useMemo(() => validateDestination(address), [address]);\n return { validation };\n}\n","/**\n * i18n — ponytail approach: static key-value map, no framework dependency.\n *\n * All UI strings go through here. No hardcoded text in components.\n * To add a language: copy this file and translate the values.\n */\n\nexport type Locale = \"en\" | \"zh\";\n\nconst en = {\n // Storage security\n \"storage.critical.title\": \"Insecure Storage Detected\",\n \"storage.critical.body\": \"Your browser does not support IndexedDB. Wallet data is stored in plaintext in localStorage and could be exposed to XSS attacks. We strongly recommend switching to a modern browser.\",\n \"storage.warning.title\": \"Storage Security Warning\",\n \"storage.warning.body\": \"Your browser does not support IndexedDB, but your wallet data is encrypted with AES-256-GCM. Consider switching browsers for better origin isolation.\",\n\n // Address validation\n \"address.empty\": \"Address is empty\",\n \"address.invalid_format\": \"Invalid address format (expected 0x + 40 hex chars)\",\n \"address.zero_address\": \"Address is the zero address — funds would be permanently lost\",\n \"address.burn_address\": \"Address appears to be a burn address — funds would be permanently lost\",\n\n // General wallet\n \"wallet.connect\": \"Connect Wallet\",\n \"wallet.disconnect\": \"Disconnect\",\n \"wallet.connecting\": \"Connecting...\",\n \"wallet.copy_address\": \"Copy address\",\n \"wallet.copied\": \"Copied!\",\n \"wallet.view_on_explorer\": \"View on Explorer\",\n \"wallet.retry\": \"Retry\",\n \"wallet.connection_failed\": \"Connection failed\",\n \"wallet.scan_qr\": \"Scan with your wallet app\",\n\n // Embedded wallet\n \"embedded.generate\": \"Create Wallet\",\n \"embedded.import\": \"Import Wallet\",\n \"embedded.backup_seed\": \"Back up your seed phrase\",\n \"embedded.backup_warning\": \"Anyone with your seed phrase can access your funds. Store it securely.\",\n \"embedded.backup_done\": \"I've saved my seed phrase\",\n \"embedded.wipe\": \"Remove Wallet\",\n \"embedded.wipe_confirm\": \"Are you sure? This cannot be undone.\",\n} as const;\n\nconst zh: Record<keyof typeof en, string> = {\n \"storage.critical.title\": \"偵測到不安全儲存\",\n \"storage.critical.body\": \"您的瀏覽器不支援 IndexedDB。錢包資料以明文儲存在 localStorage 中,可能暴露於 XSS 攻擊。強烈建議更換至現代瀏覽器。\",\n \"storage.warning.title\": \"儲存安全警告\",\n \"storage.warning.body\": \"您的瀏覽器不支援 IndexedDB,但錢包資料已使用 AES-256-GCM 加密。建議更換瀏覽器以獲得更好的隔離保護。\",\n\n \"address.empty\": \"地址為空\",\n \"address.invalid_format\": \"無效的地址格式(應為 0x + 40 個十六進位字元)\",\n \"address.zero_address\": \"此為零地址 — 資金將永久丟失\",\n \"address.burn_address\": \"此地址為燒毀地址 — 資金將永久丟失\",\n\n \"wallet.connect\": \"連接錢包\",\n \"wallet.disconnect\": \"斷開連線\",\n \"wallet.connecting\": \"連線中...\",\n \"wallet.copy_address\": \"複製地址\",\n \"wallet.copied\": \"已複製!\",\n \"wallet.view_on_explorer\": \"在瀏覽器查看\",\n \"wallet.retry\": \"重試\",\n \"wallet.connection_failed\": \"連線失敗\",\n \"wallet.scan_qr\": \"使用錢包 App 掃描\",\n\n \"embedded.generate\": \"建立錢包\",\n \"embedded.import\": \"匯入錢包\",\n \"embedded.backup_seed\": \"備份助記詞\",\n \"embedded.backup_warning\": \"任何人取得您的助記詞都可以存取您的資金。請安全儲存。\",\n \"embedded.backup_done\": \"我已儲存助記詞\",\n \"embedded.wipe\": \"移除錢包\",\n \"embedded.wipe_confirm\": \"確定要移除嗎?此操作無法復原。\",\n};\n\nconst locales = { en, zh } as const;\n\nlet currentLocale: Locale = \"en\";\n\nexport function setLocale(locale: Locale): void {\n currentLocale = locale;\n}\n\nexport function getLocale(): Locale {\n return currentLocale;\n}\n\nexport function t(key: keyof typeof en): string {\n return locales[currentLocale][key] ?? locales.en[key] ?? key;\n}\n","import { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport function useWallet() {\n const {\n status,\n session,\n accounts,\n chainId,\n error,\n connect,\n disconnect,\n reconnect,\n switchChain\n } = useWeb3();\n\n const isConnected = status === \"connected\";\n const isConnecting = status === \"connecting\";\n const isReconnecting = status === \"reconnecting\";\n\n const currentAccount = accounts[0] ?? null;\n const isDisconnected = status === \"disconnected\";\n\n return {\n status,\n session,\n accounts,\n chainId,\n error,\n isConnected,\n isConnecting,\n isReconnecting,\n isDisconnected,\n currentAccount,\n connect,\n disconnect,\n reconnect,\n switchChain\n };\n}","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getUserFriendlyError, isRetryableError } from \"../utils/errorMessages\";\n\nexport interface UserFriendlyError {\n title: string;\n description: string;\n code?: string;\n}\n\nexport interface UseWeb3ErrorHandlerReturn {\n /** Current error from the provider */\n error: Error | null;\n /** User-friendly representation of the current error */\n friendlyError: UserFriendlyError | null;\n /** Clear the current error */\n clearError: () => void;\n /** Check if current error is retryable */\n isRetryable: boolean;\n /** Get a user-friendly version of any error */\n formatError: (error: unknown) => UserFriendlyError;\n /** Wraps an async function with error formatting */\n wrapAsync: <T>(fn: () => Promise<T>) => () => Promise<T>;\n}\n\n/**\n * Hook that provides user-friendly error handling for web3 operations.\n *\n * Features:\n * - Maps WalletError codes to human-readable messages\n * - Provides retry detection for transient errors\n * - Wraps async operations with consistent error formatting\n * - Exposes the current error state from Web3ConnectProvider\n *\n * @example\n * ```tsx\n * const { friendlyError, clearError, isRetryable, wrapAsync } = useWeb3ErrorHandler();\n *\n * // Show error in UI\n * if (friendlyError) {\n * return <ErrorDisplay title={friendlyError.title} message={friendlyError.description} />;\n * }\n *\n * // Wrap an operation\n * const safeConnect = wrapAsync(() => connect());\n * await safeConnect();\n * ```\n */\nexport function useWeb3ErrorHandler(): UseWeb3ErrorHandlerReturn {\n const { error, clearError: providerClearError } = useWeb3();\n\n const friendlyError: UserFriendlyError | null = useMemo(\n () => (error ? getUserFriendlyError(error) : null),\n [error],\n );\n\n const isRetryable = useMemo(\n () => (error ? isRetryableError(error) : false),\n [error],\n );\n\n const clearError = useCallback(() => {\n providerClearError();\n }, [providerClearError]);\n\n const formatError = useCallback(\n (err: unknown): UserFriendlyError => getUserFriendlyError(err),\n [],\n );\n\n const wrapAsync = useCallback(\n <T>(fn: () => Promise<T>): (() => Promise<T>) => {\n return async () => {\n try {\n return await fn();\n } catch (err) {\n const friendly = getUserFriendlyError(err);\n\n // Attach to the original rather than replacing it. Building a fresh\n // Error here discarded the only technical evidence of the failure:\n // the wallet's own message, any `details`, and — the part callers\n // actually notice — the class, so `err instanceof WalletError` never\n // matched again. A convenience wrapper must not make the SDK's own\n // error type unusable.\n if (err instanceof Error) {\n const target = err as Error & {\n title?: string;\n code?: unknown;\n friendlyMessage?: string;\n };\n try {\n target.title = friendly.title;\n target.friendlyMessage = friendly.description;\n // Only fill a code in when the error has none. Overwriting a\n // wallet's own code with one this module inferred from the\n // message text would hide the real reason behind a guess.\n if (target.code === undefined && friendly.code !== undefined) {\n target.code = friendly.code;\n }\n } catch {\n // A frozen error cannot be annotated; it is still the better\n // thing to re-throw.\n }\n throw target;\n }\n\n // Not an Error, so there is nothing to preserve the identity of.\n // `cause` keeps the original value reachable.\n throw Object.assign(new Error(friendly.description, { cause: err }), {\n title: friendly.title,\n code: friendly.code,\n friendlyMessage: friendly.description,\n });\n }\n };\n },\n [],\n );\n\n return {\n error,\n friendlyError,\n clearError,\n isRetryable,\n formatError,\n wrapAsync,\n };\n}\n","/**\n * User-friendly error messages for WalletError codes and common errors.\n * Maps internal error codes to human-readable messages that can be shown in toasts/UI.\n */\n\nimport type { WalletErrorCode } from \"@naculus/connect-core\";\n\n/**\n * User-friendly title for each WalletError code.\n */\nexport const WALLET_ERROR_TITLES: Record<string, string> = {\n wallet_unavailable: \"Wallet Not Detected\",\n user_rejected: \"Connection Rejected\",\n deeplink_timeout: \"Wallet Connection Timed Out\",\n session_expired: \"Session Expired\",\n intent_expired: \"Connection Request Expired\",\n namespace_mismatch: \"Network Mismatch\",\n chain_unsupported: \"Unsupported Network\",\n method_not_allowed: \"Action Not Allowed\",\n signature_rejected: \"Signature Rejected\",\n tx_failed: \"Transaction Failed\",\n};\n\n/**\n * User-friendly description for each WalletError code.\n */\nexport const WALLET_ERROR_DESCRIPTIONS: Record<string, string> = {\n wallet_unavailable:\n \"No wallet found. Please install a compatible wallet (e.g., MetaMask, WalletConnect) and try again.\",\n user_rejected: \"The connection request was declined in your wallet. You can try again whenever you're ready.\",\n deeplink_timeout:\n \"The wallet didn't respond in time. This can happen if the wallet app isn't installed or takes too long to open.\",\n session_expired:\n \"Your wallet session has expired. Please reconnect to continue.\",\n intent_expired:\n \"The connection request expired. Please try connecting again.\",\n namespace_mismatch:\n \"This wallet doesn't support the required network. Try using a different wallet or network.\",\n chain_unsupported:\n \"This network isn't supported. Please switch to a supported network in your wallet.\",\n method_not_allowed:\n \"This action isn't supported by your current wallet or network.\",\n signature_rejected: \"The signature request was declined in your wallet.\",\n tx_failed:\n \"The transaction couldn't be completed. This could be due to insufficient funds, network congestion, or a contract error.\",\n};\n\n/**\n * Default title for unknown errors.\n */\nexport const UNKNOWN_ERROR_TITLE = \"Something went wrong\";\n\n/**\n * Default description for unknown errors.\n */\nexport const UNKNOWN_ERROR_DESCRIPTION =\n \"An unexpected error occurred. Please try again. If the problem persists, check your connection and wallet configuration.\";\n\n/**\n * Get a user-friendly error message object from any error.\n */\nexport function getUserFriendlyError(\n error: unknown\n): { title: string; description: string; code?: string } {\n if (!error) {\n return { title: UNKNOWN_ERROR_TITLE, description: UNKNOWN_ERROR_DESCRIPTION };\n }\n\n // Check for WalletError with code\n const maybeWalletError = error as { name?: string; code?: string; message?: string };\n if (maybeWalletError.name === \"WalletError\" && maybeWalletError.code) {\n const code = maybeWalletError.code;\n const title = WALLET_ERROR_TITLES[code] ?? UNKNOWN_ERROR_TITLE;\n const description =\n WALLET_ERROR_DESCRIPTIONS[code] ?? maybeWalletError.message ?? UNKNOWN_ERROR_DESCRIPTION;\n return { title, description, code };\n }\n\n // Check for standard Error\n if (error instanceof Error) {\n const message = error.message;\n // Map common error patterns\n if (/user rejected/i.test(message) || /rejected/.test(message)) {\n return {\n title: \"Request Rejected\",\n description: \"The request was declined.\",\n code: \"user_rejected\",\n };\n }\n if (/timeout/i.test(message) || /timed? ?out/i.test(message)) {\n return {\n title: \"Request Timed Out\",\n description: \"The request took too long. Please try again.\",\n code: \"deeplink_timeout\",\n };\n }\n // Specific before generic: \"insufficient funds on chain 1\" also matches\n // /chain/i, and reporting that as a network problem sends the user to\n // check their connection instead of their balance.\n if (/insufficient funds/i.test(message)) {\n return {\n title: \"Insufficient Funds\",\n description: \"You don't have enough funds to complete this transaction.\",\n code: \"tx_failed\",\n };\n }\n if (/network/i.test(message) || /chain/i.test(message)) {\n return {\n title: \"Network Error\",\n description: message,\n code: \"chain_unsupported\",\n };\n }\n\n return {\n title: UNKNOWN_ERROR_TITLE,\n description: message || UNKNOWN_ERROR_DESCRIPTION,\n };\n }\n\n // String error\n if (typeof error === \"string\") {\n return {\n title: UNKNOWN_ERROR_TITLE,\n description: error || UNKNOWN_ERROR_DESCRIPTION,\n };\n }\n\n return { title: UNKNOWN_ERROR_TITLE, description: UNKNOWN_ERROR_DESCRIPTION };\n}\n\n/**\n * Check if an error is retryable (transient).\n */\nexport function isRetryableError(error: unknown): boolean {\n // A rejected promise with no reason gives `undefined` here. Reading `.name`\n // off it threw, so the error handler crashed while handling an error and\n // buried whatever actually went wrong.\n if (error === null || typeof error !== \"object\") return false;\n const maybe = error as { name?: string; code?: string; message?: string };\n if (maybe.name !== \"WalletError\" || !maybe.code) return false;\n const retryableCodes: WalletErrorCode[] = [\n \"deeplink_timeout\",\n \"session_expired\",\n \"intent_expired\",\n \"tx_failed\",\n ];\n return retryableCodes.includes(maybe.code as WalletErrorCode);\n}\n","/**\n * useTokenList — React hook for loading token lists.\n *\n * Manages TokenListManager lifecycle and provides reactive\n * token data scoped to a specific chain.\n */\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport { TokenListManager } from \"@naculus/connect-core\";\nimport type { TokenListEntry, TokenListSource, TokenListManagerConfig } from \"@naculus/connect-core\";\nimport { eip155ChainIdToNumber } from \"@naculus/connect-appkit-core\";\n\nexport interface UseTokenListOptions {\n /** Auto-load on mount (default: true) */\n autoLoad?: boolean;\n /** Custom sources (overrides defaults) */\n sources?: TokenListSource[];\n}\n\nexport interface UseTokenListReturn {\n /** Loaded tokens for the specified chain */\n tokens: TokenListEntry[];\n /** Whether the initial load is in progress */\n isLoading: boolean;\n /** Whether tokens have been loaded at least once */\n isLoaded: boolean;\n /** Last error, if any */\n error: Error | null;\n /** Force a full refresh from all sources */\n refetch: () => Promise<void>;\n}\n\n/**\n * React hook for accessing token lists for a specific chain.\n *\n * @example\n * const { tokens, isLoading } = useTokenList(\"eip155:1\");\n * // tokens → [WETH, USDC, USDT, DAI, ...]\n */\nexport function useTokenList(\n chainId?: string,\n options?: UseTokenListOptions,\n): UseTokenListReturn {\n const managerRef = useRef<TokenListManager | null>(null);\n const [tokens, setTokens] = useState<TokenListEntry[]>([]);\n const [isLoading, setIsLoading] = useState(options?.autoLoad !== false);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Initialize manager once\n if (!managerRef.current) {\n const config: Partial<TokenListManagerConfig> = {};\n if (options?.sources) {\n config.sources = options.sources;\n }\n managerRef.current = new TokenListManager(config);\n }\n\n const load = useCallback(async () => {\n const manager = managerRef.current;\n if (!manager) return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await manager.load();\n const numericChainId = chainId ? eip155ChainIdToNumber(chainId) : undefined;\n const loaded = manager.getTokens(\n numericChainId !== undefined ? { chainId: numericChainId } : undefined,\n );\n setTokens(loaded);\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [chainId]);\n\n const refetch = useCallback(async () => {\n const manager = managerRef.current;\n if (!manager) return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await manager.refresh();\n const numericChainId = chainId ? eip155ChainIdToNumber(chainId) : undefined;\n const loaded = manager.getTokens(\n numericChainId !== undefined ? { chainId: numericChainId } : undefined,\n );\n setTokens(loaded);\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [chainId]);\n\n useEffect(() => {\n if (options?.autoLoad !== false) {\n load();\n }\n }, [load, options?.autoLoad]);\n\n return { tokens, isLoading, isLoaded, error, refetch };\n}\n\n/**\n * Parse a CAIP-2 chain ID like \"eip155:1\" into a numeric chain ID (1).\n * Returns undefined for non-numeric chains.\n */\n\n","/**\n * useTokenSearch — React hook for searching tokens.\n *\n * Debounced search over loaded token lists.\n * Returns structured results (exact + fuzzy matches).\n */\n\nimport { useState, useEffect, useRef } from \"react\";\nimport { TokenListManager } from \"@naculus/connect-core\";\nimport type { TokenSearchResult } from \"@naculus/connect-core\";\nimport { getDefaultSources } from \"./defaults\";\nimport { eip155ChainIdToNumber } from \"@naculus/connect-appkit-core\";\n\nconst DEBOUNCE_MS = 300;\n\nexport interface UseTokenSearchReturn {\n /** Structured search results */\n results: TokenSearchResult;\n /** Whether a search is currently running */\n isSearching: boolean;\n}\n\n// Shared manager instance across hooks\nlet sharedManager: TokenListManager | null = null;\n\nfunction getManager(): TokenListManager {\n if (!sharedManager) {\n sharedManager = new TokenListManager({\n sources: getDefaultSources(),\n });\n // Start loading in background\n sharedManager.load().catch(() => {});\n }\n return sharedManager;\n}\n\n/**\n * React hook for searching tokens by symbol, name, or address.\n *\n * Debounced 300ms to avoid excessive re-renders during typing.\n *\n * @example\n * const { results, isSearching } = useTokenSearch(\"USDC\");\n * // results.exact → [USDC on ETH]\n * // results.fuzzy → [USDC.e on AVAX]\n */\nexport function useTokenSearch(\n query: string,\n chainId?: string,\n): UseTokenSearchReturn {\n const [results, setResults] = useState<TokenSearchResult>({\n exact: [],\n fuzzy: [],\n hasMore: false,\n });\n const [isSearching, setIsSearching] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const trimmedQuery = query.trim();\n\n useEffect(() => {\n if (!trimmedQuery) {\n setResults({ exact: [], fuzzy: [], hasMore: false });\n setIsSearching(false);\n return;\n }\n\n // Debounce\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n setIsSearching(true);\n\n debounceRef.current = setTimeout(() => {\n const manager = getManager();\n const numericChainId = chainId ? eip155ChainIdToNumber(chainId) : undefined;\n const searchResults = manager.search(trimmedQuery, {\n chainId: numericChainId,\n limit: 20,\n });\n setResults(searchResults);\n setIsSearching(false);\n }, DEBOUNCE_MS);\n\n return () => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n };\n }, [trimmedQuery, chainId]);\n\n return { results, isSearching };\n}\n\n\n","/**\n * Default token list sources for React hooks.\n */\n\nimport type { TokenListSource } from \"@naculus/connect-core\";\nimport {\n ETHEREUM_MAINNET_TOKENS,\n POLYGON_TOKENS,\n OPTIMISM_TOKENS,\n ARBITRUM_TOKENS,\n BASE_TOKENS,\n} from \"@naculus/connect-core\";\n\n/**\n * Get default sources for useTokenList / useTokenSearch hooks.\n * Includes built-in tokens and remote source URLs.\n */\nexport function getDefaultSources(): TokenListSource[] {\n return [\n {\n name: \"built-in\",\n tokens: [\n ...ETHEREUM_MAINNET_TOKENS,\n ...POLYGON_TOKENS,\n ...OPTIMISM_TOKENS,\n ...ARBITRUM_TOKENS,\n ...BASE_TOKENS,\n ],\n enabled: true,\n },\n {\n name: \"uniswap-default\",\n url: \"https://tokens.uniswap.org\",\n enabled: true,\n refreshInterval: 24 * 60 * 60 * 1000,\n },\n ];\n}\n","/**\n * TokenSelector — chain-aware, searchable token selection component.\n *\n * Features:\n * - Loads token list for the given chain\n * - Search by symbol, name, or address\n * - Displays token logo, symbol, name, and decimals\n * - Calls onSelect when a token is chosen\n */\n\nimport React, { useCallback } from \"react\";\nimport type { TokenListEntry } from \"@naculus/connect-core\";\nimport { useTokenList } from \"./useTokenList\";\nimport { useTokenSearch } from \"./useTokenSearch\";\n\nexport interface TokenSelectorProps {\n /** Chain ID in CAIP-2 format (e.g. \"eip155:1\") */\n chainId: string;\n /** Called when a token is selected */\n onSelect: (token: TokenListEntry) => void;\n /** Called to close/dismiss the selector */\n onClose: () => void;\n /** Optional configuration */\n options?: {\n /** Show popular/recommended tokens (default: true) */\n showRecommendations?: boolean;\n /** Custom filter for tokens */\n filter?: (token: TokenListEntry) => boolean;\n };\n}\n\n/**\n * TokenSelector — a dropdown/modal component for selecting tokens.\n *\n * @example\n * <TokenSelector\n * chainId=\"eip155:1\"\n * onSelect={(token) => setSelectedToken(token)}\n * onClose={() => setOpen(false)}\n * />\n */\nexport function TokenSelector({\n chainId,\n onSelect,\n onClose,\n options,\n}: TokenSelectorProps) {\n const [searchQuery, setSearchQuery] = React.useState(\"\");\n\n const {\n tokens: allTokens,\n isLoading,\n error,\n } = useTokenList(chainId);\n\n const { results, isSearching } = useTokenSearch(\n searchQuery,\n searchQuery ? chainId : undefined,\n );\n\n const showRecommendations = options?.showRecommendations ?? true;\n\n // Display tokens: when searching, show results; otherwise show the full list\n const displayTokens = React.useMemo(() => {\n if (searchQuery.trim()) {\n const combined = [...results.exact, ...results.fuzzy].map((m) => m.token);\n return options?.filter\n ? combined.filter(options.filter)\n : combined;\n }\n\n const tokens = allTokens;\n return options?.filter\n ? tokens.filter(options.filter)\n : tokens;\n }, [searchQuery, results, allTokens, options?.filter]);\n\n // Popular tokens for recommendation section\n const popularTokens = React.useMemo(() => {\n if (!showRecommendations || searchQuery.trim()) return [];\n return allTokens.slice(0, 6); // Top 6\n }, [allTokens, showRecommendations, searchQuery]);\n\n const handleSelect = useCallback(\n (token: TokenListEntry) => {\n onSelect(token);\n onClose();\n },\n [onSelect, onClose],\n );\n\n return (\n <div\n style={{\n background: \"hsl(var(--background))\",\n borderRadius: \"12px\",\n padding: \"16px\",\n color: \"hsl(var(--foreground))\",\n minWidth: \"320px\",\n maxWidth: \"400px\",\n fontFamily: \"system-ui, sans-serif\",\n }}\n >\n {/* Header */}\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"12px\",\n }}\n >\n <h3 style={{ margin: 0, fontSize: \"16px\", fontWeight: 600 }}>\n Select Token\n </h3>\n <button type=\"button\"\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n color: \"hsl(var(--muted-foreground))\",\n cursor: \"pointer\",\n fontSize: \"18px\",\n padding: \"4px 8px\",\n }}\n >\n ✕\n </button>\n </div>\n\n {/* Search Input */}\n <input\n type=\"text\"\n placeholder=\"Search token name or paste address\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: \"1px solid #333\",\n background: \"hsl(var(--card))\",\n color: \"hsl(var(--foreground))\",\n fontSize: \"14px\",\n outline: \"none\",\n boxSizing: \"border-box\",\n marginBottom: \"12px\",\n }}\n // biome-ignore lint/a11y/noAutofocus: focus moves into the search field of the selector the user just opened\n autoFocus\n />\n\n {/* Loading / Error States */}\n {isLoading && !isSearching && (\n <div style={{ textAlign: \"center\", padding: \"20px\", color: \"hsl(var(--muted-foreground))\" }}>\n Loading tokens...\n </div>\n )}\n {error && (\n <div\n style={{\n textAlign: \"center\",\n padding: \"12px\",\n color: \"hsl(var(--destructive))\",\n fontSize: \"13px\",\n }}\n >\n Error: {error.message}\n </div>\n )}\n\n {/* Popular / Recommended Section */}\n {showRecommendations && popularTokens.length > 0 && !searchQuery.trim() && (\n <div style={{ marginBottom: \"12px\" }}>\n <div\n style={{\n fontSize: \"11px\",\n color: \"hsl(var(--muted-foreground))\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.5px\",\n marginBottom: \"8px\",\n }}\n >\n Popular\n </div>\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\" }}>\n {popularTokens.map((token) => (\n <button type=\"button\"\n key={`${token.chainId}:${token.address}`}\n onClick={() => handleSelect(token)}\n style={{\n background: \"hsl(var(--card))\",\n border: \"1px solid #333\",\n borderRadius: \"20px\",\n padding: \"6px 14px\",\n color: \"hsl(var(--foreground))\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n }}\n >\n {token.logoURI ? (\n <img\n src={token.logoURI}\n alt=\"\"\n style={{ width: \"16px\", height: \"16px\", borderRadius: \"50%\" }}\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n ) : null}\n {token.symbol}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Search Result Count */}\n {searchQuery.trim() && !isLoading && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"hsl(var(--muted-foreground))\",\n marginBottom: \"8px\",\n }}\n >\n {displayTokens.length > 0 ? (\n <>\n {results.exact.length} exact, {results.fuzzy.length} fuzzy\n {results.hasMore ? \" (more available)\" : \"\"}\n </>\n ) : (\n \"No results found\"\n )}\n </div>\n )}\n\n {/* Token List */}\n <div\n style={{\n maxHeight: \"320px\",\n overflowY: \"auto\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n }}\n >\n {displayTokens.map((token) => (\n <button type=\"button\"\n key={`${token.chainId}:${token.address}`}\n onClick={() => handleSelect(token)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n padding: \"10px 8px\",\n background: \"transparent\",\n border: \"none\",\n borderRadius: \"8px\",\n color: \"hsl(var(--foreground))\",\n cursor: \"pointer\",\n textAlign: \"left\",\n width: \"100%\",\n fontSize: \"14px\",\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.background = \"hsl(var(--card))\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.background = \"transparent\";\n }}\n >\n {/* Logo */}\n <div\n style={{\n width: \"32px\",\n height: \"32px\",\n borderRadius: \"50%\",\n background: \"hsl(var(--border))\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"12px\",\n fontWeight: 600,\n flexShrink: 0,\n overflow: \"hidden\",\n }}\n >\n {token.logoURI ? (\n <img\n src={token.logoURI}\n alt={token.symbol}\n style={{ width: \"100%\", height: \"100%\" }}\n onError={(e) => {\n const img = e.target as HTMLImageElement;\n img.style.display = \"none\";\n (img.parentElement as HTMLElement).textContent =\n token.symbol.slice(0, 2);\n }}\n />\n ) : (\n token.symbol.slice(0, 2)\n )}\n </div>\n\n {/* Token info */}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontWeight: 600,\n fontSize: \"14px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {token.symbol}\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"hsl(var(--muted-foreground))\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {token.name}\n </div>\n </div>\n\n {/* Decimals & Chain Info */}\n <div\n style={{\n fontSize: \"11px\",\n color: \"#666\",\n textAlign: \"right\",\n flexShrink: 0,\n }}\n >\n <div>{token.decimals} decimals</div>\n <div>Chain {token.chainId}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n );\n}\n","'use client';\n\n/**\n * This file was automatically generated by the Stencil React Output Target.\n * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.\n */\n\n/* eslint-disable */\n\nimport type { EventName, StencilReactComponent } from '@stencil/react-output-target/runtime';\nimport { createComponent } from '@stencil/react-output-target/runtime';\nimport React from 'react';\n\nimport { type AppkitAccordionCustomEvent, type AppkitAlertDialogCustomEvent, type AppkitCheckboxCustomEvent, type AppkitCollapsibleCustomEvent, type AppkitConnectButtonCustomEvent, type AppkitDialogCustomEvent, type AppkitDropdownMenuCustomEvent, type AppkitInputCustomEvent, type AppkitPopoverCustomEvent, type AppkitSelectCustomEvent, type AppkitSwitchCustomEvent, type AppkitTabsCustomEvent, type AppkitToggleGroupCustomEvent } from \"@naculus/connect-appkit-wc\";\nimport type { Components } from \"@naculus/connect-appkit-wc/dist/components\";\nimport { AppkitAccordion as AppkitAccordionElement, defineCustomElement as defineAppkitAccordion } from \"@naculus/connect-appkit-wc/dist/components/appkit-accordion.js\";\nimport { AppkitAccountButton as AppkitAccountButtonElement, defineCustomElement as defineAppkitAccountButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-account-button.js\";\nimport { AppkitAlertDialog as AppkitAlertDialogElement, defineCustomElement as defineAppkitAlertDialog } from \"@naculus/connect-appkit-wc/dist/components/appkit-alert-dialog.js\";\nimport { AppkitAvatar as AppkitAvatarElement, defineCustomElement as defineAppkitAvatar } from \"@naculus/connect-appkit-wc/dist/components/appkit-avatar.js\";\nimport { AppkitBadge as AppkitBadgeElement, defineCustomElement as defineAppkitBadge } from \"@naculus/connect-appkit-wc/dist/components/appkit-badge.js\";\nimport { AppkitButton as AppkitButtonElement, defineCustomElement as defineAppkitButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-button.js\";\nimport { AppkitCardContent as AppkitCardContentElement, defineCustomElement as defineAppkitCardContent } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-content.js\";\nimport { AppkitCardDescription as AppkitCardDescriptionElement, defineCustomElement as defineAppkitCardDescription } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-description.js\";\nimport { AppkitCardFooter as AppkitCardFooterElement, defineCustomElement as defineAppkitCardFooter } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-footer.js\";\nimport { AppkitCardHeader as AppkitCardHeaderElement, defineCustomElement as defineAppkitCardHeader } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-header.js\";\nimport { AppkitCardTitle as AppkitCardTitleElement, defineCustomElement as defineAppkitCardTitle } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-title.js\";\nimport { AppkitCard as AppkitCardElement, defineCustomElement as defineAppkitCard } from \"@naculus/connect-appkit-wc/dist/components/appkit-card.js\";\nimport { AppkitCheckbox as AppkitCheckboxElement, defineCustomElement as defineAppkitCheckbox } from \"@naculus/connect-appkit-wc/dist/components/appkit-checkbox.js\";\nimport { AppkitCollapsible as AppkitCollapsibleElement, defineCustomElement as defineAppkitCollapsible } from \"@naculus/connect-appkit-wc/dist/components/appkit-collapsible.js\";\nimport { AppkitConnectButton as AppkitConnectButtonElement, defineCustomElement as defineAppkitConnectButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-connect-button.js\";\nimport { AppkitDialog as AppkitDialogElement, defineCustomElement as defineAppkitDialog } from \"@naculus/connect-appkit-wc/dist/components/appkit-dialog.js\";\nimport { AppkitDropdownMenu as AppkitDropdownMenuElement, defineCustomElement as defineAppkitDropdownMenu } from \"@naculus/connect-appkit-wc/dist/components/appkit-dropdown-menu.js\";\nimport { AppkitInput as AppkitInputElement, defineCustomElement as defineAppkitInput } from \"@naculus/connect-appkit-wc/dist/components/appkit-input.js\";\nimport { AppkitPopover as AppkitPopoverElement, defineCustomElement as defineAppkitPopover } from \"@naculus/connect-appkit-wc/dist/components/appkit-popover.js\";\nimport { AppkitProgress as AppkitProgressElement, defineCustomElement as defineAppkitProgress } from \"@naculus/connect-appkit-wc/dist/components/appkit-progress.js\";\nimport { AppkitScrollArea as AppkitScrollAreaElement, defineCustomElement as defineAppkitScrollArea } from \"@naculus/connect-appkit-wc/dist/components/appkit-scroll-area.js\";\nimport { AppkitSelect as AppkitSelectElement, defineCustomElement as defineAppkitSelect } from \"@naculus/connect-appkit-wc/dist/components/appkit-select.js\";\nimport { AppkitSeparator as AppkitSeparatorElement, defineCustomElement as defineAppkitSeparator } from \"@naculus/connect-appkit-wc/dist/components/appkit-separator.js\";\nimport { AppkitSkeleton as AppkitSkeletonElement, defineCustomElement as defineAppkitSkeleton } from \"@naculus/connect-appkit-wc/dist/components/appkit-skeleton.js\";\nimport { AppkitSwitch as AppkitSwitchElement, defineCustomElement as defineAppkitSwitch } from \"@naculus/connect-appkit-wc/dist/components/appkit-switch.js\";\nimport { AppkitTabs as AppkitTabsElement, defineCustomElement as defineAppkitTabs } from \"@naculus/connect-appkit-wc/dist/components/appkit-tabs.js\";\nimport { AppkitToggleGroup as AppkitToggleGroupElement, defineCustomElement as defineAppkitToggleGroup } from \"@naculus/connect-appkit-wc/dist/components/appkit-toggle-group.js\";\nimport { AppkitTooltip as AppkitTooltipElement, defineCustomElement as defineAppkitTooltip } from \"@naculus/connect-appkit-wc/dist/components/appkit-tooltip.js\";\n\nexport type AppkitAccordionEvents = { onAppkitToggle: EventName<AppkitAccordionCustomEvent<boolean>> };\n\nexport const AppkitAccordion: StencilReactComponent<AppkitAccordionElement, AppkitAccordionEvents, Components.AppkitAccordion> = /*@__PURE__*/ createComponent<AppkitAccordionElement, AppkitAccordionEvents, Components.AppkitAccordion>({\n tagName: 'appkit-accordion',\n elementClass: AppkitAccordionElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitToggle: 'appkitToggle' } as AppkitAccordionEvents,\n defineCustomElement: defineAppkitAccordion\n});\n\nexport type AppkitAccountButtonEvents = NonNullable<unknown>;\n\nexport const AppkitAccountButton: StencilReactComponent<AppkitAccountButtonElement, AppkitAccountButtonEvents, Components.AppkitAccountButton> = /*@__PURE__*/ createComponent<AppkitAccountButtonElement, AppkitAccountButtonEvents, Components.AppkitAccountButton>({\n tagName: 'appkit-account-button',\n elementClass: AppkitAccountButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitAccountButtonEvents,\n defineCustomElement: defineAppkitAccountButton\n});\n\nexport type AppkitAlertDialogEvents = {\n onAppkitClose: EventName<AppkitAlertDialogCustomEvent<void>>,\n onAppkitOpenChange: EventName<AppkitAlertDialogCustomEvent<boolean>>\n};\n\nexport const AppkitAlertDialog: StencilReactComponent<AppkitAlertDialogElement, AppkitAlertDialogEvents, Components.AppkitAlertDialog> = /*@__PURE__*/ createComponent<AppkitAlertDialogElement, AppkitAlertDialogEvents, Components.AppkitAlertDialog>({\n tagName: 'appkit-alert-dialog',\n elementClass: AppkitAlertDialogElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitClose: 'appkitClose',\n onAppkitOpenChange: 'appkitOpenChange'\n } as AppkitAlertDialogEvents,\n defineCustomElement: defineAppkitAlertDialog\n});\n\nexport type AppkitAvatarEvents = NonNullable<unknown>;\n\nexport const AppkitAvatar: StencilReactComponent<AppkitAvatarElement, AppkitAvatarEvents, Components.AppkitAvatar> = /*@__PURE__*/ createComponent<AppkitAvatarElement, AppkitAvatarEvents, Components.AppkitAvatar>({\n tagName: 'appkit-avatar',\n elementClass: AppkitAvatarElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitAvatarEvents,\n defineCustomElement: defineAppkitAvatar\n});\n\nexport type AppkitBadgeEvents = NonNullable<unknown>;\n\nexport const AppkitBadge: StencilReactComponent<AppkitBadgeElement, AppkitBadgeEvents, Components.AppkitBadge> = /*@__PURE__*/ createComponent<AppkitBadgeElement, AppkitBadgeEvents, Components.AppkitBadge>({\n tagName: 'appkit-badge',\n elementClass: AppkitBadgeElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitBadgeEvents,\n defineCustomElement: defineAppkitBadge\n});\n\nexport type AppkitButtonEvents = NonNullable<unknown>;\n\nexport const AppkitButton: StencilReactComponent<AppkitButtonElement, AppkitButtonEvents, Components.AppkitButton> = /*@__PURE__*/ createComponent<AppkitButtonElement, AppkitButtonEvents, Components.AppkitButton>({\n tagName: 'appkit-button',\n elementClass: AppkitButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitButtonEvents,\n defineCustomElement: defineAppkitButton\n});\n\nexport type AppkitCardEvents = NonNullable<unknown>;\n\nexport const AppkitCard: StencilReactComponent<AppkitCardElement, AppkitCardEvents, Components.AppkitCard> = /*@__PURE__*/ createComponent<AppkitCardElement, AppkitCardEvents, Components.AppkitCard>({\n tagName: 'appkit-card',\n elementClass: AppkitCardElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardEvents,\n defineCustomElement: defineAppkitCard\n});\n\nexport type AppkitCardContentEvents = NonNullable<unknown>;\n\nexport const AppkitCardContent: StencilReactComponent<AppkitCardContentElement, AppkitCardContentEvents, Components.AppkitCardContent> = /*@__PURE__*/ createComponent<AppkitCardContentElement, AppkitCardContentEvents, Components.AppkitCardContent>({\n tagName: 'appkit-card-content',\n elementClass: AppkitCardContentElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardContentEvents,\n defineCustomElement: defineAppkitCardContent\n});\n\nexport type AppkitCardDescriptionEvents = NonNullable<unknown>;\n\nexport const AppkitCardDescription: StencilReactComponent<AppkitCardDescriptionElement, AppkitCardDescriptionEvents, Components.AppkitCardDescription> = /*@__PURE__*/ createComponent<AppkitCardDescriptionElement, AppkitCardDescriptionEvents, Components.AppkitCardDescription>({\n tagName: 'appkit-card-description',\n elementClass: AppkitCardDescriptionElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardDescriptionEvents,\n defineCustomElement: defineAppkitCardDescription\n});\n\nexport type AppkitCardFooterEvents = NonNullable<unknown>;\n\nexport const AppkitCardFooter: StencilReactComponent<AppkitCardFooterElement, AppkitCardFooterEvents, Components.AppkitCardFooter> = /*@__PURE__*/ createComponent<AppkitCardFooterElement, AppkitCardFooterEvents, Components.AppkitCardFooter>({\n tagName: 'appkit-card-footer',\n elementClass: AppkitCardFooterElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardFooterEvents,\n defineCustomElement: defineAppkitCardFooter\n});\n\nexport type AppkitCardHeaderEvents = NonNullable<unknown>;\n\nexport const AppkitCardHeader: StencilReactComponent<AppkitCardHeaderElement, AppkitCardHeaderEvents, Components.AppkitCardHeader> = /*@__PURE__*/ createComponent<AppkitCardHeaderElement, AppkitCardHeaderEvents, Components.AppkitCardHeader>({\n tagName: 'appkit-card-header',\n elementClass: AppkitCardHeaderElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardHeaderEvents,\n defineCustomElement: defineAppkitCardHeader\n});\n\nexport type AppkitCardTitleEvents = NonNullable<unknown>;\n\nexport const AppkitCardTitle: StencilReactComponent<AppkitCardTitleElement, AppkitCardTitleEvents, Components.AppkitCardTitle> = /*@__PURE__*/ createComponent<AppkitCardTitleElement, AppkitCardTitleEvents, Components.AppkitCardTitle>({\n tagName: 'appkit-card-title',\n elementClass: AppkitCardTitleElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardTitleEvents,\n defineCustomElement: defineAppkitCardTitle\n});\n\nexport type AppkitCheckboxEvents = { onAppkitChange: EventName<AppkitCheckboxCustomEvent<boolean>> };\n\nexport const AppkitCheckbox: StencilReactComponent<AppkitCheckboxElement, AppkitCheckboxEvents, Components.AppkitCheckbox> = /*@__PURE__*/ createComponent<AppkitCheckboxElement, AppkitCheckboxEvents, Components.AppkitCheckbox>({\n tagName: 'appkit-checkbox',\n elementClass: AppkitCheckboxElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitCheckboxEvents,\n defineCustomElement: defineAppkitCheckbox\n});\n\nexport type AppkitCollapsibleEvents = { onAppkitToggle: EventName<AppkitCollapsibleCustomEvent<boolean>> };\n\nexport const AppkitCollapsible: StencilReactComponent<AppkitCollapsibleElement, AppkitCollapsibleEvents, Components.AppkitCollapsible> = /*@__PURE__*/ createComponent<AppkitCollapsibleElement, AppkitCollapsibleEvents, Components.AppkitCollapsible>({\n tagName: 'appkit-collapsible',\n elementClass: AppkitCollapsibleElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitToggle: 'appkitToggle' } as AppkitCollapsibleEvents,\n defineCustomElement: defineAppkitCollapsible\n});\n\nexport type AppkitConnectButtonEvents = {\n onAppkitConnect: EventName<AppkitConnectButtonCustomEvent<{ kind: string; walletId?: string }>>,\n onAppkitDisconnect: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitStartPairing: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitRetry: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitCancelPairing: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitMobileDeepLink: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitCopyAddress: EventName<AppkitConnectButtonCustomEvent<string>>\n};\n\nexport const AppkitConnectButton: StencilReactComponent<AppkitConnectButtonElement, AppkitConnectButtonEvents, Components.AppkitConnectButton> = /*@__PURE__*/ createComponent<AppkitConnectButtonElement, AppkitConnectButtonEvents, Components.AppkitConnectButton>({\n tagName: 'appkit-connect-button',\n elementClass: AppkitConnectButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitConnect: 'appkitConnect',\n onAppkitDisconnect: 'appkitDisconnect',\n onAppkitStartPairing: 'appkitStartPairing',\n onAppkitRetry: 'appkitRetry',\n onAppkitCancelPairing: 'appkitCancelPairing',\n onAppkitMobileDeepLink: 'appkitMobileDeepLink',\n onAppkitCopyAddress: 'appkitCopyAddress'\n } as AppkitConnectButtonEvents,\n defineCustomElement: defineAppkitConnectButton\n});\n\nexport type AppkitDialogEvents = {\n onAppkitClose: EventName<AppkitDialogCustomEvent<void>>,\n onAppkitOpenChange: EventName<AppkitDialogCustomEvent<boolean>>\n};\n\nexport const AppkitDialog: StencilReactComponent<AppkitDialogElement, AppkitDialogEvents, Components.AppkitDialog> = /*@__PURE__*/ createComponent<AppkitDialogElement, AppkitDialogEvents, Components.AppkitDialog>({\n tagName: 'appkit-dialog',\n elementClass: AppkitDialogElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitClose: 'appkitClose',\n onAppkitOpenChange: 'appkitOpenChange'\n } as AppkitDialogEvents,\n defineCustomElement: defineAppkitDialog\n});\n\nexport type AppkitDropdownMenuEvents = { onAppkitSelect: EventName<AppkitDropdownMenuCustomEvent<string>> };\n\nexport const AppkitDropdownMenu: StencilReactComponent<AppkitDropdownMenuElement, AppkitDropdownMenuEvents, Components.AppkitDropdownMenu> = /*@__PURE__*/ createComponent<AppkitDropdownMenuElement, AppkitDropdownMenuEvents, Components.AppkitDropdownMenu>({\n tagName: 'appkit-dropdown-menu',\n elementClass: AppkitDropdownMenuElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitSelect: 'appkitSelect' } as AppkitDropdownMenuEvents,\n defineCustomElement: defineAppkitDropdownMenu\n});\n\nexport type AppkitInputEvents = { onAppkitChange: EventName<AppkitInputCustomEvent<string>> };\n\nexport const AppkitInput: StencilReactComponent<AppkitInputElement, AppkitInputEvents, Components.AppkitInput> = /*@__PURE__*/ createComponent<AppkitInputElement, AppkitInputEvents, Components.AppkitInput>({\n tagName: 'appkit-input',\n elementClass: AppkitInputElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitInputEvents,\n defineCustomElement: defineAppkitInput\n});\n\nexport type AppkitPopoverEvents = { onAppkitOpenChange: EventName<AppkitPopoverCustomEvent<boolean>> };\n\nexport const AppkitPopover: StencilReactComponent<AppkitPopoverElement, AppkitPopoverEvents, Components.AppkitPopover> = /*@__PURE__*/ createComponent<AppkitPopoverElement, AppkitPopoverEvents, Components.AppkitPopover>({\n tagName: 'appkit-popover',\n elementClass: AppkitPopoverElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitOpenChange: 'appkitOpenChange' } as AppkitPopoverEvents,\n defineCustomElement: defineAppkitPopover\n});\n\nexport type AppkitProgressEvents = NonNullable<unknown>;\n\nexport const AppkitProgress: StencilReactComponent<AppkitProgressElement, AppkitProgressEvents, Components.AppkitProgress> = /*@__PURE__*/ createComponent<AppkitProgressElement, AppkitProgressEvents, Components.AppkitProgress>({\n tagName: 'appkit-progress',\n elementClass: AppkitProgressElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitProgressEvents,\n defineCustomElement: defineAppkitProgress\n});\n\nexport type AppkitScrollAreaEvents = NonNullable<unknown>;\n\nexport const AppkitScrollArea: StencilReactComponent<AppkitScrollAreaElement, AppkitScrollAreaEvents, Components.AppkitScrollArea> = /*@__PURE__*/ createComponent<AppkitScrollAreaElement, AppkitScrollAreaEvents, Components.AppkitScrollArea>({\n tagName: 'appkit-scroll-area',\n elementClass: AppkitScrollAreaElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitScrollAreaEvents,\n defineCustomElement: defineAppkitScrollArea\n});\n\nexport type AppkitSelectEvents = { onAppkitChange: EventName<AppkitSelectCustomEvent<string>> };\n\nexport const AppkitSelect: StencilReactComponent<AppkitSelectElement, AppkitSelectEvents, Components.AppkitSelect> = /*@__PURE__*/ createComponent<AppkitSelectElement, AppkitSelectEvents, Components.AppkitSelect>({\n tagName: 'appkit-select',\n elementClass: AppkitSelectElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitSelectEvents,\n defineCustomElement: defineAppkitSelect\n});\n\nexport type AppkitSeparatorEvents = NonNullable<unknown>;\n\nexport const AppkitSeparator: StencilReactComponent<AppkitSeparatorElement, AppkitSeparatorEvents, Components.AppkitSeparator> = /*@__PURE__*/ createComponent<AppkitSeparatorElement, AppkitSeparatorEvents, Components.AppkitSeparator>({\n tagName: 'appkit-separator',\n elementClass: AppkitSeparatorElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitSeparatorEvents,\n defineCustomElement: defineAppkitSeparator\n});\n\nexport type AppkitSkeletonEvents = NonNullable<unknown>;\n\nexport const AppkitSkeleton: StencilReactComponent<AppkitSkeletonElement, AppkitSkeletonEvents, Components.AppkitSkeleton> = /*@__PURE__*/ createComponent<AppkitSkeletonElement, AppkitSkeletonEvents, Components.AppkitSkeleton>({\n tagName: 'appkit-skeleton',\n elementClass: AppkitSkeletonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitSkeletonEvents,\n defineCustomElement: defineAppkitSkeleton\n});\n\nexport type AppkitSwitchEvents = { onAppkitChange: EventName<AppkitSwitchCustomEvent<boolean>> };\n\nexport const AppkitSwitch: StencilReactComponent<AppkitSwitchElement, AppkitSwitchEvents, Components.AppkitSwitch> = /*@__PURE__*/ createComponent<AppkitSwitchElement, AppkitSwitchEvents, Components.AppkitSwitch>({\n tagName: 'appkit-switch',\n elementClass: AppkitSwitchElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitSwitchEvents,\n defineCustomElement: defineAppkitSwitch\n});\n\nexport type AppkitTabsEvents = { onAppkitTabChange: EventName<AppkitTabsCustomEvent<string>> };\n\nexport const AppkitTabs: StencilReactComponent<AppkitTabsElement, AppkitTabsEvents, Components.AppkitTabs> = /*@__PURE__*/ createComponent<AppkitTabsElement, AppkitTabsEvents, Components.AppkitTabs>({\n tagName: 'appkit-tabs',\n elementClass: AppkitTabsElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitTabChange: 'appkitTabChange' } as AppkitTabsEvents,\n defineCustomElement: defineAppkitTabs\n});\n\nexport type AppkitToggleGroupEvents = { onAppkitChange: EventName<AppkitToggleGroupCustomEvent<string[]>> };\n\nexport const AppkitToggleGroup: StencilReactComponent<AppkitToggleGroupElement, AppkitToggleGroupEvents, Components.AppkitToggleGroup> = /*@__PURE__*/ createComponent<AppkitToggleGroupElement, AppkitToggleGroupEvents, Components.AppkitToggleGroup>({\n tagName: 'appkit-toggle-group',\n elementClass: AppkitToggleGroupElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitToggleGroupEvents,\n defineCustomElement: defineAppkitToggleGroup\n});\n\nexport type AppkitTooltipEvents = NonNullable<unknown>;\n\nexport const AppkitTooltip: StencilReactComponent<AppkitTooltipElement, AppkitTooltipEvents, Components.AppkitTooltip> = /*@__PURE__*/ createComponent<AppkitTooltipElement, AppkitTooltipEvents, Components.AppkitTooltip>({\n tagName: 'appkit-tooltip',\n elementClass: AppkitTooltipElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitTooltipEvents,\n defineCustomElement: defineAppkitTooltip\n});\n"],"mappings":"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","names":["formatSol","getLatestBlockhash","getSignatureStatus","getSolanaBalance","LAMPORTS_PER_SOL","PassphraseCancelledError","PassphraseGate","parseSol","SolanaRpcError","compareCostsKey","useCallback","useEffect","useRef","useState","useCompareCosts","input","compareCostsFn","operation","chains","options","comparisons","setComparisons","loading","setLoading","error","setError","mountedRef","generationRef","inputKey","fetchComparisons","generation","result","err","refresh","toExecuteRouteError","validateRouteRecipient","useCallback","useEffect","useRef","useState","useExecuteRoute","executeRouteFn","executing","setExecuting","result","setResult","error","setError","mountedRef","inFlightRef","execute","quote","recipient","options","recipientError","execResult","err","reset","isQuotableInput","useCallback","useEffect","useRef","useState","useRouteQuote","input","getQuoteFn","fromChain","toChain","fromToken","toToken","amount","options","quotes","setQuotes","loading","setLoading","error","setError","debounceTimer","mountedRef","fetchQuotes","result","err","refresh","clear","logger","WalletError","eip6963Connector","PassphraseGate","createWalletConnectConnector","clientInstance","createClient","config","clientRef","connector","_embeddedConnector","embeddedInit","_passkeysConnector","passkeysInit","_passphraseGate","mod","embeddedConfig","salt","passkeys","err","_solanaConnector","solanaInit","conn","wallet","info","provider","client","walletId","session","input","handler","noop","calls","chainId","options","bundleHash","connectors","getClient","clearClient","isEvmAddress","parseCaip10","useMemo","createConnectorManager","createSessionManager","LocalStorageSessionStorage","logger","WalletError","eip6963Connector","createContext","useCallback","useContext","useEffect","useMemo","useReducer","useRef","logger","issueNonce","parseSiwxMessage","selectSiwxAccount","session","chainId","namespace","candidate","caip10","resolveSiwxChainId","session","runSiwxFlow","input","siwx","signMessage","chainId","account","selectSiwxAccount","address","message","parsed","parseSiwxMessage","issueNonce","signature","cause","error","logger","initialWeb3State","web3Reducer","withRetry","withTimeout","resolveChain","CHAINS","DEFAULT_RPC_URLS","eip155Reference","getRpcUrl","STATIC_TESTNETS","toWalletChain","chainId","info","caip2Id","buildDefaultChains","registryChains","chainIds","a","b","id","chain","testnet","reference","DEFAULT_EVM_CHAINS","getChainById","chains","getDefaultChains","jsx","Web3Context","createContext","Web3ConnectProvider","children","config","autoConnect","state","dispatch","useReducer","web3Reducer","initialWeb3State","chains","useMemo","getDefaultChains","connectionTimeout","maxRetries","storage","LocalStorageSessionStorage","client","createClient","sessionManagerRef","useRef","pendingExternalChainSyncRef","sessionManager","cm","createConnectorManager","connector","eip6963Connector","defaultRpcUrls","defaultCurrencies","chain","caip2Id","sm","createSessionManager","useEffect","onConnected","payload","walletSession","accounts","ns","onDisconnected","onChainChanged","onScopeChanged","onRevoked","handler","syncSessionManagerConnectors","useCallback","attachSession","session","candidate","chainId","updateStateFromSession","evmChain","solChain","xrplChain","activeClient","syncExternalChain","syncPromise","error","logger","runSiwx","outcome","runSiwxFlow","s","args","connect","withTimeout","smError","message","connectEmbedded","connectPasskeys","disconnect","connectInjected","walletId","startPairing","cancelPairing","completePairing","runSiwxOnReconnect","siwx","err","reconnect","savedSession","withRetry","switchChain","WalletError","clearError","value","useWeb3","context","useContext","useAccount","accounts","isConnected","useWeb3","accountData","useMemo","address","parsed","parseCaip10","isEvmAddress","evmAccount","a","listAuthorizations","revokeListedAuthorization","useCallback","useEffect","useRef","useState","useAuthorizations","managers","managersRef","generationRef","mountedRef","entries","setEntries","loading","setLoading","error","setError","refresh","own","next","cause","revoke","entry","result","normalized","chainNumber","resolveChain","toViemChain","useState","useEffect","useCallback","useMemo","useRef","createPublicClient","http","formatEther","getNativeTokenPriceUsd","useBalance","options","evmAccount","isConnected","useAccount","chainId","chains","useWeb3","balance","setBalance","useState","isLoading","setIsLoading","error","setError","usdPrice","setUsdPrice","refreshInterval","intervalRef","useRef","currentChain","useMemo","resolveChain","evmChainNumber","chainNumber","viemChain","toViemChain","tokenSymbol","client","setClient","useEffect","publicClient","fetchBalance","useCallback","address_","balanceResult","price","err","formatted","usdValue","numericBalance","totalUsd","atomicSupportFor","normalizeCapabilities","selectChainCapabilities","useCallback","useEffect","useRef","useState","resolveClient","client","getClient","useCapabilities","client","session","chainId","useWeb3","capabilities","setCapabilities","useState","isFetching","setIsFetching","error","setError","generationRef","useRef","refetch","useCallback","generation","activeClient","resolveClient","raw","normalizeCapabilities","err","useEffect","selectChainCapabilities","atomicSupportFor","useMemo","chainsForNamespace","describeChain","resolveChain","useChain","chainId","session","switchChain","chains","useWeb3","currentChain","useMemo","resolveChain","chainInfo","describeChain","availableChains","chainsForNamespace","useCallback","useState","WalletError","useConnect","connect","status","useWeb3","isLoading","setIsLoading","useState","error","setError","useCallback","err","errorMessage","bareEvmAddress","delegateAccount","eip155Reference","REVOKE_DELEGATE","WalletError","useCallback","useEffect","useRef","useState","chainNumber","toViemChain","useMemo","createPublicClient","http","createWalletClient","useViemClient","evmAccount","isConnected","useAccount","currentChain","chains","useChain","evmChainNumber","chainNumber","viemChain","useMemo","toViemChain","publicClient","createPublicClient","http","walletClient","address","createWalletClient","useDelegate","options","evmAccount","useAccount","session","chainId","client","useWeb3","publicClient","useViemClient","result","setResult","useState","isPending","setIsPending","error","setError","requestIdRef","useRef","inFlightRef","useEffect","run","useCallback","target","allowlist","fail","nextError","account","bareEvmAddress","WalletError","eip155Reference","connector","resolveClient","requestId","sent","delegateAccount","address","blockTag","err","delegate","revoke","REVOKE_DELEGATE","reset","applySettlementVerification","DEFAULT_VERIFY_RETRY","describePayment","useCallback","useEffect","useRef","useState","usePaymentFetch","pay","options","inFlight","setInFlight","lastPayment","setLastPayment","error","setError","generationRef","epochRef","payRef","optionsRef","verificationRef","payFetch","input","init","own","epoch","n","result","payment","verify","verification","retry","outcome","attempt","resolve","cause","current","normalized","reset","createX402WalletSigner","findX402Provider","eip6963Connector","useMemo","useX402Signer","session","accounts","chainId","client","switchChain","useWeb3","accountKey","useMemo","provider","findX402Provider","eip6963Connector","createX402WalletSigner","readCurrentMppSessionChannel","readMppRecoveryChannelId","readMppSessionReceipt","useCallback","useEffect","useMemo","useRef","useState","normalizeError","cause","useMppSession","session","inFlight","setInFlight","pending","setPending","channel","setChannel","lastReceipt","setLastReceipt","recoveryChannelId","setRecoveryChannelId","error","setError","generationRef","epochRef","mountedRef","sessionRef","run","operation","publish","clearsRecovery","own","epoch","invokedSession","count","result","currentChannel","normalized","recovery","fetch","input","init","current","receipt","close","forceClose","add","units","reset","meter","createSolanaSessionKeyFlow","useCallback","useEffect","useMemo","useRef","useState","unavailable","useSolanaSessionKey","deps","keys","setKeys","inFlight","setInFlight","error","setError","generationRef","manager","rpc","owner","flow","run","action","fallback","own","n","cause","normalized","next","refresh","create","scope","revoke","id","readDelegation","UNKNOWN_DELEGATION","useCallback","useEffect","useRef","useState","useDelegation","publicClient","useViemClient","evmAccount","useAccount","status","setStatus","useState","UNKNOWN_DELEGATION","isFetching","setIsFetching","error","setError","generationRef","useRef","address","refetch","useCallback","generation","code","readDelegation","err","useEffect","bareEvmAddress","createDelegationPolicyFlow","isVerifiablePolicy","useCallback","useEffect","useMemo","useState","recoverMessageAddress","planExecution","WalletError","useCallback","useState","errorMessage","chooseExecutionStrategy","getAccountCapabilities","WalletError","useCallback","useState","WalletError","extractTransactionHash","result","candidate","useSendCalls","session","chainId","client","useWeb3","status","setStatus","useState","error","setError","batchHash","setBatchHash","callsStatus","setCallsStatus","execution","setExecution","sendCalls","useCallback","calls","options","err","WalletError","activeClient","resolveClient","targetChain","strategy","chooseExecutionStrategy","getAccountCapabilities","result","lastHash","i","call","extractTransactionHash","errorMessage","getCallsStatus","hash","bundleHash","showCallsStatus","reset","useExecuteCalls","options","current","atomic","useCapabilities","delegated","delegate","useDelegation","sendCalls","useSendCalls","isExecuting","setIsExecuting","useState","error","setError","lastRoute","setLastRoute","defaultAtomicity","defaultSponsorship","paymasterService","userOperation","userOperationSponsored","walletPaymasterAvailable","preview","useCallback","callCount","atomicity","plan","planExecution","sponsorshipRefused","delegationNote","needsUserOperation","execute","calls","chosen","WalletError","err","e","checkSessionKeyRailGrant","getSharedSessionKeyManager","resetSharedSessionKeyManager","WalletError","useCallback","useEffect","useRef","useState","getSessionKeyManagerForHooks","config","getSharedSessionKeyManager","useSessionKeys","config","session","useWeb3","sessions","setSessions","useState","loading","setLoading","error","setError","mountedRef","useRef","clearError","useCallback","manager","getSessionKeyManagerForHooks","storageAvailable","refresh","keys","err","useEffect","activeSessions","s","checkSessionKeyRailGrant","useCreateSessionKey","lastCreated","setLastCreated","isCreating","setIsCreating","scope","signerAddress","WalletError","resolvedSigner","info","errorObj","useRevokeSession","isRevoking","setIsRevoking","sessionId","useSendWithSession","isBusy","setIsBusy","signWithSession","messageHash","tx","checkScope","resetSessionKeyManager","resetSharedSessionKeyManager","useState","useCallback","WalletError","useSignMessage","session","chainId","client","useWeb3","isLoading","setIsLoading","useState","error","setError","useCallback","message","err","WalletError","address","activeClient","resolveClient","errorMessage","buildDelegationPolicyMessage","useDelegationPolicy","options","evmAccount","useAccount","signer","bareEvmAddress","delegation","useDelegation","execution","useExecuteCalls","signMessage","useSignMessage","sessionKeys","useSessionKeys","manager","getSessionKeyManagerForHooks","isBusy","setIsBusy","useState","error","setError","verifiedPolicyIds","setVerifiedPolicyIds","isVerifying","setIsVerifying","policyOrigin","encryptionKeyConfigured","sponsorship","refresh","storageAvailable","preview","delegated","delegate","flow","useMemo","createDelegationPolicyFlow","message","signature","signerAddress","recoverMessageAddress","useEffect","cancelled","candidates","isVerifiablePolicy","policy","results","verified","policyId","cause","clearError","useCallback","track","step","fallback","next","createPolicy","scope","revokePolicy","executePolicy","tx","activePolicies","useCallback","useRef","useState","useDisconnect","disconnect","status","useWeb3","isLoading","setIsLoading","useState","error","setError","mountedRef","useRef","useCallback","err","WalletError","useCallback","useEffect","useRef","useState","toWalletView","data","activeNamespace","accounts","namespace","address","derivationPath","account","useEmbeddedWallet","providerConnectEmbedded","client","useWeb3","wallet","setWallet","useState","seedPhraseRef","useRef","storageSecurityLevelRef","restoreErroredRef","reportRef","backupPending","setBackupPending","isBusy","setIsBusy","error","setError","clearError","getSeedPhrase","useCallback","phrase","getEmbeddedConnector","activeClient","resolveClient","WalletError","getPrivateKey","getReadyEmbeddedConnector","connector","getPassphraseGate","forgetOnDecryptionFailure","err","restoreWallet","restored","useEffect","cancelled","retryTimer","handleConnectEmbedded","loaded","w","w2","handleGenerateWallet","handleImportFromMnemonic","mnemonic","handleImportFromPrivateKey","pk","handleWipe","handleSetActiveNamespace","next","handleBackfillAccounts","added","handleConfirmBackup","level","json","chainNumber","useState","useCallback","useEffect","useRef","useMemo","WalletError","useCallback","useEffect","useLayoutEffect","useMemo","useRef","tokenChainMismatch","contextKey","options","useERC20Context","token","chainId","address","key","identity","latestKey","mounted","isCurrent","assertCurrent","mismatch","ERC20_MIN_ABI","formatUnits","useERC20Allowance","options","publicClient","useViemClient","currentChain","useChain","identity","isCurrent","assertCurrent","useERC20Context","chainNumber","read","setRead","useState","allowanceRaw","isFetching","error","intervalRef","useRef","generationRef","fetchAllowance","useCallback","generation","stillCurrent","raw","err","useEffect","e","useMemo","decimals","chainNumber","createDecimalsCache","encodeErc20Approve","readDecimals","writeDecimals","ERC20_MIN_ABI","formatUnits","parseUnits","WalletError","useCallback","useRef","useState","WalletError","useCallback","useState","useSendTransaction","session","chainId","client","useWeb3","status","setStatus","useState","error","setError","sendTransaction","useCallback","transaction","err","WalletError","evmAccount","account","txWithFrom","activeClient","resolveClient","result","hash","extractTransactionHash","errorMessage","reset","toBareAddress","addr","MAX_UINT256","useERC20Approve","options","publicClient","walletClient","useViemClient","evmAccount","isConnected","useAccount","currentChain","useChain","session","client","useWeb3","sendTransaction","isSending","sendTxError","reset","useSendTransaction","localError","setLocalError","useState","identity","isCurrent","assertCurrent","useERC20Context","chainNumber","read","setRead","allowanceRaw","isFetchingAllowance","decimalsRef","useRef","createDecimalsCache","allowanceGenerationRef","error","ownerAddress","fetchAllowance","useCallback","generation","stillCurrent","raw","ERC20_MIN_ABI","err","allowance","decimals","readDecimals","formatUnits","doApprove","rawAmount","WalletError","data","encodeErc20Approve","activeClient","resolveClient","txHash","request","approveAmount","amount","writeDecimals","parseUnits","approveMaxAmount","checkAllowance","required","current","requiredRaw","chainNumber","createDecimalsCache","encodeErc20Transfer","readDecimals","writeDecimals","ERC20_MIN_ABI","parseUnits","WalletError","useCallback","useRef","useState","toBareAddress","addr","useERC20Transfer","options","publicClient","walletClient","useViemClient","evmAccount","isConnected","useAccount","currentChain","useChain","session","client","useWeb3","sendTransaction","isSending","sendTxError","reset","useSendTransaction","localError","setLocalError","useState","isCurrent","assertCurrent","useERC20Context","chainNumber","decimalsRef","useRef","createDecimalsCache","error","useCallback","to","amount","err","WalletError","address","decimals","readDecimals","ERC20_MIN_ABI","writeDecimals","rawAmount","parseUnits","data","encodeErc20Transfer","activeClient","resolveClient","request","chainNumber","encodeErc20Transfer","parseUnits","useMemo","simulateTransactionPreview","useCallback","useEffect","useRef","useState","useTransactionSimulation","tx","chainId","useWeb3","evmAccount","useAccount","currentChain","useChain","publicClient","useViemClient","result","setResult","useState","isSimulating","setIsSimulating","error","setError","debounceRef","useRef","simulate","useCallback","simResult","simulateTransactionPreview","cause","err","useEffect","reset","useERC20TransferSimulation","options","evmAccount","isConnected","useAccount","currentChain","useChain","chainId","chainNumber","tx","useMemo","decimals","rawAmount","parseUnits","data","encodeErc20Transfer","sim","useTransactionSimulation","useState","useCallback","useRef","useState","useEffect","useCallback","useRef","createContext","useContext","TxMonitorContext","useTxMonitorProvider","useTxMonitor","hash","chainId","monitor","ctxMonitor","effectiveMonitor","entry","setEntry","isLoading","setIsLoading","isWatching","setIsWatching","error","setError","prevHashRef","refresh","current","err","stopWatching","cancelled","initial","onStatusChange","updated","status","useLastTx","monitor","ctxMonitor","useTxMonitorProvider","effectiveMonitor","lastTx","setLastTx","useState","lastConfirmedTx","setLastConfirmedTx","lastFailedTx","setLastFailedTx","lastTxRef","useRef","confirmedHandlerRef","failedHandlerRef","entry","clear","useCallback","useCallback","useCallback","useEffect","useMemo","useRef","useState","getResolver","useNameLookup","input","skip","resolverConfig","scope","query","data","setData","isLoading","setIsLoading","error","setError","generationRef","mountedRef","resolver","run","trimmed","generation","result","err","useLookupAddress","address","options","query","useCallback","resolver","input","scope","useNameLookup","useState","useCallback","useMemo","useEffect","useRef","addInAppNotification","channelsUpdate","clearOneInAppNotification","createNotificationSettingsStorage","DEFAULT_NOTIFICATION_SETTINGS","loadNotificationSettings","mutedChainSettings","saveNotificationSettings","replayNotificationSettings","updateNotificationSettings","InAppChannel","useNotification","options","channelRef","channel","notifications","setNotifications","settings","setSettingsState","pendingRef","storage","settle","saved","pending","next","item","prev","unreadCount","n","clear","clearOne","id","markAsRead","markAllAsRead","addNotification","applySettings","compute","updateSettings","update","setChannels","channels","muteChain","chainId","unmuteChain","useCallback","useSyncExternalStore","NO_REQUEST","NEVER","usePassphraseGate","client","useWeb3","gate","resolveClient","request","useSyncExternalStore","submit","useCallback","passphrase","cancel","forget","reason","useCallback","useResolveName","name","options","query","useCallback","resolver","input","useNameLookup","assertHexSignature","bareEvmAddress","buildSmartAccountConfig","resolveUserOpChain","WalletError","useCallback","useEffect","useRef","useState","signHashWithSession","session","client","hash","address","chainId","activeClient","resolveClient","WalletError","params","eip6963Connector","wallet","candidate","result","assertHexSignature","embedded","useSendUserOperation","options","evmAccount","useAccount","connectedChainId","useWeb3","userOpHash","setUserOpHash","useState","receipt","setReceipt","isPending","setIsPending","isEstimating","setIsEstimating","error","setError","requestIdRef","useRef","inFlightRef","useEffect","sendUserOp","useCallback","calls","opts","fail","nextError","owner","bareEvmAddress","targetChainId","resolveUserOpChain","chainError","requestId","SmartAccountManager","signer","manager","config","buildSmartAccountConfig","response","nextReceipt","err","reset","useSyncExternalStore","useCallback","subscribeToSessionManager","sm","callback","handler","EMPTY_SESSION","snapshotCache","sameChainSessions","a","b","i","getSessionSnapshot","bundle","previous","chainSessions","next","useSession","sessionManager","web3","useWeb3","subscribe","useCallback","getSnapshot","useSyncExternalStore","defaultSiwxDomain","defaultSiwxUri","WalletError","createSiwxMessage","generateNonce","getBlockchainName","issueNonce","nowISO","useCallback","useState","DEFAULT_EXPIRY_SECONDS","useSIWxLogin","session","currentChainId","client","useWeb3","isSigningIn","setIsSigningIn","useState","error","setError","clearError","useCallback","options","WalletError","chainId","account","selectSiwxAccount","activeClient","resolveClient","address","location","domain","defaultSiwxDomain","uri","defaultSiwxUri","nonce","generateNonce","issueNonce","issuedAt","nowISO","expirySeconds","expirationTime","message","createSiwxMessage","signature","siwxResult","getBlockchainName","err","wrappedErr","siwxResultToSession","logger","checkSessionExpired","createLocalStorageSiwxSessionStorage","useCallback","useEffect","useRef","useState","useSIWxSession","options","storagePrefix","autoRestore","defaultExpirySeconds","session","setSession","useState","isRestoring","setIsRestoring","isSigningIn","setIsSigningIn","error","setError","currentChainId","useWeb3","login","useSIWxLogin","storageRef","useRef","createLocalStorageSiwxSessionStorage","clearError","useCallback","useEffect","cancelled","saved","logger","err","timeUntilExpiry","timer","prev","signIn","signOptions","effectiveOptions","result","siwxSession","siwxResultToSession","wrapped","signOut","refresh","refreshedSession","isAuthenticated","checkSessionExpired","expired","defaultSiwxDomain","defaultSiwxUri","WalletError","createSiwxMessage","generateNonce","getBlockchainName","issueNonce","nowISO","useCallback","useState","useSignInWithX","session","currentChainId","client","useWeb3","isSigningIn","setIsSigningIn","useState","result","setResult","error","setError","clearError","useCallback","options","WalletError","chainId","account","selectSiwxAccount","activeClient","resolveClient","address","location","domain","defaultSiwxDomain","uri","defaultSiwxUri","nonce","generateNonce","issueNonce","issuedAt","nowISO","message","createSiwxMessage","signature","expirationTime","siwxResult","getBlockchainName","err","wrappedErr","WalletError","useCallback","useEip155SessionGuard","session","activeChainId","useWeb3","chainId","WalletError","requestedChainId","evmNamespace","useSignInWithEthereum","guard","siwx","useSignInWithX","options","resolveSimulationEndpoint","SimulationManager","useCallback","useRef","useState","useSimulateTransfer","options","rpcUrl","chainId","managerRef","getManager","result","setResult","loading","setLoading","error","setError","simulate","tokenAddress","from","to","amount","simOptions","manager","endpoint","simResult","err","errorObj","reset","isSiwxExpired","isSiwxNotBeforeValid","LocalStorageAdapter","logger","useCallback","useEffect","useRef","useState","SIWX_AUTH_KEY","getStorage","prefix","LocalStorageAdapter","useSiwxAuthSession","options","storagePrefix","autoRestore","siwxResult","setSiwxResult","useState","isRestoring","setIsRestoring","isSigningIn","setIsSigningIn","error","setError","signInWithX","useSignInWithX","storageRef","useRef","clearError","useCallback","useEffect","cancelled","storage","saved","isSiwxExpired","isSiwxNotBeforeValid","logger","err","signIn","signOptions","result","wrapped","signOut","bareEvmAddress","buildSmartAccountConfig","resolveEvmChainId","WalletError","useCallback","useEffect","useRef","useState","accountError","message","WalletError","useSmartAccount","options","evmAccount","useAccount","session","connectedChainId","client","useWeb3","address","setAddress","useState","isDeployed","setIsDeployed","accountInfo","setAccountInfo","isLoading","setIsLoading","error","setError","managerRef","useRef","generationRef","inFlightRef","useEffect","cancelled","SmartAccountManager","chainId","resolveEvmChainId","err","getConfig","useCallback","owner","bareEvmAddress","buildSmartAccountConfig","fail","nextError","ensureOperation","finishOperation","operation","createWallet","config","info","e","deployWallet","activeClient","resolveClient","manager","before","deployTx","deployResult","after","getAddress","generation","addr","useMemo","useSolanaAccount","accounts","isConnected","useWeb3","useMemo","caip10","a","parts","address","chainId","useCallback","useEffect","useRef","useState","getSolanaBalance","useSolanaBalance","options","client","useWeb3","connectedAddress","useSolanaAccount","address","rpcUrl","resolveClient","balance","setBalance","useState","isFetching","setIsFetching","error","setError","generationRef","useRef","refetch","useCallback","generation","next","getSolanaBalance","err","useEffect","id","readSolanaRoles","useMemo","useSolanaRoles","client","session","accounts","useWeb3","useMemo","connector","resolveClient","roles","absence","readSolanaRoles","WalletError","useCallback","useState","getSignatureStatus","useSolanaTransaction","client","session","useWeb3","isSigning","setIsSigning","useState","isSending","setIsSending","error","setError","requireSession","activeClient","resolveClient","WalletError","signTransaction","useCallback","transaction","err","e","sendTransaction","getStatus","signature","rpcUrl","getSignatureStatus","useCallback","useState","toChainSwitchError","useSwitchChain","providerSwitchChain","chainId","useWeb3","isSwitching","setIsSwitching","useState","error","setError","handleSwitchChain","useCallback","targetChainId","err","walletError","toChainSwitchError","clearError","chainNumber","resolveChain","toViemChain","useState","useEffect","useCallback","useMemo","useRef","createPublicClient","http","formatUnits","erc20Abi","useTokenBalance","options","evmAccount","isConnected","useAccount","chainId","chains","useWeb3","tokenBalances","setTokenBalances","useState","isLoading","setIsLoading","error","setError","tokens","refreshInterval","intervalRef","useRef","tokensKey","useMemo","t","currentChain","resolveChain","evmChainNumber","chainNumber","viemChain","toViemChain","client","setClient","useEffect","publicClient","fetchTokenBalances","useCallback","address","balances","token","balance","r","err","getTokenBalance","tokenAddress","tb","useState","useEffect","useCallback","useRef","useTxHistory","address","chainId","monitor","ctxMonitor","useTxMonitorProvider","effectiveMonitor","entries","setEntries","useState","isLoading","setIsLoading","error","setError","refreshCounter","useRef","refresh","useCallback","results","err","useEffect","onStatusChange","summary","e","fetchUserOperationReceipt","InvalidUserOperationReceiptError","useCallback","useEffect","useRef","useState","useUserOpStatus","options","bundlerUrl","pollInterval","maxRetries","status","setStatus","receipt","setReceipt","userOpHash","setUserOpHash","error","setError","isPolling","setIsPolling","attempts","setAttempts","startTimeRef","elapsedMs","setElapsedMs","intervalRef","pollTimerRef","requestGenerationRef","attemptsRef","abortControllerRef","clearTimers","poll","hash","generation","currentAttempt","controller","finishUnavailable","nextError","retryOrFinish","receiptData","networkError","start","stop","reset","autoHash","autoStart","validateDestinationCore","useMemo","en","zh","locales","currentLocale","setLocale","locale","getLocale","t","key","validateDestination","address","isValid","level","issue","validateDestinationCore","t","useValidateDestination","useMemo","useWallet","status","session","accounts","chainId","error","connect","disconnect","reconnect","switchChain","useWeb3","isConnected","isConnecting","isReconnecting","currentAccount","useCallback","useMemo","WALLET_ERROR_TITLES","WALLET_ERROR_DESCRIPTIONS","UNKNOWN_ERROR_TITLE","UNKNOWN_ERROR_DESCRIPTION","getUserFriendlyError","error","maybeWalletError","code","title","description","message","isRetryableError","maybe","useWeb3ErrorHandler","error","providerClearError","useWeb3","friendlyError","useMemo","getUserFriendlyError","isRetryable","isRetryableError","clearError","useCallback","formatError","err","wrapAsync","fn","friendly","target","useState","useEffect","useCallback","useRef","TokenListManager","eip155ChainIdToNumber","useTokenList","chainId","options","managerRef","tokens","setTokens","isLoading","setIsLoading","isLoaded","setIsLoaded","error","setError","config","load","manager","numericChainId","loaded","err","refetch","useState","useEffect","useRef","TokenListManager","ETHEREUM_MAINNET_TOKENS","POLYGON_TOKENS","OPTIMISM_TOKENS","ARBITRUM_TOKENS","BASE_TOKENS","getDefaultSources","eip155ChainIdToNumber","DEBOUNCE_MS","sharedManager","getManager","TokenListManager","getDefaultSources","useTokenSearch","query","chainId","results","setResults","useState","isSearching","setIsSearching","debounceRef","useRef","trimmedQuery","useEffect","manager","numericChainId","searchResults","React","useCallback","Fragment","jsx","jsxs","TokenSelector","chainId","onSelect","onClose","options","searchQuery","setSearchQuery","React","allTokens","isLoading","error","useTokenList","results","isSearching","useTokenSearch","showRecommendations","displayTokens","combined","m","tokens","popularTokens","handleSelect","useCallback","token","e","img","createComponent","React","AppkitAccordionElement","defineAppkitAccordion","AppkitAccountButtonElement","defineAppkitAccountButton","AppkitAlertDialogElement","defineAppkitAlertDialog","AppkitAvatarElement","defineAppkitAvatar","AppkitBadgeElement","defineAppkitBadge","AppkitButtonElement","defineAppkitButton","AppkitCardContentElement","defineAppkitCardContent","AppkitCardDescriptionElement","defineAppkitCardDescription","AppkitCardFooterElement","defineAppkitCardFooter","AppkitCardHeaderElement","defineAppkitCardHeader","AppkitCardTitleElement","defineAppkitCardTitle","AppkitCardElement","defineAppkitCard","AppkitCheckboxElement","defineAppkitCheckbox","AppkitCollapsibleElement","defineAppkitCollapsible","AppkitConnectButtonElement","defineAppkitConnectButton","AppkitDialogElement","defineAppkitDialog","AppkitDropdownMenuElement","defineAppkitDropdownMenu","AppkitInputElement","defineAppkitInput","AppkitPopoverElement","defineAppkitPopover","AppkitProgressElement","defineAppkitProgress","AppkitScrollAreaElement","defineAppkitScrollArea","AppkitSelectElement","defineAppkitSelect","AppkitSeparatorElement","defineAppkitSeparator","AppkitSkeletonElement","defineAppkitSkeleton","AppkitSwitchElement","defineAppkitSwitch","AppkitTabsElement","defineAppkitTabs","AppkitToggleGroupElement","defineAppkitToggleGroup","AppkitTooltipElement","defineAppkitTooltip","AppkitAccordion","AppkitAccountButton","AppkitAlertDialog","AppkitAvatar","AppkitBadge","AppkitButton","AppkitCard","AppkitCardContent","AppkitCardDescription","AppkitCardFooter","AppkitCardHeader","AppkitCardTitle","AppkitCheckbox","AppkitCollapsible","AppkitConnectButton","AppkitDialog","AppkitDropdownMenu","AppkitInput","AppkitPopover","AppkitProgress","AppkitScrollArea","AppkitSelect","AppkitSeparator","AppkitSkeleton","AppkitSwitch","AppkitTabs","AppkitToggleGroup","AppkitTooltip"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/chain-abstraction/useCompareCosts.ts","../src/chain-abstraction/useExecuteRoute.ts","../src/chain-abstraction/useRouteQuote.ts","../src/client.ts","../src/hooks/useAccount.ts","../src/provider/Web3ConnectProvider.tsx","../src/core/siwx-flow.ts","../src/hooks/siwx-accounts.ts","../src/utils/chains.ts","../src/hooks/useAuthorizations.ts","../src/hooks/useBalance.ts","../src/hooks/useCapabilities.ts","../src/hooks/client-resolver.ts","../src/hooks/useChain.ts","../src/hooks/useConnect.ts","../src/hooks/useDelegate.ts","../src/hooks/useViemClient.ts","../src/hooks/usePaymentFetch.ts","../src/hooks/useX402Signer.ts","../src/hooks/useMppSession.ts","../src/hooks/useSolanaSessionKey.ts","../src/hooks/useDelegation.ts","../src/hooks/useDelegationPolicy.ts","../src/hooks/useExecuteCalls.ts","../src/hooks/useSendCalls.ts","../src/hooks/transaction-hash.ts","../src/hooks/useSessionKeys.ts","../src/hooks/useSignMessage.ts","../src/hooks/useDisconnect.ts","../src/hooks/useEmbeddedWallet.ts","../src/hooks/useERC20Allowance.ts","../src/hooks/useERC20Context.ts","../src/hooks/useERC20Approve.ts","../src/hooks/useSendTransaction.ts","../src/hooks/useERC20Transfer.ts","../src/hooks/useERC20TransferSimulation.ts","../src/hooks/useTransactionSimulation.ts","../src/hooks/useLastTx.ts","../src/hooks/useTxMonitor.ts","../src/hooks/useLookupAddress.ts","../src/core/name-lookup.ts","../src/hooks/useNotification.ts","../src/hooks/usePassphraseGate.ts","../src/hooks/useResolveName.ts","../src/hooks/useSendUserOperation.ts","../src/hooks/useSession.ts","../src/hooks/useSIWxLogin.ts","../src/hooks/useSIWxSession.ts","../src/hooks/useSignInWithX.ts","../src/hooks/useSignInWithEthereum.ts","../src/hooks/useSimulateTransfer.ts","../src/hooks/useSiwxAuthSession.ts","../src/hooks/useSmartAccount.ts","../src/hooks/useSolanaAccount.ts","../src/hooks/useSolanaBalance.ts","../src/hooks/useSolanaRoles.ts","../src/hooks/useSolanaTransaction.ts","../src/hooks/useSwitchChain.ts","../src/hooks/useTokenBalance.ts","../src/hooks/useTxHistory.ts","../src/hooks/useUserOpStatus.ts","../src/hooks/useValidateDestination.ts","../src/utils/i18n.ts","../src/hooks/useWallet.ts","../src/hooks/useWeb3ErrorHandler.ts","../src/utils/errorMessages.ts","../src/token-list/useTokenList.ts","../src/token-list/useTokenSearch.ts","../src/token-list/defaults.ts","../src/token-list/TokenSelector.tsx","../src/wc-generated/components.ts"],"sourcesContent":["export type {\n PassphraseIntent,\n PassphraseRequest,\n SolanaBalance,\n SolanaConfirmationStatus,\n} from \"@naculus/connect-core\";\n// Re-exported from connect-core, where it lives so the Vue layer can use the\n// same object. Kept exported here so a React consumer never has to know that.\n// Re-exported from connect-core, where the framework-neutral half lives so a\n// Vue composable can use it unchanged. A React consumer never has to know.\nexport {\n formatSol,\n getLatestBlockhash,\n getSignatureStatus,\n getSolanaBalance,\n LAMPORTS_PER_SOL,\n PassphraseCancelledError,\n PassphraseGate,\n parseSol,\n SolanaRpcError,\n} from \"@naculus/connect-core\";\n// Re-exported so a UI package can name what the hook returns without taking a\n// direct dependency on the connector layer.\nexport type {\n StorageSecurityFinding,\n StorageSecurityReport,\n WalletAccount,\n WalletData,\n WalletNamespace,\n} from \"@naculus/connector-embedded\";\nexport type {\n CostComparison,\n CostComparisonOperation,\n CostComparisonOptions,\n ExecuteError,\n ExecuteOptions,\n ExecuteRouteResult,\n Quote,\n QuoteOptions,\n UseCompareCostsInput,\n UseCompareCostsReturn,\n UseExecuteRouteReturn,\n UseRouteQuoteInput,\n UseRouteQuoteReturn,\n} from \"./chain-abstraction\";\nexport {\n useCompareCosts,\n useExecuteRoute,\n useRouteQuote,\n} from \"./chain-abstraction\";\nexport type {\n ClientConfig,\n InjectedProviderRegistration,\n NativeWalletConnectOptions,\n Web3Client,\n} from \"./client\";\nexport { clearClient, createClient, getClient } from \"./client\";\nexport { useAccount } from \"./hooks/useAccount\";\nexport type {\n UseAuthorizationsOptions,\n UseAuthorizationsReturn,\n} from \"./hooks/useAuthorizations\";\nexport { useAuthorizations } from \"./hooks/useAuthorizations\";\nexport { useBalance } from \"./hooks/useBalance\";\nexport type {\n AtomicSupport,\n ChainCapabilities,\n UseCapabilitiesReturn,\n} from \"./hooks/useCapabilities\";\nexport { useCapabilities } from \"./hooks/useCapabilities\";\nexport { useChain } from \"./hooks/useChain\";\nexport { useConnect } from \"./hooks/useConnect\";\nexport type {\n UseDelegateOptions,\n UseDelegateReturn,\n} from \"./hooks/useDelegate\";\nexport { useDelegate } from \"./hooks/useDelegate\";\nexport type {\n UsePaymentFetchOptions,\n UsePaymentFetchReturn,\n} from \"./hooks/usePaymentFetch\";\nexport { usePaymentFetch } from \"./hooks/usePaymentFetch\";\nexport { useX402Signer } from \"./hooks/useX402Signer\";\nexport type { UseX402SignerReturn } from \"./hooks/useX402Signer\";\nexport type { UseMppSessionReturn } from \"./hooks/useMppSession\";\nexport { useMppSession } from \"./hooks/useMppSession\";\nexport type { UseSolanaSessionKeyReturn } from \"./hooks/useSolanaSessionKey\";\nexport { useSolanaSessionKey } from \"./hooks/useSolanaSessionKey\";\nexport type { UseDelegationReturn } from \"./hooks/useDelegation\";\nexport { useDelegation } from \"./hooks/useDelegation\";\nexport type {\n DelegationPolicyPreview,\n PolicyExecutionAdapter,\n PolicyExecutionCheck,\n PolicyExecutionRoute,\n PolicyExecutionSubmission,\n PreparedPolicyExecution,\n UseDelegationPolicyOptions,\n UseDelegationPolicyReturn,\n} from \"./hooks/useDelegationPolicy\";\nexport {\n buildDelegationPolicyMessage,\n useDelegationPolicy,\n} from \"./hooks/useDelegationPolicy\";\nexport { useDisconnect } from \"./hooks/useDisconnect\";\nexport type {\n EmbeddedWalletAccountView,\n EmbeddedWalletView,\n UseEmbeddedWalletReturn,\n} from \"./hooks/useEmbeddedWallet\";\nexport { useEmbeddedWallet } from \"./hooks/useEmbeddedWallet\";\nexport type {\n UseERC20AllowanceOptions,\n UseERC20AllowanceReturn,\n} from \"./hooks/useERC20Allowance\";\nexport { useERC20Allowance } from \"./hooks/useERC20Allowance\";\nexport type {\n UseERC20ApproveOptions,\n UseERC20ApproveReturn,\n} from \"./hooks/useERC20Approve\";\nexport { useERC20Approve } from \"./hooks/useERC20Approve\";\nexport type {\n UseERC20TransferOptions,\n UseERC20TransferReturn,\n} from \"./hooks/useERC20Transfer\";\nexport { useERC20Transfer } from \"./hooks/useERC20Transfer\";\nexport type {\n UseERC20TransferSimulationOptions,\n UseERC20TransferSimulationReturn,\n} from \"./hooks/useERC20TransferSimulation\";\nexport { useERC20TransferSimulation } from \"./hooks/useERC20TransferSimulation\";\nexport type {\n ExecutionPreview,\n ExecutionRoute,\n UseExecuteCallsOptions,\n UseExecuteCallsReturn,\n} from \"./hooks/useExecuteCalls\";\nexport { useExecuteCalls } from \"./hooks/useExecuteCalls\";\nexport type { UseLastTxResult } from \"./hooks/useLastTx\";\nexport { useLastTx } from \"./hooks/useLastTx\";\nexport type {\n UseLookupAddressOptions,\n UseLookupAddressResult,\n} from \"./hooks/useLookupAddress\";\nexport { useLookupAddress } from \"./hooks/useLookupAddress\";\nexport { useNotification } from \"./hooks/useNotification\";\nexport type { UsePassphraseGateReturn } from \"./hooks/usePassphraseGate\";\nexport { usePassphraseGate } from \"./hooks/usePassphraseGate\";\nexport type {\n UseResolveNameOptions,\n UseResolveNameResult,\n} from \"./hooks/useResolveName\";\nexport { useResolveName } from \"./hooks/useResolveName\";\nexport type { SendCallsStatus } from \"./hooks/useSendCalls\";\nexport { useSendCalls } from \"./hooks/useSendCalls\";\nexport { useSendTransaction } from \"./hooks/useSendTransaction\";\nexport type {\n UseSendUserOperationOptions,\n UseSendUserOperationReturn,\n} from \"./hooks/useSendUserOperation\";\nexport { useSendUserOperation } from \"./hooks/useSendUserOperation\";\nexport type { UseSessionReturn } from \"./hooks/useSession\";\nexport { useSession } from \"./hooks/useSession\";\nexport type {\n UseCreateSessionKeyReturn,\n UseRevokeSessionReturn,\n UseSendWithSessionReturn,\n UseSessionKeysReturn,\n} from \"./hooks/useSessionKeys\";\nexport {\n resetSessionKeyManager,\n useCreateSessionKey,\n useRevokeSession,\n useSendWithSession,\n useSessionKeys,\n} from \"./hooks/useSessionKeys\";\nexport type {\n UseSIWxLoginOptions,\n UseSIWxLoginReturn,\n} from \"./hooks/useSIWxLogin\";\nexport { useSIWxLogin } from \"./hooks/useSIWxLogin\";\nexport type {\n UseSIWxSessionOptions,\n UseSIWxSessionReturn,\n} from \"./hooks/useSIWxSession\";\nexport { useSIWxSession } from \"./hooks/useSIWxSession\";\nexport type {\n UseSignInWithEthereumOptions,\n UseSignInWithEthereumReturn,\n} from \"./hooks/useSignInWithEthereum\";\nexport { useSignInWithEthereum } from \"./hooks/useSignInWithEthereum\";\nexport type {\n UseSignInWithXOptions,\n UseSignInWithXReturn,\n} from \"./hooks/useSignInWithX\";\nexport { useSignInWithX } from \"./hooks/useSignInWithX\";\nexport { useSignMessage } from \"./hooks/useSignMessage\";\nexport type {\n UseSimulateTransferOptions,\n UseSimulateTransferReturn,\n} from \"./hooks/useSimulateTransfer\";\nexport { useSimulateTransfer } from \"./hooks/useSimulateTransfer\";\nexport type {\n UseSiwxAuthSessionOptions,\n UseSiwxAuthSessionReturn,\n} from \"./hooks/useSiwxAuthSession\";\nexport { useSiwxAuthSession } from \"./hooks/useSiwxAuthSession\";\nexport type {\n UseSmartAccountOptions,\n UseSmartAccountReturn,\n} from \"./hooks/useSmartAccount\";\nexport { useSmartAccount } from \"./hooks/useSmartAccount\";\nexport type { UseSolanaAccountReturn } from \"./hooks/useSolanaAccount\";\n// ── Solana ────────────────────────────────────────────────────────\nexport { useSolanaAccount } from \"./hooks/useSolanaAccount\";\nexport type {\n UseSolanaBalanceOptions,\n UseSolanaBalanceReturn,\n} from \"./hooks/useSolanaBalance\";\nexport { useSolanaBalance } from \"./hooks/useSolanaBalance\";\nexport type {\n SolanaIdentity,\n SolanaPayer,\n SolanaRoles,\n SolanaRolesAbsence,\n SolanaSigner,\n SolanaWalletFeatures,\n UseSolanaRolesReturn,\n} from \"./hooks/useSolanaRoles\";\nexport { useSolanaRoles } from \"./hooks/useSolanaRoles\";\nexport type { UseSolanaTransactionReturn } from \"./hooks/useSolanaTransaction\";\nexport { useSolanaTransaction } from \"./hooks/useSolanaTransaction\";\nexport type { UseSwitchChainReturn } from \"./hooks/useSwitchChain\";\nexport { useSwitchChain } from \"./hooks/useSwitchChain\";\nexport type {\n TokenBalanceResult,\n TokenInfo,\n UseTokenBalanceOptions,\n} from \"./hooks/useTokenBalance\";\nexport { useTokenBalance } from \"./hooks/useTokenBalance\";\nexport type {\n ApprovalChange,\n BalanceChange,\n GasInfo,\n RiskAssessment,\n RiskLevel,\n RiskWarning,\n SimulationResult,\n SimulationStatus,\n UseTransactionSimulationReturn,\n} from \"./hooks/useTransactionSimulation\";\nexport { useTransactionSimulation } from \"./hooks/useTransactionSimulation\";\nexport type { UseTxHistoryResult } from \"./hooks/useTxHistory\";\nexport { useTxHistory } from \"./hooks/useTxHistory\";\nexport type {\n TxMonitorLike,\n TxStatus,\n TxStatusEntry,\n UseTxMonitorResult,\n} from \"./hooks/useTxMonitor\";\nexport { TxMonitorContext, useTxMonitor } from \"./hooks/useTxMonitor\";\nexport type {\n UserOpStatus,\n UseUserOpStatusOptions,\n UseUserOpStatusReturn,\n} from \"./hooks/useUserOpStatus\";\nexport { useUserOpStatus } from \"./hooks/useUserOpStatus\";\nexport type {\n AddressValidationLevel,\n AddressValidationResult,\n UseValidateDestinationOptions,\n UseValidateDestinationReturn,\n} from \"./hooks/useValidateDestination\";\nexport {\n useValidateDestination,\n validateDestination,\n} from \"./hooks/useValidateDestination\";\nexport { useViemClient } from \"./hooks/useViemClient\";\nexport { useWallet } from \"./hooks/useWallet\";\nexport type {\n UserFriendlyError,\n UseWeb3ErrorHandlerReturn,\n} from \"./hooks/useWeb3ErrorHandler\";\nexport { useWeb3ErrorHandler } from \"./hooks/useWeb3ErrorHandler\";\nexport type { Web3ConnectProviderProps } from \"./provider/Web3ConnectProvider\";\nexport {\n useWeb3,\n Web3ConnectProvider,\n Web3Context,\n} from \"./provider/Web3ConnectProvider\";\nexport type {\n TokenSelectorProps,\n UseTokenListOptions,\n UseTokenListReturn,\n UseTokenSearchReturn,\n} from \"./token-list\";\nexport { TokenSelector, useTokenList, useTokenSearch } from \"./token-list\";\nexport type {\n ChainInfo,\n ConnectionStatus,\n EvmTransaction,\n SIWxConfig,\n UseWalletReturn,\n WalletChain,\n Web3Actions,\n Web3ConnectConfig,\n Web3State,\n} from \"./types\";\nexport {\n DEFAULT_EVM_CHAINS,\n getChainById,\n getDefaultChains,\n} from \"./utils/chains\";\nexport {\n getUserFriendlyError,\n isRetryableError,\n WALLET_ERROR_DESCRIPTIONS,\n WALLET_ERROR_TITLES,\n} from \"./utils/errorMessages\";\nexport type { Locale } from \"./utils/i18n\";\nexport { getLocale, setLocale, t } from \"./utils/i18n\";\n\n// ── Stencil WC React wrappers ───────────────────────────────────\n\nexport type {\n AppkitAccordionEvents,\n AppkitAccountButtonEvents,\n AppkitAlertDialogEvents,\n AppkitAvatarEvents,\n AppkitBadgeEvents,\n AppkitButtonEvents,\n AppkitCardContentEvents,\n AppkitCardDescriptionEvents,\n AppkitCardEvents,\n AppkitCardFooterEvents,\n AppkitCardHeaderEvents,\n AppkitCardTitleEvents,\n AppkitCheckboxEvents,\n AppkitCollapsibleEvents,\n AppkitConnectButtonEvents,\n AppkitDialogEvents,\n AppkitDropdownMenuEvents,\n AppkitInputEvents,\n AppkitPopoverEvents,\n AppkitProgressEvents,\n AppkitScrollAreaEvents,\n AppkitSelectEvents,\n AppkitSeparatorEvents,\n AppkitSkeletonEvents,\n AppkitSwitchEvents,\n AppkitTabsEvents,\n AppkitToggleGroupEvents,\n AppkitTooltipEvents,\n} from \"./wc-generated/components\";\nexport {\n AppkitAccordion,\n AppkitAccountButton,\n AppkitAlertDialog,\n AppkitAvatar,\n AppkitBadge,\n AppkitButton,\n AppkitCard,\n AppkitCardContent,\n AppkitCardDescription,\n AppkitCardFooter,\n AppkitCardHeader,\n AppkitCardTitle,\n AppkitCheckbox,\n AppkitCollapsible,\n AppkitConnectButton,\n AppkitDialog,\n AppkitDropdownMenu,\n AppkitInput,\n AppkitPopover,\n AppkitProgress,\n AppkitScrollArea,\n AppkitSelect,\n AppkitSeparator,\n AppkitSkeleton,\n AppkitSwitch,\n AppkitTabs,\n AppkitToggleGroup,\n AppkitTooltip,\n} from \"./wc-generated/components\";\n","/**\n * useCompareCosts — compare an operation's cost across chains.\n *\n * Types and the value-key for the input live in\n * `@naculus/connect-appkit-core` (`routing`), shared with the Vue composable.\n */\n\nimport {\n type CompareCosts,\n type CompareCostsInput,\n type CostComparison,\n type CostComparisonOperation,\n type CostComparisonOptions,\n compareCostsKey,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type { CostComparison, CostComparisonOperation, CostComparisonOptions };\nexport type UseCompareCostsInput = CompareCostsInput;\n\nexport interface UseCompareCostsReturn {\n comparisons: CostComparison[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n}\n\nexport function useCompareCosts(\n input: UseCompareCostsInput,\n compareCostsFn?: CompareCosts,\n): UseCompareCostsReturn {\n const { operation, chains, options } = input;\n const [comparisons, setComparisons] = useState<CostComparison[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n const generationRef = useRef(0);\n\n // Keyed on the values, not the array/object identity — see compareCostsKey.\n const inputKey = compareCostsKey(input);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on inputKey (the inputs by value), not on the array/object identities that change every render; see compareCostsKey\n const fetchComparisons = useCallback(async () => {\n if (!chains || chains.length === 0) {\n setComparisons([]);\n return;\n }\n if (!compareCostsFn) return;\n\n // Only the newest request may write. A comparison for a previous chain set\n // resolving last would otherwise decide which route the user is shown as\n // cheapest, using costs for chains they are no longer looking at.\n const generation = ++generationRef.current;\n setLoading(true);\n setError(null);\n try {\n const result = await compareCostsFn(operation, chains, options);\n if (mountedRef.current && generation === generationRef.current) {\n setComparisons(result);\n }\n } catch (err) {\n if (mountedRef.current && generation === generationRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setComparisons([]);\n }\n } finally {\n if (mountedRef.current && generation === generationRef.current) {\n setLoading(false);\n }\n }\n }, [inputKey, compareCostsFn]);\n\n useEffect(() => {\n fetchComparisons();\n }, [fetchComparisons]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const refresh = useCallback(async () => {\n await fetchComparisons();\n }, [fetchComparisons]);\n\n return { comparisons, loading, error, refresh };\n}\n","/**\n * useExecuteRoute — execute a quoted cross-chain route once.\n *\n * Types, the recipient check and error normalization live in\n * `@naculus/connect-appkit-core` (`routing`), shared with the Vue composable.\n */\n\nimport {\n type ExecutableQuote,\n type ExecuteRoute,\n type ExecuteRouteError,\n type ExecuteRouteOptions,\n type ExecuteRouteResult,\n toExecuteRouteError,\n validateRouteRecipient,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type Quote = ExecutableQuote;\nexport type ExecuteOptions = ExecuteRouteOptions;\nexport type ExecuteError = ExecuteRouteError;\nexport type { ExecuteRouteResult };\n\nexport interface UseExecuteRouteReturn {\n execute: (\n quote: Quote,\n recipient: string,\n options?: ExecuteOptions,\n ) => Promise<ExecuteRouteResult | null>;\n executing: boolean;\n result: ExecuteRouteResult | null;\n error: ExecuteError | null;\n reset: () => void;\n}\n\nexport function useExecuteRoute(\n executeRouteFn?: ExecuteRoute,\n): UseExecuteRouteReturn {\n const [executing, setExecuting] = useState(false);\n const [result, setResult] = useState<ExecuteRouteResult | null>(null);\n const [error, setError] = useState<ExecuteError | null>(null);\n const mountedRef = useRef(true);\n const inFlightRef = useRef(false);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const execute = useCallback(\n async (\n quote: Quote,\n recipient: string,\n options?: ExecuteOptions,\n ): Promise<ExecuteRouteResult | null> => {\n if (!executeRouteFn) {\n setError({\n code: \"no_executor\",\n message: \"No executeRoute function provided\",\n });\n // Clear any earlier success too. A UI showing last run's transaction\n // hash next to this error reads as though something was sent.\n setResult(null);\n return null;\n }\n\n const recipientError = validateRouteRecipient(quote, recipient);\n if (recipientError) {\n setError(recipientError);\n setResult(null);\n return null;\n }\n\n // A cross-chain transfer must not be submitted twice because a button was\n // pressed twice. Matches useSendUserOperation.\n if (inFlightRef.current) {\n setError({\n code: \"execution_in_progress\",\n message: \"A route execution is already in progress\",\n });\n return null;\n }\n\n inFlightRef.current = true;\n setExecuting(true);\n setError(null);\n setResult(null);\n try {\n const execResult = await executeRouteFn(quote, recipient, options);\n if (mountedRef.current) setResult(execResult);\n return execResult;\n } catch (err) {\n if (mountedRef.current) setError(toExecuteRouteError(err));\n return null;\n } finally {\n inFlightRef.current = false;\n if (mountedRef.current) setExecuting(false);\n }\n },\n [executeRouteFn],\n );\n\n const reset = useCallback(() => {\n // Deliberately does not clear inFlightRef: a request already sent to the\n // executor is still out there, and letting reset() unlock the guard would\n // permit exactly the double submission it exists to prevent.\n setResult(null);\n setError(null);\n setExecuting(false);\n }, []);\n\n return { execute, executing, result, error, reset };\n}\n","/**\n * useRouteQuote — debounced cross-chain route quotes.\n *\n * Types and the \"is this amount quotable\" decision live in\n * `@naculus/connect-appkit-core` (`routing`), shared with the Vue composable.\n */\n\nimport {\n type GetRouteQuotes,\n isQuotableInput,\n type RouteQuote,\n type RouteQuoteInput,\n type RouteQuoteOptions,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type Quote = RouteQuote;\nexport type QuoteOptions = RouteQuoteOptions;\nexport type UseRouteQuoteInput = RouteQuoteInput;\n\nexport interface UseRouteQuoteReturn {\n quotes: Quote[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n clear: () => void;\n}\n\nexport function useRouteQuote(\n input: UseRouteQuoteInput,\n getQuoteFn?: GetRouteQuotes,\n): UseRouteQuoteReturn {\n const { fromChain, toChain, fromToken, toToken, amount, options } = input;\n const [quotes, setQuotes] = useState<Quote[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const mountedRef = useRef(true);\n\n const fetchQuotes = useCallback(async () => {\n if (!isQuotableInput({ fromChain, toChain, fromToken, amount })) {\n setQuotes([]);\n return;\n }\n if (!getQuoteFn) return;\n\n setLoading(true);\n setError(null);\n try {\n const result = await getQuoteFn(\n fromChain,\n toChain,\n fromToken,\n amount,\n options,\n toToken,\n );\n if (mountedRef.current) setQuotes(result);\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setQuotes([]);\n }\n } finally {\n if (mountedRef.current) setLoading(false);\n }\n }, [fromChain, toChain, fromToken, toToken, amount, options, getQuoteFn]);\n\n // Debounced auto-fetch on input change\n useEffect(() => {\n if (debounceTimer.current) clearTimeout(debounceTimer.current);\n if (!fromChain || !toChain || !fromToken || !amount) {\n setQuotes([]);\n return;\n }\n debounceTimer.current = setTimeout(() => {\n fetchQuotes();\n }, 300);\n return () => {\n if (debounceTimer.current) clearTimeout(debounceTimer.current);\n };\n }, [fetchQuotes, fromChain, toChain, fromToken, amount]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const refresh = useCallback(async () => {\n await fetchQuotes();\n }, [fetchQuotes]);\n\n const clear = useCallback(() => {\n setQuotes([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { quotes, loading, error, refresh, clear };\n}\n","import type {\n BatchCall,\n CallsStatus,\n SendCallsOptions,\n UniversalConnector,\n UniversalWalletSession,\n WalletCapabilities,\n} from \"@naculus/connect-core\";\nimport { logger, WalletError } from \"@naculus/connect-core\";\nimport type {\n PocketConnectorClass as EmbeddedWalletConnector,\n PocketConfig,\n} from \"@naculus/connector-embedded\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport type PasskeysConnectorImpl from \"@naculus/connector-passkeys\";\nimport { PassphraseGate } from \"@naculus/connect-core\";\nimport {\n createWalletConnectConnector,\n type WalletConnectConnector,\n} from \"@naculus/connector-walletconnect\";\n\n/** App-supplied WalletConnect pieces (see `ClientConfig.walletConnect`). */\nexport type NativeWalletConnectOptions = {\n /** A pre-built `@walletconnect/sign-client` SignClient. */\n client?: unknown;\n openUrl?: (url: string) => void | Promise<void>;\n};\n\n/** An EIP-1193 provider announced to the injected-wallet connector. */\nexport type InjectedProviderRegistration = {\n info: { uuid: string; name: string; icon: string; rdns: string };\n provider: unknown;\n};\n\nexport type ClientConfig = {\n projectId: string;\n metadata: {\n name: string;\n description: string;\n url: string;\n icons: string[];\n };\n /** Enable embedded (self-custodial) wallet */\n enableEmbedded?: boolean;\n /** Configuration forwarded to the embedded wallet engine. */\n embeddedConfig?: PocketConfig;\n\n /**\n * Ask the user for the storage passphrase through the UI instead of\n * supplying `embeddedConfig.encryptionPassphrase` yourself.\n *\n * Creates a `PassphraseGate` on the client and wires it in. Mount\n * `<PassphraseDialog />` from `@naculus/connect-appkit-ui` — or drive\n * `usePassphraseGate()` yourself — and the wallet's encrypted storage has\n * somewhere to ask.\n *\n * A callback you supply in `embeddedConfig` wins: your own prompt is a\n * deliberate choice, not something to override.\n */\n passphrasePrompt?: boolean;\n\n /** Enable passkeys (WebAuthn) connector */\n enablePasskeys?: boolean;\n\n /** Enable Solana injected wallet connector (Phantom, Solflare) */\n enableSolana?: boolean;\n /** Default Solana chain (e.g. \"solana:0\"). Only used when enableSolana is true. */\n solanaDefaultChain?: string;\n /**\n * WalletConnect wiring the app supplies — on React Native, a SignClient\n * built with native storage and `Linking.openURL` for deep links.\n */\n walletConnect?: NativeWalletConnectOptions;\n /**\n * Wallet Standard wallets to register with the Solana connector (React\n * Native's Mobile Wallet Adapter wallet). Needs `enableSolana`.\n */\n solanaWallets?: readonly unknown[];\n /**\n * EIP-1193 providers to register as injected wallets (React Native's\n * Coinbase Mobile Wallet Protocol provider); connect with\n * `connectInjected(info.uuid)`.\n */\n injectedProviders?: readonly InjectedProviderRegistration[];\n /**\n * Solana JSON-RPC endpoint, for reading balances and submitting\n * transactions.\n *\n * Kept separate from any EVM endpoint: pointing Solana traffic at an\n * EIP-155 node fails with an error that blames the request.\n */\n solanaRpcUrl?: string;\n};\n\n/**\n * What a transaction looks like on the way in.\n *\n * An EVM transaction is a set of named fields the wallet assembles; a Solana\n * one is bytes the application has already built and serialized. Typing this\n * as `Record<string, unknown>` made the second impossible to express, so a\n * Solana transaction could not be sent through the client even once the\n * connector below it knew how.\n */\nexport type TransactionInput = {\n transaction: Record<string, unknown> | Uint8Array | string;\n chainId?: string;\n};\n\nexport interface Web3Client {\n connector: WalletConnectConnector;\n embeddedConnector: EmbeddedWalletConnector | null;\n /** Wait for the lazily imported embedded connector to become available. */\n getEmbeddedConnector: () => Promise<EmbeddedWalletConnector | null>;\n /** The Passkeys connector if enabled */\n passkeysConnector: PasskeysConnectorImpl | null;\n /**\n * Where encrypted storage asks for a passphrase, when `passphrasePrompt` is\n * on. Null otherwise, including when the app supplies its own callback.\n */\n passphraseGate: PassphraseGate | null;\n /** Solana JSON-RPC endpoint from config, or null when none was given. */\n solanaRpcUrl: string | null;\n /** The Solana injected wallet connector if enabled */\n solanaConnector: UniversalConnector | null;\n connect: () => Promise<UniversalWalletSession>;\n /** Connect via EIP-6963 injected wallet */\n connectInjected: (walletId?: string) => Promise<UniversalWalletSession>;\n connectEmbedded: () => Promise<UniversalWalletSession>;\n /** Connect via passkeys (WebAuthn) */\n connectPasskeys: () => Promise<UniversalWalletSession>;\n reconnect: (\n session: UniversalWalletSession,\n ) => Promise<UniversalWalletSession>;\n disconnect: (session: UniversalWalletSession) => Promise<void>;\n /** Sign a message via the appropriate connector for the session */\n signMessage: (\n session: UniversalWalletSession,\n input: { message: string; address?: string; chainId?: string },\n ) => Promise<unknown>;\n /** Send a transaction via the appropriate connector for the session */\n sendTransaction: (\n session: UniversalWalletSession,\n input: TransactionInput,\n ) => Promise<unknown>;\n /**\n * Sign without broadcasting.\n *\n * Present because a Solana application routinely signs a transaction it\n * submits itself, or hands to a relayer. There was no way to ask for that\n * through the client at all.\n */\n signTransaction: (\n session: UniversalWalletSession,\n input: TransactionInput,\n ) => Promise<unknown>;\n /** Send batched calls (EIP-5792 wallet_sendCalls) via the appropriate connector */\n sendCalls: (\n session: UniversalWalletSession,\n calls: BatchCall[],\n chainId?: string,\n options?: SendCallsOptions,\n ) => Promise<string>;\n /**\n * Ask the wallet what the account can do, keyed by CAIP-2 chain.\n *\n * Undefined when the active connector has no way to answer, which is a\n * different fact from \"the account supports nothing\" — see\n * getAccountCapabilities in @naculus/connect-core.\n */\n getCapabilities?: (\n session: UniversalWalletSession,\n ) => Promise<Record<string, WalletCapabilities>> | undefined;\n /**\n * Subscribe to in-wallet account switches, whatever the namespace.\n *\n * Dispatches to the connector carrying the session, so a consumer never has\n * to know whether the wallet reports EIP-1193 `accountsChanged`, Solana's\n * `accountChanged`, or a WalletConnect session update. Returns an\n * unsubscribe function; returns a no-op when the connector cannot report.\n */\n onAccountsChanged?: (\n session: UniversalWalletSession,\n handler: (accounts: string[]) => void,\n ) => () => void;\n /** Counterpart to onAccountsChanged for in-wallet chain switches. */\n onChainChanged?: (\n session: UniversalWalletSession,\n handler: (chainId: string) => void,\n ) => () => void;\n /**\n * EIP-5792 `wallet_showCallsStatus`: ask the wallet to display a bundle.\n *\n * Optional because most wallets do not implement it, and a refusal is\n * cosmetic — the bundle is unaffected.\n */\n showCallsStatus?: (\n session: UniversalWalletSession,\n bundleHash: string,\n ) => Promise<void>;\n getCallsStatus: (\n session: UniversalWalletSession,\n bundleHash: string,\n ) => Promise<CallsStatus>;\n startPairing: () => Promise<string>;\n completePairing: () => Promise<UniversalWalletSession>;\n /** Abandon an in-flight pairing; a session that still arrives is torn down. */\n cancelPairing: () => void;\n getAllConnectors: () => UniversalConnector[];\n /** @internal set embedded connector after lazy init */\n _setEmbeddedConnector: (conn: EmbeddedWalletConnector) => void;\n /** @internal set passkeys connector after lazy init */\n _setPasskeysConnector: (conn: PasskeysConnectorImpl) => void;\n /** @internal set solana connector after lazy init */\n _setSolanaConnector: (conn: UniversalConnector) => void;\n}\n\nlet clientInstance: Web3Client | null = null;\n\nexport function createClient(config: ClientConfig): Web3Client {\n // A provider owns its client. Keeping a process-wide singleton here causes\n // the first provider's projectId, metadata, and feature flags to leak into\n // every later provider. `getClient()` remains as a legacy last-created\n // accessor; provider hooks use the client carried by context.\n let clientRef: Web3Client | null = null;\n\n const connector = createWalletConnectConnector({\n projectId: config.projectId,\n metadata: config.metadata,\n ...(config.walletConnect?.client\n ? { client: config.walletConnect.client as never }\n : {}),\n ...(config.walletConnect?.openUrl\n ? { openUrl: config.walletConnect.openUrl }\n : {}),\n });\n\n let _embeddedConnector: EmbeddedWalletConnector | null = null;\n let embeddedInit: Promise<void> | null = null;\n\n // Declared before the passkeys connector exists, because the embedded\n // wallet is constructed from it and the two load independently.\n let _passkeysConnector: PasskeysConnectorImpl | null = null;\n let passkeysInit: Promise<void> | null = null;\n\n // Only when asked for, and never over a callback the app already supplied.\n const _passphraseGate =\n config.passphrasePrompt &&\n config.enableEmbedded &&\n !config.embeddedConfig?.encryptionPassphrase\n ? new PassphraseGate()\n : null;\n\n if (config.enableEmbedded) {\n embeddedInit = import(\"@naculus/connector-embedded\")\n .then((mod) => {\n const embeddedConfig: PocketConfig = { ...config.embeddedConfig };\n if (_passphraseGate) {\n embeddedConfig.encryptionPassphrase = _passphraseGate.request;\n }\n // Passkey unlock turns itself on where the platform supports it: a\n // protection that has to be switched on protects only the people who\n // already knew to look for it. Where the authenticator cannot answer\n // this returns null and the record stays passphrase-only, which is\n // why it is safe to wire without asking.\n //\n // Requires encryption to be on at all — there is no key to wrap\n // otherwise — and never replaces a provider the app supplied.\n if (\n config.enablePasskeys &&\n embeddedConfig.encryptionPassphrase &&\n !embeddedConfig.prfUnlock\n ) {\n embeddedConfig.prfUnlock = {\n async derive(salt: Uint8Array) {\n if (passkeysInit) await passkeysInit;\n const passkeys = _passkeysConnector;\n if (!passkeys?.hasCredential()) return null;\n return passkeys.derivePrfKey(salt);\n },\n };\n }\n const conn = mod.createPocketConnector(embeddedConfig);\n _embeddedConnector = conn;\n clientRef?._setEmbeddedConnector(_embeddedConnector);\n })\n .catch((err) => {\n logger.warn(\n \"react/client\",\n \"Embedded wallet connector not available:\",\n err,\n );\n _embeddedConnector = null;\n });\n }\n\n if (config.enablePasskeys) {\n passkeysInit = import(\"@naculus/connector-passkeys\")\n .then((mod) => {\n const conn = mod.createPasskeysConnector();\n _passkeysConnector = conn;\n clientRef?._setPasskeysConnector(_passkeysConnector);\n })\n .catch((err) => {\n logger.warn(\"react/client\", \"Passkeys connector not available:\", err);\n _passkeysConnector = null;\n });\n }\n\n let _solanaConnector: UniversalConnector | null = null;\n let solanaInit: Promise<void> | null = null;\n\n if (config.enableSolana) {\n solanaInit = import(\"@naculus/connector-solana\")\n .then((mod: any) => {\n // Use the singleton instance so hooks (useSolanaAccount, etc.) and\n // the client routing share the same activeSession state.\n const conn = mod.solanaConnector as UniversalConnector;\n if (config.solanaDefaultChain && \"configure\" in conn) {\n (conn as any).configure({ defaultChain: config.solanaDefaultChain });\n }\n _solanaConnector = conn;\n if (typeof window !== \"undefined\" && \"startDiscovery\" in conn) {\n (conn as any).startDiscovery();\n }\n for (const wallet of config.solanaWallets ?? []) {\n (conn as any).registerWallet?.(wallet);\n }\n clientRef?._setSolanaConnector(_solanaConnector);\n })\n .catch((err) => {\n logger.warn(\"react/client\", \"Solana connector not available:\", err);\n _solanaConnector = null;\n });\n }\n\n // Start EIP-6963 discovery eagerly so wallets are available when user clicks connect\n if (typeof window !== \"undefined\") {\n eip6963Connector.startDiscovery();\n }\n for (const { info, provider } of config.injectedProviders ?? []) {\n eip6963Connector.registerProvider(info, provider as never);\n }\n\n const client: Web3Client = {\n connector,\n get embeddedConnector() {\n return _embeddedConnector;\n },\n getEmbeddedConnector: async () => {\n if (embeddedInit) await embeddedInit;\n return _embeddedConnector;\n },\n get passkeysConnector() {\n return _passkeysConnector;\n },\n passphraseGate: _passphraseGate,\n solanaRpcUrl: config.solanaRpcUrl ?? null,\n get solanaConnector() {\n return _solanaConnector;\n },\n connect: () => connector.connect(),\n connectInjected: async (walletId?: string) => {\n return eip6963Connector.connect(walletId);\n },\n connectEmbedded: async () => {\n if (embeddedInit) await embeddedInit;\n if (!_embeddedConnector) {\n throw new Error(\n \"Embedded wallet not enabled. Set enableEmbedded: true in config.\",\n );\n }\n return _embeddedConnector.connect();\n },\n connectPasskeys: async () => {\n if (passkeysInit) await passkeysInit;\n if (!_passkeysConnector) {\n throw new Error(\n \"Passkeys connector not enabled. Set enablePasskeys: true in config.\",\n );\n }\n return _passkeysConnector.connect();\n },\n startPairing: () => connector.startPairing(),\n completePairing: () => connector.completePairing(),\n cancelPairing: () => connector.cancelPairing?.(),\n signMessage: async (session, input) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.signMessage(session as any, input);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.signMessage(session as any, input);\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet connector not available.\",\n );\n }\n return _embeddedConnector.signMessage(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).signMessage(session as any, input);\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.signMessage(session, input);\n },\n signTransaction: async (session, input) => {\n // Same dispatch as sendTransaction; only the connector method differs.\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.signTransaction(session as any, input);\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet connector not available.\",\n );\n }\n return _embeddedConnector.signTransaction(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).signTransaction(\n session as any,\n input,\n );\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.signTransaction(session as any, input);\n },\n sendTransaction: async (session, input) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet connector not available.\",\n );\n }\n return _embeddedConnector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).sendTransaction(\n session as any,\n input,\n );\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.sendTransaction(session, input);\n },\n onAccountsChanged: (session, handler) => {\n // Same dispatch as every other session-routed call.\n const noop = () => {};\n if (session.id?.startsWith(\"eip6963-\")) {\n return (\n eip6963Connector.onAccountsChanged?.(session as never, handler) ??\n noop\n );\n }\n if (session.walletType === \"embedded\") {\n // The embedded wallet does rotate its active account, through\n // `setActiveNamespace` and `backfillAccounts`. This used to return a\n // no-op on the reasoning that a local key \"only rotates through an\n // explicit call\" — which is exactly the case that now exists, and\n // left the provider publishing the connect-time account while a\n // different key signed.\n return (\n _embeddedConnector?.onAccountsChanged?.(session, handler) ?? noop\n );\n }\n if (session.walletType === \"passkeys\") {\n // A passkey connector holds no account to rotate: it cannot even\n // produce an address without a deployed smart account.\n return noop;\n }\n if (session.walletType === \"solana\") {\n return (\n (_solanaConnector as UniversalConnector | null)?.onAccountsChanged?.(\n session,\n handler,\n ) ?? noop\n );\n }\n return connector.onAccountsChanged?.(session, handler) ?? noop;\n },\n onChainChanged: (session, handler) => {\n const noop = () => {};\n if (session.id?.startsWith(\"eip6963-\")) {\n return (\n eip6963Connector.onChainChanged?.(session as never, handler) ?? noop\n );\n }\n if (\n session.walletType === \"passkeys\" ||\n session.walletType === \"embedded\"\n ) {\n return noop;\n }\n if (session.walletType === \"solana\") {\n return (\n (_solanaConnector as UniversalConnector | null)?.onChainChanged?.(\n session,\n handler,\n ) ?? noop\n );\n }\n return connector.onChainChanged?.(session, handler) ?? noop;\n },\n getCapabilities: (session) => {\n // Same dispatch as sendCalls, so the capability answer always comes from\n // the connector that would carry out the send. Asking one connector and\n // sending through another is how a caller ends up promised atomicity\n // that the executing wallet never claimed.\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.getCapabilities?.(session as never);\n }\n if (session.walletType === \"passkeys\") {\n return _passkeysConnector?.getCapabilities?.(session as never);\n }\n if (session.walletType === \"solana\") {\n // The Solana connector answers nothing today. Returning undefined\n // reports that rather than a fabricated \"no support\".\n return (\n _solanaConnector as UniversalConnector | null\n )?.getCapabilities?.(session);\n }\n if (session.walletType === \"embedded\") {\n return _embeddedConnector?.getCapabilities?.(session as never);\n }\n // Undefined rather than an empty object: \"cannot be asked\" has to stay\n // distinguishable from \"asked, and answered nothing\".\n return connector.getCapabilities?.(session);\n },\n sendCalls: async (session, calls, chainId, options) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.sendCalls!(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.sendCalls!(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).sendCalls(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n if (session.walletType === \"embedded\") {\n if (!_embeddedConnector?.sendCalls) {\n throw new WalletError(\n \"method_not_allowed\",\n \"Embedded wallet does not support sendCalls\",\n );\n }\n return _embeddedConnector.sendCalls!(\n session as any,\n calls,\n chainId,\n options,\n );\n }\n if (!connector.sendCalls) {\n throw new WalletError(\n \"method_not_allowed\",\n \"sendCalls not supported by this connector\",\n );\n }\n return connector.sendCalls(session, calls, chainId, options);\n },\n showCallsStatus: async (session, bundleHash) => {\n // Same dispatch as sendCalls, so the wallet asked to display the bundle\n // is the one that sent it.\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.showCallsStatus!(session as never, bundleHash);\n }\n if (\n session.walletType === \"passkeys\" ||\n session.walletType === \"embedded\"\n ) {\n throw new WalletError(\n \"method_unsupported\",\n `${session.walletType} wallets have no UI to display a call bundle.`,\n );\n }\n if (!connector.showCallsStatus) {\n throw new WalletError(\n \"method_unsupported\",\n \"This connector cannot display call status.\",\n );\n }\n return connector.showCallsStatus(session, bundleHash);\n },\n getCallsStatus: async (session, bundleHash) => {\n if (\n session.id?.startsWith(\"eip6963-\") &&\n eip6963Connector.getCallsStatus\n ) {\n return eip6963Connector.getCallsStatus(session as any, bundleHash);\n }\n if (\n session.walletType === \"passkeys\" &&\n _passkeysConnector?.getCallsStatus\n ) {\n return _passkeysConnector.getCallsStatus(session as any, bundleHash);\n }\n if (session.walletType === \"embedded\") {\n throw new WalletError(\n \"method_not_allowed\",\n \"Embedded wallet does not support getCallsStatus\",\n );\n }\n if (!connector.getCallsStatus) {\n throw new WalletError(\n \"method_not_allowed\",\n \"getCallsStatus not supported by this connector\",\n );\n }\n return connector.getCallsStatus(session, bundleHash);\n },\n reconnect: async (session) => {\n if (session.walletType === \"eip6963\") {\n return eip6963Connector.reconnect(session);\n }\n if (session.walletType === \"embedded\") {\n if (_embeddedConnector) {\n return _embeddedConnector.reconnect(session);\n }\n return session;\n }\n if (session.walletType === \"solana\") {\n // Solana injected wallet doesn't support reconnect (no persisted session).\n // Return the saved session as-is; signing ops require wallet reconnection.\n return session;\n }\n return connector.reconnect(session);\n },\n disconnect: async (session) => {\n if (\n session.id?.startsWith(\"eip6963-\") ||\n session.walletType === \"eip6963\"\n ) {\n return eip6963Connector.disconnect(session as any);\n }\n if (session.walletType === \"embedded\" && _embeddedConnector) {\n return _embeddedConnector.disconnect();\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.disconnect(session as any);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return _solanaConnector.disconnect(session);\n }\n throw new WalletError(\n \"wallet_unavailable\",\n \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\",\n );\n }\n return connector.disconnect(session);\n },\n getAllConnectors: () => {\n const connectors: UniversalConnector[] = [connector];\n if (_embeddedConnector) connectors.push(_embeddedConnector);\n if (_passkeysConnector) connectors.push(_passkeysConnector);\n if (_solanaConnector) connectors.push(_solanaConnector);\n return connectors;\n },\n _setEmbeddedConnector: (conn: EmbeddedWalletConnector) => {\n _embeddedConnector = conn;\n },\n _setPasskeysConnector: (conn: PasskeysConnectorImpl) => {\n _passkeysConnector = conn;\n },\n _setSolanaConnector: (conn: UniversalConnector) => {\n _solanaConnector = conn;\n },\n };\n\n clientRef = client;\n clientInstance = client;\n return client;\n}\n\nexport function getClient(): Web3Client | null {\n return clientInstance;\n}\n\nexport function clearClient(): void {\n clientInstance = null;\n}\n","import { isEvmAddress, parseCaip10 } from \"@naculus/connect-core\";\nimport { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface AccountEntry {\n /** As the session reports it: CAIP-10 for most wallets, bare hex for some. */\n address: string;\n /** The namespace, when the entry was CAIP-10. Null for a bare address. */\n namespace: string | null;\n isEVM: boolean;\n}\n\n/**\n * The connected accounts, split by what they actually are.\n *\n * Reads the namespace from the CAIP-10 form rather than inferring it from\n * address shape wherever it can, and falls back to shape only for a bare\n * address. A bare 0x-40-hex value is unambiguously EVM; a bare base58 string\n * is not unambiguously anything.\n */\nexport function useAccount() {\n const { accounts, isConnected } = useWeb3();\n\n const accountData = useMemo<AccountEntry[] | null>(() => {\n if (!isConnected || accounts.length === 0) return null;\n\n return accounts.map((address) => {\n const parsed = parseCaip10(address);\n if (parsed) {\n return {\n address,\n namespace: parsed.namespace,\n // The namespace decides, not the shape. A wallet that reports\n // `solana:...:0x...` is telling us something about the account that\n // its characters do not.\n isEVM: parsed.namespace === \"eip155\" && isEvmAddress(parsed.address),\n };\n }\n return {\n address,\n namespace: null,\n isEVM: isEvmAddress(address),\n };\n });\n }, [accounts, isConnected]);\n\n const evmAccount = accountData?.find((a) => a.isEVM)?.address ?? null;\n\n return {\n accounts: accountData,\n evmAccount,\n primaryAccount: accounts[0] ?? null,\n isConnected,\n count: accounts.length,\n };\n}\n","\"use client\";\n\nimport type {\n ActiveSessionBundle,\n SessionManager,\n UniversalWalletSession,\n} from \"@naculus/connect-core\";\nimport {\n createConnectorManager,\n createSessionManager,\n LocalStorageSessionStorage,\n logger,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport type React from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n} from \"react\";\nimport { createClient, type Web3Client } from \"../client\";\nimport { runSiwxFlow } from \"../core/siwx-flow\";\nimport {\n initialWeb3State,\n web3Reducer,\n withRetry,\n withTimeout,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n WalletChain,\n Web3Actions,\n Web3ConnectConfig,\n Web3State,\n} from \"../types\";\nimport { getDefaultChains } from \"../utils/chains\";\n\n// ── Timeout Helper ────────────────────────────────────────────────\n\nexport interface Web3ContextValue extends Web3State, Web3Actions {\n isConnected: boolean;\n chains: WalletChain[];\n /** Client owned by this provider instance. */\n client: Web3Client;\n /** SessionManager instance for multi-chain session management */\n sessionManager: SessionManager | null;\n}\n\nexport const Web3Context = createContext<Web3ContextValue | null>(null);\n\nexport interface Web3ConnectProviderProps {\n children: React.ReactNode;\n config: Web3ConnectConfig;\n autoConnect?: boolean;\n}\n\nexport function Web3ConnectProvider({\n children,\n config,\n autoConnect = true,\n}: Web3ConnectProviderProps) {\n const [state, dispatch] = useReducer(web3Reducer, initialWeb3State);\n\n const chains = useMemo(\n () => config.chains ?? getDefaultChains(),\n [config.chains],\n );\n\n const connectionTimeout = config.connectionTimeout ?? 30000;\n const maxRetries = config.maxRetries ?? 2;\n\n const storage = useMemo(\n () =>\n config.sessionStorage ??\n new LocalStorageSessionStorage(\n config.storageKey ?? \"naculus_web3_session\",\n config.encryptionKey,\n ),\n [config.sessionStorage, config.storageKey, config.encryptionKey],\n );\n\n const client = useMemo(() => {\n return createClient({\n projectId: config.projectId,\n metadata: config.metadata,\n enableEmbedded: config.enableEmbedded,\n embeddedConfig: config.embeddedConfig,\n enablePasskeys: config.enablePasskeys,\n enableSolana: config.enableSolana,\n solanaDefaultChain: config.solanaDefaultChain,\n walletConnect: config.walletConnect,\n solanaWallets: config.solanaWallets,\n injectedProviders: config.injectedProviders,\n });\n }, [\n config.projectId,\n config.metadata,\n config.enableEmbedded,\n config.embeddedConfig,\n config.enablePasskeys,\n config.enableSolana,\n config.solanaDefaultChain,\n config.walletConnect,\n config.solanaWallets,\n config.injectedProviders,\n ]);\n\n // ── SessionManager ───────────────────────────────────────────────\n\n const sessionManagerRef = useRef<SessionManager | null>(null);\n // EIP-1193 chain events and an imperative switch can arrive in the same\n // tick. Keep the external synchronization promise visible to switchChain so\n // it cannot observe the old SessionManager chain and incorrectly no-op.\n const pendingExternalChainSyncRef = useRef<Promise<void> | null>(null);\n\n const sessionManager = useMemo(() => {\n // Build a connector manager that shares the client's connectors\n const cm = createConnectorManager();\n for (const connector of [eip6963Connector, ...client.getAllConnectors()]) {\n cm.register(connector.id, connector);\n }\n\n // Build default RPC/currency configs from the configured chains\n const defaultRpcUrls: Record<string, string> = {};\n const defaultCurrencies: Record<\n string,\n { name: string; symbol: string; decimals: number }\n > = {};\n\n for (const chain of chains) {\n const caip2Id = chain.caip2;\n if (chain.rpcUrl) {\n defaultRpcUrls[caip2Id] = chain.rpcUrl;\n }\n if (chain.token) {\n defaultCurrencies[caip2Id] = {\n name: chain.name,\n symbol: chain.token,\n decimals: 18,\n };\n }\n }\n\n const sm = createSessionManager(cm, {\n autoRefreshFeeOnSwitch: config.autoRefreshFeeOnSwitch ?? true,\n defaultRpcUrls,\n defaultCurrencies,\n encryptionKey: config.encryptionKey,\n });\n\n sessionManagerRef.current = sm;\n return sm;\n }, [client, chains, config.autoRefreshFeeOnSwitch, config.encryptionKey]);\n\n // Sync SessionManager events to provider state\n useEffect(() => {\n const onConnected = (payload: { bundle: any }) => {\n const { walletSession } = payload.bundle;\n dispatch({ type: \"SET_SESSION\", payload: walletSession });\n\n const accounts: string[] = [];\n Object.values(walletSession.namespaces).forEach((ns: any) => {\n accounts.push(...ns.accounts);\n });\n dispatch({ type: \"SET_ACCOUNTS\", payload: accounts });\n dispatch({ type: \"SET_CHAIN\", payload: payload.bundle.activeChainId });\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n };\n\n const onDisconnected = () => {\n dispatch({ type: \"RESET\" });\n };\n\n const onChainChanged = (payload: { newChainId: string }) => {\n dispatch({ type: \"SET_CHAIN\", payload: payload.newChainId });\n };\n\n // The wallet narrowed the scope: re-read accounts and active chain from\n // the bundle rather than keeping what the wider session had.\n const onScopeChanged = (payload: { bundle: ActiveSessionBundle }) =>\n onConnected(payload);\n // The wallet ended the session (revoked, expired, or scope emptied).\n // Covers the persisted-session-cleared case for every connector,\n // replacing WalletConnect's connector-private onSessionExpiry.\n const onRevoked = () => {\n storage.clear();\n dispatch({ type: \"RESET\" });\n };\n\n sessionManager.on(\"sessionConnected\", onConnected);\n sessionManager.on(\"sessionDisconnected\", onDisconnected);\n sessionManager.on(\"chainChanged\", onChainChanged);\n sessionManager.on(\"sessionScopeChanged\", onScopeChanged);\n sessionManager.on(\"sessionRevoked\", onRevoked);\n\n return () => {\n sessionManager.off(\"sessionConnected\", onConnected);\n sessionManager.off(\"sessionDisconnected\", onDisconnected);\n sessionManager.off(\"chainChanged\", onChainChanged);\n sessionManager.off(\"sessionScopeChanged\", onScopeChanged);\n sessionManager.off(\"sessionRevoked\", onRevoked);\n };\n }, [sessionManager, storage]);\n\n useEffect(() => {\n const handler = () => {\n storage.clear();\n dispatch({ type: \"RESET\" });\n };\n client.connector.onSessionExpiry(handler);\n }, [client, storage]);\n\n const syncSessionManagerConnectors = useCallback(() => {\n for (const connector of [eip6963Connector, ...client.getAllConnectors()]) {\n sessionManager.registerConnector(connector);\n }\n }, [client, sessionManager]);\n\n const attachSession = useCallback(\n async (session: UniversalWalletSession) => {\n syncSessionManagerConnectors();\n const connector = [eip6963Connector, ...client.getAllConnectors()].find(\n (candidate) =>\n candidate.id === session.walletType ||\n candidate.kind === session.walletType,\n );\n if (connector && !session.connectorId) session.connectorId = connector.id;\n const chainId =\n session.namespaces.eip155?.chains?.[0] ??\n session.namespaces.solana?.chains?.[0] ??\n session.namespaces.xrpl?.chains?.[0];\n if (chainId) await sessionManager.attach(session, chainId);\n },\n [client, sessionManager, syncSessionManagerConnectors],\n );\n\n const updateStateFromSession = useCallback(\n (session: typeof state.session) => {\n dispatch({ type: \"SET_SESSION\", payload: session });\n\n if (session) {\n const accounts: string[] = [];\n Object.values(session.namespaces).forEach((ns) => {\n accounts.push(...ns.accounts);\n });\n dispatch({ type: \"SET_ACCOUNTS\", payload: accounts });\n\n const evmChain = session.namespaces.eip155?.chains?.[0];\n const solChain = session.namespaces.solana?.chains?.[0];\n const xrplChain = session.namespaces.xrpl?.chains?.[0];\n dispatch({\n type: \"SET_CHAIN\",\n payload: evmChain ?? solChain ?? xrplChain ?? null,\n });\n } else {\n dispatch({ type: \"SET_ACCOUNTS\", payload: [] });\n dispatch({ type: \"SET_CHAIN\", payload: null });\n }\n },\n [],\n );\n\n // Wallets can change accounts without a reconnect call, and every namespace\n // has its own way of saying so: EIP-1193 `accountsChanged`, Solana's\n // `accountChanged`, a WalletConnect session update. This used to subscribe by\n // reaching through `eip6963Connector.getDiscoveredWallets()` into the raw\n // provider, which meant it re-implemented the CAIP-10 re-keying the connector\n // already did and worked for exactly one wallet kind — a Solana or\n // WalletConnect account switch was never noticed at all.\n //\n // The connector reports it now, so this subscribes once, namespace-agnostic,\n // and only mirrors the session the connector has already updated.\n useEffect(() => {\n const session = state.session;\n const activeClient = client;\n if (!session || !activeClient?.onAccountsChanged) return;\n\n const unsubscribe = activeClient.onAccountsChanged(session, (accounts) => {\n if (accounts.length === 0) {\n // The wallet is no longer authorizing this dApp.\n void storage.clear().finally(() => dispatch({ type: \"RESET\" }));\n return;\n }\n updateStateFromSession(session);\n void storage.save(session);\n });\n\n return unsubscribe;\n }, [state.session, client, storage, updateStateFromSession]);\n\n // Chain switches made in the wallet. The connector re-keys the session's\n // accounts to the new chain; what only the provider can do is drive the\n // SessionManager's external-chain sync, which other operations await.\n useEffect(() => {\n const session = state.session;\n const activeClient = client;\n if (!session || !activeClient?.onChainChanged) return;\n\n return activeClient.onChainChanged(session, (chainId) => {\n updateStateFromSession(session);\n void storage.save(session);\n\n const syncExternalChain = (\n sessionManager as SessionManager & {\n syncExternalChain?: (nextChainId: string) => Promise<void>;\n }\n ).syncExternalChain;\n if (!syncExternalChain) return;\n\n const syncPromise = syncExternalChain\n .call(sessionManager, chainId)\n .catch((error) => {\n logger.warn(\"react/provider\", \"External chain sync error:\", error);\n });\n pendingExternalChainSyncRef.current = syncPromise;\n void syncPromise.finally(() => {\n if (pendingExternalChainSyncRef.current === syncPromise) {\n pendingExternalChainSyncRef.current = null;\n }\n });\n });\n }, [state.session, client, storage, updateStateFromSession, sessionManager]);\n\n // ── SIWx post-connection helper ──────────────────────────────────\n // Run after any connect method succeeds. Returns false if SIWx is\n // configured, required, and failed — the caller should abort without\n // setting status to \"connected\".\n // The sequence itself lives in core/siwx-flow so every binding shares it;\n // this only maps the outcome onto React state and storage.\n const runSiwx = useCallback(\n async (session: UniversalWalletSession | null): Promise<boolean> => {\n if (!config.siwx || !session) return true;\n dispatch({ type: \"SET_STATUS\", payload: \"authenticating\" });\n\n const outcome = await runSiwxFlow({\n session,\n siwx: config.siwx,\n signMessage: (s, args) => client.signMessage(s, args),\n });\n\n if (outcome.kind === \"failed\" && outcome.fatal) {\n await storage.clear();\n dispatch({ type: \"RESET\" });\n dispatch({ type: \"SET_ERROR\", payload: outcome.error });\n return false;\n }\n return true;\n },\n [config.siwx, client, storage],\n );\n\n const connect = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await withTimeout(\n client.connect(),\n connectionTimeout,\n \"Wallet connect\",\n );\n await storage.save(session);\n updateStateFromSession(session);\n\n try {\n await attachSession(session);\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager sync error:\", smError);\n }\n\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [\n client,\n storage,\n updateStateFromSession,\n connectionTimeout,\n runSiwx,\n attachSession,\n ]);\n\n const connectEmbedded = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await client.connectEmbedded();\n await storage.save(session);\n updateStateFromSession(session);\n await attachSession(session);\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Embedded wallet connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, runSiwx, attachSession]);\n\n const connectPasskeys = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await client.connectPasskeys();\n await storage.save(session);\n updateStateFromSession(session);\n await attachSession(session);\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Passkeys connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, runSiwx, attachSession]);\n\n const disconnect = useCallback(async () => {\n if (!state.session) {\n dispatch({ type: \"RESET\" });\n return;\n }\n\n try {\n await client.disconnect(state.session);\n } catch (error) {\n logger.error(\"react/provider\", \"Disconnect error:\", error);\n }\n\n // Also disconnect via SessionManager\n try {\n const sm = sessionManagerRef.current;\n if (sm) {\n await sm.disconnect();\n }\n } catch (smError) {\n logger.warn(\n \"react/provider\",\n \"SessionManager disconnect error:\",\n smError,\n );\n }\n\n await storage.clear();\n dispatch({ type: \"RESET\" });\n }, [client, state.session, storage]);\n\n const connectInjected = useCallback(\n async (walletId?: string): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await withTimeout(\n client.connectInjected(walletId),\n connectionTimeout,\n \"Injected wallet connect\",\n );\n await storage.save(session);\n updateStateFromSession(session);\n\n try {\n await attachSession(session);\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager sync error:\", smError);\n }\n\n if (!(await runSiwx(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Connection failed\";\n dispatch({\n type: \"SET_ERROR\",\n payload: error instanceof Error ? error : new Error(message),\n });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n },\n [\n client,\n storage,\n updateStateFromSession,\n connectionTimeout,\n runSiwx,\n attachSession,\n ],\n );\n\n const startPairing = useCallback(async () => {\n return client.startPairing();\n }, [client]);\n\n const cancelPairing = useCallback(() => {\n client.cancelPairing?.();\n }, [client]);\n\n const completePairing = useCallback(async () => {\n const session = await client.completePairing();\n await storage.save(session);\n updateStateFromSession(session);\n await attachSession(session);\n if (!(await runSiwx(session))) return session;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n return session;\n }, [client, storage, updateStateFromSession, runSiwx, attachSession]);\n\n /**\n * SIWx on the reconnect path.\n *\n * Every other entry point runs `runSiwx` before reporting `connected`;\n * this one did not, and `autoConnect` makes it the path taken on every page\n * load. An application configured with `required: true` therefore had the\n * setting enforced once and bypassed on every refresh.\n *\n * Optional SIWx is left alone: prompting for a signature the application\n * said it can live without, on every reload, is the wrong trade.\n */\n const runSiwxOnReconnect = useCallback(\n async (session: UniversalWalletSession): Promise<boolean> => {\n const siwx = config.siwx;\n if (!siwx || siwx.required === false) return true;\n try {\n if (await siwx.hasValidSession?.()) return true;\n } catch (err) {\n // A session check that throws has not established a session. Fall\n // through and ask for a signature rather than assuming one.\n logger.warn(\"react/provider\", \"siwx.hasValidSession failed\", err);\n }\n return runSiwx(session);\n },\n [config.siwx, runSiwx],\n );\n\n const reconnect = useCallback(async () => {\n const savedSession = await storage.load();\n if (!savedSession) {\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n return;\n }\n\n dispatch({ type: \"SET_STATUS\", payload: \"reconnecting\" });\n\n try {\n const session = await withRetry(() => client.reconnect(savedSession), {\n maxRetries,\n baseDelay: 1000,\n label: \"reconnect\",\n });\n updateStateFromSession(session);\n\n // Restore SessionManager from persistence\n try {\n const sm = sessionManagerRef.current;\n if (sm) {\n syncSessionManagerConnectors();\n await sm.restoreFromPersistence();\n }\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager restore error:\", smError);\n }\n\n if (!(await runSiwxOnReconnect(session))) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n logger.error(\"react/provider\", \"Reconnect error:\", error);\n await storage.clear();\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n dispatch({ type: \"SET_SESSION\", payload: null });\n }\n }, [\n client,\n storage,\n updateStateFromSession,\n maxRetries,\n syncSessionManagerConnectors,\n runSiwxOnReconnect,\n ]);\n\n const switchChain = useCallback(\n async (chainId: string) => {\n if (pendingExternalChainSyncRef.current) {\n await pendingExternalChainSyncRef.current;\n }\n const sm = sessionManagerRef.current;\n if (sm?.getActiveBundle()) {\n // Use SessionManager's switchChain which handles fee sync + events\n await sm.switchChain(chainId);\n updateStateFromSession(state.session);\n return;\n }\n\n // Fallback to direct connector switching (no SessionManager)\n if (!state.session) {\n throw new Error(\"No active session\");\n }\n\n try {\n if (\n state.session.walletType === \"eip6963\" ||\n state.session.id?.startsWith(\"eip6963-\")\n ) {\n await eip6963Connector.switchChain(state.session, chainId);\n } else if (\n state.session.walletType === \"embedded\" &&\n client.embeddedConnector\n ) {\n await client.embeddedConnector.switchChain?.(state.session, chainId);\n } else if (\n state.session.walletType === \"passkeys\" &&\n client.passkeysConnector\n ) {\n await client.passkeysConnector.switchChain?.(state.session, chainId);\n } else if (\n state.session.walletType === \"solana\" &&\n client.solanaConnector\n ) {\n await client.solanaConnector.switchChain?.(state.session, chainId);\n } else {\n await client.connector.switchChain(state.session, chainId);\n }\n updateStateFromSession(state.session);\n } catch (error) {\n throw new WalletError(\n \"chain_unsupported\",\n \"Failed to switch chain\",\n error,\n );\n }\n },\n [client, state.session, updateStateFromSession],\n );\n\n useEffect(() => {\n if (autoConnect) {\n reconnect();\n }\n }, [autoConnect, reconnect]);\n\n const clearError = useCallback(() => {\n dispatch({ type: \"SET_ERROR\", payload: null });\n }, []);\n\n const value = useMemo<Web3ContextValue>(\n () => ({\n ...state,\n connect,\n connectEmbedded,\n connectPasskeys,\n disconnect,\n reconnect,\n switchChain,\n startPairing,\n completePairing,\n cancelPairing,\n connectInjected,\n clearError,\n isConnected: state.status === \"connected\",\n chains,\n client,\n sessionManager,\n }),\n [\n state,\n connect,\n connectEmbedded,\n connectPasskeys,\n disconnect,\n reconnect,\n switchChain,\n startPairing,\n completePairing,\n cancelPairing,\n connectInjected,\n clearError,\n chains,\n client,\n sessionManager,\n ],\n );\n\n return <Web3Context.Provider value={value}>{children}</Web3Context.Provider>;\n}\n\nexport function useWeb3(): Web3ContextValue {\n const context = useContext(Web3Context);\n if (!context) {\n throw new Error(\"useWeb3 must be used within a Web3ConnectProvider\");\n }\n return context;\n}\n","/**\n * Framework-agnostic SIWx orchestration.\n *\n * The sign-in sequence — pick the chain, pick the account in that chain's\n * namespace, build the message, register its nonce, sign, hand the signature\n * back — has nothing React-specific in it. Only the reaction to failure does\n * (clearing storage, resetting reducer state), so this returns a description\n * of what happened and lets the binding decide what to do about it.\n *\n * Keeping the decision here means Vue, Svelte and native bindings get the same\n * authentication behavior instead of each re-deriving it.\n */\nimport { logger } from \"@naculus/connect-core\";\nimport type { UniversalWalletSession } from \"@naculus/connect-core\";\nimport { issueNonce, parseSiwxMessage } from \"@naculus/siwx\";\nimport { selectSiwxAccount } from \"../hooks/siwx-accounts\";\n\nexport interface SiwxHandlers {\n createMessage: (input: {\n address: string;\n chainId: string;\n }) => Promise<string>;\n handleSignComplete?: (input: {\n message: string;\n signature: string;\n }) => Promise<void> | void;\n /** When false, a failed sign-in leaves the connection intact. */\n required?: boolean;\n}\n\nexport type SiwxOutcome =\n | { kind: \"skipped\" }\n | { kind: \"authenticated\"; address: string; chainId: string }\n /** `fatal` means the caller must tear the connection down. */\n | { kind: \"failed\"; error: Error; fatal: boolean };\n\n/**\n * Resolve the chain a SIWx message should be scoped to.\n *\n * `chains[0]` is the active chain by convention across every connector, so the\n * first namespace present wins in a fixed order rather than by object key\n * enumeration, which is not guaranteed to be stable.\n */\nexport function resolveSiwxChainId(session: UniversalWalletSession): string {\n return (\n session.namespaces.eip155?.chains?.[0] ??\n session.namespaces.solana?.chains?.[0] ??\n session.namespaces.xrpl?.chains?.[0] ??\n \"eip155:1\"\n );\n}\n\nexport async function runSiwxFlow(input: {\n session: UniversalWalletSession | null;\n siwx: SiwxHandlers | undefined;\n signMessage: (\n session: UniversalWalletSession,\n args: { message: string; address: string; chainId: string },\n ) => Promise<unknown>;\n}): Promise<SiwxOutcome> {\n const { session, siwx, signMessage } = input;\n if (!siwx || !session) return { kind: \"skipped\" };\n\n try {\n const chainId = resolveSiwxChainId(session);\n const account = selectSiwxAccount(session, chainId);\n if (!account) throw new Error(\"No account found in session\");\n const { address } = account;\n\n const message = await siwx.createMessage({ address, chainId });\n const parsed = parseSiwxMessage(message);\n if (!parsed?.nonce) {\n // A message the verifier cannot parse would be signed and then rejected\n // server-side, so refuse before asking the user to sign anything.\n throw new Error(\"SIWx message must contain a nonce\");\n }\n await issueNonce(parsed.nonce);\n\n const signature = (await signMessage(session, {\n message,\n address,\n chainId,\n })) as string;\n\n await siwx.handleSignComplete?.({ message, signature });\n return { kind: \"authenticated\", address, chainId };\n } catch (cause) {\n const error =\n cause instanceof Error\n ? cause\n : new Error(\"Wallet authentication failed\");\n logger.error(\"appkit/core\", \"SIWx authentication failed:\", cause);\n return { kind: \"failed\", error, fatal: siwx.required !== false };\n }\n}\n","import type { UniversalWalletSession } from \"@naculus/connect-core\";\n\nexport interface SiwxAccount {\n namespace: string;\n caip10: string;\n address: string;\n}\n\n/**\n * Pick an account from the namespace selected by the SIWx chain.\n * SIWx messages contain a bare account address; CAIP-10 accounts are only\n * used as the source of truth for selecting the right namespace.\n */\nexport function selectSiwxAccount(\n session: UniversalWalletSession,\n chainId: string,\n): SiwxAccount | undefined {\n const namespace = chainId.split(\":\", 1)[0];\n // SIWx chain and account must come from the same CAIP namespace. Falling\n // back to another namespace can sign an EVM message with a Solana/XRPL\n // address (or vice versa), which is an authentication identity mismatch.\n const preferred = session.namespaces[namespace]?.accounts ?? [];\n const candidate = preferred\n .filter((caip10) => caip10.startsWith(`${namespace}:`))\n .map((caip10) => ({ namespace, caip10 }))[0];\n if (!candidate) return undefined;\n\n return {\n ...candidate,\n address: candidate.caip10.split(\":\").pop() ?? candidate.caip10,\n };\n}\n","import { resolveChain } from \"@naculus/connect-appkit-core\";\nimport type { WalletChain } from \"../types\";\nimport {\n CHAINS,\n DEFAULT_RPC_URLS,\n eip155Reference,\n getRpcUrl,\n} from \"@naculus/connect-core\";\n\n// ─── Static Overrides ──────────────────────────────────────────────\n// Chains that exist in the old default list but are NOT in chain-registry.\n// These are deprecated testnets; keep for backward compatibility.\n\nconst STATIC_TESTNETS: WalletChain[] = [\n {\n caip2: \"eip155:5\",\n name: \"Goerli\",\n rpcUrl: \"https://goerli.blockpi.network/v1/rpc/public\",\n explorerUrl: \"https://goerli.etherscan.io\",\n token: \"ETH\",\n },\n {\n caip2: \"eip155:80001\",\n name: \"Mumbai\",\n rpcUrl: \"https://rpc-mumbai.maticvigil.com\",\n explorerUrl: \"https://mumbai.polygonscan.com\",\n token: \"MATIC\",\n },\n {\n caip2: \"eip155:421613\",\n name: \"Arbitrum Goerli\",\n rpcUrl: \"https://goerli-rollup.arbitrum.io/rpc\",\n explorerUrl: \"https://goerli.arbiscan.io\",\n token: \"ETH\",\n },\n {\n caip2: \"eip155:420\",\n name: \"Optimism Goerli\",\n rpcUrl: \"https://goerli.optimism.io\",\n explorerUrl: \"https://goerli-optimism.etherscan.io\",\n token: \"ETH\",\n },\n];\n\n// ─── Build from Registry ───────────────────────────────────────────\n// Derive WalletChain entries from the single-source-of-truth chain-registry\n// and the RPC URL defaults from rpc.ts.\n\nfunction toWalletChain(chainId: number): WalletChain | null {\n const info = CHAINS[chainId];\n if (!info) return null;\n\n // Only include chains with an explorer URL (meaningful for UI display)\n if (!info.explorerUrl) return null;\n\n const caip2Id = info.caip2Id;\n\n return {\n caip2: caip2Id,\n name: info.name,\n rpcUrl: getRpcUrl(caip2Id, DEFAULT_RPC_URLS[caip2Id] ?? \"\"),\n explorerUrl: info.explorerUrl,\n token: info.nativeCurrency.symbol,\n };\n}\n\nfunction buildDefaultChains(): WalletChain[] {\n if (!CHAINS) return [];\n\n const registryChains: WalletChain[] = [];\n\n // Order by chain ID for deterministic output\n const chainIds = Object.keys(CHAINS)\n .map(Number)\n .sort((a, b) => a - b);\n\n for (const id of chainIds) {\n const chain = toWalletChain(id);\n if (chain) {\n registryChains.push(chain);\n }\n }\n\n // Append static testnets that aren't in the registry\n for (const testnet of STATIC_TESTNETS) {\n // eip155Reference rather than a split: the registry is keyed by an\n // EIP-155 number, and only a chain that has one can collide with it.\n const reference = eip155Reference(testnet.caip2);\n if (reference === null || !CHAINS[reference]) {\n registryChains.push(testnet);\n }\n }\n\n return registryChains;\n}\n\nexport const DEFAULT_EVM_CHAINS: WalletChain[] = buildDefaultChains();\n\n// ─── Helpers ───────────────────────────────────────────────────────\n\n/**\n * The configured chain for a CAIP-2 id.\n *\n * Delegates rather than parsing again. The version this replaces did\n * `parseInt(chainId.split(\":\")[1])`, which answers 5 for\n * `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`.\n */\nexport function getChainById(chains: WalletChain[], chainId: string): WalletChain | undefined {\n return resolveChain(chains, chainId) ?? undefined;\n}\n\nexport function getDefaultChains(): WalletChain[] {\n return [...DEFAULT_EVM_CHAINS];\n}\n","import {\n type AuthorizationManagers,\n type ListedAuthorization,\n listAuthorizations,\n type RevokeListedAuthorizationResult,\n revokeListedAuthorization,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UseAuthorizationsOptions {\n managers: AuthorizationManagers;\n}\n\nexport interface UseAuthorizationsReturn {\n entries: ListedAuthorization[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n revoke: (\n entry: ListedAuthorization,\n ) => Promise<RevokeListedAuthorizationResult>;\n}\n\n/** Reactive shell over the caller-owned authorization managers. */\nexport function useAuthorizations({\n managers,\n}: UseAuthorizationsOptions): UseAuthorizationsReturn {\n const managersRef = useRef(managers);\n managersRef.current = managers;\n const generationRef = useRef(0);\n const mountedRef = useRef(true);\n const [entries, setEntries] = useState<ListedAuthorization[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(\n () => () => {\n mountedRef.current = false;\n generationRef.current += 1;\n },\n [],\n );\n\n const refresh = useCallback(async () => {\n const own = ++generationRef.current;\n setLoading(true);\n setError(null);\n try {\n const next = await listAuthorizations(managersRef.current);\n if (mountedRef.current && own === generationRef.current) setEntries(next);\n } catch (cause) {\n if (mountedRef.current && own === generationRef.current) {\n setError(\n cause instanceof Error\n ? cause\n : new Error(\"Failed to list authorizations\"),\n );\n }\n } finally {\n if (mountedRef.current && own === generationRef.current)\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const revoke = useCallback(\n async (entry: ListedAuthorization) => {\n try {\n const result = await revokeListedAuthorization(\n managersRef.current,\n entry,\n );\n await refresh();\n return result;\n } catch (cause) {\n const normalized =\n cause instanceof Error\n ? cause\n : new Error(\"Failed to revoke authorization\");\n if (mountedRef.current) setError(normalized);\n throw normalized;\n }\n },\n [refresh],\n );\n\n return { entries, loading, error, refresh, revoke };\n}\n","import type { WalletChain } from \"../types\";\nimport {\n chainNumber,\n resolveChain,\n toViemChain,\n} from \"@naculus/connect-appkit-core\";\nimport { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport { createPublicClient, http, formatEther, type PublicClient, type Address } from \"viem\";\nimport { getNativeTokenPriceUsd } from \"@naculus/connect-core\";\n\nexport interface UseBalanceOptions {\n /** Auto-refresh interval in milliseconds. Default: undefined (no auto-refresh). */\n refreshInterval?: number;\n}\n\nexport interface UseBalanceResult {\n /** Raw balance in wei (string), or null if not connected / error */\n balance: string | null;\n /** Human-readable formatted balance in ETH (or native token), or null */\n formatted: string | null;\n /** Native token symbol (e.g. \"ETH\", \"MATIC\") */\n /**\n * The native currency symbol, or null when it is not known.\n *\n * Null rather than \"ETH\". This is rendered beside the number, so a fallback\n * labels 1.5 MATIC or 1.5 SOL as ether. Show the amount without a unit, or\n * hide it, but do not name the wrong one.\n */\n symbol: string | null;\n /** USD price of one native token, or null if unavailable */\n usdPrice: number | null;\n /** Formatted USD value of the balance (e.g. \"$1,234.56\"), or null */\n usdValue: string | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n chain: WalletChain | null;\n}\n\nexport function useBalance(options?: UseBalanceOptions): UseBalanceResult {\n const { evmAccount, isConnected } = useAccount();\n const { chainId, chains } = useWeb3();\n const [balance, setBalance] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [usdPrice, setUsdPrice] = useState<number | null>(null);\n const refreshInterval = options?.refreshInterval;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const currentChain = useMemo(\n () => resolveChain(chains, chainId),\n [chainId, chains],\n );\n const evmChainNumber = currentChain ? chainNumber(currentChain) : null;\n // Memoized: `toViemChain` builds a fresh object per call, and an unmemoized\n // one would change identity every render — which drives the client effects\n // below into a loop that never settles.\n const viemChain = useMemo(\n () => (currentChain ? toViemChain(currentChain, evmChainNumber) : null),\n [currentChain, evmChainNumber],\n );\n\n // No `?? \"ETH\"`. This label is rendered directly beside the number, so a\n // fallback shows \"1.5 ETH\" to someone holding 1.5 MATIC or 1.5 SOL. When\n // the chain is unknown or its native symbol was never configured, the\n // honest answer is that we do not know it.\n const tokenSymbol = useMemo(\n () => currentChain?.token ?? null,\n [currentChain],\n );\n\n const [client, setClient] = useState<PublicClient | null>(null);\n\n useEffect(() => {\n if (!viemChain || !currentChain?.rpcUrl) {\n setClient(null);\n return;\n }\n\n const publicClient = createPublicClient({\n transport: http(currentChain.rpcUrl),\n chain: viemChain,\n });\n\n setClient(publicClient);\n\n // H10: Cleanup previous client on chain change\n return () => {\n // viem PublicClient doesn't have a close method, but we clear the reference\n // to prevent stale state from being used in fetchBalance\n };\n }, [currentChain, viemChain]);\n\n const fetchBalance = useCallback(async () => {\n if (!evmAccount || !client) {\n setBalance(null);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const address = evmAccount.includes(\":\") ? evmAccount.split(\":\").pop()! : evmAccount;\n const address_ = address as Address;\n const [balanceResult, price] = await Promise.all([\n client.getBalance({ address: address_ }),\n chainId ? getNativeTokenPriceUsd(chainId, currentChain?.rpcUrl).catch(() => null) : Promise.resolve(null),\n ]);\n setBalance(balanceResult.toString());\n setUsdPrice(price);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to fetch balance\"));\n setBalance(null);\n setUsdPrice(null);\n } finally {\n setIsLoading(false);\n }\n }, [evmAccount, client, chainId, currentChain?.rpcUrl]);\n\n // Initial fetch on connect / account change\n useEffect(() => {\n if (isConnected && evmAccount) {\n fetchBalance();\n }\n }, [isConnected, evmAccount, fetchBalance]);\n\n // Auto-refresh interval\n useEffect(() => {\n if (refreshInterval && refreshInterval > 0 && isConnected && evmAccount) {\n intervalRef.current = setInterval(fetchBalance, refreshInterval);\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [refreshInterval, isConnected, evmAccount, fetchBalance]);\n\n const formatted = useMemo(() => {\n if (balance === null) return null;\n try {\n return formatEther(BigInt(balance));\n } catch {\n return null;\n }\n }, [balance]);\n\n const usdValue = useMemo(() => {\n if (usdPrice === null || formatted === null) return null;\n const numericBalance = parseFloat(formatted);\n if (Number.isNaN(numericBalance)) return null;\n const totalUsd = numericBalance * usdPrice;\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(totalUsd);\n }, [usdPrice, formatted]);\n\n return {\n balance,\n formatted,\n symbol: tokenSymbol,\n usdPrice,\n usdValue,\n isLoading,\n error,\n refetch: fetchBalance,\n chain: currentChain,\n };\n}\n","import {\n atomicSupportFor,\n type AtomicSupport,\n type ChainCapabilities,\n normalizeCapabilities,\n selectChainCapabilities,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\n// `AtomicSupport` and `ChainCapabilities` are re-exported rather than declared\n// here: Vue needs the same two, and a second declaration of \"three values, not\n// two\" is the one that quietly becomes two.\nexport type { AtomicSupport, ChainCapabilities };\n\nexport interface UseCapabilitiesReturn {\n /** Per-chain, keyed by CAIP-2. Null until a query has actually returned. */\n capabilities: Record<string, ChainCapabilities> | null;\n /** The connected chain's entry, for the common case. */\n current: ChainCapabilities | null;\n /**\n * Atomic support on the connected chain.\n *\n * `\"unknown\"` while loading, when the wallet does not implement the method,\n * and when the query failed — all three are \"we have not been told\", and a\n * caller deciding between an atomic and a sequential path needs to know that\n * rather than be handed a confident `false`.\n */\n atomic: AtomicSupport;\n isFetching: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\n/**\n * What the connected wallet says it can do — EIP-5792\n * `wallet_getCapabilities`.\n *\n * This is the query a dApp makes *before* choosing how to execute: ask whether\n * the wallet batches atomically, then send one batch or a sequence, rather\n * than sending a batch and discovering the answer from a rejection.\n */\nexport function useCapabilities(): UseCapabilitiesReturn {\n const { client, session, chainId } = useWeb3();\n const [capabilities, setCapabilities] = useState<Record<\n string,\n ChainCapabilities\n > | null>(null);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n // Guards a slow answer for a previous session overwriting a newer one.\n const generationRef = useRef(0);\n\n const refetch = useCallback(async () => {\n const generation = ++generationRef.current;\n const activeClient = resolveClient(client);\n if (!activeClient?.getCapabilities || !session) {\n setCapabilities(null);\n setIsFetching(false);\n setError(null);\n return;\n }\n setIsFetching(true);\n setError(null);\n try {\n const raw = await activeClient.getCapabilities(session);\n if (generation !== generationRef.current) return;\n setCapabilities(normalizeCapabilities(raw as Record<string, unknown>));\n } catch (err) {\n if (generation !== generationRef.current) return;\n // Cleared rather than left stale. A capability map from a previous\n // wallet is a worse answer than no answer.\n setCapabilities(null);\n setError(\n err instanceof Error ? err : new Error(\"Capability query failed\"),\n );\n } finally {\n if (generation === generationRef.current) setIsFetching(false);\n }\n }, [client, session]);\n\n useEffect(() => {\n void refetch();\n }, [refetch]);\n\n return {\n capabilities,\n current: selectChainCapabilities(capabilities, chainId),\n atomic: atomicSupportFor(capabilities, chainId),\n isFetching,\n error,\n refetch,\n };\n}\n","import { getClient } from \"../client\";\nimport type { Web3Client } from \"../client\";\n\n/**\n * Resolve the provider-owned client while retaining compatibility with older\n * hook consumers that rendered outside Web3ConnectProvider.\n *\n * The provider value is always authoritative. The legacy accessor is only a\n * fallback for isolated hooks/tests and is never used when a provider client\n * is present, so multiple providers cannot share routing state accidentally.\n */\nexport function resolveClient(client?: Web3Client | null): Web3Client | null {\n return client ?? getClient();\n}\n","import { useMemo } from \"react\";\nimport {\n chainsForNamespace,\n describeChain,\n resolveChain,\n} from \"@naculus/connect-appkit-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { ChainInfo, WalletChain } from \"../types\";\n\n/**\n * The connected chain, and the chains it is possible to switch to.\n *\n * All the judgement lives in `core/chain-selection.ts`, which imports no\n * framework — the Vue binding for this is the same three calls.\n */\nexport function useChain() {\n const { chainId, session, switchChain, chains } = useWeb3();\n\n const currentChain = useMemo<WalletChain | null>(\n () => resolveChain(chains, chainId),\n [chains, chainId],\n );\n\n // Gated on the session, unlike `currentChain`. The two answer different\n // questions: `currentChain` is the chain this client is pointed at,\n // `chainInfo` is the chain of the connection that exists. A consumer\n // rendering chain details only while connected depends on the difference.\n const chainInfo = useMemo<ChainInfo | null>(\n () => (session ? describeChain(chains, chainId) : null),\n [chains, chainId, session],\n );\n\n // Only the chains the connected wallet could actually switch to. Offering\n // an EVM chain to a Solana wallet presents an action that cannot work.\n const availableChains = useMemo<WalletChain[]>(\n () => chainsForNamespace(chains, chainId),\n [chains, chainId],\n );\n\n return {\n chainId,\n currentChain,\n chainInfo,\n availableChains,\n chains: availableChains,\n isEvm: chainId?.startsWith(\"eip155:\") ?? false,\n switchChain,\n };\n}\n","import { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { WalletError } from \"@naculus/connect-core\";\n\nexport function useConnect() {\n const { connect, status } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleConnect = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n await connect();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Connection failed\";\n setError(err instanceof WalletError ? err : new Error(errorMessage));\n } finally {\n setIsLoading(false);\n }\n }, [connect]);\n\n return {\n connect: handleConnect,\n isConnecting: isLoading || status === \"connecting\",\n error\n };\n}","import { bareEvmAddress } from \"@naculus/connect-appkit-core\";\nimport {\n delegateAccount,\n eip155Reference,\n REVOKE_DELEGATE,\n type SentDelegation,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\nimport { useViemClient } from \"./useViemClient\";\n\nexport interface UseDelegateOptions {\n /**\n * Implementations this app trusts to run with full control of the\n * account. Required and empty by default: which contract an EOA runs is the\n * security decision, and nothing is allowed unless listed. Revoking is\n * always allowed.\n */\n allowlist: readonly string[];\n}\n\nexport interface UseDelegateReturn {\n /** Delegate the connected account to `delegate` (must be allowlisted). */\n delegate: (delegate: `0x${string}`) => Promise<SentDelegation | null>;\n /** Clear the account's delegation. */\n revoke: () => Promise<SentDelegation | null>;\n /** The last sent type-4 transaction and the authorization it carried. */\n result: SentDelegation | null;\n isPending: boolean;\n error: Error | null;\n reset: () => void;\n}\n\n/**\n * EIP-7702 owner path: delegate or revoke the connected account by sending\n * a type-4 transaction from it.\n *\n * Embedded wallet only. Browser and WalletConnect wallets upgrade accounts\n * through `wallet_sendCalls`; for them this fails with `method_unsupported`\n * before anything is read or signed. Core's `delegateAccount` applies the\n * allowlist and computes both nonces; this hook only wires the session and\n * the pending-nonce read. Pair with `useDelegation().refetch()` once the\n * transaction is included.\n */\nexport function useDelegate(options: UseDelegateOptions): UseDelegateReturn {\n const { evmAccount } = useAccount();\n const { session, chainId, client } = useWeb3();\n const { publicClient } = useViemClient();\n const [result, setResult] = useState<SentDelegation | null>(null);\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const requestIdRef = useRef(0);\n const inFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n requestIdRef.current += 1;\n };\n }, []);\n\n // A new wallet context invalidates what is on screen; an operation already\n // handed to the wallet keeps the single-flight slot until it settles.\n // biome-ignore lint/correctness/useExhaustiveDependencies: resets state when the wallet context changes.\n useEffect(() => {\n requestIdRef.current += 1;\n setResult(null);\n setIsPending(false);\n setError(null);\n }, [session, chainId, evmAccount]);\n\n const run = useCallback(\n async (\n target: `0x${string}`,\n allowlist: readonly string[],\n ): Promise<SentDelegation | null> => {\n const fail = (nextError: Error): null => {\n setError(nextError);\n return null;\n };\n if (inFlightRef.current) {\n return fail(new Error(\"A delegation is already in progress\"));\n }\n const account = bareEvmAddress(evmAccount);\n if (!session || !account || !chainId) {\n return fail(\n new WalletError(\"wallet_unavailable\", \"No connected EVM account\"),\n );\n }\n // The nonce must come from the chain the wallet will send on.\n if (\n !publicClient ||\n publicClient.chain?.id !== eip155Reference(chainId)\n ) {\n return fail(\n new WalletError(\n \"chain_mismatch\",\n `No RPC client for ${chainId}; refusing to read the nonce elsewhere.`,\n ),\n );\n }\n const connector =\n session.walletType === \"embedded\"\n ? (resolveClient(client)?.embeddedConnector ?? {})\n : {};\n\n const requestId = ++requestIdRef.current;\n inFlightRef.current = true;\n setIsPending(true);\n setError(null);\n setResult(null);\n try {\n const sent = await delegateAccount({\n connector,\n session,\n account,\n chainId,\n delegate: target,\n allowlist,\n getTransactionCount: (address, blockTag) =>\n publicClient.getTransactionCount({ address, blockTag }),\n });\n if (requestId !== requestIdRef.current) return null;\n setResult(sent);\n return sent;\n } catch (err) {\n if (requestId !== requestIdRef.current) return null;\n return fail(\n err instanceof Error ? err : new Error(\"Failed to send delegation\"),\n );\n } finally {\n inFlightRef.current = false;\n if (requestId === requestIdRef.current) setIsPending(false);\n }\n },\n [chainId, client, evmAccount, publicClient, session],\n );\n\n const delegate = useCallback(\n (target: `0x${string}`) => run(target, options.allowlist),\n [run, options.allowlist],\n );\n const revoke = useCallback(() => run(REVOKE_DELEGATE, []), [run]);\n\n // Does not unlock single-flight: the transaction may still be signing or\n // broadcasting, and a second one meanwhile would be a second side effect.\n const reset = useCallback(() => {\n requestIdRef.current += 1;\n setResult(null);\n setIsPending(false);\n setError(null);\n }, []);\n\n return { delegate, revoke, result, isPending, error, reset };\n}\n","import { chainNumber, toViemChain } from \"@naculus/connect-appkit-core\";\nimport { useMemo } from \"react\";\nimport { createPublicClient, http, createWalletClient, type PublicClient, type WalletClient } from \"viem\";\nimport type { WalletChain } from \"../types\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\n\nexport function useViemClient(): {\n publicClient: PublicClient | null;\n walletClient: WalletClient | null;\n chains: WalletChain[];\n} {\n const { evmAccount, isConnected } = useAccount();\n const { currentChain, chains } = useChain();\n\n // Null for anything that is not EIP-155. viem speaks to EVM nodes, and a\n // client built with a stand-in number would address a real chain that is\n // not the one connected.\n const evmChainNumber = currentChain ? chainNumber(currentChain) : null;\n // Memoized: `toViemChain` builds a fresh object per call, and an unmemoized\n // one would change identity every render — which drives the client effects\n // below into a loop that never settles.\n const viemChain = useMemo(\n () => (currentChain ? toViemChain(currentChain, evmChainNumber) : null),\n [currentChain, evmChainNumber],\n );\n\n const publicClient = useMemo<PublicClient | null>(() => {\n if (!viemChain) return null;\n\n return createPublicClient({\n transport: http(viemChain.rpcUrls.default.http[0]),\n chain: viemChain,\n });\n }, [viemChain]);\n\n const walletClient = useMemo<WalletClient | null>(() => {\n if (!isConnected || !evmAccount || !viemChain) return null;\n\n const address = evmAccount.includes(\":\") ? evmAccount.split(\":\").pop()! : evmAccount;\n\n return createWalletClient({\n transport: http(viemChain.rpcUrls.default.http[0]),\n chain: viemChain,\n account: address as `0x${string}`\n });\n }, [isConnected, evmAccount, viemChain]);\n\n return {\n publicClient,\n walletClient,\n chains\n };\n}","import {\n applySettlementVerification,\n DEFAULT_VERIFY_RETRY,\n describePayment,\n type PaymentFetch,\n type PaymentFetchResult,\n type PaymentRecord,\n type VerifyRetryOptions,\n} from \"@naculus/connect-appkit-core\";\nimport type { SettlementVerification } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UsePaymentFetchReturn {\n /** Fetch through the paying fetch; resolves to its full result. */\n payFetch: PaymentFetch;\n /** True while any request is in flight. */\n isPending: boolean;\n /**\n * The most recently completed payment. Every paid request is recorded, in\n * completion order, until `reset()`.\n */\n lastPayment: PaymentRecord | null;\n error: Error | null;\n reset: () => void;\n}\n\nexport interface UsePaymentFetchOptions {\n verify?: (result: PaymentFetchResult) => Promise<SettlementVerification>;\n verifyRetry?: VerifyRetryOptions;\n}\n\n/**\n * State around a caller-owned paying fetch — `createX402Fetch`\n * (`@naculus/payments-x402`) or `createMppFetch` (`@naculus/payments-mpp`),\n * built with the session key and limits the app chooses. What may be paid is\n * decided there and by the session key's policy, not here.\n */\nexport function usePaymentFetch(\n pay: PaymentFetch,\n options: UsePaymentFetchOptions = {},\n): UsePaymentFetchReturn {\n const [inFlight, setInFlight] = useState(0);\n const [lastPayment, setLastPayment] = useState<PaymentRecord | null>(null);\n const [error, setError] = useState<Error | null>(null);\n // Newest request publishes errors; any paid request records its payment\n // (money was spent) until reset() or unmount bumps the epoch.\n const generationRef = useRef(0);\n const epochRef = useRef(0);\n const payRef = useRef(pay);\n payRef.current = pay;\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const verificationRef = useRef(0);\n\n useEffect(() => {\n return () => {\n generationRef.current += 1;\n epochRef.current += 1;\n verificationRef.current += 1;\n };\n }, []);\n\n const payFetch = useCallback<PaymentFetch>(async (input, init) => {\n const own = ++generationRef.current;\n const epoch = epochRef.current;\n setInFlight((n) => n + 1);\n setError(null);\n try {\n const result = await payRef.current(input, init);\n let payment = describePayment(input, result);\n if (payment && epoch === epochRef.current) {\n const verify = optionsRef.current.verify;\n if (!verify) {\n setLastPayment(payment);\n } else {\n payment = applySettlementVerification(payment, { status: \"pending\" });\n setLastPayment(payment);\n const verification = ++verificationRef.current;\n const retry = optionsRef.current.verifyRetry ?? DEFAULT_VERIFY_RETRY;\n void Promise.resolve().then(async () => {\n let outcome: SettlementVerification = { status: \"pending\" };\n for (let attempt = 0; attempt < retry.attempts; attempt += 1) {\n if (attempt > 0) {\n await new Promise((resolve) =>\n setTimeout(resolve, retry.delayMs),\n );\n }\n if (\n epoch !== epochRef.current ||\n verification !== verificationRef.current\n )\n return;\n try {\n outcome = await verify(result);\n } catch (cause) {\n outcome = {\n status: \"unavailable\",\n reason:\n cause instanceof Error\n ? cause.message\n : \"Settlement verification failed\",\n };\n }\n if (outcome.status !== \"pending\") break;\n }\n if (\n epoch === epochRef.current &&\n verification === verificationRef.current\n ) {\n setLastPayment((current) =>\n current\n ? applySettlementVerification(current, outcome)\n : current,\n );\n }\n });\n }\n }\n return result;\n } catch (cause) {\n const normalized =\n cause instanceof Error ? cause : new Error(\"Paid request failed\");\n if (own === generationRef.current) setError(normalized);\n throw normalized;\n } finally {\n setInFlight((n) => n - 1);\n }\n }, []);\n\n const reset = useCallback(() => {\n generationRef.current += 1;\n epochRef.current += 1;\n verificationRef.current += 1;\n setLastPayment(null);\n setError(null);\n }, []);\n\n return { payFetch, isPending: inFlight > 0, lastPayment, error, reset };\n}\n","import {\n createX402WalletSigner,\n findX402Provider,\n type X402SignerUnavailableReason,\n type X402TypedDataSigner,\n} from \"@naculus/connect-appkit-core\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface UseX402SignerReturn {\n signer: X402TypedDataSigner | null;\n reason: X402SignerUnavailableReason | null;\n}\n\n/** Build an x402 signer for the currently connected external EVM wallet. */\nexport function useX402Signer(): UseX402SignerReturn {\n const { session, accounts, chainId, client, switchChain } = useWeb3();\n const accountKey = accounts.join(\"\\0\");\n\n return useMemo(() => {\n void accountKey;\n void chainId;\n const provider = findX402Provider(session, {\n injected: eip6963Connector.getDiscoveredWallets(),\n walletConnect: client.connector,\n });\n return createX402WalletSigner(session, provider, switchChain);\n }, [session, accountKey, chainId, client.connector, switchChain]);\n}\n","import {\n type MppSessionChannel,\n type MppSessionFetch,\n type MppSessionFetchResult,\n type MppSessionForceCloseResult,\n type MppSessionReceipt,\n type MppSessionRequest,\n readCurrentMppSessionChannel,\n readMppRecoveryChannelId,\n readMppSessionReceipt,\n} from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nexport interface UseMppSessionReturn {\n fetch: MppSessionRequest;\n meter: { add(units: bigint): void };\n pending: bigint;\n channel: MppSessionChannel | null;\n lastReceipt: MppSessionReceipt | null;\n recoveryChannelId: string | null;\n isPending: boolean;\n error: Error | null;\n close(): Promise<MppSessionFetchResult>;\n forceClose(): Promise<MppSessionForceCloseResult>;\n reset(): void;\n}\n\nfunction normalizeError(cause: unknown): Error {\n return cause instanceof Error\n ? cause\n : new Error(\"MPP session operation failed\");\n}\n\n/** Reactive state around an MPP session fetch built and owned by the app. */\nexport function useMppSession(session: MppSessionFetch): UseMppSessionReturn {\n const [inFlight, setInFlight] = useState(0);\n const [pending, setPending] = useState(() => session.meter.pending);\n const [channel, setChannel] = useState<MppSessionChannel | null>(() =>\n readCurrentMppSessionChannel(session),\n );\n const [lastReceipt, setLastReceipt] = useState<MppSessionReceipt | null>(\n null,\n );\n const [recoveryChannelId, setRecoveryChannelId] = useState<string | null>(\n null,\n );\n const [error, setError] = useState<Error | null>(null);\n const generationRef = useRef(0);\n const epochRef = useRef(0);\n const mountedRef = useRef(true);\n const sessionRef = useRef(session);\n sessionRef.current = session;\n\n useEffect(() => {\n generationRef.current += 1;\n epochRef.current += 1;\n setInFlight(0);\n setPending(session.meter.pending);\n setChannel(readCurrentMppSessionChannel(session));\n setLastReceipt(null);\n setRecoveryChannelId(null);\n setError(null);\n }, [session]);\n\n useEffect(\n () => () => {\n mountedRef.current = false;\n generationRef.current += 1;\n epochRef.current += 1;\n },\n [],\n );\n\n const run = useCallback(\n async <T>(\n operation: (current: MppSessionFetch) => Promise<T>,\n publish?: (value: T) => void,\n clearsRecovery = false,\n ): Promise<T> => {\n const own = ++generationRef.current;\n const epoch = epochRef.current;\n const invokedSession = sessionRef.current;\n setInFlight((count) => count + 1);\n setError(null);\n try {\n const result = await operation(invokedSession);\n if (mountedRef.current && epoch === epochRef.current) {\n publish?.(result);\n const currentChannel = readCurrentMppSessionChannel(invokedSession);\n setChannel(currentChannel);\n setPending(invokedSession.meter.pending);\n if (clearsRecovery || !currentChannel) setRecoveryChannelId(null);\n }\n return result;\n } catch (cause) {\n const normalized = normalizeError(cause);\n if (mountedRef.current && epoch === epochRef.current) {\n const currentChannel = readCurrentMppSessionChannel(invokedSession);\n setChannel(currentChannel);\n setPending(invokedSession.meter.pending);\n const recovery = readMppRecoveryChannelId(cause);\n if (recovery) setRecoveryChannelId(recovery);\n else if (!currentChannel) setRecoveryChannelId(null);\n if (own === generationRef.current) setError(normalized);\n }\n throw normalized;\n } finally {\n if (mountedRef.current && epoch === epochRef.current) {\n setInFlight((count) => count - 1);\n }\n }\n },\n [],\n );\n\n const fetch = useCallback<MppSessionRequest>(\n (input, init) =>\n run(\n (current) => current(input, init),\n (result) => {\n const receipt = readMppSessionReceipt(result.receipt);\n if (receipt) setLastReceipt(receipt);\n },\n ),\n [run],\n );\n\n const close = useCallback(\n () =>\n run(\n (current) => current.close(),\n (result) => {\n const receipt = readMppSessionReceipt(result.receipt);\n if (receipt) setLastReceipt(receipt);\n },\n true,\n ),\n [run],\n );\n\n const forceClose = useCallback(\n () => run((current) => current.forceClose(), undefined, true),\n [run],\n );\n\n const add = useCallback((units: bigint) => {\n try {\n sessionRef.current.meter.add(units);\n setPending(sessionRef.current.meter.pending);\n setError(null);\n } catch (cause) {\n const normalized = normalizeError(cause);\n setError(normalized);\n setRecoveryChannelId(readMppRecoveryChannelId(cause));\n throw normalized;\n }\n }, []);\n\n const reset = useCallback(() => {\n generationRef.current += 1;\n epochRef.current += 1;\n // Calls from the old epoch no longer decrement the counter.\n setInFlight(0);\n setPending(sessionRef.current.meter.pending);\n setChannel(readCurrentMppSessionChannel(sessionRef.current));\n setLastReceipt(null);\n setRecoveryChannelId(null);\n setError(null);\n }, []);\n\n const meter = useMemo(() => ({ add }), [add]);\n\n return {\n fetch,\n meter,\n pending,\n channel,\n lastReceipt,\n recoveryChannelId,\n isPending: inFlight > 0,\n error,\n close,\n forceClose,\n reset,\n };\n}\n","import {\n createSolanaSessionKeyFlow,\n type SolanaSessionKeyFlowDeps,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n SolanaSessionKeyInfo,\n SolanaSessionKeyScope,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nfunction unavailable(): Promise<never> {\n return Promise.reject(\n new Error(\"No Solana session key manager is connected\"),\n );\n}\n\nexport interface UseSolanaSessionKeyReturn {\n /** The connected owner's keys, newest first. */\n keys: SolanaSessionKeyInfo[];\n /** Create a key; the owner's wallet approves it once. */\n create: (\n scope: SolanaSessionKeyScope,\n ) => Promise<{ key: SolanaSessionKeyInfo; signature: string }>;\n /** Stop a key; the owner's wallet signs the on-chain Revoke. */\n revoke: (id: string) => Promise<{ signature: string }>;\n refresh: () => Promise<void>;\n isPending: boolean;\n error: Error | null;\n}\n\n/**\n * Solana session keys that pay x402 / MPP without a prompt (pass\n * `{ sessionKey: { manager, id }, rpc }` to the paying fetch). The app owns\n * the `SolanaSessionKeyManager` and the RPC; `owner` is the connected\n * wallet's Solana signer role. Keep `manager`, `rpc` and `owner` stable\n * (module scope or `useMemo`): a new object each render rebuilds the flow\n * and refetches the keys every render.\n */\nexport function useSolanaSessionKey(\n deps: SolanaSessionKeyFlowDeps | null,\n): UseSolanaSessionKeyReturn {\n const [keys, setKeys] = useState<SolanaSessionKeyInfo[]>([]);\n const [inFlight, setInFlight] = useState(0);\n const [error, setError] = useState<Error | null>(null);\n const generationRef = useRef(0);\n const manager = deps?.manager;\n const rpc = deps?.rpc;\n const owner = deps?.owner;\n const flow = useMemo(\n () =>\n manager && rpc && owner\n ? createSolanaSessionKeyFlow({ manager, rpc, owner })\n : null,\n [manager, rpc, owner],\n );\n\n const run = useCallback(\n async <T>(action: () => Promise<T>, fallback: string): Promise<T> => {\n const own = ++generationRef.current;\n setInFlight((n) => n + 1);\n setError(null);\n try {\n return await action();\n } catch (cause) {\n const normalized = cause instanceof Error ? cause : new Error(fallback);\n if (own === generationRef.current) setError(normalized);\n throw normalized;\n } finally {\n // Whatever happened, show the stored state before settling (a failed\n // create is revoked, a revoke is local at once) — as the Vue shell.\n if (flow && own === generationRef.current) {\n const next = await flow.list().catch(() => null);\n if (next && own === generationRef.current) setKeys(next);\n }\n setInFlight((n) => n - 1);\n }\n },\n [flow],\n );\n\n const refresh = useCallback(async () => {\n if (!flow) {\n setKeys([]);\n return;\n }\n const own = generationRef.current;\n const next = await flow.list();\n if (own === generationRef.current) setKeys(next);\n }, [flow]);\n\n useEffect(() => {\n generationRef.current += 1;\n void refresh().catch(() => {});\n return () => {\n generationRef.current += 1;\n };\n }, [refresh]);\n\n const create = useCallback(\n (scope: SolanaSessionKeyScope) =>\n flow\n ? run(() => flow.create(scope), \"Could not create the key\")\n : unavailable(),\n [flow, run],\n );\n const revoke = useCallback(\n (id: string) =>\n flow\n ? run(() => flow.revoke(id), \"Could not revoke the key\")\n : unavailable(),\n [flow, run],\n );\n\n return { keys, create, revoke, refresh, isPending: inFlight > 0, error };\n}\n","import {\n readDelegation,\n UNKNOWN_DELEGATION,\n type DelegationStatus,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useAccount } from \"./useAccount\";\nimport { useViemClient } from \"./useViemClient\";\n\nexport interface UseDelegationReturn extends DelegationStatus {\n isFetching: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\n/**\n * Whether the connected EOA currently delegates to contract code — EIP-7702.\n *\n * A delegated account executes like a contract account: it can run several\n * calls in one transaction, which is the thing that decides whether batching\n * is possible at all for an ordinary address.\n *\n * `delegated` is `null` until the code has actually been read, and stays null\n * when the read fails. That is not the same as `false`: treating a failed RPC\n * as \"no delegation\" is how an account that can batch gets sent down the path\n * for one that cannot.\n */\nexport function useDelegation(): UseDelegationReturn {\n const { publicClient } = useViemClient();\n const { evmAccount } = useAccount();\n const [status, setStatus] = useState<DelegationStatus>(UNKNOWN_DELEGATION);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const generationRef = useRef(0);\n\n const address = evmAccount?.includes(\":\")\n ? evmAccount.split(\":\").pop()\n : evmAccount;\n\n const refetch = useCallback(async () => {\n const generation = ++generationRef.current;\n if (!publicClient || !address) {\n setStatus(UNKNOWN_DELEGATION);\n setIsFetching(false);\n setError(null);\n return;\n }\n setIsFetching(true);\n setError(null);\n try {\n const code = await publicClient.getCode({\n address: address as `0x${string}`,\n });\n if (generation !== generationRef.current) return;\n // viem answers `undefined` for an account with no code; the reader wants\n // the RPC's own \"0x\" so that \"no code\" stays distinct from \"not read\".\n setStatus(readDelegation(code ?? \"0x\"));\n } catch (err) {\n if (generation !== generationRef.current) return;\n setStatus(UNKNOWN_DELEGATION);\n setError(err instanceof Error ? err : new Error(\"Code read failed\"));\n } finally {\n if (generation === generationRef.current) setIsFetching(false);\n }\n }, [publicClient, address]);\n\n useEffect(() => {\n void refetch();\n }, [refetch]);\n\n return { ...status, isFetching, error, refetch };\n}\n","\"use client\";\n\nimport {\n bareEvmAddress,\n createDelegationPolicyFlow,\n type DelegationPolicyPreview,\n type DelegationTypedData,\n isVerifiablePolicy,\n type PolicyExecutionAdapter,\n type PolicyExecutionCheck,\n type PolicyExecutionRoute,\n type PolicyExecutionSubmission,\n type PreparedPolicyExecution,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n AtomicityRequirement,\n SessionKeyInfo,\n SessionKeyManagerConfig,\n SessionKeyScope,\n SessionKeyTransaction,\n} from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { recoverMessageAddress } from \"viem\";\nimport { useAccount } from \"./useAccount\";\nimport { useDelegation } from \"./useDelegation\";\nimport {\n type UseExecuteCallsOptions,\n useExecuteCalls,\n} from \"./useExecuteCalls\";\nimport { getSessionKeyManagerForHooks, useSessionKeys } from \"./useSessionKeys\";\nimport { useSignMessage } from \"./useSignMessage\";\n\n// The decisions — message format, verification, create/preview/sign/execute\n// ordering and every refusal — live in appkit-core (delegation-policy.ts),\n// shared with the Vue composable. This file wires them to React state and\n// the provider hooks.\nexport { buildDelegationPolicyMessage } from \"@naculus/connect-appkit-core\";\nexport type {\n DelegationPolicyPreview,\n PolicyExecutionAdapter,\n PolicyExecutionCheck,\n PolicyExecutionRoute,\n PolicyExecutionSubmission,\n PreparedPolicyExecution,\n};\n\nexport interface UseDelegationPolicyOptions {\n /** Must include a host-provided encryptionKey before a policy can be created. */\n managerConfig?: SessionKeyManagerConfig;\n execution?: UseExecuteCallsOptions;\n /** Domain shown in the signed policy. Defaults to the browser origin. */\n origin?: string;\n /** Concrete AA-module or EIP-7702 executor for promptless submissions. */\n adapter?: PolicyExecutionAdapter;\n /**\n * For `eip7702` policies: the wallet's EIP-712 signer. `message.salt` is a\n * decimal string (JSON-safe, as `eth_signTypedData_v4` takes it); for viem's\n * `signTypedData`, pass `{ ...t, message: { ...t.message, salt: BigInt(t.message.salt) } }`.\n */\n signTypedData?: (typedData: DelegationTypedData) => Promise<string>;\n /** For `eip7702` policies: the connected EVM chain number. */\n chainId?: number | null;\n}\n\nexport interface UseDelegationPolicyReturn {\n policies: SessionKeyInfo[];\n /** Active policies whose persisted signature still verifies. */\n activePolicies: SessionKeyInfo[];\n storageAvailable: boolean;\n loading: boolean;\n isBusy: boolean;\n error: Error | null;\n delegation: ReturnType<typeof useDelegation>;\n createPolicy: (scope: Partial<SessionKeyScope>) => Promise<SessionKeyInfo>;\n revokePolicy: (policyId: string) => Promise<void>;\n previewPolicyExecution: (\n policyId: string,\n tx: SessionKeyTransaction,\n callCount?: number,\n atomicity?: AtomicityRequirement,\n ) => Promise<DelegationPolicyPreview>;\n /**\n * Sign one prepared execution after enforcing the persisted policy. The\n * digest is checked against `prepared.request` before signing. This returns\n * a signature only; an AA/7702 adapter must still broadcast it.\n *\n * Breaking change: the input is now the `PreparedPolicyExecution` (with its\n * `request`) instead of a bare `digest` and `tx`.\n */\n signPolicyDigest: (\n policyId: string,\n prepared: PreparedPolicyExecution,\n ) => Promise<`0x${string}`>;\n /** Prepare, policy-check, session-sign, and submit one exact operation. */\n executePolicy: (\n policyId: string,\n tx: SessionKeyTransaction,\n ) => Promise<PolicyExecutionSubmission>;\n refresh: () => Promise<void>;\n clearError: () => void;\n}\n\n/**\n * Complete product flow for local, signed, persistent session policies.\n *\n * This intentionally supports `offchain` mode only. Creating an EIP-7702 or\n * AA-module policy requires a real on-chain executor; accepting those modes\n * here would turn a local record into a false delegation claim.\n */\nexport function useDelegationPolicy(\n options: UseDelegationPolicyOptions = {},\n): UseDelegationPolicyReturn {\n const { evmAccount } = useAccount();\n const signer = bareEvmAddress(evmAccount);\n const delegation = useDelegation();\n const execution = useExecuteCalls(options.execution);\n const { signMessage } = useSignMessage();\n const sessionKeys = useSessionKeys(options.managerConfig);\n const manager = getSessionKeyManagerForHooks(options.managerConfig);\n\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [verifiedPolicyIds, setVerifiedPolicyIds] = useState<Set<string>>(\n () => new Set(),\n );\n const [isVerifying, setIsVerifying] = useState(false);\n\n const policyOrigin =\n options.origin ??\n (typeof window !== \"undefined\" ? window.location.origin : \"unknown\");\n const encryptionKeyConfigured = Boolean(options.managerConfig?.encryptionKey);\n const sponsorship = options.execution?.sponsorship;\n const { refresh, storageAvailable } = sessionKeys;\n const { preview } = execution;\n const { delegated, delegate } = delegation;\n\n const flow = useMemo(\n () =>\n createDelegationPolicyFlow({\n manager,\n origin: policyOrigin,\n signer: () => signer,\n signMessage,\n verifySignature: async ({ message, signature, signerAddress }) => {\n const recovered = await recoverMessageAddress({ message, signature });\n return recovered.toLowerCase() === signerAddress.toLowerCase();\n },\n previewExecution: preview,\n sponsorship,\n adapter: options.adapter,\n signTypedData: options.signTypedData,\n chainId: () => options.chainId ?? null,\n delegation: () => ({ delegated, delegate }),\n encryptionKeyConfigured,\n storageAvailable: () => storageAvailable,\n refresh,\n }),\n [\n manager,\n policyOrigin,\n signer,\n signMessage,\n preview,\n sponsorship,\n options.adapter,\n options.signTypedData,\n options.chainId,\n delegated,\n delegate,\n encryptionKeyConfigured,\n storageAvailable,\n refresh,\n ],\n );\n\n // Verify every candidate policy whenever the list changes; a stale\n // verification for a previous list must not mark the current one.\n useEffect(() => {\n let cancelled = false;\n const candidates = sessionKeys.sessions.filter(isVerifiablePolicy);\n if (candidates.length === 0) {\n setVerifiedPolicyIds(new Set());\n setIsVerifying(false);\n return () => {\n cancelled = true;\n };\n }\n setIsVerifying(true);\n void Promise.all(\n candidates.map(\n async (policy) =>\n [policy.id, await flow.verifyStoredPolicy(policy)] as const,\n ),\n )\n .then((results) => {\n if (!cancelled) {\n setVerifiedPolicyIds(\n new Set(\n results\n .filter(([, verified]) => verified)\n .map(([policyId]) => policyId),\n ),\n );\n }\n })\n .catch((cause) => {\n if (!cancelled) {\n setVerifiedPolicyIds(new Set());\n setError(\n cause instanceof Error\n ? cause\n : new Error(\"Policy verification failed\"),\n );\n }\n })\n .finally(() => {\n if (!cancelled) setIsVerifying(false);\n });\n return () => {\n cancelled = true;\n };\n }, [sessionKeys.sessions, flow]);\n\n const clearError = useCallback(() => {\n setError(null);\n sessionKeys.clearError();\n }, [sessionKeys]);\n\n /** Busy/error state around a flow step; the error is rethrown as before. */\n const track = useCallback(\n async <T>(step: () => Promise<T>, fallback: string): Promise<T> => {\n setIsBusy(true);\n setError(null);\n try {\n return await step();\n } catch (cause) {\n const next = cause instanceof Error ? cause : new Error(fallback);\n setError(next);\n throw next;\n } finally {\n setIsBusy(false);\n }\n },\n [],\n );\n\n const createPolicy = useCallback(\n (scope: Partial<SessionKeyScope>) =>\n track(() => flow.createPolicy(scope), \"Policy creation failed\"),\n [flow, track],\n );\n const revokePolicy = useCallback(\n (policyId: string) =>\n track(() => flow.revokePolicy(policyId), \"Policy revocation failed\"),\n [flow, track],\n );\n const executePolicy = useCallback(\n (policyId: string, tx: SessionKeyTransaction) =>\n track(() => flow.executePolicy(policyId, tx), \"Policy execution failed\"),\n [flow, track],\n );\n\n const activePolicies = sessionKeys.activeSessions.filter((policy) =>\n verifiedPolicyIds.has(policy.id),\n );\n\n return {\n policies: sessionKeys.sessions,\n activePolicies,\n storageAvailable: sessionKeys.storageAvailable,\n loading: sessionKeys.loading || isVerifying,\n isBusy,\n error: error ?? sessionKeys.error,\n delegation,\n createPolicy,\n revokePolicy,\n previewPolicyExecution: flow.previewPolicyExecution,\n signPolicyDigest: flow.signPolicyDigest,\n executePolicy,\n refresh: sessionKeys.refresh,\n clearError,\n };\n}\n","import {\n type AtomicityRequirement,\n type BatchCall,\n type ExecutionPlan,\n planExecution,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useDelegation } from \"./useDelegation\";\nimport { useCallback, useState } from \"react\";\nimport { useCapabilities } from \"./useCapabilities\";\nimport { useSendCalls } from \"./useSendCalls\";\n\n/** Which executor actually runs the calls. */\nexport type ExecutionRoute = \"wallet-batch\" | \"user-operation\" | \"sequential\";\n\nexport interface ExecutionPreview extends ExecutionPlan {\n route: ExecutionRoute | null;\n}\n\nexport interface UseExecuteCallsOptions {\n /** Default requirement for `execute`. Per-call override is also accepted. */\n atomicity?: AtomicityRequirement;\n /**\n * Whether gas must be covered by a paymaster.\n *\n * A separate axis from atomicity: it answers who pays, not whether the calls\n * land together, and either can end in a refusal on its own. A route that\n * executes perfectly but charges a user who was promised sponsored gas is\n * still the wrong route, and signing is too late to find out.\n */\n sponsorship?: AtomicityRequirement;\n /**\n * ERC-7677 service passed to `wallet_sendCalls` when the wallet advertises\n * paymaster support. Advertising support alone does not sponsor a call: the\n * service URL (and optional context) is the executable configuration.\n */\n paymasterService?: {\n url: string;\n context?: Record<string, unknown>;\n };\n /**\n * A smart-account executor, typically `sendUserOp` from\n * `useSendUserOperation`.\n *\n * A UserOperation carries its calls in one on-chain execution, so it is\n * atomic by construction. Supplying this gives a wallet that cannot batch a\n * route that still satisfies `\"required\"` instead of a refusal.\n */\n userOperation?: (calls: BatchCall[]) => Promise<string>;\n /** Whether the supplied UserOperation executor is configured to sponsor gas. */\n userOperationSponsored?: boolean;\n}\n\nexport interface UseExecuteCallsReturn {\n /**\n * What would happen for this many calls, without sending anything.\n *\n * This is the query EIP-5792 exists for. An application can show \"these two\n * will land together\" or \"these will be sent one by one\" before the user\n * commits, rather than discovering it from a half-executed batch.\n */\n preview: (\n callCount: number,\n atomicity?: AtomicityRequirement,\n ) => ExecutionPreview;\n execute: (\n calls: BatchCall[],\n atomicity?: AtomicityRequirement,\n ) => Promise<string>;\n isExecuting: boolean;\n error: Error | null;\n /** The route the last `execute` took. */\n lastRoute: ExecutionRoute | null;\n reset: () => void;\n}\n\n/**\n * Route a set of calls to whichever executor can honour the caller's\n * atomicity requirement — and refuse when none can.\n *\n * `useSendCalls` already picks between an EIP-5792 batch and a sequential\n * fallback, but it picks silently and always sends something. A caller that\n * batched an approve with the swap it pays for cannot tell the difference\n * between \"these landed together\" and \"the approve landed and the swap did\n * not\", which is the outcome that leaves an approval standing to a contract\n * the user never transacted with.\n */\nexport function useExecuteCalls(\n options: UseExecuteCallsOptions = {},\n): UseExecuteCallsReturn {\n const { current, atomic } = useCapabilities();\n const { delegated, delegate } = useDelegation();\n const { sendCalls } = useSendCalls();\n const [isExecuting, setIsExecuting] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [lastRoute, setLastRoute] = useState<ExecutionRoute | null>(null);\n\n const defaultAtomicity = options.atomicity ?? \"preferred\";\n const defaultSponsorship = options.sponsorship ?? \"any\";\n const paymasterService = options.paymasterService;\n const userOperation = options.userOperation;\n const userOperationSponsored = options.userOperationSponsored ?? false;\n const walletPaymasterAvailable = Boolean(\n current?.raw?.paymasterService?.supported && paymasterService,\n );\n\n const preview = useCallback(\n (callCount: number, atomicity = defaultAtomicity): ExecutionPreview => {\n const plan = planExecution(\n {\n atomicBatch: atomic === \"supported\",\n // \"The wallet said no\" and \"the wallet has no way to say\" are\n // different facts, and the planner treats them differently.\n discovered: atomic !== \"unknown\",\n // ERC-7677 explicitly says an app MUST NOT assume the paymaster it\n // supplies is ultimately used. A supported capability plus a URL is\n // therefore a requestable route, not proof that the user will not\n // pay. Only an app-controlled sponsored executor can satisfy the\n // strict preflight guarantee.\n sponsoredTransactions: false,\n ...(current?.maxBatchSize === undefined\n ? {}\n : { maxBatchSize: current.maxBatchSize }),\n },\n callCount,\n { atomicity, sponsorship: defaultSponsorship },\n );\n\n // Capability advertising plus a paymaster URL is only a request for\n // sponsorship; EIP-7677 does not guarantee who ultimately paid. Keep a\n // strict sponsorship requirement fail-closed unless the app controls a\n // sponsored UserOperation route.\n const sponsorshipRefused =\n defaultSponsorship === \"required\" && !userOperationSponsored;\n if (plan.strategy === \"atomic-batch\" && !sponsorshipRefused) {\n return {\n ...plan,\n reason:\n plan.reason +\n (walletPaymasterAvailable\n ? \" A paymaster service will be requested, but the wallet's final fee payer must be checked after execution.\"\n : \"\"),\n route: \"wallet-batch\",\n };\n }\n // Delegation is evidence about the account, not about the wallet's RPC\n // surface, so it never upgrades a capability — a delegated EOA behind a\n // wallet that does not expose wallet_sendCalls still cannot be asked to\n // batch. It is said out loud because it is the difference between \"this\n // cannot work\" and \"this wallet has not wired it up\".\n const delegationNote =\n delegated && atomic !== \"supported\"\n ? ` This account does delegate to ${delegate} under EIP-7702, so it is capable of batching even though the wallet has not offered to.`\n : \"\";\n // A UserOperation executes its calls in one transaction, so it rescues\n // both a refusal and a non-atomic fallback the caller did not want.\n const needsUserOperation =\n (atomicity !== \"any\" && !plan.atomic) ||\n defaultSponsorship === \"required\";\n if (userOperation && needsUserOperation && !sponsorshipRefused) {\n return {\n strategy: \"atomic-batch\",\n atomic: true,\n sponsored: userOperationSponsored,\n reason:\n defaultSponsorship === \"required\" && !plan.sponsored\n ? \"The wallet batch is not configured for sponsored gas, so the calls are executed through the configured sponsored UserOperation route.\"\n : \"This wallet cannot batch, so the calls are executed as a single UserOperation through the smart account, which lands as one transaction.\",\n route: \"user-operation\",\n };\n }\n if (sponsorshipRefused) {\n return {\n strategy: \"refuse\",\n atomic: plan.atomic,\n sponsored: false,\n reason:\n \"Sponsored gas was required, but there is no executable sponsored route: no paymaster is configured for a wallet batch, and capability advertising alone cannot pay for a sequential transaction.\",\n route: null,\n };\n }\n if (plan.strategy === \"refuse\") {\n return { ...plan, reason: plan.reason + delegationNote, route: null };\n }\n return {\n ...plan,\n reason: plan.reason + delegationNote,\n route: \"sequential\",\n };\n },\n [\n atomic,\n current,\n walletPaymasterAvailable,\n userOperation,\n userOperationSponsored,\n defaultAtomicity,\n defaultSponsorship,\n delegated,\n delegate,\n ],\n );\n\n const execute = useCallback(\n async (calls: BatchCall[], atomicity = defaultAtomicity) => {\n setIsExecuting(true);\n setError(null);\n try {\n const chosen = preview(calls.length, atomicity);\n if (chosen.route === null) {\n // Refused before anything is sent. The alternative is a partial\n // execution the caller explicitly said it could not accept.\n throw new WalletError(\"method_not_allowed\", chosen.reason);\n }\n setLastRoute(chosen.route);\n\n if (chosen.route === \"user-operation\") {\n return await userOperation!(calls);\n }\n return await sendCalls(calls, {\n strategy:\n chosen.route === \"wallet-batch\" ? \"atomic-batch\" : \"sequential\",\n ...(chosen.route === \"wallet-batch\" && walletPaymasterAvailable\n ? { paymasterService }\n : {}),\n });\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Execution failed\");\n setError(e);\n throw e;\n } finally {\n setIsExecuting(false);\n }\n },\n [\n preview,\n sendCalls,\n userOperation,\n defaultAtomicity,\n paymasterService,\n walletPaymasterAvailable,\n ],\n );\n\n return {\n preview,\n execute,\n isExecuting,\n error,\n lastRoute,\n reset: () => {\n setError(null);\n setLastRoute(null);\n },\n };\n}\n","import { errorMessage } from \"@naculus/connect-appkit-core\";\nimport type {\n BatchCall,\n CallsStatus,\n ExecutionStrategy,\n} from \"@naculus/connect-core\";\nimport {\n chooseExecutionStrategy,\n getAccountCapabilities,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { extractTransactionHash } from \"./transaction-hash\";\n\n/**\n * Where a batch has got to.\n *\n * `\"submitted\"` was `\"confirmed\"`, which this hook is two steps away from\n * knowing. `wallet_sendCalls` answers with a bundle identifier, and a bundle\n * identifier does not even promise the calls were broadcast — EIP-5792 lets a\n * wallet accept them and send later. The sequential fallback returns the last\n * transaction hash, which promises broadcast and nothing more.\n *\n * `getCallsStatus` is what turns a bundle identifier into an outcome.\n */\nexport type SendCallsStatus =\n | \"idle\"\n | \"awaiting_approval\"\n | \"submitted\"\n | \"failed\";\n\nexport function useSendCalls() {\n const { session, chainId, client } = useWeb3();\n const [status, setStatus] = useState<SendCallsStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n const [batchHash, setBatchHash] = useState<string | null>(null);\n const [callsStatus, setCallsStatus] = useState<CallsStatus | null>(null);\n const [execution, setExecution] = useState<ExecutionStrategy | null>(null);\n\n const sendCalls = useCallback(\n async (\n calls: BatchCall[],\n options?: {\n chainId?: string;\n strategy?: ExecutionStrategy;\n paymasterService?: {\n url: string;\n context?: Record<string, unknown>;\n };\n },\n ): Promise<string> => {\n if (!session) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n if (calls.length === 0) {\n setStatus(\"failed\");\n const err = new WalletError(\n \"invalid_input\",\n \"At least one call is required\",\n );\n setError(err);\n throw err;\n }\n\n setStatus(\"awaiting_approval\");\n setError(null);\n setBatchHash(null);\n\n try {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const targetChain = options?.chainId ?? chainId ?? undefined;\n\n // Ask what the account can actually do before assuming it can batch.\n // A wallet with no answer, or one that says no, gets the sequential\n // path instead of an outright failure — the caller asked to send\n // these calls, not specifically to use EIP-5792.\n const strategy =\n options?.strategy ??\n chooseExecutionStrategy(\n await getAccountCapabilities(activeClient, session, targetChain),\n calls.length,\n );\n setExecution(strategy);\n\n if (strategy === \"atomic-batch\") {\n // This path was chosen because the wallet said it can execute the\n // calls atomically, so require it. Without the flag EIP-5792 lets\n // the wallet split the batch anyway, and the caller would be told\n // \"atomic-batch\" for an execution that was not.\n const result = await activeClient.sendCalls(\n session,\n calls,\n targetChain,\n {\n atomicRequired: true,\n ...(options?.paymasterService\n ? { paymasterService: options.paymasterService }\n : {}),\n },\n );\n setStatus(\"submitted\");\n setBatchHash(result);\n return result;\n }\n\n // Sequential fallback. These calls are NOT atomic: an earlier one can\n // land while a later one fails, so the returned hash is the last\n // transaction and `execution` says how it was sent. A caller that\n // needs all-or-nothing must check `capabilities.atomicBatch` first.\n let lastHash = \"\";\n for (let i = 0; i < calls.length; i++) {\n const call = calls[i];\n try {\n lastHash = extractTransactionHash(\n await activeClient.sendTransaction(session, {\n transaction: {\n to: call.to,\n data: call.data,\n value: call.value,\n },\n chainId: targetChain,\n }),\n );\n } catch (err) {\n // The dangerous case for this path: an approve landed and the swap\n // it was for did not. Say how far it got, because the caller now\n // has on-chain state it did not ask for and cannot infer the count\n // from a bare wallet error.\n throw new WalletError(\n \"tx_failed\",\n `Call ${i + 1} of ${calls.length} failed after ${i} already landed ` +\n `(sent sequentially — this wallet cannot batch atomically): ` +\n `${errorMessage(err)}`,\n );\n }\n }\n setStatus(\"submitted\");\n setBatchHash(lastHash);\n return lastHash;\n } catch (err) {\n setStatus(\"failed\");\n setError(err instanceof Error ? err : new Error(errorMessage(err)));\n throw err;\n }\n },\n [session, chainId, client],\n );\n\n const getCallsStatus = useCallback(\n async (hash?: string): Promise<CallsStatus> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n const bundleHash = hash ?? batchHash;\n if (!bundleHash) {\n throw new WalletError(\"invalid_input\", \"No bundle hash available\");\n }\n // After a sequential send the stored handle is a transaction hash, not an\n // EIP-5792 bundle identifier. Querying the wallet with it returns an\n // opaque error at best; refusing here names the actual reason.\n if (!hash && execution === \"sequential\") {\n throw new WalletError(\n \"invalid_input\",\n \"Calls were sent sequentially, so there is no bundle to query. \" +\n \"Track the returned transaction hash instead.\",\n );\n }\n\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const result = await activeClient.getCallsStatus(session, bundleHash);\n setCallsStatus(result);\n return result;\n },\n [session, batchHash, client, execution],\n );\n\n /**\n * Ask the wallet to display the bundle.\n *\n * Cosmetic: a wallet that refuses, or has no such screen, leaves the bundle\n * exactly as it was. Returns whether the wallet showed it, so a caller can\n * fall back to its own UI rather than surfacing a transaction error for\n * something that is not one.\n */\n const showCallsStatus = useCallback(\n async (hash?: string): Promise<boolean> => {\n if (!session) return false;\n const bundleHash = hash ?? batchHash;\n if (!bundleHash) return false;\n // After a sequential send the handle is a transaction hash, not a\n // bundle, so there is nothing for the wallet to look up.\n if (!hash && execution === \"sequential\") return false;\n\n const activeClient = resolveClient(client);\n if (!activeClient?.showCallsStatus) return false;\n try {\n await activeClient.showCallsStatus(session, bundleHash);\n return true;\n } catch {\n return false;\n }\n },\n [session, batchHash, client, execution],\n );\n\n const reset = useCallback(() => {\n setStatus(\"idle\");\n setError(null);\n setBatchHash(null);\n setCallsStatus(null);\n setExecution(null);\n }, []);\n\n return {\n sendCalls,\n getCallsStatus,\n showCallsStatus,\n status,\n error,\n batchHash,\n callsStatus,\n /**\n * How the last send was actually executed, or null before one runs.\n *\n * \"sequential\" means the calls were sent one at a time and are NOT atomic:\n * an earlier call can land while a later one fails. Surfaced rather than\n * hidden because a caller batching an approve + swap needs to know which\n * guarantee it got.\n */\n execution,\n reset,\n isSending: status === \"awaiting_approval\",\n };\n}\n","import { WalletError } from \"@naculus/connect-core\";\n\n/** Normalize connector-specific send results without accepting fake success. */\nexport function extractTransactionHash(result: unknown): string {\n const candidate =\n typeof result === \"string\"\n ? result\n : result && typeof result === \"object\" && \"hash\" in result\n ? (result as { hash?: unknown }).hash\n : undefined;\n\n if (typeof candidate === \"string\" && /^0x[0-9a-fA-F]{64}$/.test(candidate)) {\n return candidate;\n }\n\n throw new WalletError(\n \"tx_failed\",\n \"Wallet did not return a valid 32-byte transaction hash\",\n );\n}\n","\"use client\";\n\nimport {\n checkSessionKeyRailGrant,\n type Eip3009SessionKeyRail,\n getSharedSessionKeyManager,\n resetSharedSessionKeyManager,\n type SessionKeyRailGrantCheck,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n SessionKeyInfo,\n SessionKeyManagerConfig,\n SessionKeyScope,\n} from \"@naculus/connect-core\";\nimport { type SessionKeyManager, WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\n// The process-wide manager and its config guard live in appkit-core so the\n// React hooks and the Vue composables share one instance and one policy.\nexport function getSessionKeyManagerForHooks(\n config?: SessionKeyManagerConfig,\n): SessionKeyManager {\n return getSharedSessionKeyManager(config);\n}\n\n/** @internal test helper */\nexport function __resetSessionKeyManagerForTests(): void {\n resetSharedSessionKeyManager();\n}\n\n// ─── useSessionKeys ────────────────────────────────────────────────────\n\nexport interface UseSessionKeysReturn {\n /** All session keys (active, revoked, expired) */\n sessions: SessionKeyInfo[];\n /** Only active session keys */\n activeSessions: SessionKeyInfo[];\n /** Whether data is loading */\n loading: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Refresh the session list from storage */\n refresh: () => Promise<void>;\n /** Clear any error */\n clearError: () => void;\n /** Whether the storage backend is available */\n storageAvailable: boolean;\n /** Fail-closed check for whether a stored scope grants EIP-3009 signing. */\n checkRailGrant: (\n scope: SessionKeyScope | null | undefined,\n rail: Eip3009SessionKeyRail,\n ) => SessionKeyRailGrantCheck;\n}\n\n/**\n * Hook to list and manage session keys.\n *\n * @example\n * ```tsx\n * const { sessions, activeSessions, refresh } = useSessionKeys();\n * ```\n */\nexport function useSessionKeys(\n config?: SessionKeyManagerConfig,\n): UseSessionKeysReturn {\n const { session } = useWeb3();\n const [sessions, setSessions] = useState<SessionKeyInfo[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n const storageAvailable = manager.isStorageAvailable();\n\n const refresh = useCallback(async () => {\n if (!session) {\n setSessions([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const keys = await manager.listSessions();\n if (mountedRef.current) {\n setSessions(keys);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to load session keys\"),\n );\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [session, manager]);\n\n // Load sessions on mount and on session change\n useEffect(() => {\n mountedRef.current = true;\n refresh();\n return () => {\n mountedRef.current = false;\n };\n }, [refresh]);\n\n const activeSessions = sessions.filter((s) => s.status === \"active\");\n\n return {\n sessions,\n activeSessions,\n loading,\n error,\n refresh,\n clearError,\n storageAvailable,\n checkRailGrant: checkSessionKeyRailGrant,\n };\n}\n\n// ─── useCreateSessionKey ───────────────────────────────────────────────\n\nexport interface UseCreateSessionKeyReturn {\n /** Create a new session key */\n createSessionKey: (\n scope?: Partial<SessionKeyScope>,\n signerAddress?: `0x${string}`,\n ) => Promise<SessionKeyInfo>;\n /** The last created session key info */\n lastCreated: SessionKeyInfo | null;\n /** Whether creation is in progress */\n isCreating: boolean;\n /** Error from last creation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to create new session keys.\n *\n * @example\n * ```tsx\n * const { createSessionKey, lastCreated, isCreating } = useCreateSessionKey();\n *\n * const handleCreate = async () => {\n * const session = await createSessionKey({\n * expiry: Math.floor(Date.now() / 1000) + 1800, // 30 min\n * maxTotalValue: parseEther(\"0.1\"),\n * });\n * };\n * ```\n */\nexport function useCreateSessionKey(\n config?: SessionKeyManagerConfig,\n): UseCreateSessionKeyReturn {\n const { session } = useWeb3();\n const [lastCreated, setLastCreated] = useState<SessionKeyInfo | null>(null);\n const [isCreating, setIsCreating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n\n const createSessionKey = useCallback(\n async (\n scope?: Partial<SessionKeyScope>,\n signerAddress?: `0x${string}`,\n ): Promise<SessionKeyInfo> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active wallet session\");\n }\n\n setIsCreating(true);\n setError(null);\n try {\n const resolvedSigner = signerAddress ?? undefined;\n const info = await manager.createSessionKey(scope, resolvedSigner);\n setLastCreated(info);\n return info;\n } catch (err) {\n const errorObj =\n err instanceof Error\n ? err\n : new Error(\"Failed to create session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsCreating(false);\n }\n },\n [session, manager],\n );\n\n return {\n createSessionKey,\n lastCreated,\n isCreating,\n error,\n clearError,\n };\n}\n\n// ─── useRevokeSession ──────────────────────────────────────────────────\n\nexport interface UseRevokeSessionReturn {\n /** Revoke a session key by ID */\n revokeSession: (sessionId: string) => Promise<void>;\n /** Whether revoking is in progress */\n isRevoking: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to revoke a session key.\n *\n * @example\n * ```tsx\n * const { revokeSession, isRevoking } = useRevokeSession();\n * await revokeSession(sessionId);\n * ```\n */\nexport function useRevokeSession(\n config?: SessionKeyManagerConfig,\n): UseRevokeSessionReturn {\n const [isRevoking, setIsRevoking] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n\n const revokeSession = useCallback(\n async (sessionId: string): Promise<void> => {\n setIsRevoking(true);\n setError(null);\n try {\n await manager.revokeSession(sessionId);\n } catch (err) {\n const errorObj =\n err instanceof Error\n ? err\n : new Error(\"Failed to revoke session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsRevoking(false);\n }\n },\n [manager],\n );\n\n return {\n revokeSession,\n isRevoking,\n error,\n clearError,\n };\n}\n\n// ─── useSendWithSession ────────────────────────────────────────────────\n\nexport interface UseSendWithSessionReturn {\n /** Check if a transaction is within a session's scope */\n checkScope: (\n sessionId: string,\n tx: {\n to?: string;\n value?: string;\n data?: string;\n chainId?: number;\n gas?: string;\n },\n ) => Promise<{\n valid: boolean;\n reason?: string;\n remainingGas?: bigint;\n remainingValue?: bigint;\n remainingTxCount?: number;\n }>;\n /** Whether an operation is in progress */\n isBusy: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to check a transaction against a session key's scope.\n *\n * @example\n * ```tsx\n * const { checkScope } = useSendWithSession();\n *\n * const check = await checkScope(sessionId, tx);\n * ```\n */\nexport function useSendWithSession(\n config?: SessionKeyManagerConfig,\n): UseSendWithSessionReturn {\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManagerForHooks(config);\n\n const checkScope = useCallback(\n async (\n sessionId: string,\n tx: {\n to?: string;\n value?: string;\n data?: string;\n chainId?: number;\n gas?: string;\n },\n ) => {\n setIsBusy(true);\n setError(null);\n try {\n return await manager.checkSessionScope(sessionId, tx);\n } catch (err) {\n const errorObj =\n err instanceof Error\n ? err\n : new Error(\"Failed to check session scope\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsBusy(false);\n }\n },\n [manager],\n );\n\n return {\n checkScope,\n isBusy,\n error,\n clearError,\n };\n}\n\n/**\n * Reset the global session key manager (useful for testing / cleanup).\n */\nexport function resetSessionKeyManager(): void {\n resetSharedSessionKeyManager();\n}\n","import { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { resolveClient } from \"./client-resolver\";\n\nexport function useSignMessage() {\n const { session, chainId, client } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const signMessage = useCallback(\n async (message: string): Promise<string> => {\n // Precondition checks — set error state before throwing (consistent with useSendTransaction pattern)\n if (!session) {\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n const address = session.namespaces.eip155?.accounts[0]\n ?? Object.values(session.namespaces)[0]?.accounts[0];\n\n if (!address) {\n const err = new WalletError(\"wallet_unavailable\", \"No account found\");\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const result = (await activeClient.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined\n })) as string;\n\n return result;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Signing failed\";\n const error = err instanceof Error ? err : new Error(errorMessage);\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [session, chainId, client]\n );\n\n return {\n signMessage,\n isSigning: isLoading,\n error\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport function useDisconnect() {\n const { disconnect, status } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const handleDisconnect = useCallback(async () => {\n if (status === \"disconnected\") return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await disconnect();\n } catch (err) {\n if (!mountedRef.current) return;\n setError(err instanceof Error ? err : new Error(\"Disconnect failed\"));\n } finally {\n if (mountedRef.current) setIsLoading(false);\n }\n }, [disconnect, status]);\n\n return {\n disconnect: handleDisconnect,\n isDisconnecting: isLoading,\n error,\n cleanup: () => { mountedRef.current = false; },\n };\n}","import { WalletError } from \"@naculus/connect-core\";\nimport type {\n StorageSecurityReport,\n WalletAccount,\n WalletData,\n WalletNamespace,\n} from \"@naculus/connector-embedded\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\n/** Public account metadata. Signing material never enters React state. */\nexport type EmbeddedWalletAccountView = Omit<WalletAccount, \"privateKey\">;\n\n/**\n * Public wallet metadata safe to render or pass through application state.\n *\n * `WalletData` is deliberately still returned by explicit create/import\n * calls because those are recovery workflows. The long-lived `wallet` state\n * must never retain the mnemonic or account private keys.\n */\nexport interface EmbeddedWalletView {\n accounts: EmbeddedWalletAccountView[];\n activeNamespace: WalletNamespace;\n createdAt: number;\n chainId?: string;\n version?: 2;\n /** Whether the stored record can derive missing namespace accounts. */\n recoveryAvailable: boolean;\n readonly address?: string;\n}\n\nfunction toWalletView(data: WalletData): EmbeddedWalletView {\n const activeNamespace = data.activeNamespace ?? \"eip155\";\n const accounts = Array.isArray(data.accounts)\n ? data.accounts.map(({ namespace, address, derivationPath }) => ({\n namespace,\n address,\n ...(derivationPath ? { derivationPath } : {}),\n }))\n : data.address\n ? [{ namespace: activeNamespace, address: data.address }]\n : [];\n\n return {\n accounts,\n activeNamespace,\n createdAt: data.createdAt ?? 0,\n ...(data.chainId ? { chainId: data.chainId } : {}),\n ...(data.version ? { version: data.version } : {}),\n recoveryAvailable: Boolean(data.mnemonic),\n address:\n accounts.find((account) => account.namespace === activeNamespace)\n ?.address ?? data.address,\n };\n}\n\nexport interface UseEmbeddedWalletReturn {\n connectEmbedded: () => Promise<void>;\n /** Load an existing wallet without creating or connecting a new one. */\n restoreWallet: () => Promise<boolean>;\n generateWallet: () => Promise<WalletData | null>;\n importFromMnemonic: (mnemonic: string) => Promise<WalletData | null>;\n /**\n * Import a raw key in whatever form the user has it.\n *\n * Accepts the forms MetaMask, Phantom and `solana-keygen` export, and works\n * out which chain it belongs to rather than asking. Only that namespace is\n * enabled: a key is on exactly one curve, so an account for the other would\n * be an address the key cannot control and the user cannot recover.\n */\n importFromPrivateKey: (pk: string) => Promise<WalletData | null>;\n wipe: () => Promise<void>;\n wallet: EmbeddedWalletView | null;\n hasWallet: boolean;\n /** The active account's address. See `accounts` for the rest. */\n address: string | null;\n /**\n * Every account this wallet holds, one per namespace.\n *\n * A phrase derives an independent key per BIP-44 coin type, so a wallet\n * created from one holds both an EVM and a Solana account. They are not\n * variants of one key — holding one does not reveal the other.\n */\n accounts: EmbeddedWalletAccountView[];\n /** Which account signs when no namespace is named. */\n activeNamespace: WalletNamespace | null;\n /**\n * Choose which account signs.\n *\n * Rejects a namespace this wallet holds no account for, rather than leaving\n * it pointing at nothing — a wallet imported from a raw key has only the\n * namespace that key belongs to.\n */\n setActiveNamespace: (namespace: WalletNamespace) => void;\n /**\n * Derive accounts the phrase produces but this record does not yet hold.\n *\n * A wallet created before multi-namespace support already owns its Solana\n * account — the same phrase in Phantom shows the balance — so this makes it\n * visible here rather than leaving funds reachable everywhere except in this\n * app. Leaves the active namespace alone: someone who had an Ethereum wallet\n * yesterday should not find themselves on Solana today.\n */\n backfillAccounts: () => Promise<EmbeddedWalletAccountView[]>;\n /** @deprecated Use getSeedPhrase() instead. This field will be removed. */\n seedPhrase: string | null;\n /** Get seed phrase once and clear from memory. Returns mnemonic or null. */\n getSeedPhrase: () => string | null;\n /** Read the active private key only for an explicit backup/export action. */\n getPrivateKey: () => string | null;\n backupPending: boolean;\n confirmBackup: () => void;\n isBusy: boolean;\n error: Error | null;\n clearError: () => void;\n /**\n * Storage security tier (1-4).\n * 1 = IndexedDB + AES-GCM, 2 = IndexedDB,\n * 3 = localStorage + AES-GCM, 4 = localStorage plaintext\n */\n storageSecurityLevel: number;\n /**\n * The same tier as a score with the findings behind it, or null before a\n * wallet exists.\n *\n * Null rather than a worst-case report: the storage backend is chosen when\n * the wallet is created, so warning about it beforehand would describe a\n * state that has not happened.\n */\n securityReport: StorageSecurityReport | null;\n}\n\nexport function useEmbeddedWallet(): UseEmbeddedWalletReturn {\n const { connectEmbedded: providerConnectEmbedded, client } = useWeb3();\n const [wallet, setWallet] = useState<EmbeddedWalletView | null>(null);\n const seedPhraseRef = useRef<string | null>(null);\n const storageSecurityLevelRef = useRef(4);\n const restoreErroredRef = useRef(false);\n // The connector builds a fresh report object on every call, so returning it\n // straight through would hand consumers a new identity each render and make\n // it unusable as an effect dependency. Reuse the previous object while the\n // content is unchanged.\n const reportRef = useRef<{\n json: string;\n value: StorageSecurityReport;\n } | null>(null);\n const [backupPending, setBackupPending] = useState(false);\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = () => setError(null);\n\n /** Get seed phrase once and immediately clear from memory */\n const getSeedPhrase = useCallback(() => {\n const phrase = seedPhraseRef.current;\n seedPhraseRef.current = null; // Clear immediately\n return phrase;\n }, []);\n\n const getEmbeddedConnector = useCallback(() => {\n const activeClient = resolveClient(client);\n if (!activeClient?.embeddedConnector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet not enabled.\",\n );\n }\n return activeClient.embeddedConnector;\n }, [client]);\n\n const getPrivateKey = useCallback(() => {\n try {\n return getEmbeddedConnector().getWallet()?.privateKey ?? null;\n } catch {\n return null;\n }\n }, [getEmbeddedConnector]);\n\n const getReadyEmbeddedConnector = useCallback(async () => {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet not enabled.\",\n );\n }\n const connector = activeClient.getEmbeddedConnector\n ? await activeClient.getEmbeddedConnector()\n : activeClient.embeddedConnector;\n if (!connector) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Embedded wallet not enabled.\",\n );\n }\n return connector;\n }, [client]);\n\n const getPassphraseGate = useCallback(() => {\n try {\n return resolveClient(client)?.passphraseGate ?? null;\n } catch {\n return null;\n }\n }, [client]);\n\n /**\n * Drop a passphrase that did not open the wallet.\n *\n * Without this the gate keeps handing the same wrong value to every retry:\n * the user is told their passphrase is wrong and is never asked for a\n * different one, which reads as a wallet that will not open at all.\n */\n const forgetOnDecryptionFailure = useCallback(\n (err: unknown) => {\n const code = (err as { code?: unknown } | null)?.code;\n if (code !== \"decryption_failed\") return;\n getPassphraseGate()?.forget(\"That passphrase did not open the wallet.\");\n },\n [getPassphraseGate],\n );\n\n const restoreWallet = useCallback(async (): Promise<boolean> => {\n restoreErroredRef.current = false;\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n const loaded = await connector.load();\n if (!loaded) return false;\n const restored = connector.getWallet();\n if (!restored) return false;\n // Restoring signing material must not re-expose recovery material.\n seedPhraseRef.current = null;\n setBackupPending(false);\n setWallet(toWalletView(restored));\n return true;\n } catch (err) {\n restoreErroredRef.current = true;\n forgetOnDecryptionFailure(err);\n setError(\n err instanceof Error\n ? err\n : new Error(\"Failed to restore embedded wallet\"),\n );\n return false;\n }\n }, [forgetOnDecryptionFailure, getReadyEmbeddedConnector]);\n\n useEffect(() => {\n let cancelled = false;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n void restoreWallet().then((restored) => {\n if (cancelled || restored || restoreErroredRef.current) return;\n // In real production hydration the connector import and the first\n // IndexedDB open can settle in the opposite order. One bounded retry\n // closes that race without polling, prompting twice, or ever creating a\n // replacement wallet.\n retryTimer = setTimeout(() => {\n if (!cancelled) void restoreWallet();\n }, 100);\n });\n\n return () => {\n cancelled = true;\n if (retryTimer) clearTimeout(retryTimer);\n };\n }, [restoreWallet]);\n\n const handleConnectEmbedded = async () => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n const loaded = await connector.load();\n const w = connector.getWallet();\n if (loaded && w) {\n setWallet(toWalletView(w));\n seedPhraseRef.current = w.mnemonic || null;\n setBackupPending(!w.mnemonic);\n }\n await providerConnectEmbedded();\n const w2 = connector.getWallet();\n if (w2) {\n setWallet(toWalletView(w2));\n if (w2.mnemonic && !loaded) {\n seedPhraseRef.current = w2.mnemonic;\n setBackupPending(true);\n }\n }\n } catch (err) {\n forgetOnDecryptionFailure(err);\n setError(\n err instanceof Error\n ? err\n : new Error(\"Embedded wallet connection failed\"),\n );\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleGenerateWallet = async (): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n // The first save will ask for a passphrase. Say which question to put\n // to the user: prompting \"enter your passphrase\" for a wallet that does\n // not exist yet has no right answer.\n getPassphraseGate()?.expect(\"create\");\n const w = await connector.generateWallet();\n setWallet(toWalletView(w));\n seedPhraseRef.current = w.mnemonic;\n setBackupPending(true);\n return w;\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to generate wallet\"),\n );\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleImportFromMnemonic = async (\n mnemonic: string,\n ): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n // The first save will ask for a passphrase. Say which question to put\n // to the user: prompting \"enter your passphrase\" for a wallet that does\n // not exist yet has no right answer.\n getPassphraseGate()?.expect(\"create\");\n const w = await connector.importFromMnemonic(mnemonic);\n setWallet(toWalletView(w));\n seedPhraseRef.current = null;\n setBackupPending(false);\n return w;\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to import wallet\"),\n );\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleImportFromPrivateKey = async (\n pk: string,\n ): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n getPassphraseGate()?.expect(\"create\");\n const w = await connector.importFromPrivateKey(pk);\n setWallet(toWalletView(w));\n seedPhraseRef.current = null;\n setBackupPending(false);\n return w;\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to import wallet\"),\n );\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleWipe = async () => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = await getReadyEmbeddedConnector();\n await connector.wipe();\n setWallet(null);\n seedPhraseRef.current = null;\n setBackupPending(false);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to wipe wallet\"));\n } finally {\n setIsBusy(false);\n }\n };\n\n /**\n * Switch namespaces and re-render.\n *\n * The wallet record is mutated in place by the connector, so a new object\n * has to be published for React to notice — without it the switch happens\n * and the UI keeps showing the previous address, which is the kind of\n * mismatch a user acts on before anyone notices.\n */\n const handleSetActiveNamespace = useCallback(\n (namespace: WalletNamespace) => {\n const connector = getEmbeddedConnector();\n connector.setActiveNamespace(namespace);\n const next = connector.getWallet();\n setWallet(next ? toWalletView(next) : null);\n },\n [getEmbeddedConnector],\n );\n\n const handleBackfillAccounts = useCallback(async () => {\n const connector = await getReadyEmbeddedConnector();\n // The connector persists what it adds, so this only has to publish it.\n const added = await connector.backfillAccounts();\n if (added.length > 0) {\n const next = connector.getWallet();\n setWallet(next ? toWalletView(next) : null);\n }\n return added.map(({ namespace, address, derivationPath }) => ({\n namespace,\n address,\n ...(derivationPath ? { derivationPath } : {}),\n }));\n }, [getReadyEmbeddedConnector]);\n\n const handleConfirmBackup = () => {\n seedPhraseRef.current = null;\n setBackupPending(false);\n };\n\n return {\n connectEmbedded: handleConnectEmbedded,\n restoreWallet,\n generateWallet: handleGenerateWallet,\n importFromMnemonic: handleImportFromMnemonic,\n importFromPrivateKey: handleImportFromPrivateKey,\n wipe: handleWipe,\n wallet,\n hasWallet: wallet !== null,\n address: wallet?.address ?? null,\n accounts: wallet?.accounts ?? [],\n activeNamespace: wallet?.activeNamespace ?? null,\n setActiveNamespace: handleSetActiveNamespace,\n backfillAccounts: handleBackfillAccounts,\n seedPhrase: seedPhraseRef.current, // backward compat (deprecated)\n getSeedPhrase,\n getPrivateKey,\n backupPending,\n confirmBackup: handleConfirmBackup,\n isBusy,\n error,\n clearError,\n storageSecurityLevel: (() => {\n try {\n const connector = getEmbeddedConnector();\n const level = connector.getStorageSecurityLevel?.() ?? 4;\n if (connector.getWallet()) {\n storageSecurityLevelRef.current = level;\n return level;\n }\n return wallet ? storageSecurityLevelRef.current : level;\n } catch {\n return wallet ? storageSecurityLevelRef.current : 4;\n }\n })(),\n securityReport: (() => {\n let next: StorageSecurityReport | null = null;\n try {\n next = getEmbeddedConnector().getStorageSecurityReport?.() ?? null;\n } catch {\n next = null;\n }\n if (!next) {\n reportRef.current = null;\n return null;\n }\n const json = JSON.stringify(next);\n if (reportRef.current?.json === json) return reportRef.current.value;\n reportRef.current = { json, value: next };\n return next;\n })(),\n };\n}\n","import { chainNumber } from \"@naculus/connect-appkit-core\";\nimport { useState, useCallback, useEffect, useRef, useMemo } from \"react\";\nimport { useViemClient } from \"./useViemClient\";\nimport { useChain } from \"./useChain\";\nimport { useERC20Context } from \"./useERC20Context\";\nimport { ERC20_MIN_ABI, formatUnits } from \"@naculus/connect-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport type { Address } from \"viem\";\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20AllowanceOptions {\n token: TokenConfig;\n owner: Address;\n spender: Address;\n refreshInterval?: number;\n}\n\nexport interface UseERC20AllowanceReturn {\n allowance: string | null;\n allowanceRaw: bigint | null;\n isFetching: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Allowance(\n options: UseERC20AllowanceOptions,\n): UseERC20AllowanceReturn {\n const { publicClient } = useViemClient();\n const { currentChain } = useChain();\n const { identity, isCurrent, assertCurrent } = useERC20Context({\n token: options.token,\n chainId: currentChain ? (chainNumber(currentChain) ?? undefined) : undefined,\n owner: options.owner,\n spender: options.spender,\n publicClient,\n });\n const [read, setRead] = useState<{\n identity: object;\n raw: bigint | null;\n fetching: boolean;\n error: Error | null;\n } | null>(null);\n const allowanceRaw = read?.identity === identity ? read.raw : null;\n const isFetching = read?.identity === identity && read.fetching;\n const error = read?.identity === identity ? read.error : null;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const generationRef = useRef(0);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: chainId keeps the callback per chain, so the refetch effect keyed on it runs when only the chain changes\n const fetchAllowance = useCallback(async () => {\n if (!isCurrent()) return;\n const generation = ++generationRef.current;\n const stillCurrent = () =>\n isCurrent() && generation === generationRef.current;\n setRead({ identity, raw: null, fetching: !!publicClient, error: null });\n if (!publicClient) return;\n try {\n assertCurrent();\n const raw = await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"allowance\",\n args: [options.owner, options.spender],\n });\n if (!stillCurrent()) return;\n setRead({ identity, raw: raw as bigint, fetching: false, error: null });\n } catch (err) {\n if (!stillCurrent()) return;\n setRead({\n identity,\n raw: null,\n fetching: false,\n error:\n err instanceof Error ? err : new Error(\"Failed to fetch allowance\"),\n });\n }\n }, [\n publicClient,\n options.token.address,\n options.token.chainId,\n options.owner,\n options.spender,\n identity,\n isCurrent,\n assertCurrent,\n ]);\n\n // Initial fetch\n useEffect(() => {\n fetchAllowance().catch((e) =>\n console.warn(\"useERC20Allowance: initial fetch failed:\", e),\n );\n }, [fetchAllowance]);\n\n // Auto-refresh interval\n useEffect(() => {\n if (options.refreshInterval && options.refreshInterval > 0) {\n intervalRef.current = setInterval(\n fetchAllowance,\n options.refreshInterval,\n );\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [options.refreshInterval, fetchAllowance]);\n\n const allowance = useMemo(() => {\n if (allowanceRaw === null) return null;\n // No `?? 18`. This string is what a user reads when auditing what they\n // have approved: formatting a 6-decimal allowance with 18 turns\n // 1,000,000 USDC into \"0.000001\", which reads as safe. Return null and let\n // the caller show the raw value and say the precision is unknown.\n const decimals = options.token.decimals;\n if (decimals === undefined) return null;\n return formatUnits(allowanceRaw, decimals);\n }, [allowanceRaw, options.token.decimals]);\n\n return {\n allowance,\n allowanceRaw,\n isFetching,\n error,\n refetch: fetchAllowance,\n };\n}\n","import type { TokenConfig } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { tokenChainMismatch } from \"@naculus/connect-appkit-core\";\n\ninterface ERC20ContextOptions {\n token: TokenConfig;\n chainId: number | undefined;\n owner: string | null;\n spender?: string;\n connected?: boolean;\n publicClient: unknown;\n walletClient?: unknown;\n session?: unknown;\n client?: unknown;\n}\n\nexport interface ERC20Context {\n /**\n * Stable token for the current context.\n *\n * Changes only when the context itself changes, so it is safe to compare\n * cached results against with `===`.\n */\n identity: object;\n /** Whether the caller's captured context is still the mounted one. */\n isCurrent: () => boolean;\n /** Throw unless the context still holds and the token is on the active chain. */\n assertCurrent: () => void;\n}\n\n/**\n * Identify the wallet/token context by value, not by object reference.\n *\n * The reference form was hostage to consumer prop hygiene. `publicClient` is\n * memoized on `currentChain`, which is memoized on `config.chains` — and a\n * consumer writing `config={{ chains: [...] }}` inline, which is ordinary\n * React, produces a new array every render. That churned the identity every\n * render, which made `isCurrent()` false for work that was in fact still\n * current and re-fired the effects keyed on these callbacks.\n *\n * What identifies the context is the values an operation targets: the token,\n * the chain, the parties, and whether a client exists at all. Two different\n * `publicClient` objects pointing at the same chain describe the same\n * operation, so they must compare equal. The client facade is deliberately not\n * part of it: which object routes the call does not change what the call does.\n */\nfunction contextKey(options: ERC20ContextOptions): string {\n return [\n options.token.address.toLowerCase(),\n options.token.chainId ?? \"\",\n options.token.decimals ?? \"\",\n options.chainId ?? \"\",\n options.owner ?? \"\",\n options.spender ?? \"\",\n options.connected ? \"1\" : \"0\",\n options.publicClient ? \"1\" : \"0\",\n options.walletClient ? \"1\" : \"0\",\n // Session identity, not the object: a re-created wrapper around the same\n // session is the same session.\n (options.session as { id?: string } | undefined)?.id ?? \"\",\n ].join(\"|\");\n}\n\n/** Bind reads and pre-signing work to the wallet/token context that started it. */\nexport function useERC20Context(options: ERC20ContextOptions): ERC20Context {\n const { token, chainId } = options;\n const address = token.address.toLowerCase() as TokenConfig[\"address\"];\n const key = contextKey(options);\n\n // One object per distinct context. Callers compare cached results against it.\n const identity = useMemo(() => ({ key }), [key]);\n\n const latestKey = useRef(key);\n const mounted = useRef(true);\n\n useLayoutEffect(() => {\n latestKey.current = key;\n }, [key]);\n\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n // Compares the key captured when the callback was created against the newest\n // one, so work started under a previous account, token, or chain can tell\n // that it no longer speaks for the component.\n const isCurrent = useCallback(\n () => mounted.current && latestKey.current === key,\n [key],\n );\n\n const assertCurrent = useCallback(() => {\n if (!isCurrent()) {\n throw new WalletError(\n \"session_inactive\",\n \"Wallet or token context changed. Retry the operation with the current account and chain.\",\n );\n }\n // Checked here rather than only at the call sites: every path that signs or\n // reads goes through this, and a token on another chain resolves to a\n // different contract at the same address.\n const mismatch = tokenChainMismatch(\n { address, chainId: token.chainId },\n chainId,\n );\n if (mismatch) throw mismatch;\n }, [isCurrent, address, token.chainId, chainId]);\n\n return { identity, isCurrent, assertCurrent };\n}\n","import {\n chainNumber,\n createDecimalsCache,\n encodeErc20Approve,\n readDecimals,\n writeDecimals,\n} from \"@naculus/connect-appkit-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport {\n ERC20_MIN_ABI,\n formatUnits,\n parseUnits,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { useCallback, useRef, useState } from \"react\";\nimport type { Address } from \"viem\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport { useERC20Context } from \"./useERC20Context\";\nimport { useSendTransaction } from \"./useSendTransaction\";\nimport { useViemClient } from \"./useViemClient\";\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction toBareAddress(addr: string): Address {\n return (addr.includes(\":\") ? addr.split(\":\").pop()! : addr) as Address;\n}\n\n// ── Constants ─────────────────────────────────────────────────────\n\nconst MAX_UINT256 = 2n ** 256n - 1n;\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20ApproveOptions {\n token: TokenConfig;\n spender: Address;\n}\n\nexport interface UseERC20ApproveReturn {\n /** Approve a specific amount */\n approve: (amount: string) => Promise<`0x${string}`>;\n /** Approve max (type(uint256).max — infinite approval) */\n approveMax: () => Promise<`0x${string}`>;\n /** Current allowance as raw bigint */\n allowanceRaw: bigint | null;\n /** Current allowance as human-readable string */\n allowance: string | null;\n /** Check if allowance >= required amount */\n hasAllowance: (required: string) => Promise<boolean>;\n isApproving: boolean;\n isFetchingAllowance: boolean;\n error: Error | null;\n /**\n * Re-read the allowance and return it.\n *\n * The value is returned because reading `allowanceRaw` immediately after\n * awaiting this does not work: that binding belongs to the render that\n * created the callback, and setState does not rewrite it.\n */\n refetchAllowance: () => Promise<bigint | null>;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Approve(\n options: UseERC20ApproveOptions,\n): UseERC20ApproveReturn {\n const { publicClient, walletClient } = useViemClient();\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n const { session, client } = useWeb3();\n const {\n sendTransaction,\n isSending,\n error: sendTxError,\n reset,\n } = useSendTransaction();\n const [localError, setLocalError] = useState<Error | null>(null);\n const { identity, isCurrent, assertCurrent } = useERC20Context({\n token: options.token,\n chainId: currentChain\n ? (chainNumber(currentChain) ?? undefined)\n : undefined,\n owner: evmAccount,\n spender: options.spender,\n connected: isConnected,\n publicClient,\n walletClient,\n session,\n client,\n });\n const [read, setRead] = useState<{\n identity: object;\n raw: bigint | null;\n fetching: boolean;\n } | null>(null);\n const allowanceRaw = read?.identity === identity ? read.raw : null;\n const isFetchingAllowance = read?.identity === identity && read.fetching;\n\n const decimalsRef = useRef(\n createDecimalsCache(options.token, options.token.decimals),\n );\n const allowanceGenerationRef = useRef(0);\n const error = localError ?? sendTxError;\n\n const ownerAddress = (() => {\n if (!evmAccount) return null;\n return toBareAddress(evmAccount);\n })();\n\n // Returns what it read. Callers that need the value cannot get it from\n // `allowanceRaw` right after awaiting: that binding is the one captured at\n // render, and a setState does not rewrite it.\n // biome-ignore lint/correctness/useExhaustiveDependencies: chainId keeps the callback per chain, so the refetch effect keyed on it runs when only the chain changes\n const fetchAllowance = useCallback(async (): Promise<bigint | null> => {\n if (!isCurrent()) return null;\n const generation = ++allowanceGenerationRef.current;\n const stillCurrent = () =>\n isCurrent() && generation === allowanceGenerationRef.current;\n setRead({\n identity,\n raw: null,\n fetching: !!publicClient && !!ownerAddress && isConnected,\n });\n setLocalError(null);\n if (!publicClient || !ownerAddress || !isConnected) return null;\n try {\n assertCurrent();\n const raw = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"allowance\",\n args: [ownerAddress, options.spender],\n })) as bigint;\n if (!stillCurrent()) return null;\n setRead({ identity, raw, fetching: false });\n return raw;\n } catch (err) {\n if (stillCurrent()) {\n setRead({ identity, raw: null, fetching: false });\n setLocalError(\n err instanceof Error ? err : new Error(\"Failed to fetch allowance\"),\n );\n }\n return null;\n }\n }, [\n publicClient,\n ownerAddress,\n options.token.address,\n options.token.chainId,\n options.spender,\n identity,\n isCurrent,\n assertCurrent,\n isConnected,\n ]);\n\n const allowance = (() => {\n if (allowanceRaw === null) return null;\n // No `?? 18`: guessing a token's precision misstates every amount derived\n // from it, and 18 is only right for the tokens that happen to use it.\n const decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) return null;\n return formatUnits(allowanceRaw, decimals);\n })();\n\n const doApprove = useCallback(\n async (rawAmount: bigint): Promise<`0x${string}`> => {\n setLocalError(null);\n reset();\n\n if (!isConnected || !evmAccount) {\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No connected account\",\n );\n setLocalError(err);\n throw err;\n }\n\n if (!publicClient) {\n const err = new WalletError(\"wallet_unavailable\", \"No public client\");\n setLocalError(err);\n throw err;\n }\n\n // Approving on the wrong chain grants a spender rights over whatever\n // contract sits at this address there, which is not the token the user\n // was shown.\n try {\n assertCurrent();\n const data = encodeErc20Approve(options.spender, rawAmount);\n const activeClient = resolveClient(client);\n if (session) {\n if (activeClient) {\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n fetchAllowance();\n return txHash as `0x${string}`;\n }\n }\n\n if (walletClient) {\n const { request } = await publicClient.simulateContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"approve\",\n args: [options.spender, rawAmount],\n account: ownerAddress!,\n });\n assertCurrent();\n const txHash = await walletClient.writeContract(request);\n fetchAllowance();\n return txHash;\n }\n\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n fetchAllowance();\n return txHash as `0x${string}`;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Approve failed\");\n if (isCurrent()) setLocalError(error);\n throw error;\n }\n },\n [\n options,\n publicClient,\n walletClient,\n evmAccount,\n isConnected,\n session,\n client,\n ownerAddress,\n sendTransaction,\n reset,\n fetchAllowance,\n assertCurrent,\n isCurrent,\n ],\n );\n\n const approveAmount = useCallback(\n async (amount: string): Promise<`0x${string}`> => {\n try {\n assertCurrent();\n if (!publicClient)\n throw new WalletError(\"wallet_unavailable\", \"No public client\");\n\n let decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) {\n decimals = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n })) as number;\n assertCurrent();\n writeDecimals(decimalsRef.current, options.token, decimals);\n }\n\n const rawAmount = parseUnits(amount, decimals);\n return await doApprove(rawAmount);\n } catch (err) {\n if (isCurrent())\n setLocalError(\n err instanceof Error ? err : new Error(\"Approve failed\"),\n );\n throw err;\n }\n },\n [options.token, publicClient, doApprove, assertCurrent, isCurrent],\n );\n\n const approveMaxAmount = useCallback(async (): Promise<`0x${string}`> => {\n return doApprove(MAX_UINT256);\n }, [doApprove]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on the token fields it reads (address, chainId, decimals); the token object identity changes every render\n const checkAllowance = useCallback(\n async (required: string): Promise<boolean> => {\n if (!isCurrent() || !isConnected || !ownerAddress || !publicClient)\n return false;\n try {\n assertCurrent();\n } catch (err) {\n setLocalError(\n err instanceof Error ? err : new Error(\"Cannot check allowance\"),\n );\n return false;\n }\n // `allowanceRaw` is the render-time binding, so awaiting a refetch never\n // changed it — the second null check below used to always hit, and this\n // gate answered false on every first call. Callers reading it as \"no\n // approval yet\" prompted for an approval the user had already granted.\n const current = allowanceRaw ?? (await fetchAllowance());\n if (current === null) return false;\n\n // No `decimals = 18` fallback. This is a gate: a caller does\n // `if (await hasAllowance(x)) skipApprove()`, so a wrong precision here\n // is a wrong answer to \"is it safe to skip the approval\", not a\n // misformatted string. Read the token instead, and refuse if that fails.\n let decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) {\n if (!publicClient) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"Cannot check allowance: no public client to read token decimals.\",\n );\n }\n decimals = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n })) as number;\n if (!isCurrent()) return false;\n writeDecimals(decimalsRef.current, options.token, decimals);\n }\n\n const requiredRaw = parseUnits(required, decimals);\n return isCurrent() && current >= requiredRaw;\n },\n [\n allowanceRaw,\n fetchAllowance,\n options.token.address,\n options.token.chainId,\n options.token.decimals,\n publicClient,\n isCurrent,\n assertCurrent,\n isConnected,\n ownerAddress,\n ],\n );\n\n return {\n approve: approveAmount,\n approveMax: approveMaxAmount,\n allowance,\n allowanceRaw,\n hasAllowance: checkAllowance,\n isApproving: isSending,\n isFetchingAllowance,\n error,\n refetchAllowance: fetchAllowance,\n };\n}\n","import { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { EvmTransaction } from \"../types\";\nimport { resolveClient } from \"./client-resolver\";\nimport { extractTransactionHash } from \"./transaction-hash\";\n\n/**\n * Where a send has got to.\n *\n * `\"submitted\"` was `\"confirmed\"`, which was a claim the hook could not\n * support: `sendTransaction` resolves with a transaction hash, and a hash\n * means the wallet broadcast it — not that it was mined, and not that it\n * succeeded. An interface showing \"confirmed\" at that moment tells someone\n * their payment went through while it can still revert or never be included.\n *\n * To reach an actual confirmation, watch the returned hash with\n * `useTxMonitor`, where `\"confirmed\"` is established by a receipt.\n */\nexport type SendTransactionStatus =\n | \"idle\"\n | \"awaiting_approval\"\n | \"submitted\"\n | \"failed\";\n\nexport function useSendTransaction() {\n const { session, chainId, client } = useWeb3();\n const [status, setStatus] = useState<SendTransactionStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n\n const sendTransaction = useCallback(\n async (transaction: EvmTransaction): Promise<string> => {\n if (!session) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n const evmAccount = session.namespaces.eip155?.accounts.find(\n (account) =>\n /^eip155:\\d+:0x[0-9a-fA-F]{40}$/.test(account) ||\n /^0x[0-9a-fA-F]{40}$/.test(account),\n );\n\n if (!evmAccount) {\n setStatus(\"failed\");\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No EVM account found\",\n );\n setError(err);\n throw err;\n }\n\n setStatus(\"awaiting_approval\");\n setError(null);\n\n try {\n const txWithFrom = {\n ...transaction,\n from: transaction.from ?? evmAccount.split(\":\").pop(),\n };\n\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const result = await activeClient.sendTransaction(session, {\n transaction: txWithFrom,\n chainId: chainId ?? undefined,\n });\n const hash = extractTransactionHash(result);\n\n setStatus(\"submitted\");\n return hash;\n } catch (err) {\n setStatus(\"failed\");\n const errorMessage =\n err instanceof Error ? err.message : \"Transaction failed\";\n setError(err instanceof Error ? err : new Error(errorMessage));\n throw err;\n }\n },\n [session, chainId, client],\n );\n\n const reset = useCallback(() => {\n setStatus(\"idle\");\n setError(null);\n }, []);\n\n return {\n sendTransaction,\n status,\n error,\n reset,\n isSending: status === \"awaiting_approval\",\n };\n}\n","import {\n chainNumber,\n createDecimalsCache,\n encodeErc20Transfer,\n readDecimals,\n writeDecimals,\n} from \"@naculus/connect-appkit-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport { ERC20_MIN_ABI, parseUnits, WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useRef, useState } from \"react\";\nimport type { Address } from \"viem\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport { useERC20Context } from \"./useERC20Context\";\nimport { useSendTransaction } from \"./useSendTransaction\";\nimport { useViemClient } from \"./useViemClient\";\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction toBareAddress(addr: string): Address {\n return (addr.includes(\":\") ? addr.split(\":\").pop()! : addr) as Address;\n}\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20TransferOptions {\n token: TokenConfig;\n}\n\nexport interface UseERC20TransferReturn {\n /** Send a transfer. Returns tx hash on success. */\n sendTransfer: (to: Address, amount: string) => Promise<`0x${string}`>;\n isSending: boolean;\n error: Error | null;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Transfer(\n options: UseERC20TransferOptions,\n): UseERC20TransferReturn {\n const { publicClient, walletClient } = useViemClient();\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n const { session, client } = useWeb3();\n const {\n sendTransaction,\n isSending,\n error: sendTxError,\n reset,\n } = useSendTransaction();\n const [localError, setLocalError] = useState<Error | null>(null);\n const { isCurrent, assertCurrent } = useERC20Context({\n token: options.token,\n chainId: currentChain\n ? (chainNumber(currentChain) ?? undefined)\n : undefined,\n owner: evmAccount,\n connected: isConnected,\n publicClient,\n walletClient,\n session,\n client,\n });\n\n // Keyed by token: a bare ref kept the first token's precision when the user\n // switched tokens, and converted the amount with the wrong scale.\n const decimalsRef = useRef(\n createDecimalsCache(options.token, options.token.decimals),\n );\n const error = localError ?? sendTxError;\n\n const sendTransfer = useCallback(\n async (to: Address, amount: string): Promise<`0x${string}`> => {\n setLocalError(null);\n reset();\n\n if (!isConnected || !evmAccount) {\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No connected account\",\n );\n setLocalError(err);\n throw err;\n }\n\n if (!publicClient) {\n const err = new WalletError(\n \"wallet_unavailable\",\n \"No public client available\",\n );\n setLocalError(err);\n throw err;\n }\n\n // Transferring on the wrong chain sends the call to whatever contract\n // occupies this address there. The decimals read below would come from\n // that contract too, so the amount would be wrong as well.\n try {\n assertCurrent();\n\n const address = toBareAddress(evmAccount);\n\n // Fetch decimals if not cached\n let decimals = readDecimals(\n decimalsRef.current,\n options.token,\n options.token.decimals,\n );\n if (decimals === undefined) {\n decimals = (await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n })) as number;\n assertCurrent();\n writeDecimals(decimalsRef.current, options.token, decimals);\n }\n\n const rawAmount = parseUnits(amount, decimals);\n const data = encodeErc20Transfer(to, rawAmount);\n\n const activeClient = resolveClient(client);\n // Strategy 1: session-based connector\n if (session) {\n if (activeClient) {\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n return txHash as `0x${string}`;\n }\n }\n\n // Strategy 2: embedded wallet via viem wallet client\n if (walletClient) {\n const { request } = await publicClient.simulateContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"transfer\",\n args: [to, rawAmount],\n account: address,\n });\n assertCurrent();\n const txHash = await walletClient.writeContract(request);\n return txHash;\n }\n\n // Strategy 3: fallback to sendTransaction hook\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n return txHash as `0x${string}`;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Transfer failed\");\n if (isCurrent()) setLocalError(error);\n throw error;\n }\n },\n [\n options.token,\n publicClient,\n walletClient,\n evmAccount,\n isConnected,\n session,\n client,\n sendTransaction,\n reset,\n assertCurrent,\n isCurrent,\n ],\n );\n\n return {\n sendTransfer,\n isSending,\n error,\n };\n}\n","import { chainNumber, encodeErc20Transfer } from \"@naculus/connect-appkit-core\";\n/**\n * useERC20TransferSimulation — React hook for simulating ERC-20 token\n * transfers before signing/submitting.\n *\n * Wraps useTransactionSimulation with ERC-20 transfer calldata building,\n * so callers only need the token, recipient, and amount.\n *\n * @see /docs/features/transaction-simulation.md\n */\n\nimport { parseUnits, type TokenConfig } from \"@naculus/connect-core\";\nimport { useMemo } from \"react\";\nimport type { EvmTransaction } from \"../types\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport {\n type SimulationResult,\n type UseTransactionSimulationReturn,\n useTransactionSimulation,\n} from \"./useTransactionSimulation\";\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20TransferSimulationOptions {\n /** Token configuration (address, decimals, chainId) */\n token: TokenConfig;\n /** Recipient address */\n to: `0x${string}`;\n /** Amount in human-readable units (e.g. \"1.50\" for 1.5 USDC) */\n amount: string;\n}\n\nexport interface UseERC20TransferSimulationReturn\n extends Omit<UseTransactionSimulationReturn, \"simulate\"> {\n /** Simulation result for the built ERC-20 transfer */\n result: SimulationResult | undefined;\n /** Whether a simulation is in progress */\n isSimulating: boolean;\n /** Error from the last simulation attempt */\n error: Error | null;\n /** Re-run the simulation with current parameters */\n reSimulate: () => Promise<SimulationResult>;\n /** Reset simulation state */\n reset: () => void;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20TransferSimulation(\n options: UseERC20TransferSimulationOptions,\n): UseERC20TransferSimulationReturn {\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n // No `?? 1`. TokenConfig.chainId says where the token lives; falling back to\n // mainnet simulates against whatever contract occupies that address there.\n const chainId =\n options.token.chainId ??\n (currentChain ? (chainNumber(currentChain) ?? undefined) : undefined);\n\n // Build the transaction descriptor from ERC-20 transfer params\n const tx: EvmTransaction | undefined = useMemo(() => {\n if (!isConnected || !evmAccount) return undefined;\n\n try {\n // No `?? 18`. A simulation built with the wrong precision previews a\n // different transfer than the one that will be sent, which is worse\n // than showing no preview at all.\n const decimals = options.token.decimals;\n if (decimals === undefined) return undefined;\n const rawAmount = parseUnits(options.amount, decimals);\n const data = encodeErc20Transfer(options.to, rawAmount);\n\n return {\n to: options.token.address,\n data,\n value: \"0\",\n };\n } catch {\n // Fail closed: never preview calldata different from what sendTransfer accepts.\n return undefined;\n }\n }, [\n options.token.address,\n options.token.decimals,\n options.to,\n options.amount,\n evmAccount,\n isConnected,\n ]);\n\n // Use the base transaction simulation hook\n const sim = useTransactionSimulation(tx, chainId);\n\n // Alias simulate → reSimulate for semantic clarity\n return {\n // The base hook may still hold (or later receive) the previous transaction's\n // result. Never display it for inputs that cannot produce sendable calldata.\n result: tx ? sim.result : undefined,\n isSimulating: !!tx && sim.isSimulating,\n error: tx ? sim.error : null,\n reSimulate: sim.simulate,\n reset: sim.reset,\n };\n}\n","/** React state shell for the framework-neutral eth_call revert preview. */\nimport { simulateTransactionPreview } from \"@naculus/connect-appkit-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { EvmTransaction } from \"../types\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport { useViemClient } from \"./useViemClient\";\n\nexport type {\n ApprovalChange,\n BalanceChange,\n GasInfo,\n RiskAssessment,\n RiskLevel,\n RiskWarning,\n SimulationResult,\n SimulationStatus,\n} from \"@naculus/wallet-engine\";\n\nimport type { SimulationResult } from \"@naculus/wallet-engine\";\n\nexport interface UseTransactionSimulationReturn {\n result: SimulationResult | undefined;\n isSimulating: boolean;\n error: Error | null;\n simulate: () => Promise<SimulationResult>;\n reset: () => void;\n}\n\nexport function useTransactionSimulation(\n tx: EvmTransaction | undefined,\n chainId?: number,\n): UseTransactionSimulationReturn {\n useWeb3();\n const { evmAccount } = useAccount();\n const { currentChain } = useChain();\n const { publicClient } = useViemClient();\n const [result, setResult] = useState<SimulationResult | undefined>(undefined);\n const [isSimulating, setIsSimulating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n\n const simulate = useCallback(async (): Promise<SimulationResult> => {\n if (tx) {\n setIsSimulating(true);\n setError(null);\n }\n try {\n const simResult = await simulateTransactionPreview(tx, {\n chainId,\n currentChain,\n publicClient,\n evmAccount,\n });\n setResult(simResult);\n return simResult;\n } catch (cause) {\n const err =\n cause instanceof Error ? cause : new Error(\"Simulation failed\");\n setError(err);\n throw err;\n } finally {\n if (tx) setIsSimulating(false);\n }\n }, [tx, chainId, currentChain, publicClient, evmAccount]);\n\n useEffect(() => {\n if (!tx) return;\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n simulate().catch(() => {\n // Error is captured in state.\n });\n }, 300);\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [tx, simulate]);\n\n const reset = useCallback(() => {\n setResult(undefined);\n setError(null);\n setIsSimulating(false);\n }, []);\n\n return { result, isSimulating, error, simulate, reset };\n}\n","import { useState, useCallback, useRef } from \"react\";\nimport type { TxMonitorLike, TxStatusEntry } from \"./useTxMonitor\";\nimport { useTxMonitorProvider } from \"./useTxMonitor\";\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseLastTxResult {\n /** Most recent transaction by createdAt */\n lastTx: TxStatusEntry | null;\n /** Most recent confirmed transaction */\n lastConfirmedTx: TxStatusEntry | null;\n /** Most recent failed transaction */\n lastFailedTx: TxStatusEntry | null;\n /** Clear cached lastTx state */\n clear: () => void;\n}\n\n/**\n * Track the most recent transaction.\n * Automatically updates when a new transaction is sent (via statusChange events).\n */\nexport function useLastTx(monitor?: TxMonitorLike): UseLastTxResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [lastTx, setLastTx] = useState<TxStatusEntry | null>(null);\n const [lastConfirmedTx, setLastConfirmedTx] = useState<TxStatusEntry | null>(null);\n const [lastFailedTx, setLastFailedTx] = useState<TxStatusEntry | null>(null);\n const lastTxRef = useRef<{ createdAt: number } | null>(null);\n\n // Track confirmed and failed events\n const confirmedHandlerRef = useRef<((entry: TxStatusEntry) => void) | null>(null);\n const failedHandlerRef = useRef<((entry: TxStatusEntry) => void) | null>(null);\n\n // Set up listeners\n if (effectiveMonitor) {\n if (!confirmedHandlerRef.current) {\n confirmedHandlerRef.current = (entry: TxStatusEntry) => {\n setLastConfirmedTx(entry);\n if (!lastTxRef.current || entry.createdAt >= lastTxRef.current.createdAt) {\n setLastTx(entry);\n lastTxRef.current = entry;\n }\n };\n effectiveMonitor.on(\"confirmed\", confirmedHandlerRef.current);\n }\n\n if (!failedHandlerRef.current) {\n failedHandlerRef.current = (entry: TxStatusEntry) => {\n setLastFailedTx(entry);\n if (!lastTxRef.current || entry.createdAt >= lastTxRef.current.createdAt) {\n setLastTx(entry);\n lastTxRef.current = entry;\n }\n };\n effectiveMonitor.on(\"failed\", failedHandlerRef.current);\n }\n }\n\n const clear = useCallback(() => {\n setLastTx(null);\n setLastConfirmedTx(null);\n setLastFailedTx(null);\n lastTxRef.current = null;\n }, []);\n\n return {\n lastTx,\n lastConfirmedTx,\n lastFailedTx,\n clear,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\n\n// ── Types (standalone, to avoid dependency on wallet-engine) ──────\n\nexport type TxStatus =\n | \"pending\"\n | \"mined\"\n | \"confirmed\"\n | \"failed\"\n | \"unknown\";\n\nexport interface TxStatusEntry {\n hash: string;\n chainId: number;\n from: string;\n to: string;\n value: string;\n data?: string;\n nonce?: number;\n status: TxStatus;\n blockNumber?: number;\n blockHash?: string;\n gasUsed?: string;\n effectiveGasPrice?: string;\n createdAt: number;\n confirmedAt?: number;\n updatedAt: number;\n error?: string;\n label?: string;\n memo?: string;\n replacementCount?: number;\n}\n\n/** Minimal TxMonitor interface for React hooks */\nexport interface TxMonitorLike {\n watchTx(hash: string, chainId: number, options?: {\n requiredConfirmations?: number;\n pollInterval?: number;\n label?: string;\n memo?: string;\n initialEntry?: Partial<TxStatusEntry>;\n }): Promise<TxStatusEntry>;\n\n stopWatching(hash: string, chainId?: number): void;\n getTxStatus(hash: string, chainId?: number): TxStatusEntry | null;\n getTxHistory(address?: string, chainId?: number): Promise<TxStatusEntry[]>;\n refreshTx(hash: string, chainId?: number): Promise<void>;\n\n on(event: \"statusChange\", listener: (entry: TxStatusEntry) => void): this;\n on(event: \"confirmed\", listener: (entry: TxStatusEntry) => void): this;\n on(event: \"failed\", listener: (entry: TxStatusEntry) => void): this;\n off(event: string, listener: (entry: TxStatusEntry) => void): this;\n}\n\n// ── Context for providing TxMonitor ───────────────────────────────\n\nimport { createContext, useContext } from \"react\";\n\nexport const TxMonitorContext = createContext<TxMonitorLike | null>(null);\n\nexport function useTxMonitorProvider(): TxMonitorLike | null {\n return useContext(TxMonitorContext);\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseTxMonitorResult {\n entry: TxStatusEntry | null;\n status: TxStatus | \"idle\";\n isLoading: boolean;\n isWatching: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n stopWatching: () => void;\n}\n\n/**\n * Monitor a single transaction's lifecycle.\n * When hash changes, automatically stops old watch and starts new one.\n */\nexport function useTxMonitor(\n hash?: string,\n chainId?: number,\n monitor?: TxMonitorLike,\n): UseTxMonitorResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [entry, setEntry] = useState<TxStatusEntry | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isWatching, setIsWatching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const prevHashRef = useRef<string | undefined>(undefined);\n\n const refresh = useCallback(async () => {\n if (!effectiveMonitor || !hash) return;\n setIsLoading(true);\n setError(null);\n try {\n await effectiveMonitor.refreshTx(hash, chainId);\n const current = effectiveMonitor.getTxStatus(hash, chainId);\n if (current) setEntry(current);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [effectiveMonitor, hash, chainId]);\n\n const stopWatching = useCallback(() => {\n if (!effectiveMonitor || !hash) return;\n effectiveMonitor.stopWatching(hash, chainId);\n setIsWatching(false);\n }, [effectiveMonitor, hash, chainId]);\n\n useEffect(() => {\n if (!effectiveMonitor || !hash || !chainId) {\n setEntry(null);\n setIsWatching(false);\n return;\n }\n\n // Stop previous watch if hash changed\n if (prevHashRef.current && prevHashRef.current !== hash) {\n effectiveMonitor.stopWatching(prevHashRef.current);\n }\n prevHashRef.current = hash;\n\n let cancelled = false;\n setIsWatching(true);\n setIsLoading(true);\n setError(null);\n\n // Check if we already have status\n const current = effectiveMonitor.getTxStatus(hash, chainId);\n if (current) {\n setEntry(current);\n setIsLoading(false);\n }\n\n // Start watching\n effectiveMonitor.watchTx(hash, chainId, {}).then((initial) => {\n if (!cancelled) {\n setEntry(initial);\n setIsLoading(false);\n }\n }).catch((err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n }\n });\n\n // Listen for status changes\n const onStatusChange = (updated: TxStatusEntry) => {\n if (!cancelled) setEntry({ ...updated });\n };\n effectiveMonitor.on(\"statusChange\", onStatusChange);\n\n return () => {\n cancelled = true;\n setIsWatching(false);\n effectiveMonitor.off(\"statusChange\", onStatusChange);\n };\n }, [effectiveMonitor, hash, chainId]);\n\n const status: TxStatus | \"idle\" = entry?.status ?? \"idle\";\n\n return {\n entry,\n status,\n isLoading,\n isWatching,\n error,\n refresh,\n stopWatching,\n };\n}\n","import type {\n NameResolver,\n NameResolverConfig,\n NameResult,\n} from \"@naculus/connect-core\";\nimport { useCallback } from \"react\";\nimport { useNameLookup } from \"../core/name-lookup\";\n\n/**\n * Result of a reverse resolution query.\n */\nexport interface UseLookupAddressResult {\n /** Resolved name, or null if not found / not started. */\n data: NameResult | null;\n /** Whether the lookup is in progress. */\n isLoading: boolean;\n /** Error that occurred during lookup, if any. */\n error: Error | null;\n /** Manually trigger re-lookup of the current address. */\n refetch: () => void;\n}\n\n/**\n * Options for the useLookupAddress hook.\n */\nexport interface UseLookupAddressOptions {\n /** Chain to resolve against, CAIP-2. */\n chainId?: string;\n /** Whether to skip the lookup (e.g. if the input is incomplete). */\n skip?: boolean;\n /** Custom resolver configuration (overrides default RPC URLs). */\n resolverConfig?: NameResolverConfig;\n}\n\n/**\n * React hook to resolve a blockchain address to a human-readable name.\n *\n * Reverse resolution for ENS and SNS.\n *\n * @example\n * ```tsx\n * function AccountLabel({ address }) {\n * const { data } = useLookupAddress(address);\n * return <span>{data?.name ?? address}</span>;\n * }\n * ```\n */\nexport function useLookupAddress(\n address: string,\n options?: UseLookupAddressOptions,\n): UseLookupAddressResult {\n const query = useCallback(\n (resolver: NameResolver, input: string, scope?: string) =>\n resolver.lookupAddress(input, scope),\n [],\n );\n\n return useNameLookup<NameResult>({\n input: address,\n skip: options?.skip,\n resolverConfig: options?.resolverConfig,\n scope: options?.chainId,\n query,\n });\n}\n","/**\n * The shared half of the two name-resolution hooks.\n *\n * `useResolveName` (name to address) and `useLookupAddress` (address to name)\n * were near-identical copies, and carried identical defects:\n *\n * - No request-generation guard. Typing quickly meant two lookups in flight,\n * and if the earlier one resolved last it overwrote the later result — the\n * UI then showed one address's name next to a different address, which is\n * exactly the pairing a user reads before deciding where to send funds.\n * - The resolver was captured into a ref on first render and never rebuilt, so\n * a caller changing `resolverConfig` kept querying through the old one.\n * - The de-duplication guard closed over `data` without listing it as a\n * dependency, so it tested a value from an earlier render.\n *\n * Keeping the logic here means fixing it once. The two hooks differ only in\n * which resolver method they call and what they call the input.\n */\n\nimport type { NameResolver, NameResolverConfig } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getResolver } from \"@naculus/connect-appkit-core\";\n\nexport interface NameLookupState<T> {\n data: T | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport interface NameLookupOptions<T> {\n /** The name or address being looked up. */\n input: string;\n /** Skip entirely, e.g. while the input is known to be incomplete. */\n skip?: boolean;\n /** Overrides the shared resolver when supplied. */\n resolverConfig?: NameResolverConfig;\n /** Extra value that changes the query's meaning, such as a chain ID. */\n scope?: string;\n /**\n * Performs the lookup. Must be stable or wrapped by the caller.\n *\n * Resolves null for \"no such name\", which is an answer rather than a\n * failure and is reported as `data: null` with no error.\n */\n query: (\n resolver: NameResolver,\n input: string,\n scope?: string,\n ) => Promise<T | null>;\n}\n\nexport function useNameLookup<T>({\n input,\n skip = false,\n resolverConfig,\n scope,\n query,\n}: NameLookupOptions<T>): NameLookupState<T> {\n const [data, setData] = useState<T | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const generationRef = useRef(0);\n const mountedRef = useRef(true);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n // Rebuilt when the config changes rather than pinned to the first render.\n // getResolver returns a dedicated instance for a config and the shared one\n // otherwise, so this stays a single instance for the common case.\n const resolver = useMemo(() => getResolver(resolverConfig), [resolverConfig]);\n\n const run = useCallback(() => {\n const trimmed = input.trim();\n if (!trimmed || skip) {\n // Bump the generation so a lookup already in flight cannot land after\n // the caller has cleared the field.\n generationRef.current += 1;\n setData(null);\n setIsLoading(false);\n setError(null);\n return;\n }\n\n const generation = ++generationRef.current;\n setIsLoading(true);\n setError(null);\n\n query(resolver, trimmed, scope)\n .then((result) => {\n if (!mountedRef.current || generation !== generationRef.current) return;\n setData(result);\n setIsLoading(false);\n })\n .catch((err: unknown) => {\n if (!mountedRef.current || generation !== generationRef.current) return;\n setError(err instanceof Error ? err : new Error(String(err)));\n setData(null);\n setIsLoading(false);\n });\n }, [input, skip, scope, resolver, query]);\n\n useEffect(() => {\n run();\n }, [run]);\n\n return { data, isLoading, error, refetch: run };\n}\n","/**\n * useNotification — React hook for push notification state.\n *\n * Provides notifications, settings, and control methods for the\n * in-app notification center.\n *\n * @example\n * ```tsx\n * import { useNotification } from \"@naculus/connect-appkit-react\";\n *\n * function NotificationCenter() {\n * const { notifications, unreadCount, clear, markAsRead } = useNotification();\n * return (\n * <div>\n * <span>Unread: {unreadCount}</span>\n * <ul>\n * {notifications.map(n => (\n * <li key={n.id} onClick={() => markAsRead(n.id)}>\n * {n.title} — {n.body}\n * </li>\n * ))}\n * </ul>\n * <button onClick={clear}>Clear all</button>\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from \"react\";\nimport {\n addInAppNotification,\n channelsUpdate,\n clearOneInAppNotification,\n createNotificationSettingsStorage,\n DEFAULT_NOTIFICATION_SETTINGS,\n loadNotificationSettings,\n mutedChainSettings,\n saveNotificationSettings,\n replayNotificationSettings,\n updateNotificationSettings,\n type NotificationSettingsStorage,\n type NotificationSettingsUpdate,\n} from \"@naculus/connect-appkit-core\";\nimport {\n InAppChannel,\n type NotificationItem,\n type NotificationSettings,\n} from \"@naculus/connect-core\";\n\n// ─── Hook ──────────────────────────────────────────────────────────────\n\n/**\n * Hook for consuming in-app notifications in React components.\n *\n * Uses InAppChannel internally to manage the notification queue.\n * All persistent state is stored via localStorage.\n */\nexport function useNotification(options?: {\n /** External InAppChannel instance (for sharing between hooks). If omitted, creates one. */\n channel?: InAppChannel;\n /** Custom storage for settings (defaults to localStorage) */\n storage?: NotificationSettingsStorage;\n}) {\n // ── Channel ──────────────────────────────────────────────────────\n\n const channelRef = useRef<InAppChannel | null>(null);\n\n if (!channelRef.current) {\n channelRef.current = options?.channel ?? new InAppChannel();\n }\n\n const channel = channelRef.current;\n\n // ── State ────────────────────────────────────────────────────────\n\n const [notifications, setNotifications] = useState<NotificationItem[]>(() =>\n channel.getHistory(),\n );\n\n const [settings, setSettingsState] = useState<NotificationSettings>(() => {\n // Try to load from storage, fall back to default\n return DEFAULT_NOTIFICATION_SETTINGS;\n });\n\n // ── Load persisted settings on mount ──────────────────────────────\n\n // Changes made before the persisted settings load are queued and replayed\n // on top of them (replayNotificationSettings); null once loaded.\n const pendingRef = useRef<NotificationSettingsUpdate[] | null>([]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: loads persisted settings once, on mount; later storage changes are written, not re-read\n useEffect(() => {\n const storage = options?.storage ?? createNotificationSettingsStorage();\n const settle = (saved: NotificationSettings | null) => {\n const pending = pendingRef.current ?? [];\n pendingRef.current = null;\n if (pending.length === 0) {\n if (saved) setSettingsState(saved);\n return;\n }\n setSettingsState(() => {\n const next = replayNotificationSettings(saved, pending);\n saveNotificationSettings(storage, next);\n return next;\n });\n };\n loadNotificationSettings(storage).then(settle, () => settle(null));\n }, []);\n\n // ── Sync notifications with channel ──────────────────────────────\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: channel comes from a ref and never changes; wired once on mount\n useEffect(() => {\n // Set up callback to reactively update state when new notifications arrive\n channel.onNotification = (item) => {\n setNotifications((prev) => [...prev, item]);\n };\n\n // Restore persisted history\n channel.restore().then(() => {\n setNotifications(channel.getHistory());\n });\n\n return () => {\n // Cleanup: deregister callback on unmount\n channel.onNotification = undefined;\n };\n }, []);\n\n // ── Computed ─────────────────────────────────────────────────────\n\n const unreadCount = useMemo(() => {\n return notifications.filter((n) => !n.read).length;\n }, [notifications]);\n\n // ── Actions ──────────────────────────────────────────────────────\n\n const clear = useCallback(() => {\n channel.clear();\n setNotifications([]);\n }, [channel]);\n\n const clearOne = useCallback(\n (id: string) => {\n clearOneInAppNotification(channel, id).then(() => {\n // Force re-sync\n setNotifications(channel.getHistory());\n });\n },\n [channel],\n );\n\n const markAsRead = useCallback(\n (id: string) => {\n channel.markAsRead(id);\n setNotifications((prev) =>\n prev.map((n) => (n.id === id ? { ...n, read: true } : n)),\n );\n },\n [channel],\n );\n\n const markAllAsRead = useCallback(() => {\n channel.markAllAsRead();\n setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));\n }, [channel]);\n\n // ── Add single notification ──────────────────────────────────────\n\n const addNotification = useCallback(\n (item: Omit<NotificationItem, \"id\" | \"timestamp\">) => {\n addInAppNotification(channel, item);\n // The onNotification callback will update state\n },\n [channel],\n );\n\n // ── Settings ──────────────────────────────────────────────────────\n\n // Every change is computed from the latest state inside the updater, never\n // from the `settings` captured at render: two calls in one tick (mute A,\n // mute B) would otherwise both start from the same list, and the second\n // would drop the first.\n const applySettings = useCallback(\n (compute: NotificationSettingsUpdate) => {\n pendingRef.current?.push(compute);\n setSettingsState((prev) => {\n const next = updateNotificationSettings(prev, compute(prev));\n const storage = options?.storage ?? createNotificationSettingsStorage();\n saveNotificationSettings(storage, next);\n return next;\n });\n },\n [options?.storage],\n );\n\n const updateSettings = useCallback(\n (update: Partial<NotificationSettings>) => applySettings(() => update),\n [applySettings],\n );\n\n const setChannels = useCallback(\n (channels: string[]) => {\n updateSettings(channelsUpdate(channels));\n },\n [updateSettings],\n );\n\n const muteChain = useCallback(\n (chainId: string) => {\n applySettings((prev) => mutedChainSettings(prev, chainId, true));\n },\n [applySettings],\n );\n\n const unmuteChain = useCallback(\n (chainId: string) => {\n applySettings((prev) => mutedChainSettings(prev, chainId, false));\n },\n [applySettings],\n );\n\n // ── Return ───────────────────────────────────────────────────────\n\n return {\n /** All in-app notifications (newest last) */\n notifications,\n /** Number of unread notifications */\n unreadCount,\n /** Add a single notification manually */\n addNotification,\n /** Clear all in-app notifications */\n clear,\n /** Clear a single notification */\n clearOne,\n /** Mark a notification as read */\n markAsRead,\n /** Mark all as read */\n markAllAsRead,\n /** Current notification settings */\n settings,\n /** Update notification settings */\n updateSettings,\n /** Set active channels by id */\n setChannels,\n /** Mute a chain */\n muteChain,\n /** Unmute a chain */\n unmuteChain,\n };\n}\n","import { useCallback, useSyncExternalStore } from \"react\";\nimport type {\n PassphraseGate,\n PassphraseRequest,\n} from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\nexport interface UsePassphraseGateReturn {\n /**\n * The open request, or null when nothing is being asked.\n *\n * Also null when no gate exists — an app that supplies its own\n * `encryptionPassphrase`, or one with encryption off entirely. A dialog can\n * render against this unconditionally.\n */\n request: PassphraseRequest | null;\n /** Answer the open request. */\n submit: (passphrase: string) => void;\n /** Abandon it, failing the load or save that asked. */\n cancel: () => void;\n /** Drop the held passphrase, so the next operation asks again. */\n forget: (reason?: string) => void;\n /** Whether a passphrase is held for this session. */\n isUnlocked: boolean;\n gate: PassphraseGate | null;\n}\n\nconst NO_REQUEST = () => null;\nconst NEVER = () => () => {};\n\n/**\n * Drives the passphrase prompt for the embedded wallet's encrypted storage.\n *\n * The gate belongs to the client, so a dialog mounted anywhere under the\n * provider answers whichever load or save is currently blocked on it.\n */\nexport function usePassphraseGate(): UsePassphraseGateReturn {\n const { client } = useWeb3();\n const gate = resolveClient(client)?.passphraseGate ?? null;\n\n const request = useSyncExternalStore(\n gate?.subscribe ?? NEVER,\n gate?.getSnapshot ?? NO_REQUEST,\n // Server renders have no gate state. Returning null rather than reading\n // the live one keeps hydration from flashing a dialog the server never\n // rendered.\n NO_REQUEST,\n );\n\n const submit = useCallback(\n (passphrase: string) => gate?.submit(passphrase),\n [gate],\n );\n const cancel = useCallback(() => gate?.cancel(), [gate]);\n const forget = useCallback((reason?: string) => gate?.forget(reason), [gate]);\n\n return {\n request,\n submit,\n cancel,\n forget,\n isUnlocked: gate?.isUnlocked ?? false,\n gate,\n };\n}\n","import type {\n AddressResult,\n NameResolver,\n NameResolverConfig,\n} from \"@naculus/connect-core\";\nimport { useCallback } from \"react\";\nimport { useNameLookup } from \"../core/name-lookup\";\n\n/**\n * Result of a name resolution query.\n */\nexport interface UseResolveNameResult {\n /** Resolved address, or null if not found / not started. */\n data: AddressResult | null;\n /** Whether the resolution is in progress. */\n isLoading: boolean;\n /** Error that occurred during resolution, if any. */\n error: Error | null;\n /** Manually trigger re-resolution of the current name. */\n refetch: () => void;\n}\n\n/**\n * Options for the useResolveName hook.\n */\nexport interface UseResolveNameOptions {\n /** Whether to skip resolution (e.g. if input is invalid). Default: false. */\n skip?: boolean;\n /** Custom resolver configuration (overrides default RPC URLs). */\n resolverConfig?: NameResolverConfig;\n}\n\n/**\n * React hook to resolve a human-readable name to a blockchain address.\n *\n * Supports ENS (.eth) and SNS (.sol) names.\n * Automatically detects the name service from the suffix.\n *\n * @example\n * ```tsx\n * function AddressInput() {\n * const { data, isLoading, error } = useResolveName('vitalik.eth');\n * return <div>{data?.address ?? 'Enter a name'}</div>;\n * }\n * ```\n */\nexport function useResolveName(\n name: string,\n options?: UseResolveNameOptions,\n): UseResolveNameResult {\n const query = useCallback(\n (resolver: NameResolver, input: string) => resolver.resolveName(input),\n [],\n );\n\n return useNameLookup<AddressResult>({\n input: name,\n skip: options?.skip,\n resolverConfig: options?.resolverConfig,\n query,\n });\n}\n","/**\n * useSendUserOperation\n *\n * React hook for sending ERC-4337 UserOperations.\n * Uses the core SmartAccountManager so address derivation, deployment,\n * nonce reads, gas estimation, signing, and bundler serialization stay on one\n * implementation path.\n */\n\nimport {\n assertHexSignature,\n bareEvmAddress,\n buildSmartAccountConfig,\n resolveUserOpChain,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n Address,\n Call,\n Hex,\n SendUserOpOptions,\n UniversalWalletSession,\n UserOperationReceipt,\n UserOperationResponse,\n} from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\n\nasync function signHashWithSession(\n session: NonNullable<ReturnType<typeof useWeb3>[\"session\"]>,\n client: ReturnType<typeof useWeb3>[\"client\"],\n hash: Hex,\n address: Address,\n chainId: string,\n): Promise<Hex> {\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n\n const params = [hash, address];\n if (session.walletType === \"eip6963\" || session.id?.startsWith(\"eip6963-\")) {\n // `signMessage` accepts text and encodes it before personal_sign. A\n // UserOperation hash must instead reach the wallet as the original 32\n // bytes, so use the connector's raw EIP-1193 request here.\n const { eip6963Connector } = await import(\n \"@naculus/connector-evm-injected\"\n );\n const wallet = eip6963Connector\n .getDiscoveredWallets()\n .find((candidate) => candidate.id === session.walletId);\n const result = wallet\n ? await wallet.provider.request({ method: \"personal_sign\", params })\n : await eip6963Connector.request({\n method: \"personal_sign\",\n params,\n });\n return assertHexSignature(result);\n }\n\n if (session.walletType === \"walletconnect\") {\n return assertHexSignature(\n await activeClient.connector.request({\n method: \"personal_sign\",\n params,\n }),\n );\n }\n\n if (session.walletType === \"embedded\") {\n const embedded = activeClient.embeddedConnector as {\n signHash?: (\n session: UniversalWalletSession,\n hash: Hex,\n ) => Promise<`0x${string}`>;\n } | null;\n if (!embedded?.signHash) {\n throw new WalletError(\n \"method_unsupported\",\n \"This embedded wallet build cannot sign a raw digest. Upgrade @naculus/connector-embedded or pass an explicit signer.\",\n );\n }\n return assertHexSignature(await embedded.signHash(session, hash));\n }\n\n if (session.walletType === \"passkeys\") {\n // Not a missing primitive: a passkey signs with P-256 (COSE alg -7) and a\n // SimpleAccount recovers a secp256k1 key, so no wiring here can make the\n // two agree. It needs an account implementation that verifies P-256 on\n // chain — a WebAuthn validator, or RIP-7212 where the precompile exists.\n // Saying so is the difference between a fixable gap and an impossible one.\n throw new WalletError(\n \"method_unsupported\",\n \"Passkeys sign with P-256, which a SimpleAccount cannot verify. Use a smart account with a WebAuthn validator, or pass an explicit signer.\",\n );\n }\n\n throw new WalletError(\n \"method_unsupported\",\n `Raw UserOperation signing is not available for ${session.walletType} on ${chainId}. Pass a signer that signs the raw 32-byte hash.`,\n );\n}\n\nexport interface UseSendUserOperationOptions {\n /** RPC URL for the target chain */\n rpcUrl?: string;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Chain ID (CAIP-2 format) */\n chainId?: string;\n /** EntryPoint contract address */\n entryPoint?: Address;\n /** Smart account implementation type (default: \"simple\") */\n accountType?: \"simple\" | \"light\" | \"kernel\" | \"safe\";\n /** Optional salt for deterministic smart account address */\n salt?: bigint;\n /** Override the connected EVM account as the smart account owner */\n owner?: Address;\n /**\n * Optional signer for the UserOperation hash. A custom signer is assumed to\n * apply the signature scheme selected by `signerMode`.\n */\n signer?: (hash: Hex) => Promise<Hex> | Hex;\n /** Signature hash format expected by the account implementation */\n signerMode?: \"raw\" | \"eip191\";\n}\n\nexport interface UseSendUserOperationReturn {\n /** Send a UserOperation with the given calls */\n sendUserOp: (\n calls: Call[],\n options?: SendUserOpOptions,\n ) => Promise<UserOperationResponse | null>;\n /** The userOpHash from the last send */\n userOpHash: Hex | null;\n /** The receipt from the last UserOperation (null while pending) */\n receipt: UserOperationReceipt | null;\n /** Whether a UserOperation is currently being sent */\n isPending: boolean;\n /** Loading state for gas estimation and submission */\n isEstimating: boolean;\n /** Error state */\n error: Error | null;\n /** Reset state */\n reset: () => void;\n}\n\n/**\n * Hook for sending ERC-4337 UserOperations to a bundler.\n *\n * The connected EVM account is used as the smart-account owner. The hook uses\n * the active wallet's raw `personal_sign` request for WalletConnect and\n * injected wallets; embedded/passkey users must provide a raw-hash signer until\n * those connectors expose one.\n */\nexport function useSendUserOperation(\n options?: UseSendUserOperationOptions,\n): UseSendUserOperationReturn {\n const { evmAccount } = useAccount();\n const { session, chainId: connectedChainId, client } = useWeb3();\n const [userOpHash, setUserOpHash] = useState<Hex | null>(null);\n const [receipt, setReceipt] = useState<UserOperationReceipt | null>(null);\n const [isPending, setIsPending] = useState(false);\n const [isEstimating, setIsEstimating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const requestIdRef = useRef(0);\n const inFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n // Receipt polling can outlive the component. Invalidate its callbacks so\n // an unmounted hook cannot publish stale state.\n requestIdRef.current += 1;\n inFlightRef.current = false;\n };\n }, []);\n\n // A context change invalidates an in-flight operation. The manager captures\n // the old owner, chain, and signer in its closure, so its result must not be\n // published after React has rendered a new wallet context.\n // biome-ignore lint/correctness/useExhaustiveDependencies: The effect intentionally resets operation state when the wallet context changes.\n useEffect(() => {\n requestIdRef.current += 1;\n inFlightRef.current = false;\n setUserOpHash(null);\n setReceipt(null);\n setIsPending(false);\n setIsEstimating(false);\n setError(null);\n }, [\n client,\n connectedChainId,\n evmAccount,\n options?.accountType,\n options?.bundlerUrl,\n options?.chainId,\n options?.entryPoint,\n options?.owner,\n options?.rpcUrl,\n options?.salt,\n options?.signerMode,\n session,\n ]);\n\n const sendUserOp = useCallback(\n async (\n calls: Call[],\n opts?: SendUserOpOptions,\n ): Promise<UserOperationResponse | null> => {\n const fail = (nextError: Error): null => {\n setError(nextError);\n return null;\n };\n\n if (!options?.rpcUrl) return fail(new Error(\"RPC URL not configured\"));\n if (!options.bundlerUrl)\n return fail(new Error(\"Bundler URL not configured\"));\n if (!calls.length)\n return fail(new Error(\"At least one call is required\"));\n if (inFlightRef.current) {\n return fail(new Error(\"A UserOperation is already in progress\"));\n }\n\n const owner = bareEvmAddress(options.owner ?? evmAccount);\n if (!owner)\n return fail(\n new WalletError(\"wallet_unavailable\", \"No EVM account found\"),\n );\n\n // No mainnet default. The mismatch check below is skipped when there is\n // no connected chain, so defaulting there would build and sign a\n // UserOperation for chain 1 with nothing to contradict it — and the\n // chain ID is part of the hash the user approves.\n let targetChainId: string;\n try {\n targetChainId = resolveUserOpChain(options.chainId, connectedChainId);\n } catch (chainError) {\n return fail(chainError as Error);\n }\n if (!options.signer && !session) {\n return fail(new WalletError(\"wallet_unavailable\", \"No active session\"));\n }\n\n const requestId = ++requestIdRef.current;\n inFlightRef.current = true;\n setIsPending(true);\n setIsEstimating(true);\n setError(null);\n setUserOpHash(null);\n setReceipt(null);\n\n try {\n const { SmartAccountManager } = await import(\"@naculus/connect-core\");\n const signer =\n options.signer ??\n ((hash: Hex) =>\n signHashWithSession(session!, client, hash, owner, targetChainId));\n const manager = new SmartAccountManager({\n rpcUrl: options.rpcUrl,\n bundlerClient: { url: options.bundlerUrl },\n chainId: targetChainId,\n signer,\n // The wallet's personal_sign request applies EIP-191 itself. A\n // caller-supplied signer retains the core's historical default.\n signerMode: options.signer ? (options.signerMode ?? \"eip191\") : \"raw\",\n });\n const config = buildSmartAccountConfig(owner, targetChainId, options);\n\n const response = await manager.sendUserOperation(config, calls, opts);\n if (requestId !== requestIdRef.current) return null;\n\n setIsEstimating(false);\n setUserOpHash(response.userOpHash);\n\n // The core manager owns the receipt polling policy and validates the\n // receipt shape. A timeout should leave the submitted hash available;\n // callers can decide how to surface that pending state.\n void manager\n .getUserOperationReceipt(response.userOpHash)\n .then((nextReceipt) => {\n if (requestId === requestIdRef.current) setReceipt(nextReceipt);\n })\n .catch(() => undefined);\n\n return response;\n } catch (err) {\n if (requestId !== requestIdRef.current) return null;\n const nextError =\n err instanceof Error\n ? err\n : new Error(\"Failed to send UserOperation\");\n setError(nextError);\n return null;\n } finally {\n // The operation that took the single-flight slot has settled, whether\n // or not its result is still wanted.\n inFlightRef.current = false;\n if (requestId === requestIdRef.current) {\n setIsPending(false);\n setIsEstimating(false);\n }\n }\n },\n [client, connectedChainId, evmAccount, options, session],\n );\n\n // reset() does not unlock single-flight: an operation already handed to\n // the manager may still sign and broadcast, and a second sendUserOp in the\n // meantime would be a second on-chain side effect. The flag clears when\n // that operation settles.\n const reset = useCallback(() => {\n requestIdRef.current += 1;\n setUserOpHash(null);\n setReceipt(null);\n setIsPending(false);\n setIsEstimating(false);\n setError(null);\n }, []);\n\n return {\n sendUserOp,\n userOpHash,\n receipt,\n isPending,\n isEstimating,\n error,\n reset,\n };\n}\n","/**\n * useSession Hook\n *\n * Provides access to the complete session state from SessionManager,\n * including all active chain sessions, the active chain ID, and\n * connection status.\n *\n * @see SRS-009 §7.2\n */\n\nimport { useSyncExternalStore, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { ChainSession, ActiveSessionBundle } from \"@naculus/connect-core\";\n\nexport interface UseSessionReturn {\n /** The raw wallet session (from the active bundle) */\n session: ActiveSessionBundle[\"walletSession\"] | null;\n /** All chain sessions within the active bundle */\n chainSessions: ChainSession[];\n /** The currently active chain ID */\n activeChainId: string | null;\n /** Whether a wallet is connected */\n isConnected: boolean;\n /** The connector/wallet type (e.g., \"eip6963\", \"walletconnect\") */\n connectorId: string | null;\n}\n\nfunction subscribeToSessionManager(\n sm: import(\"@naculus/connect-core\").SessionManager | null,\n callback: () => void,\n): () => void {\n if (!sm) return () => {};\n\n const handler = () => callback();\n sm.on(\"sessionConnected\", handler);\n sm.on(\"sessionDisconnected\", handler);\n sm.on(\"chainChanged\", handler);\n // CAIP-25 lifecycle (connect-core >= 0.2.6): the wallet narrowed or\n // ended the session without the app asking.\n sm.on(\"sessionScopeChanged\", handler);\n sm.on(\"sessionRevoked\", handler);\n\n return () => {\n sm.off(\"sessionConnected\", handler);\n sm.off(\"sessionDisconnected\", handler);\n sm.off(\"chainChanged\", handler);\n sm.off(\"sessionScopeChanged\", handler);\n sm.off(\"sessionRevoked\", handler);\n };\n}\n\nconst EMPTY_SESSION: UseSessionReturn = Object.freeze({\n session: null,\n chainSessions: [],\n activeChainId: null,\n isConnected: false,\n connectorId: null,\n}) as UseSessionReturn;\n\n/**\n * Last snapshot handed to React, per SessionManager.\n *\n * useSyncExternalStore compares snapshots with Object.is and re-renders when\n * they differ, so returning a fresh object literal on every call meant the\n * comparison never succeeded: React re-rendered, called getSnapshot again, got\n * another new object, and threw \"Maximum update depth exceeded\". Any component\n * calling useSession() crashed on first render, which is also why this file\n * had no coverage — it had never actually run.\n *\n * The bundle is mutated in place rather than replaced, so identity alone is\n * not a usable signal; the derived fields are compared instead and a new\n * object is produced only when one of them actually changed.\n */\nconst snapshotCache = new WeakMap<object, UseSessionReturn>();\n\nfunction sameChainSessions(a: ChainSession[], b: ChainSession[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\nfunction getSessionSnapshot(\n sm: import(\"@naculus/connect-core\").SessionManager | null,\n): UseSessionReturn {\n if (!sm) return EMPTY_SESSION;\n\n const bundle = sm.getActiveBundle();\n const previous = snapshotCache.get(sm as unknown as object);\n\n if (!bundle) {\n if (previous && previous.session === null) return previous;\n snapshotCache.set(sm as unknown as object, EMPTY_SESSION);\n return EMPTY_SESSION;\n }\n\n const chainSessions = Array.from(bundle.chainSessions.values());\n if (\n previous &&\n previous.session === bundle.walletSession &&\n previous.activeChainId === bundle.activeChainId &&\n sameChainSessions(previous.chainSessions, chainSessions)\n ) {\n return previous;\n }\n\n const next: UseSessionReturn = {\n session: bundle.walletSession,\n chainSessions,\n activeChainId: bundle.activeChainId,\n isConnected: true,\n connectorId: bundle.walletSession.walletType,\n };\n snapshotCache.set(sm as unknown as object, next);\n return next;\n}\n\nexport function useSession(\n sessionManager?: import(\"@naculus/connect-core\").SessionManager | null,\n): UseSessionReturn {\n const web3 = useWeb3();\n const sm = sessionManager ?? web3.sessionManager ?? null;\n\n const subscribe = useCallback(\n (callback: () => void) => subscribeToSessionManager(sm, callback),\n [sm],\n );\n\n const getSnapshot = useCallback(() => getSessionSnapshot(sm), [sm]);\n\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","/**\n * useSIWxLogin — Trigger a SIWx sign-in flow.\n *\n * A simplified hook for initiating wallet sign-in.\n * Returns a `signIn()` function and loading/error state.\n */\n\nimport {\n defaultSiwxDomain,\n defaultSiwxUri,\n} from \"@naculus/connect-appkit-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n createSiwxMessage,\n generateNonce,\n getBlockchainName,\n issueNonce,\n nowISO,\n type SiwxResult,\n} from \"@naculus/siwx\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { selectSiwxAccount } from \"./siwx-accounts\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSIWxLoginOptions {\n /** Originating domain (default: window.location.host) */\n domain?: string;\n /** Human-readable statement */\n statement?: string;\n /** RFC 3986 URI (default: window.location.origin) */\n uri?: string;\n /** CAIP-2 chain ID (default: current chain from Web3 context) */\n chainId?: string;\n /** Session lifetime in seconds (default: 86400 = 24h) */\n expirySeconds?: number;\n /** URIs of resources the identity wishes to access */\n resources?: string[];\n /** CAIP-74 request ID */\n requestId?: string;\n}\n\nexport interface UseSIWxLoginReturn {\n /** Trigger the SIWx sign-in flow */\n signIn: (options?: UseSIWxLoginOptions) => Promise<SiwxResult>;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Last sign-in error */\n error: Error | null;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Defaults ─────────────────────────────────────────────────────\n\nconst DEFAULT_EXPIRY_SECONDS = 86_400; // 24h\n\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSIWxLogin(): UseSIWxLoginReturn {\n const { session, chainId: currentChainId, client } = useWeb3();\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const signIn = useCallback(\n async (options?: UseSIWxLoginOptions): Promise<SiwxResult> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n // No mainnet default. This value becomes the `Chain ID:` field of the\n // CAIP-122 message the user signs, so an assumed chain is an assertion\n // the user never made — and on a wallet sitting on another chain, a\n // signature that binds to the wrong one.\n const chainId = options?.chainId ?? currentChainId;\n if (!chainId) {\n throw new WalletError(\n \"invalid_chain\",\n \"No chain to sign for. Connect a wallet or pass options.chainId.\",\n );\n }\n const account = selectSiwxAccount(session, chainId);\n if (!account) {\n throw new WalletError(\"wallet_unavailable\", \"No account found\");\n }\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const { address } = account;\n const location =\n typeof window === \"undefined\" ? undefined : window.location;\n const domain = options?.domain ?? defaultSiwxDomain(location);\n const uri = options?.uri ?? defaultSiwxUri(location);\n setIsSigningIn(true);\n setError(null);\n\n try {\n const nonce = generateNonce();\n await issueNonce(nonce);\n const issuedAt = nowISO();\n const expirySeconds = options?.expirySeconds ?? DEFAULT_EXPIRY_SECONDS;\n const expirationTime = new Date(\n Date.now() + expirySeconds * 1000,\n ).toISOString();\n\n // Build the CAIP-122 message string\n const message = createSiwxMessage({\n domain,\n address,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n expirationTime,\n statement: options?.statement,\n resources: options?.resources,\n requestId: options?.requestId,\n });\n\n const signature = (await activeClient.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined,\n })) as string;\n\n const siwxResult: SiwxResult = {\n message: {\n raw: message,\n domain,\n address,\n statement: options?.statement ?? null,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n blockchain: getBlockchainName(chainId),\n expirationTime,\n notBefore: null,\n resources: options?.resources ?? [],\n requestId: options?.requestId ?? null,\n },\n signature,\n };\n\n setIsSigningIn(false);\n return siwxResult;\n } catch (err) {\n const wrappedErr =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrappedErr);\n setIsSigningIn(false);\n throw wrappedErr;\n }\n },\n [session, currentChainId, client],\n );\n\n return { signIn, isSigningIn, error, clearError };\n}\n","/**\n * useSIWxSession — Unified SIWx session management hook.\n *\n * Combines the sign-in flow with session persistence, expiry tracking,\n * and automatic restoration. Replaces the older useSiwxAuthSession.\n *\n * Provides:\n * - signIn / signOut / refresh lifecycle\n * - Auto-restore from storage on mount\n * - isExpired / timeUntilExpiry query\n * - Loading/error state\n */\n\nimport { siwxResultToSession } from \"@naculus/connect-appkit-core\";\nimport { logger } from \"@naculus/connect-core\";\nimport type { SiwxSession } from \"@naculus/siwx\";\nimport {\n checkSessionExpired,\n createLocalStorageSiwxSessionStorage,\n} from \"@naculus/siwx\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { UseSIWxLoginOptions } from \"./useSIWxLogin\";\nimport { useSIWxLogin } from \"./useSIWxLogin\";\n\n// ── Constants ────────────────────────────────────────────────────\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSIWxSessionOptions {\n /** Storage key prefix (default: \"naculus_\") */\n storagePrefix?: string;\n /** Auto-restore session from storage on mount (default: true) */\n autoRestore?: boolean;\n /** Default chain ID when signing in (default: current chain from context) */\n defaultChainId?: string;\n /** Default session lifetime in seconds (default: 86400 = 24h) */\n defaultExpirySeconds?: number;\n}\n\nexport interface UseSIWxSessionReturn {\n /** The current SIWx session, or null */\n session: SiwxSession | null;\n /** Whether a valid session exists */\n isAuthenticated: boolean;\n /** Whether we're still checking persisted auth on mount */\n isRestoring: boolean;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Whether the current session has expired */\n isExpired: boolean;\n /** Milliseconds until session expires, or null */\n timeUntilExpiry: number | null;\n\n /** Sign in with optional overrides */\n signIn: (options?: UseSIWxLoginOptions) => Promise<SiwxSession>;\n /** Sign out: clears session from memory and storage */\n signOut: () => Promise<void>;\n /** Refresh the current session */\n refresh: () => Promise<SiwxSession>;\n\n /** Last error */\n error: Error | null;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\n/**\n * Random suffix for a session record ID.\n *\n * `Math.random` gave roughly 31 predictable bits. The signature, not this ID,\n * is what authenticates a SIWx session, so this was not an authentication\n * bypass — but an ID a consumer may key storage or a request on should not be\n * guessable, and the CSPRNG is already the convention everywhere else here.\n */\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSIWxSession(\n options?: UseSIWxSessionOptions,\n): UseSIWxSessionReturn {\n const {\n storagePrefix = \"naculus_\",\n autoRestore = true,\n defaultExpirySeconds = 86_400,\n } = options ?? {};\n\n const [session, setSession] = useState<SiwxSession | null>(null);\n const [isRestoring, setIsRestoring] = useState(autoRestore);\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const { chainId: currentChainId } = useWeb3();\n const login = useSIWxLogin();\n const storageRef = useRef(\n createLocalStorageSiwxSessionStorage(`${storagePrefix}siwx_session`),\n );\n\n const clearError = useCallback(() => setError(null), []);\n\n // ── Restore from storage on mount ──────────────────────────────\n\n useEffect(() => {\n if (!autoRestore) {\n setIsRestoring(false);\n return;\n }\n\n let cancelled = false;\n\n (async () => {\n try {\n const storage = storageRef.current;\n const saved = await storage.get();\n\n if (cancelled) return;\n\n if (saved) {\n logger.info(\n \"react/useSIWxSession\",\n \"Restored persisted SIWx session\",\n );\n setSession(saved);\n setError(null);\n } else {\n // No valid session in storage\n setSession(null);\n }\n } catch (err) {\n logger.warn(\n \"react/useSIWxSession\",\n \"Failed to restore SIWx session:\",\n err,\n );\n setSession(null);\n } finally {\n if (!cancelled) setIsRestoring(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [autoRestore]);\n\n // ── Expiry refresh timer ───────────────────────────────────────\n\n useEffect(() => {\n if (!session?.expiresAt) return;\n\n const timeUntilExpiry = new Date(session.expiresAt).getTime() - Date.now();\n if (timeUntilExpiry <= 0) {\n // Already expired — clear session\n setSession(null);\n return;\n }\n\n // Schedule clearing when expired\n const timer = setTimeout(() => {\n setSession((prev) => {\n if (prev && prev.id === session.id) {\n return null;\n }\n return prev;\n });\n }, timeUntilExpiry);\n\n return () => clearTimeout(timer);\n }, [session?.id, session?.expiresAt]);\n\n // ── Sign In ────────────────────────────────────────────────────\n\n const signIn = useCallback(\n async (signOptions?: UseSIWxLoginOptions): Promise<SiwxSession> => {\n setIsSigningIn(true);\n setError(null);\n\n try {\n // Merge default options with provided overrides\n const effectiveOptions: UseSIWxLoginOptions = {\n expirySeconds: defaultExpirySeconds,\n chainId: currentChainId ?? undefined,\n ...signOptions,\n };\n\n const result = await login.signIn(effectiveOptions);\n\n // Convert SiwxResult to SiwxSession\n const siwxSession = siwxResultToSession(result);\n\n // Persist to storage\n const storage = storageRef.current;\n await storage.set(siwxSession);\n\n setSession(siwxSession);\n setIsSigningIn(false);\n return siwxSession;\n } catch (err) {\n const wrapped =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n },\n [login, currentChainId, defaultExpirySeconds],\n );\n\n // ── Sign Out ───────────────────────────────────────────────────\n\n const signOut = useCallback(async () => {\n try {\n const storage = storageRef.current;\n await storage.remove();\n } catch (err) {\n logger.warn(\"react/useSIWxSession\", \"Failed to clear session:\", err);\n }\n setSession(null);\n setError(null);\n }, []);\n\n // ── Refresh ────────────────────────────────────────────────────\n\n const refresh = useCallback(async (): Promise<SiwxSession> => {\n if (!session) {\n throw new Error(\"No active session to refresh\");\n }\n\n setIsSigningIn(true);\n setError(null);\n\n try {\n // Re-sign with updated timestamps\n const result = await login.signIn({\n domain: session.domain,\n statement: session.message.statement ?? undefined,\n uri: session.message.uri,\n chainId: session.chainId,\n expirySeconds: defaultExpirySeconds,\n resources:\n session.message.resources.length > 0\n ? session.message.resources\n : undefined,\n requestId: session.message.requestId ?? undefined,\n });\n\n const refreshedSession: SiwxSession = {\n ...siwxResultToSession(result),\n id: session.id, // preserve the original session ID\n refreshedAt: new Date().toISOString(),\n };\n\n // Persist\n const storage = storageRef.current;\n await storage.set(refreshedSession);\n\n setSession(refreshedSession);\n setIsSigningIn(false);\n return refreshedSession;\n } catch (err) {\n const wrapped =\n err instanceof Error ? err : new Error(\"Session refresh failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n }, [session, login, defaultExpirySeconds]);\n\n // ── Computed state ─────────────────────────────────────────────\n\n const isAuthenticated = session !== null && !checkSessionExpired(session);\n const expired = checkSessionExpired(session);\n const timeUntilExpiry = session?.expiresAt\n ? Math.max(0, new Date(session.expiresAt).getTime() - Date.now())\n : null;\n\n return {\n session: isAuthenticated ? session : null,\n isAuthenticated,\n isRestoring,\n isSigningIn,\n isExpired: expired,\n timeUntilExpiry,\n\n signIn,\n signOut,\n refresh,\n\n error,\n clearError,\n };\n}\n","import {\n defaultSiwxDomain,\n defaultSiwxUri,\n} from \"@naculus/connect-appkit-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n createSiwxMessage,\n generateNonce,\n getBlockchainName,\n issueNonce,\n nowISO,\n type SiwxResult,\n} from \"@naculus/siwx\";\nimport { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { selectSiwxAccount } from \"./siwx-accounts\";\n\nexport interface UseSignInWithXOptions {\n domain?: string;\n statement?: string;\n uri?: string;\n chainId?: string;\n expirySeconds?: number;\n resources?: string[];\n requestId?: string;\n}\n\nexport interface UseSignInWithXReturn {\n signIn: (options?: UseSignInWithXOptions) => Promise<SiwxResult>;\n isSigningIn: boolean;\n result: SiwxResult | null;\n error: Error | null;\n clearError: () => void;\n}\n\nexport function useSignInWithX(): UseSignInWithXReturn {\n const { session, chainId: currentChainId, client } = useWeb3();\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [result, setResult] = useState<SiwxResult | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const signIn = useCallback(\n async (options?: UseSignInWithXOptions): Promise<SiwxResult> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n // No mainnet default. This value becomes the `Chain ID:` field of the\n // CAIP-122 message the user signs, so an assumed chain is an assertion\n // the user never made — and on a wallet sitting on another chain, a\n // signature that binds to the wrong one.\n const chainId = options?.chainId ?? currentChainId;\n if (!chainId) {\n throw new WalletError(\n \"invalid_chain\",\n \"No chain to sign for. Connect a wallet or pass options.chainId.\",\n );\n }\n const account = selectSiwxAccount(session, chainId);\n if (!account) {\n throw new WalletError(\"wallet_unavailable\", \"No account found\");\n }\n const activeClient = resolveClient(client);\n if (!activeClient) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n const { address } = account;\n const location =\n typeof window === \"undefined\" ? undefined : window.location;\n const domain = options?.domain ?? defaultSiwxDomain(location);\n const uri = options?.uri ?? defaultSiwxUri(location);\n setIsSigningIn(true);\n setError(null);\n\n try {\n const nonce = generateNonce();\n await issueNonce(nonce);\n const issuedAt = nowISO();\n\n const message = createSiwxMessage({\n domain,\n address,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n statement: options?.statement,\n expirationTime: options?.expirySeconds\n ? new Date(Date.now() + options.expirySeconds * 1000).toISOString()\n : undefined,\n resources: options?.resources,\n requestId: options?.requestId,\n });\n\n const signature = (await activeClient.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined,\n })) as string;\n\n const expirationTime = options?.expirySeconds\n ? new Date(Date.now() + options.expirySeconds * 1000).toISOString()\n : null;\n\n const siwxResult: SiwxResult = {\n message: {\n raw: message,\n domain,\n address,\n statement: options?.statement ?? null,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n blockchain: getBlockchainName(chainId),\n expirationTime,\n notBefore: null,\n resources: options?.resources ?? [],\n requestId: options?.requestId ?? null,\n },\n signature,\n };\n\n setResult(siwxResult);\n return siwxResult;\n } catch (err) {\n const wrappedErr =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrappedErr);\n throw wrappedErr;\n } finally {\n setIsSigningIn(false);\n }\n },\n [session, currentChainId, client],\n );\n\n return { signIn, isSigningIn, result, error, clearError };\n}\n","import { useSignInWithX } from \"./useSignInWithX\";\nimport type { UseSignInWithXOptions, UseSignInWithXReturn } from \"./useSignInWithX\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useCallback } from \"react\";\n\nexport interface UseSignInWithEthereumOptions extends UseSignInWithXOptions {}\n\nexport interface UseSignInWithEthereumReturn extends UseSignInWithXReturn {}\n\nfunction useEip155SessionGuard(): (chainId?: string) => void {\n const { session, chainId: activeChainId } = useWeb3();\n return useCallback((chainId?: string) => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n const requestedChainId = chainId ?? activeChainId;\n if (requestedChainId && !requestedChainId.startsWith(\"eip155:\")) {\n throw new WalletError(\n \"namespace_mismatch\",\n `Ethereum SIWx requires an eip155 chain, received ${requestedChainId}`,\n );\n }\n const evmNamespace = session.namespaces.eip155;\n if (!evmNamespace || evmNamespace.accounts.length === 0) {\n throw new WalletError(\n \"namespace_mismatch\",\n \"No EVM (eip155) accounts found in session\"\n );\n }\n }, [session, activeChainId]);\n}\n\nexport function useSignInWithEthereum(): UseSignInWithEthereumReturn {\n const guard = useEip155SessionGuard();\n const siwx = useSignInWithX();\n\n const signIn = useCallback(\n async (options?: UseSignInWithEthereumOptions) => {\n guard(options?.chainId);\n return siwx.signIn(options);\n },\n [guard, siwx.signIn]\n );\n\n return {\n signIn,\n isSigningIn: siwx.isSigningIn,\n result: siwx.result,\n error: siwx.error,\n clearError: siwx.clearError,\n };\n}\n","import { resolveSimulationEndpoint } from \"@naculus/connect-appkit-core\";\n\n/**\n * useSimulateTransfer — React hook for simulating ERC-20 token transfers.\n *\n * Wraps SimulationManager.simulateERC20Transfer in a React hook with\n * reactive state for loading, result, and error.\n *\n * @example\n * ```tsx\n * import { useSimulateTransfer } from \"@naculus/connect-appkit-react\";\n *\n * function SendForm({ token, to, amount }) {\n * const { result, simulate, loading } = useSimulateTransfer({\n * rpcUrl: \"https://eth.llamarpc.com\",\n * });\n *\n * return (\n * <div>\n * <button onClick={() => simulate(token, to, amount)} disabled={loading}>\n * Simulate Transfer\n * </button>\n * {result && <p>Result: {result.status}</p>}\n * </div>\n * );\n * }\n * ```\n */\n\nimport type { SimulationResult } from \"@naculus/wallet-engine\";\nimport { SimulationManager } from \"@naculus/wallet-engine\";\nimport { useCallback, useRef, useState } from \"react\";\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface UseSimulateTransferOptions {\n /** RPC URL for eth_call simulation */\n rpcUrl?: string;\n /** Default chain ID */\n chainId?: number;\n}\n\nexport interface UseSimulateTransferReturn {\n /** Current simulation result */\n result: SimulationResult | null;\n /** Whether a simulation is in progress */\n loading: boolean;\n /** Last error (null if no error) */\n error: Error | null;\n /**\n * Simulate an ERC-20 transfer.\n *\n * @param tokenAddress - ERC-20 token contract address\n * @param from - Sender address\n * @param to - Recipient address\n * @param amount - Human-readable amount (e.g. \"1.50\")\n * @param options - Optional chainId, rpcUrl, decimals override\n */\n simulate: (\n tokenAddress: `0x${string}`,\n from: `0x${string}`,\n to: `0x${string}`,\n amount: string,\n options?: {\n chainId?: number;\n rpcUrl?: string;\n decimals?: number;\n },\n ) => Promise<SimulationResult>;\n /** Reset result and error state */\n reset: () => void;\n}\n\n// ── Hook ───────────────────────────────────────────────────────────\n\n/**\n * Hook for simulating an ERC-20 token transfer.\n *\n * Creates a SimulationManager internally and provides a `simulate`\n * function that builds transfer calldata automatically.\n *\n * @param options - Configuration for the underlying SimulationManager\n */\nexport function useSimulateTransfer(\n options?: UseSimulateTransferOptions,\n): UseSimulateTransferReturn {\n const rpcUrl = options?.rpcUrl;\n const chainId = options?.chainId;\n\n // ── SimulationManager ref (lazy init) ──────────────────────────\n\n const managerRef = useRef<SimulationManager | null>(null);\n\n const getManager = useCallback((): SimulationManager => {\n if (!managerRef.current) {\n managerRef.current = new SimulationManager({\n enabled: true,\n rpcUrl,\n autoSimulate: false,\n });\n }\n return managerRef.current;\n }, [rpcUrl]);\n\n // ── State ──────────────────────────────────────────────────────\n\n const [result, setResult] = useState<SimulationResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // ── Simulate ───────────────────────────────────────────────────\n\n const simulate = useCallback(\n async (\n tokenAddress: `0x${string}`,\n from: `0x${string}`,\n to: `0x${string}`,\n amount: string,\n simOptions?: {\n chainId?: number;\n rpcUrl?: string;\n decimals?: number;\n },\n ): Promise<SimulationResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const manager = getManager();\n // No `?? 1`. Simulating an ERC-20 transfer on the wrong chain reads a\n // different contract at the same address, so the preview describes a\n // transfer that will not happen.\n const endpoint = resolveSimulationEndpoint(\n simOptions?.chainId,\n chainId,\n simOptions?.rpcUrl,\n rpcUrl,\n );\n // Forwarded rather than computed and dropped. Without it a caller's\n // per-call endpoint did nothing, and the simulation ran against\n // whichever URL happened to be baked into the manager on first use.\n const simResult = await manager.simulateERC20Transfer(\n tokenAddress,\n from,\n to,\n amount,\n endpoint.chainId,\n simOptions?.decimals,\n endpoint.rpcUrl,\n );\n\n setResult(simResult);\n return simResult;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n } finally {\n setLoading(false);\n }\n },\n [rpcUrl, chainId, getManager],\n );\n\n // ── Reset ──────────────────────────────────────────────────────\n\n const reset = useCallback(() => {\n setResult(null);\n setError(null);\n setLoading(false);\n }, []);\n\n // ── Return ─────────────────────────────────────────────────────\n\n return { result, loading, error, simulate, reset };\n}\n","import {\n isSiwxExpired,\n isSiwxNotBeforeValid,\n} from \"@naculus/connect-appkit-core\";\nimport { LocalStorageAdapter, logger } from \"@naculus/connect-core\";\nimport type { SiwxResult } from \"@naculus/siwx\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseSignInWithXOptions } from \"./useSignInWithX\";\nimport { useSignInWithX } from \"./useSignInWithX\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSiwxAuthSessionOptions {\n /** Storage key prefix (default: \"naculus_\") */\n storagePrefix?: string;\n /** Auto-restore auth from storage on mount (default: true) */\n autoRestore?: boolean;\n}\n\nexport interface UseSiwxAuthSessionReturn {\n /** Whether a valid SIWx auth session exists */\n isSignedIn: boolean;\n /** Whether we're still checking persisted auth on mount */\n isRestoring: boolean;\n /** The persisted SIWx result, or null if not signed in */\n siwxResult: SiwxResult | null;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Last sign-in error */\n error: Error | null;\n /** Sign in with optional overrides. Persists result to storage on success. */\n signIn: (options?: UseSignInWithXOptions) => Promise<SiwxResult>;\n /** Sign out: clears persisted auth and resets state */\n signOut: () => void;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Constants ────────────────────────────────────────────────────\n\nconst SIWX_AUTH_KEY = \"siwx_auth\";\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction getStorage(prefix: string): LocalStorageAdapter {\n return new LocalStorageAdapter(prefix);\n}\n\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSiwxAuthSession(\n options?: UseSiwxAuthSessionOptions,\n): UseSiwxAuthSessionReturn {\n const { storagePrefix = \"naculus_\", autoRestore = true } = options ?? {};\n\n const [siwxResult, setSiwxResult] = useState<SiwxResult | null>(null);\n const [isRestoring, setIsRestoring] = useState(autoRestore);\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Use the generic SIWx hook for the underlying signing flow.\n const signInWithX = useSignInWithX();\n const storageRef = useRef(getStorage(storagePrefix));\n\n const clearError = useCallback(() => setError(null), []);\n\n // ── Restore persisted auth on mount ────────────────────────────\n\n useEffect(() => {\n if (!autoRestore) {\n setIsRestoring(false);\n return;\n }\n\n let cancelled = false;\n\n (async () => {\n try {\n const storage = storageRef.current;\n const saved = await storage.get<SiwxResult>(SIWX_AUTH_KEY);\n\n if (cancelled) return;\n\n if (\n saved &&\n !isSiwxExpired(saved, new Date()) &&\n isSiwxNotBeforeValid(saved, new Date())\n ) {\n logger.info(\n \"react/useSiwxAuthSession\",\n \"Restored persisted SIWx auth session\",\n );\n setSiwxResult(saved);\n setError(null);\n } else if (saved) {\n // Expired or not-yet-valid — clean up stale entry\n logger.info(\n \"react/useSiwxAuthSession\",\n \"Persisted SIWx auth expired, clearing\",\n );\n await storage.remove(SIWX_AUTH_KEY);\n }\n } catch (err) {\n logger.warn(\n \"react/useSiwxAuthSession\",\n \"Failed to restore SIWx auth:\",\n err,\n );\n } finally {\n if (!cancelled) setIsRestoring(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [autoRestore]);\n\n // ── Sign In ────────────────────────────────────────────────────\n\n const signIn = useCallback(\n async (signOptions?: UseSignInWithXOptions): Promise<SiwxResult> => {\n setIsSigningIn(true);\n setError(null);\n\n try {\n const result = await signInWithX.signIn(signOptions);\n\n // Persist to storage\n const storage = storageRef.current;\n await storage.set(SIWX_AUTH_KEY, result);\n\n setSiwxResult(result);\n setIsSigningIn(false);\n return result;\n } catch (err) {\n const wrapped =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n },\n [signInWithX],\n );\n\n // ── Sign Out ───────────────────────────────────────────────────\n\n const signOut = useCallback(async () => {\n try {\n const storage = storageRef.current;\n await storage.remove(SIWX_AUTH_KEY);\n } catch (err) {\n logger.warn(\n \"react/useSiwxAuthSession\",\n \"Failed to clear SIWx auth:\",\n err,\n );\n }\n setSiwxResult(null);\n setError(null);\n }, []);\n\n // ── Result ─────────────────────────────────────────────────────\n\n return {\n isSignedIn: siwxResult !== null,\n isRestoring,\n siwxResult,\n isSigningIn,\n error,\n signIn,\n signOut,\n clearError,\n };\n}\n","/**\n * useSmartAccount\n *\n * React hook for ERC-4337 Smart Account lifecycle management.\n * Provides create, deploy, and address lookup for smart contract wallets.\n *\n * @example\n * ```tsx\n * const { address, isDeployed, createWallet, deployWallet, isLoading } = useSmartAccount({\n * rpcUrl: \"https://eth.llamarpc.com\",\n * bundlerUrl: \"https://api.pimlico.io/v2/1/rpc?apikey=...\",\n * });\n * ```\n */\n\nimport {\n bareEvmAddress,\n buildSmartAccountConfig,\n resolveEvmChainId,\n} from \"@naculus/connect-appkit-core\";\nimport type {\n Address,\n SmartAccountConfig,\n SmartAccountInfo,\n} from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useAccount } from \"./useAccount\";\n\nfunction accountError(message: string): WalletError {\n return new WalletError(\"wallet_unavailable\", message);\n}\n\nexport interface UseSmartAccountOptions {\n /** RPC URL for the target chain */\n rpcUrl?: string;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Chain ID (CAIP-2 format) */\n chainId?: string;\n /** ERC-4337 EntryPoint address for the selected supported chain */\n entryPoint?: Address;\n /** Account type (default: \"simple\") */\n accountType?: \"simple\" | \"light\" | \"kernel\" | \"safe\";\n /** Optional salt for deterministic address */\n salt?: bigint;\n}\n\nexport interface UseSmartAccountReturn {\n /** Smart account address (null if not created) */\n address: Address | null;\n /** Whether the account is deployed on-chain */\n isDeployed: boolean;\n /** Smart account info object */\n accountInfo: SmartAccountInfo | null;\n /** Loading state */\n isLoading: boolean;\n /** Error state */\n error: Error | null;\n /** Create a new smart account (compute address) */\n createWallet: () => Promise<SmartAccountInfo | null>;\n /** Deploy the smart account to chain */\n deployWallet: () => Promise<Address | null>;\n /** Get the counterfactual address without creating */\n getAddress: () => Promise<Address | null>;\n}\n\n/**\n * Hook for managing a ERC-4337 Smart Contract Wallet lifecycle.\n *\n * @param options - Smart account configuration options\n * @returns Smart account state and actions\n */\nexport function useSmartAccount(\n options?: UseSmartAccountOptions,\n): UseSmartAccountReturn {\n const { evmAccount } = useAccount();\n const { session, chainId: connectedChainId, client } = useWeb3();\n const [address, setAddress] = useState<Address | null>(null);\n const [isDeployed, setIsDeployed] = useState(false);\n const [accountInfo, setAccountInfo] = useState<SmartAccountInfo | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const managerRef = useRef<\n import(\"@naculus/connect-core\").SmartAccountManager | null\n >(null);\n const generationRef = useRef(0);\n const inFlightRef = useRef(false);\n\n // Initialize SmartAccountManager on config change (with cleanup to prevent race conditions)\n useEffect(() => {\n managerRef.current = null;\n if (!options?.rpcUrl) {\n return;\n }\n\n let cancelled = false;\n\n import(\"@naculus/connect-core\")\n .then(({ SmartAccountManager }) => {\n if (cancelled) return; // prevent stale state update\n // No mainnet default: a manager built for the wrong chain reads the\n // wrong EntryPoint and derives an address the user never sees.\n const chainId = resolveEvmChainId(options.chainId, connectedChainId);\n if (!chainId) return;\n managerRef.current = new SmartAccountManager({\n rpcUrl: options.rpcUrl!,\n chainId,\n bundlerClient: {\n url: options.bundlerUrl ?? \"\",\n },\n });\n })\n .catch((err) => {\n if (cancelled) return; // prevent stale state update\n setError(\n err instanceof Error\n ? err\n : new Error(\"Failed to load account-abstraction module\"),\n );\n });\n\n return () => {\n cancelled = true;\n };\n }, [\n connectedChainId,\n options?.rpcUrl,\n options?.bundlerUrl,\n options?.chainId,\n ]);\n\n // Account and chain changes invalidate derived state. A result from the\n // previous owner must never remain visible as the current smart account.\n // biome-ignore lint/correctness/useExhaustiveDependencies: The effect intentionally resets derived state when any account configuration value changes.\n useEffect(() => {\n generationRef.current += 1;\n inFlightRef.current = false;\n setAddress(null);\n setIsDeployed(false);\n setAccountInfo(null);\n setIsLoading(false);\n setError(null);\n }, [\n evmAccount,\n connectedChainId,\n options?.rpcUrl,\n options?.bundlerUrl,\n options?.chainId,\n options?.entryPoint,\n options?.accountType,\n options?.salt,\n ]);\n\n // Get account config from options + connected EOA\n const getConfig = useCallback((): SmartAccountConfig | null => {\n const owner = bareEvmAddress(evmAccount);\n if (!owner || !managerRef.current) return null;\n // Returning null rather than assuming a chain. getConfig already has a\n // null contract, and every caller checks it.\n const chainId = resolveEvmChainId(options?.chainId, connectedChainId);\n if (!chainId) return null;\n\n return buildSmartAccountConfig(owner, chainId, {\n accountType: options?.accountType,\n entryPoint: options?.entryPoint,\n salt: options?.salt,\n });\n }, [\n evmAccount,\n connectedChainId,\n options?.accountType,\n options?.chainId,\n options?.entryPoint,\n options?.salt,\n ]);\n\n const fail = useCallback((nextError: Error): null => {\n setError(nextError);\n return null;\n }, []);\n\n const ensureOperation = useCallback((): number | null => {\n if (inFlightRef.current) {\n return null;\n }\n inFlightRef.current = true;\n return generationRef.current;\n }, []);\n\n const finishOperation = useCallback((operation: number): void => {\n if (generationRef.current === operation) inFlightRef.current = false;\n }, []);\n\n // Create wallet (compute counterfactual address)\n const createWallet =\n useCallback(async (): Promise<SmartAccountInfo | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) {\n return fail(new Error(\"Smart account not configured\"));\n }\n\n const operation = ensureOperation();\n if (operation === null)\n return fail(new Error(\"Smart account operation already in progress\"));\n\n setIsLoading(true);\n setError(null);\n\n try {\n const manager = managerRef.current;\n const info = await manager.createAccount(config);\n if (generationRef.current !== operation) return null;\n setAddress(info.address);\n setIsDeployed(info.isDeployed);\n setAccountInfo(info);\n return info;\n } catch (err) {\n if (generationRef.current !== operation) return null;\n const e =\n err instanceof Error\n ? err\n : new Error(\"Failed to create smart account\");\n setError(e);\n return null;\n } finally {\n if (generationRef.current === operation) setIsLoading(false);\n finishOperation(operation);\n }\n }, [ensureOperation, fail, finishOperation, getConfig]);\n\n // Deploy wallet\n const deployWallet = useCallback(async (): Promise<Address | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) {\n return fail(new Error(\"Smart account not configured\"));\n }\n\n if (!session) return fail(accountError(\"No active session\"));\n const activeClient = resolveClient(client);\n if (!activeClient) return fail(accountError(\"Client not initialized\"));\n if (connectedChainId && connectedChainId !== config.chainId) {\n return fail(\n new WalletError(\n \"chain_mismatch\",\n `Connected chain ${connectedChainId} does not match smart account chain ${config.chainId}.`,\n ),\n );\n }\n\n const operation = ensureOperation();\n if (operation === null)\n return fail(new Error(\"Smart account operation already in progress\"));\n\n setIsLoading(true);\n setError(null);\n\n try {\n const manager = managerRef.current;\n const before = await manager.createAccount(config);\n if (generationRef.current !== operation) return null;\n if (before.isDeployed) {\n setAddress(before.address);\n setIsDeployed(true);\n setAccountInfo(before);\n return before.address;\n }\n\n // SmartAccountManager.deployAccount intentionally refuses to broadcast\n // an account that is not deployed. Build the factory transaction and route it\n // through the active wallet instead.\n const deployTx = await manager.getDeployCallData(config);\n const deployResult = (await activeClient.sendTransaction(session, {\n transaction: {\n to: deployTx.to,\n data: deployTx.data,\n value: deployTx.value.toString(),\n },\n chainId: config.chainId,\n })) as Address;\n\n if (generationRef.current !== operation) return null;\n const after = await manager.createAccount(config);\n setAddress(after.address);\n setIsDeployed(after.isDeployed);\n setAccountInfo(after);\n return deployResult;\n } catch (err) {\n if (generationRef.current !== operation) return null;\n const e =\n err instanceof Error\n ? err\n : new Error(\"Failed to deploy smart account\");\n setError(e);\n return null;\n } finally {\n if (generationRef.current === operation) setIsLoading(false);\n finishOperation(operation);\n }\n }, [\n client,\n connectedChainId,\n ensureOperation,\n fail,\n finishOperation,\n getConfig,\n session,\n ]);\n\n // Get counterfactual address\n const getAddress = useCallback(async (): Promise<Address | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) return null;\n const generation = generationRef.current;\n\n try {\n const addr = await managerRef.current.getAccountAddress(config);\n if (generationRef.current !== generation) return null;\n setAddress(addr);\n return addr;\n } catch (err) {\n if (generationRef.current !== generation) return null;\n setError(\n err instanceof Error\n ? err\n : new Error(\"Failed to get smart account address\"),\n );\n return null;\n }\n }, [getConfig]);\n\n return {\n address,\n isDeployed,\n accountInfo,\n isLoading,\n error,\n createWallet,\n deployWallet,\n getAddress,\n };\n}\n","import { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface UseSolanaAccountReturn {\n /** The bare base58 address, or null when no Solana account is connected. */\n address: string | null;\n /** The CAIP-10 form, which carries which cluster it is on. */\n caip10: string | null;\n /** The CAIP-2 cluster, e.g. `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`. */\n chainId: string | null;\n isConnected: boolean;\n}\n\n/**\n * The connected Solana account, whichever wallet supplied it.\n *\n * Read off the session's namespaces rather than from the embedded connector,\n * so an injected wallet (Phantom, Solflare) and the embedded wallet answer the\n * same way.\n *\n * Matched on the `solana:` namespace, never on address shape. A base58 string\n * is not distinguishable from other base58 strings by inspection, and guessing\n * would eventually call something a Solana address that is not one.\n */\nexport function useSolanaAccount(): UseSolanaAccountReturn {\n const { accounts, isConnected } = useWeb3();\n\n return useMemo(() => {\n if (!isConnected) {\n return { address: null, caip10: null, chainId: null, isConnected: false };\n }\n const caip10 = accounts.find((a) => a.startsWith(\"solana:\")) ?? null;\n if (!caip10) {\n return { address: null, caip10: null, chainId: null, isConnected };\n }\n // `solana:<reference>:<address>` — the address is the last segment and the\n // reference may itself contain no colon, so splitting from the end is safe.\n const parts = caip10.split(\":\");\n const address = parts.length >= 3 ? parts[parts.length - 1] : null;\n const chainId = parts.length >= 3 ? parts.slice(0, -1).join(\":\") : null;\n return { address, caip10, chainId, isConnected };\n }, [accounts, isConnected]);\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n getSolanaBalance,\n type SolanaBalance,\n} from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\nimport { useSolanaAccount } from \"./useSolanaAccount\";\n\nexport interface UseSolanaBalanceOptions {\n /** Defaults to the connected Solana account. */\n address?: string;\n /** Defaults to the client's `solanaRpcUrl`. */\n rpcUrl?: string;\n /** Milliseconds between refreshes. Off by default. */\n refreshInterval?: number;\n}\n\nexport interface UseSolanaBalanceReturn {\n /** Null until a balance has actually been read. Never a fabricated zero. */\n balance: SolanaBalance | null;\n isFetching: boolean;\n error: Error | null;\n /** Absent when no RPC endpoint is configured — a different fact from a\n * balance of zero, and the only one a caller can act on. */\n isConfigured: boolean;\n refetch: () => Promise<void>;\n}\n\n/**\n * The SOL balance of the connected Solana account.\n *\n * `balance` stays null until a read succeeds. A zero placeholder while\n * loading, or after a failure, is a number a user reads as their balance.\n */\nexport function useSolanaBalance(\n options: UseSolanaBalanceOptions = {},\n): UseSolanaBalanceReturn {\n const { client } = useWeb3();\n const { address: connectedAddress } = useSolanaAccount();\n const address = options.address ?? connectedAddress;\n const rpcUrl = options.rpcUrl ?? resolveClient(client)?.solanaRpcUrl ?? null;\n\n const [balance, setBalance] = useState<SolanaBalance | null>(null);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n // Guards against a slow response for a previous address overwriting the\n // balance of the one now on screen.\n const generationRef = useRef(0);\n\n const refetch = useCallback(async () => {\n if (!address || !rpcUrl) {\n setBalance(null);\n return;\n }\n const generation = ++generationRef.current;\n setIsFetching(true);\n setError(null);\n try {\n const next = await getSolanaBalance(rpcUrl, address);\n if (generation !== generationRef.current) return;\n setBalance(next);\n } catch (err) {\n if (generation !== generationRef.current) return;\n // Cleared rather than left stale: a balance shown next to an error is\n // read as the current balance, and it is not.\n setBalance(null);\n setError(err instanceof Error ? err : new Error(\"Balance read failed\"));\n } finally {\n if (generation === generationRef.current) setIsFetching(false);\n }\n }, [address, rpcUrl]);\n\n useEffect(() => {\n void refetch();\n }, [refetch]);\n\n useEffect(() => {\n if (!options.refreshInterval || options.refreshInterval <= 0) return;\n const id = setInterval(() => void refetch(), options.refreshInterval);\n return () => clearInterval(id);\n }, [options.refreshInterval, refetch]);\n\n return {\n balance,\n isFetching,\n error,\n isConfigured: Boolean(rpcUrl),\n refetch,\n };\n}\n","import {\n readSolanaRoles,\n type SolanaIdentity,\n type SolanaPayer,\n type SolanaRoles,\n type SolanaRolesAbsence,\n type SolanaRolesSource,\n type SolanaSigner,\n type SolanaWalletFeatures,\n} from \"@naculus/connect-appkit-core\";\nimport { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\n// Re-exported rather than declared here, for the same reason as\n// `AtomicSupport`: Vue needs the same shapes, and the declaration that\n// `signer` is `null` rather than a throwing stub must exist exactly once.\nexport type {\n SolanaIdentity,\n SolanaPayer,\n SolanaRoles,\n SolanaRolesAbsence,\n SolanaSigner,\n SolanaWalletFeatures,\n};\n\nexport interface UseSolanaRolesReturn {\n /** The roles the connected account can fill, or null with a reason. */\n roles: SolanaRoles | null;\n /** Why `roles` is null. Null when it is not. */\n absence: SolanaRolesAbsence | null;\n /** Which account this is. Never null while `roles` is present. */\n identity: SolanaIdentity | null;\n /**\n * Signs without submitting. Null when the wallet declared it cannot — a\n * send-only wallet, the usual shape behind Mobile Wallet Adapter — *and*\n * null when nothing is known; check `absence` to tell those apart.\n */\n signer: SolanaSigner | null;\n /** Signs and broadcasts itself. Null under the same two conditions. */\n payer: SolanaPayer | null;\n}\n\n/**\n * Which roles the connected Solana account can actually fill.\n *\n * Ask before building a flow. A multisig proposal, a co-signed escrow or a\n * relayer-submitted transaction needs `signer`; an ordinary transfer needs\n * `payer`; filling an `authority` field needs only `identity`. A wallet can\n * answer yes to one and no to another, and finding out here is what keeps\n * the answer from arriving at the approval prompt instead.\n *\n * Synchronous: the connector recorded what the wallet declared at discovery,\n * so this never prompts. Recomputed when the session or its accounts change,\n * which is how an in-wallet account switch reaches `identity.address`.\n */\nexport function useSolanaRoles(): UseSolanaRolesReturn {\n const { client, session, accounts } = useWeb3();\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `accounts` is a dependency for its identity only. The connector mutates the session in place on an account switch, so `session` alone would not change, but `accounts` is re-derived from it and does.\n return useMemo(() => {\n const connector = resolveClient(client)?.solanaConnector as\n | SolanaRolesSource\n | null\n | undefined;\n const { roles, absence } = readSolanaRoles(connector, session);\n return {\n roles,\n absence,\n identity: roles?.identity ?? null,\n signer: roles?.signer ?? null,\n payer: roles?.payer ?? null,\n };\n }, [client, session, accounts]);\n}\n","import { WalletError } from \"@naculus/connect-core\";\nimport { useCallback, useState } from \"react\";\nimport {\n getSignatureStatus,\n type SolanaConfirmationStatus,\n} from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { resolveClient } from \"./client-resolver\";\n\nexport interface UseSolanaTransactionReturn {\n /**\n * Sign a serialized transaction and return the signed bytes.\n *\n * Build and serialize it with `@solana/kit` or `@solana/web3.js` first —\n * the wallet's job is the signature, not the instructions. base64 or raw\n * bytes both work.\n */\n signTransaction: (\n transaction: Uint8Array | string,\n ) => Promise<Uint8Array>;\n /** Sign and submit, returning the base58 signature the cluster reports. */\n sendTransaction: (transaction: Uint8Array | string) => Promise<string>;\n /** Poll a signature. `\"unknown\"` is its own answer, not a failure. */\n getStatus: (\n signature: string,\n ) => Promise<{ status: SolanaConfirmationStatus; error: string | null }>;\n isSigning: boolean;\n isSending: boolean;\n error: Error | null;\n reset: () => void;\n}\n\n/**\n * Sign and send Solana transactions through whichever wallet is connected.\n *\n * The wallet is not asked to understand the transaction. It fills its own\n * signature slot and, for send, hands the bytes to a cluster.\n */\nexport function useSolanaTransaction(): UseSolanaTransactionReturn {\n const { client, session } = useWeb3();\n const [isSigning, setIsSigning] = useState(false);\n const [isSending, setIsSending] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const requireSession = () => {\n const activeClient = resolveClient(client);\n if (!activeClient || !session) {\n throw new WalletError(\"wallet_unavailable\", \"No connected wallet.\");\n }\n return activeClient;\n };\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: requireSession reads client and session, which are the dependencies\n const signTransaction = useCallback(\n async (transaction: Uint8Array | string) => {\n setIsSigning(true);\n setError(null);\n try {\n const activeClient = requireSession();\n const signed = await activeClient.signTransaction(session!, {\n transaction,\n });\n return signed as Uint8Array;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Signing failed\");\n setError(e);\n throw e;\n } finally {\n setIsSigning(false);\n }\n },\n [client, session],\n );\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: requireSession reads client and session, which are the dependencies\n const sendTransaction = useCallback(\n async (transaction: Uint8Array | string) => {\n setIsSending(true);\n setError(null);\n try {\n const activeClient = requireSession();\n const signature = await activeClient.sendTransaction(session!, {\n transaction,\n });\n return signature as string;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Send failed\");\n setError(e);\n throw e;\n } finally {\n setIsSending(false);\n }\n },\n [client, session],\n );\n\n const getStatus = useCallback(\n async (signature: string) => {\n const rpcUrl = resolveClient(client)?.solanaRpcUrl;\n if (!rpcUrl) {\n throw new WalletError(\n \"no_rpc\",\n \"Set solanaRpcUrl on the client to read a signature's status.\",\n );\n }\n return getSignatureStatus(rpcUrl, signature);\n },\n [client],\n );\n\n return {\n signTransaction,\n sendTransaction,\n getStatus,\n isSigning,\n isSending,\n error,\n reset: () => setError(null),\n };\n}\n","/**\n * useSwitchChain Hook\n *\n * Provides the switchChain method with loading/error state tracking.\n *\n * @see SRS-009 §7.2\n */\n\nimport { useCallback, useState } from \"react\";\nimport { toChainSwitchError } from \"@naculus/connect-appkit-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport interface UseSwitchChainReturn {\n /** Switch the active chain for the current session */\n switchChain: (chainId: string) => Promise<void>;\n /** Whether a chain switch is in progress */\n isSwitching: boolean;\n /** The currently active chain ID */\n currentChainId: string | null;\n /** The last error that occurred during chain switch (if any) */\n error: Error | null;\n /** Clear the error state */\n clearError: () => void;\n}\n\nexport function useSwitchChain(): UseSwitchChainReturn {\n const { switchChain: providerSwitchChain, chainId } = useWeb3();\n const [isSwitching, setIsSwitching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleSwitchChain = useCallback(\n async (targetChainId: string) => {\n setIsSwitching(true);\n setError(null);\n\n try {\n await providerSwitchChain(targetChainId);\n } catch (err) {\n // Every failure used to become chain_unsupported, so a user pressing\n // Cancel was reported as the chain being unavailable — two states a UI\n // must treat differently, since one is worth offering to retry.\n const walletError = toChainSwitchError(err);\n setError(walletError);\n throw walletError;\n } finally {\n setIsSwitching(false);\n }\n },\n [providerSwitchChain],\n );\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n return {\n switchChain: handleSwitchChain,\n isSwitching,\n currentChainId: chainId,\n error,\n clearError,\n };\n}\n","import {\n chainNumber,\n resolveChain,\n toViemChain,\n} from \"@naculus/connect-appkit-core\";\nimport { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport {\n createPublicClient,\n http,\n formatUnits,\n type PublicClient,\n type Address,\n} from \"viem\";\n\nexport interface TokenInfo {\n /** ERC-20 token contract address */\n address: Address;\n /** Token symbol (e.g. \"USDC\", \"LINK\") */\n symbol: string;\n /** Token decimals (e.g. 6 for USDC, 18 for most) */\n decimals: number;\n /** Optional display name */\n name?: string;\n}\n\nexport interface UseTokenBalanceOptions {\n /** ERC-20 token(s) to query */\n tokens: TokenInfo[];\n /** Auto-refresh interval in milliseconds. Default: undefined (no auto-refresh). */\n refreshInterval?: number;\n}\n\nexport interface TokenBalanceResult {\n address: Address;\n symbol: string;\n decimals: number;\n name?: string;\n /** Raw balance as string (in smallest unit), or null if not loaded */\n balance: string | null;\n /** Human-readable formatted balance, or null if not loaded */\n formatted: string | null;\n}\n\n// ERC-20 ABI fragment for balanceOf\nconst erc20Abi = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"owner\", type: \"address\" }],\n outputs: [{ name: \"balance\", type: \"uint256\" }],\n },\n] as const;\n\nexport function useTokenBalance(options: UseTokenBalanceOptions) {\n const { evmAccount, isConnected } = useAccount();\n const { chainId, chains } = useWeb3();\n const [tokenBalances, setTokenBalances] = useState<TokenBalanceResult[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const { tokens, refreshInterval } = options;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n // Stable key for tokens to avoid infinite loops when array reference changes\n const tokensKey = useMemo(\n () => tokens.map(t => t.address.toLowerCase() + \"|\" + t.decimals + \"|\" + t.symbol).join(\",\"),\n [tokens]\n );\n\n const currentChain = useMemo(\n () => resolveChain(chains, chainId),\n [chainId, chains],\n );\n // Null for a non-EVM chain, and a viem client must not be built for one.\n const evmChainNumber = currentChain ? chainNumber(currentChain) : null;\n // Memoized: `toViemChain` builds a fresh object per call, and an unmemoized\n // one would change identity every render — which drives the client effects\n // below into a loop that never settles.\n const viemChain = useMemo(\n () => (currentChain ? toViemChain(currentChain, evmChainNumber) : null),\n [currentChain, evmChainNumber],\n );\n\n const [client, setClient] = useState<PublicClient | null>(null);\n\n useEffect(() => {\n if (!viemChain || !currentChain?.rpcUrl) {\n setClient(null);\n return;\n }\n\n const publicClient = createPublicClient({\n transport: http(currentChain.rpcUrl),\n chain: viemChain,\n });\n\n setClient(publicClient);\n }, [currentChain, viemChain]);\n\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on tokensKey (the token list by value), not on the array identity that changes every render\n const fetchTokenBalances = useCallback(async () => {\n if (!evmAccount || !client || tokens.length === 0) {\n setTokenBalances([]);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const address = evmAccount.includes(\":\")\n ? (evmAccount.split(\":\").pop() as Address)\n : (evmAccount as Address);\n\n // Query all token balances with individual error handling\n const results = await Promise.allSettled(\n tokens.map(async (token) => {\n try {\n const balance = await client.readContract({\n address: token.address,\n abi: erc20Abi,\n functionName: \"balanceOf\",\n args: [address],\n });\n return {\n address: token.address,\n symbol: token.symbol,\n decimals: token.decimals,\n name: token.name,\n balance: balance.toString(),\n formatted: formatUnits(balance, token.decimals),\n } as TokenBalanceResult;\n } catch {\n return {\n address: token.address,\n symbol: token.symbol,\n decimals: token.decimals,\n name: token.name,\n balance: null,\n formatted: null,\n } as TokenBalanceResult;\n }\n })\n );\n\n const balances: TokenBalanceResult[] = results.map((r) => {\n if (r.status === \"fulfilled\") {\n return r.value;\n }\n // Fallback for rejected promises (shouldn't happen with inner catch)\n return {\n address: \"\" as Address,\n symbol: \"?\",\n decimals: 0,\n balance: null,\n formatted: null,\n };\n });\n\n setTokenBalances(balances);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to fetch token balances\"));\n } finally {\n setIsLoading(false);\n }\n }, [evmAccount, client, tokensKey]);\n\n // Initial fetch\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on tokensKey (the token list by value), not on the array identity that changes every render\n useEffect(() => {\n if (isConnected && evmAccount && tokens.length > 0) {\n fetchTokenBalances();\n }\n }, [isConnected, evmAccount, tokensKey, fetchTokenBalances]);\n\n // Auto-refresh interval\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on tokensKey (the token list by value), not on the array identity that changes every render\n useEffect(() => {\n if (refreshInterval && refreshInterval > 0 && isConnected && evmAccount && tokens.length > 0) {\n intervalRef.current = setInterval(fetchTokenBalances, refreshInterval);\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [refreshInterval, isConnected, evmAccount, tokensKey, fetchTokenBalances]);\n\n // Helper: get a single token balance by address\n const getTokenBalance = useCallback(\n (tokenAddress: Address): TokenBalanceResult | undefined => {\n return tokenBalances.find(\n (tb) => tb.address.toLowerCase() === tokenAddress.toLowerCase()\n );\n },\n [tokenBalances]\n );\n\n return {\n /** Array of token balance results */\n tokenBalances,\n isLoading,\n error,\n /** Re-fetch all token balances */\n refetch: fetchTokenBalances,\n /** Get a specific token balance by contract address */\n getTokenBalance,\n chain: currentChain,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\nimport type { TxMonitorLike, TxStatusEntry } from \"./useTxMonitor\";\nimport { useTxMonitorProvider } from \"./useTxMonitor\";\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseTxHistoryResult {\n entries: TxStatusEntry[];\n isLoading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n summary: {\n pending: number;\n confirmed: number;\n failed: number;\n };\n}\n\n/**\n * Query transaction history.\n * address defaults to current wallet address; chainId defaults to current chain.\n */\nexport function useTxHistory(\n address?: string,\n chainId?: number,\n monitor?: TxMonitorLike,\n): UseTxHistoryResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [entries, setEntries] = useState<TxStatusEntry[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const refreshCounter = useRef(0);\n\n const refresh = useCallback(async () => {\n if (!effectiveMonitor) return;\n setIsLoading(true);\n setError(null);\n refreshCounter.current++;\n try {\n const results = await effectiveMonitor.getTxHistory(address, chainId);\n setEntries(results);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [effectiveMonitor, address, chainId]);\n\n useEffect(() => {\n refresh().catch(() => {});\n }, [refresh]);\n\n // Listen for status changes to update entries reactively\n useEffect(() => {\n if (!effectiveMonitor) return;\n\n const onStatusChange = () => {\n // Re-fetch on any status change\n refresh().catch(() => {});\n };\n effectiveMonitor.on(\"statusChange\", onStatusChange);\n\n return () => {\n effectiveMonitor.off(\"statusChange\", onStatusChange as any);\n };\n }, [effectiveMonitor, refresh]);\n\n const summary = {\n pending: entries.filter(e => e.status === \"pending\").length,\n confirmed: entries.filter(e => e.status === \"confirmed\").length,\n failed: entries.filter(e => e.status === \"failed\").length,\n };\n\n return {\n entries,\n isLoading,\n error,\n refresh,\n summary,\n };\n}\n","/**\n * useUserOpStatus\n *\n * React hook for tracking ERC-4337 UserOperation lifecycle.\n * Polls the bundler for UserOperation receipt and reports status transitions.\n *\n * @example\n * ```tsx\n * const { userOpHash, status, receipt, error } = useUserOpStatus({\n * userOpHash: \"0x...\",\n * bundlerUrl: \"https://api.pimlico.io/v2/1/rpc?apikey=...\",\n * pollInterval: 2000,\n * });\n *\n * if (status === \"confirmed\") {\n * console.log(\"UserOp included in block!\");\n * }\n * ```\n */\n\nimport {\n fetchUserOperationReceipt,\n InvalidUserOperationReceiptError,\n} from \"@naculus/connect-appkit-core\";\nimport type { Hex, UserOperationReceipt } from \"@naculus/connect-core\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type UserOpStatus =\n | \"idle\"\n | \"pending\"\n | \"confirmed\"\n | \"failed\"\n | \"not_found\";\n\nexport interface UseUserOpStatusOptions {\n /** The UserOperation hash to track */\n userOpHash?: Hex | null;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Polling interval in milliseconds (default: 2000) */\n pollInterval?: number;\n /** Maximum number of retries (default: 30) */\n maxRetries?: number;\n /** Auto-start polling when userOpHash is provided */\n autoStart?: boolean;\n}\n\nexport interface UseUserOpStatusReturn {\n /** Current status of the UserOperation */\n status: UserOpStatus;\n /** UserOperation receipt (available when confirmed or failed) */\n receipt: UserOperationReceipt | null;\n /** The userOpHash being tracked */\n userOpHash: Hex | null;\n /** Error state */\n error: Error | null;\n /** Whether polling is active */\n isPolling: boolean;\n /** Time elapsed since tracking started (ms) */\n elapsedMs: number;\n /** Number of poll attempts made */\n attempts: number;\n /** Start tracking a UserOperation */\n start: (hash: Hex) => void;\n /** Stop tracking */\n stop: () => void;\n /** Reset state */\n reset: () => void;\n}\n\nexport function useUserOpStatus(\n options?: UseUserOpStatusOptions,\n): UseUserOpStatusReturn {\n const bundlerUrl = options?.bundlerUrl;\n const pollInterval = options?.pollInterval ?? 2000;\n const maxRetries = options?.maxRetries ?? 30;\n\n const [status, setStatus] = useState<UserOpStatus>(\"idle\");\n const [receipt, setReceipt] = useState<UserOperationReceipt | null>(null);\n const [userOpHash, setUserOpHash] = useState<Hex | null>(\n options?.userOpHash ?? null,\n );\n const [error, setError] = useState<Error | null>(null);\n const [isPolling, setIsPolling] = useState(false);\n const [attempts, setAttempts] = useState(0);\n\n const startTimeRef = useRef<number>(0);\n const [elapsedMs, setElapsedMs] = useState(0);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const requestGenerationRef = useRef(0);\n const attemptsRef = useRef(0);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n // Clear all timers\n const clearTimers = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n if (pollTimerRef.current) {\n clearTimeout(pollTimerRef.current);\n pollTimerRef.current = null;\n }\n }, []);\n\n // Poll the bundler for receipt\n const poll = useCallback(\n async (hash: Hex, generation: number) => {\n if (!bundlerUrl || generation !== requestGenerationRef.current) return;\n\n const currentAttempt = attemptsRef.current + 1;\n attemptsRef.current = currentAttempt;\n setAttempts(currentAttempt);\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n const finishUnavailable = (nextError: Error): void => {\n if (generation !== requestGenerationRef.current) return;\n setStatus(\"not_found\");\n setIsPolling(false);\n clearTimers();\n setError(nextError);\n };\n\n const retryOrFinish = (nextError: Error): void => {\n if (generation !== requestGenerationRef.current) return;\n if (currentAttempt <= maxRetries) {\n pollTimerRef.current = setTimeout(\n () => void poll(hash, generation),\n pollInterval,\n );\n return;\n }\n finishUnavailable(nextError);\n };\n\n try {\n const receiptData = await fetchUserOperationReceipt(\n bundlerUrl,\n hash,\n controller.signal,\n );\n if (generation !== requestGenerationRef.current) return;\n if (receiptData) {\n setReceipt(receiptData);\n setStatus(receiptData.success ? \"confirmed\" : \"failed\");\n setIsPolling(false);\n clearTimers();\n return;\n }\n setStatus(\"pending\");\n retryOrFinish(\n new Error(\"UserOperation not included after maximum retries\"),\n );\n } catch (networkError) {\n if (\n generation !== requestGenerationRef.current ||\n controller.signal.aborted\n ) {\n return;\n }\n const nextError =\n networkError instanceof Error\n ? networkError\n : new Error(\"Unknown bundler response failure\");\n if (nextError instanceof InvalidUserOperationReceiptError) {\n finishUnavailable(nextError);\n return;\n }\n retryOrFinish(\n new Error(\n `UserOperation status unavailable after ${currentAttempt} attempt${currentAttempt === 1 ? \"\" : \"s\"}: ${nextError.message}`,\n ),\n );\n } finally {\n if (abortControllerRef.current === controller) {\n abortControllerRef.current = null;\n }\n }\n },\n [bundlerUrl, pollInterval, maxRetries, clearTimers],\n );\n\n // Start tracking\n const start = useCallback(\n (hash: Hex) => {\n requestGenerationRef.current += 1;\n const generation = requestGenerationRef.current;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n setUserOpHash(hash);\n setReceipt(null);\n setError(null);\n attemptsRef.current = 0;\n setAttempts(0);\n setElapsedMs(0);\n startTimeRef.current = Date.now();\n\n if (!bundlerUrl) {\n setStatus(\"not_found\");\n setIsPolling(false);\n setError(new Error(\"Bundler URL not configured\"));\n return;\n }\n\n setStatus(\"pending\");\n setIsPolling(true);\n\n // Start elapsed timer\n intervalRef.current = setInterval(() => {\n setElapsedMs(Date.now() - startTimeRef.current);\n }, 1000);\n\n // Start polling\n void poll(hash, generation);\n },\n [bundlerUrl, clearTimers, poll],\n );\n\n // Stop tracking\n const stop = useCallback(() => {\n requestGenerationRef.current += 1;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n setIsPolling(false);\n }, [clearTimers]);\n\n // Reset state\n const reset = useCallback(() => {\n requestGenerationRef.current += 1;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n setUserOpHash(null);\n setStatus(\"idle\");\n setReceipt(null);\n setError(null);\n setIsPolling(false);\n attemptsRef.current = 0;\n setAttempts(0);\n setElapsedMs(0);\n }, [clearTimers]);\n\n // Auto-start whenever a userOpHash is provided: at mount, or later when\n // the hash arrives after sending (the usual case). This ran only on mount,\n // so a hash passed after the first render was never tracked.\n const autoHash = options?.userOpHash ?? null;\n const autoStart = options?.autoStart !== false;\n useEffect(() => {\n if (autoHash && autoStart) start(autoHash);\n }, [autoHash, autoStart, start]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n requestGenerationRef.current += 1;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n clearTimers();\n };\n }, [clearTimers]);\n\n return {\n status,\n receipt,\n userOpHash,\n error,\n isPolling,\n elapsedMs,\n attempts,\n start,\n stop,\n reset,\n };\n}\n","/**\n * useValidateDestination — address blackhole prevention hook.\n *\n * The checks live in `@naculus/connect-appkit-core` (`validateDestination`),\n * shared with the Vue composable. This file only adds React and the\n * user-facing string for the machine-readable issue.\n *\n * Level: \"ok\" | \"warning\" | \"blocked\". \"ok\" means nothing wrong was found —\n * not that the destination is safe; see the core module for why.\n */\n\nimport {\n type AddressValidationLevel,\n validateDestination as validateDestinationCore,\n} from \"@naculus/connect-appkit-core\";\nimport { useMemo } from \"react\";\nimport { t } from \"../utils/i18n\";\n\nexport type { AddressValidationLevel };\n\nexport interface AddressValidationResult {\n isValid: boolean;\n level: AddressValidationLevel;\n warning: string | null;\n}\n\nexport function validateDestination(address: string): AddressValidationResult {\n const { isValid, level, issue } = validateDestinationCore(address);\n return { isValid, level, warning: issue ? t(`address.${issue}`) : null };\n}\n\nexport interface UseValidateDestinationOptions {\n address: string;\n}\n\nexport interface UseValidateDestinationReturn {\n validation: AddressValidationResult;\n}\n\nexport function useValidateDestination({\n address,\n}: UseValidateDestinationOptions): UseValidateDestinationReturn {\n const validation = useMemo(() => validateDestination(address), [address]);\n return { validation };\n}\n","/**\n * i18n — ponytail approach: static key-value map, no framework dependency.\n *\n * All UI strings go through here. No hardcoded text in components.\n * To add a language: copy this file and translate the values.\n */\n\nexport type Locale = \"en\" | \"zh\";\n\nconst en = {\n // Storage security\n \"storage.critical.title\": \"Insecure Storage Detected\",\n \"storage.critical.body\": \"Your browser does not support IndexedDB. Wallet data is stored in plaintext in localStorage and could be exposed to XSS attacks. We strongly recommend switching to a modern browser.\",\n \"storage.warning.title\": \"Storage Security Warning\",\n \"storage.warning.body\": \"Your browser does not support IndexedDB, but your wallet data is encrypted with AES-256-GCM. Consider switching browsers for better origin isolation.\",\n\n // Address validation\n \"address.empty\": \"Address is empty\",\n \"address.invalid_format\": \"Invalid address format (expected 0x + 40 hex chars)\",\n \"address.zero_address\": \"Address is the zero address — funds would be permanently lost\",\n \"address.burn_address\": \"Address appears to be a burn address — funds would be permanently lost\",\n\n // General wallet\n \"wallet.connect\": \"Connect Wallet\",\n \"wallet.disconnect\": \"Disconnect\",\n \"wallet.connecting\": \"Connecting...\",\n \"wallet.copy_address\": \"Copy address\",\n \"wallet.copied\": \"Copied!\",\n \"wallet.view_on_explorer\": \"View on Explorer\",\n \"wallet.retry\": \"Retry\",\n \"wallet.connection_failed\": \"Connection failed\",\n \"wallet.scan_qr\": \"Scan with your wallet app\",\n\n // Embedded wallet\n \"embedded.generate\": \"Create Wallet\",\n \"embedded.import\": \"Import Wallet\",\n \"embedded.backup_seed\": \"Back up your seed phrase\",\n \"embedded.backup_warning\": \"Anyone with your seed phrase can access your funds. Store it securely.\",\n \"embedded.backup_done\": \"I've saved my seed phrase\",\n \"embedded.wipe\": \"Remove Wallet\",\n \"embedded.wipe_confirm\": \"Are you sure? This cannot be undone.\",\n} as const;\n\nconst zh: Record<keyof typeof en, string> = {\n \"storage.critical.title\": \"偵測到不安全儲存\",\n \"storage.critical.body\": \"您的瀏覽器不支援 IndexedDB。錢包資料以明文儲存在 localStorage 中,可能暴露於 XSS 攻擊。強烈建議更換至現代瀏覽器。\",\n \"storage.warning.title\": \"儲存安全警告\",\n \"storage.warning.body\": \"您的瀏覽器不支援 IndexedDB,但錢包資料已使用 AES-256-GCM 加密。建議更換瀏覽器以獲得更好的隔離保護。\",\n\n \"address.empty\": \"地址為空\",\n \"address.invalid_format\": \"無效的地址格式(應為 0x + 40 個十六進位字元)\",\n \"address.zero_address\": \"此為零地址 — 資金將永久丟失\",\n \"address.burn_address\": \"此地址為燒毀地址 — 資金將永久丟失\",\n\n \"wallet.connect\": \"連接錢包\",\n \"wallet.disconnect\": \"斷開連線\",\n \"wallet.connecting\": \"連線中...\",\n \"wallet.copy_address\": \"複製地址\",\n \"wallet.copied\": \"已複製!\",\n \"wallet.view_on_explorer\": \"在瀏覽器查看\",\n \"wallet.retry\": \"重試\",\n \"wallet.connection_failed\": \"連線失敗\",\n \"wallet.scan_qr\": \"使用錢包 App 掃描\",\n\n \"embedded.generate\": \"建立錢包\",\n \"embedded.import\": \"匯入錢包\",\n \"embedded.backup_seed\": \"備份助記詞\",\n \"embedded.backup_warning\": \"任何人取得您的助記詞都可以存取您的資金。請安全儲存。\",\n \"embedded.backup_done\": \"我已儲存助記詞\",\n \"embedded.wipe\": \"移除錢包\",\n \"embedded.wipe_confirm\": \"確定要移除嗎?此操作無法復原。\",\n};\n\nconst locales = { en, zh } as const;\n\nlet currentLocale: Locale = \"en\";\n\nexport function setLocale(locale: Locale): void {\n currentLocale = locale;\n}\n\nexport function getLocale(): Locale {\n return currentLocale;\n}\n\nexport function t(key: keyof typeof en): string {\n return locales[currentLocale][key] ?? locales.en[key] ?? key;\n}\n","import { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport function useWallet() {\n const {\n status,\n session,\n accounts,\n chainId,\n error,\n connect,\n disconnect,\n reconnect,\n switchChain\n } = useWeb3();\n\n const isConnected = status === \"connected\";\n const isConnecting = status === \"connecting\";\n const isReconnecting = status === \"reconnecting\";\n\n const currentAccount = accounts[0] ?? null;\n const isDisconnected = status === \"disconnected\";\n\n return {\n status,\n session,\n accounts,\n chainId,\n error,\n isConnected,\n isConnecting,\n isReconnecting,\n isDisconnected,\n currentAccount,\n connect,\n disconnect,\n reconnect,\n switchChain\n };\n}","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getUserFriendlyError, isRetryableError } from \"../utils/errorMessages\";\n\nexport interface UserFriendlyError {\n title: string;\n description: string;\n code?: string;\n}\n\nexport interface UseWeb3ErrorHandlerReturn {\n /** Current error from the provider */\n error: Error | null;\n /** User-friendly representation of the current error */\n friendlyError: UserFriendlyError | null;\n /** Clear the current error */\n clearError: () => void;\n /** Check if current error is retryable */\n isRetryable: boolean;\n /** Get a user-friendly version of any error */\n formatError: (error: unknown) => UserFriendlyError;\n /** Wraps an async function with error formatting */\n wrapAsync: <T>(fn: () => Promise<T>) => () => Promise<T>;\n}\n\n/**\n * Hook that provides user-friendly error handling for web3 operations.\n *\n * Features:\n * - Maps WalletError codes to human-readable messages\n * - Provides retry detection for transient errors\n * - Wraps async operations with consistent error formatting\n * - Exposes the current error state from Web3ConnectProvider\n *\n * @example\n * ```tsx\n * const { friendlyError, clearError, isRetryable, wrapAsync } = useWeb3ErrorHandler();\n *\n * // Show error in UI\n * if (friendlyError) {\n * return <ErrorDisplay title={friendlyError.title} message={friendlyError.description} />;\n * }\n *\n * // Wrap an operation\n * const safeConnect = wrapAsync(() => connect());\n * await safeConnect();\n * ```\n */\nexport function useWeb3ErrorHandler(): UseWeb3ErrorHandlerReturn {\n const { error, clearError: providerClearError } = useWeb3();\n\n const friendlyError: UserFriendlyError | null = useMemo(\n () => (error ? getUserFriendlyError(error) : null),\n [error],\n );\n\n const isRetryable = useMemo(\n () => (error ? isRetryableError(error) : false),\n [error],\n );\n\n const clearError = useCallback(() => {\n providerClearError();\n }, [providerClearError]);\n\n const formatError = useCallback(\n (err: unknown): UserFriendlyError => getUserFriendlyError(err),\n [],\n );\n\n const wrapAsync = useCallback(\n <T>(fn: () => Promise<T>): (() => Promise<T>) => {\n return async () => {\n try {\n return await fn();\n } catch (err) {\n const friendly = getUserFriendlyError(err);\n\n // Attach to the original rather than replacing it. Building a fresh\n // Error here discarded the only technical evidence of the failure:\n // the wallet's own message, any `details`, and — the part callers\n // actually notice — the class, so `err instanceof WalletError` never\n // matched again. A convenience wrapper must not make the SDK's own\n // error type unusable.\n if (err instanceof Error) {\n const target = err as Error & {\n title?: string;\n code?: unknown;\n friendlyMessage?: string;\n };\n try {\n target.title = friendly.title;\n target.friendlyMessage = friendly.description;\n // Only fill a code in when the error has none. Overwriting a\n // wallet's own code with one this module inferred from the\n // message text would hide the real reason behind a guess.\n if (target.code === undefined && friendly.code !== undefined) {\n target.code = friendly.code;\n }\n } catch {\n // A frozen error cannot be annotated; it is still the better\n // thing to re-throw.\n }\n throw target;\n }\n\n // Not an Error, so there is nothing to preserve the identity of.\n // `cause` keeps the original value reachable.\n throw Object.assign(new Error(friendly.description, { cause: err }), {\n title: friendly.title,\n code: friendly.code,\n friendlyMessage: friendly.description,\n });\n }\n };\n },\n [],\n );\n\n return {\n error,\n friendlyError,\n clearError,\n isRetryable,\n formatError,\n wrapAsync,\n };\n}\n","/**\n * User-friendly error messages for WalletError codes and common errors.\n * Maps internal error codes to human-readable messages that can be shown in toasts/UI.\n */\n\nimport type { WalletErrorCode } from \"@naculus/connect-core\";\n\n/**\n * User-friendly title for each WalletError code.\n */\nexport const WALLET_ERROR_TITLES: Record<string, string> = {\n wallet_unavailable: \"Wallet Not Detected\",\n user_rejected: \"Connection Rejected\",\n deeplink_timeout: \"Wallet Connection Timed Out\",\n session_expired: \"Session Expired\",\n intent_expired: \"Connection Request Expired\",\n namespace_mismatch: \"Network Mismatch\",\n chain_unsupported: \"Unsupported Network\",\n method_not_allowed: \"Action Not Allowed\",\n signature_rejected: \"Signature Rejected\",\n tx_failed: \"Transaction Failed\",\n};\n\n/**\n * User-friendly description for each WalletError code.\n */\nexport const WALLET_ERROR_DESCRIPTIONS: Record<string, string> = {\n wallet_unavailable:\n \"No wallet found. Please install a compatible wallet (e.g., MetaMask, WalletConnect) and try again.\",\n user_rejected: \"The connection request was declined in your wallet. You can try again whenever you're ready.\",\n deeplink_timeout:\n \"The wallet didn't respond in time. This can happen if the wallet app isn't installed or takes too long to open.\",\n session_expired:\n \"Your wallet session has expired. Please reconnect to continue.\",\n intent_expired:\n \"The connection request expired. Please try connecting again.\",\n namespace_mismatch:\n \"This wallet doesn't support the required network. Try using a different wallet or network.\",\n chain_unsupported:\n \"This network isn't supported. Please switch to a supported network in your wallet.\",\n method_not_allowed:\n \"This action isn't supported by your current wallet or network.\",\n signature_rejected: \"The signature request was declined in your wallet.\",\n tx_failed:\n \"The transaction couldn't be completed. This could be due to insufficient funds, network congestion, or a contract error.\",\n};\n\n/**\n * Default title for unknown errors.\n */\nexport const UNKNOWN_ERROR_TITLE = \"Something went wrong\";\n\n/**\n * Default description for unknown errors.\n */\nexport const UNKNOWN_ERROR_DESCRIPTION =\n \"An unexpected error occurred. Please try again. If the problem persists, check your connection and wallet configuration.\";\n\n/**\n * Get a user-friendly error message object from any error.\n */\nexport function getUserFriendlyError(\n error: unknown\n): { title: string; description: string; code?: string } {\n if (!error) {\n return { title: UNKNOWN_ERROR_TITLE, description: UNKNOWN_ERROR_DESCRIPTION };\n }\n\n // Check for WalletError with code\n const maybeWalletError = error as { name?: string; code?: string; message?: string };\n if (maybeWalletError.name === \"WalletError\" && maybeWalletError.code) {\n const code = maybeWalletError.code;\n const title = WALLET_ERROR_TITLES[code] ?? UNKNOWN_ERROR_TITLE;\n const description =\n WALLET_ERROR_DESCRIPTIONS[code] ?? maybeWalletError.message ?? UNKNOWN_ERROR_DESCRIPTION;\n return { title, description, code };\n }\n\n // Check for standard Error\n if (error instanceof Error) {\n const message = error.message;\n // Map common error patterns\n if (/user rejected/i.test(message) || /rejected/.test(message)) {\n return {\n title: \"Request Rejected\",\n description: \"The request was declined.\",\n code: \"user_rejected\",\n };\n }\n if (/timeout/i.test(message) || /timed? ?out/i.test(message)) {\n return {\n title: \"Request Timed Out\",\n description: \"The request took too long. Please try again.\",\n code: \"deeplink_timeout\",\n };\n }\n // Specific before generic: \"insufficient funds on chain 1\" also matches\n // /chain/i, and reporting that as a network problem sends the user to\n // check their connection instead of their balance.\n if (/insufficient funds/i.test(message)) {\n return {\n title: \"Insufficient Funds\",\n description: \"You don't have enough funds to complete this transaction.\",\n code: \"tx_failed\",\n };\n }\n if (/network/i.test(message) || /chain/i.test(message)) {\n return {\n title: \"Network Error\",\n description: message,\n code: \"chain_unsupported\",\n };\n }\n\n return {\n title: UNKNOWN_ERROR_TITLE,\n description: message || UNKNOWN_ERROR_DESCRIPTION,\n };\n }\n\n // String error\n if (typeof error === \"string\") {\n return {\n title: UNKNOWN_ERROR_TITLE,\n description: error || UNKNOWN_ERROR_DESCRIPTION,\n };\n }\n\n return { title: UNKNOWN_ERROR_TITLE, description: UNKNOWN_ERROR_DESCRIPTION };\n}\n\n/**\n * Check if an error is retryable (transient).\n */\nexport function isRetryableError(error: unknown): boolean {\n // A rejected promise with no reason gives `undefined` here. Reading `.name`\n // off it threw, so the error handler crashed while handling an error and\n // buried whatever actually went wrong.\n if (error === null || typeof error !== \"object\") return false;\n const maybe = error as { name?: string; code?: string; message?: string };\n if (maybe.name !== \"WalletError\" || !maybe.code) return false;\n const retryableCodes: WalletErrorCode[] = [\n \"deeplink_timeout\",\n \"session_expired\",\n \"intent_expired\",\n \"tx_failed\",\n ];\n return retryableCodes.includes(maybe.code as WalletErrorCode);\n}\n","/**\n * useTokenList — React hook for loading token lists.\n *\n * Manages TokenListManager lifecycle and provides reactive\n * token data scoped to a specific chain.\n */\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport { TokenListManager } from \"@naculus/connect-core\";\nimport type { TokenListEntry, TokenListSource, TokenListManagerConfig } from \"@naculus/connect-core\";\nimport { eip155ChainIdToNumber } from \"@naculus/connect-appkit-core\";\n\nexport interface UseTokenListOptions {\n /** Auto-load on mount (default: true) */\n autoLoad?: boolean;\n /** Custom sources (overrides defaults) */\n sources?: TokenListSource[];\n}\n\nexport interface UseTokenListReturn {\n /** Loaded tokens for the specified chain */\n tokens: TokenListEntry[];\n /** Whether the initial load is in progress */\n isLoading: boolean;\n /** Whether tokens have been loaded at least once */\n isLoaded: boolean;\n /** Last error, if any */\n error: Error | null;\n /** Force a full refresh from all sources */\n refetch: () => Promise<void>;\n}\n\n/**\n * React hook for accessing token lists for a specific chain.\n *\n * @example\n * const { tokens, isLoading } = useTokenList(\"eip155:1\");\n * // tokens → [WETH, USDC, USDT, DAI, ...]\n */\nexport function useTokenList(\n chainId?: string,\n options?: UseTokenListOptions,\n): UseTokenListReturn {\n const managerRef = useRef<TokenListManager | null>(null);\n const [tokens, setTokens] = useState<TokenListEntry[]>([]);\n const [isLoading, setIsLoading] = useState(options?.autoLoad !== false);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Initialize manager once\n if (!managerRef.current) {\n const config: Partial<TokenListManagerConfig> = {};\n if (options?.sources) {\n config.sources = options.sources;\n }\n managerRef.current = new TokenListManager(config);\n }\n\n const load = useCallback(async () => {\n const manager = managerRef.current;\n if (!manager) return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await manager.load();\n const numericChainId = chainId ? eip155ChainIdToNumber(chainId) : undefined;\n const loaded = manager.getTokens(\n numericChainId !== undefined ? { chainId: numericChainId } : undefined,\n );\n setTokens(loaded);\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [chainId]);\n\n const refetch = useCallback(async () => {\n const manager = managerRef.current;\n if (!manager) return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await manager.refresh();\n const numericChainId = chainId ? eip155ChainIdToNumber(chainId) : undefined;\n const loaded = manager.getTokens(\n numericChainId !== undefined ? { chainId: numericChainId } : undefined,\n );\n setTokens(loaded);\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [chainId]);\n\n useEffect(() => {\n if (options?.autoLoad !== false) {\n load();\n }\n }, [load, options?.autoLoad]);\n\n return { tokens, isLoading, isLoaded, error, refetch };\n}\n\n/**\n * Parse a CAIP-2 chain ID like \"eip155:1\" into a numeric chain ID (1).\n * Returns undefined for non-numeric chains.\n */\n\n","/**\n * useTokenSearch — React hook for searching tokens.\n *\n * Debounced search over loaded token lists.\n * Returns structured results (exact + fuzzy matches).\n */\n\nimport { useState, useEffect, useRef } from \"react\";\nimport { TokenListManager } from \"@naculus/connect-core\";\nimport type { TokenSearchResult } from \"@naculus/connect-core\";\nimport { getDefaultSources } from \"./defaults\";\nimport { eip155ChainIdToNumber } from \"@naculus/connect-appkit-core\";\n\nconst DEBOUNCE_MS = 300;\n\nexport interface UseTokenSearchReturn {\n /** Structured search results */\n results: TokenSearchResult;\n /** Whether a search is currently running */\n isSearching: boolean;\n}\n\n// Shared manager instance across hooks\nlet sharedManager: TokenListManager | null = null;\n\nfunction getManager(): TokenListManager {\n if (!sharedManager) {\n sharedManager = new TokenListManager({\n sources: getDefaultSources(),\n });\n // Start loading in background\n sharedManager.load().catch(() => {});\n }\n return sharedManager;\n}\n\n/**\n * React hook for searching tokens by symbol, name, or address.\n *\n * Debounced 300ms to avoid excessive re-renders during typing.\n *\n * @example\n * const { results, isSearching } = useTokenSearch(\"USDC\");\n * // results.exact → [USDC on ETH]\n * // results.fuzzy → [USDC.e on AVAX]\n */\nexport function useTokenSearch(\n query: string,\n chainId?: string,\n): UseTokenSearchReturn {\n const [results, setResults] = useState<TokenSearchResult>({\n exact: [],\n fuzzy: [],\n hasMore: false,\n });\n const [isSearching, setIsSearching] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const trimmedQuery = query.trim();\n\n useEffect(() => {\n if (!trimmedQuery) {\n setResults({ exact: [], fuzzy: [], hasMore: false });\n setIsSearching(false);\n return;\n }\n\n // Debounce\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n setIsSearching(true);\n\n debounceRef.current = setTimeout(() => {\n const manager = getManager();\n const numericChainId = chainId ? eip155ChainIdToNumber(chainId) : undefined;\n const searchResults = manager.search(trimmedQuery, {\n chainId: numericChainId,\n limit: 20,\n });\n setResults(searchResults);\n setIsSearching(false);\n }, DEBOUNCE_MS);\n\n return () => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n };\n }, [trimmedQuery, chainId]);\n\n return { results, isSearching };\n}\n\n\n","/**\n * Default token list sources for React hooks.\n */\n\nimport type { TokenListSource } from \"@naculus/connect-core\";\nimport {\n ETHEREUM_MAINNET_TOKENS,\n POLYGON_TOKENS,\n OPTIMISM_TOKENS,\n ARBITRUM_TOKENS,\n BASE_TOKENS,\n} from \"@naculus/connect-core\";\n\n/**\n * Get default sources for useTokenList / useTokenSearch hooks.\n * Includes built-in tokens and remote source URLs.\n */\nexport function getDefaultSources(): TokenListSource[] {\n return [\n {\n name: \"built-in\",\n tokens: [\n ...ETHEREUM_MAINNET_TOKENS,\n ...POLYGON_TOKENS,\n ...OPTIMISM_TOKENS,\n ...ARBITRUM_TOKENS,\n ...BASE_TOKENS,\n ],\n enabled: true,\n },\n {\n name: \"uniswap-default\",\n url: \"https://tokens.uniswap.org\",\n enabled: true,\n refreshInterval: 24 * 60 * 60 * 1000,\n },\n ];\n}\n","/**\n * TokenSelector — chain-aware, searchable token selection component.\n *\n * Features:\n * - Loads token list for the given chain\n * - Search by symbol, name, or address\n * - Displays token logo, symbol, name, and decimals\n * - Calls onSelect when a token is chosen\n */\n\nimport React, { useCallback } from \"react\";\nimport type { TokenListEntry } from \"@naculus/connect-core\";\nimport { useTokenList } from \"./useTokenList\";\nimport { useTokenSearch } from \"./useTokenSearch\";\n\nexport interface TokenSelectorProps {\n /** Chain ID in CAIP-2 format (e.g. \"eip155:1\") */\n chainId: string;\n /** Called when a token is selected */\n onSelect: (token: TokenListEntry) => void;\n /** Called to close/dismiss the selector */\n onClose: () => void;\n /** Optional configuration */\n options?: {\n /** Show popular/recommended tokens (default: true) */\n showRecommendations?: boolean;\n /** Custom filter for tokens */\n filter?: (token: TokenListEntry) => boolean;\n };\n}\n\n/**\n * TokenSelector — a dropdown/modal component for selecting tokens.\n *\n * @example\n * <TokenSelector\n * chainId=\"eip155:1\"\n * onSelect={(token) => setSelectedToken(token)}\n * onClose={() => setOpen(false)}\n * />\n */\nexport function TokenSelector({\n chainId,\n onSelect,\n onClose,\n options,\n}: TokenSelectorProps) {\n const [searchQuery, setSearchQuery] = React.useState(\"\");\n\n const {\n tokens: allTokens,\n isLoading,\n error,\n } = useTokenList(chainId);\n\n const { results, isSearching } = useTokenSearch(\n searchQuery,\n searchQuery ? chainId : undefined,\n );\n\n const showRecommendations = options?.showRecommendations ?? true;\n\n // Display tokens: when searching, show results; otherwise show the full list\n const displayTokens = React.useMemo(() => {\n if (searchQuery.trim()) {\n const combined = [...results.exact, ...results.fuzzy].map((m) => m.token);\n return options?.filter\n ? combined.filter(options.filter)\n : combined;\n }\n\n const tokens = allTokens;\n return options?.filter\n ? tokens.filter(options.filter)\n : tokens;\n }, [searchQuery, results, allTokens, options?.filter]);\n\n // Popular tokens for recommendation section\n const popularTokens = React.useMemo(() => {\n if (!showRecommendations || searchQuery.trim()) return [];\n return allTokens.slice(0, 6); // Top 6\n }, [allTokens, showRecommendations, searchQuery]);\n\n const handleSelect = useCallback(\n (token: TokenListEntry) => {\n onSelect(token);\n onClose();\n },\n [onSelect, onClose],\n );\n\n return (\n <div\n style={{\n background: \"hsl(var(--background))\",\n borderRadius: \"12px\",\n padding: \"16px\",\n color: \"hsl(var(--foreground))\",\n minWidth: \"320px\",\n maxWidth: \"400px\",\n fontFamily: \"system-ui, sans-serif\",\n }}\n >\n {/* Header */}\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"12px\",\n }}\n >\n <h3 style={{ margin: 0, fontSize: \"16px\", fontWeight: 600 }}>\n Select Token\n </h3>\n <button type=\"button\"\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n color: \"hsl(var(--muted-foreground))\",\n cursor: \"pointer\",\n fontSize: \"18px\",\n padding: \"4px 8px\",\n }}\n >\n ✕\n </button>\n </div>\n\n {/* Search Input */}\n <input\n type=\"text\"\n placeholder=\"Search token name or paste address\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: \"1px solid #333\",\n background: \"hsl(var(--card))\",\n color: \"hsl(var(--foreground))\",\n fontSize: \"14px\",\n outline: \"none\",\n boxSizing: \"border-box\",\n marginBottom: \"12px\",\n }}\n // biome-ignore lint/a11y/noAutofocus: focus moves into the search field of the selector the user just opened\n autoFocus\n />\n\n {/* Loading / Error States */}\n {isLoading && !isSearching && (\n <div style={{ textAlign: \"center\", padding: \"20px\", color: \"hsl(var(--muted-foreground))\" }}>\n Loading tokens...\n </div>\n )}\n {error && (\n <div\n style={{\n textAlign: \"center\",\n padding: \"12px\",\n color: \"hsl(var(--destructive))\",\n fontSize: \"13px\",\n }}\n >\n Error: {error.message}\n </div>\n )}\n\n {/* Popular / Recommended Section */}\n {showRecommendations && popularTokens.length > 0 && !searchQuery.trim() && (\n <div style={{ marginBottom: \"12px\" }}>\n <div\n style={{\n fontSize: \"11px\",\n color: \"hsl(var(--muted-foreground))\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.5px\",\n marginBottom: \"8px\",\n }}\n >\n Popular\n </div>\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\" }}>\n {popularTokens.map((token) => (\n <button type=\"button\"\n key={`${token.chainId}:${token.address}`}\n onClick={() => handleSelect(token)}\n style={{\n background: \"hsl(var(--card))\",\n border: \"1px solid #333\",\n borderRadius: \"20px\",\n padding: \"6px 14px\",\n color: \"hsl(var(--foreground))\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n }}\n >\n {token.logoURI ? (\n <img\n src={token.logoURI}\n alt=\"\"\n style={{ width: \"16px\", height: \"16px\", borderRadius: \"50%\" }}\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n ) : null}\n {token.symbol}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Search Result Count */}\n {searchQuery.trim() && !isLoading && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"hsl(var(--muted-foreground))\",\n marginBottom: \"8px\",\n }}\n >\n {displayTokens.length > 0 ? (\n <>\n {results.exact.length} exact, {results.fuzzy.length} fuzzy\n {results.hasMore ? \" (more available)\" : \"\"}\n </>\n ) : (\n \"No results found\"\n )}\n </div>\n )}\n\n {/* Token List */}\n <div\n style={{\n maxHeight: \"320px\",\n overflowY: \"auto\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n }}\n >\n {displayTokens.map((token) => (\n <button type=\"button\"\n key={`${token.chainId}:${token.address}`}\n onClick={() => handleSelect(token)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n padding: \"10px 8px\",\n background: \"transparent\",\n border: \"none\",\n borderRadius: \"8px\",\n color: \"hsl(var(--foreground))\",\n cursor: \"pointer\",\n textAlign: \"left\",\n width: \"100%\",\n fontSize: \"14px\",\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.background = \"hsl(var(--card))\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.background = \"transparent\";\n }}\n >\n {/* Logo */}\n <div\n style={{\n width: \"32px\",\n height: \"32px\",\n borderRadius: \"50%\",\n background: \"hsl(var(--border))\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"12px\",\n fontWeight: 600,\n flexShrink: 0,\n overflow: \"hidden\",\n }}\n >\n {token.logoURI ? (\n <img\n src={token.logoURI}\n alt={token.symbol}\n style={{ width: \"100%\", height: \"100%\" }}\n onError={(e) => {\n const img = e.target as HTMLImageElement;\n img.style.display = \"none\";\n (img.parentElement as HTMLElement).textContent =\n token.symbol.slice(0, 2);\n }}\n />\n ) : (\n token.symbol.slice(0, 2)\n )}\n </div>\n\n {/* Token info */}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontWeight: 600,\n fontSize: \"14px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {token.symbol}\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"hsl(var(--muted-foreground))\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {token.name}\n </div>\n </div>\n\n {/* Decimals & Chain Info */}\n <div\n style={{\n fontSize: \"11px\",\n color: \"#666\",\n textAlign: \"right\",\n flexShrink: 0,\n }}\n >\n <div>{token.decimals} decimals</div>\n <div>Chain {token.chainId}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n );\n}\n","'use client';\n\n/**\n * This file was automatically generated by the Stencil React Output Target.\n * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.\n */\n\n/* eslint-disable */\n\nimport type { EventName, StencilReactComponent } from '@stencil/react-output-target/runtime';\nimport { createComponent } from '@stencil/react-output-target/runtime';\nimport React from 'react';\n\nimport { type AppkitAccordionCustomEvent, type AppkitAlertDialogCustomEvent, type AppkitCheckboxCustomEvent, type AppkitCollapsibleCustomEvent, type AppkitConnectButtonCustomEvent, type AppkitDialogCustomEvent, type AppkitDropdownMenuCustomEvent, type AppkitInputCustomEvent, type AppkitPopoverCustomEvent, type AppkitSelectCustomEvent, type AppkitSwitchCustomEvent, type AppkitTabsCustomEvent, type AppkitToggleGroupCustomEvent } from \"@naculus/connect-appkit-wc\";\nimport type { Components } from \"@naculus/connect-appkit-wc/dist/components\";\nimport { AppkitAccordion as AppkitAccordionElement, defineCustomElement as defineAppkitAccordion } from \"@naculus/connect-appkit-wc/dist/components/appkit-accordion.js\";\nimport { AppkitAccountButton as AppkitAccountButtonElement, defineCustomElement as defineAppkitAccountButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-account-button.js\";\nimport { AppkitAlertDialog as AppkitAlertDialogElement, defineCustomElement as defineAppkitAlertDialog } from \"@naculus/connect-appkit-wc/dist/components/appkit-alert-dialog.js\";\nimport { AppkitAvatar as AppkitAvatarElement, defineCustomElement as defineAppkitAvatar } from \"@naculus/connect-appkit-wc/dist/components/appkit-avatar.js\";\nimport { AppkitBadge as AppkitBadgeElement, defineCustomElement as defineAppkitBadge } from \"@naculus/connect-appkit-wc/dist/components/appkit-badge.js\";\nimport { AppkitButton as AppkitButtonElement, defineCustomElement as defineAppkitButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-button.js\";\nimport { AppkitCardContent as AppkitCardContentElement, defineCustomElement as defineAppkitCardContent } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-content.js\";\nimport { AppkitCardDescription as AppkitCardDescriptionElement, defineCustomElement as defineAppkitCardDescription } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-description.js\";\nimport { AppkitCardFooter as AppkitCardFooterElement, defineCustomElement as defineAppkitCardFooter } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-footer.js\";\nimport { AppkitCardHeader as AppkitCardHeaderElement, defineCustomElement as defineAppkitCardHeader } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-header.js\";\nimport { AppkitCardTitle as AppkitCardTitleElement, defineCustomElement as defineAppkitCardTitle } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-title.js\";\nimport { AppkitCard as AppkitCardElement, defineCustomElement as defineAppkitCard } from \"@naculus/connect-appkit-wc/dist/components/appkit-card.js\";\nimport { AppkitCheckbox as AppkitCheckboxElement, defineCustomElement as defineAppkitCheckbox } from \"@naculus/connect-appkit-wc/dist/components/appkit-checkbox.js\";\nimport { AppkitCollapsible as AppkitCollapsibleElement, defineCustomElement as defineAppkitCollapsible } from \"@naculus/connect-appkit-wc/dist/components/appkit-collapsible.js\";\nimport { AppkitConnectButton as AppkitConnectButtonElement, defineCustomElement as defineAppkitConnectButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-connect-button.js\";\nimport { AppkitDialog as AppkitDialogElement, defineCustomElement as defineAppkitDialog } from \"@naculus/connect-appkit-wc/dist/components/appkit-dialog.js\";\nimport { AppkitDropdownMenu as AppkitDropdownMenuElement, defineCustomElement as defineAppkitDropdownMenu } from \"@naculus/connect-appkit-wc/dist/components/appkit-dropdown-menu.js\";\nimport { AppkitInput as AppkitInputElement, defineCustomElement as defineAppkitInput } from \"@naculus/connect-appkit-wc/dist/components/appkit-input.js\";\nimport { AppkitPopover as AppkitPopoverElement, defineCustomElement as defineAppkitPopover } from \"@naculus/connect-appkit-wc/dist/components/appkit-popover.js\";\nimport { AppkitProgress as AppkitProgressElement, defineCustomElement as defineAppkitProgress } from \"@naculus/connect-appkit-wc/dist/components/appkit-progress.js\";\nimport { AppkitScrollArea as AppkitScrollAreaElement, defineCustomElement as defineAppkitScrollArea } from \"@naculus/connect-appkit-wc/dist/components/appkit-scroll-area.js\";\nimport { AppkitSelect as AppkitSelectElement, defineCustomElement as defineAppkitSelect } from \"@naculus/connect-appkit-wc/dist/components/appkit-select.js\";\nimport { AppkitSeparator as AppkitSeparatorElement, defineCustomElement as defineAppkitSeparator } from \"@naculus/connect-appkit-wc/dist/components/appkit-separator.js\";\nimport { AppkitSkeleton as AppkitSkeletonElement, defineCustomElement as defineAppkitSkeleton } from \"@naculus/connect-appkit-wc/dist/components/appkit-skeleton.js\";\nimport { AppkitSwitch as AppkitSwitchElement, defineCustomElement as defineAppkitSwitch } from \"@naculus/connect-appkit-wc/dist/components/appkit-switch.js\";\nimport { AppkitTabs as AppkitTabsElement, defineCustomElement as defineAppkitTabs } from \"@naculus/connect-appkit-wc/dist/components/appkit-tabs.js\";\nimport { AppkitToggleGroup as AppkitToggleGroupElement, defineCustomElement as defineAppkitToggleGroup } from \"@naculus/connect-appkit-wc/dist/components/appkit-toggle-group.js\";\nimport { AppkitTooltip as AppkitTooltipElement, defineCustomElement as defineAppkitTooltip } from \"@naculus/connect-appkit-wc/dist/components/appkit-tooltip.js\";\n\nexport type AppkitAccordionEvents = { onAppkitToggle: EventName<AppkitAccordionCustomEvent<boolean>> };\n\nexport const AppkitAccordion: StencilReactComponent<AppkitAccordionElement, AppkitAccordionEvents, Components.AppkitAccordion> = /*@__PURE__*/ createComponent<AppkitAccordionElement, AppkitAccordionEvents, Components.AppkitAccordion>({\n tagName: 'appkit-accordion',\n elementClass: AppkitAccordionElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitToggle: 'appkitToggle' } as AppkitAccordionEvents,\n defineCustomElement: defineAppkitAccordion\n});\n\nexport type AppkitAccountButtonEvents = NonNullable<unknown>;\n\nexport const AppkitAccountButton: StencilReactComponent<AppkitAccountButtonElement, AppkitAccountButtonEvents, Components.AppkitAccountButton> = /*@__PURE__*/ createComponent<AppkitAccountButtonElement, AppkitAccountButtonEvents, Components.AppkitAccountButton>({\n tagName: 'appkit-account-button',\n elementClass: AppkitAccountButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitAccountButtonEvents,\n defineCustomElement: defineAppkitAccountButton\n});\n\nexport type AppkitAlertDialogEvents = {\n onAppkitClose: EventName<AppkitAlertDialogCustomEvent<void>>,\n onAppkitOpenChange: EventName<AppkitAlertDialogCustomEvent<boolean>>\n};\n\nexport const AppkitAlertDialog: StencilReactComponent<AppkitAlertDialogElement, AppkitAlertDialogEvents, Components.AppkitAlertDialog> = /*@__PURE__*/ createComponent<AppkitAlertDialogElement, AppkitAlertDialogEvents, Components.AppkitAlertDialog>({\n tagName: 'appkit-alert-dialog',\n elementClass: AppkitAlertDialogElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitClose: 'appkitClose',\n onAppkitOpenChange: 'appkitOpenChange'\n } as AppkitAlertDialogEvents,\n defineCustomElement: defineAppkitAlertDialog\n});\n\nexport type AppkitAvatarEvents = NonNullable<unknown>;\n\nexport const AppkitAvatar: StencilReactComponent<AppkitAvatarElement, AppkitAvatarEvents, Components.AppkitAvatar> = /*@__PURE__*/ createComponent<AppkitAvatarElement, AppkitAvatarEvents, Components.AppkitAvatar>({\n tagName: 'appkit-avatar',\n elementClass: AppkitAvatarElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitAvatarEvents,\n defineCustomElement: defineAppkitAvatar\n});\n\nexport type AppkitBadgeEvents = NonNullable<unknown>;\n\nexport const AppkitBadge: StencilReactComponent<AppkitBadgeElement, AppkitBadgeEvents, Components.AppkitBadge> = /*@__PURE__*/ createComponent<AppkitBadgeElement, AppkitBadgeEvents, Components.AppkitBadge>({\n tagName: 'appkit-badge',\n elementClass: AppkitBadgeElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitBadgeEvents,\n defineCustomElement: defineAppkitBadge\n});\n\nexport type AppkitButtonEvents = NonNullable<unknown>;\n\nexport const AppkitButton: StencilReactComponent<AppkitButtonElement, AppkitButtonEvents, Components.AppkitButton> = /*@__PURE__*/ createComponent<AppkitButtonElement, AppkitButtonEvents, Components.AppkitButton>({\n tagName: 'appkit-button',\n elementClass: AppkitButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitButtonEvents,\n defineCustomElement: defineAppkitButton\n});\n\nexport type AppkitCardEvents = NonNullable<unknown>;\n\nexport const AppkitCard: StencilReactComponent<AppkitCardElement, AppkitCardEvents, Components.AppkitCard> = /*@__PURE__*/ createComponent<AppkitCardElement, AppkitCardEvents, Components.AppkitCard>({\n tagName: 'appkit-card',\n elementClass: AppkitCardElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardEvents,\n defineCustomElement: defineAppkitCard\n});\n\nexport type AppkitCardContentEvents = NonNullable<unknown>;\n\nexport const AppkitCardContent: StencilReactComponent<AppkitCardContentElement, AppkitCardContentEvents, Components.AppkitCardContent> = /*@__PURE__*/ createComponent<AppkitCardContentElement, AppkitCardContentEvents, Components.AppkitCardContent>({\n tagName: 'appkit-card-content',\n elementClass: AppkitCardContentElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardContentEvents,\n defineCustomElement: defineAppkitCardContent\n});\n\nexport type AppkitCardDescriptionEvents = NonNullable<unknown>;\n\nexport const AppkitCardDescription: StencilReactComponent<AppkitCardDescriptionElement, AppkitCardDescriptionEvents, Components.AppkitCardDescription> = /*@__PURE__*/ createComponent<AppkitCardDescriptionElement, AppkitCardDescriptionEvents, Components.AppkitCardDescription>({\n tagName: 'appkit-card-description',\n elementClass: AppkitCardDescriptionElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardDescriptionEvents,\n defineCustomElement: defineAppkitCardDescription\n});\n\nexport type AppkitCardFooterEvents = NonNullable<unknown>;\n\nexport const AppkitCardFooter: StencilReactComponent<AppkitCardFooterElement, AppkitCardFooterEvents, Components.AppkitCardFooter> = /*@__PURE__*/ createComponent<AppkitCardFooterElement, AppkitCardFooterEvents, Components.AppkitCardFooter>({\n tagName: 'appkit-card-footer',\n elementClass: AppkitCardFooterElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardFooterEvents,\n defineCustomElement: defineAppkitCardFooter\n});\n\nexport type AppkitCardHeaderEvents = NonNullable<unknown>;\n\nexport const AppkitCardHeader: StencilReactComponent<AppkitCardHeaderElement, AppkitCardHeaderEvents, Components.AppkitCardHeader> = /*@__PURE__*/ createComponent<AppkitCardHeaderElement, AppkitCardHeaderEvents, Components.AppkitCardHeader>({\n tagName: 'appkit-card-header',\n elementClass: AppkitCardHeaderElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardHeaderEvents,\n defineCustomElement: defineAppkitCardHeader\n});\n\nexport type AppkitCardTitleEvents = NonNullable<unknown>;\n\nexport const AppkitCardTitle: StencilReactComponent<AppkitCardTitleElement, AppkitCardTitleEvents, Components.AppkitCardTitle> = /*@__PURE__*/ createComponent<AppkitCardTitleElement, AppkitCardTitleEvents, Components.AppkitCardTitle>({\n tagName: 'appkit-card-title',\n elementClass: AppkitCardTitleElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardTitleEvents,\n defineCustomElement: defineAppkitCardTitle\n});\n\nexport type AppkitCheckboxEvents = { onAppkitChange: EventName<AppkitCheckboxCustomEvent<boolean>> };\n\nexport const AppkitCheckbox: StencilReactComponent<AppkitCheckboxElement, AppkitCheckboxEvents, Components.AppkitCheckbox> = /*@__PURE__*/ createComponent<AppkitCheckboxElement, AppkitCheckboxEvents, Components.AppkitCheckbox>({\n tagName: 'appkit-checkbox',\n elementClass: AppkitCheckboxElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitCheckboxEvents,\n defineCustomElement: defineAppkitCheckbox\n});\n\nexport type AppkitCollapsibleEvents = { onAppkitToggle: EventName<AppkitCollapsibleCustomEvent<boolean>> };\n\nexport const AppkitCollapsible: StencilReactComponent<AppkitCollapsibleElement, AppkitCollapsibleEvents, Components.AppkitCollapsible> = /*@__PURE__*/ createComponent<AppkitCollapsibleElement, AppkitCollapsibleEvents, Components.AppkitCollapsible>({\n tagName: 'appkit-collapsible',\n elementClass: AppkitCollapsibleElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitToggle: 'appkitToggle' } as AppkitCollapsibleEvents,\n defineCustomElement: defineAppkitCollapsible\n});\n\nexport type AppkitConnectButtonEvents = {\n onAppkitConnect: EventName<AppkitConnectButtonCustomEvent<{ kind: string; walletId?: string }>>,\n onAppkitDisconnect: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitStartPairing: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitRetry: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitCancelPairing: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitMobileDeepLink: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitCopyAddress: EventName<AppkitConnectButtonCustomEvent<string>>\n};\n\nexport const AppkitConnectButton: StencilReactComponent<AppkitConnectButtonElement, AppkitConnectButtonEvents, Components.AppkitConnectButton> = /*@__PURE__*/ createComponent<AppkitConnectButtonElement, AppkitConnectButtonEvents, Components.AppkitConnectButton>({\n tagName: 'appkit-connect-button',\n elementClass: AppkitConnectButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitConnect: 'appkitConnect',\n onAppkitDisconnect: 'appkitDisconnect',\n onAppkitStartPairing: 'appkitStartPairing',\n onAppkitRetry: 'appkitRetry',\n onAppkitCancelPairing: 'appkitCancelPairing',\n onAppkitMobileDeepLink: 'appkitMobileDeepLink',\n onAppkitCopyAddress: 'appkitCopyAddress'\n } as AppkitConnectButtonEvents,\n defineCustomElement: defineAppkitConnectButton\n});\n\nexport type AppkitDialogEvents = {\n onAppkitClose: EventName<AppkitDialogCustomEvent<void>>,\n onAppkitOpenChange: EventName<AppkitDialogCustomEvent<boolean>>\n};\n\nexport const AppkitDialog: StencilReactComponent<AppkitDialogElement, AppkitDialogEvents, Components.AppkitDialog> = /*@__PURE__*/ createComponent<AppkitDialogElement, AppkitDialogEvents, Components.AppkitDialog>({\n tagName: 'appkit-dialog',\n elementClass: AppkitDialogElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitClose: 'appkitClose',\n onAppkitOpenChange: 'appkitOpenChange'\n } as AppkitDialogEvents,\n defineCustomElement: defineAppkitDialog\n});\n\nexport type AppkitDropdownMenuEvents = { onAppkitSelect: EventName<AppkitDropdownMenuCustomEvent<string>> };\n\nexport const AppkitDropdownMenu: StencilReactComponent<AppkitDropdownMenuElement, AppkitDropdownMenuEvents, Components.AppkitDropdownMenu> = /*@__PURE__*/ createComponent<AppkitDropdownMenuElement, AppkitDropdownMenuEvents, Components.AppkitDropdownMenu>({\n tagName: 'appkit-dropdown-menu',\n elementClass: AppkitDropdownMenuElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitSelect: 'appkitSelect' } as AppkitDropdownMenuEvents,\n defineCustomElement: defineAppkitDropdownMenu\n});\n\nexport type AppkitInputEvents = { onAppkitChange: EventName<AppkitInputCustomEvent<string>> };\n\nexport const AppkitInput: StencilReactComponent<AppkitInputElement, AppkitInputEvents, Components.AppkitInput> = /*@__PURE__*/ createComponent<AppkitInputElement, AppkitInputEvents, Components.AppkitInput>({\n tagName: 'appkit-input',\n elementClass: AppkitInputElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitInputEvents,\n defineCustomElement: defineAppkitInput\n});\n\nexport type AppkitPopoverEvents = { onAppkitOpenChange: EventName<AppkitPopoverCustomEvent<boolean>> };\n\nexport const AppkitPopover: StencilReactComponent<AppkitPopoverElement, AppkitPopoverEvents, Components.AppkitPopover> = /*@__PURE__*/ createComponent<AppkitPopoverElement, AppkitPopoverEvents, Components.AppkitPopover>({\n tagName: 'appkit-popover',\n elementClass: AppkitPopoverElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitOpenChange: 'appkitOpenChange' } as AppkitPopoverEvents,\n defineCustomElement: defineAppkitPopover\n});\n\nexport type AppkitProgressEvents = NonNullable<unknown>;\n\nexport const AppkitProgress: StencilReactComponent<AppkitProgressElement, AppkitProgressEvents, Components.AppkitProgress> = /*@__PURE__*/ createComponent<AppkitProgressElement, AppkitProgressEvents, Components.AppkitProgress>({\n tagName: 'appkit-progress',\n elementClass: AppkitProgressElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitProgressEvents,\n defineCustomElement: defineAppkitProgress\n});\n\nexport type AppkitScrollAreaEvents = NonNullable<unknown>;\n\nexport const AppkitScrollArea: StencilReactComponent<AppkitScrollAreaElement, AppkitScrollAreaEvents, Components.AppkitScrollArea> = /*@__PURE__*/ createComponent<AppkitScrollAreaElement, AppkitScrollAreaEvents, Components.AppkitScrollArea>({\n tagName: 'appkit-scroll-area',\n elementClass: AppkitScrollAreaElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitScrollAreaEvents,\n defineCustomElement: defineAppkitScrollArea\n});\n\nexport type AppkitSelectEvents = { onAppkitChange: EventName<AppkitSelectCustomEvent<string>> };\n\nexport const AppkitSelect: StencilReactComponent<AppkitSelectElement, AppkitSelectEvents, Components.AppkitSelect> = /*@__PURE__*/ createComponent<AppkitSelectElement, AppkitSelectEvents, Components.AppkitSelect>({\n tagName: 'appkit-select',\n elementClass: AppkitSelectElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitSelectEvents,\n defineCustomElement: defineAppkitSelect\n});\n\nexport type AppkitSeparatorEvents = NonNullable<unknown>;\n\nexport const AppkitSeparator: StencilReactComponent<AppkitSeparatorElement, AppkitSeparatorEvents, Components.AppkitSeparator> = /*@__PURE__*/ createComponent<AppkitSeparatorElement, AppkitSeparatorEvents, Components.AppkitSeparator>({\n tagName: 'appkit-separator',\n elementClass: AppkitSeparatorElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitSeparatorEvents,\n defineCustomElement: defineAppkitSeparator\n});\n\nexport type AppkitSkeletonEvents = NonNullable<unknown>;\n\nexport const AppkitSkeleton: StencilReactComponent<AppkitSkeletonElement, AppkitSkeletonEvents, Components.AppkitSkeleton> = /*@__PURE__*/ createComponent<AppkitSkeletonElement, AppkitSkeletonEvents, Components.AppkitSkeleton>({\n tagName: 'appkit-skeleton',\n elementClass: AppkitSkeletonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitSkeletonEvents,\n defineCustomElement: defineAppkitSkeleton\n});\n\nexport type AppkitSwitchEvents = { onAppkitChange: EventName<AppkitSwitchCustomEvent<boolean>> };\n\nexport const AppkitSwitch: StencilReactComponent<AppkitSwitchElement, AppkitSwitchEvents, Components.AppkitSwitch> = /*@__PURE__*/ createComponent<AppkitSwitchElement, AppkitSwitchEvents, Components.AppkitSwitch>({\n tagName: 'appkit-switch',\n elementClass: AppkitSwitchElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitSwitchEvents,\n defineCustomElement: defineAppkitSwitch\n});\n\nexport type AppkitTabsEvents = { onAppkitTabChange: EventName<AppkitTabsCustomEvent<string>> };\n\nexport const AppkitTabs: StencilReactComponent<AppkitTabsElement, AppkitTabsEvents, Components.AppkitTabs> = /*@__PURE__*/ createComponent<AppkitTabsElement, AppkitTabsEvents, Components.AppkitTabs>({\n tagName: 'appkit-tabs',\n elementClass: AppkitTabsElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitTabChange: 'appkitTabChange' } as AppkitTabsEvents,\n defineCustomElement: defineAppkitTabs\n});\n\nexport type AppkitToggleGroupEvents = { onAppkitChange: EventName<AppkitToggleGroupCustomEvent<string[]>> };\n\nexport const AppkitToggleGroup: StencilReactComponent<AppkitToggleGroupElement, AppkitToggleGroupEvents, Components.AppkitToggleGroup> = /*@__PURE__*/ createComponent<AppkitToggleGroupElement, AppkitToggleGroupEvents, Components.AppkitToggleGroup>({\n tagName: 'appkit-toggle-group',\n elementClass: AppkitToggleGroupElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitToggleGroupEvents,\n defineCustomElement: defineAppkitToggleGroup\n});\n\nexport type AppkitTooltipEvents = NonNullable<unknown>;\n\nexport const AppkitTooltip: StencilReactComponent<AppkitTooltipElement, AppkitTooltipEvents, Components.AppkitTooltip> = /*@__PURE__*/ createComponent<AppkitTooltipElement, AppkitTooltipEvents, Components.AppkitTooltip>({\n tagName: 'appkit-tooltip',\n elementClass: AppkitTooltipElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitTooltipEvents,\n defineCustomElement: defineAppkitTooltip\n});\n"],"mappings":"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","names":["formatSol","getLatestBlockhash","getSignatureStatus","getSolanaBalance","LAMPORTS_PER_SOL","PassphraseCancelledError","PassphraseGate","parseSol","SolanaRpcError","compareCostsKey","useCallback","useEffect","useRef","useState","useCompareCosts","input","compareCostsFn","operation","chains","options","comparisons","setComparisons","loading","setLoading","error","setError","mountedRef","generationRef","inputKey","fetchComparisons","generation","result","err","refresh","toExecuteRouteError","validateRouteRecipient","useCallback","useEffect","useRef","useState","useExecuteRoute","executeRouteFn","executing","setExecuting","result","setResult","error","setError","mountedRef","inFlightRef","execute","quote","recipient","options","recipientError","execResult","err","reset","isQuotableInput","useCallback","useEffect","useRef","useState","useRouteQuote","input","getQuoteFn","fromChain","toChain","fromToken","toToken","amount","options","quotes","setQuotes","loading","setLoading","error","setError","debounceTimer","mountedRef","fetchQuotes","result","err","refresh","clear","logger","WalletError","eip6963Connector","PassphraseGate","createWalletConnectConnector","clientInstance","createClient","config","clientRef","connector","_embeddedConnector","embeddedInit","_passkeysConnector","passkeysInit","_passphraseGate","mod","embeddedConfig","salt","passkeys","err","_solanaConnector","solanaInit","conn","wallet","info","provider","client","walletId","session","input","handler","noop","calls","chainId","options","bundleHash","connectors","getClient","clearClient","isEvmAddress","parseCaip10","useMemo","createConnectorManager","createSessionManager","LocalStorageSessionStorage","logger","WalletError","eip6963Connector","createContext","useCallback","useContext","useEffect","useMemo","useReducer","useRef","logger","issueNonce","parseSiwxMessage","selectSiwxAccount","session","chainId","namespace","candidate","caip10","resolveSiwxChainId","session","runSiwxFlow","input","siwx","signMessage","chainId","account","selectSiwxAccount","address","message","parsed","parseSiwxMessage","issueNonce","signature","cause","error","logger","initialWeb3State","web3Reducer","withRetry","withTimeout","resolveChain","CHAINS","DEFAULT_RPC_URLS","eip155Reference","getRpcUrl","STATIC_TESTNETS","toWalletChain","chainId","info","caip2Id","buildDefaultChains","registryChains","chainIds","a","b","id","chain","testnet","reference","DEFAULT_EVM_CHAINS","getChainById","chains","getDefaultChains","jsx","Web3Context","createContext","Web3ConnectProvider","children","config","autoConnect","state","dispatch","useReducer","web3Reducer","initialWeb3State","chains","useMemo","getDefaultChains","connectionTimeout","maxRetries","storage","LocalStorageSessionStorage","client","createClient","sessionManagerRef","useRef","pendingExternalChainSyncRef","sessionManager","cm","createConnectorManager","connector","eip6963Connector","defaultRpcUrls","defaultCurrencies","chain","caip2Id","sm","createSessionManager","useEffect","onConnected","payload","walletSession","accounts","ns","onDisconnected","onChainChanged","onScopeChanged","onRevoked","handler","syncSessionManagerConnectors","useCallback","attachSession","session","candidate","chainId","updateStateFromSession","evmChain","solChain","xrplChain","activeClient","syncExternalChain","syncPromise","error","logger","runSiwx","outcome","runSiwxFlow","s","args","connect","withTimeout","smError","message","connectEmbedded","connectPasskeys","disconnect","connectInjected","walletId","startPairing","cancelPairing","completePairing","runSiwxOnReconnect","siwx","err","reconnect","savedSession","withRetry","switchChain","WalletError","clearError","value","useWeb3","context","useContext","useAccount","accounts","isConnected","useWeb3","accountData","useMemo","address","parsed","parseCaip10","isEvmAddress","evmAccount","a","listAuthorizations","revokeListedAuthorization","useCallback","useEffect","useRef","useState","useAuthorizations","managers","managersRef","generationRef","mountedRef","entries","setEntries","loading","setLoading","error","setError","refresh","own","next","cause","revoke","entry","result","normalized","chainNumber","resolveChain","toViemChain","useState","useEffect","useCallback","useMemo","useRef","createPublicClient","http","formatEther","getNativeTokenPriceUsd","useBalance","options","evmAccount","isConnected","useAccount","chainId","chains","useWeb3","balance","setBalance","useState","isLoading","setIsLoading","error","setError","usdPrice","setUsdPrice","refreshInterval","intervalRef","useRef","currentChain","useMemo","resolveChain","evmChainNumber","chainNumber","viemChain","toViemChain","tokenSymbol","client","setClient","useEffect","publicClient","fetchBalance","useCallback","address_","balanceResult","price","err","formatted","usdValue","numericBalance","totalUsd","atomicSupportFor","normalizeCapabilities","selectChainCapabilities","useCallback","useEffect","useRef","useState","resolveClient","client","getClient","useCapabilities","client","session","chainId","useWeb3","capabilities","setCapabilities","useState","isFetching","setIsFetching","error","setError","generationRef","useRef","refetch","useCallback","generation","activeClient","resolveClient","raw","normalizeCapabilities","err","useEffect","selectChainCapabilities","atomicSupportFor","useMemo","chainsForNamespace","describeChain","resolveChain","useChain","chainId","session","switchChain","chains","useWeb3","currentChain","useMemo","resolveChain","chainInfo","describeChain","availableChains","chainsForNamespace","useCallback","useState","WalletError","useConnect","connect","status","useWeb3","isLoading","setIsLoading","useState","error","setError","useCallback","err","errorMessage","bareEvmAddress","delegateAccount","eip155Reference","REVOKE_DELEGATE","WalletError","useCallback","useEffect","useRef","useState","chainNumber","toViemChain","useMemo","createPublicClient","http","createWalletClient","useViemClient","evmAccount","isConnected","useAccount","currentChain","chains","useChain","evmChainNumber","chainNumber","viemChain","useMemo","toViemChain","publicClient","createPublicClient","http","walletClient","address","createWalletClient","useDelegate","options","evmAccount","useAccount","session","chainId","client","useWeb3","publicClient","useViemClient","result","setResult","useState","isPending","setIsPending","error","setError","requestIdRef","useRef","inFlightRef","useEffect","run","useCallback","target","allowlist","fail","nextError","account","bareEvmAddress","WalletError","eip155Reference","connector","resolveClient","requestId","sent","delegateAccount","address","blockTag","err","delegate","revoke","REVOKE_DELEGATE","reset","applySettlementVerification","DEFAULT_VERIFY_RETRY","describePayment","useCallback","useEffect","useRef","useState","usePaymentFetch","pay","options","inFlight","setInFlight","lastPayment","setLastPayment","error","setError","generationRef","epochRef","payRef","optionsRef","verificationRef","payFetch","input","init","own","epoch","n","result","payment","verify","verification","retry","outcome","attempt","resolve","cause","current","normalized","reset","createX402WalletSigner","findX402Provider","eip6963Connector","useMemo","useX402Signer","session","accounts","chainId","client","switchChain","useWeb3","accountKey","useMemo","provider","findX402Provider","eip6963Connector","createX402WalletSigner","readCurrentMppSessionChannel","readMppRecoveryChannelId","readMppSessionReceipt","useCallback","useEffect","useMemo","useRef","useState","normalizeError","cause","useMppSession","session","inFlight","setInFlight","pending","setPending","channel","setChannel","lastReceipt","setLastReceipt","recoveryChannelId","setRecoveryChannelId","error","setError","generationRef","epochRef","mountedRef","sessionRef","run","operation","publish","clearsRecovery","own","epoch","invokedSession","count","result","currentChannel","normalized","recovery","fetch","input","init","current","receipt","close","forceClose","add","units","reset","meter","createSolanaSessionKeyFlow","useCallback","useEffect","useMemo","useRef","useState","unavailable","useSolanaSessionKey","deps","keys","setKeys","inFlight","setInFlight","error","setError","generationRef","manager","rpc","owner","flow","run","action","fallback","own","n","cause","normalized","next","refresh","create","scope","revoke","id","readDelegation","UNKNOWN_DELEGATION","useCallback","useEffect","useRef","useState","useDelegation","publicClient","useViemClient","evmAccount","useAccount","status","setStatus","useState","UNKNOWN_DELEGATION","isFetching","setIsFetching","error","setError","generationRef","useRef","address","refetch","useCallback","generation","code","readDelegation","err","useEffect","bareEvmAddress","createDelegationPolicyFlow","isVerifiablePolicy","useCallback","useEffect","useMemo","useState","recoverMessageAddress","planExecution","WalletError","useCallback","useState","errorMessage","chooseExecutionStrategy","getAccountCapabilities","WalletError","useCallback","useState","WalletError","extractTransactionHash","result","candidate","useSendCalls","session","chainId","client","useWeb3","status","setStatus","useState","error","setError","batchHash","setBatchHash","callsStatus","setCallsStatus","execution","setExecution","sendCalls","useCallback","calls","options","err","WalletError","activeClient","resolveClient","targetChain","strategy","chooseExecutionStrategy","getAccountCapabilities","result","lastHash","i","call","extractTransactionHash","errorMessage","getCallsStatus","hash","bundleHash","showCallsStatus","reset","useExecuteCalls","options","current","atomic","useCapabilities","delegated","delegate","useDelegation","sendCalls","useSendCalls","isExecuting","setIsExecuting","useState","error","setError","lastRoute","setLastRoute","defaultAtomicity","defaultSponsorship","paymasterService","userOperation","userOperationSponsored","walletPaymasterAvailable","preview","useCallback","callCount","atomicity","plan","planExecution","sponsorshipRefused","delegationNote","needsUserOperation","execute","calls","chosen","WalletError","err","e","checkSessionKeyRailGrant","getSharedSessionKeyManager","resetSharedSessionKeyManager","WalletError","useCallback","useEffect","useRef","useState","getSessionKeyManagerForHooks","config","getSharedSessionKeyManager","useSessionKeys","config","session","useWeb3","sessions","setSessions","useState","loading","setLoading","error","setError","mountedRef","useRef","clearError","useCallback","manager","getSessionKeyManagerForHooks","storageAvailable","refresh","keys","err","useEffect","activeSessions","s","checkSessionKeyRailGrant","useCreateSessionKey","lastCreated","setLastCreated","isCreating","setIsCreating","scope","signerAddress","WalletError","resolvedSigner","info","errorObj","useRevokeSession","isRevoking","setIsRevoking","sessionId","useSendWithSession","isBusy","setIsBusy","tx","resetSessionKeyManager","resetSharedSessionKeyManager","useState","useCallback","WalletError","useSignMessage","session","chainId","client","useWeb3","isLoading","setIsLoading","useState","error","setError","useCallback","message","err","WalletError","address","activeClient","resolveClient","errorMessage","buildDelegationPolicyMessage","useDelegationPolicy","options","evmAccount","useAccount","signer","bareEvmAddress","delegation","useDelegation","execution","useExecuteCalls","signMessage","useSignMessage","sessionKeys","useSessionKeys","manager","getSessionKeyManagerForHooks","isBusy","setIsBusy","useState","error","setError","verifiedPolicyIds","setVerifiedPolicyIds","isVerifying","setIsVerifying","policyOrigin","encryptionKeyConfigured","sponsorship","refresh","storageAvailable","preview","delegated","delegate","flow","useMemo","createDelegationPolicyFlow","message","signature","signerAddress","recoverMessageAddress","useEffect","cancelled","candidates","isVerifiablePolicy","policy","results","verified","policyId","cause","clearError","useCallback","track","step","fallback","next","createPolicy","scope","revokePolicy","executePolicy","tx","activePolicies","useCallback","useRef","useState","useDisconnect","disconnect","status","useWeb3","isLoading","setIsLoading","useState","error","setError","mountedRef","useRef","useCallback","err","WalletError","useCallback","useEffect","useRef","useState","toWalletView","data","activeNamespace","accounts","namespace","address","derivationPath","account","useEmbeddedWallet","providerConnectEmbedded","client","useWeb3","wallet","setWallet","useState","seedPhraseRef","useRef","storageSecurityLevelRef","restoreErroredRef","reportRef","backupPending","setBackupPending","isBusy","setIsBusy","error","setError","clearError","getSeedPhrase","useCallback","phrase","getEmbeddedConnector","activeClient","resolveClient","WalletError","getPrivateKey","getReadyEmbeddedConnector","connector","getPassphraseGate","forgetOnDecryptionFailure","err","restoreWallet","restored","useEffect","cancelled","retryTimer","handleConnectEmbedded","loaded","w","w2","handleGenerateWallet","handleImportFromMnemonic","mnemonic","handleImportFromPrivateKey","pk","handleWipe","handleSetActiveNamespace","next","handleBackfillAccounts","added","handleConfirmBackup","level","json","chainNumber","useState","useCallback","useEffect","useRef","useMemo","WalletError","useCallback","useEffect","useLayoutEffect","useMemo","useRef","tokenChainMismatch","contextKey","options","useERC20Context","token","chainId","address","key","identity","latestKey","mounted","isCurrent","assertCurrent","mismatch","ERC20_MIN_ABI","formatUnits","useERC20Allowance","options","publicClient","useViemClient","currentChain","useChain","identity","isCurrent","assertCurrent","useERC20Context","chainNumber","read","setRead","useState","allowanceRaw","isFetching","error","intervalRef","useRef","generationRef","fetchAllowance","useCallback","generation","stillCurrent","raw","err","useEffect","e","useMemo","decimals","chainNumber","createDecimalsCache","encodeErc20Approve","readDecimals","writeDecimals","ERC20_MIN_ABI","formatUnits","parseUnits","WalletError","useCallback","useRef","useState","WalletError","useCallback","useState","useSendTransaction","session","chainId","client","useWeb3","status","setStatus","useState","error","setError","sendTransaction","useCallback","transaction","err","WalletError","evmAccount","account","txWithFrom","activeClient","resolveClient","result","hash","extractTransactionHash","errorMessage","reset","toBareAddress","addr","MAX_UINT256","useERC20Approve","options","publicClient","walletClient","useViemClient","evmAccount","isConnected","useAccount","currentChain","useChain","session","client","useWeb3","sendTransaction","isSending","sendTxError","reset","useSendTransaction","localError","setLocalError","useState","identity","isCurrent","assertCurrent","useERC20Context","chainNumber","read","setRead","allowanceRaw","isFetchingAllowance","decimalsRef","useRef","createDecimalsCache","allowanceGenerationRef","error","ownerAddress","fetchAllowance","useCallback","generation","stillCurrent","raw","ERC20_MIN_ABI","err","allowance","decimals","readDecimals","formatUnits","doApprove","rawAmount","WalletError","data","encodeErc20Approve","activeClient","resolveClient","txHash","request","approveAmount","amount","writeDecimals","parseUnits","approveMaxAmount","checkAllowance","required","current","requiredRaw","chainNumber","createDecimalsCache","encodeErc20Transfer","readDecimals","writeDecimals","ERC20_MIN_ABI","parseUnits","WalletError","useCallback","useRef","useState","toBareAddress","addr","useERC20Transfer","options","publicClient","walletClient","useViemClient","evmAccount","isConnected","useAccount","currentChain","useChain","session","client","useWeb3","sendTransaction","isSending","sendTxError","reset","useSendTransaction","localError","setLocalError","useState","isCurrent","assertCurrent","useERC20Context","chainNumber","decimalsRef","useRef","createDecimalsCache","error","useCallback","to","amount","err","WalletError","address","decimals","readDecimals","ERC20_MIN_ABI","writeDecimals","rawAmount","parseUnits","data","encodeErc20Transfer","activeClient","resolveClient","request","chainNumber","encodeErc20Transfer","parseUnits","useMemo","simulateTransactionPreview","useCallback","useEffect","useRef","useState","useTransactionSimulation","tx","chainId","useWeb3","evmAccount","useAccount","currentChain","useChain","publicClient","useViemClient","result","setResult","useState","isSimulating","setIsSimulating","error","setError","debounceRef","useRef","simulate","useCallback","simResult","simulateTransactionPreview","cause","err","useEffect","reset","useERC20TransferSimulation","options","evmAccount","isConnected","useAccount","currentChain","useChain","chainId","chainNumber","tx","useMemo","decimals","rawAmount","parseUnits","data","encodeErc20Transfer","sim","useTransactionSimulation","useState","useCallback","useRef","useState","useEffect","useCallback","useRef","createContext","useContext","TxMonitorContext","useTxMonitorProvider","useTxMonitor","hash","chainId","monitor","ctxMonitor","effectiveMonitor","entry","setEntry","isLoading","setIsLoading","isWatching","setIsWatching","error","setError","prevHashRef","refresh","current","err","stopWatching","cancelled","initial","onStatusChange","updated","status","useLastTx","monitor","ctxMonitor","useTxMonitorProvider","effectiveMonitor","lastTx","setLastTx","useState","lastConfirmedTx","setLastConfirmedTx","lastFailedTx","setLastFailedTx","lastTxRef","useRef","confirmedHandlerRef","failedHandlerRef","entry","clear","useCallback","useCallback","useCallback","useEffect","useMemo","useRef","useState","getResolver","useNameLookup","input","skip","resolverConfig","scope","query","data","setData","isLoading","setIsLoading","error","setError","generationRef","mountedRef","resolver","run","trimmed","generation","result","err","useLookupAddress","address","options","query","useCallback","resolver","input","scope","useNameLookup","useState","useCallback","useMemo","useEffect","useRef","addInAppNotification","channelsUpdate","clearOneInAppNotification","createNotificationSettingsStorage","DEFAULT_NOTIFICATION_SETTINGS","loadNotificationSettings","mutedChainSettings","saveNotificationSettings","replayNotificationSettings","updateNotificationSettings","InAppChannel","useNotification","options","channelRef","channel","notifications","setNotifications","settings","setSettingsState","pendingRef","storage","settle","saved","pending","next","item","prev","unreadCount","n","clear","clearOne","id","markAsRead","markAllAsRead","addNotification","applySettings","compute","updateSettings","update","setChannels","channels","muteChain","chainId","unmuteChain","useCallback","useSyncExternalStore","NO_REQUEST","NEVER","usePassphraseGate","client","useWeb3","gate","resolveClient","request","useSyncExternalStore","submit","useCallback","passphrase","cancel","forget","reason","useCallback","useResolveName","name","options","query","useCallback","resolver","input","useNameLookup","assertHexSignature","bareEvmAddress","buildSmartAccountConfig","resolveUserOpChain","WalletError","useCallback","useEffect","useRef","useState","signHashWithSession","session","client","hash","address","chainId","activeClient","resolveClient","WalletError","params","eip6963Connector","wallet","candidate","result","assertHexSignature","embedded","useSendUserOperation","options","evmAccount","useAccount","connectedChainId","useWeb3","userOpHash","setUserOpHash","useState","receipt","setReceipt","isPending","setIsPending","isEstimating","setIsEstimating","error","setError","requestIdRef","useRef","inFlightRef","useEffect","sendUserOp","useCallback","calls","opts","fail","nextError","owner","bareEvmAddress","targetChainId","resolveUserOpChain","chainError","requestId","SmartAccountManager","signer","manager","config","buildSmartAccountConfig","response","nextReceipt","err","reset","useSyncExternalStore","useCallback","subscribeToSessionManager","sm","callback","handler","EMPTY_SESSION","snapshotCache","sameChainSessions","a","b","i","getSessionSnapshot","bundle","previous","chainSessions","next","useSession","sessionManager","web3","useWeb3","subscribe","useCallback","getSnapshot","useSyncExternalStore","defaultSiwxDomain","defaultSiwxUri","WalletError","createSiwxMessage","generateNonce","getBlockchainName","issueNonce","nowISO","useCallback","useState","DEFAULT_EXPIRY_SECONDS","useSIWxLogin","session","currentChainId","client","useWeb3","isSigningIn","setIsSigningIn","useState","error","setError","clearError","useCallback","options","WalletError","chainId","account","selectSiwxAccount","activeClient","resolveClient","address","location","domain","defaultSiwxDomain","uri","defaultSiwxUri","nonce","generateNonce","issueNonce","issuedAt","nowISO","expirySeconds","expirationTime","message","createSiwxMessage","signature","siwxResult","getBlockchainName","err","wrappedErr","siwxResultToSession","logger","checkSessionExpired","createLocalStorageSiwxSessionStorage","useCallback","useEffect","useRef","useState","useSIWxSession","options","storagePrefix","autoRestore","defaultExpirySeconds","session","setSession","useState","isRestoring","setIsRestoring","isSigningIn","setIsSigningIn","error","setError","currentChainId","useWeb3","login","useSIWxLogin","storageRef","useRef","createLocalStorageSiwxSessionStorage","clearError","useCallback","useEffect","cancelled","saved","logger","err","timeUntilExpiry","timer","prev","signIn","signOptions","effectiveOptions","result","siwxSession","siwxResultToSession","wrapped","signOut","refresh","refreshedSession","isAuthenticated","checkSessionExpired","expired","defaultSiwxDomain","defaultSiwxUri","WalletError","createSiwxMessage","generateNonce","getBlockchainName","issueNonce","nowISO","useCallback","useState","useSignInWithX","session","currentChainId","client","useWeb3","isSigningIn","setIsSigningIn","useState","result","setResult","error","setError","clearError","useCallback","options","WalletError","chainId","account","selectSiwxAccount","activeClient","resolveClient","address","location","domain","defaultSiwxDomain","uri","defaultSiwxUri","nonce","generateNonce","issueNonce","issuedAt","nowISO","message","createSiwxMessage","signature","expirationTime","siwxResult","getBlockchainName","err","wrappedErr","WalletError","useCallback","useEip155SessionGuard","session","activeChainId","useWeb3","chainId","WalletError","requestedChainId","evmNamespace","useSignInWithEthereum","guard","siwx","useSignInWithX","options","resolveSimulationEndpoint","SimulationManager","useCallback","useRef","useState","useSimulateTransfer","options","rpcUrl","chainId","managerRef","getManager","result","setResult","loading","setLoading","error","setError","simulate","tokenAddress","from","to","amount","simOptions","manager","endpoint","simResult","err","errorObj","reset","isSiwxExpired","isSiwxNotBeforeValid","LocalStorageAdapter","logger","useCallback","useEffect","useRef","useState","SIWX_AUTH_KEY","getStorage","prefix","LocalStorageAdapter","useSiwxAuthSession","options","storagePrefix","autoRestore","siwxResult","setSiwxResult","useState","isRestoring","setIsRestoring","isSigningIn","setIsSigningIn","error","setError","signInWithX","useSignInWithX","storageRef","useRef","clearError","useCallback","useEffect","cancelled","storage","saved","isSiwxExpired","isSiwxNotBeforeValid","logger","err","signIn","signOptions","result","wrapped","signOut","bareEvmAddress","buildSmartAccountConfig","resolveEvmChainId","WalletError","useCallback","useEffect","useRef","useState","accountError","message","WalletError","useSmartAccount","options","evmAccount","useAccount","session","connectedChainId","client","useWeb3","address","setAddress","useState","isDeployed","setIsDeployed","accountInfo","setAccountInfo","isLoading","setIsLoading","error","setError","managerRef","useRef","generationRef","inFlightRef","useEffect","cancelled","SmartAccountManager","chainId","resolveEvmChainId","err","getConfig","useCallback","owner","bareEvmAddress","buildSmartAccountConfig","fail","nextError","ensureOperation","finishOperation","operation","createWallet","config","info","e","deployWallet","activeClient","resolveClient","manager","before","deployTx","deployResult","after","getAddress","generation","addr","useMemo","useSolanaAccount","accounts","isConnected","useWeb3","useMemo","caip10","a","parts","address","chainId","useCallback","useEffect","useRef","useState","getSolanaBalance","useSolanaBalance","options","client","useWeb3","connectedAddress","useSolanaAccount","address","rpcUrl","resolveClient","balance","setBalance","useState","isFetching","setIsFetching","error","setError","generationRef","useRef","refetch","useCallback","generation","next","getSolanaBalance","err","useEffect","id","readSolanaRoles","useMemo","useSolanaRoles","client","session","accounts","useWeb3","useMemo","connector","resolveClient","roles","absence","readSolanaRoles","WalletError","useCallback","useState","getSignatureStatus","useSolanaTransaction","client","session","useWeb3","isSigning","setIsSigning","useState","isSending","setIsSending","error","setError","requireSession","activeClient","resolveClient","WalletError","signTransaction","useCallback","transaction","err","e","sendTransaction","getStatus","signature","rpcUrl","getSignatureStatus","useCallback","useState","toChainSwitchError","useSwitchChain","providerSwitchChain","chainId","useWeb3","isSwitching","setIsSwitching","useState","error","setError","handleSwitchChain","useCallback","targetChainId","err","walletError","toChainSwitchError","clearError","chainNumber","resolveChain","toViemChain","useState","useEffect","useCallback","useMemo","useRef","createPublicClient","http","formatUnits","erc20Abi","useTokenBalance","options","evmAccount","isConnected","useAccount","chainId","chains","useWeb3","tokenBalances","setTokenBalances","useState","isLoading","setIsLoading","error","setError","tokens","refreshInterval","intervalRef","useRef","tokensKey","useMemo","t","currentChain","resolveChain","evmChainNumber","chainNumber","viemChain","toViemChain","client","setClient","useEffect","publicClient","fetchTokenBalances","useCallback","address","balances","token","balance","r","err","getTokenBalance","tokenAddress","tb","useState","useEffect","useCallback","useRef","useTxHistory","address","chainId","monitor","ctxMonitor","useTxMonitorProvider","effectiveMonitor","entries","setEntries","useState","isLoading","setIsLoading","error","setError","refreshCounter","useRef","refresh","useCallback","results","err","useEffect","onStatusChange","summary","e","fetchUserOperationReceipt","InvalidUserOperationReceiptError","useCallback","useEffect","useRef","useState","useUserOpStatus","options","bundlerUrl","pollInterval","maxRetries","status","setStatus","receipt","setReceipt","userOpHash","setUserOpHash","error","setError","isPolling","setIsPolling","attempts","setAttempts","startTimeRef","elapsedMs","setElapsedMs","intervalRef","pollTimerRef","requestGenerationRef","attemptsRef","abortControllerRef","clearTimers","poll","hash","generation","currentAttempt","controller","finishUnavailable","nextError","retryOrFinish","receiptData","networkError","start","stop","reset","autoHash","autoStart","validateDestinationCore","useMemo","en","zh","locales","currentLocale","setLocale","locale","getLocale","t","key","validateDestination","address","isValid","level","issue","validateDestinationCore","t","useValidateDestination","useMemo","useWallet","status","session","accounts","chainId","error","connect","disconnect","reconnect","switchChain","useWeb3","isConnected","isConnecting","isReconnecting","currentAccount","useCallback","useMemo","WALLET_ERROR_TITLES","WALLET_ERROR_DESCRIPTIONS","UNKNOWN_ERROR_TITLE","UNKNOWN_ERROR_DESCRIPTION","getUserFriendlyError","error","maybeWalletError","code","title","description","message","isRetryableError","maybe","useWeb3ErrorHandler","error","providerClearError","useWeb3","friendlyError","useMemo","getUserFriendlyError","isRetryable","isRetryableError","clearError","useCallback","formatError","err","wrapAsync","fn","friendly","target","useState","useEffect","useCallback","useRef","TokenListManager","eip155ChainIdToNumber","useTokenList","chainId","options","managerRef","tokens","setTokens","isLoading","setIsLoading","isLoaded","setIsLoaded","error","setError","config","load","manager","numericChainId","loaded","err","refetch","useState","useEffect","useRef","TokenListManager","ETHEREUM_MAINNET_TOKENS","POLYGON_TOKENS","OPTIMISM_TOKENS","ARBITRUM_TOKENS","BASE_TOKENS","getDefaultSources","eip155ChainIdToNumber","DEBOUNCE_MS","sharedManager","getManager","TokenListManager","getDefaultSources","useTokenSearch","query","chainId","results","setResults","useState","isSearching","setIsSearching","debounceRef","useRef","trimmedQuery","useEffect","manager","numericChainId","searchResults","React","useCallback","Fragment","jsx","jsxs","TokenSelector","chainId","onSelect","onClose","options","searchQuery","setSearchQuery","React","allTokens","isLoading","error","useTokenList","results","isSearching","useTokenSearch","showRecommendations","displayTokens","combined","m","tokens","popularTokens","handleSelect","useCallback","token","e","img","createComponent","React","AppkitAccordionElement","defineAppkitAccordion","AppkitAccountButtonElement","defineAppkitAccountButton","AppkitAlertDialogElement","defineAppkitAlertDialog","AppkitAvatarElement","defineAppkitAvatar","AppkitBadgeElement","defineAppkitBadge","AppkitButtonElement","defineAppkitButton","AppkitCardContentElement","defineAppkitCardContent","AppkitCardDescriptionElement","defineAppkitCardDescription","AppkitCardFooterElement","defineAppkitCardFooter","AppkitCardHeaderElement","defineAppkitCardHeader","AppkitCardTitleElement","defineAppkitCardTitle","AppkitCardElement","defineAppkitCard","AppkitCheckboxElement","defineAppkitCheckbox","AppkitCollapsibleElement","defineAppkitCollapsible","AppkitConnectButtonElement","defineAppkitConnectButton","AppkitDialogElement","defineAppkitDialog","AppkitDropdownMenuElement","defineAppkitDropdownMenu","AppkitInputElement","defineAppkitInput","AppkitPopoverElement","defineAppkitPopover","AppkitProgressElement","defineAppkitProgress","AppkitScrollAreaElement","defineAppkitScrollArea","AppkitSelectElement","defineAppkitSelect","AppkitSeparatorElement","defineAppkitSeparator","AppkitSkeletonElement","defineAppkitSkeleton","AppkitSwitchElement","defineAppkitSwitch","AppkitTabsElement","defineAppkitTabs","AppkitToggleGroupElement","defineAppkitToggleGroup","AppkitTooltipElement","defineAppkitTooltip","AppkitAccordion","AppkitAccountButton","AppkitAlertDialog","AppkitAvatar","AppkitBadge","AppkitButton","AppkitCard","AppkitCardContent","AppkitCardDescription","AppkitCardFooter","AppkitCardHeader","AppkitCardTitle","AppkitCheckbox","AppkitCollapsible","AppkitConnectButton","AppkitDialog","AppkitDropdownMenu","AppkitInput","AppkitPopover","AppkitProgress","AppkitScrollArea","AppkitSelect","AppkitSeparator","AppkitSkeleton","AppkitSwitch","AppkitTabs","AppkitToggleGroup","AppkitTooltip"]}