@algobright/solana-connector 0.1.5 → 0.1.8

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/WalletDropdown/index.ts","../src/components/WalletDropdown/WalletDropdown.tsx","../src/components/shared/Avatar/Avatar.tsx","../src/components/shared/Avatar/index.ts","../src/components/shared/Button/Button.tsx","../src/components/shared/Button/index.ts","../src/utils/fetchBalance.tsx"],"sourcesContent":["import WalletDropdown from './WalletDropdown';\n\n\nexport default WalletDropdown","import { useEffect, useRef, useState } from 'react'\nimport { isAddress } from '@solana/kit';\nimport styles from './WalletDropdown.module.css'\nimport { motion } from 'motion/react';\nimport Avatar from '@shared/Avatar';\nimport { Check, ChevronLeft, Copy, Globe, LogOut, RefreshCw } from 'lucide-react';\nimport Button from '@shared/Button';\nimport { ClusterElement, DisconnectElement, useConnector, useConnectorClient } from '@solana/connector';\nimport { clsx } from 'clsx';\nimport { getSolBalance, getTokenBalance } from 'src/utils/fetchBalance';\n\n/**\n * Props for the WalletDropdown component.\n */\ninterface WalletDropdownProps {\n /** * Custom CSS class for the dropdown menu container. \n * If not passed, the component uses default absolute positioning.\n */\n CN_DropdownMenu?: string;\n\n /** * Visual theme for the dropdown items. \n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /** * Enables the option to switch between Solana clusters. \n * @default true\n */\n allowNetworkSwitch?: boolean;\n\n /** * Displays the user's SOL balance inside the dropdown header. \n * @default true\n */\n showSolBalance?: boolean;\n\n /** * Configuration to display a specific SPL token balance. \n * If not provided, this defaults to false (hidden).\n */\n showDefaultToken?: {\n address: string;\n symbol: string;\n } | undefined;\n}\n\ntype DropdownView = 'wallet' | 'network';\n\nconst networkColor: Record<string, string> = {\n 'solana:mainnet': '#00c950',\n 'solana:devnet': '#2b7fff',\n 'solana:testnet': '#f0b100',\n 'solana:localnet': '#ff3b3b',\n};\n\nexport function WalletDropdown(props: WalletDropdownProps) {\n const client = useConnectorClient();\n\n const { CN_DropdownMenu,\n theme = 'light',\n allowNetworkSwitch = true,\n showSolBalance = true,\n showDefaultToken\n } = props\n\n const [view, setView] = useState<DropdownView>('wallet');\n const [copied, setCopied] = useState(false);\n\n const { account, connector } = useConnector();\n const fetchingSolBalance = useRef(false);\n const [isFetchingBalance, setIsFetchingBalance] = useState(false);\n\n const fetchingDefaultToken = useRef(false);\n const [isFetchingDefaultTokenBalance, setIsFetchingDefaultTokenBalance] = useState(false);\n\n const [solBalance, setSolBalance] = useState<number | null>(null);\n const [defaultTokenBalance, setDefaultTokenBalance] = useState<number | null>(null);\n\n const selectedAccount = account || '';\n const walletName = connector?.name || 'Unknown Wallet';\n const walletIcon = connector?.icon || undefined;\n const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;\n\n async function handleCopy() {\n try {\n await navigator.clipboard.writeText(selectedAccount);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (error) {\n setCopied(false);\n console.error('Failed to copy to clipboard:', error);\n }\n }\n\n async function fetchSolBalance() {\n if (!client || fetchingSolBalance.current) return;\n setIsFetchingBalance(true);\n fetchingSolBalance.current = true;\n\n const solBalance = await getSolBalance(client, selectedAccount);\n setSolBalance(solBalance);\n\n setIsFetchingBalance(false);\n fetchingSolBalance.current = false;\n }\n\n async function fetchDefaultTokenBalance() {\n if (!showDefaultToken || !showDefaultToken.address || !client || fetchingDefaultToken.current) return;\n\n const isValidAddress = isAddress(showDefaultToken.address);\n if (!isValidAddress) {\n console.error('Invalid default token address:', showDefaultToken);\n return\n }\n\n setIsFetchingDefaultTokenBalance(true);\n fetchingDefaultToken.current = true;\n\n const tokenBalance = await getTokenBalance(client, selectedAccount, showDefaultToken.address);\n setDefaultTokenBalance(tokenBalance);\n\n setIsFetchingDefaultTokenBalance(false);\n fetchingDefaultToken.current = false;\n }\n\n useEffect(() => {\n if (showSolBalance && selectedAccount && client) {\n fetchSolBalance();\n }\n if (showDefaultToken && selectedAccount && client) {\n fetchDefaultTokenBalance();\n }\n }, [selectedAccount, client, showSolBalance, showDefaultToken]);\n\n if (view === 'wallet') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header with Avatar and Address */}\n <div className={styles.Header}>\n <div className={styles.addressAndAvatar}>\n <Avatar\n width={48}\n height={48}\n src={walletIcon}\n alt={walletName}\n />\n <div className={styles.address}>\n <span className={styles.shortAddress}>{shortAddress}</span>\n <span className={styles.walletName}>{walletName}</span>\n </div>\n </div>\n\n <div className={styles.actions}>\n <Button\n type=\"button\"\n onClick={handleCopy}\n variant=\"outline\"\n size=\"icon\"\n className=\"rounded-full\"\n title={copied ? 'Copied!' : 'Copy address'}\n >\n {copied ?\n <Check className={styles.checkIcon} /> :\n <Copy />\n }\n </Button>\n\n {/* Network Selector Globe Button */}\n {allowNetworkSwitch && (\n <ClusterElement\n render={({ cluster }) => (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('network')}\n title={`Network: ${cluster?.label || 'Unknown'}`}\n >\n <Globe />\n <span\n className={styles.networkIndicator}\n style={{ background: networkColor[cluster?.id || 'solana:mainnet'] }}\n />\n </Button>\n )}\n />\n )}\n </div>\n </div>\n\n {showSolBalance && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchSolBalance()}\n disabled={isFetchingBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(solBalance) || \"0\"}>\n {isFetchingBalance ? (\n <div className={styles.balanceLoading} />\n ) : solBalance !== null ? (\n `${solBalance.toFixed(4)} SOL`\n ) : (\n '-- SOL'\n )}\n </div>\n </div>\n )}\n\n {showDefaultToken && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchDefaultTokenBalance()}\n disabled={isFetchingDefaultTokenBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingDefaultTokenBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(defaultTokenBalance) || \"0\"}>\n {isFetchingDefaultTokenBalance ? (\n <div className={styles.balanceLoading} />\n ) : defaultTokenBalance !== null ? (\n `${defaultTokenBalance.toFixed(4)} ${showDefaultToken?.symbol || ''}`\n ) : (\n `-- ${showDefaultToken?.symbol || ''}`\n )}\n </div>\n </div>\n )}\n\n <DisconnectElement\n render={({ disconnect, disconnecting }) => (\n <Button\n variant=\"default\"\n className={styles.disconnectButton}\n onClick={disconnect}\n disabled={disconnecting}\n >\n <LogOut className={styles.disconnectIcon} />\n {disconnecting ? 'Disconnecting...' : 'Disconnect'}\n </Button>\n )}\n />\n </motion.div>\n )\n }\n\n //network switch view\n if (view === 'network') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header */}\n <div className={styles.NetworkHeader}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('wallet')}\n title={`Network: Back to Wallet`}\n className={styles.backButton}\n >\n <ChevronLeft />\n </Button>\n <span>Network Settings</span>\n </div>\n\n {/* Network Options */}\n <ClusterElement\n render={({ cluster, clusters, setCluster }) => {\n const currentClusterId = (cluster as { id?: string })?.id || 'solana:mainnet';\n return (\n <div className={styles.networkOptions}>\n {clusters.map((network) => {\n const isSelected = currentClusterId === network.id;\n return (\n <div\n key={network.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setCluster(network.id)}\n onKeyDown={e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setCluster(network.id);\n }\n }}\n className={styles.networkButton}\n >\n <div className={styles.networkName}>\n <span\n className={styles.networkColor}\n style={{ background: networkColor[network.id] }}\n />\n <span className={styles.networkLabel}>{network.label}</span>\n </div>\n <div className={styles.checkMark} data-selected={isSelected}>\n {isSelected && <Check />}\n </div>\n </div>\n );\n })}\n </div>\n );\n }}\n />\n </motion.div>\n )\n }\n}\n\nexport default WalletDropdown","import { useState } from 'react';\nimport styles from './Avatar.module.css';\nimport { Wallet } from 'lucide-react';\ninterface AvatarProps {\n height?: number | string;\n width?: number | string;\n src?: string;\n alt?: string;\n theme?: 'light' | 'dark';\n}\nexport function Avatar({\n height,\n width,\n src,\n alt,\n theme = 'light',\n}: AvatarProps) {\n const [hasError, setHasError] = useState(false);\n return (\n <div className={styles.avatar} data-theme={theme}>\n {src && !hasError ? (\n <img\n height={height}\n width={width}\n src={src}\n alt={alt || \"Avatar\"}\n onError={() => setHasError(true)}\n />\n ) : (\n <div className={styles.fallback} style={{ height, width }}>\n <Wallet />\n </div>\n )}\n </div>\n );\n}\n","import { Avatar } from './Avatar';\n\nexport default Avatar;","'use client';\n\nimport { forwardRef } from 'react';\nimport { Button as BaseButton } from '@base-ui/react/button';\nimport styles from './Button.module.css';\n\n// 1. Define Types\ntype ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n}\n\n// 2. The Component\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'default', size = 'default', ...props }, ref) => {\n return (\n <BaseButton\n ref={ref}\n\n className={`${styles.button} ${className || ''}`}\n data-variant={variant}\n data-size={size}\n\n {...props}\n />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport default Button;","import Button from \"./Button\";\n\nexport default Button;","import { findAssociatedTokenPda } from \"@solana-program/token\";\nimport { address, ConnectorClient, lamportsToSol } from \"@solana/connector\";\nimport { createSolanaRpc } from \"@solana/kit\";\n\nexport async function getSolBalance(\n client: ConnectorClient,\n pubkey: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const rpc = createSolanaRpc(rpcUrl);\n const balanceResponse = await rpc.getBalance(pubkeyAddress).send();\n balance = lamportsToSol(balanceResponse.value);\n } catch (error) {\n console.error(\"Error fetching SOL balance:\", error);\n } finally {\n return balance;\n }\n}\n\nexport async function getTokenBalance(\n client: ConnectorClient,\n pubkey: string,\n mintAddress: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const mintPubkey = address(mintAddress);\n const rpc = createSolanaRpc(rpcUrl);\n\n const mintInfo = await rpc.getAccountInfo(\n mintPubkey,\n { encoding: \"base64\" }\n ).send();\n\n const ownerProgram = mintInfo.value?.owner;\n if (!ownerProgram) {\n throw new Error('Failed to fetch mint account info');\n }\n const tokenProgram = address(ownerProgram)\n const [tokenPDA] = await findAssociatedTokenPda({\n mint: mintPubkey,\n owner: pubkeyAddress,\n tokenProgram: tokenProgram\n });\n const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();\n if (tokenBalance.value) {\n balance = parseFloat(tokenBalance.value.uiAmountString);\n }\n } catch (error) {\n // console.error(\"Error fetching token balance:\", error);\n } finally {\n return balance;\n }\n}"],"mappings":"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","names":["WalletDropdown_default","import_react","import_kit","styles","import_lucide_react","import_react","import_jsx_runtime","BaseButton","styles","Button_default","import_connector","import_jsx_runtime","solBalance","styles","Button_default","WalletDropdown_default"]}
1
+ {"version":3,"sources":["../src/components/WalletDropdown/index.ts","../src/components/WalletDropdown/WalletDropdown.tsx","../src/components/shared/Avatar/Avatar.tsx","../src/components/shared/Avatar/index.ts","../src/components/shared/Button/Button.tsx","../src/components/shared/Button/index.ts","../src/utils/fetchBalance.tsx"],"sourcesContent":["import WalletDropdown from './WalletDropdown';\n\n\nexport default WalletDropdown","import { useEffect, useRef, useState } from 'react'\nimport { isAddress } from '@solana/kit';\nimport styles from './WalletDropdown.module.css'\nimport { motion } from 'motion/react';\nimport Avatar from '@shared/Avatar';\nimport { Check, ChevronLeft, Copy, Globe, LogOut, RefreshCw } from 'lucide-react';\nimport Button from '@shared/Button';\nimport { ClusterElement, DisconnectElement, useConnector, useConnectorClient } from '@solana/connector';\nimport { clsx } from 'clsx';\nimport { getSolBalance, getTokenBalance } from 'src/utils/fetchBalance';\n\n/**\n * Props for the WalletDropdown component.\n */\ninterface WalletDropdownProps {\n /** * Custom CSS class for the dropdown menu container. \n * If not passed, the component uses default absolute positioning.\n */\n CN_DropdownMenu?: string;\n\n /** * Visual theme for the dropdown items. \n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /** * Enables the option to switch between Solana clusters. \n * @default true\n */\n allowNetworkSwitch?: boolean;\n\n /** * Displays the user's SOL balance inside the dropdown header. \n * @default true\n */\n showSolBalance?: boolean;\n\n /** * Configuration to display a specific SPL token balance. \n * If not provided, this defaults to false (hidden).\n */\n showDefaultToken?: {\n address: string;\n symbol: string;\n } | undefined;\n}\n\ntype DropdownView = 'wallet' | 'network';\n\nconst networkColor: Record<string, string> = {\n 'solana:mainnet': '#00c950',\n 'solana:devnet': '#2b7fff',\n 'solana:testnet': '#f0b100',\n 'solana:localnet': '#ff3b3b',\n};\n\nexport function WalletDropdown(props: WalletDropdownProps) {\n const client = useConnectorClient();\n\n const { CN_DropdownMenu,\n theme = 'light',\n allowNetworkSwitch = true,\n showSolBalance = true,\n showDefaultToken\n } = props\n\n const [view, setView] = useState<DropdownView>('wallet');\n const [copied, setCopied] = useState(false);\n\n const { account, connector } = useConnector();\n const fetchingSolBalance = useRef(false);\n const [isFetchingBalance, setIsFetchingBalance] = useState(false);\n\n const fetchingDefaultToken = useRef(false);\n const [isFetchingDefaultTokenBalance, setIsFetchingDefaultTokenBalance] = useState(false);\n\n const [solBalance, setSolBalance] = useState<number | null>(null);\n const [defaultTokenBalance, setDefaultTokenBalance] = useState<number | null>(null);\n\n const selectedAccount = account || '';\n const walletName = connector?.name || 'Unknown Wallet';\n const walletIcon = connector?.icon || undefined;\n const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;\n\n async function handleCopy() {\n try {\n await navigator.clipboard.writeText(selectedAccount);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (error) {\n setCopied(false);\n console.error('Failed to copy to clipboard:', error);\n }\n }\n\n async function fetchSolBalance() {\n if (!client || fetchingSolBalance.current) return;\n setIsFetchingBalance(true);\n fetchingSolBalance.current = true;\n\n const solBalance = await getSolBalance(client, selectedAccount);\n setSolBalance(solBalance);\n\n setIsFetchingBalance(false);\n fetchingSolBalance.current = false;\n }\n\n async function fetchDefaultTokenBalance() {\n if (!showDefaultToken || !showDefaultToken.address || !client || fetchingDefaultToken.current) return;\n\n const isValidAddress = isAddress(showDefaultToken.address);\n if (!isValidAddress) {\n console.error('Invalid default token address:', showDefaultToken);\n return\n }\n\n setIsFetchingDefaultTokenBalance(true);\n fetchingDefaultToken.current = true;\n\n const tokenBalance = await getTokenBalance(client, selectedAccount, showDefaultToken.address);\n setDefaultTokenBalance(tokenBalance);\n\n setIsFetchingDefaultTokenBalance(false);\n fetchingDefaultToken.current = false;\n }\n\n useEffect(() => {\n if (showSolBalance && selectedAccount && client) {\n fetchSolBalance();\n }\n if (showDefaultToken && selectedAccount && client) {\n fetchDefaultTokenBalance();\n }\n }, [selectedAccount, client, showSolBalance, showDefaultToken]);\n\n if (view === 'wallet') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header with Avatar and Address */}\n <div className={styles.Header}>\n <div className={styles.addressAndAvatar}>\n <Avatar\n width={48}\n height={48}\n src={walletIcon}\n alt={walletName}\n />\n <div className={styles.address}>\n <span className={styles.shortAddress}>{shortAddress}</span>\n <span className={styles.walletName}>{walletName}</span>\n </div>\n </div>\n\n <div className={styles.actions}>\n <Button\n type=\"button\"\n onClick={handleCopy}\n variant=\"outline\"\n size=\"icon\"\n className=\"rounded-full\"\n title={copied ? 'Copied!' : 'Copy address'}\n >\n {copied ?\n <Check className={styles.checkIcon} /> :\n <Copy />\n }\n </Button>\n\n {/* Network Selector Globe Button */}\n {allowNetworkSwitch && (\n <ClusterElement\n render={({ cluster }) => (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('network')}\n title={`Network: ${cluster?.label || 'Unknown'}`}\n >\n <Globe />\n <span\n className={styles.networkIndicator}\n style={{ background: networkColor[cluster?.id || 'solana:mainnet'] }}\n />\n </Button>\n )}\n />\n )}\n </div>\n </div>\n\n {showSolBalance && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchSolBalance()}\n disabled={isFetchingBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(solBalance) || \"0\"}>\n {isFetchingBalance ? (\n <div className={styles.balanceLoading} />\n ) : solBalance !== null ? (\n `${solBalance.toFixed(4)} SOL`\n ) : (\n '-- SOL'\n )}\n </div>\n </div>\n )}\n\n {showDefaultToken && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchDefaultTokenBalance()}\n disabled={isFetchingDefaultTokenBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingDefaultTokenBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(defaultTokenBalance) || \"0\"}>\n {isFetchingDefaultTokenBalance ? (\n <div className={styles.balanceLoading} />\n ) : defaultTokenBalance !== null ? (\n `${defaultTokenBalance.toFixed(4)} ${showDefaultToken?.symbol || ''}`\n ) : (\n `-- ${showDefaultToken?.symbol || ''}`\n )}\n </div>\n </div>\n )}\n\n <DisconnectElement\n render={({ disconnect, disconnecting }) => (\n <Button\n variant=\"default\"\n className={styles.disconnectButton}\n onClick={disconnect}\n disabled={disconnecting}\n >\n <LogOut className={styles.disconnectIcon} />\n {disconnecting ? 'Disconnecting...' : 'Disconnect'}\n </Button>\n )}\n />\n </motion.div>\n )\n }\n\n //network switch view\n if (view === 'network') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header */}\n <div className={styles.NetworkHeader}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('wallet')}\n title={`Network: Back to Wallet`}\n className={styles.backButton}\n >\n <ChevronLeft />\n </Button>\n <span>Network Settings</span>\n </div>\n\n {/* Network Options */}\n <ClusterElement\n render={({ cluster, clusters, setCluster }) => {\n const currentClusterId = (cluster as { id?: string })?.id || 'solana:mainnet';\n return (\n <div className={styles.networkOptions}>\n {clusters.map((network) => {\n const isSelected = currentClusterId === network.id;\n return (\n <div\n key={network.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setCluster(network.id)}\n onKeyDown={e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setCluster(network.id);\n }\n }}\n className={styles.networkButton}\n >\n <div className={styles.networkName}>\n <span\n className={styles.networkColor}\n style={{ background: networkColor[network.id] }}\n />\n <span className={styles.networkLabel}>{network.label}</span>\n </div>\n <div className={styles.checkMark} data-selected={isSelected}>\n {isSelected && <Check />}\n </div>\n </div>\n );\n })}\n </div>\n );\n }}\n />\n </motion.div>\n )\n }\n}\n\nexport default WalletDropdown","import { useState } from 'react';\nimport styles from './Avatar.module.css';\nimport { Wallet } from 'lucide-react';\ninterface AvatarProps {\n height?: number | string;\n width?: number | string;\n src?: string;\n alt?: string;\n theme?: 'light' | 'dark';\n}\nexport function Avatar({\n height,\n width,\n src,\n alt,\n theme = 'light',\n}: AvatarProps) {\n const [hasError, setHasError] = useState(false);\n return (\n <div className={styles.avatar} data-theme={theme}>\n {src && !hasError ? (\n <img\n height={height}\n width={width}\n src={src}\n alt={alt || \"Avatar\"}\n onError={() => setHasError(true)}\n />\n ) : (\n <div className={styles.fallback} style={{ height, width }}>\n <Wallet />\n </div>\n )}\n </div>\n );\n}\n","import { Avatar } from './Avatar';\n\nexport default Avatar;","'use client';\n\nimport { forwardRef } from 'react';\nimport { Button as BaseButton } from '@base-ui/react/button';\nimport styles from './Button.module.css';\n\n// 1. Define Types\ntype ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n}\n\n// 2. The Component\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'default', size = 'default', ...props }, ref) => {\n return (\n <BaseButton\n ref={ref}\n\n className={`${styles.button} ${className || ''}`}\n data-variant={variant}\n data-size={size}\n\n {...props}\n />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport default Button;","import Button from \"./Button\";\n\nexport default Button;","import { address, ConnectorClient, lamportsToSol } from \"@solana/connector\";\nimport { createSolanaRpc, getAddressEncoder, getProgramDerivedAddress } from \"@solana/kit\";\n\nexport async function getSolBalance(\n client: ConnectorClient,\n pubkey: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const rpc = createSolanaRpc(rpcUrl);\n const balanceResponse = await rpc.getBalance(pubkeyAddress).send();\n balance = lamportsToSol(balanceResponse.value);\n } catch (error) {\n console.error(\"Error fetching SOL balance:\", error);\n } finally {\n return balance;\n }\n}\n\n\nexport const SPL_ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL')\n\nexport async function getTokenBalance(\n client: ConnectorClient,\n pubkey: string,\n mintAddress: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const mintPubkey = address(mintAddress);\n const rpc = createSolanaRpc(rpcUrl);\n\n const mintInfo = await rpc.getAccountInfo(\n mintPubkey,\n { encoding: \"base64\" }\n ).send();\n\n const ownerProgram = mintInfo.value?.owner;\n if (!ownerProgram) {\n throw new Error('Failed to fetch mint account info');\n }\n const tokenProgram = address(ownerProgram)\n const [tokenPDA] = await getProgramDerivedAddress({\n programAddress: SPL_ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n seeds: [\n getAddressEncoder().encode(pubkeyAddress),\n getAddressEncoder().encode(tokenProgram),\n getAddressEncoder().encode(mintPubkey)\n ]\n })\n\n const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();\n if (tokenBalance.value) {\n balance = parseFloat(tokenBalance.value.uiAmountString);\n }\n } catch (error) {\n console.error(\"Error fetching token balance:\", error);\n } finally {\n return balance;\n }\n}"],"mappings":"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","names":["WalletDropdown_default","import_react","import_kit","styles","import_lucide_react","import_react","import_jsx_runtime","BaseButton","styles","Button_default","import_connector","import_jsx_runtime","solBalance","styles","Button_default","WalletDropdown_default"]}
@@ -67,9 +67,8 @@ import { ClusterElement, DisconnectElement, useConnector, useConnectorClient } f
67
67
  import { clsx } from "clsx";
68
68
 
69
69
  // src/utils/fetchBalance.tsx
70
- import { findAssociatedTokenPda } from "@solana-program/token";
71
70
  import { address, lamportsToSol } from "@solana/connector";
72
- import { createSolanaRpc } from "@solana/kit";
71
+ import { createSolanaRpc, getAddressEncoder, getProgramDerivedAddress } from "@solana/kit";
73
72
  async function getSolBalance(client, pubkey) {
74
73
  let balance = 0;
75
74
  try {
@@ -88,6 +87,7 @@ async function getSolBalance(client, pubkey) {
88
87
  return balance;
89
88
  }
90
89
  }
90
+ var SPL_ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
91
91
  async function getTokenBalance(client, pubkey, mintAddress) {
92
92
  var _a;
93
93
  let balance = 0;
@@ -109,16 +109,20 @@ async function getTokenBalance(client, pubkey, mintAddress) {
109
109
  throw new Error("Failed to fetch mint account info");
110
110
  }
111
111
  const tokenProgram = address(ownerProgram);
112
- const [tokenPDA] = await findAssociatedTokenPda({
113
- mint: mintPubkey,
114
- owner: pubkeyAddress,
115
- tokenProgram
112
+ const [tokenPDA] = await getProgramDerivedAddress({
113
+ programAddress: SPL_ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
114
+ seeds: [
115
+ getAddressEncoder().encode(pubkeyAddress),
116
+ getAddressEncoder().encode(tokenProgram),
117
+ getAddressEncoder().encode(mintPubkey)
118
+ ]
116
119
  });
117
120
  const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();
118
121
  if (tokenBalance.value) {
119
122
  balance = parseFloat(tokenBalance.value.uiAmountString);
120
123
  }
121
124
  } catch (error) {
125
+ console.error("Error fetching token balance:", error);
122
126
  } finally {
123
127
  return balance;
124
128
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/WalletDropdown/WalletDropdown.tsx","../src/components/shared/Avatar/Avatar.tsx","../src/components/shared/Avatar/index.ts","../src/components/shared/Button/Button.tsx","../src/components/shared/Button/index.ts","../src/utils/fetchBalance.tsx","../src/components/WalletDropdown/index.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\nimport { isAddress } from '@solana/kit';\nimport styles from './WalletDropdown.module.css'\nimport { motion } from 'motion/react';\nimport Avatar from '@shared/Avatar';\nimport { Check, ChevronLeft, Copy, Globe, LogOut, RefreshCw } from 'lucide-react';\nimport Button from '@shared/Button';\nimport { ClusterElement, DisconnectElement, useConnector, useConnectorClient } from '@solana/connector';\nimport { clsx } from 'clsx';\nimport { getSolBalance, getTokenBalance } from 'src/utils/fetchBalance';\n\n/**\n * Props for the WalletDropdown component.\n */\ninterface WalletDropdownProps {\n /** * Custom CSS class for the dropdown menu container. \n * If not passed, the component uses default absolute positioning.\n */\n CN_DropdownMenu?: string;\n\n /** * Visual theme for the dropdown items. \n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /** * Enables the option to switch between Solana clusters. \n * @default true\n */\n allowNetworkSwitch?: boolean;\n\n /** * Displays the user's SOL balance inside the dropdown header. \n * @default true\n */\n showSolBalance?: boolean;\n\n /** * Configuration to display a specific SPL token balance. \n * If not provided, this defaults to false (hidden).\n */\n showDefaultToken?: {\n address: string;\n symbol: string;\n } | undefined;\n}\n\ntype DropdownView = 'wallet' | 'network';\n\nconst networkColor: Record<string, string> = {\n 'solana:mainnet': '#00c950',\n 'solana:devnet': '#2b7fff',\n 'solana:testnet': '#f0b100',\n 'solana:localnet': '#ff3b3b',\n};\n\nexport function WalletDropdown(props: WalletDropdownProps) {\n const client = useConnectorClient();\n\n const { CN_DropdownMenu,\n theme = 'light',\n allowNetworkSwitch = true,\n showSolBalance = true,\n showDefaultToken\n } = props\n\n const [view, setView] = useState<DropdownView>('wallet');\n const [copied, setCopied] = useState(false);\n\n const { account, connector } = useConnector();\n const fetchingSolBalance = useRef(false);\n const [isFetchingBalance, setIsFetchingBalance] = useState(false);\n\n const fetchingDefaultToken = useRef(false);\n const [isFetchingDefaultTokenBalance, setIsFetchingDefaultTokenBalance] = useState(false);\n\n const [solBalance, setSolBalance] = useState<number | null>(null);\n const [defaultTokenBalance, setDefaultTokenBalance] = useState<number | null>(null);\n\n const selectedAccount = account || '';\n const walletName = connector?.name || 'Unknown Wallet';\n const walletIcon = connector?.icon || undefined;\n const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;\n\n async function handleCopy() {\n try {\n await navigator.clipboard.writeText(selectedAccount);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (error) {\n setCopied(false);\n console.error('Failed to copy to clipboard:', error);\n }\n }\n\n async function fetchSolBalance() {\n if (!client || fetchingSolBalance.current) return;\n setIsFetchingBalance(true);\n fetchingSolBalance.current = true;\n\n const solBalance = await getSolBalance(client, selectedAccount);\n setSolBalance(solBalance);\n\n setIsFetchingBalance(false);\n fetchingSolBalance.current = false;\n }\n\n async function fetchDefaultTokenBalance() {\n if (!showDefaultToken || !showDefaultToken.address || !client || fetchingDefaultToken.current) return;\n\n const isValidAddress = isAddress(showDefaultToken.address);\n if (!isValidAddress) {\n console.error('Invalid default token address:', showDefaultToken);\n return\n }\n\n setIsFetchingDefaultTokenBalance(true);\n fetchingDefaultToken.current = true;\n\n const tokenBalance = await getTokenBalance(client, selectedAccount, showDefaultToken.address);\n setDefaultTokenBalance(tokenBalance);\n\n setIsFetchingDefaultTokenBalance(false);\n fetchingDefaultToken.current = false;\n }\n\n useEffect(() => {\n if (showSolBalance && selectedAccount && client) {\n fetchSolBalance();\n }\n if (showDefaultToken && selectedAccount && client) {\n fetchDefaultTokenBalance();\n }\n }, [selectedAccount, client, showSolBalance, showDefaultToken]);\n\n if (view === 'wallet') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header with Avatar and Address */}\n <div className={styles.Header}>\n <div className={styles.addressAndAvatar}>\n <Avatar\n width={48}\n height={48}\n src={walletIcon}\n alt={walletName}\n />\n <div className={styles.address}>\n <span className={styles.shortAddress}>{shortAddress}</span>\n <span className={styles.walletName}>{walletName}</span>\n </div>\n </div>\n\n <div className={styles.actions}>\n <Button\n type=\"button\"\n onClick={handleCopy}\n variant=\"outline\"\n size=\"icon\"\n className=\"rounded-full\"\n title={copied ? 'Copied!' : 'Copy address'}\n >\n {copied ?\n <Check className={styles.checkIcon} /> :\n <Copy />\n }\n </Button>\n\n {/* Network Selector Globe Button */}\n {allowNetworkSwitch && (\n <ClusterElement\n render={({ cluster }) => (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('network')}\n title={`Network: ${cluster?.label || 'Unknown'}`}\n >\n <Globe />\n <span\n className={styles.networkIndicator}\n style={{ background: networkColor[cluster?.id || 'solana:mainnet'] }}\n />\n </Button>\n )}\n />\n )}\n </div>\n </div>\n\n {showSolBalance && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchSolBalance()}\n disabled={isFetchingBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(solBalance) || \"0\"}>\n {isFetchingBalance ? (\n <div className={styles.balanceLoading} />\n ) : solBalance !== null ? (\n `${solBalance.toFixed(4)} SOL`\n ) : (\n '-- SOL'\n )}\n </div>\n </div>\n )}\n\n {showDefaultToken && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchDefaultTokenBalance()}\n disabled={isFetchingDefaultTokenBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingDefaultTokenBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(defaultTokenBalance) || \"0\"}>\n {isFetchingDefaultTokenBalance ? (\n <div className={styles.balanceLoading} />\n ) : defaultTokenBalance !== null ? (\n `${defaultTokenBalance.toFixed(4)} ${showDefaultToken?.symbol || ''}`\n ) : (\n `-- ${showDefaultToken?.symbol || ''}`\n )}\n </div>\n </div>\n )}\n\n <DisconnectElement\n render={({ disconnect, disconnecting }) => (\n <Button\n variant=\"default\"\n className={styles.disconnectButton}\n onClick={disconnect}\n disabled={disconnecting}\n >\n <LogOut className={styles.disconnectIcon} />\n {disconnecting ? 'Disconnecting...' : 'Disconnect'}\n </Button>\n )}\n />\n </motion.div>\n )\n }\n\n //network switch view\n if (view === 'network') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header */}\n <div className={styles.NetworkHeader}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('wallet')}\n title={`Network: Back to Wallet`}\n className={styles.backButton}\n >\n <ChevronLeft />\n </Button>\n <span>Network Settings</span>\n </div>\n\n {/* Network Options */}\n <ClusterElement\n render={({ cluster, clusters, setCluster }) => {\n const currentClusterId = (cluster as { id?: string })?.id || 'solana:mainnet';\n return (\n <div className={styles.networkOptions}>\n {clusters.map((network) => {\n const isSelected = currentClusterId === network.id;\n return (\n <div\n key={network.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setCluster(network.id)}\n onKeyDown={e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setCluster(network.id);\n }\n }}\n className={styles.networkButton}\n >\n <div className={styles.networkName}>\n <span\n className={styles.networkColor}\n style={{ background: networkColor[network.id] }}\n />\n <span className={styles.networkLabel}>{network.label}</span>\n </div>\n <div className={styles.checkMark} data-selected={isSelected}>\n {isSelected && <Check />}\n </div>\n </div>\n );\n })}\n </div>\n );\n }}\n />\n </motion.div>\n )\n }\n}\n\nexport default WalletDropdown","import { useState } from 'react';\nimport styles from './Avatar.module.css';\nimport { Wallet } from 'lucide-react';\ninterface AvatarProps {\n height?: number | string;\n width?: number | string;\n src?: string;\n alt?: string;\n theme?: 'light' | 'dark';\n}\nexport function Avatar({\n height,\n width,\n src,\n alt,\n theme = 'light',\n}: AvatarProps) {\n const [hasError, setHasError] = useState(false);\n return (\n <div className={styles.avatar} data-theme={theme}>\n {src && !hasError ? (\n <img\n height={height}\n width={width}\n src={src}\n alt={alt || \"Avatar\"}\n onError={() => setHasError(true)}\n />\n ) : (\n <div className={styles.fallback} style={{ height, width }}>\n <Wallet />\n </div>\n )}\n </div>\n );\n}\n","import { Avatar } from './Avatar';\n\nexport default Avatar;","'use client';\n\nimport { forwardRef } from 'react';\nimport { Button as BaseButton } from '@base-ui/react/button';\nimport styles from './Button.module.css';\n\n// 1. Define Types\ntype ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n}\n\n// 2. The Component\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'default', size = 'default', ...props }, ref) => {\n return (\n <BaseButton\n ref={ref}\n\n className={`${styles.button} ${className || ''}`}\n data-variant={variant}\n data-size={size}\n\n {...props}\n />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport default Button;","import Button from \"./Button\";\n\nexport default Button;","import { findAssociatedTokenPda } from \"@solana-program/token\";\nimport { address, ConnectorClient, lamportsToSol } from \"@solana/connector\";\nimport { createSolanaRpc } from \"@solana/kit\";\n\nexport async function getSolBalance(\n client: ConnectorClient,\n pubkey: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const rpc = createSolanaRpc(rpcUrl);\n const balanceResponse = await rpc.getBalance(pubkeyAddress).send();\n balance = lamportsToSol(balanceResponse.value);\n } catch (error) {\n console.error(\"Error fetching SOL balance:\", error);\n } finally {\n return balance;\n }\n}\n\nexport async function getTokenBalance(\n client: ConnectorClient,\n pubkey: string,\n mintAddress: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const mintPubkey = address(mintAddress);\n const rpc = createSolanaRpc(rpcUrl);\n\n const mintInfo = await rpc.getAccountInfo(\n mintPubkey,\n { encoding: \"base64\" }\n ).send();\n\n const ownerProgram = mintInfo.value?.owner;\n if (!ownerProgram) {\n throw new Error('Failed to fetch mint account info');\n }\n const tokenProgram = address(ownerProgram)\n const [tokenPDA] = await findAssociatedTokenPda({\n mint: mintPubkey,\n owner: pubkeyAddress,\n tokenProgram: tokenProgram\n });\n const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();\n if (tokenBalance.value) {\n balance = parseFloat(tokenBalance.value.uiAmountString);\n }\n } catch (error) {\n // console.error(\"Error fetching token balance:\", error);\n } finally {\n return balance;\n }\n}","import WalletDropdown from './WalletDropdown';\n\n\nexport default WalletDropdown"],"mappings":"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","names":["useState","styles","styles","jsx","Button_default","jsx","useState","solBalance","styles","Button_default","WalletDropdown_default"]}
1
+ {"version":3,"sources":["../src/components/WalletDropdown/WalletDropdown.tsx","../src/components/shared/Avatar/Avatar.tsx","../src/components/shared/Avatar/index.ts","../src/components/shared/Button/Button.tsx","../src/components/shared/Button/index.ts","../src/utils/fetchBalance.tsx","../src/components/WalletDropdown/index.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\nimport { isAddress } from '@solana/kit';\nimport styles from './WalletDropdown.module.css'\nimport { motion } from 'motion/react';\nimport Avatar from '@shared/Avatar';\nimport { Check, ChevronLeft, Copy, Globe, LogOut, RefreshCw } from 'lucide-react';\nimport Button from '@shared/Button';\nimport { ClusterElement, DisconnectElement, useConnector, useConnectorClient } from '@solana/connector';\nimport { clsx } from 'clsx';\nimport { getSolBalance, getTokenBalance } from 'src/utils/fetchBalance';\n\n/**\n * Props for the WalletDropdown component.\n */\ninterface WalletDropdownProps {\n /** * Custom CSS class for the dropdown menu container. \n * If not passed, the component uses default absolute positioning.\n */\n CN_DropdownMenu?: string;\n\n /** * Visual theme for the dropdown items. \n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /** * Enables the option to switch between Solana clusters. \n * @default true\n */\n allowNetworkSwitch?: boolean;\n\n /** * Displays the user's SOL balance inside the dropdown header. \n * @default true\n */\n showSolBalance?: boolean;\n\n /** * Configuration to display a specific SPL token balance. \n * If not provided, this defaults to false (hidden).\n */\n showDefaultToken?: {\n address: string;\n symbol: string;\n } | undefined;\n}\n\ntype DropdownView = 'wallet' | 'network';\n\nconst networkColor: Record<string, string> = {\n 'solana:mainnet': '#00c950',\n 'solana:devnet': '#2b7fff',\n 'solana:testnet': '#f0b100',\n 'solana:localnet': '#ff3b3b',\n};\n\nexport function WalletDropdown(props: WalletDropdownProps) {\n const client = useConnectorClient();\n\n const { CN_DropdownMenu,\n theme = 'light',\n allowNetworkSwitch = true,\n showSolBalance = true,\n showDefaultToken\n } = props\n\n const [view, setView] = useState<DropdownView>('wallet');\n const [copied, setCopied] = useState(false);\n\n const { account, connector } = useConnector();\n const fetchingSolBalance = useRef(false);\n const [isFetchingBalance, setIsFetchingBalance] = useState(false);\n\n const fetchingDefaultToken = useRef(false);\n const [isFetchingDefaultTokenBalance, setIsFetchingDefaultTokenBalance] = useState(false);\n\n const [solBalance, setSolBalance] = useState<number | null>(null);\n const [defaultTokenBalance, setDefaultTokenBalance] = useState<number | null>(null);\n\n const selectedAccount = account || '';\n const walletName = connector?.name || 'Unknown Wallet';\n const walletIcon = connector?.icon || undefined;\n const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;\n\n async function handleCopy() {\n try {\n await navigator.clipboard.writeText(selectedAccount);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (error) {\n setCopied(false);\n console.error('Failed to copy to clipboard:', error);\n }\n }\n\n async function fetchSolBalance() {\n if (!client || fetchingSolBalance.current) return;\n setIsFetchingBalance(true);\n fetchingSolBalance.current = true;\n\n const solBalance = await getSolBalance(client, selectedAccount);\n setSolBalance(solBalance);\n\n setIsFetchingBalance(false);\n fetchingSolBalance.current = false;\n }\n\n async function fetchDefaultTokenBalance() {\n if (!showDefaultToken || !showDefaultToken.address || !client || fetchingDefaultToken.current) return;\n\n const isValidAddress = isAddress(showDefaultToken.address);\n if (!isValidAddress) {\n console.error('Invalid default token address:', showDefaultToken);\n return\n }\n\n setIsFetchingDefaultTokenBalance(true);\n fetchingDefaultToken.current = true;\n\n const tokenBalance = await getTokenBalance(client, selectedAccount, showDefaultToken.address);\n setDefaultTokenBalance(tokenBalance);\n\n setIsFetchingDefaultTokenBalance(false);\n fetchingDefaultToken.current = false;\n }\n\n useEffect(() => {\n if (showSolBalance && selectedAccount && client) {\n fetchSolBalance();\n }\n if (showDefaultToken && selectedAccount && client) {\n fetchDefaultTokenBalance();\n }\n }, [selectedAccount, client, showSolBalance, showDefaultToken]);\n\n if (view === 'wallet') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header with Avatar and Address */}\n <div className={styles.Header}>\n <div className={styles.addressAndAvatar}>\n <Avatar\n width={48}\n height={48}\n src={walletIcon}\n alt={walletName}\n />\n <div className={styles.address}>\n <span className={styles.shortAddress}>{shortAddress}</span>\n <span className={styles.walletName}>{walletName}</span>\n </div>\n </div>\n\n <div className={styles.actions}>\n <Button\n type=\"button\"\n onClick={handleCopy}\n variant=\"outline\"\n size=\"icon\"\n className=\"rounded-full\"\n title={copied ? 'Copied!' : 'Copy address'}\n >\n {copied ?\n <Check className={styles.checkIcon} /> :\n <Copy />\n }\n </Button>\n\n {/* Network Selector Globe Button */}\n {allowNetworkSwitch && (\n <ClusterElement\n render={({ cluster }) => (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('network')}\n title={`Network: ${cluster?.label || 'Unknown'}`}\n >\n <Globe />\n <span\n className={styles.networkIndicator}\n style={{ background: networkColor[cluster?.id || 'solana:mainnet'] }}\n />\n </Button>\n )}\n />\n )}\n </div>\n </div>\n\n {showSolBalance && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchSolBalance()}\n disabled={isFetchingBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(solBalance) || \"0\"}>\n {isFetchingBalance ? (\n <div className={styles.balanceLoading} />\n ) : solBalance !== null ? (\n `${solBalance.toFixed(4)} SOL`\n ) : (\n '-- SOL'\n )}\n </div>\n </div>\n )}\n\n {showDefaultToken && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchDefaultTokenBalance()}\n disabled={isFetchingDefaultTokenBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingDefaultTokenBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(defaultTokenBalance) || \"0\"}>\n {isFetchingDefaultTokenBalance ? (\n <div className={styles.balanceLoading} />\n ) : defaultTokenBalance !== null ? (\n `${defaultTokenBalance.toFixed(4)} ${showDefaultToken?.symbol || ''}`\n ) : (\n `-- ${showDefaultToken?.symbol || ''}`\n )}\n </div>\n </div>\n )}\n\n <DisconnectElement\n render={({ disconnect, disconnecting }) => (\n <Button\n variant=\"default\"\n className={styles.disconnectButton}\n onClick={disconnect}\n disabled={disconnecting}\n >\n <LogOut className={styles.disconnectIcon} />\n {disconnecting ? 'Disconnecting...' : 'Disconnect'}\n </Button>\n )}\n />\n </motion.div>\n )\n }\n\n //network switch view\n if (view === 'network') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_DropdownMenu)}\n data-theme={theme}\n >\n {/* Header */}\n <div className={styles.NetworkHeader}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('wallet')}\n title={`Network: Back to Wallet`}\n className={styles.backButton}\n >\n <ChevronLeft />\n </Button>\n <span>Network Settings</span>\n </div>\n\n {/* Network Options */}\n <ClusterElement\n render={({ cluster, clusters, setCluster }) => {\n const currentClusterId = (cluster as { id?: string })?.id || 'solana:mainnet';\n return (\n <div className={styles.networkOptions}>\n {clusters.map((network) => {\n const isSelected = currentClusterId === network.id;\n return (\n <div\n key={network.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setCluster(network.id)}\n onKeyDown={e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setCluster(network.id);\n }\n }}\n className={styles.networkButton}\n >\n <div className={styles.networkName}>\n <span\n className={styles.networkColor}\n style={{ background: networkColor[network.id] }}\n />\n <span className={styles.networkLabel}>{network.label}</span>\n </div>\n <div className={styles.checkMark} data-selected={isSelected}>\n {isSelected && <Check />}\n </div>\n </div>\n );\n })}\n </div>\n );\n }}\n />\n </motion.div>\n )\n }\n}\n\nexport default WalletDropdown","import { useState } from 'react';\nimport styles from './Avatar.module.css';\nimport { Wallet } from 'lucide-react';\ninterface AvatarProps {\n height?: number | string;\n width?: number | string;\n src?: string;\n alt?: string;\n theme?: 'light' | 'dark';\n}\nexport function Avatar({\n height,\n width,\n src,\n alt,\n theme = 'light',\n}: AvatarProps) {\n const [hasError, setHasError] = useState(false);\n return (\n <div className={styles.avatar} data-theme={theme}>\n {src && !hasError ? (\n <img\n height={height}\n width={width}\n src={src}\n alt={alt || \"Avatar\"}\n onError={() => setHasError(true)}\n />\n ) : (\n <div className={styles.fallback} style={{ height, width }}>\n <Wallet />\n </div>\n )}\n </div>\n );\n}\n","import { Avatar } from './Avatar';\n\nexport default Avatar;","'use client';\n\nimport { forwardRef } from 'react';\nimport { Button as BaseButton } from '@base-ui/react/button';\nimport styles from './Button.module.css';\n\n// 1. Define Types\ntype ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n}\n\n// 2. The Component\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'default', size = 'default', ...props }, ref) => {\n return (\n <BaseButton\n ref={ref}\n\n className={`${styles.button} ${className || ''}`}\n data-variant={variant}\n data-size={size}\n\n {...props}\n />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport default Button;","import Button from \"./Button\";\n\nexport default Button;","import { address, ConnectorClient, lamportsToSol } from \"@solana/connector\";\nimport { createSolanaRpc, getAddressEncoder, getProgramDerivedAddress } from \"@solana/kit\";\n\nexport async function getSolBalance(\n client: ConnectorClient,\n pubkey: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const rpc = createSolanaRpc(rpcUrl);\n const balanceResponse = await rpc.getBalance(pubkeyAddress).send();\n balance = lamportsToSol(balanceResponse.value);\n } catch (error) {\n console.error(\"Error fetching SOL balance:\", error);\n } finally {\n return balance;\n }\n}\n\n\nexport const SPL_ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL')\n\nexport async function getTokenBalance(\n client: ConnectorClient,\n pubkey: string,\n mintAddress: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const mintPubkey = address(mintAddress);\n const rpc = createSolanaRpc(rpcUrl);\n\n const mintInfo = await rpc.getAccountInfo(\n mintPubkey,\n { encoding: \"base64\" }\n ).send();\n\n const ownerProgram = mintInfo.value?.owner;\n if (!ownerProgram) {\n throw new Error('Failed to fetch mint account info');\n }\n const tokenProgram = address(ownerProgram)\n const [tokenPDA] = await getProgramDerivedAddress({\n programAddress: SPL_ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n seeds: [\n getAddressEncoder().encode(pubkeyAddress),\n getAddressEncoder().encode(tokenProgram),\n getAddressEncoder().encode(mintPubkey)\n ]\n })\n\n const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();\n if (tokenBalance.value) {\n balance = parseFloat(tokenBalance.value.uiAmountString);\n }\n } catch (error) {\n console.error(\"Error fetching token balance:\", error);\n } finally {\n return balance;\n }\n}","import WalletDropdown from './WalletDropdown';\n\n\nexport default WalletDropdown"],"mappings":"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","names":["useState","styles","styles","jsx","Button_default","jsx","useState","solBalance","styles","Button_default","WalletDropdown_default"]}
package/dist/index.js CHANGED
@@ -184,13 +184,13 @@ function SolanaWalletProvider(props) {
184
184
  wallets: walletsDisplayConfig
185
185
  });
186
186
  }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);
187
- const mobile = {
188
- appIdentity: {
189
- name: appName,
190
- uri: appOrigin,
191
- icon: appUrl ? `${appOrigin}/favicon.ico` : void 0
192
- }
193
- };
187
+ const mobile = (0, import_react2.useMemo)(() => {
188
+ return (0, import_react3.getDefaultMobileConfig)({
189
+ appName,
190
+ appUrl: appOrigin,
191
+ network: activeNetwork === "localnet" ? "devnet" : activeNetwork
192
+ });
193
+ }, [appName, appOrigin, activeNetwork]);
194
194
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react3.AppProvider, { connectorConfig, mobile, children });
195
195
  }
196
196
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/providers/RpcProvider.tsx","../src/providers/SolanaWalletProvider.tsx","../src/providers/SolanaWrapper.tsx"],"sourcesContent":["import { SolanaWrapper } from '@providers/SolanaWrapper';\nimport { useRpcProvider } from '@providers/RpcProvider';\n\nexport {\n SolanaWrapper,\n useRpcProvider,\n};","'use client';\n\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n useCallback,\n useMemo,\n type ReactNode\n} from 'react';\nimport { Network, RpcMap } from '../types';\n\n\nconst DEFAULT_RPCS: RpcMap = {\n mainnet: ['https://api.mainnet.solana.com'],\n devnet: ['https://api.devnet.solana.com'],\n testnet: ['https://api.testnet.solana.com'],\n localnet: ['http://localhost:8899'],\n};\n\ninterface RpcContextType {\n rpcUrl: string;\n setRpcUrl: (url: string) => void;\n\n persistClusterSelection: boolean;\n clusterStorageKey: string;\n maxRPCRetries: number;\n\n allRpcUrls: RpcMap;\n addRpcUrl: (network: Network, url: string) => void;\n removeRpcUrl: (network: Network, url: string) => void;\n}\nconst RpcContext = createContext<RpcContextType | null>(null);\n\n\ntype RpcProviderProps = {\n children: ReactNode;\n\n defaultRpcList?: RpcMap;\n defaultRpcUrl?: string;\n\n LS_KEY_RPC_LIST?: string;\n LS_KEY_RPC_DEFAULT?: string;\n LS_KEY_CLUSTER?: string;\n persistClusterSelection?: boolean;\n MAX_RPC_RETRIES?: number;\n};\nexport function RpcProvider(props: RpcProviderProps) {\n const {\n children,\n defaultRpcList = DEFAULT_RPCS,\n defaultRpcUrl = DEFAULT_RPCS.mainnet[0],\n LS_KEY_RPC_LIST = 'all-rpc-urls',\n LS_KEY_RPC_DEFAULT = 'curr-rpc',\n LS_KEY_CLUSTER = 'solana-cluster',\n persistClusterSelection = true,\n MAX_RPC_RETRIES = 3,\n } = props;\n\n const [allRpcUrls, setAllRpcUrls] = useState<RpcMap>(defaultRpcList);\n const [rpcUrl, setRpcUrlState] = useState<string>(defaultRpcUrl);\n\n useEffect(() => {\n const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);\n const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);\n\n if (savedRpc && savedRpc !== rpcUrl) {\n setRpcUrlState(savedRpc);\n }\n\n if (savedHistory) {\n try {\n const parsed = JSON.parse(savedHistory) as RpcMap;\n setAllRpcUrls({\n mainnet: Array.from(new Set([...DEFAULT_RPCS.mainnet, ...(parsed.mainnet || [])])),\n devnet: Array.from(new Set([...DEFAULT_RPCS.devnet, ...(parsed.devnet || [])])),\n testnet: Array.from(new Set([...DEFAULT_RPCS.testnet, ...(parsed.testnet || [])])),\n localnet: Array.from(new Set([...DEFAULT_RPCS.localnet, ...(parsed.localnet || [])])),\n });\n } catch (e) {\n console.error(e);\n }\n }\n }, []);\n\n const setRpcUrl = useCallback((url: string) => {\n setRpcUrlState(url);\n localStorage.setItem(LS_KEY_RPC_DEFAULT, url);\n }, []);\n\n const addRpcUrl = useCallback((network: Network, url: string) => {\n if (!url) return;\n\n setAllRpcUrls((prev) => {\n const newList = Array.from(new Set([...prev[network], url]));\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n\n setRpcUrl(url);\n }, [setRpcUrl]);\n\n const removeRpcUrl = useCallback((network: Network, url: string) => {\n setAllRpcUrls((prev) => {\n let newList = prev[network].filter((rpc) => rpc !== url);\n\n if (newList.length === 0) {\n newList = [...DEFAULT_RPCS[network]];\n }\n\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n }, [LS_KEY_RPC_LIST]);\n\n const value = useMemo<RpcContextType>(() => ({\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: LS_KEY_CLUSTER,\n maxRPCRetries: MAX_RPC_RETRIES,\n rpcUrl,\n setRpcUrl,\n allRpcUrls,\n addRpcUrl,\n removeRpcUrl\n }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);\n\n\n return (\n <RpcContext.Provider value={value}>\n {children}\n </RpcContext.Provider>\n );\n}\n\nexport const useRpcProvider = () => {\n const context = useContext(RpcContext);\n if (!context) {\n throw new Error('useRpcProvider must be used within RpcProvider');\n }\n return context;\n};","'use client';\n\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport { AppProvider, getDefaultConfig, getDefaultMobileConfig, MobileWalletAdapterConfig, SimplifiedWalletConnectConfig, Wallet, WalletDisplayConfig } from '@solana/connector/react';\nimport { Network } from '../types';\nimport { CoinGeckoConfig, SolanaCluster } from '@solana/connector';\nimport { useRpcProvider } from './RpcProvider';\n\ntype SolanaWalletProviderProps = {\n children: ReactNode;\n\n appName?: string;\n appUrl?: string;\n\n autoConnect?: boolean;\n enableMobile?: boolean;\n\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n additionalWallets?: Wallet[];\n coingecko?: CoinGeckoConfig;\n walletsDisplayConfig?: WalletDisplayConfig;\n};\n\nexport function SolanaWalletProvider(props: SolanaWalletProviderProps) {\n const {\n children,\n appName = \"Solana Kit\",\n appUrl,\n autoConnect = true,\n enableMobile = true,\n walletConnect = false,\n additionalWallets = [],\n coingecko,\n walletsDisplayConfig\n } = props;\n\n const {\n persistClusterSelection,\n clusterStorageKey,\n maxRPCRetries,\n rpcUrl, allRpcUrls\n } = useRpcProvider();\n\n const appOrigin = appUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n\n const activeNetwork: Network = useMemo(() => {\n if (allRpcUrls.devnet.includes(rpcUrl)) return 'devnet';\n else if (allRpcUrls.testnet.includes(rpcUrl)) return 'testnet';\n else if (allRpcUrls.localnet.includes(rpcUrl)) return 'localnet';\n return 'mainnet';\n }, [rpcUrl, allRpcUrls]);\n\n const connectorConfig = useMemo(() => {\n\n const clusters: SolanaCluster[] = [\n {\n id: 'solana:mainnet',\n label: 'Mainnet',\n url: activeNetwork === 'mainnet' ? rpcUrl : allRpcUrls.mainnet[0],\n },\n {\n id: 'solana:localnet',\n label: 'Localnet',\n url: activeNetwork === 'localnet' ? rpcUrl : allRpcUrls.localnet[0],\n },\n {\n id: 'solana:devnet',\n label: 'Devnet',\n url: activeNetwork === 'devnet' ? rpcUrl : allRpcUrls.devnet[0],\n },\n {\n id: 'solana:testnet',\n label: 'Testnet',\n url: activeNetwork === 'testnet' ? rpcUrl : allRpcUrls.testnet[0],\n },\n ];\n\n return getDefaultConfig({\n appName: appName,\n appUrl: appOrigin,\n autoConnect: autoConnect,\n\n network: activeNetwork,\n enableMobile: enableMobile,\n\n // from RPC settings\n clusters,\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: clusterStorageKey,\n maxRetries: maxRPCRetries,\n\n walletConnect: walletConnect,\n additionalWallets: additionalWallets,\n coingecko: coingecko,\n wallets: walletsDisplayConfig\n\n });\n }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);\n\n // const mobile = useMemo(\n // () =>\n // getDefaultMobileConfig({\n // appName: appName,\n // appUrl: appOrigin,\n // network: activeNetwork === 'localnet' ? 'devnet' : activeNetwork,\n // }),\n // [appName, appOrigin, activeNetwork],\n // );\n\n // console.error(mobile.appIdentity)\n\n const mobile: MobileWalletAdapterConfig = {\n appIdentity: {\n name: appName,\n uri: appOrigin,\n icon: appUrl ? `${appOrigin}/favicon.ico` : undefined,\n }\n }\n\n\n return (\n <AppProvider connectorConfig={connectorConfig} mobile={mobile} >\n {children}\n </AppProvider >\n );\n}","\"use client\";\n\nimport { SimplifiedWalletConnectConfig } from \"@solana/connector\";\nimport { RpcMap } from \"../types\";\nimport { RpcProvider } from \"./RpcProvider\";\nimport { SolanaWalletProvider } from \"./SolanaWalletProvider\";\n\ntype SolanaWrapperProps = {\n children: React.ReactNode;\n\n /** * Name of your app (displayed in wallet connection modals) \n * @default \"Solana Kit\"\n */\n appName?: string;\n\n /** * URL of your app (used for deep linking) \n */\n appUrl?: string;\n\n /** * Automatically connect to the last used wallet on load.\n * @default true\n */\n autoConnect?: boolean;\n\n /** * Enable mobile wallets (e.g. Phantom on iOS/Android) \n * @default true\n */\n enableMobile?: boolean;\n\n /** * Enable WalletConnect support \n * Enable or configure WalletConnect support for QR code and deep-link connections.\n * * **Mobile-First Note:** Setting this to `false` (default) reduces initial bundle size. \n * Enable this if you need to support desktop-to-mobile connections via QR codes.\n * * - `false`: (Default) Disables WalletConnect.\n * - `true`: Enables using `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` from your environment.\n * - `object`: Provides manual overrides for `projectId`, `metadata`, etc.\n * * @default false\n * @see https://docs.reown.com/appkit/overview\n */\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n /** * List of default RPC endpoints mapped by network \n * @default DEFAULT_RPCS\n */\n defaultRpcList?: RpcMap;\n\n /** * The default RPC endpoint to use if none is selected \n * @default DEFAULT_RPCS.mainnet[0]\n */\n defaultRpcUrl?: string;\n\n /** * LocalStorage key for saving custom RPC list \n * @default 'all-rpc-urls'\n */\n LS_KEY_RPC_LIST?: string;\n\n /** * LocalStorage key for saving default RPC endpoint \n * @default 'curr-rpc'\n */\n LS_KEY_RPC_DEFAULT?: string;\n\n /** * LocalStorage key for saving selected cluster \n * @default 'solana-cluster'\n */\n LS_KEY_CLUSTER?: string;\n\n /** * Persist cluster selection in LocalStorage \n * @default true\n */\n persistClusterSelection?: boolean;\n\n /** * Maximum number of retries for RPC requests \n * @default 3\n */\n MAX_RPC_RETRIES?: number;\n}\n\nexport function SolanaWrapper(props: SolanaWrapperProps) {\n const {\n children,\n\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n walletConnect,\n\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n } = props\n\n\n const RPC_PROVIDER_PROPS = {\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n }\n\n const solanaWalletProviderProps = {\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n\n walletConnect,\n additionalWallets: [],\n coingecko: undefined,\n walletsDisplayConfig: undefined\n }\n\n return (\n <RpcProvider {...RPC_PROVIDER_PROPS}>\n <SolanaWalletProvider {...solanaWalletProviderProps}>\n {children}\n </SolanaWalletProvider>\n </RpcProvider>\n )\n}"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/providers/RpcProvider.tsx","../src/providers/SolanaWalletProvider.tsx","../src/providers/SolanaWrapper.tsx"],"sourcesContent":["import { SolanaWrapper } from '@providers/SolanaWrapper';\nimport { useRpcProvider } from '@providers/RpcProvider';\n\nexport {\n SolanaWrapper,\n useRpcProvider,\n};","'use client';\n\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n useCallback,\n useMemo,\n type ReactNode\n} from 'react';\nimport { Network, RpcMap } from '../types';\n\n\nconst DEFAULT_RPCS: RpcMap = {\n mainnet: ['https://api.mainnet.solana.com'],\n devnet: ['https://api.devnet.solana.com'],\n testnet: ['https://api.testnet.solana.com'],\n localnet: ['http://localhost:8899'],\n};\n\ninterface RpcContextType {\n rpcUrl: string;\n setRpcUrl: (url: string) => void;\n\n persistClusterSelection: boolean;\n clusterStorageKey: string;\n maxRPCRetries: number;\n\n allRpcUrls: RpcMap;\n addRpcUrl: (network: Network, url: string) => void;\n removeRpcUrl: (network: Network, url: string) => void;\n}\nconst RpcContext = createContext<RpcContextType | null>(null);\n\n\ntype RpcProviderProps = {\n children: ReactNode;\n\n defaultRpcList?: RpcMap;\n defaultRpcUrl?: string;\n\n LS_KEY_RPC_LIST?: string;\n LS_KEY_RPC_DEFAULT?: string;\n LS_KEY_CLUSTER?: string;\n persistClusterSelection?: boolean;\n MAX_RPC_RETRIES?: number;\n};\nexport function RpcProvider(props: RpcProviderProps) {\n const {\n children,\n defaultRpcList = DEFAULT_RPCS,\n defaultRpcUrl = DEFAULT_RPCS.mainnet[0],\n LS_KEY_RPC_LIST = 'all-rpc-urls',\n LS_KEY_RPC_DEFAULT = 'curr-rpc',\n LS_KEY_CLUSTER = 'solana-cluster',\n persistClusterSelection = true,\n MAX_RPC_RETRIES = 3,\n } = props;\n\n const [allRpcUrls, setAllRpcUrls] = useState<RpcMap>(defaultRpcList);\n const [rpcUrl, setRpcUrlState] = useState<string>(defaultRpcUrl);\n\n useEffect(() => {\n const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);\n const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);\n\n if (savedRpc && savedRpc !== rpcUrl) {\n setRpcUrlState(savedRpc);\n }\n\n if (savedHistory) {\n try {\n const parsed = JSON.parse(savedHistory) as RpcMap;\n setAllRpcUrls({\n mainnet: Array.from(new Set([...DEFAULT_RPCS.mainnet, ...(parsed.mainnet || [])])),\n devnet: Array.from(new Set([...DEFAULT_RPCS.devnet, ...(parsed.devnet || [])])),\n testnet: Array.from(new Set([...DEFAULT_RPCS.testnet, ...(parsed.testnet || [])])),\n localnet: Array.from(new Set([...DEFAULT_RPCS.localnet, ...(parsed.localnet || [])])),\n });\n } catch (e) {\n console.error(e);\n }\n }\n }, []);\n\n const setRpcUrl = useCallback((url: string) => {\n setRpcUrlState(url);\n localStorage.setItem(LS_KEY_RPC_DEFAULT, url);\n }, []);\n\n const addRpcUrl = useCallback((network: Network, url: string) => {\n if (!url) return;\n\n setAllRpcUrls((prev) => {\n const newList = Array.from(new Set([...prev[network], url]));\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n\n setRpcUrl(url);\n }, [setRpcUrl]);\n\n const removeRpcUrl = useCallback((network: Network, url: string) => {\n setAllRpcUrls((prev) => {\n let newList = prev[network].filter((rpc) => rpc !== url);\n\n if (newList.length === 0) {\n newList = [...DEFAULT_RPCS[network]];\n }\n\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n }, [LS_KEY_RPC_LIST]);\n\n const value = useMemo<RpcContextType>(() => ({\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: LS_KEY_CLUSTER,\n maxRPCRetries: MAX_RPC_RETRIES,\n rpcUrl,\n setRpcUrl,\n allRpcUrls,\n addRpcUrl,\n removeRpcUrl\n }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);\n\n\n return (\n <RpcContext.Provider value={value}>\n {children}\n </RpcContext.Provider>\n );\n}\n\nexport const useRpcProvider = () => {\n const context = useContext(RpcContext);\n if (!context) {\n throw new Error('useRpcProvider must be used within RpcProvider');\n }\n return context;\n};","'use client';\n\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport { AppProvider, getDefaultConfig, getDefaultMobileConfig, MobileWalletAdapterConfig, SimplifiedWalletConnectConfig, Wallet, WalletDisplayConfig } from '@solana/connector/react';\nimport { Network } from '../types';\nimport { CoinGeckoConfig, SolanaCluster } from '@solana/connector';\nimport { useRpcProvider } from './RpcProvider';\n\ntype SolanaWalletProviderProps = {\n children: ReactNode;\n\n appName?: string;\n appUrl?: string;\n\n autoConnect?: boolean;\n enableMobile?: boolean;\n\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n additionalWallets?: Wallet[];\n coingecko?: CoinGeckoConfig;\n walletsDisplayConfig?: WalletDisplayConfig;\n};\n\nexport function SolanaWalletProvider(props: SolanaWalletProviderProps) {\n const {\n children,\n appName = \"Solana Kit\",\n appUrl,\n autoConnect = true,\n enableMobile = true,\n walletConnect = false,\n additionalWallets = [],\n coingecko,\n walletsDisplayConfig\n } = props;\n\n const {\n persistClusterSelection,\n clusterStorageKey,\n maxRPCRetries,\n rpcUrl, allRpcUrls\n } = useRpcProvider();\n\n const appOrigin = appUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n\n const activeNetwork: Network = useMemo(() => {\n if (allRpcUrls.devnet.includes(rpcUrl)) return 'devnet';\n else if (allRpcUrls.testnet.includes(rpcUrl)) return 'testnet';\n else if (allRpcUrls.localnet.includes(rpcUrl)) return 'localnet';\n return 'mainnet';\n }, [rpcUrl, allRpcUrls]);\n\n const connectorConfig = useMemo(() => {\n\n const clusters: SolanaCluster[] = [\n {\n id: 'solana:mainnet',\n label: 'Mainnet',\n url: activeNetwork === 'mainnet' ? rpcUrl : allRpcUrls.mainnet[0],\n },\n {\n id: 'solana:localnet',\n label: 'Localnet',\n url: activeNetwork === 'localnet' ? rpcUrl : allRpcUrls.localnet[0],\n },\n {\n id: 'solana:devnet',\n label: 'Devnet',\n url: activeNetwork === 'devnet' ? rpcUrl : allRpcUrls.devnet[0],\n },\n {\n id: 'solana:testnet',\n label: 'Testnet',\n url: activeNetwork === 'testnet' ? rpcUrl : allRpcUrls.testnet[0],\n },\n ];\n\n return getDefaultConfig({\n appName: appName,\n appUrl: appOrigin,\n autoConnect: autoConnect,\n\n network: activeNetwork,\n enableMobile: enableMobile,\n\n // from RPC settings\n clusters,\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: clusterStorageKey,\n maxRetries: maxRPCRetries,\n\n walletConnect: walletConnect,\n additionalWallets: additionalWallets,\n coingecko: coingecko,\n wallets: walletsDisplayConfig\n\n });\n }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);\n\n const mobile = useMemo(() => {\n return getDefaultMobileConfig({\n appName: appName,\n appUrl: appOrigin,\n network: activeNetwork === 'localnet' ? 'devnet' : activeNetwork,\n });\n }, [appName, appOrigin, activeNetwork]);\n\n\n return (\n <AppProvider connectorConfig={connectorConfig} mobile={mobile} >\n {children}\n </AppProvider >\n );\n}","\"use client\";\n\nimport { SimplifiedWalletConnectConfig } from \"@solana/connector\";\nimport { RpcMap } from \"../types\";\nimport { RpcProvider } from \"./RpcProvider\";\nimport { SolanaWalletProvider } from \"./SolanaWalletProvider\";\n\ntype SolanaWrapperProps = {\n children: React.ReactNode;\n\n /** * Name of your app (displayed in wallet connection modals) \n * @default \"Solana Kit\"\n */\n appName?: string;\n\n /** * URL of your app (used for deep linking) \n */\n appUrl?: string;\n\n /** * Automatically connect to the last used wallet on load.\n * @default true\n */\n autoConnect?: boolean;\n\n /** * Enable mobile wallets (e.g. Phantom on iOS/Android) \n * @default true\n */\n enableMobile?: boolean;\n\n /** * Enable WalletConnect support \n * Enable or configure WalletConnect support for QR code and deep-link connections.\n * * **Mobile-First Note:** Setting this to `false` (default) reduces initial bundle size. \n * Enable this if you need to support desktop-to-mobile connections via QR codes.\n * * - `false`: (Default) Disables WalletConnect.\n * - `true`: Enables using `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` from your environment.\n * - `object`: Provides manual overrides for `projectId`, `metadata`, etc.\n * * @default false\n * @see https://docs.reown.com/appkit/overview\n */\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n /** * List of default RPC endpoints mapped by network \n * @default DEFAULT_RPCS\n */\n defaultRpcList?: RpcMap;\n\n /** * The default RPC endpoint to use if none is selected \n * @default DEFAULT_RPCS.mainnet[0]\n */\n defaultRpcUrl?: string;\n\n /** * LocalStorage key for saving custom RPC list \n * @default 'all-rpc-urls'\n */\n LS_KEY_RPC_LIST?: string;\n\n /** * LocalStorage key for saving default RPC endpoint \n * @default 'curr-rpc'\n */\n LS_KEY_RPC_DEFAULT?: string;\n\n /** * LocalStorage key for saving selected cluster \n * @default 'solana-cluster'\n */\n LS_KEY_CLUSTER?: string;\n\n /** * Persist cluster selection in LocalStorage \n * @default true\n */\n persistClusterSelection?: boolean;\n\n /** * Maximum number of retries for RPC requests \n * @default 3\n */\n MAX_RPC_RETRIES?: number;\n}\n\nexport function SolanaWrapper(props: SolanaWrapperProps) {\n const {\n children,\n\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n walletConnect,\n\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n } = props\n\n\n const RPC_PROVIDER_PROPS = {\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n }\n\n const solanaWalletProviderProps = {\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n\n walletConnect,\n additionalWallets: [],\n coingecko: undefined,\n walletsDisplayConfig: undefined\n }\n\n return (\n <RpcProvider {...RPC_PROVIDER_PROPS}>\n <SolanaWalletProvider {...solanaWalletProviderProps}>\n {children}\n </SolanaWalletProvider>\n </RpcProvider>\n )\n}"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -97,7 +97,7 @@ var useRpcProvider = () => {
97
97
 
98
98
  // src/providers/SolanaWalletProvider.tsx
99
99
  import { useMemo as useMemo2 } from "react";
100
- import { AppProvider, getDefaultConfig } from "@solana/connector/react";
100
+ import { AppProvider, getDefaultConfig, getDefaultMobileConfig } from "@solana/connector/react";
101
101
  import { jsx as jsx2 } from "react/jsx-runtime";
102
102
  function SolanaWalletProvider(props) {
103
103
  const {
@@ -165,13 +165,13 @@ function SolanaWalletProvider(props) {
165
165
  wallets: walletsDisplayConfig
166
166
  });
167
167
  }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);
168
- const mobile = {
169
- appIdentity: {
170
- name: appName,
171
- uri: appOrigin,
172
- icon: appUrl ? `${appOrigin}/favicon.ico` : void 0
173
- }
174
- };
168
+ const mobile = useMemo2(() => {
169
+ return getDefaultMobileConfig({
170
+ appName,
171
+ appUrl: appOrigin,
172
+ network: activeNetwork === "localnet" ? "devnet" : activeNetwork
173
+ });
174
+ }, [appName, appOrigin, activeNetwork]);
175
175
  return /* @__PURE__ */ jsx2(AppProvider, { connectorConfig, mobile, children });
176
176
  }
177
177
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers/RpcProvider.tsx","../src/providers/SolanaWalletProvider.tsx","../src/providers/SolanaWrapper.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n useCallback,\n useMemo,\n type ReactNode\n} from 'react';\nimport { Network, RpcMap } from '../types';\n\n\nconst DEFAULT_RPCS: RpcMap = {\n mainnet: ['https://api.mainnet.solana.com'],\n devnet: ['https://api.devnet.solana.com'],\n testnet: ['https://api.testnet.solana.com'],\n localnet: ['http://localhost:8899'],\n};\n\ninterface RpcContextType {\n rpcUrl: string;\n setRpcUrl: (url: string) => void;\n\n persistClusterSelection: boolean;\n clusterStorageKey: string;\n maxRPCRetries: number;\n\n allRpcUrls: RpcMap;\n addRpcUrl: (network: Network, url: string) => void;\n removeRpcUrl: (network: Network, url: string) => void;\n}\nconst RpcContext = createContext<RpcContextType | null>(null);\n\n\ntype RpcProviderProps = {\n children: ReactNode;\n\n defaultRpcList?: RpcMap;\n defaultRpcUrl?: string;\n\n LS_KEY_RPC_LIST?: string;\n LS_KEY_RPC_DEFAULT?: string;\n LS_KEY_CLUSTER?: string;\n persistClusterSelection?: boolean;\n MAX_RPC_RETRIES?: number;\n};\nexport function RpcProvider(props: RpcProviderProps) {\n const {\n children,\n defaultRpcList = DEFAULT_RPCS,\n defaultRpcUrl = DEFAULT_RPCS.mainnet[0],\n LS_KEY_RPC_LIST = 'all-rpc-urls',\n LS_KEY_RPC_DEFAULT = 'curr-rpc',\n LS_KEY_CLUSTER = 'solana-cluster',\n persistClusterSelection = true,\n MAX_RPC_RETRIES = 3,\n } = props;\n\n const [allRpcUrls, setAllRpcUrls] = useState<RpcMap>(defaultRpcList);\n const [rpcUrl, setRpcUrlState] = useState<string>(defaultRpcUrl);\n\n useEffect(() => {\n const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);\n const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);\n\n if (savedRpc && savedRpc !== rpcUrl) {\n setRpcUrlState(savedRpc);\n }\n\n if (savedHistory) {\n try {\n const parsed = JSON.parse(savedHistory) as RpcMap;\n setAllRpcUrls({\n mainnet: Array.from(new Set([...DEFAULT_RPCS.mainnet, ...(parsed.mainnet || [])])),\n devnet: Array.from(new Set([...DEFAULT_RPCS.devnet, ...(parsed.devnet || [])])),\n testnet: Array.from(new Set([...DEFAULT_RPCS.testnet, ...(parsed.testnet || [])])),\n localnet: Array.from(new Set([...DEFAULT_RPCS.localnet, ...(parsed.localnet || [])])),\n });\n } catch (e) {\n console.error(e);\n }\n }\n }, []);\n\n const setRpcUrl = useCallback((url: string) => {\n setRpcUrlState(url);\n localStorage.setItem(LS_KEY_RPC_DEFAULT, url);\n }, []);\n\n const addRpcUrl = useCallback((network: Network, url: string) => {\n if (!url) return;\n\n setAllRpcUrls((prev) => {\n const newList = Array.from(new Set([...prev[network], url]));\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n\n setRpcUrl(url);\n }, [setRpcUrl]);\n\n const removeRpcUrl = useCallback((network: Network, url: string) => {\n setAllRpcUrls((prev) => {\n let newList = prev[network].filter((rpc) => rpc !== url);\n\n if (newList.length === 0) {\n newList = [...DEFAULT_RPCS[network]];\n }\n\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n }, [LS_KEY_RPC_LIST]);\n\n const value = useMemo<RpcContextType>(() => ({\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: LS_KEY_CLUSTER,\n maxRPCRetries: MAX_RPC_RETRIES,\n rpcUrl,\n setRpcUrl,\n allRpcUrls,\n addRpcUrl,\n removeRpcUrl\n }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);\n\n\n return (\n <RpcContext.Provider value={value}>\n {children}\n </RpcContext.Provider>\n );\n}\n\nexport const useRpcProvider = () => {\n const context = useContext(RpcContext);\n if (!context) {\n throw new Error('useRpcProvider must be used within RpcProvider');\n }\n return context;\n};","'use client';\n\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport { AppProvider, getDefaultConfig, getDefaultMobileConfig, MobileWalletAdapterConfig, SimplifiedWalletConnectConfig, Wallet, WalletDisplayConfig } from '@solana/connector/react';\nimport { Network } from '../types';\nimport { CoinGeckoConfig, SolanaCluster } from '@solana/connector';\nimport { useRpcProvider } from './RpcProvider';\n\ntype SolanaWalletProviderProps = {\n children: ReactNode;\n\n appName?: string;\n appUrl?: string;\n\n autoConnect?: boolean;\n enableMobile?: boolean;\n\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n additionalWallets?: Wallet[];\n coingecko?: CoinGeckoConfig;\n walletsDisplayConfig?: WalletDisplayConfig;\n};\n\nexport function SolanaWalletProvider(props: SolanaWalletProviderProps) {\n const {\n children,\n appName = \"Solana Kit\",\n appUrl,\n autoConnect = true,\n enableMobile = true,\n walletConnect = false,\n additionalWallets = [],\n coingecko,\n walletsDisplayConfig\n } = props;\n\n const {\n persistClusterSelection,\n clusterStorageKey,\n maxRPCRetries,\n rpcUrl, allRpcUrls\n } = useRpcProvider();\n\n const appOrigin = appUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n\n const activeNetwork: Network = useMemo(() => {\n if (allRpcUrls.devnet.includes(rpcUrl)) return 'devnet';\n else if (allRpcUrls.testnet.includes(rpcUrl)) return 'testnet';\n else if (allRpcUrls.localnet.includes(rpcUrl)) return 'localnet';\n return 'mainnet';\n }, [rpcUrl, allRpcUrls]);\n\n const connectorConfig = useMemo(() => {\n\n const clusters: SolanaCluster[] = [\n {\n id: 'solana:mainnet',\n label: 'Mainnet',\n url: activeNetwork === 'mainnet' ? rpcUrl : allRpcUrls.mainnet[0],\n },\n {\n id: 'solana:localnet',\n label: 'Localnet',\n url: activeNetwork === 'localnet' ? rpcUrl : allRpcUrls.localnet[0],\n },\n {\n id: 'solana:devnet',\n label: 'Devnet',\n url: activeNetwork === 'devnet' ? rpcUrl : allRpcUrls.devnet[0],\n },\n {\n id: 'solana:testnet',\n label: 'Testnet',\n url: activeNetwork === 'testnet' ? rpcUrl : allRpcUrls.testnet[0],\n },\n ];\n\n return getDefaultConfig({\n appName: appName,\n appUrl: appOrigin,\n autoConnect: autoConnect,\n\n network: activeNetwork,\n enableMobile: enableMobile,\n\n // from RPC settings\n clusters,\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: clusterStorageKey,\n maxRetries: maxRPCRetries,\n\n walletConnect: walletConnect,\n additionalWallets: additionalWallets,\n coingecko: coingecko,\n wallets: walletsDisplayConfig\n\n });\n }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);\n\n // const mobile = useMemo(\n // () =>\n // getDefaultMobileConfig({\n // appName: appName,\n // appUrl: appOrigin,\n // network: activeNetwork === 'localnet' ? 'devnet' : activeNetwork,\n // }),\n // [appName, appOrigin, activeNetwork],\n // );\n\n // console.error(mobile.appIdentity)\n\n const mobile: MobileWalletAdapterConfig = {\n appIdentity: {\n name: appName,\n uri: appOrigin,\n icon: appUrl ? `${appOrigin}/favicon.ico` : undefined,\n }\n }\n\n\n return (\n <AppProvider connectorConfig={connectorConfig} mobile={mobile} >\n {children}\n </AppProvider >\n );\n}","\"use client\";\n\nimport { SimplifiedWalletConnectConfig } from \"@solana/connector\";\nimport { RpcMap } from \"../types\";\nimport { RpcProvider } from \"./RpcProvider\";\nimport { SolanaWalletProvider } from \"./SolanaWalletProvider\";\n\ntype SolanaWrapperProps = {\n children: React.ReactNode;\n\n /** * Name of your app (displayed in wallet connection modals) \n * @default \"Solana Kit\"\n */\n appName?: string;\n\n /** * URL of your app (used for deep linking) \n */\n appUrl?: string;\n\n /** * Automatically connect to the last used wallet on load.\n * @default true\n */\n autoConnect?: boolean;\n\n /** * Enable mobile wallets (e.g. Phantom on iOS/Android) \n * @default true\n */\n enableMobile?: boolean;\n\n /** * Enable WalletConnect support \n * Enable or configure WalletConnect support for QR code and deep-link connections.\n * * **Mobile-First Note:** Setting this to `false` (default) reduces initial bundle size. \n * Enable this if you need to support desktop-to-mobile connections via QR codes.\n * * - `false`: (Default) Disables WalletConnect.\n * - `true`: Enables using `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` from your environment.\n * - `object`: Provides manual overrides for `projectId`, `metadata`, etc.\n * * @default false\n * @see https://docs.reown.com/appkit/overview\n */\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n /** * List of default RPC endpoints mapped by network \n * @default DEFAULT_RPCS\n */\n defaultRpcList?: RpcMap;\n\n /** * The default RPC endpoint to use if none is selected \n * @default DEFAULT_RPCS.mainnet[0]\n */\n defaultRpcUrl?: string;\n\n /** * LocalStorage key for saving custom RPC list \n * @default 'all-rpc-urls'\n */\n LS_KEY_RPC_LIST?: string;\n\n /** * LocalStorage key for saving default RPC endpoint \n * @default 'curr-rpc'\n */\n LS_KEY_RPC_DEFAULT?: string;\n\n /** * LocalStorage key for saving selected cluster \n * @default 'solana-cluster'\n */\n LS_KEY_CLUSTER?: string;\n\n /** * Persist cluster selection in LocalStorage \n * @default true\n */\n persistClusterSelection?: boolean;\n\n /** * Maximum number of retries for RPC requests \n * @default 3\n */\n MAX_RPC_RETRIES?: number;\n}\n\nexport function SolanaWrapper(props: SolanaWrapperProps) {\n const {\n children,\n\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n walletConnect,\n\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n } = props\n\n\n const RPC_PROVIDER_PROPS = {\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n }\n\n const solanaWalletProviderProps = {\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n\n walletConnect,\n additionalWallets: [],\n coingecko: undefined,\n walletsDisplayConfig: undefined\n }\n\n return (\n <RpcProvider {...RPC_PROVIDER_PROPS}>\n <SolanaWalletProvider {...solanaWalletProviderProps}>\n {children}\n </SolanaWalletProvider>\n </RpcProvider>\n )\n}"],"mappings":"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","names":["useMemo","jsx","useMemo","jsx"]}
1
+ {"version":3,"sources":["../src/providers/RpcProvider.tsx","../src/providers/SolanaWalletProvider.tsx","../src/providers/SolanaWrapper.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n useCallback,\n useMemo,\n type ReactNode\n} from 'react';\nimport { Network, RpcMap } from '../types';\n\n\nconst DEFAULT_RPCS: RpcMap = {\n mainnet: ['https://api.mainnet.solana.com'],\n devnet: ['https://api.devnet.solana.com'],\n testnet: ['https://api.testnet.solana.com'],\n localnet: ['http://localhost:8899'],\n};\n\ninterface RpcContextType {\n rpcUrl: string;\n setRpcUrl: (url: string) => void;\n\n persistClusterSelection: boolean;\n clusterStorageKey: string;\n maxRPCRetries: number;\n\n allRpcUrls: RpcMap;\n addRpcUrl: (network: Network, url: string) => void;\n removeRpcUrl: (network: Network, url: string) => void;\n}\nconst RpcContext = createContext<RpcContextType | null>(null);\n\n\ntype RpcProviderProps = {\n children: ReactNode;\n\n defaultRpcList?: RpcMap;\n defaultRpcUrl?: string;\n\n LS_KEY_RPC_LIST?: string;\n LS_KEY_RPC_DEFAULT?: string;\n LS_KEY_CLUSTER?: string;\n persistClusterSelection?: boolean;\n MAX_RPC_RETRIES?: number;\n};\nexport function RpcProvider(props: RpcProviderProps) {\n const {\n children,\n defaultRpcList = DEFAULT_RPCS,\n defaultRpcUrl = DEFAULT_RPCS.mainnet[0],\n LS_KEY_RPC_LIST = 'all-rpc-urls',\n LS_KEY_RPC_DEFAULT = 'curr-rpc',\n LS_KEY_CLUSTER = 'solana-cluster',\n persistClusterSelection = true,\n MAX_RPC_RETRIES = 3,\n } = props;\n\n const [allRpcUrls, setAllRpcUrls] = useState<RpcMap>(defaultRpcList);\n const [rpcUrl, setRpcUrlState] = useState<string>(defaultRpcUrl);\n\n useEffect(() => {\n const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);\n const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);\n\n if (savedRpc && savedRpc !== rpcUrl) {\n setRpcUrlState(savedRpc);\n }\n\n if (savedHistory) {\n try {\n const parsed = JSON.parse(savedHistory) as RpcMap;\n setAllRpcUrls({\n mainnet: Array.from(new Set([...DEFAULT_RPCS.mainnet, ...(parsed.mainnet || [])])),\n devnet: Array.from(new Set([...DEFAULT_RPCS.devnet, ...(parsed.devnet || [])])),\n testnet: Array.from(new Set([...DEFAULT_RPCS.testnet, ...(parsed.testnet || [])])),\n localnet: Array.from(new Set([...DEFAULT_RPCS.localnet, ...(parsed.localnet || [])])),\n });\n } catch (e) {\n console.error(e);\n }\n }\n }, []);\n\n const setRpcUrl = useCallback((url: string) => {\n setRpcUrlState(url);\n localStorage.setItem(LS_KEY_RPC_DEFAULT, url);\n }, []);\n\n const addRpcUrl = useCallback((network: Network, url: string) => {\n if (!url) return;\n\n setAllRpcUrls((prev) => {\n const newList = Array.from(new Set([...prev[network], url]));\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n\n setRpcUrl(url);\n }, [setRpcUrl]);\n\n const removeRpcUrl = useCallback((network: Network, url: string) => {\n setAllRpcUrls((prev) => {\n let newList = prev[network].filter((rpc) => rpc !== url);\n\n if (newList.length === 0) {\n newList = [...DEFAULT_RPCS[network]];\n }\n\n const newState = { ...prev, [network]: newList };\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\n return newState;\n });\n }, [LS_KEY_RPC_LIST]);\n\n const value = useMemo<RpcContextType>(() => ({\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: LS_KEY_CLUSTER,\n maxRPCRetries: MAX_RPC_RETRIES,\n rpcUrl,\n setRpcUrl,\n allRpcUrls,\n addRpcUrl,\n removeRpcUrl\n }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);\n\n\n return (\n <RpcContext.Provider value={value}>\n {children}\n </RpcContext.Provider>\n );\n}\n\nexport const useRpcProvider = () => {\n const context = useContext(RpcContext);\n if (!context) {\n throw new Error('useRpcProvider must be used within RpcProvider');\n }\n return context;\n};","'use client';\n\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport { AppProvider, getDefaultConfig, getDefaultMobileConfig, MobileWalletAdapterConfig, SimplifiedWalletConnectConfig, Wallet, WalletDisplayConfig } from '@solana/connector/react';\nimport { Network } from '../types';\nimport { CoinGeckoConfig, SolanaCluster } from '@solana/connector';\nimport { useRpcProvider } from './RpcProvider';\n\ntype SolanaWalletProviderProps = {\n children: ReactNode;\n\n appName?: string;\n appUrl?: string;\n\n autoConnect?: boolean;\n enableMobile?: boolean;\n\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n additionalWallets?: Wallet[];\n coingecko?: CoinGeckoConfig;\n walletsDisplayConfig?: WalletDisplayConfig;\n};\n\nexport function SolanaWalletProvider(props: SolanaWalletProviderProps) {\n const {\n children,\n appName = \"Solana Kit\",\n appUrl,\n autoConnect = true,\n enableMobile = true,\n walletConnect = false,\n additionalWallets = [],\n coingecko,\n walletsDisplayConfig\n } = props;\n\n const {\n persistClusterSelection,\n clusterStorageKey,\n maxRPCRetries,\n rpcUrl, allRpcUrls\n } = useRpcProvider();\n\n const appOrigin = appUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n\n const activeNetwork: Network = useMemo(() => {\n if (allRpcUrls.devnet.includes(rpcUrl)) return 'devnet';\n else if (allRpcUrls.testnet.includes(rpcUrl)) return 'testnet';\n else if (allRpcUrls.localnet.includes(rpcUrl)) return 'localnet';\n return 'mainnet';\n }, [rpcUrl, allRpcUrls]);\n\n const connectorConfig = useMemo(() => {\n\n const clusters: SolanaCluster[] = [\n {\n id: 'solana:mainnet',\n label: 'Mainnet',\n url: activeNetwork === 'mainnet' ? rpcUrl : allRpcUrls.mainnet[0],\n },\n {\n id: 'solana:localnet',\n label: 'Localnet',\n url: activeNetwork === 'localnet' ? rpcUrl : allRpcUrls.localnet[0],\n },\n {\n id: 'solana:devnet',\n label: 'Devnet',\n url: activeNetwork === 'devnet' ? rpcUrl : allRpcUrls.devnet[0],\n },\n {\n id: 'solana:testnet',\n label: 'Testnet',\n url: activeNetwork === 'testnet' ? rpcUrl : allRpcUrls.testnet[0],\n },\n ];\n\n return getDefaultConfig({\n appName: appName,\n appUrl: appOrigin,\n autoConnect: autoConnect,\n\n network: activeNetwork,\n enableMobile: enableMobile,\n\n // from RPC settings\n clusters,\n persistClusterSelection: persistClusterSelection,\n clusterStorageKey: clusterStorageKey,\n maxRetries: maxRPCRetries,\n\n walletConnect: walletConnect,\n additionalWallets: additionalWallets,\n coingecko: coingecko,\n wallets: walletsDisplayConfig\n\n });\n }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);\n\n const mobile = useMemo(() => {\n return getDefaultMobileConfig({\n appName: appName,\n appUrl: appOrigin,\n network: activeNetwork === 'localnet' ? 'devnet' : activeNetwork,\n });\n }, [appName, appOrigin, activeNetwork]);\n\n\n return (\n <AppProvider connectorConfig={connectorConfig} mobile={mobile} >\n {children}\n </AppProvider >\n );\n}","\"use client\";\n\nimport { SimplifiedWalletConnectConfig } from \"@solana/connector\";\nimport { RpcMap } from \"../types\";\nimport { RpcProvider } from \"./RpcProvider\";\nimport { SolanaWalletProvider } from \"./SolanaWalletProvider\";\n\ntype SolanaWrapperProps = {\n children: React.ReactNode;\n\n /** * Name of your app (displayed in wallet connection modals) \n * @default \"Solana Kit\"\n */\n appName?: string;\n\n /** * URL of your app (used for deep linking) \n */\n appUrl?: string;\n\n /** * Automatically connect to the last used wallet on load.\n * @default true\n */\n autoConnect?: boolean;\n\n /** * Enable mobile wallets (e.g. Phantom on iOS/Android) \n * @default true\n */\n enableMobile?: boolean;\n\n /** * Enable WalletConnect support \n * Enable or configure WalletConnect support for QR code and deep-link connections.\n * * **Mobile-First Note:** Setting this to `false` (default) reduces initial bundle size. \n * Enable this if you need to support desktop-to-mobile connections via QR codes.\n * * - `false`: (Default) Disables WalletConnect.\n * - `true`: Enables using `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` from your environment.\n * - `object`: Provides manual overrides for `projectId`, `metadata`, etc.\n * * @default false\n * @see https://docs.reown.com/appkit/overview\n */\n walletConnect?: boolean | SimplifiedWalletConnectConfig;\n /** * List of default RPC endpoints mapped by network \n * @default DEFAULT_RPCS\n */\n defaultRpcList?: RpcMap;\n\n /** * The default RPC endpoint to use if none is selected \n * @default DEFAULT_RPCS.mainnet[0]\n */\n defaultRpcUrl?: string;\n\n /** * LocalStorage key for saving custom RPC list \n * @default 'all-rpc-urls'\n */\n LS_KEY_RPC_LIST?: string;\n\n /** * LocalStorage key for saving default RPC endpoint \n * @default 'curr-rpc'\n */\n LS_KEY_RPC_DEFAULT?: string;\n\n /** * LocalStorage key for saving selected cluster \n * @default 'solana-cluster'\n */\n LS_KEY_CLUSTER?: string;\n\n /** * Persist cluster selection in LocalStorage \n * @default true\n */\n persistClusterSelection?: boolean;\n\n /** * Maximum number of retries for RPC requests \n * @default 3\n */\n MAX_RPC_RETRIES?: number;\n}\n\nexport function SolanaWrapper(props: SolanaWrapperProps) {\n const {\n children,\n\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n walletConnect,\n\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n } = props\n\n\n const RPC_PROVIDER_PROPS = {\n defaultRpcList,\n defaultRpcUrl,\n LS_KEY_RPC_LIST,\n LS_KEY_RPC_DEFAULT,\n LS_KEY_CLUSTER,\n persistClusterSelection,\n MAX_RPC_RETRIES,\n\n }\n\n const solanaWalletProviderProps = {\n appName,\n appUrl,\n\n autoConnect,\n enableMobile,\n\n walletConnect,\n additionalWallets: [],\n coingecko: undefined,\n walletsDisplayConfig: undefined\n }\n\n return (\n <RpcProvider {...RPC_PROVIDER_PROPS}>\n <SolanaWalletProvider {...solanaWalletProviderProps}>\n {children}\n </SolanaWalletProvider>\n </RpcProvider>\n )\n}"],"mappings":"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","names":["useMemo","jsx","useMemo","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algobright/solana-connector",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/algobright/solana-connector.git"
@@ -48,30 +48,35 @@
48
48
  "prepublishOnly": "npm run build"
49
49
  },
50
50
  "dependencies": {
51
+ "@solana/kit": "^6.0.0",
52
+ "@solana/connector": "^0.2.0",
51
53
  "@base-ui/react": "^1.1.0",
52
- "@solana-program/token": "^0.9.0",
53
- "@solana-program/token-2022": "^0.6.1",
54
- "@solana/connector": "^0.2.3",
55
- "@solana/kit": "^5.4.0",
56
- "@solana/web3.js": "^1.98.4",
57
- "@types/qrcode": "^1.5.6",
58
54
  "clsx": "^2.1.1",
59
55
  "esbuild-css-modules-plugin": "^3.1.5",
60
56
  "lucide-react": "^0.563.0",
61
- "motion": "^12.29.0",
57
+ "motion": "^12.34.0",
62
58
  "qrcode": "^1.5.4",
63
59
  "react-icons": "^5.5.0"
64
60
  },
65
61
  "peerDependencies": {
66
62
  "react": ">=18.0.0",
63
+ "@solana/web3.js": "^1.0.0",
67
64
  "react-dom": ">=18.0.0"
68
65
  },
66
+ "peerDependenciesMeta": {
67
+ "@solana/web3.js": {
68
+ "optional": true
69
+ }
70
+ },
69
71
  "devDependencies": {
70
- "@types/react": "^19.0.0",
71
- "@types/react-dom": "^19.0.0",
72
+ "@solana/kit": "^5.4.0",
73
+ "@solana/connector": "^0.2.4",
74
+ "@types/qrcode": "^1.5.6",
75
+ "@types/react": "^19.2.13",
76
+ "@types/react-dom": "^19.2.3",
72
77
  "postcss": "^8.5.6",
73
- "react": "^19.0.0",
74
- "react-dom": "^19.0.0",
78
+ "react": "^19.2.4",
79
+ "react-dom": "^19.2.4",
75
80
  "tsup": "^8.5.1",
76
81
  "typescript": "^5.9.3"
77
82
  }