@aurum-sdk/core 0.1.0 → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hunter Cote
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -751,12 +751,12 @@ function getEnvironment() {
751
751
  }
752
752
  function initSentry(enabled = true) {
753
753
  telemetryEnabled = enabled;
754
- if (initialized || !telemetryEnabled || true) return;
754
+ if (initialized || !telemetryEnabled || false) return;
755
755
  initialized = true;
756
756
  Sentry.init({
757
- dsn: "",
757
+ dsn: "https://0bb16fd7057ac7b45ae0ab416cdbea8b@o4505953815494656.ingest.us.sentry.io/4509747448184832",
758
758
  environment: getEnvironment(),
759
- release: `@aurum-sdk/core@${"0.1.0"}`,
759
+ release: `@aurum-sdk/core@${"0.1.1"}`,
760
760
  sendDefaultPii: false,
761
761
  enableLogs: true
762
762
  });
@@ -2429,4 +2429,4 @@ ${generateBrandCssVariables(brandConfig)}`;
2429
2429
 
2430
2430
 
2431
2431
  exports.useAurumStore = useAurumStore; exports.waitForStoreHydration = waitForStoreHydration; exports.useWidgetContext = useWidgetContext; exports.WidgetProvider = WidgetProvider; exports.DEFAULT_THEME = DEFAULT_THEME; exports.getDefaultThemeConfig = getDefaultThemeConfig; exports.POWERED_BY_SPACER_REM = POWERED_BY_SPACER_REM; exports.PageTransitionContainer = PageTransitionContainer; exports.PoweredBy = PoweredBy; exports.Modal = Modal; exports.Spacer = Spacer; exports.ThemeContainer = ThemeContainer; exports.useNavigation = useNavigation; exports.sortWallets = sortWallets; exports.initSentry = initSentry; exports.sentryLogger = sentryLogger; exports.createConfigError = createConfigError; exports.isMobile = isMobile; exports.ConnectUIProviders = ConnectUIProviders; exports.ConnectPages = ConnectPages; exports.generateCompleteStyles = generateCompleteStyles;
2432
- //# sourceMappingURL=chunk-DHEVW7CR.js.map
2432
+ //# sourceMappingURL=chunk-7TIZKMSS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/huntercote/Desktop/code/2025/station-6/monorepo/packages/core/dist/chunk-7TIZKMSS.js","../src/contexts/WidgetContext.tsx","../src/store/aurumStore.ts","../src/utils/sortWallets.ts","../src/utils/platform/isMobile.ts","../src/contexts/NavigationContext.tsx","../src/contexts/ConnectModalContext.tsx","../src/components/ConnectModal/SelectWallet.tsx","../src/ui/Badge/Badge.tsx","../src/ui/Button/Button.tsx","../src/ui/Column/Column.tsx","../src/ui/CopyButton/CopyButton.tsx","../src/ui/Divider/Divider.tsx","../src/ui/Modal/Modal.tsx","../src/hooks/useFocusTrap.ts","../src/components/PageTransitionContainer/PageTransitionContainer.tsx","../src/hooks/usePageTransition.ts","../src/constants/theme.ts","../src/constants/layout.ts","../src/components/PoweredBy/PoweredBy.tsx","../src/ui/Row/Row.tsx","../src/ui/Spacer/Spacer.tsx","../src/ui/Spinner/Spinner.tsx","../src/ui/Text/Text.tsx","../src/ui/ThemeContainer.tsx","../src/components/ModalHeader/ModalHeader.tsx","../src/components/ConnectModal/EmailAuth.tsx","../src/contexts/EmailAuthContext.tsx","../src/services/sentry.ts","../src/utils/isConfigError.ts","../src/components/WalletLogoWrapper/WalletLogoWrapper.tsx","../src/components/WalletButton/GridWalletButton.tsx","../src/components/ConnectModal/WalletListGrid.tsx","../src/components/ConnectModal/WalletListStacked.tsx","../src/components/WalletButton/WalletButton.tsx","../src/components/WalletButton/WalletButtonLabel.tsx","../src/components/ConnectModal/AdditionalWalletsIcon.tsx","../src/components/ConnectModal/ConnectionStatus/ConnectionStatusBase.tsx","../src/components/ConnectModal/ConnectionStatus/ConnectionIconsRow.tsx","../src/components/ConnectModal/BrandLogo.tsx","../src/components/ConnectModal/ConnectionStatus/StatusIcons.tsx","../src/components/ConnectModal/ConnectionStatus/Desktop.tsx","../src/components/ConnectModal/ConnectionStatus/Mobile.tsx","../src/components/ConnectModal/QRCodePage.tsx","../src/components/QRCodeDisplay/QRCodeDisplay.tsx","../src/utils/generateQrCodeWalletLogo.tsx","../src/components/QRCodeDisplay/QREye.tsx","../src/components/QRCodeDisplay/generateSkeletonDots.tsx","../src/components/QRCodeDisplay/QRCodeSkeleton.tsx","../src/components/ConnectModal/AllWallets.tsx","../src/components/ConnectModal/DownloadWalletPage.tsx","../src/components/ConnectModal/EmailVerifyOtp/EmailVerifyOtp.tsx","../src/components/ConnectModal/EmailVerifyOtp/constants.ts","../src/components/ConnectModal/EmailVerifyOtp/styles.ts","../src/components/ConnectModal/EmailVerifyOtp/useCountdown.ts","../src/components/ConnectModal/EmailVerifyOtp/useOtpInputs.ts","../src/components/ConnectModal/ConfigErrorPage.tsx","../src/components/ConnectModal/PageIds.tsx","../src/utils/walletConnectDeepLink.ts","../src/hooks/useConnectSelectedWallet.tsx","../src/components/ConnectUIProviders.tsx","../src/components/ConnectModal/ConnectPages.tsx","../src/styles/bundledStyles.ts","../src/utils/generateBrandStyles.ts"],"names":["createContext","jsx","useContext","useEffect","useLayoutEffect"],"mappings":"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","file":"/Users/huntercote/Desktop/code/2025/station-6/monorepo/packages/core/dist/chunk-7TIZKMSS.js","sourcesContent":[null,"import React, { createContext, useContext, RefObject } from 'react';\nimport { NonNullableBrandConfig } from '@aurum-sdk/types';\n\n/**\n * Rendering mode for SDK UI components.\n *\n * - `'modal'`: Rendered inside Modal overlay (has close button, can be dismissed)\n * - `'widget'`: Rendered embedded on page (no close button)\n */\nexport type WidgetMode = 'modal' | 'widget';\n\ninterface WidgetContextType {\n mode: WidgetMode;\n brandConfig: NonNullableBrandConfig;\n onDismiss: () => void;\n headerPortalRef: RefObject<HTMLDivElement | null> | null;\n}\n\nconst WidgetContext = createContext<WidgetContextType | null>(null);\n\n// All page components should use this hook\nexport const useWidgetContext = () => {\n const context = useContext(WidgetContext);\n if (!context) {\n throw new Error('useWidgetContext must be used within a WidgetProvider');\n }\n return context;\n};\n\ninterface WidgetProviderProps {\n children: React.ReactNode;\n mode: WidgetMode;\n brandConfig: NonNullableBrandConfig;\n onDismiss: () => void;\n headerPortalRef?: RefObject<HTMLDivElement | null> | null;\n}\n\n/**\n * Unified provider for both modal and widget contexts.\n *\n * ## Provider Hierarchy\n *\n * For Modals:\n * ```\n * ModalShell\n * └── Modal\n * └── WidgetProvider (mode='modal', onDismiss=closeModal)\n * └── ConnectPages\n * ```\n *\n * For Widgets:\n * ```\n * ConnectWidget\n * └── WidgetShell\n * └── WidgetProvider (mode='widget', onDismiss=noop)\n * └── ConnectPages\n * ```\n */\nexport const WidgetProvider: React.FC<WidgetProviderProps> = ({\n children,\n mode,\n brandConfig,\n onDismiss,\n headerPortalRef = null,\n}) => {\n const contextValue: WidgetContextType = {\n mode,\n brandConfig,\n onDismiss,\n headerPortalRef,\n };\n\n return <WidgetContext.Provider value={contextValue}>{children}</WidgetContext.Provider>;\n};\n","import { create, StateCreator, StoreApi, UseBoundStore } from 'zustand';\nimport { persist, createJSONStorage, StateStorage } from 'zustand/middleware';\nimport { WalletName } from '@aurum-sdk/types';\n\ninterface AurumState {\n walletId: string | null;\n address: string | null;\n walletName: WalletName | null;\n email: string | null;\n isConnected: boolean;\n lastUsedWalletId: string | null;\n\n setConnection: (walletId: string, address: string, walletName: WalletName, email?: string) => void;\n clearConnection: () => void;\n}\n\ninterface AurumStorePersist {\n persist: {\n hasHydrated: () => boolean;\n onFinishHydration: (fn: () => void) => () => void;\n };\n}\n\ntype AurumStoreType = UseBoundStore<StoreApi<AurumState>> & AurumStorePersist;\n\n// SSR-safe storage that checks for localStorage availability\nconst getStorage = (): StateStorage => ({\n getItem: (name: string) => {\n if (typeof window === 'undefined') return null;\n return localStorage.getItem(name);\n },\n setItem: (name: string, value: string) => {\n if (typeof window === 'undefined') return;\n localStorage.setItem(name, value);\n },\n removeItem: (name: string) => {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(name);\n },\n});\n\nconst storeCreator = persist<AurumState>(\n (set) => ({\n walletId: null,\n address: null,\n walletName: null,\n email: null,\n isConnected: false,\n lastUsedWalletId: null,\n\n setConnection: (walletId, address, walletName, email) =>\n set({\n walletId,\n address,\n walletName,\n email: email ?? null,\n isConnected: true,\n lastUsedWalletId: walletId,\n }),\n\n clearConnection: () =>\n set({\n walletId: null,\n address: null,\n walletName: null,\n email: null,\n isConnected: false,\n }),\n }),\n {\n name: '@aurum-sdk/core-store',\n storage: createJSONStorage(getStorage),\n skipHydration: typeof window === 'undefined',\n },\n);\n\nexport const useAurumStore = create(storeCreator as unknown as StateCreator<AurumState>) as AurumStoreType;\n\nexport const waitForStoreHydration = (): Promise<void> => {\n return new Promise((resolve) => {\n if (useAurumStore.persist.hasHydrated()) {\n resolve();\n return;\n }\n useAurumStore.persist.onFinishHydration(() => resolve());\n });\n};\n","import { WalletAdapter } from '@src/types/internal';\nimport { useAurumStore } from '@src/store';\nimport { WalletId } from '@aurum-sdk/types';\n\n// Wallet display priority order\nconst WALLET_PRIORITY = [\n WalletId.MetaMask,\n WalletId.Phantom,\n WalletId.WalletConnect,\n WalletId.Brave,\n WalletId.Rabby,\n WalletId.CoinbaseWallet,\n WalletId.Ledger,\n];\n\nexport interface SortWalletsOptions {\n filterHidden?: boolean;\n}\n\n/**\n * Sorting priority:\n * 1. Last used wallet first (if exists)\n * 2. Installed wallets before uninstalled\n * 3. WALLET_PRIORITY order\n */\nexport function sortWallets(wallets: WalletAdapter[], options: SortWalletsOptions = {}): WalletAdapter[] {\n const { filterHidden = true } = options;\n const lastUsedWalletId = useAurumStore.getState().lastUsedWalletId;\n\n let result = [...wallets];\n\n if (filterHidden) {\n result = result.filter((wallet) => !wallet.hide);\n }\n\n result.sort((a, b) => {\n // 1. Last used wallet first\n if (a.id === lastUsedWalletId) return -1;\n if (b.id === lastUsedWalletId) return 1;\n\n // 2. Installed wallets first\n const aInstalled = a.isInstalled();\n const bInstalled = b.isInstalled();\n if (aInstalled !== bInstalled) {\n return aInstalled ? -1 : 1;\n }\n\n // 3. Priority order\n const aIndex = WALLET_PRIORITY.indexOf(a.id);\n const bIndex = WALLET_PRIORITY.indexOf(b.id);\n\n if (aIndex === -1 && bIndex === -1) return 0;\n if (aIndex === -1) return 1;\n if (bIndex === -1) return -1;\n\n return aIndex - bIndex;\n });\n\n return result;\n}\n","import MobileDetect from 'mobile-detect';\n\n// Returns true if mobile phone or tablet\nexport function isMobile(): boolean {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') {\n return false;\n }\n\n const md = new MobileDetect(window.navigator.userAgent);\n\n return md.mobile() !== null || md.tablet() !== null;\n}\n","import React, { createContext, useContext, useState, ReactNode } from 'react';\nimport { PageIdType } from '@src/components/ConnectModal/PageIds';\n\ninterface NavigationContextType {\n currentPage: PageIdType;\n navigateTo: (pageId: PageIdType) => void;\n navigateBack: () => void;\n canNavigateBack: boolean;\n}\n\nconst NavigationContext = createContext<NavigationContextType | undefined>(undefined);\n\ninterface NavigationProviderProps {\n children: ReactNode;\n initialPage: PageIdType;\n}\n\nexport const NavigationProvider: React.FC<NavigationProviderProps> = ({ children, initialPage }) => {\n const [currentPage, setCurrentPage] = useState<PageIdType>(initialPage);\n const [pageHistory, setPageHistory] = useState<PageIdType[]>([initialPage]);\n\n const navigateTo = (pageId: PageIdType) => {\n setCurrentPage(pageId);\n setPageHistory((prev) => [...prev, pageId]);\n };\n\n const navigateBack = () => {\n if (pageHistory.length > 1) {\n const newHistory = pageHistory.slice(0, -1);\n const previousPage = newHistory[newHistory.length - 1];\n setPageHistory(newHistory);\n setCurrentPage(previousPage);\n }\n };\n\n const canNavigateBack = pageHistory.length > 1;\n\n const value: NavigationContextType = {\n currentPage,\n navigateTo,\n navigateBack,\n canNavigateBack,\n };\n\n return <NavigationContext.Provider value={value}>{children}</NavigationContext.Provider>;\n};\n\nexport const useNavigation = (): NavigationContextType => {\n const context = useContext(NavigationContext);\n if (context === undefined) {\n throw new Error('useNavigation must be used within a NavigationProvider');\n }\n return context;\n};\n","import React, { createContext, useContext, useState } from 'react';\n\nimport { WalletAdapter, WalletConnectionResult } from '@src/types/internal';\nimport { PAGE_IDS } from '@src/components/ConnectModal/PageIds';\nimport { isMobile } from '@src/utils/platform/isMobile';\nimport { useConnectSelectedWallet } from '@src/hooks/useConnectSelectedWallet';\nimport { useNavigation } from '@src/contexts/NavigationContext';\nimport { EmailAuthProvider } from '@src/contexts/EmailAuthContext';\nimport { WalletId } from '@aurum-sdk/types';\nimport { isConfigError } from '@src/utils/isConfigError';\nimport { sentryLogger } from '@src/services/sentry';\n\ninterface ConnectModalProviderProps {\n children: React.ReactNode;\n displayedWallets: WalletAdapter[];\n onConnect: (result: WalletConnectionResult) => void;\n}\n\ninterface ConnectModalContextValue {\n error: boolean;\n configError: boolean;\n success: boolean;\n qrSuccess: boolean;\n selectedWallet: WalletAdapter | null;\n displayedWallets: WalletAdapter[];\n goBackToHome: () => void;\n connectWallet: (wallet: WalletAdapter) => void;\n retryConnection: () => void;\n setSelectedWallet: (wallet: WalletAdapter | null) => void;\n setSuccess: (success: boolean) => void;\n setQrSuccess: (success: boolean) => void;\n}\n\nconst ConnectModalContext = createContext<ConnectModalContextValue | null>(null);\n\nexport const useConnectModal = () => {\n const context = useContext(ConnectModalContext);\n if (!context) {\n throw new Error('useConnectModal must be used within a ConnectModalProvider');\n }\n return context;\n};\n\nexport const ConnectModalProvider = ({ children, displayedWallets, onConnect }: ConnectModalProviderProps) => {\n const { navigateTo } = useNavigation();\n const {\n redirectToDownloadPage,\n connectInstalledWallet,\n connectWithMobileDeepLink,\n connectUninstalledWalletQRCode,\n connectAppKit,\n } = useConnectSelectedWallet();\n\n const [error, setError] = useState<boolean>(false);\n const [configError, setConfigError] = useState<boolean>(false);\n const [success, setSuccess] = useState<boolean>(false);\n const [qrSuccess, setQrSuccess] = useState<boolean>(false);\n const [selectedWallet, setSelectedWallet] = useState<WalletAdapter | null>(null);\n\n const connectWallet = async (wallet: WalletAdapter) => {\n try {\n setError(false);\n setConfigError(false);\n setSuccess(false);\n setQrSuccess(false);\n setSelectedWallet(wallet);\n\n const isOnMobile = isMobile();\n const isDesktop = !isOnMobile;\n const hasDeepLink = Boolean(wallet.wcDeepLinkUrl);\n\n if (isDesktop) {\n // User clicks `Open AppKit` button\n if (wallet.id === WalletId.AppKit)\n return await connectAppKit({ adapter: wallet, onConnect, setSuccess: setQrSuccess });\n\n if (!wallet.isInstalled() && !hasDeepLink) {\n return await redirectToDownloadPage();\n }\n\n // User clicks `WalletConnect` wallet button (or clicks wallet button for uninstalled wallet)\n if (wallet.id === WalletId.WalletConnect || !wallet.isInstalled())\n return await connectUninstalledWalletQRCode({\n adapter: wallet,\n displayedWallets,\n onConnect,\n setSuccess: setQrSuccess,\n });\n\n // User clicks wallet button that is installed\n return await connectInstalledWallet({ adapter: wallet, onConnect, setSuccess });\n }\n\n if (isOnMobile) {\n if (wallet.id === WalletId.WalletConnect || wallet.id === WalletId.AppKit) {\n const appkitAdapter = displayedWallets?.find(({ id }) => id === WalletId.AppKit);\n if (!appkitAdapter) {\n sentryLogger.error('AppKit adapter not found');\n throw new Error('AppKit adapter not found');\n }\n return await connectAppKit({ adapter: appkitAdapter, onConnect, setSuccess: setQrSuccess });\n }\n if (wallet.isInstalled()) return await connectInstalledWallet({ adapter: wallet, onConnect, setSuccess });\n if (hasDeepLink) {\n return await connectWithMobileDeepLink({ adapter: wallet, displayedWallets, onConnect, setSuccess });\n }\n return await redirectToDownloadPage();\n }\n } catch (err) {\n setError(true);\n if (isConfigError(err)) {\n setConfigError(true);\n }\n }\n };\n\n const retryConnection = () => {\n if (selectedWallet) connectWallet(selectedWallet);\n };\n\n const goBackToHome = () => {\n navigateTo(PAGE_IDS.SELECT_WALLET);\n setSelectedWallet(null);\n setError(false);\n setConfigError(false);\n setSuccess(false);\n setQrSuccess(false);\n };\n\n const contextValue: ConnectModalContextValue = {\n error,\n configError,\n success,\n qrSuccess,\n selectedWallet,\n displayedWallets,\n goBackToHome,\n connectWallet,\n retryConnection,\n setSelectedWallet,\n setSuccess,\n setQrSuccess,\n };\n\n return (\n <ConnectModalContext.Provider value={contextValue}>\n <EmailAuthProvider\n onConnect={onConnect}\n navigateTo={navigateTo}\n displayedWallets={displayedWallets}\n setSelectedWallet={setSelectedWallet}\n >\n {children}\n </EmailAuthProvider>\n </ConnectModalContext.Provider>\n );\n};\n","import React, { useMemo } from 'react';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { Spacer, Column, Button } from '@src/ui';\nimport { X } from 'lucide-react';\nimport { Divider } from '@src/ui';\nimport { ModalHeader } from '@src/components/ModalHeader/ModalHeader';\nimport { sortWallets } from '@src/utils/sortWallets';\nimport { EmailAuth } from '@src/components/ConnectModal/EmailAuth';\nimport { WalletListGrid } from '@src/components/ConnectModal/WalletListGrid';\nimport { WalletListStacked } from '@src/components/ConnectModal/WalletListStacked';\nimport { WalletId } from '@aurum-sdk/types';\n\nexport const SelectWalletPage: React.FC = () => {\n const { displayedWallets } = useConnectModal();\n const { onDismiss, brandConfig } = useWidgetContext();\n\n const hasEmailAuth = displayedWallets.some((wallet) => wallet.id === WalletId.Email);\n const sortedWallets = useMemo(() => sortWallets(displayedWallets), [displayedWallets]);\n const isGridLayout = brandConfig.walletLayout === 'grid';\n\n return (\n <>\n <ModalHeader\n title=\"Log in or sign up\"\n rightAction={\n <Button size=\"sm\" variant=\"close\" onClick={onDismiss} aria-label=\"Close\">\n <X size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n }\n />\n {hasEmailAuth && (\n <>\n <Column align=\"center\" gap={0}>\n <EmailAuth />\n </Column>\n {sortedWallets.length > 0 && (\n <>\n <Spacer size={20} />\n <Divider>or continue with</Divider>\n <Spacer size={20} />\n </>\n )}\n </>\n )}\n\n {isGridLayout ? (\n <WalletListGrid wallets={sortedWallets} />\n ) : (\n <WalletListStacked wallets={sortedWallets} hasEmailAuth={hasEmailAuth} />\n )}\n </>\n );\n};\n","import './Badge.css';\n\nexport const RecentBadge = () => {\n return <span className=\"aurum-badge-recent\">Recent</span>;\n};\n","import React from 'react';\n\nimport { Spinner } from '@src/ui';\nimport './Button.css';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'primary' | 'secondary' | 'tertiary' | 'text' | 'close';\n size?: 'xs' | 'sm' | 'md' | 'lg';\n expand?: boolean;\n loading?: boolean;\n children?: React.ReactNode;\n}\n\nexport const Button: React.FC<ButtonProps> = ({\n variant = 'primary',\n size = 'md',\n loading = false,\n expand = false,\n disabled = false,\n className,\n children,\n ...props\n}) => {\n const baseClassName = 'aurum-button';\n const classes = [\n baseClassName,\n `${baseClassName}--${variant}`,\n `${baseClassName}--${size}`,\n expand && `${baseClassName}--full-width`,\n loading && `${baseClassName}--loading`,\n disabled && `${baseClassName}--disabled`,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button className={classes} disabled={disabled || loading} {...props}>\n {loading && <Spinner color=\"currentColor\" />}\n {children}\n </button>\n );\n};\n","export const Column = ({\n align = 'center',\n gap = 8,\n justify = 'center',\n style,\n children,\n}: {\n align?: 'center' | 'start' | 'end';\n gap?: number;\n justify?: 'center' | 'start' | 'end';\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: align,\n gap: `${gap}px`,\n justifyContent: justify,\n ...style,\n }}\n >\n {children}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { Button, Text } from '@src/ui';\nimport { Copy, CopyCheck } from 'lucide-react';\n\nexport interface CopyButtonProps {\n text: string;\n /** Label to show next to icon. Pass empty string or undefined for icon-only mode. */\n label?: string;\n /** Label to show after copying. Pass empty string or undefined for icon-only mode. */\n copiedLabel?: string;\n variant?: 'primary' | 'secondary' | 'tertiary' | 'success' | 'error' | 'brand';\n size?: 'xs' | 'sm' | 'md' | 'lg';\n iconSize?: number;\n disabled?: boolean;\n}\n\n// Map text variants to new semantic color tokens\nconst variantColorMap: Record<string, string> = {\n primary: 'var(--color-foreground)',\n secondary: 'var(--color-foreground-muted)',\n tertiary: 'var(--color-foreground-subtle)',\n success: 'var(--color-success)',\n error: 'var(--color-error)',\n brand: 'var(--color-primary)',\n};\n\nexport const CopyButton: React.FC<CopyButtonProps> = ({\n text,\n label,\n copiedLabel,\n variant = 'brand',\n size = 'sm',\n iconSize = 16,\n disabled = false,\n}) => {\n const [isCopied, setIsCopied] = useState(false);\n\n const handleCopy = async () => {\n if (!text || disabled || isCopied) return;\n\n try {\n await navigator.clipboard.writeText(text);\n setIsCopied(true);\n setTimeout(() => {\n setIsCopied(false);\n }, 1500);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Failed to copy text', error);\n }\n };\n\n // Icon-only mode\n if (!label && !copiedLabel) {\n return (\n <Button\n variant=\"text\"\n size={size}\n onClick={handleCopy}\n disabled={disabled}\n style={{ cursor: disabled ? 'not-allowed' : 'pointer', padding: '0.25rem' }}\n >\n {isCopied ? (\n <CopyCheck size={iconSize} color=\"var(--color-success)\" />\n ) : (\n <Copy size={iconSize} color={variantColorMap[variant]} />\n )}\n </Button>\n );\n }\n\n return (\n <Button\n variant=\"text\"\n size={size}\n onClick={handleCopy}\n disabled={disabled}\n style={{ cursor: disabled ? 'not-allowed' : 'pointer' }}\n >\n {isCopied ? (\n <Text\n variant=\"success\"\n size=\"sm\"\n align=\"center\"\n weight=\"semibold\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <CopyCheck size={iconSize} color=\"var(--color-success)\" />\n {copiedLabel || 'Copied'}\n </Text>\n ) : (\n <Text\n variant={variant}\n size=\"sm\"\n align=\"center\"\n weight=\"semibold\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <Copy size={iconSize} color={variantColorMap[variant]} />\n {label || 'Copy'}\n </Text>\n )}\n </Button>\n );\n};\n","import React from 'react';\nimport './Divider.css';\n\ninterface DividerProps {\n children?: React.ReactNode;\n}\n\nexport const Divider: React.FC<DividerProps> = ({ children }) => {\n return (\n <div className=\"divider\">\n <div className=\"divider-line\" />\n {children && <div className=\"divider-text\">{children}</div>}\n <div className=\"divider-line\" />\n </div>\n );\n};\n","import React, { ReactNode, useRef, useEffect, useState, useCallback, useMemo } from 'react';\n\nimport { WidgetProvider } from '@src/contexts/WidgetContext';\nimport { useFocusTrap } from '@src/hooks/useFocusTrap';\nimport { PageTransitionContainer } from '@src/components/PageTransitionContainer';\nimport { PoweredBy } from '@src/components/PoweredBy/PoweredBy';\nimport { Spacer } from '@src/ui';\nimport { POWERED_BY_SPACER_REM } from '@src/constants/layout';\nimport { NonNullableBrandConfig } from '@aurum-sdk/types';\nimport './Modal.css';\n\ntype ModalAnimationState = 'closed' | 'entering' | 'open' | 'exiting';\n\nexport interface BaseModalProps {\n isOpen: boolean;\n onCloseComplete: () => void;\n children: ReactNode;\n closeOnOverlayClick?: boolean;\n transitionKey?: string | number;\n brandConfig: NonNullableBrandConfig;\n}\n\nexport const Modal: React.FC<BaseModalProps> = ({\n isOpen,\n onCloseComplete,\n children,\n closeOnOverlayClick = true,\n transitionKey = 'default',\n brandConfig,\n}) => {\n const overlayRef = useRef<HTMLDivElement>(null);\n const dialogRef = useRef<HTMLDivElement>(null);\n const headerPortalRef = useRef<HTMLDivElement>(null);\n\n const [animState, setAnimState] = useState<ModalAnimationState>('closed');\n\n useEffect(() => {\n if (isOpen && animState === 'closed') {\n setAnimState('entering');\n }\n }, [isOpen, animState]);\n\n // RAF ensures browser paints the off-screen state before transition starts\n useEffect(() => {\n if (animState !== 'entering') return;\n\n const rafId = requestAnimationFrame(() => {\n setAnimState('open');\n dialogRef.current?.focus();\n });\n\n return () => cancelAnimationFrame(rafId);\n }, [animState]);\n\n // Listen for transition end to complete exit animation\n useEffect(() => {\n if (animState !== 'exiting') return;\n\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n const handleTransitionEnd = (e: TransitionEvent) => {\n // Only react to transitions on the dialog itself, not children\n if (e.target === dialog) {\n setAnimState('closed');\n onCloseComplete();\n }\n };\n\n dialog.addEventListener('transitionend', handleTransitionEnd);\n return () => dialog.removeEventListener('transitionend', handleTransitionEnd);\n }, [animState, onCloseComplete]);\n\n useEffect(() => {\n if (animState === 'closed') return;\n\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = 'unset';\n };\n }, [animState]);\n\n const handleClose = useCallback(() => {\n if (animState === 'open' || animState === 'entering') {\n setAnimState('exiting');\n }\n }, [animState]);\n\n const handleOverlayClick = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (closeOnOverlayClick && e.target === overlayRef.current) {\n handleClose();\n }\n },\n [closeOnOverlayClick, handleClose],\n );\n\n const focusTrapOptions = useMemo(\n () => ({\n isActive: animState !== 'closed',\n onEscape: handleClose,\n refocusKey: transitionKey,\n }),\n [animState, handleClose, transitionKey],\n );\n\n useFocusTrap(dialogRef, focusTrapOptions);\n\n const overlayClassName = useMemo(() => {\n const classes = ['modal-overlay'];\n if (animState === 'open') classes.push('modal-open');\n if (animState === 'exiting') classes.push('modal-exiting');\n return classes.join(' ');\n }, [animState]);\n\n if (animState === 'closed') return null;\n\n return (\n <WidgetProvider mode=\"modal\" brandConfig={brandConfig} onDismiss={handleClose} headerPortalRef={headerPortalRef}>\n <div ref={overlayRef} className={overlayClassName} onClick={handleOverlayClick}>\n <div ref={dialogRef} className=\"modal-content\" role=\"dialog\" aria-modal=\"true\" tabIndex={-1}>\n <div ref={headerPortalRef} />\n <PageTransitionContainer transitionKey={transitionKey}>{children}</PageTransitionContainer>\n {brandConfig.hideFooter ? (\n <Spacer size=\"0.3125rem\" />\n ) : (\n <>\n <Spacer size={`${POWERED_BY_SPACER_REM}rem`} />\n <PoweredBy />\n </>\n )}\n </div>\n </div>\n </WidgetProvider>\n );\n};\n","import { useEffect, RefObject } from 'react';\n\nconst FOCUSABLE_SELECTOR =\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\ninterface UseFocusTrapOptions {\n isActive: boolean;\n onEscape?: () => void;\n /** Re-focus container when this key changes (e.g., page transitions) */\n refocusKey?: string | number;\n}\n\n/**\n * Gets the actual focused element, traversing into Shadow DOM if needed.\n * document.activeElement only returns the shadow host, not the element inside.\n */\nfunction getDeepActiveElement(): Element | null {\n let active = document.activeElement;\n while (active?.shadowRoot?.activeElement) {\n active = active.shadowRoot.activeElement;\n }\n return active;\n}\n\n/**\n * Traps focus within a container element.\n * - Tab/Shift+Tab cycles within the container\n * - Escape triggers onEscape callback\n * - Refocuses container when refocusKey changes\n */\nexport function useFocusTrap(\n containerRef: RefObject<HTMLElement>,\n { isActive, onEscape, refocusKey }: UseFocusTrapOptions,\n) {\n // Refocus container when page changes\n useEffect(() => {\n if (isActive && containerRef.current) {\n const timer = setTimeout(() => {\n containerRef.current?.focus();\n }, 50);\n return () => clearTimeout(timer);\n }\n }, [refocusKey, isActive]);\n\n // Focus trap and escape handler\n useEffect(() => {\n if (!isActive) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onEscape?.();\n return;\n }\n\n if (e.key !== 'Tab' || !containerRef.current) return;\n\n const focusableElements = containerRef.current.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR);\n\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n const activeElement = getDeepActiveElement();\n\n // Shift+Tab on first element -> go to last\n if (e.shiftKey && activeElement === firstElement) {\n e.preventDefault();\n lastElement.focus();\n }\n // Tab on last element -> go to first\n else if (!e.shiftKey && activeElement === lastElement) {\n e.preventDefault();\n firstElement.focus();\n }\n // If focus is outside focusable elements (e.g., on container), go to first/last\n else if (!Array.from(focusableElements).includes(activeElement as HTMLElement)) {\n e.preventDefault();\n if (e.shiftKey) {\n lastElement.focus();\n } else {\n firstElement.focus();\n }\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isActive, onEscape]);\n}\n","import React, { useRef } from 'react';\nimport { useContentHeight, usePageActiveState, usePageContainerStyle } from '@src/hooks/usePageTransition';\nimport { contentWrapperStyle } from '@src/constants/layout';\n\ninterface PageTransitionContainerProps {\n /** Key that triggers page transition animation when changed */\n transitionKey: string | number;\n /** Page content to render */\n children: React.ReactNode;\n}\n\n/**\n * Shared page transition container used by both Modal and Widget.\n *\n * Provides:\n * - Smooth height animations when content changes\n * - Fade in/out transitions when transitionKey changes\n * - Consistent padding/spacing for header overlay\n *\n * ## Structure\n * ```\n * .modal-page-container (height animation, overflow handling)\n * └── .modal-page (opacity transition)\n * └── content wrapper (paddingTop for header space)\n * └── {children}\n * ```\n *\n * @see Modal - Uses this with transitionKey from navigation\n * @see ConnectWidget - Uses this with currentPage from NavigationContext\n */\nexport const PageTransitionContainer: React.FC<PageTransitionContainerProps> = ({ transitionKey, children }) => {\n const pageRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n\n const contentHeight = useContentHeight(contentRef, transitionKey);\n const isPageActive = usePageActiveState(transitionKey);\n const containerStyle = usePageContainerStyle(contentHeight);\n\n return (\n <div className=\"modal-page-container\" style={containerStyle}>\n <div key={transitionKey} ref={pageRef} className={`modal-page ${isPageActive ? 'active' : ''}`}>\n <div ref={contentRef} style={contentWrapperStyle}>\n {children}\n </div>\n </div>\n </div>\n );\n};\n","import { useEffect, useRef, useState, useLayoutEffect, useMemo, RefObject } from 'react';\nimport { ANIMATION_DURATION } from '@src/constants/theme';\nimport { PAGE_CONTENT_PADDING, PAGE_MIN_HEIGHT, PAGE_MAX_HEIGHT } from '@src/constants/layout';\n\n// Hook to measure and track content height for smooth animations.\nexport function useContentHeight(\n contentRef: RefObject<HTMLDivElement | null>,\n transitionKey: string | number,\n): number | null {\n const [contentHeight, setContentHeight] = useState<number | null>(null);\n\n // Measure content height before paint\n useLayoutEffect(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight);\n }\n }, [transitionKey]);\n\n // Watch for dynamic content changes\n useEffect(() => {\n if (!contentRef.current) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n setContentHeight(entry.target.scrollHeight);\n }\n });\n\n resizeObserver.observe(contentRef.current);\n return () => resizeObserver.disconnect();\n }, [transitionKey]);\n\n return contentHeight;\n}\n\n// Hook for page transition animation (fade in/out on page change).\nexport function usePageActiveState(transitionKey: string | number): boolean {\n const prevKeyRef = useRef(transitionKey);\n const [isPageActive, setIsPageActive] = useState(true);\n\n useEffect(() => {\n if (prevKeyRef.current === transitionKey) return;\n prevKeyRef.current = transitionKey;\n\n setIsPageActive(false);\n // Double rAF ensures DOM updates before triggering fade-in\n requestAnimationFrame(() => {\n requestAnimationFrame(() => setIsPageActive(true));\n });\n }, [transitionKey]);\n\n return isPageActive;\n}\n\n// Handles smooth height animations when content changes.\nexport function usePageContainerStyle(contentHeight: number | null): React.CSSProperties {\n return useMemo<React.CSSProperties>(\n () => ({\n height: contentHeight ? `${contentHeight / 16 + PAGE_CONTENT_PADDING * 2}rem` : 'auto',\n minHeight: PAGE_MIN_HEIGHT,\n maxHeight: PAGE_MAX_HEIGHT,\n padding: `${PAGE_CONTENT_PADDING}rem`,\n margin: `${-PAGE_CONTENT_PADDING}rem`,\n width: `calc(100% + ${PAGE_CONTENT_PADDING * 2}rem)`,\n boxSizing: 'border-box',\n transition: contentHeight\n ? `height ${ANIMATION_DURATION.MODAL_HEIGHT_TRANSITION}ms cubic-bezier(0.4, 0, 0.2, 1)`\n : 'none',\n }),\n [contentHeight],\n );\n}\n","import {\n NonNullableBrandConfig,\n Theme,\n BorderRadiusToken,\n BorderRadiusScale,\n BorderRadiusSizeSlot,\n BORDER_RADIUS_SCALES,\n WalletLayout,\n} from '@aurum-sdk/types';\n\nexport const DEFAULT_THEME = 'dark';\n\nexport const MOBILE_BREAKPOINT = 484;\n\nexport const ANIMATION_DURATION = {\n SHAKE: 300,\n MODAL_HEIGHT_TRANSITION: 200,\n} as const;\n\nconst DEFAULT_BORDER_RADIUS: BorderRadiusToken = 'md';\nconst DEFAULT_MODAL_Z_INDEX = 1000;\nconst DEFAULT_APP_NAME = 'Aurum';\nexport const DEFAULT_FONT = \"'Inter', -apple-system, sans-serif\";\nconst DEFAULT_WALLET_LAYOUT: WalletLayout = 'stacked';\n\n/**\n * Gets the full border radius scale for a given token.\n */\nexport const getBorderRadiusScale = (token: BorderRadiusToken): BorderRadiusScale => {\n return BORDER_RADIUS_SCALES[token];\n};\n\n/**\n * Gets the border radius in pixels for a given config token and size slot.\n * NOTE: Keep in sync with @aurum-sdk/logos/src/core/utils.ts\n */\nexport function getBorderRadius(token: BorderRadiusToken, slot: BorderRadiusSizeSlot): number {\n return BORDER_RADIUS_SCALES[token][slot];\n}\n\nconst defaultLightThemeConfig: NonNullableBrandConfig = {\n logo: '',\n theme: 'light',\n primaryColor: '#000000',\n borderRadius: DEFAULT_BORDER_RADIUS,\n modalZIndex: DEFAULT_MODAL_Z_INDEX,\n appName: DEFAULT_APP_NAME,\n hideFooter: false,\n font: DEFAULT_FONT,\n walletLayout: DEFAULT_WALLET_LAYOUT,\n};\n\nconst defaultDarkThemeConfig: NonNullableBrandConfig = {\n logo: '',\n theme: 'dark',\n primaryColor: '#ffffff',\n borderRadius: DEFAULT_BORDER_RADIUS,\n modalZIndex: DEFAULT_MODAL_Z_INDEX,\n appName: DEFAULT_APP_NAME,\n hideFooter: false,\n font: DEFAULT_FONT,\n walletLayout: DEFAULT_WALLET_LAYOUT,\n};\n\nexport const getDefaultThemeConfig = (theme: Theme): NonNullableBrandConfig => {\n return theme === 'dark' ? defaultDarkThemeConfig : defaultLightThemeConfig;\n};\n","import React from 'react';\n\n/**\n * Shared layout constants for page containers (Modal and Widget).\n * These values ensure parity between modal and embedded widget views.\n */\n\n/** Padding around the page content container (rem) */\nexport const PAGE_CONTENT_PADDING = 0.25;\n\n/** Minimum height of the page content area */\nexport const PAGE_MIN_HEIGHT = '8rem';\n\n/** Maximum height of the page content area */\nexport const PAGE_MAX_HEIGHT = '600'; // px\n\n/** Padding at top of content to reserve space for the fixed header */\nexport const HEADER_HEIGHT = '3.5rem';\n\n/** Spacer height above the PoweredBy footer (rem) */\nexport const POWERED_BY_SPACER_REM = 2.5;\n\n/** Debounce delay for resize events (ms) */\nexport const RESIZE_DEBOUNCE_MS = 100;\n\n/**\n * Static style for the content wrapper inside page transitions.\n * Provides space for the absolutely-positioned header.\n */\nexport const contentWrapperStyle: React.CSSProperties = { paddingTop: HEADER_HEIGHT };\n","import { AurumLogo } from '@aurum-sdk/logos/react';\nimport { Row, Text, Button } from '@src/ui';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport './PoweredBy.css';\n\nexport const PoweredBy = () => {\n const { brandConfig } = useWidgetContext();\n\n return (\n <div className=\"powered-by-container\">\n <Row align=\"center\" justify=\"center\" gap={0}>\n <Button\n variant=\"text\"\n size=\"xs\"\n onClick={() => window.open('https://npmjs.com/package/@aurum-sdk/core', '_blank')}\n style={{ gap: '0.15rem' }}\n >\n <Text variant=\"secondary\" size=\"xs\">\n Powered by\n </Text>\n <Row align=\"center\" justify=\"center\" gap={0}>\n <AurumLogo\n variant=\"icon\"\n size={22}\n radius={brandConfig.borderRadius}\n sizeSlot=\"xs\"\n color=\"var(--color-foreground-muted)\"\n title=\"Aurum\"\n />\n <Text variant=\"secondary\" weight=\"bold\" style={{ fontSize: '13px' }}>\n Aurum\n </Text>\n </Row>\n </Button>\n </Row>\n </div>\n );\n};\n","export const Row = ({\n align = 'center',\n justify = 'center',\n children,\n gap = 8,\n style,\n ...props\n}: {\n align?: 'center' | 'start' | 'end' | 'baseline';\n justify?: 'center' | 'start' | 'end' | 'space-between';\n gap?: number;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: align,\n justifyContent: justify,\n gap: `${gap}px`,\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","export const Spacer = ({ size = 16 }: { size?: number | string }) => {\n return <div style={{ height: size }} />;\n};\n","import { Loader2 } from 'lucide-react';\nimport './Spinner.css';\n\nexport const Spinner = ({\n size = 16,\n color = 'var(--aurum-primary-color)',\n strokeWidth = 2,\n}: {\n size?: number;\n color?: string;\n strokeWidth?: number;\n}) => {\n return (\n <Loader2\n className=\"spinner\"\n strokeWidth={strokeWidth}\n size={size}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n color,\n }}\n />\n );\n};\n","import React from 'react';\nimport './Text.css';\n\nexport interface TextProps {\n variant?: 'primary' | 'secondary' | 'tertiary' | 'error' | 'brand' | 'success';\n as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div';\n size?: 'xs' | 'sm' | 'md' | 'lg';\n weight?: 'normal' | 'semibold' | 'bold';\n align?: 'left' | 'center' | 'right';\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const Text: React.FC<TextProps> = ({\n variant = 'primary',\n as = 'p',\n size = 'md',\n weight = 'normal',\n align = 'left',\n children,\n className,\n style,\n ...props\n}) => {\n const Element = as;\n\n const baseClassName = 'aurum-text';\n const classes = [\n baseClassName,\n `${baseClassName}--${variant}`,\n size && `${baseClassName}--${size}`,\n weight && `${baseClassName}--${weight}`,\n align && `${baseClassName}--align-${align}`,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <Element className={classes} {...props} style={style}>\n {children}\n </Element>\n );\n};\n","import React from 'react';\n\ninterface ThemeContainerProps {\n children: React.ReactNode;\n theme?: 'light' | 'dark';\n}\n\nexport const ThemeContainer: React.FC<ThemeContainerProps> = ({ children, theme = 'light' }) => {\n return (\n <div className=\"aurum-sdk\" data-theme={theme}>\n {children}\n </div>\n );\n};\n","import React, { useLayoutEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Text } from '@src/ui';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport './ModalHeader.css';\n\ninterface ModalHeaderProps {\n leftAction?: React.ReactNode;\n rightAction?: React.ReactNode;\n title?: React.ReactNode | string;\n}\n\nexport const ModalHeader = ({ leftAction, rightAction, title }: ModalHeaderProps) => {\n const { headerPortalRef, mode } = useWidgetContext();\n const [portalTarget, setPortalTarget] = useState<HTMLDivElement | null>(null);\n\n // Capture the portal target from context after mount\n useLayoutEffect(() => {\n if (headerPortalRef) {\n setPortalTarget(headerPortalRef.current);\n }\n }, [headerPortalRef]);\n\n // In widget mode, don't render the close button (rightAction)\n const resolvedRightAction = mode === 'widget' ? null : rightAction;\n\n const headerContent = (\n <header className=\"modal-header\">\n <div className=\"modal-header-left\">{leftAction}</div>\n <div className=\"modal-header-center\">\n {typeof title === 'string' ? (\n <Text align=\"center\" variant=\"secondary\" style={{ fontSize: '15px' }}>\n {title}\n </Text>\n ) : (\n title\n )}\n </div>\n <div className=\"modal-header-right\">{resolvedRightAction}</div>\n </header>\n );\n\n if (!portalTarget) return null;\n\n return createPortal(headerContent, portalTarget);\n};\n","import { useEffect, useState } from 'react';\nimport { useEmailAuth } from '@src/contexts/EmailAuthContext';\nimport { Button, Text } from '@src/ui';\nimport { ChevronRight, Mail } from 'lucide-react';\nimport './EmailAuth.css';\n\nconst EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport const EmailAuth = () => {\n const { emailAuthState, error, sendEmailOTP, clearError } = useEmailAuth();\n\n const [email, setEmail] = useState(emailAuthState.email);\n const [isValidEmail, setIsValidEmail] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [isButtonFocused, setIsButtonFocused] = useState(false);\n\n const showPrimary = isValidEmail && (isFocused || isButtonFocused);\n\n useEffect(() => {\n setIsValidEmail(EMAIL_REGEX.test(email));\n }, [email]);\n\n const handleSend = async () => {\n try {\n setIsLoading(true);\n await sendEmailOTP(email);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (error) {\n clearError();\n }\n if (e.key === 'Enter' && isValidEmail) {\n handleSend();\n }\n };\n\n const getInputClassName = () => {\n const classes = ['email-auth-input'];\n if (error) classes.push('email-auth-input--error');\n return classes.join(' ');\n };\n\n return (\n <>\n <div style={{ position: 'relative', width: '100%' }}>\n <div className=\"email-auth-icon\">\n <Mail size={20} color=\"var(--color-foreground-muted)\" />\n </div>\n <input\n aria-label=\"Email address\"\n id=\"email-input\"\n name=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n inputMode=\"email\"\n value={email}\n className={getInputClassName()}\n disabled={isLoading}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n placeholder=\"Email address\"\n onChange={(e) => setEmail(e.target.value)}\n />\n <Button\n size=\"sm\"\n variant={showPrimary ? 'primary' : 'secondary'}\n loading={isLoading}\n onClick={handleSend}\n disabled={!isValidEmail}\n className=\"email-auth-submit-button\"\n onFocus={() => setIsButtonFocused(true)}\n onBlur={() => setIsButtonFocused(false)}\n >\n {!isLoading && (\n <ChevronRight\n size={16}\n color={showPrimary ? 'var(--color-primary-foreground)' : 'var(--color-foreground-subtle)'}\n />\n )}\n </Button>\n </div>\n\n {error && (\n <Text variant=\"error\" size=\"sm\" align=\"left\" style={{ width: '100%', marginTop: '0.3125rem' }}>\n {error}\n </Text>\n )}\n </>\n );\n};\n","import React, { createContext, useContext, useState } from 'react';\nimport { SignInWithEmailResult } from '@coinbase/cdp-core';\nimport { WalletAdapter, WalletConnectionResult } from '@src/types/internal';\nimport { PAGE_IDS, PageIdType } from '@src/components/ConnectModal/PageIds';\nimport { AurumRpcProvider } from '@aurum-sdk/types';\nimport { sentryLogger } from '@src/services/sentry';\nimport { isConfigError } from '@src/utils/isConfigError';\n\nexport interface EmailAuthState {\n email: string;\n authResult: SignInWithEmailResult | null;\n step: 'email' | 'otp' | 'connecting' | 'success';\n}\n\ninterface EmailAuthProviderProps {\n children: React.ReactNode;\n displayedWallets: WalletAdapter[];\n onConnect: (result: WalletConnectionResult) => void;\n navigateTo: (pageId: PageIdType) => void;\n setSelectedWallet: (wallet: WalletAdapter | null) => void;\n}\n\ninterface EmailAuthContextValue {\n error: string;\n emailAuthState: EmailAuthState;\n clearError: () => void;\n sendEmailOTP: (email: string) => Promise<void>;\n resetEmailAuth: () => void;\n verifyEmailOTPAndConnect: (otp: string) => Promise<void>;\n}\n\nconst EmailAuthContext = createContext<EmailAuthContextValue | null>(null);\n\nexport const useEmailAuth = () => {\n const context = useContext(EmailAuthContext);\n if (!context) {\n throw new Error('useEmailAuth must be used within an EmailAuthProvider');\n }\n return context;\n};\n\nexport const EmailAuthProvider = ({\n children,\n displayedWallets,\n onConnect,\n navigateTo,\n setSelectedWallet,\n}: EmailAuthProviderProps) => {\n const initialAuthState: EmailAuthState = {\n email: '',\n authResult: null,\n step: 'email',\n };\n\n const [error, setError] = useState<string>('');\n const [emailAuthState, setEmailAuthState] = useState<EmailAuthState>(initialAuthState);\n\n const resetEmailAuth = () => {\n setEmailAuthState(initialAuthState);\n setError('');\n };\n\n const clearError = () => {\n setError('');\n };\n\n const attemptEmailAuth = async (email: string, emailAdapter: WalletAdapter) => {\n setError('');\n if (!emailAdapter.emailAuthStart) {\n sentryLogger.error('emailAuthStart not implemented');\n throw new Error('emailAuthStart not implemented');\n }\n const authResult = await emailAdapter.emailAuthStart(email);\n setEmailAuthState((prev) => ({ ...prev, authResult, step: 'otp' }));\n navigateTo(PAGE_IDS.EMAIL_VERIFY_OTP);\n };\n\n const handleAlreadyAuthenticatedError = async (email: string, emailAdapter: WalletAdapter) => {\n try {\n await emailAdapter.disconnect();\n await attemptEmailAuth(email, emailAdapter);\n } catch (retryError) {\n sentryLogger.error('Failed to retry email OTP after disconnect:', { error: retryError });\n setError('Failed to send email verification');\n setEmailAuthState((prev) => ({ ...prev, step: 'email' }));\n }\n };\n\n const sendEmailOTP = async (email: string) => {\n const emailAdapter = displayedWallets.find((adapter) => adapter.id === 'email');\n if (!emailAdapter) {\n sentryLogger.error('sendEmailOTP: Email adapter not found');\n throw new Error('Email adapter not found');\n }\n\n setEmailAuthState((prev) => ({ ...prev, email }));\n\n try {\n await attemptEmailAuth(email, emailAdapter);\n } catch (error) {\n setEmailAuthState((prev) => ({ ...prev, step: 'email' }));\n\n const errorMessage = (error as Error).message?.toLowerCase() ?? '';\n const isAlreadyAuthenticated = errorMessage.includes('user is already authenticated');\n\n if (isConfigError(error)) {\n navigateTo(PAGE_IDS.CONFIG_ERROR);\n } else if (isAlreadyAuthenticated) {\n try {\n await handleAlreadyAuthenticatedError(email, emailAdapter);\n } catch {\n setError('Failed to send email verification');\n }\n } else {\n setError('Failed to send email verification');\n }\n }\n };\n\n const verifyEmailOTPAndConnect = async (otp: string) => {\n try {\n if (!emailAuthState.authResult) {\n sentryLogger.error('No auth result found');\n throw new Error('No auth result found');\n }\n\n const emailAdapter = displayedWallets.find((adapter) => adapter.id === 'email');\n if (!emailAdapter) {\n sentryLogger.error('verifyEmailOTPAndConnect: Email adapter not found');\n throw new Error('Email adapter not found');\n }\n\n setEmailAuthState((prev) => ({ ...prev, step: 'connecting' }));\n\n if (!emailAdapter.emailAuthVerify) {\n sentryLogger.error('emailAuthVerify not implemented');\n throw new Error('emailAuthVerify not implemented');\n }\n const verifyResult = await emailAdapter.emailAuthVerify(emailAuthState.authResult.flowId, otp);\n setSelectedWallet(emailAdapter);\n\n setEmailAuthState((prev) => ({ ...prev, step: 'success' }));\n\n setTimeout(() => {\n onConnect({\n walletId: emailAdapter.id,\n address: verifyResult.user?.evmAccounts?.[0] ?? '',\n provider: emailAdapter.getProvider() as AurumRpcProvider,\n email: emailAuthState.email,\n });\n }, 1500);\n } catch {\n setError('Invalid or expired code');\n setEmailAuthState((prev) => ({ ...prev, step: 'otp' }));\n }\n };\n\n const contextValue: EmailAuthContextValue = {\n error,\n emailAuthState,\n clearError,\n sendEmailOTP,\n resetEmailAuth,\n verifyEmailOTPAndConnect,\n };\n\n return <EmailAuthContext.Provider value={contextValue}>{children}</EmailAuthContext.Provider>;\n};\n","import * as Sentry from '@sentry/browser';\n\ndeclare const __SDK_VERSION__: string;\ndeclare const __SENTRY_DSN__: string;\n\nlet initialized = false;\nlet telemetryEnabled = true;\n\nfunction getEnvironment(): string {\n if (typeof window !== 'undefined') {\n const hostname = window.location.hostname;\n if (hostname === 'localhost' || hostname === '127.0.0.1') {\n return 'development';\n }\n }\n return 'production';\n}\n\nexport function initSentry(enabled: boolean = true) {\n telemetryEnabled = enabled;\n if (initialized || !telemetryEnabled || !__SENTRY_DSN__) return;\n initialized = true;\n\n Sentry.init({\n dsn: __SENTRY_DSN__,\n environment: getEnvironment(),\n release: `@aurum-sdk/core@${__SDK_VERSION__}`,\n sendDefaultPii: false,\n enableLogs: true,\n });\n}\n\n// Wrapper that no-ops when telemetry is disabled\nexport const sentryLogger = {\n info: (message: string, attributes?: Record<string, unknown>) => {\n if (telemetryEnabled) Sentry.logger.info(message, attributes);\n },\n warn: (message: string, attributes?: Record<string, unknown>) => {\n if (telemetryEnabled) Sentry.logger.warn(message, attributes);\n },\n error: (message: string, attributes?: Record<string, unknown>) => {\n if (telemetryEnabled) Sentry.logger.error(message, attributes);\n },\n};\n","/**\n * Checks if an error is a configuration error (missing project ID).\n * Used to detect when adapters fail due to missing required configuration.\n */\nexport const isConfigError = (error: unknown): boolean => {\n const name = (error as Error)?.name;\n return name === 'ConfigError';\n};\n\n/**\n * Creates a standardized configuration error for missing project IDs.\n * All adapters should use this to ensure consistent error handling.\n */\nexport const createConfigError = (adapterName: string): Error => {\n const error = new Error(`Missing required project ID for ${adapterName}`);\n error.name = 'ConfigError';\n return error;\n};\n","import { WalletLogo as BaseLogo, WalletLogoProps as BaseLogoProps } from '@aurum-sdk/logos/react';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\n\nexport const WalletLogoWrapper = ({ radius, variant = 'brand', ...props }: BaseLogoProps) => {\n const { brandConfig } = useWidgetContext();\n return <BaseLogo radius={radius ?? brandConfig.borderRadius} variant={variant} {...props} />;\n};\n","import { WalletAdapter } from '@src/types/internal';\nimport { Button } from '@src/ui';\nimport { WalletLogoWrapper } from '@src/components/WalletLogoWrapper/WalletLogoWrapper';\n\nexport const GridWalletButton = ({\n wallet,\n connectWallet,\n}: {\n wallet: WalletAdapter;\n connectWallet: (wallet: WalletAdapter) => void;\n}) => {\n return (\n <Button\n variant=\"secondary\"\n onClick={() => connectWallet(wallet)}\n aria-label={`Connect with ${wallet.name}`}\n title={wallet.name}\n >\n <WalletLogoWrapper id={wallet.id} size={44} variant=\"icon\" />\n </Button>\n );\n};\n","import React from 'react';\nimport { WalletAdapter } from '@src/types/internal';\nimport { GridWalletButton } from '@src/components/WalletButton/GridWalletButton';\nimport '@src/components/ConnectModal/WalletGrid.css';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\n\ninterface WalletListGridProps {\n wallets: WalletAdapter[];\n}\n\nconst getGridColumns = (walletCount: number): number => {\n if (walletCount <= 2) return 2;\n if (walletCount === 3) return 3;\n if (walletCount === 5) return 3;\n if (walletCount === 6) return 3;\n return 4;\n};\n\nexport const WalletListGrid: React.FC<WalletListGridProps> = ({ wallets }) => {\n const { connectWallet } = useConnectModal();\n\n const columns = getGridColumns(wallets.length);\n\n return (\n <div className=\"aurum-wallet-grid\" style={{ '--grid-columns': columns } as React.CSSProperties}>\n {wallets.map((wallet) => (\n <GridWalletButton key={wallet.id} wallet={wallet} connectWallet={connectWallet} />\n ))}\n </div>\n );\n};\n","import React from 'react';\nimport { WalletAdapter } from '@src/types/internal';\nimport { Column, Button, Row, Text } from '@src/ui';\nimport { ChevronRight } from 'lucide-react';\nimport { WalletButton } from '@src/components/WalletButton/WalletButton';\nimport { AdditionalWalletsIcon } from '@src/components/ConnectModal/AdditionalWalletsIcon';\nimport { PAGE_IDS } from '@src/components/ConnectModal/PageIds';\nimport { useAurumStore } from '@src/store';\nimport { useNavigation } from '@src/contexts/NavigationContext';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\n\ninterface WalletListStackedProps {\n wallets: WalletAdapter[];\n hasEmailAuth: boolean;\n}\n\nexport const WalletListStacked: React.FC<WalletListStackedProps> = ({ wallets, hasEmailAuth }) => {\n const { navigateTo } = useNavigation();\n const { connectWallet } = useConnectModal();\n\n const lastUsedWalletId = useAurumStore((state) => state.lastUsedWalletId);\n\n const showAllButton = hasEmailAuth ? wallets.length > 4 : wallets.length > 5;\n const walletsToShow = showAllButton ? wallets.slice(0, 3) : wallets;\n const additionalWallets = showAllButton ? wallets.slice(3) : [];\n\n const goToAllWallets = () => {\n navigateTo(PAGE_IDS.ALL_WALLETS);\n };\n\n return (\n <Column>\n {walletsToShow.map((wallet) => (\n <WalletButton\n key={wallet.id}\n wallet={wallet}\n connectWallet={connectWallet}\n isLastUsed={wallet.id === lastUsedWalletId}\n />\n ))}\n\n {showAllButton && (\n <Button variant=\"secondary\" onClick={goToAllWallets} expand>\n <Row justify=\"space-between\" align=\"center\" style={{ width: '100%' }}>\n <Row align=\"center\" gap={10}>\n <AdditionalWalletsIcon additionalWallets={additionalWallets} size={32} />\n <Text weight=\"semibold\" size=\"md\">\n All Wallets\n </Text>\n </Row>\n <ChevronRight size={18} color=\"var(--color-foreground-subtle)\" />\n </Row>\n </Button>\n )}\n </Column>\n );\n};\n","import { WalletAdapter } from '@src/types/internal';\nimport { Button, Row, Text } from '@src/ui';\nimport { QrCode } from 'lucide-react';\nimport { WalletButtonLabel } from '@src/components/WalletButton/WalletButtonLabel';\nimport { WalletLogoWrapper } from '@src/components/WalletLogoWrapper/WalletLogoWrapper';\nimport { WalletId } from '@aurum-sdk/types';\n\nexport const WalletButton = ({\n wallet,\n connectWallet,\n isLastUsed = false,\n iconSize = 32,\n}: {\n wallet: WalletAdapter;\n connectWallet: (wallet: WalletAdapter) => void;\n isLastUsed?: boolean;\n iconSize?: number;\n}) => {\n const label = isLastUsed ? 'Recent' : undefined;\n\n return (\n <Button\n key={wallet.id}\n variant={'secondary'}\n onClick={() => connectWallet(wallet)}\n expand\n // account for the logo making the button larger, and the normal border\n // radius not being enough to make it fully rounded in xl radius config\n // (normally, button has `-2px` subtracted from the border radius to make it look better)\n style={{ borderRadius: 'var(--aurum-border-radius-md)' }}\n >\n <Row justify=\"space-between\" align=\"center\" style={{ width: '100%' }}>\n <Row align=\"center\" gap={10}>\n <WalletLogoWrapper id={wallet.id} size={iconSize} sizeSlot=\"sm\" />\n <Text weight=\"semibold\" size=\"md\">\n {wallet.name}\n </Text>\n </Row>\n {wallet.id === WalletId.WalletConnect && !isLastUsed ? (\n <QrCode color=\"var(--color-foreground)\" size={18} />\n ) : (\n <WalletButtonLabel type={label} />\n )}\n </Row>\n </Button>\n );\n};\n","import { RecentBadge } from '@src/ui';\nimport { ChevronRight } from 'lucide-react';\n\nexport const WalletButtonLabel = ({ type }: { type?: 'Recent' }) => {\n if (!type) return <ChevronRight size={18} color=\"var(--color-foreground-subtle)\" />;\n return <RecentBadge />;\n};\n","import React from 'react';\nimport { WalletAdapter } from '@src/types/internal';\nimport { WalletLogoWrapper } from '@src/components/WalletLogoWrapper/WalletLogoWrapper';\nimport { Row } from '@src/ui';\nimport './AdditionalWalletsIcon.css';\n\ninterface AdditionalWalletsIconProps {\n additionalWallets: WalletAdapter[];\n size?: number;\n}\n\nexport const AdditionalWalletsIcon: React.FC<AdditionalWalletsIconProps> = ({ additionalWallets, size = 32 }) => {\n const walletCount = additionalWallets.length;\n\n // 1 wallet: single centered icon\n if (walletCount === 1) {\n const iconSize = Math.floor(size * 0.7);\n return (\n <div className=\"additional-wallets-container\" style={{ width: size, height: size }}>\n <WalletLogoWrapper\n id={additionalWallets[0].id}\n size={iconSize}\n sizeSlot=\"xs\"\n title={additionalWallets[0].name}\n />\n </div>\n );\n }\n\n // 2 wallets: horizontal row with overlapping effect\n if (walletCount === 2) {\n const iconSize = Math.floor(size * 0.55);\n return (\n <div className=\"additional-wallets-container\" style={{ width: size, height: size }}>\n <Row align=\"center\" gap={0}>\n <div\n className=\"circular-icon-wrapper circular-icon-wrapper--front\"\n style={{ width: iconSize, height: iconSize }}\n >\n <WalletLogoWrapper\n id={additionalWallets[0].id}\n size={iconSize}\n sizeSlot=\"xs\"\n title={additionalWallets[0].name}\n />\n </div>\n <div\n className=\"circular-icon-wrapper circular-icon-wrapper--back\"\n style={{ width: iconSize, height: iconSize }}\n >\n <WalletLogoWrapper\n id={additionalWallets[1].id}\n size={iconSize}\n sizeSlot=\"xs\"\n title={additionalWallets[1].name}\n />\n </div>\n </Row>\n </div>\n );\n }\n\n // 3+ wallets: 2x2 grid (take up to 4)\n const walletsToShow = additionalWallets.slice(0, 4);\n const iconSize = Math.floor(size * 0.4);\n\n return (\n <div className=\"additional-wallets-grid\" style={{ width: size, height: size }}>\n {walletsToShow.map((wallet) => (\n <div key={wallet.id} className=\"additional-wallets-grid-item\" style={{ width: iconSize, height: iconSize }}>\n <WalletLogoWrapper id={wallet.id} size={iconSize} sizeSlot=\"xs\" title={wallet.name} />\n </div>\n ))}\n\n {/* Fill empty slot with placeholder if 3 wallets */}\n {walletsToShow.length === 3 && (\n <div className=\"additional-wallets-placeholder\" style={{ width: iconSize, height: iconSize }} />\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { Spacer, Column, Row, Button, Text } from '@src/ui';\nimport { X, ChevronLeft, CircleCheck } from 'lucide-react';\nimport { ModalHeader } from '@src/components/ModalHeader/ModalHeader';\nimport { ANIMATION_DURATION } from '@src/constants/theme';\nimport { ConnectionIconsRow } from '@src/components/ConnectModal/ConnectionStatus/ConnectionIconsRow';\nimport './ConnectionStatus.css';\n\ninterface ConnectionStatusBaseProps {\n title?: string;\n pendingHeaderText: string;\n pendingSubContent: React.ReactNode;\n extraContent?: React.ReactNode;\n}\n\nexport const ConnectionStatusBase: React.FC<ConnectionStatusBaseProps> = ({\n title,\n pendingHeaderText,\n pendingSubContent,\n extraContent,\n}) => {\n const { selectedWallet, error, success, goBackToHome, retryConnection } = useConnectModal();\n const { onDismiss, brandConfig } = useWidgetContext();\n const [shouldShake, setShouldShake] = useState(false);\n\n // Trigger shake animation when error occurs\n useEffect(() => {\n if (error) {\n setShouldShake(true);\n const timer = setTimeout(() => {\n setShouldShake(false);\n }, ANIMATION_DURATION.SHAKE);\n return () => clearTimeout(timer);\n }\n }, [error]);\n\n if (!selectedWallet) {\n return null;\n }\n\n const getHeaderVariant = () => {\n if (success) return 'success';\n if (error) return 'error';\n return 'primary';\n };\n\n const getHeaderText = () => {\n if (success) return '';\n if (error) return 'Request Rejected';\n return pendingHeaderText;\n };\n\n const renderSubContent = () => {\n if (success) {\n return (\n <div className=\"success-icon-large\">\n <CircleCheck color=\"var(--aurum-primary-color)\" size={46} />\n </div>\n );\n }\n\n if (error) {\n return (\n <Text align=\"center\" size=\"sm\" variant=\"secondary\">\n Please try again or select a {'\\n'}different wallet\n </Text>\n );\n }\n\n return pendingSubContent;\n };\n\n return (\n <>\n <ModalHeader\n leftAction={\n success ? null : (\n <Button size=\"sm\" variant=\"close\" onClick={goBackToHome} aria-label=\"Go back\">\n <ChevronLeft size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n )\n }\n rightAction={\n success ? null : (\n <Button size=\"sm\" variant=\"close\" onClick={onDismiss} aria-label=\"Close\">\n <X size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n )\n }\n title={title || selectedWallet.name}\n />\n <Spacer size={12} />\n <Column align=\"center\" style={{ maxWidth: '15.625rem', margin: '0 auto' }} gap={8}>\n <ConnectionIconsRow\n brandConfig={brandConfig}\n walletId={selectedWallet.id}\n walletName={selectedWallet.name}\n success={success}\n error={error}\n shouldShake={shouldShake}\n onRetry={retryConnection}\n />\n <Spacer size={12} />\n <Column align=\"center\" justify=\"start\" gap={0} style={{ minHeight: '5rem', width: '100%' }}>\n <Column gap={8} style={{ width: '100%' }} align=\"center\">\n <Row align=\"center\" justify=\"center\" gap={0} style={{ width: '100%' }}>\n <Text size=\"lg\" variant={getHeaderVariant()} weight=\"bold\" align=\"center\">\n {getHeaderText()}\n </Text>\n </Row>\n <Row align=\"center\" justify=\"center\" gap={0} style={{ width: '100%', whiteSpace: 'pre-line' }}>\n {renderSubContent()}\n </Row>\n {extraContent}\n </Column>\n </Column>\n </Column>\n <Spacer size={12} />\n </>\n );\n};\n","import React from 'react';\nimport { AurumLogo } from '@aurum-sdk/logos/react';\nimport { Row, Button } from '@src/ui';\nimport { RotateCcw } from 'lucide-react';\nimport { WalletLogoWrapper } from '@src/components/WalletLogoWrapper/WalletLogoWrapper';\nimport { BrandLogo } from '@src/components/ConnectModal/BrandLogo';\nimport { StatusIcons } from '@src/components/ConnectModal/ConnectionStatus/StatusIcons';\nimport { BrandConfig, WalletId } from '@aurum-sdk/types';\n\ninterface ConnectionIconsRowProps {\n brandConfig: BrandConfig;\n walletId: WalletId;\n walletName: string;\n success: boolean;\n error: boolean;\n shouldShake: boolean;\n onRetry: () => void;\n}\n\nexport const ConnectionIconsRow: React.FC<ConnectionIconsRowProps> = ({\n brandConfig,\n walletId,\n walletName,\n success,\n error,\n shouldShake,\n onRetry,\n}) => {\n return (\n <div className={`connection-icons-row ${shouldShake ? 'wallet-icon-shake' : ''}`}>\n <Row gap={4}>\n <div className=\"brand-logo-container\">\n {brandConfig.logo ? (\n <BrandLogo size={54} sizeSlot=\"md\" />\n ) : (\n <AurumLogo variant=\"black\" size={53} radius={brandConfig.borderRadius} sizeSlot=\"md\" title=\"Aurum\" />\n )}\n </div>\n <StatusIcons success={success} error={error} />\n <div className=\"wallet-logo-with-retry\">\n <WalletLogoWrapper id={walletId} size={54} sizeSlot=\"md\" title={walletName} />\n {error && (\n <Button variant=\"secondary\" className=\"retry-icon-overlay\" onClick={onRetry} aria-label=\"Retry connection\">\n <RotateCcw size={18} />\n </Button>\n )}\n </div>\n </Row>\n </div>\n );\n};\n","import { getLogoRadius } from '@aurum-sdk/logos/react';\nimport { BorderRadiusSizeSlot } from '@aurum-sdk/types';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\n\ninterface BrandLogoProps {\n size?: number;\n sizeSlot?: BorderRadiusSizeSlot;\n}\n\nexport const BrandLogo = ({ size = 70, sizeSlot = 'sm' }: BrandLogoProps) => {\n const { brandConfig } = useWidgetContext();\n\n return brandConfig.logo ? (\n <img\n src={brandConfig.logo}\n alt={`${brandConfig.appName} logo`}\n style={{\n width: size,\n height: size,\n objectFit: 'cover',\n borderRadius: getLogoRadius(brandConfig.borderRadius, sizeSlot),\n }}\n />\n ) : null;\n};\n","import React from 'react';\nimport { Row } from '@src/ui';\nimport { X } from 'lucide-react';\n\nconst ELLIPSES_COUNT = 3;\n\ninterface StatusIconsProps {\n success: boolean;\n error: boolean | string | null;\n}\n\nexport const StatusIcons: React.FC<StatusIconsProps> = ({ success, error }) => {\n const getStatusKey = () => {\n if (success) return 'success';\n if (error) return 'error';\n return 'connecting';\n };\n\n if (success) {\n return (\n <Row\n key={getStatusKey()}\n align=\"center\"\n justify=\"center\"\n gap={0}\n style={{ padding: '0 0.5rem', minHeight: '3rem' }}\n >\n <div className=\"ellipses-success\">\n {Array.from({ length: ELLIPSES_COUNT }, (_, i) => (\n <span key={i}>·</span>\n ))}\n </div>\n </Row>\n );\n }\n\n if (error) {\n const dotsBeforeIcon = Math.floor(ELLIPSES_COUNT / 2);\n const dotsAfterIcon = ELLIPSES_COUNT - dotsBeforeIcon - 1;\n\n return (\n <Row\n key={getStatusKey()}\n align=\"center\"\n justify=\"center\"\n gap={0}\n style={{ padding: '0 0.5rem', minHeight: '3rem' }}\n >\n <div className=\"status-icon-with-dots error\">\n {Array.from({ length: dotsBeforeIcon }, (_, i) => (\n <span key={`before-${i}`} className=\"dot\">\n ·\n </span>\n ))}\n <div className=\"icon-center\">\n <X size={24} color=\"var(--color-error)\" />\n </div>\n {Array.from({ length: dotsAfterIcon }, (_, i) => (\n <span key={`after-${i}`} className=\"dot\">\n ·\n </span>\n ))}\n </div>\n </Row>\n );\n }\n\n return (\n <Row\n key={getStatusKey()}\n align=\"center\"\n justify=\"center\"\n gap={0}\n style={{ padding: '0 0.5rem', minHeight: '3rem' }}\n >\n <div className=\"ellipses-loading\">\n {Array.from({ length: ELLIPSES_COUNT }, (_, i) => (\n <span key={i}>·</span>\n ))}\n </div>\n </Row>\n );\n};\n","import React from 'react';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { Text } from '@src/ui';\nimport { ConnectionStatusBase } from './ConnectionStatusBase';\nimport { WalletId } from '@aurum-sdk/types';\n\nexport const ConnectionStatusPage: React.FC = () => {\n const { selectedWallet } = useConnectModal();\n\n return (\n <ConnectionStatusBase\n pendingHeaderText={`Approve in ${selectedWallet?.name}`}\n pendingSubContent={\n <Text align=\"center\" size=\"sm\" variant=\"secondary\">\n {selectedWallet?.id === WalletId.Ledger\n ? `Please wait for the Ledger Live modal to open`\n : `Please check your wallet to\\napprove the connection`}\n </Text>\n }\n />\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { Text, Button } from '@src/ui';\nimport { ConnectionStatusBase } from './ConnectionStatusBase';\n\nexport const ConnectionStatusMobilePage: React.FC = () => {\n const { selectedWallet, error, success, retryConnection } = useConnectModal();\n const [showLaunchButton, setShowLaunchButton] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setShowLaunchButton(true), 5000);\n return () => clearTimeout(timer);\n }, []);\n\n return (\n <ConnectionStatusBase\n title={selectedWallet?.name}\n pendingHeaderText={`Opening ${selectedWallet?.name}`}\n pendingSubContent={\n <Text size=\"sm\" variant=\"secondary\" align=\"center\" style={{ maxWidth: '18.75rem' }}>\n If {selectedWallet?.name} doesn't open automatically, click the button below\n </Text>\n }\n extraContent={\n showLaunchButton && !success && !error ? (\n <Button variant=\"tertiary\" size=\"md\" onClick={retryConnection} style={{ width: '100%', marginTop: '0.5rem' }}>\n Launch App\n </Button>\n ) : undefined\n }\n />\n );\n};\n","import React, { useEffect, useState, useRef } from 'react';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useNavigation } from '@src/contexts/NavigationContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { QRCodeDisplay } from '@src/components/QRCodeDisplay/QRCodeDisplay';\nimport { Spacer, Column, Button, Text } from '@src/ui';\nimport { ChevronLeft, X, SquareArrowOutUpRight, CircleCheck } from 'lucide-react';\nimport { ModalHeader } from '@src/components/ModalHeader/ModalHeader';\nimport { PAGE_IDS } from '@src/components/ConnectModal/PageIds';\nimport { WalletId, WalletName } from '@aurum-sdk/types';\nimport { WalletAdapter } from '@src/types/internal';\n\nexport const QRCodePage: React.FC = () => {\n const { onDismiss } = useWidgetContext();\n const { navigateTo } = useNavigation();\n const { selectedWallet, error, configError, retryConnection, qrSuccess } = useConnectModal();\n\n const [connectionUri, setConnectionUri] = useState<string | null>(null);\n\n // Preserve the original wallet that brought user to this page (don't let AppKit override it)\n const originalWalletRef = useRef<WalletAdapter | null>(null);\n\n useEffect(() => {\n // Only update the original wallet if selectedWallet is not AppKit\n if (selectedWallet && selectedWallet.id !== WalletId.AppKit) {\n originalWalletRef.current = selectedWallet;\n }\n }, [selectedWallet]);\n\n // Use the preserved wallet for display, fall back to selectedWallet\n const displayWallet = originalWalletRef.current || selectedWallet;\n\n const goBackToHome = () => {\n navigateTo(PAGE_IDS.SELECT_WALLET);\n };\n\n const title =\n displayWallet?.name === WalletName.WalletConnect || displayWallet?.name === WalletName.AppKit\n ? 'Scan QR code'\n : `Scan with ${displayWallet?.name} app`;\n\n useEffect(() => {\n const handleWalletConnectURI = (event: CustomEvent<{ uri: string }>) => {\n setConnectionUri(event.detail.uri);\n };\n\n window.addEventListener('walletconnect:uri', handleWalletConnectURI as EventListener);\n\n return () => {\n window.removeEventListener('walletconnect:uri', handleWalletConnectURI as EventListener);\n };\n }, []);\n\n // Don't auto-retry connect() if config error\n useEffect(() => {\n if (error && !configError) {\n setConnectionUri(null);\n retryConnection();\n }\n }, [error, configError]);\n\n if (!selectedWallet) {\n return null;\n }\n\n return (\n <>\n <ModalHeader\n leftAction={\n qrSuccess ? null : (\n <Button size=\"sm\" variant=\"close\" onClick={goBackToHome} aria-label=\"Go back\">\n <ChevronLeft size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n )\n }\n title={title}\n rightAction={\n qrSuccess ? null : (\n <Button size=\"sm\" variant=\"close\" onClick={onDismiss} aria-label=\"Close\">\n <X size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n )\n }\n />\n {qrSuccess ? (\n <Column align=\"center\" style={{ height: '8rem' }}>\n <CircleCheck color=\"var(--aurum-primary-color)\" size={46} />\n </Column>\n ) : (\n <>\n <Column align=\"center\" gap={24}>\n <QRCodeDisplay uri={error ? null : connectionUri} />\n </Column>\n {displayWallet?.downloadUrl && (\n <>\n <Spacer size={15} />\n <Button\n variant=\"tertiary\"\n expand\n onClick={() => window.open(displayWallet.downloadUrl ?? '', '_blank', 'noopener,noreferrer')}\n >\n <SquareArrowOutUpRight size={16} color=\"var(--color-foreground-muted)\" />\n <Text size=\"sm\" weight=\"semibold\" variant=\"secondary\">\n Download {displayWallet.name}\n </Text>\n </Button>\n </>\n )}\n </>\n )}\n </>\n );\n};\n","import React, { useRef, useEffect } from 'react';\nimport { QRCode } from 'react-qrcode-logo';\nimport { Column, CopyButton, Row, Button } from '@src/ui';\nimport { generateQrCodeWalletLogo } from '@src/utils/generateQrCodeWalletLogo';\nimport { QRCodeSkeleton } from '@src/components/QRCodeDisplay/QRCodeSkeleton';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { WalletId } from '@aurum-sdk/types';\nimport { getBorderRadiusScale } from '@src/constants/theme';\nimport { WalletAdapter } from '@src/types/internal';\nimport './QRCodeDisplay.css';\n\ninterface QRCodeDisplayProps {\n uri?: string | null;\n size?: number;\n title?: string;\n subtitle?: string;\n error?: boolean;\n}\n\nexport const QRCodeDisplay: React.FC<QRCodeDisplayProps> = ({ uri, size = 256 }) => {\n const { brandConfig } = useWidgetContext();\n const { selectedWallet, displayedWallets, connectWallet } = useConnectModal();\n const qrCodeDisplayColor = brandConfig.theme === 'light' ? '#000000' : '#6b7280';\n const bgColor = brandConfig.theme === 'light' ? '#ffffff' : '#121212';\n\n // Preserve the wallet logo when switching to AppKit\n const logoWalletRef = useRef<WalletAdapter | null>(null);\n\n useEffect(() => {\n // Only update the logo wallet if selectedWallet is not AppKit\n if (selectedWallet && selectedWallet.id !== WalletId.AppKit) {\n logoWalletRef.current = selectedWallet;\n }\n }, [selectedWallet]);\n\n const logoWallet = logoWalletRef.current || selectedWallet;\n\n const appKitAdapter = displayedWallets.find(({ id }) => id === WalletId.AppKit);\n\n const handleAppKitConnect = async () => {\n if (appKitAdapter) {\n connectWallet(appKitAdapter);\n }\n };\n\n return (\n <Column align=\"center\" gap={16}>\n <Column align=\"center\" gap={4}>\n <div\n className={`qr-container ${!uri ? 'qr-container-shimmer' : ''}`}\n style={{\n width: size,\n height: size,\n }}\n >\n {!uri ? (\n <QRCodeSkeleton size={size} />\n ) : (\n <QRCode\n value={uri}\n size={size}\n quietZone={0}\n bgColor={bgColor}\n fgColor={qrCodeDisplayColor}\n logoImage={generateQrCodeWalletLogo(logoWallet || undefined)}\n logoWidth={size * 0.2}\n logoHeight={size * 0.2}\n removeQrCodeBehindLogo={true}\n logoPadding={6}\n qrStyle=\"dots\"\n eyeRadius={getBorderRadiusScale(brandConfig.borderRadius).xs}\n />\n )}\n </div>\n <Row justify={appKitAdapter ? 'space-between' : 'center'} style={{ width: '100%' }}>\n <CopyButton text={uri || ''} disabled={!uri} variant=\"secondary\" label=\"Copy URI\" />\n {appKitAdapter && (\n <Button\n variant=\"text\"\n size=\"sm\"\n onClick={handleAppKitConnect}\n style={{ color: 'var(--color-foreground-muted)', fontWeight: '500' }}\n >\n Open Modal\n </Button>\n )}\n </Row>\n </Column>\n </Column>\n );\n};\n","import { getLogoDataUri } from '@aurum-sdk/logos';\nimport { WalletAdapter } from '@src/types/internal';\nimport { WalletId } from '@aurum-sdk/types';\n\nexport const generateQrCodeWalletLogo = (walletAdapter?: WalletAdapter): string => {\n // Re-use WalletConnect icon for AppKit since it's not using the QR code\n if (walletAdapter && walletAdapter.id !== WalletId.AppKit && walletAdapter.icon) {\n return walletAdapter.icon;\n }\n\n return getLogoDataUri(WalletId.WalletConnect) ?? '';\n};\n","import React from 'react';\n\ninterface QREyeProps {\n x: number;\n y: number;\n eyeSize: number;\n eyeRadius: number;\n dotSize: number;\n fillColor: string;\n bgColor: string;\n}\n\nexport const QREye: React.FC<QREyeProps> = ({ x, y, eyeSize, eyeRadius, dotSize, fillColor, bgColor }) => {\n const padding = dotSize * 0.8;\n const centerRadius = ((eyeSize - 4 * padding) / 2) * 1.1;\n\n return (\n <g>\n {/* Outer square */}\n <rect\n x={x}\n y={y}\n width={eyeSize}\n height={eyeSize}\n fill={fillColor}\n rx={eyeRadius}\n ry={eyeRadius}\n className=\"qr-skeleton-eye\"\n />\n {/* Inner white space */}\n <rect\n x={x + padding}\n y={y + padding}\n width={eyeSize - 2 * padding}\n height={eyeSize - 2 * padding}\n fill={bgColor}\n rx={eyeRadius / 2}\n ry={eyeRadius / 2}\n />\n {/* Inner center circle */}\n <circle cx={x + eyeSize / 2} cy={y + eyeSize / 2} r={centerRadius} fill={fillColor} className=\"qr-skeleton-eye\" />\n </g>\n );\n};\n","import React from 'react';\n\ninterface GenerateSkeletonDotsParams {\n logoSize: number;\n dotSize: number;\n eyeSize: number;\n gridSize: number;\n fillColor: string;\n}\n\nexport const generateSkeletonDots = ({\n logoSize,\n dotSize,\n eyeSize,\n gridSize,\n fillColor,\n}: GenerateSkeletonDotsParams): React.ReactNode[] => {\n const dots: React.ReactNode[] = [];\n\n for (let row = 0; row < gridSize; row++) {\n for (let col = 0; col < gridSize; col++) {\n const x = col * dotSize;\n const y = row * dotSize;\n\n // Skip eye areas (corners) with NO padding - exact eye size only\n const eyeAreaWithPadding = Math.ceil(eyeSize / dotSize);\n\n const isTopLeftEye = row < eyeAreaWithPadding && col < eyeAreaWithPadding;\n const isTopRightEye = row < eyeAreaWithPadding && col >= gridSize - eyeAreaWithPadding;\n const isBottomLeftEye = row >= gridSize - eyeAreaWithPadding && col < eyeAreaWithPadding;\n\n // Skip logo area (center) - fix centering by using proper center calculation\n const centerX = (gridSize - 1) / 2;\n const centerY = (gridSize - 1) / 2;\n const logoPaddingInGridUnits = 6 / dotSize;\n const logoHalfSize = logoSize / dotSize / 2 + logoPaddingInGridUnits;\n const isLogoArea = Math.abs(col - centerX) < logoHalfSize && Math.abs(row - centerY) < logoHalfSize;\n\n if (!isTopLeftEye && !isTopRightEye && !isBottomLeftEye && !isLogoArea) {\n dots.push(\n <circle\n key={`${row}-${col}`}\n cx={x + dotSize / 2}\n cy={y + dotSize / 2}\n r={dotSize * 0.25}\n fill={fillColor}\n className=\"qr-skeleton-dot\"\n />,\n );\n }\n }\n }\n\n return dots;\n};\n","import React from 'react';\nimport { generateQrCodeWalletLogo } from '@src/utils/generateQrCodeWalletLogo';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { QREye } from '@src/components/QRCodeDisplay/QREye';\nimport { generateSkeletonDots } from '@src/components/QRCodeDisplay/generateSkeletonDots';\nimport './QRCodeSkeleton.css';\n\ninterface QRCodeSkeletonProps {\n size?: number;\n}\n\nexport const QRCodeSkeleton: React.FC<QRCodeSkeletonProps> = ({ size = 128 }) => {\n const { brandConfig } = useWidgetContext();\n const { selectedWallet } = useConnectModal();\n\n const fillColor = brandConfig.theme === 'light' ? '#777777' : '#6b7280';\n const bgColor = brandConfig.theme === 'light' ? '#ffffff' : '#121212';\n\n const logoSize = size * 0.2;\n const eyeRadius = 6;\n const dotSize = size / 40;\n const eyeSize = 32;\n const gridSize = 40;\n\n return (\n <div className=\"qr-skeleton-container\" style={{ height: size }}>\n <svg width={size} height={size} className=\"qr-skeleton-svg\">\n {/* Background */}\n <rect width={size} height={size} fill={bgColor} />\n\n {/* Generate dots pattern */}\n {generateSkeletonDots({ logoSize, dotSize, eyeSize, gridSize, fillColor })}\n\n {/* QR code eyes */}\n <QREye\n x={0}\n y={0}\n eyeSize={eyeSize}\n eyeRadius={eyeRadius}\n dotSize={dotSize}\n fillColor={fillColor}\n bgColor={bgColor}\n />\n <QREye\n x={size - eyeSize}\n y={0}\n eyeSize={eyeSize}\n eyeRadius={eyeRadius}\n dotSize={dotSize}\n fillColor={fillColor}\n bgColor={bgColor}\n />\n <QREye\n x={0}\n y={size - eyeSize}\n eyeSize={eyeSize}\n eyeRadius={eyeRadius}\n dotSize={dotSize}\n fillColor={fillColor}\n bgColor={bgColor}\n />\n\n {/* Logo placeholder with square background */}\n <rect\n x={size / 2 - logoSize / 2}\n y={size / 2 - logoSize / 2}\n width={logoSize}\n height={logoSize}\n fill={bgColor}\n rx={6}\n ry={6}\n />\n\n {/* Selected wallet logo or WalletConnect fallback */}\n <image\n x={size / 2 - logoSize / 2}\n y={size / 2 - logoSize / 2}\n width={logoSize}\n height={logoSize}\n href={generateQrCodeWalletLogo(selectedWallet || undefined)}\n opacity=\"1.0\"\n />\n </svg>\n </div>\n );\n};\n","import React, { useMemo } from 'react';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useNavigation } from '@src/contexts/NavigationContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { Column, Button } from '@src/ui';\nimport { X, ChevronLeft } from 'lucide-react';\nimport { ModalHeader } from '@src/components/ModalHeader/ModalHeader';\nimport { WalletButton } from '@src/components/WalletButton/WalletButton';\nimport { useAurumStore } from '@src/store';\nimport { sortWallets } from '@src/utils/sortWallets';\nimport { PAGE_IDS } from '@src/components/ConnectModal/PageIds';\n\nexport const AllWalletsPage: React.FC = () => {\n const { onDismiss } = useWidgetContext();\n const { navigateTo } = useNavigation();\n const { displayedWallets, connectWallet } = useConnectModal();\n\n const lastUsedWalletId = useAurumStore((state) => state.lastUsedWalletId);\n\n const sortedWallets = useMemo(() => sortWallets(displayedWallets), [displayedWallets]);\n\n const goBackToSelectWallet = () => {\n navigateTo(PAGE_IDS.SELECT_WALLET);\n };\n\n return (\n <>\n <ModalHeader\n leftAction={\n <Button size=\"sm\" variant=\"close\" onClick={goBackToSelectWallet} aria-label=\"Go back\">\n <ChevronLeft size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n }\n rightAction={\n <Button size=\"sm\" variant=\"close\" onClick={onDismiss} aria-label=\"Close\">\n <X size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n }\n title=\"All Wallets\"\n />\n <Column justify=\"start\" style={{ maxHeight: '22rem', overflowY: 'auto' }}>\n {sortedWallets.map((wallet) => {\n return (\n <WalletButton\n key={wallet.id}\n wallet={wallet}\n connectWallet={connectWallet}\n isLastUsed={wallet.id === lastUsedWalletId}\n />\n );\n })}\n </Column>\n </>\n );\n};\n","import React from 'react';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { Column, Text, Button } from '@src/ui';\nimport { X, SquareArrowOutUpRight, ChevronLeft } from 'lucide-react';\nimport { ModalHeader } from '@src/components/ModalHeader/ModalHeader';\nimport { WalletLogoWrapper } from '@src/components/WalletLogoWrapper/WalletLogoWrapper';\n\n// Fallback page for when on mobile & no provider & no WalletConnect support\nexport const DownloadWalletPage: React.FC = () => {\n const { selectedWallet, goBackToHome } = useConnectModal();\n const { onDismiss } = useWidgetContext();\n\n if (!selectedWallet) {\n return null;\n }\n\n const downloadUrl = selectedWallet.downloadUrl;\n\n const handleDownload = () => {\n if (downloadUrl) {\n window.open(downloadUrl, '_blank', 'noopener,noreferrer');\n }\n };\n\n return (\n <>\n <ModalHeader\n leftAction={\n <Button size=\"sm\" variant=\"close\" onClick={goBackToHome} aria-label=\"Go back\">\n <ChevronLeft size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n }\n rightAction={\n <Button size=\"sm\" variant=\"close\" onClick={onDismiss} aria-label=\"Close\">\n <X size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n }\n title={`Install ${selectedWallet.name}`}\n />\n\n <Column align=\"center\" gap={24} justify=\"center\">\n <WalletLogoWrapper id={selectedWallet.id} size={64} sizeSlot=\"lg\" title={selectedWallet.name} />\n\n <Column align=\"center\" gap={12}>\n <Text size=\"lg\" weight=\"semibold\" align=\"center\">\n Install {selectedWallet.name}\n </Text>\n <Text size=\"md\" variant=\"secondary\" align=\"center\" style={{ maxWidth: '20rem' }}>\n {selectedWallet.name} not installed. Please download then try again.\n </Text>\n </Column>\n\n {downloadUrl && (\n <>\n <Button variant=\"tertiary\" onClick={handleDownload} expand>\n <SquareArrowOutUpRight size={16} color=\"var(--color-foreground-muted)\" />\n <Text size=\"sm\" weight=\"semibold\" variant=\"secondary\">\n Download {selectedWallet.name}\n </Text>\n </Button>\n </>\n )}\n </Column>\n </>\n );\n};\n","import { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { useEmailAuth } from '@src/contexts/EmailAuthContext';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { ModalHeader } from '@src/components/ModalHeader/ModalHeader';\nimport { Button, Column, Row, Text, Spinner } from '@src/ui';\nimport { X, ChevronLeft, Check, CircleCheck } from 'lucide-react';\nimport { OTP_LENGTH, RESEND_COUNTDOWN_SECONDS } from '@src/components/ConnectModal/EmailVerifyOtp/constants';\nimport { getOtpInputStyles, emailHighlightStyles } from '@src/components/ConnectModal/EmailVerifyOtp/styles';\nimport { useCountdown } from '@src/components/ConnectModal/EmailVerifyOtp/useCountdown';\nimport { useOtpInputs } from '@src/components/ConnectModal/EmailVerifyOtp/useOtpInputs';\n\nexport const EmailVerifyOTP = () => {\n const { onDismiss } = useWidgetContext();\n const { goBackToHome } = useConnectModal();\n const { emailAuthState, sendEmailOTP, verifyEmailOTPAndConnect, error, clearError } = useEmailAuth();\n\n const isVerifying = emailAuthState.step === 'connecting' && !error;\n\n const { otp, setOtp, focusedIndex, setFocusedIndex, inputRefs, handleInputChange, handleKeyDown, handlePaste } =\n useOtpInputs({\n emailAuthState,\n error,\n clearError,\n onComplete: verifyEmailOTPAndConnect,\n isVerifying,\n });\n const { canResend, startCountdown } = useCountdown();\n\n const isSuccess = emailAuthState.step === 'success';\n const showOtpInputs = !isVerifying && !isSuccess;\n const canResendOtp = canResend && emailAuthState.step !== 'success';\n\n const handleBackToHome = () => {\n if (emailAuthState.step !== 'otp') return;\n clearError();\n goBackToHome();\n };\n\n const handleResendOTP = async () => {\n if (!canResendOtp) return;\n\n if (error) clearError();\n\n startCountdown(RESEND_COUNTDOWN_SECONDS);\n await sendEmailOTP(emailAuthState.email);\n setOtp(Array(OTP_LENGTH).fill(''));\n inputRefs.current[0]?.focus();\n };\n\n return (\n <div>\n <ModalHeader\n leftAction={\n isSuccess ? null : (\n <Button size=\"sm\" variant=\"close\" onClick={handleBackToHome} aria-label=\"Go back\">\n <ChevronLeft size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n )\n }\n rightAction={\n isSuccess ? null : (\n <Button size=\"sm\" variant=\"close\" onClick={onDismiss} aria-label=\"Close\">\n <X size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n )\n }\n title=\"Verify Email\"\n />\n <Column gap={24}>\n <Text align=\"center\" variant=\"secondary\">\n Enter the 6-digit code sent to\n <br /> <span style={emailHighlightStyles}>{emailAuthState.email}</span>\n </Text>\n <Column align=\"center\" gap={12}>\n <div style={{ position: 'relative', height: '3rem' }}>\n {/* Keep inputs mounted but hidden during verification/success to preserve keyboard */}\n <Row\n justify=\"center\"\n gap={8}\n style={{\n opacity: showOtpInputs ? 1 : 0,\n pointerEvents: showOtpInputs ? 'auto' : 'none',\n position: 'relative',\n }}\n >\n {otp.map((digit, index) => (\n <input\n aria-label=\"OTP input\"\n id={`otp-input-${index}`}\n type=\"text\"\n key={index}\n autoFocus={index === 0}\n maxLength={1}\n value={digit}\n inputMode=\"numeric\"\n onPaste={handlePaste}\n onBlur={() => setFocusedIndex(null)}\n onFocus={() => setFocusedIndex(index)}\n onKeyDown={(e) => handleKeyDown(index, e)}\n ref={(el) => (inputRefs.current[index] = el)}\n style={getOtpInputStyles(focusedIndex === index, !!error, !showOtpInputs)}\n onChange={(e) => handleInputChange(index, e.target.value)}\n />\n ))}\n </Row>\n {/* Overlay spinner/success on top of hidden inputs */}\n {!showOtpInputs && (\n <Column align=\"center\" justify=\"center\" style={{ position: 'absolute', inset: 0 }}>\n {isVerifying ? (\n <Spinner size={32} color=\"var(--aurum-primary-color)\" />\n ) : isSuccess ? (\n <CircleCheck size={46} color=\"var(--aurum-primary-color)\" />\n ) : null}\n </Column>\n )}\n </div>\n <Text\n align=\"center\"\n variant=\"error\"\n size=\"sm\"\n style={{ visibility: error ? 'visible' : 'hidden', height: '1rem', display: isSuccess ? 'none' : 'block' }}\n >\n {error}\n </Text>\n </Column>\n {!isSuccess && (\n <Column align=\"center\" justify=\"center\">\n <Row align=\"center\" justify=\"center\" style={{ minHeight: '2rem' }}>\n {canResend ? (\n <Row align=\"baseline\" gap={2}>\n <Text size=\"sm\" variant=\"secondary\">\n Didn't receive the code?\n </Text>\n <Button\n size=\"sm\"\n variant=\"text\"\n onClick={handleResendOTP}\n onMouseDown={(e) => e.preventDefault()}\n disabled={!canResendOtp}\n >\n Resend\n </Button>\n </Row>\n ) : (\n <Row align=\"center\" gap={4}>\n <Text size=\"sm\" variant=\"secondary\">\n Email re-sent\n </Text>\n <Check size={14} color=\"var(--color-foreground-muted)\" />\n </Row>\n )}\n </Row>\n </Column>\n )}\n </Column>\n </div>\n );\n};\n","export const OTP_LENGTH = 6;\nexport const RESEND_COUNTDOWN_SECONDS = 30;\n","import React from 'react';\n\nexport const getOtpInputStyles = (isFocused: boolean, hasError: boolean, hideCaret: boolean): React.CSSProperties => ({\n width: '2.625rem',\n height: '3rem',\n textAlign: 'center',\n fontFamily: 'inherit',\n fontSize: '1.375rem',\n border: `${hasError || !isFocused ? '0.0625rem' : '0.125rem'} solid ${\n hasError ? 'var(--color-error)' : isFocused ? 'var(--color-border-focus)' : 'var(--color-border-muted)'\n }`,\n borderRadius: 'var(--aurum-border-radius-sm)',\n outline: 'none',\n backgroundColor: 'var(--color-accent)',\n color: 'var(--color-foreground)',\n caretColor: hideCaret ? 'transparent' : 'auto',\n transition: 'border-color 0.3s ease',\n});\n\nexport const emailHighlightStyles: React.CSSProperties = {\n fontWeight: 'bold',\n color: 'var(--color-primary)',\n};\n","import { useState, useEffect } from 'react';\n\ninterface UseCountdownReturn {\n countdown: number;\n canResend: boolean;\n startCountdown: (seconds: number) => void;\n}\n\nexport const useCountdown = (): UseCountdownReturn => {\n const [countdown, setCountdown] = useState(0);\n const [canResend, setCanResend] = useState(true);\n\n const startCountdown = (seconds: number) => {\n setCanResend(false);\n setCountdown(seconds);\n };\n\n useEffect(() => {\n if (countdown <= 0) return;\n\n const timer = setTimeout(() => {\n const newCountdown = countdown - 1;\n setCountdown(newCountdown);\n if (newCountdown === 0) {\n setCanResend(true);\n }\n }, 1000);\n return () => clearTimeout(timer);\n }, [countdown]);\n\n return { countdown, canResend, startCountdown };\n};\n","import { useState, useRef, useEffect } from 'react';\nimport { OTP_LENGTH } from '@src/components/ConnectModal/EmailVerifyOtp/constants';\nimport { EmailAuthState } from '@src/contexts/EmailAuthContext';\n\ninterface UseOtpInputsParams {\n emailAuthState: EmailAuthState;\n error: string;\n clearError: () => void;\n onComplete: (otpString: string) => void;\n isVerifying: boolean;\n}\n\ninterface UseOtpInputsReturn {\n otp: string[];\n setOtp: React.Dispatch<React.SetStateAction<string[]>>;\n focusedIndex: number | null;\n setFocusedIndex: React.Dispatch<React.SetStateAction<number | null>>;\n inputRefs: React.MutableRefObject<(HTMLInputElement | null)[]>;\n handleInputChange: (index: number, value: string) => void;\n handleKeyDown: (index: number, e: React.KeyboardEvent) => void;\n handlePaste: (e: React.ClipboardEvent) => void;\n}\n\nexport const useOtpInputs = ({\n emailAuthState,\n error,\n clearError,\n onComplete,\n isVerifying,\n}: UseOtpInputsParams): UseOtpInputsReturn => {\n const [otp, setOtp] = useState<string[]>(Array(OTP_LENGTH).fill(''));\n const [focusedIndex, setFocusedIndex] = useState<number | null>(0);\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n const isOtpComplete = otp.every((digit) => digit !== '');\n\n const handleInputChange = (index: number, value: string) => {\n if (error) clearError();\n\n if (emailAuthState.step === 'connecting' || !/^\\d*$/.test(value)) return;\n\n const newOtp = [...otp];\n newOtp[index] = value.slice(-1);\n setOtp(newOtp);\n\n // Move to next input, but don't blur on last digit to keep keyboard open if user is on mobile\n if (value && index < OTP_LENGTH - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handleKeyDown = (index: number, e: React.KeyboardEvent) => {\n if (e.key === 'Backspace' && !otp[index] && index > 0) {\n inputRefs.current[index - 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n e.preventDefault();\n\n if (error) clearError();\n\n if (emailAuthState.step === 'connecting' || !/^\\d*$/.test(e.clipboardData.getData('text'))) return;\n\n const pastedData = e.clipboardData.getData('text').replace(/\\D/g, '').slice(0, OTP_LENGTH);\n const newOtp = Array(OTP_LENGTH)\n .fill('')\n .map((_, i) => pastedData[i] || '');\n\n setOtp(newOtp);\n\n // Focus next empty input, or stay on last input to keep keyboard open if user is on mobile\n const nextEmptyIndex = newOtp.findIndex((digit) => !digit);\n if (nextEmptyIndex !== -1) {\n inputRefs.current[nextEmptyIndex]?.focus();\n }\n };\n\n // Auto-verify when OTP is complete\n useEffect(() => {\n if (isOtpComplete && otp.join('').length === OTP_LENGTH) {\n onComplete(otp.join(''));\n }\n }, [otp]);\n\n // Focus first input immediately on mount to trigger keyboard on mobile\n useEffect(() => {\n // Try immediate focus first\n inputRefs.current[0]?.focus();\n // Fallback after focus trap settles (for desktop/non-gesture scenarios)\n const timer = setTimeout(() => {\n inputRefs.current[0]?.focus();\n }, 100);\n return () => clearTimeout(timer);\n }, []);\n\n // Clear OTP inputs and focus first input when error occurs\n useEffect(() => {\n if (error) {\n setOtp(Array(OTP_LENGTH).fill(''));\n inputRefs.current[0]?.focus();\n }\n }, [error]);\n\n // Reset focusedIndex when verifying\n useEffect(() => {\n if (isVerifying) {\n setFocusedIndex(0);\n }\n }, [isVerifying]);\n\n return {\n otp,\n setOtp,\n focusedIndex,\n setFocusedIndex,\n inputRefs,\n handleInputChange,\n handleKeyDown,\n handlePaste,\n };\n};\n","import React from 'react';\nimport { useWidgetContext } from '@src/contexts/WidgetContext';\nimport { useConnectModal } from '@src/contexts/ConnectModalContext';\nimport { Column, Text, Button } from '@src/ui';\nimport { X, AlertTriangle, ChevronLeft } from 'lucide-react';\nimport { ModalHeader } from '@src/components/ModalHeader/ModalHeader';\n\nexport const ConfigErrorPage: React.FC = () => {\n const { onDismiss } = useWidgetContext();\n const { goBackToHome } = useConnectModal();\n\n return (\n <>\n <ModalHeader\n leftAction={\n <Button size=\"sm\" variant=\"close\" onClick={goBackToHome} aria-label=\"Go back\">\n <ChevronLeft size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n }\n rightAction={\n <Button size=\"sm\" variant=\"close\" onClick={onDismiss} aria-label=\"Close\">\n <X size={20} color=\"var(--color-foreground-muted)\" />\n </Button>\n }\n title=\"Error\"\n />\n\n <Column align=\"center\" gap={24} justify=\"center\">\n <div\n style={{\n width: 64,\n height: 64,\n borderRadius: 'var(--aurum-border-radius-md)',\n backgroundColor: 'color-mix(in srgb, var(--color-error) 80%, transparent)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <AlertTriangle size={32} color=\"white\" />\n </div>\n\n <Column align=\"center\" gap={12}>\n <Text size=\"lg\" weight=\"semibold\" align=\"center\">\n Configuration Error\n </Text>\n <Text size=\"md\" variant=\"secondary\" align=\"center\" style={{ maxWidth: '20rem' }}>\n Missing required project ID\n </Text>\n </Column>\n\n <Button variant=\"secondary\" onClick={goBackToHome} expand>\n <Text size=\"sm\" weight=\"semibold\">\n Back\n </Text>\n </Button>\n </Column>\n </>\n );\n};\n","import React from 'react';\n\nimport { SelectWalletPage } from '@src/components/ConnectModal/SelectWallet';\nimport { ConnectionStatusPage } from '@src/components/ConnectModal/ConnectionStatus';\nimport { QRCodePage } from '@src/components/ConnectModal/QRCodePage';\nimport { AllWalletsPage } from '@src/components/ConnectModal/AllWallets';\nimport { DownloadWalletPage } from '@src/components/ConnectModal/DownloadWalletPage';\nimport { EmailVerifyOTP } from '@src/components/ConnectModal/EmailVerifyOtp';\nimport { ConnectionStatusMobilePage } from '@src/components/ConnectModal/ConnectionStatus/Mobile';\nimport { ConfigErrorPage } from '@src/components/ConnectModal/ConfigErrorPage';\n\nexport type PageIdType = (typeof PAGE_IDS)[keyof typeof PAGE_IDS];\n\nexport const PAGE_IDS = {\n SELECT_WALLET: 'select-wallet',\n ALL_WALLETS: 'all-wallets',\n QR_CODE: 'qr-code',\n MOBILE_DEEP_LINK: 'mobile-deep-link',\n DOWNLOAD_WALLET: 'download-wallet',\n CONNECTING: 'connecting',\n EMAIL_VERIFY_OTP: 'email-verify-otp',\n CONFIG_ERROR: 'config-error',\n} as const;\n\nexport const PAGE_COMPONENTS: Record<PageIdType, React.ReactNode> = {\n [PAGE_IDS.SELECT_WALLET]: <SelectWalletPage />,\n [PAGE_IDS.ALL_WALLETS]: <AllWalletsPage />,\n [PAGE_IDS.QR_CODE]: <QRCodePage />,\n [PAGE_IDS.MOBILE_DEEP_LINK]: <ConnectionStatusMobilePage />,\n [PAGE_IDS.DOWNLOAD_WALLET]: <DownloadWalletPage />,\n [PAGE_IDS.CONNECTING]: <ConnectionStatusPage />,\n [PAGE_IDS.EMAIL_VERIFY_OTP]: <EmailVerifyOTP />,\n [PAGE_IDS.CONFIG_ERROR]: <ConfigErrorPage />,\n};\n","type WindowWithAurumListeners = Window & {\n __aurumDeepLinkListeners?: Array<() => void>;\n};\n\nexport interface WalletConnectEventHandlers {\n handleUri: (event: CustomEvent) => void;\n handleDisconnect: () => void;\n}\n\n/**\n * Clear any existing global deep link listeners to prevent interference\n */\nexport const clearExistingDeepLinkListeners = () => {\n const existingListeners = (window as WindowWithAurumListeners).__aurumDeepLinkListeners ?? [];\n existingListeners.forEach((cleanup) => cleanup());\n (window as WindowWithAurumListeners).__aurumDeepLinkListeners = [];\n};\n\n/**\n * Create event handlers for WalletConnect deep linking\n * @param deepLinkBaseUrl - Base URL for wallet deep linking\n * @param onRejection - Callback when connection is rejected\n */\nexport const createWalletConnectHandlers = (\n deepLinkBaseUrl: string | null,\n onRejection: () => void,\n): WalletConnectEventHandlers => {\n const handleUri = (event: CustomEvent) => {\n const uri = event.detail.uri;\n if (uri && deepLinkBaseUrl) {\n const deepLinkUrl = `${deepLinkBaseUrl}${encodeURIComponent(uri)}`;\n window.location.href = deepLinkUrl;\n }\n };\n\n const handleDisconnect = () => {\n onRejection();\n };\n\n return { handleUri, handleDisconnect };\n};\n\n/**\n * Register event listeners and setup cleanup function\n * @param handlers - WalletConnect event handlers\n * @returns Cleanup function to remove all event listeners\n */\nexport const setupEventListeners = (handlers: WalletConnectEventHandlers): (() => void) => {\n const { handleUri, handleDisconnect } = handlers;\n\n window.addEventListener('walletconnect:uri', handleUri as EventListener);\n window.addEventListener('walletconnect:disconnect', handleDisconnect as EventListener);\n\n return () => {\n window.removeEventListener('walletconnect:uri', handleUri as EventListener);\n window.removeEventListener('walletconnect:disconnect', handleDisconnect as EventListener);\n };\n};\n\n/**\n * Register cleanup function globally for multi-instance management\n * @param cleanupFn - Cleanup function to register\n * @returns Global cleanup function that includes the provided cleanup\n */\nexport const registerGlobalCleanup = (cleanupFn: () => void): (() => void) => {\n if (!(window as WindowWithAurumListeners).__aurumDeepLinkListeners) {\n (window as WindowWithAurumListeners).__aurumDeepLinkListeners = [];\n }\n\n const cleanup = () => {\n const cleanupList = (window as WindowWithAurumListeners).__aurumDeepLinkListeners ?? [];\n const index = cleanupList.indexOf(cleanup);\n if (index > -1) cleanupList.splice(index, 1);\n cleanupFn();\n };\n\n (window as WindowWithAurumListeners).__aurumDeepLinkListeners?.push(cleanup);\n return cleanup;\n};\n","import { PAGE_IDS, PageIdType } from '@src/components/ConnectModal/PageIds';\nimport { WalletAdapter, WalletConnectionResult } from '@src/types/internal';\nimport { useNavigation } from '@src/contexts/NavigationContext';\nimport {\n clearExistingDeepLinkListeners,\n createWalletConnectHandlers,\n setupEventListeners,\n registerGlobalCleanup,\n} from '@src/utils/walletConnectDeepLink';\nimport { WalletId } from '@aurum-sdk/types';\nimport { isConfigError } from '@src/utils/isConfigError';\nimport { sentryLogger } from '@src/services/sentry';\n\ninterface ResolvePayloadProps {\n adapter: WalletAdapter;\n displayedWallets?: WalletAdapter[];\n onConnect: (payload: WalletConnectionResult) => void;\n navigateTo?: (pageId: PageIdType) => void;\n setSuccess?: (success: boolean) => void;\n}\n\nexport const useConnectSelectedWallet = () => {\n const { navigateTo } = useNavigation();\n\n const connectInstalledWallet = async ({ adapter, onConnect, setSuccess }: ResolvePayloadProps) => {\n navigateTo(PAGE_IDS.CONNECTING);\n\n try {\n const { address, provider } = await adapter.connect();\n\n setSuccess?.(true);\n\n setTimeout(() => {\n onConnect({ walletId: adapter.id, address, provider });\n }, 1000);\n } catch (error) {\n if (isConfigError(error)) {\n navigateTo(PAGE_IDS.CONFIG_ERROR);\n return;\n }\n throw error;\n }\n };\n\n const connectUninstalledWalletQRCode = async ({ displayedWallets, onConnect, setSuccess }: ResolvePayloadProps) => {\n const walletConnectAdapter = displayedWallets?.find(({ id }) => id === WalletId.WalletConnect);\n if (!walletConnectAdapter) {\n sentryLogger.error('connectUninstalledWalletQRCode: WalletConnect adapter not found');\n throw new Error('WalletConnect adapter not found');\n }\n\n navigateTo(PAGE_IDS.QR_CODE);\n\n try {\n const { address, provider } = await walletConnectAdapter.connect();\n\n setSuccess?.(true);\n\n setTimeout(() => {\n onConnect({ walletId: walletConnectAdapter.id, address, provider });\n }, 1000);\n } catch (error) {\n if (isConfigError(error)) {\n navigateTo(PAGE_IDS.CONFIG_ERROR);\n return;\n }\n throw error;\n }\n };\n\n const connectWithMobileDeepLink = async ({\n displayedWallets,\n adapter,\n onConnect,\n setSuccess,\n }: ResolvePayloadProps) => {\n const walletConnectAdapter = displayedWallets?.find(({ id }) => id === WalletId.WalletConnect);\n if (!walletConnectAdapter) {\n sentryLogger.error('connectWithMobileDeepLink: WalletConnect adapter not found');\n throw new Error('WalletConnect adapter not found');\n }\n\n let isRejected = false;\n\n clearExistingDeepLinkListeners();\n\n const handlers = createWalletConnectHandlers(adapter.wcDeepLinkUrl, () => {\n isRejected = true;\n });\n\n const cleanupEventListeners = setupEventListeners(handlers);\n const cleanupGlobal = registerGlobalCleanup(cleanupEventListeners);\n\n try {\n navigateTo(PAGE_IDS.MOBILE_DEEP_LINK);\n\n const { address, provider } = await walletConnectAdapter.connect();\n\n cleanupGlobal();\n\n if (isRejected) {\n return;\n }\n\n setSuccess?.(true);\n\n setTimeout(() => {\n onConnect({ walletId: walletConnectAdapter.id, address, provider });\n }, 1000);\n } catch (error) {\n cleanupGlobal();\n if (isConfigError(error)) {\n navigateTo(PAGE_IDS.CONFIG_ERROR);\n return;\n }\n throw error;\n }\n };\n\n const connectAppKit = async ({ adapter, onConnect, setSuccess }: ResolvePayloadProps) => {\n try {\n const { address, provider } = await adapter.connect();\n setSuccess?.(true);\n setTimeout(() => {\n onConnect({ walletId: adapter.id, address, provider });\n }, 1000);\n } catch (error) {\n if (isConfigError(error)) {\n navigateTo(PAGE_IDS.CONFIG_ERROR);\n return;\n }\n // ignore - user rejected or closed AppKit modal\n }\n };\n\n const redirectToDownloadPage = async () => {\n navigateTo(PAGE_IDS.DOWNLOAD_WALLET);\n };\n\n return {\n // Both mobile and desktop\n connectInstalledWallet,\n connectAppKit,\n redirectToDownloadPage,\n\n // Desktop only\n connectUninstalledWalletQRCode,\n\n // Mobile only\n connectWithMobileDeepLink,\n };\n};\n","import React, { ReactNode } from 'react';\nimport { NavigationProvider } from '@src/contexts/NavigationContext';\nimport { ConnectModalProvider } from '@src/contexts/ConnectModalContext';\nimport { PAGE_IDS } from '@src/components/ConnectModal/PageIds';\nimport { WalletAdapter, WalletConnectionResult } from '@src/types/internal';\n\ninterface ConnectUIProvidersProps {\n children: ReactNode;\n onConnect: (result: WalletConnectionResult) => void;\n displayedWallets: WalletAdapter[];\n}\n\n/**\n * Shared provider stack for wallet connection UI.\n *\n * Wraps NavigationProvider and ConnectModalProvider (which includes EmailAuthProvider).\n * Used by both renderConnectModal and ConnectWidget for consistent behavior.\n *\n * ## Hierarchy\n * ```\n * ConnectUIProviders\n * └── NavigationProvider (page routing)\n * └── ConnectModalProvider (connection logic)\n * └── EmailAuthProvider (email auth state)\n * └── {children}\n * ```\n */\nexport const ConnectUIProviders: React.FC<ConnectUIProvidersProps> = ({ children, onConnect, displayedWallets }) => (\n <NavigationProvider initialPage={PAGE_IDS.SELECT_WALLET}>\n <ConnectModalProvider onConnect={onConnect} displayedWallets={displayedWallets}>\n {children}\n </ConnectModalProvider>\n </NavigationProvider>\n);\n","import React from 'react';\nimport { useNavigation } from '@src/contexts/NavigationContext';\nimport { PAGE_IDS, PAGE_COMPONENTS } from '@src/components/ConnectModal/PageIds';\n\n/**\n * Shared page renderer for both Modal and Widget modes.\n *\n * Renders the current page based on NavigationContext.\n * Used by both ModalShell and WidgetShell.\n */\nexport const ConnectPages: React.FC = () => {\n const { currentPage } = useNavigation();\n\n return PAGE_COMPONENTS[currentPage] || PAGE_COMPONENTS[PAGE_IDS.SELECT_WALLET];\n};\n","/**\n * Auto-generated file containing all SDK styles bundled as a string.\n * This file is generated by scripts/bundle-css.js\n * DO NOT EDIT MANUALLY\n */\nexport const bundledStyles = \"/* ui/globals.css */\\n/* ============================================\\n AURUM SDK - DESIGN TOKEN SYSTEM\\n ============================================\\n\\n Google Fonts:\\n - Noto Sans: 400, 500, 600, 700\\n ============================================ */\\n\\n@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');\\n\\n/* ============================================\\n External variables (injected by createShadowRoot.ts):\\n - --aurum-primary-color: Brand color from dapp\\n - --aurum-border-radius-*: Radius scale tokens\\n - --aurum-modal-z-index: Modal z-index\\n - --aurum-font-family: Font family from dapp\\n ============================================ */\\n\\n/* Base reset styles for Shadow DOM */\\n:host {\\n all: initial;\\n}\\n\\n*,\\n*::before,\\n*::after {\\n box-sizing: border-box;\\n}\\n\\n/* Ensure form elements inherit font from parent */\\ninput,\\nbutton,\\ntextarea,\\nselect {\\n font-family: inherit;\\n}\\n\\n.aurum-sdk {\\n /* ==========================================\\n TYPOGRAPHY\\n ========================================== */\\n font-family: var(--aurum-font-family);\\n font-size: 1rem;\\n line-height: 1.5;\\n -webkit-font-smoothing: antialiased;\\n -moz-osx-font-smoothing: grayscale;\\n\\n /* Font weights */\\n --font-normal: 400;\\n --font-medium: 500;\\n --font-semibold: 600;\\n --font-bold: 700;\\n\\n /* ==========================================\\n TRANSITIONS\\n ========================================== */\\n --duration-fast: 100ms;\\n --duration-normal: 200ms;\\n --duration-slow: 300ms;\\n --ease-default: cubic-bezier(0.4, 0, 0.2, 1);\\n --ease-in: cubic-bezier(0.4, 0, 1, 1);\\n --ease-out: cubic-bezier(0, 0, 0.2, 1);\\n\\n /* ==========================================\\n LIGHT THEME COLORS (Default)\\n ========================================== */\\n\\n /* Foreground / Text */\\n --color-foreground: #0c0c0c;\\n --color-foreground-muted: #787878;\\n --color-foreground-subtle: #979797;\\n\\n /* Card surfaces */\\n --color-card: #ffffff;\\n\\n /* Borders */\\n --color-border: #d9d9d9;\\n --color-border-muted: #c0c0c0;\\n --color-border-focus: var(--aurum-primary-color);\\n\\n /* Brand / Primary (from integrator) */\\n --color-primary: var(--aurum-primary-color);\\n --color-primary-foreground: #ffffff;\\n --color-primary-hover: color-mix(in srgb, var(--aurum-primary-color) 85%, #000);\\n --color-primary-muted: color-mix(in srgb, var(--aurum-primary-color) 15%, transparent);\\n\\n /* Interactive elements */\\n --color-accent: #f1f1f1;\\n --color-accent-foreground: #0d0d0d;\\n --color-accent-hover: #e6e6e6;\\n\\n /* Semantic colors */\\n --color-success: #22c55e;\\n --color-error: #ef4444;\\n\\n /* Overlay / Modal */\\n --color-overlay: rgb(0 0 0 / 0.5);\\n\\n /* Ring (focus indicator) */\\n --color-ring: var(--aurum-primary-color);\\n --ring-offset: 0.125rem;\\n\\n /* Shadows */\\n --shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\\n}\\n\\n/* ==========================================\\n DARK THEME COLORS\\n ========================================== */\\n\\n.aurum-sdk[data-theme='dark'] {\\n /* Foreground / Text */\\n --color-foreground: #fafafa;\\n --color-foreground-muted: #a9a9a9;\\n --color-foreground-subtle: #777777;\\n\\n /* Card surfaces */\\n --color-card: #151515;\\n\\n /* Borders */\\n --color-border: #282828;\\n --color-border-muted: #424242;\\n --color-border-focus: var(--aurum-primary-color);\\n\\n /* Brand / Primary (from integrator) */\\n --color-primary: var(--aurum-primary-color);\\n --color-primary-foreground: #0a0a0a;\\n --color-primary-hover: color-mix(in srgb, var(--aurum-primary-color) 85%, #fff);\\n --color-primary-muted: color-mix(in srgb, var(--aurum-primary-color) 20%, transparent);\\n\\n /* Interactive elements */\\n --color-accent: #272727;\\n --color-accent-foreground: #fafafa;\\n --color-accent-hover: #404040;\\n\\n /* Semantic colors */\\n --color-success: #22c55e;\\n --color-error: #ef4444;\\n\\n /* Overlay / Modal */\\n --color-overlay: rgb(0 0 0 / 0.7);\\n\\n /* Ring (focus indicator) */\\n --color-ring: var(--aurum-primary-color);\\n --ring-offset: 0.125rem;\\n\\n /* Shadows */\\n --shadow: 0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.5);\\n}\\n\\n\\n/* components/ConnectModal/AdditionalWalletsIcon.css */\\n.additional-wallets-container {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n\\n.additional-wallets-grid {\\n display: grid;\\n grid-template-columns: 1fr 1fr;\\n grid-template-rows: 1fr 1fr;\\n gap: 0.125rem;\\n align-items: center;\\n justify-items: center;\\n}\\n\\n.additional-wallets-grid-item {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n\\n.additional-wallets-placeholder {\\n background-color: var(--aurum-color-bg-tertiary);\\n border-radius: var(--aurum-border-radius-xs);\\n opacity: 0.4;\\n}\\n\\n.circular-icon-wrapper {\\n border-radius: 50%;\\n overflow: hidden;\\n border: 2px solid var(--aurum-color-bg-secondary);\\n}\\n\\n.circular-icon-wrapper--front {\\n z-index: 2;\\n}\\n\\n.circular-icon-wrapper--back {\\n margin-left: -0.5rem;\\n z-index: 1;\\n}\\n\\n\\n/* components/ConnectModal/ConnectionStatus/ConnectionStatus.css */\\n@keyframes shake {\\n 0%,\\n 100% {\\n transform: translateX(0);\\n }\\n 20%,\\n 60% {\\n transform: translateX(-0.125rem);\\n }\\n 40%,\\n 80% {\\n transform: translateX(0.125rem);\\n }\\n}\\n\\n@keyframes opacity-pulse {\\n 0%,\\n 100% {\\n opacity: 0.4;\\n }\\n 50% {\\n opacity: 1;\\n }\\n}\\n\\n@keyframes scale-in {\\n from {\\n transform: scale(0.75);\\n }\\n to {\\n transform: scale(1);\\n }\\n}\\n\\n.wallet-icon-shake {\\n /* Duration synced with ANIMATION_DURATION.SHAKE in constants/theme.ts */\\n animation: shake var(--duration-slow) var(--ease-default);\\n}\\n\\n.ellipses-loading,\\n.ellipses-success,\\n.status-icon-with-dots {\\n display: flex;\\n gap: 0.25rem;\\n align-items: center;\\n justify-content: center;\\n width: 100%;\\n}\\n\\n.ellipses-loading span,\\n.ellipses-success span,\\n.status-icon-with-dots .dot,\\n.status-icon-with-dots .icon-center {\\n font-size: 3rem;\\n line-height: 1;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n width: 0.9375rem;\\n height: 3rem;\\n margin: 0;\\n padding: 0;\\n flex-shrink: 0;\\n}\\n\\n.ellipses-loading span,\\n.ellipses-success span,\\n.status-icon-with-dots .dot {\\n transform: translateY(-0.28125rem);\\n}\\n\\n.status-icon-with-dots .icon-center {\\n transform: translateY(-0.2rem);\\n}\\n\\n.ellipses-loading span {\\n color: var(--color-foreground-subtle);\\n opacity: 0.4;\\n animation: opacity-pulse 1.5s var(--ease-default) infinite;\\n will-change: opacity;\\n}\\n\\n.ellipses-loading span:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.ellipses-loading span:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n.ellipses-loading span:nth-child(4) {\\n animation-delay: 0.6s;\\n}\\n.ellipses-loading span:nth-child(5) {\\n animation-delay: 0.8s;\\n}\\n\\n.ellipses-success span,\\n.status-icon-with-dots.success .dot {\\n color: var(--aurum-primary-color);\\n}\\n\\n.status-icon-with-dots.error .dot {\\n color: var(--color-error);\\n}\\n\\n.status-button {\\n display: flex;\\n align-items: flex-start;\\n justify-content: center;\\n width: 100%;\\n}\\n\\n.success-icon-large {\\n animation: scale-in var(--duration-fast) var(--ease-out);\\n}\\n\\n/* Logo containers for visual balance */\\n.brand-logo-container,\\n.wallet-logo-with-retry {\\n position: relative;\\n display: inline-block;\\n}\\n\\n/* Always reserve space on both sides to prevent layout shift when retry button appears/disappears */\\n.brand-logo-container {\\n margin-left: 0.375rem; /* Matches retry button's right: -0.375rem */\\n}\\n\\n.wallet-logo-with-retry {\\n margin-right: 0.375rem; /* Reserve space for retry button */\\n}\\n\\n.retry-icon-overlay.retry-icon-overlay {\\n position: absolute;\\n bottom: -0.125rem;\\n right: -0.375rem;\\n width: 1.625rem;\\n height: 1.625rem;\\n min-width: 1.625rem;\\n min-height: 1.625rem;\\n border-radius: 50%;\\n padding: 0;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n\\n\\n/* components/ConnectModal/EmailAuth.css */\\n.email-auth-input {\\n width: 100%;\\n outline: none;\\n font-family: inherit;\\n font-size: 1rem;\\n line-height: 1.75rem;\\n box-sizing: border-box;\\n padding: 0.75rem 3rem 0.75rem 3rem;\\n color: var(--color-foreground);\\n transition:\\n outline 0.2s ease,\\n border-color 0.2s ease;\\n background-color: var(--color-card);\\n border-width: 1px;\\n border-style: solid;\\n border-color: var(--color-border);\\n border-radius: var(--aurum-border-radius-md);\\n}\\n\\n.email-auth-input:hover:not(:focus):not(.email-auth-input--error) {\\n border-color: var(--color-border-muted);\\n}\\n\\n.email-auth-input:focus {\\n outline: 2px solid var(--color-ring);\\n outline-offset: var(--ring-offset);\\n}\\n\\n.email-auth-input--error {\\n outline: 2px solid var(--color-error);\\n outline-offset: var(--ring-offset);\\n}\\n\\n.email-auth-submit-button.aurum-button {\\n top: 50%;\\n right: 0.75rem;\\n height: auto;\\n padding: 0.5rem;\\n min-width: auto;\\n position: absolute;\\n transform: translateY(-50%);\\n border-radius: var(--aurum-border-radius-sm);\\n}\\n\\n.email-auth-icon {\\n top: 50%;\\n left: 1rem;\\n position: absolute;\\n transform: translateY(-50%);\\n display: flex;\\n align-items: center;\\n pointer-events: none;\\n}\\n\\n\\n/* components/ConnectModal/WalletGrid.css */\\n.aurum-wallet-grid {\\n display: grid;\\n grid-template-columns: repeat(var(--grid-columns, 3), 1fr);\\n gap: 10px;\\n width: 100%;\\n}\\n\\n\\n/* components/ModalHeader/ModalHeader.css */\\n.modal-header {\\n position: absolute;\\n top: 0;\\n left: 0;\\n right: 0;\\n padding: 1rem;\\n background-color: var(--color-card);\\n border-radius: var(--aurum-border-radius-lg) var(--aurum-border-radius-lg) 0 0;\\n z-index: 1;\\n display: grid;\\n grid-template-columns: 1fr auto 1fr;\\n align-items: center;\\n}\\n\\n.modal-header > div {\\n display: flex;\\n align-items: center;\\n width: 100%;\\n}\\n\\n.modal-header-left {\\n justify-content: flex-start;\\n min-width: 2.25rem;\\n height: 2.25rem;\\n}\\n\\n.modal-header-center {\\n justify-content: center;\\n max-width: 12.5rem;\\n text-align: center;\\n line-height: 1.2;\\n overflow-wrap: break-word;\\n}\\n\\n.modal-header-right {\\n justify-content: flex-end;\\n min-width: 2.25rem;\\n height: 2.25rem;\\n}\\n\\n\\n/* components/PoweredBy/PoweredBy.css */\\n.powered-by-container {\\n position: absolute;\\n bottom: 1rem;\\n left: 0;\\n right: 0;\\n width: 100%;\\n}\\n\\n\\n/* components/QRCodeDisplay/QRCodeDisplay.css */\\n@keyframes qr-shimmer {\\n 0% {\\n transform: translateX(-100%);\\n }\\n 100% {\\n transform: translateX(100%);\\n }\\n}\\n\\n.qr-container-shimmer {\\n position: relative;\\n overflow: hidden; /* Keep for shimmer animation */\\n}\\n\\n.qr-container-shimmer::before {\\n content: '';\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n background: linear-gradient(\\n 90deg,\\n transparent 0%,\\n color-mix(in srgb, var(--color-foreground) 10%, transparent) 50%,\\n transparent 100%\\n );\\n animation: qr-shimmer 2s infinite;\\n pointer-events: none;\\n z-index: 1;\\n}\\n\\n.qr-container {\\n border-radius: var(--aurum-border-radius-md);\\n border: 1px solid var(--color-border);\\n padding: 0.5rem;\\n box-sizing: content-box;\\n transition: border-color var(--duration-slow) var(--ease-default);\\n}\\n\\n.qr-subtitle {\\n max-width: 15rem;\\n}\\n\\n\\n/* components/QRCodeDisplay/QRCodeSkeleton.css */\\n.qr-skeleton-container {\\n width: 100%;\\n position: relative;\\n}\\n\\n.qr-skeleton-svg {\\n display: block;\\n position: relative;\\n z-index: 2;\\n border-radius: var(--aurum-border-radius-sm);\\n}\\n\\n.qr-skeleton-dot {\\n opacity: 0.7;\\n}\\n\\n.qr-skeleton-eye {\\n opacity: 0.7;\\n}\\n\\n\\n/* components/SpinnerWithIcon/SpinnerWithIcon.css */\\n.spinner-with-icon {\\n transition: all var(--duration-normal) var(--ease-default);\\n}\\n\\n.spinner-with-icon svg {\\n transition: color var(--duration-normal) var(--ease-default);\\n}\\n\\n\\n/* components/widgets/widgets.css */\\n/* Widget-specific styles that match modal-content */\\n\\n.widget-provider {\\n position: relative;\\n width: 23.75rem;\\n min-width: 17rem;\\n margin: 0 auto;\\n padding: 1.25rem 1.5rem;\\n background-color: var(--color-card);\\n border-radius: var(--aurum-border-radius-lg);\\n border: 1px solid var(--color-border-muted);\\n box-sizing: border-box;\\n color: var(--color-card-foreground);\\n box-shadow: var(--shadow);\\n outline: none;\\n overflow-x: auto;\\n}\\n\\n.widget-provider .modal-header {\\n position: absolute;\\n top: 0;\\n left: 0;\\n right: 0;\\n}\\n\\n@media (max-width: 30.25rem) {\\n .widget-provider {\\n width: 100%;\\n max-width: 100%;\\n border-radius: var(--aurum-border-radius-md);\\n display: flex;\\n flex-direction: column;\\n }\\n\\n /* Ensure page wrapper fills width in flex container on mobile */\\n /* .widget-pages {\\n width: 100%;\\n } */\\n}\\n\\n\\n/* ui/Badge/Badge.css */\\n.aurum-badge-recent {\\n padding: 0.25rem 0.5rem;\\n border-radius: var(--aurum-border-radius-xs);\\n\\n font-size: 0.65rem;\\n line-height: 1;\\n letter-spacing: 0.07em;\\n text-transform: uppercase;\\n\\n color: var(--color-foreground-muted);\\n}\\n\\n\\n/* ui/Button/Button.css */\\n.aurum-button {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border: none;\\n font-weight: var(--font-semibold);\\n cursor: pointer;\\n transition:\\n background-color var(--duration-normal) var(--ease-default),\\n color var(--duration-normal) var(--ease-default),\\n transform var(--duration-fast) var(--ease-default),\\n box-shadow var(--duration-normal) var(--ease-default);\\n text-decoration: none;\\n box-sizing: border-box;\\n position: relative;\\n outline: none;\\n font-family: inherit;\\n}\\n\\n.aurum-button:focus-visible {\\n outline: 2px solid var(--color-ring);\\n outline-offset: var(--ring-offset);\\n}\\n\\n.aurum-button--xs {\\n padding: 0.25rem 0.5rem;\\n font-size: 0.75rem;\\n gap: 0.25rem;\\n border-radius: var(--aurum-border-radius-xs);\\n}\\n\\n.aurum-button--sm {\\n padding: 0.5rem 0.75rem;\\n font-size: 0.875rem;\\n gap: 0.25rem;\\n border-radius: calc(var(--aurum-border-radius-sm) - 2px);\\n}\\n\\n.aurum-button--md {\\n padding: 0.75rem 1rem;\\n font-size: 0.9rem;\\n gap: 0.5rem;\\n border-radius: calc(var(--aurum-border-radius-md) - 2px);\\n}\\n\\n.aurum-button--lg {\\n padding: 1rem 1.5rem;\\n font-size: 1rem;\\n gap: 0.75rem;\\n border-radius: var(--aurum-border-radius-md);\\n}\\n\\n.aurum-button--full-width {\\n width: 100%;\\n}\\n\\n.aurum-button--primary {\\n background-color: var(--color-primary);\\n color: var(--color-primary-foreground);\\n}\\n\\n.aurum-button--primary:active:not(:disabled) {\\n transform: scale(0.98);\\n}\\n\\n.aurum-button--secondary {\\n background-color: var(--color-accent);\\n color: var(--color-accent-foreground);\\n}\\n\\n.aurum-button--secondary:active:not(:disabled) {\\n transform: scale(0.98);\\n}\\n\\n.aurum-button--tertiary {\\n background: transparent;\\n color: var(--color-foreground);\\n border: 1px solid var(--color-border);\\n}\\n\\n.aurum-button--tertiary:active:not(:disabled) {\\n transform: scale(0.98);\\n}\\n\\n.aurum-button--text {\\n background: transparent;\\n color: var(--color-primary);\\n padding: 0.25rem;\\n}\\n\\n.aurum-button--text:not(.aurum-button--full-width) {\\n width: fit-content;\\n}\\n\\n.aurum-button--text:active:not(:disabled) {\\n transform: scale(0.98);\\n}\\n\\n.aurum-button--close {\\n background: transparent;\\n color: var(--color-foreground-muted);\\n border: none;\\n padding: 0.5rem;\\n border-radius: var(--aurum-border-radius-md);\\n font-size: 1.25rem;\\n line-height: 1;\\n}\\n\\n.aurum-button--close:active:not(:disabled) {\\n transform: scale(0.95);\\n}\\n\\n/* Hover styles only for devices with hover capability (not touch) */\\n@media (hover: hover) {\\n .aurum-button--primary:hover:not(:disabled) {\\n background-color: var(--color-primary-hover);\\n }\\n\\n .aurum-button--secondary:hover:not(:disabled) {\\n background-color: var(--color-accent-hover);\\n }\\n\\n .aurum-button--tertiary:hover:not(:disabled) {\\n background-color: var(--color-accent);\\n border-color: var(--color-border-muted);\\n }\\n\\n .aurum-button--text:hover:not(:disabled) {\\n opacity: 0.7;\\n }\\n\\n .aurum-button--close:hover:not(:disabled) {\\n background-color: var(--color-accent);\\n color: var(--color-foreground);\\n }\\n}\\n\\n.aurum-button--disabled,\\n.aurum-button:disabled {\\n opacity: 0.5;\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\n.aurum-button--loading {\\n pointer-events: none;\\n}\\n\\n\\n/* ui/Divider/Divider.css */\\n.divider {\\n display: flex;\\n align-items: center;\\n width: 100%;\\n}\\n\\n.divider-line {\\n flex: 1;\\n height: 1px;\\n background-color: var(--color-border);\\n}\\n\\n.divider-text {\\n padding: 0 1rem;\\n color: var(--color-foreground-subtle);\\n font-size: 0.875rem;\\n font-weight: var(--font-medium);\\n}\\n\\n\\n/* ui/Modal/Modal.css */\\n.modal-overlay {\\n position: fixed;\\n inset: 0;\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n z-index: var(--aurum-modal-z-index);\\n background-color: var(--color-overlay);\\n opacity: 0;\\n}\\n\\n.modal-overlay.modal-open {\\n opacity: 1;\\n transition: opacity 150ms ease-out;\\n}\\n\\n.modal-overlay.modal-exiting {\\n opacity: 0;\\n transition: opacity 150ms ease-in;\\n}\\n\\n.modal-content {\\n position: relative;\\n width: 23.75rem;\\n min-width: 17rem;\\n padding: 1.25rem 1.5rem;\\n color: var(--color-card-foreground);\\n background-color: var(--color-card);\\n border-radius: var(--aurum-border-radius-lg);\\n box-shadow: var(--shadow);\\n border: 1px solid var(--color-border-muted);\\n outline: none;\\n opacity: 0;\\n transform: scale(0.95);\\n}\\n\\n.modal-overlay.modal-open .modal-content {\\n opacity: 1;\\n transform: scale(1);\\n transition:\\n opacity 150ms ease-out,\\n transform 150ms ease-out;\\n}\\n\\n.modal-overlay.modal-exiting .modal-content {\\n opacity: 0;\\n transform: scale(0.95);\\n transition:\\n opacity 150ms ease-in,\\n transform 150ms ease-in;\\n}\\n\\n.modal-page-container {\\n position: relative;\\n width: 100%;\\n overflow-x: visible;\\n overflow-y: auto;\\n scrollbar-width: none;\\n -ms-overflow-style: none;\\n}\\n\\n.modal-page-container::-webkit-scrollbar {\\n display: none;\\n}\\n\\n.modal-page {\\n position: relative;\\n width: 100%;\\n box-sizing: border-box;\\n opacity: 0;\\n transition: opacity 0s;\\n}\\n\\n.modal-page.active {\\n opacity: 1;\\n transition: opacity var(--duration-slow) var(--ease-out);\\n}\\n\\n/* Mobile drawer layout */\\n@media (max-width: 30.25rem) {\\n .modal-overlay {\\n align-items: flex-end;\\n justify-content: center;\\n opacity: 1;\\n transition: none;\\n }\\n\\n .modal-overlay.modal-open {\\n transition: none;\\n }\\n\\n .modal-overlay.modal-exiting {\\n opacity: 1;\\n background-color: transparent;\\n transition: none;\\n }\\n\\n .modal-content {\\n width: 100%;\\n max-height: 82vh;\\n max-height: 82dvh;\\n min-height: 35vh;\\n min-height: 35dvh;\\n padding: 1rem;\\n border-radius: var(--aurum-border-radius-lg) var(--aurum-border-radius-lg) 0 0;\\n border-bottom: none;\\n display: flex;\\n flex-direction: column;\\n height: auto;\\n opacity: 1;\\n transform: translateY(100%);\\n }\\n\\n .modal-overlay.modal-open .modal-content {\\n opacity: 1;\\n transform: translateY(0);\\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\\n }\\n\\n .modal-overlay.modal-exiting .modal-content {\\n opacity: 1;\\n transform: translateY(100%);\\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\\n }\\n\\n .modal-page-container {\\n flex: 0 1 auto;\\n display: flex;\\n flex-direction: column;\\n overflow-y: auto;\\n }\\n\\n .modal-page {\\n flex: 0 1 auto;\\n display: flex;\\n flex-direction: column;\\n }\\n}\\n\\n\\n/* ui/Spinner/Spinner.css */\\n.spinner {\\n flex-shrink: 0;\\n animation: spinner-rotate 1s linear infinite;\\n}\\n\\n@keyframes spinner-rotate {\\n from {\\n transform: rotate(0deg);\\n }\\n to {\\n transform: rotate(360deg);\\n }\\n}\\n\\n\\n/* ui/Text/Text.css */\\n.aurum-text {\\n margin: 0;\\n padding: 0;\\n font-family: inherit;\\n line-height: 1.5;\\n}\\n\\n.aurum-text--primary {\\n color: var(--color-foreground);\\n}\\n\\n.aurum-text--secondary {\\n color: var(--color-foreground-muted);\\n}\\n\\n.aurum-text--tertiary {\\n color: var(--color-foreground-subtle);\\n}\\n\\n.aurum-text--error {\\n color: var(--color-error);\\n}\\n\\n.aurum-text--brand {\\n color: var(--color-primary);\\n}\\n\\n.aurum-text--success {\\n color: var(--color-success);\\n}\\n\\n.aurum-text--xs {\\n font-size: 0.75rem;\\n line-height: 1.4;\\n}\\n\\n.aurum-text--sm {\\n font-size: 0.875rem;\\n line-height: 1.45;\\n}\\n\\n.aurum-text--md {\\n font-size: 1rem;\\n line-height: 1.5;\\n}\\n\\n.aurum-text--lg {\\n font-size: 1.125rem;\\n line-height: 1.5;\\n}\\n\\n.aurum-text--normal {\\n font-weight: var(--font-normal);\\n}\\n\\n.aurum-text--semibold {\\n font-weight: var(--font-semibold);\\n}\\n\\n.aurum-text--bold {\\n font-weight: var(--font-bold);\\n}\\n\\n.aurum-text--align-left {\\n text-align: left;\\n}\\n\\n.aurum-text--align-center {\\n text-align: center;\\n}\\n\\n.aurum-text--align-right {\\n text-align: right;\\n}\\n\\n\\n\";\n","import { NonNullableBrandConfig } from '@aurum-sdk/types';\nimport { getBorderRadiusScale, DEFAULT_FONT } from '@src/constants/theme';\nimport { bundledStyles } from '@src/styles/bundledStyles';\n\nfunction generateBrandCssVariables(brandConfig: NonNullableBrandConfig): string {\n const r = getBorderRadiusScale(brandConfig.borderRadius);\n const fontFamily = brandConfig.font === DEFAULT_FONT ? brandConfig.font : `${brandConfig.font}, ${DEFAULT_FONT}`;\n\n return `\n .aurum-sdk {\n --aurum-primary-color: ${brandConfig.primaryColor};\n --aurum-border-radius-xs: ${r.xs}px;\n --aurum-border-radius-sm: ${r.sm}px;\n --aurum-border-radius-md: ${r.md}px;\n --aurum-border-radius-lg: ${r.lg}px;\n --aurum-border-radius-xl: ${r.xl}px;\n --aurum-border-radius: ${r.md}px;\n --aurum-modal-z-index: ${brandConfig.modalZIndex};\n --aurum-font-family: ${fontFamily};\n }\n `;\n}\n\nexport function generateCompleteStyles(brandConfig: NonNullableBrandConfig): string {\n return `${bundledStyles}\\n${generateBrandCssVariables(brandConfig)}`;\n}\n"]}
@@ -751,12 +751,12 @@ function getEnvironment() {
751
751
  }
752
752
  function initSentry(enabled = true) {
753
753
  telemetryEnabled = enabled;
754
- if (initialized || !telemetryEnabled || true) return;
754
+ if (initialized || !telemetryEnabled || false) return;
755
755
  initialized = true;
756
756
  Sentry.init({
757
- dsn: "",
757
+ dsn: "https://0bb16fd7057ac7b45ae0ab416cdbea8b@o4505953815494656.ingest.us.sentry.io/4509747448184832",
758
758
  environment: getEnvironment(),
759
- release: `@aurum-sdk/core@${"0.1.0"}`,
759
+ release: `@aurum-sdk/core@${"0.1.1"}`,
760
760
  sendDefaultPii: false,
761
761
  enableLogs: true
762
762
  });
@@ -2429,4 +2429,4 @@ export {
2429
2429
  ConnectPages,
2430
2430
  generateCompleteStyles
2431
2431
  };
2432
- //# sourceMappingURL=chunk-U5BSED2R.mjs.map
2432
+ //# sourceMappingURL=chunk-DND52DSA.mjs.map