@algobright/solana-connector 0.1.6 → 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.
- package/dist/ConnectButton.js +9 -5
- package/dist/ConnectButton.js.map +1 -1
- package/dist/ConnectButton.mjs +10 -6
- package/dist/ConnectButton.mjs.map +1 -1
- package/dist/WalletDropdown.js +9 -5
- package/dist/WalletDropdown.js.map +1 -1
- package/dist/WalletDropdown.mjs +10 -6
- package/dist/WalletDropdown.mjs.map +1 -1
- package/package.json +10 -7
|
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,iBAAAA;AAAA;AAAA;;;ACAA,IAAAC,gBAA4C;AAC5C,IAAAC,cAA0B;AAC1B,4BAAmB;AACnB,IAAAD,gBAAuB;;;ACHvB,mBAAyB;AACzB,oBAAmB;AACnB,0BAAuB;AAmBP;AAXT,SAAS,OAAO;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AACZ,GAAgB;AACZ,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,SACI,4CAAC,SAAI,WAAW,cAAAE,QAAO,QAAQ,cAAY,OACtC,iBAAO,CAAC,WACL;AAAA,IAAC;AAAA;AAAA,MACG;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,SAAS,MAAM,YAAY,IAAI;AAAA;AAAA,EACnC,IAEA,4CAAC,SAAI,WAAW,cAAAA,QAAO,UAAU,OAAO,EAAE,QAAQ,MAAM,GACpD,sDAAC,8BAAO,GACZ,GAER;AAER;;;ACjCA,IAAO,iBAAQ;;;AFGf,IAAAC,uBAAmE;;;AGHnE,IAAAC,gBAA2B;AAC3B,oBAAqC;AACrC,oBAAmB;AAeP,IAAAC,sBAAA;AAHZ,IAAM,aAAS;AAAA,EACX,CAAC,EAAE,WAAW,UAAU,WAAW,OAAO,WAAW,GAAG,MAAM,GAAG,QAAQ;AACrE,WACI;AAAA,MAAC,cAAAC;AAAA,MAAA;AAAA,QACG;AAAA,QAEA,WAAW,GAAG,cAAAC,QAAO,MAAM,IAAI,aAAa,EAAE;AAAA,QAC9C,gBAAc;AAAA,QACd,aAAW;AAAA,QAEV,GAAG;AAAA;AAAA,IACR;AAAA,EAER;AACJ;AACA,OAAO,cAAc;AAErB,IAAO,iBAAQ;;;AC/Bf,IAAOC,kBAAQ;;;AJKf,IAAAC,oBAAoF;AACpF,kBAAqB;;;AKRrB,mBAAuC;AACvC,uBAAwD;AACxD,iBAAgC;AAEhC,eAAsB,cAClB,QACA,QACe;AACf,MAAI,UAAU;AACd,MAAI;AACA,UAAM,SAAS,OAAO,UAAU;AAChC,QAAI,CAAC,QAAQ;AACT,cAAQ,MAAM,oDAAoD;AAClE,aAAO;AAAA,IACX;AACA,UAAM,oBAAgB,0BAAQ,MAAM;AACpC,UAAM,UAAM,4BAAgB,MAAM;AAClC,UAAM,kBAAkB,MAAM,IAAI,WAAW,aAAa,EAAE,KAAK;AACjE,kBAAU,gCAAc,gBAAgB,KAAK;AAAA,EACjD,SAAS,OAAO;AACZ,YAAQ,MAAM,+BAA+B,KAAK;AAAA,EACtD,UAAE;AACE,WAAO;AAAA,EACX;AACJ;AAEA,eAAsB,gBAClB,QACA,QACA,aACe;AA9BnB;AA+BI,MAAI,UAAU;AACd,MAAI;AACA,UAAM,SAAS,OAAO,UAAU;AAChC,QAAI,CAAC,QAAQ;AACT,cAAQ,MAAM,oDAAoD;AAClE,aAAO;AAAA,IACX;AACA,UAAM,oBAAgB,0BAAQ,MAAM;AACpC,UAAM,iBAAa,0BAAQ,WAAW;AACtC,UAAM,UAAM,4BAAgB,MAAM;AAElC,UAAM,WAAW,MAAM,IAAI;AAAA,MACvB;AAAA,MACA,EAAE,UAAU,SAAS;AAAA,IACzB,EAAE,KAAK;AAEP,UAAM,gBAAe,cAAS,UAAT,mBAAgB;AACrC,QAAI,CAAC,cAAc;AACf,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACvD;AACA,UAAM,mBAAe,0BAAQ,YAAY;AACzC,UAAM,CAAC,QAAQ,IAAI,UAAM,qCAAuB;AAAA,MAC5C,MAAM;AAAA,MACN,OAAO;AAAA,MACP;AAAA,IACJ,CAAC;AACD,UAAM,eAAe,MAAM,IAAI,uBAAuB,QAAQ,EAAE,KAAK;AACrE,QAAI,aAAa,OAAO;AACpB,gBAAU,WAAW,aAAa,MAAM,cAAc;AAAA,IAC1D;AAAA,EACJ,SAAS,OAAO;AAAA,EAEhB,UAAE;AACE,WAAO;AAAA,EACX;AACJ;;;AL+EwB,IAAAC,sBAAA;AAnGxB,IAAM,eAAuC;AAAA,EACzC,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AACvB;AAEO,SAAS,eAAe,OAA4B;AACvD,QAAM,aAAS,sCAAmB;AAElC,QAAM;AAAA,IAAE;AAAA,IACJ,QAAQ;AAAA,IACR,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB;AAAA,EACJ,IAAI;AAEJ,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAuB,QAAQ;AACvD,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAE1C,QAAM,EAAE,SAAS,UAAU,QAAI,gCAAa;AAC5C,QAAM,yBAAqB,sBAAO,KAAK;AACvC,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAAS,KAAK;AAEhE,QAAM,2BAAuB,sBAAO,KAAK;AACzC,QAAM,CAAC,+BAA+B,gCAAgC,QAAI,wBAAS,KAAK;AAExF,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAwB,IAAI;AAChE,QAAM,CAAC,qBAAqB,sBAAsB,QAAI,wBAAwB,IAAI;AAElF,QAAM,kBAAkB,WAAW;AACnC,QAAM,cAAa,uCAAW,SAAQ;AACtC,QAAM,cAAa,uCAAW,SAAQ;AACtC,QAAM,eAAe,GAAG,gBAAgB,MAAM,GAAG,CAAC,CAAC,MAAM,gBAAgB,MAAM,EAAE,CAAC;AAElF,iBAAe,aAAa;AACxB,QAAI;AACA,YAAM,UAAU,UAAU,UAAU,eAAe;AACnD,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IAC3C,SAAS,OAAO;AACZ,gBAAU,KAAK;AACf,cAAQ,MAAM,gCAAgC,KAAK;AAAA,IACvD;AAAA,EACJ;AAEA,iBAAe,kBAAkB;AAC7B,QAAI,CAAC,UAAU,mBAAmB,QAAS;AAC3C,yBAAqB,IAAI;AACzB,uBAAmB,UAAU;AAE7B,UAAMC,cAAa,MAAM,cAAc,QAAQ,eAAe;AAC9D,kBAAcA,WAAU;AAExB,yBAAqB,KAAK;AAC1B,uBAAmB,UAAU;AAAA,EACjC;AAEA,iBAAe,2BAA2B;AACtC,QAAI,CAAC,oBAAoB,CAAC,iBAAiB,WAAW,CAAC,UAAU,qBAAqB,QAAS;AAE/F,UAAM,qBAAiB,uBAAU,iBAAiB,OAAO;AACzD,QAAI,CAAC,gBAAgB;AACjB,cAAQ,MAAM,kCAAkC,gBAAgB;AAChE;AAAA,IACJ;AAEA,qCAAiC,IAAI;AACrC,yBAAqB,UAAU;AAE/B,UAAM,eAAe,MAAM,gBAAgB,QAAQ,iBAAiB,iBAAiB,OAAO;AAC5F,2BAAuB,YAAY;AAEnC,qCAAiC,KAAK;AACtC,yBAAqB,UAAU;AAAA,EACnC;AAEA,+BAAU,MAAM;AACZ,QAAI,kBAAkB,mBAAmB,QAAQ;AAC7C,sBAAgB;AAAA,IACpB;AACA,QAAI,oBAAoB,mBAAmB,QAAQ;AAC/C,+BAAyB;AAAA,IAC7B;AAAA,EACJ,GAAG,CAAC,iBAAiB,QAAQ,gBAAgB,gBAAgB,CAAC;AAE9D,MAAI,SAAS,UAAU;AACnB,WACI;AAAA,MAAC,qBAAO;AAAA,MAAP;AAAA,QACG,SAAS,EAAE,SAAS,EAAE;AAAA,QACtB,SAAS,EAAE,SAAS,EAAE;AAAA,QACtB,MAAM,EAAE,SAAS,EAAE;AAAA,QACnB,YAAY,EAAE,UAAU,IAAI;AAAA,QAC5B,eAAW,kBAAK,sBAAAC,QAAO,gBAAgB,eAAe;AAAA,QACtD,cAAY;AAAA,QAGZ;AAAA,wDAAC,SAAI,WAAW,sBAAAA,QAAO,QACnB;AAAA,0DAAC,SAAI,WAAW,sBAAAA,QAAO,kBACnB;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACG,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,KAAK;AAAA,kBACL,KAAK;AAAA;AAAA,cACT;AAAA,cACA,8CAAC,SAAI,WAAW,sBAAAA,QAAO,SACnB;AAAA,6DAAC,UAAK,WAAW,sBAAAA,QAAO,cAAe,wBAAa;AAAA,gBACpD,6CAAC,UAAK,WAAW,sBAAAA,QAAO,YAAa,sBAAW;AAAA,iBACpD;AAAA,eACJ;AAAA,YAEA,8CAAC,SAAI,WAAW,sBAAAA,QAAO,SACnB;AAAA;AAAA,gBAACC;AAAA,gBAAA;AAAA,kBACG,MAAK;AAAA,kBACL,SAAS;AAAA,kBACT,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,OAAO,SAAS,YAAY;AAAA,kBAE3B,mBACG,6CAAC,8BAAM,WAAW,sBAAAD,QAAO,WAAW,IACpC,6CAAC,6BAAK;AAAA;AAAA,cAEd;AAAA,cAGC,sBACG;AAAA,gBAAC;AAAA;AAAA,kBACG,QAAQ,CAAC,EAAE,QAAQ,MACf;AAAA,oBAACC;AAAA,oBAAA;AAAA,sBACG,MAAK;AAAA,sBACL,SAAQ;AAAA,sBACR,MAAK;AAAA,sBACL,SAAS,MAAM,QAAQ,SAAS;AAAA,sBAChC,OAAO,aAAY,mCAAS,UAAS,SAAS;AAAA,sBAE9C;AAAA,qEAAC,8BAAM;AAAA,wBACP;AAAA,0BAAC;AAAA;AAAA,4BACG,WAAW,sBAAAD,QAAO;AAAA,4BAClB,OAAO,EAAE,YAAY,cAAa,mCAAS,OAAM,gBAAgB,EAAE;AAAA;AAAA,wBACvE;AAAA;AAAA;AAAA,kBACJ;AAAA;AAAA,cAER;AAAA,eAER;AAAA,aACJ;AAAA,UAEC,kBACG,8CAAC,SAAI,WAAW,sBAAAA,QAAO,gBACnB;AAAA;AAAA,cAAC;AAAA;AAAA,gBACG,WAAW,sBAAAA,QAAO;AAAA,gBAElB;AAAA,+DAAC,UAAK,WAAW,sBAAAA,QAAO,cAAc,qBAAO;AAAA,kBAC7C;AAAA,oBAAC;AAAA;AAAA,sBACG,SAAS,MAAM,gBAAgB;AAAA,sBAC/B,UAAU;AAAA,sBACV,OAAM;AAAA,sBACN,WAAW,sBAAAA,QAAO;AAAA,sBAClB,gBAAc;AAAA,sBAEd;AAAA,wBAAC;AAAA;AAAA,0BACG,WAAW,sBAAAA,QAAO;AAAA;AAAA,sBACtB;AAAA;AAAA,kBACJ;AAAA;AAAA;AAAA,YACJ;AAAA,YACA,6CAAC,SAAI,WAAW,sBAAAA,QAAO,cAAc,OAAO,OAAO,UAAU,KAAK,KAC7D,8BACG,6CAAC,SAAI,WAAW,sBAAAA,QAAO,gBAAgB,IACvC,eAAe,OACf,GAAG,WAAW,QAAQ,CAAC,CAAC,SAExB,UAER;AAAA,aACJ;AAAA,UAGH,oBACG,8CAAC,SAAI,WAAW,sBAAAA,QAAO,gBACnB;AAAA;AAAA,cAAC;AAAA;AAAA,gBACG,WAAW,sBAAAA,QAAO;AAAA,gBAElB;AAAA,+DAAC,UAAK,WAAW,sBAAAA,QAAO,cAAc,qBAAO;AAAA,kBAC7C;AAAA,oBAAC;AAAA;AAAA,sBACG,SAAS,MAAM,yBAAyB;AAAA,sBACxC,UAAU;AAAA,sBACV,OAAM;AAAA,sBACN,WAAW,sBAAAA,QAAO;AAAA,sBAClB,gBAAc;AAAA,sBAEd;AAAA,wBAAC;AAAA;AAAA,0BACG,WAAW,sBAAAA,QAAO;AAAA;AAAA,sBACtB;AAAA;AAAA,kBACJ;AAAA;AAAA;AAAA,YACJ;AAAA,YACA,6CAAC,SAAI,WAAW,sBAAAA,QAAO,cAAc,OAAO,OAAO,mBAAmB,KAAK,KACtE,0CACG,6CAAC,SAAI,WAAW,sBAAAA,QAAO,gBAAgB,IACvC,wBAAwB,OACxB,GAAG,oBAAoB,QAAQ,CAAC,CAAC,KAAI,qDAAkB,WAAU,EAAE,KAEnE,OAAM,qDAAkB,WAAU,EAAE,IAE5C;AAAA,aACJ;AAAA,UAGJ;AAAA,YAAC;AAAA;AAAA,cACG,QAAQ,CAAC,EAAE,YAAY,cAAc,MACjC;AAAA,gBAACC;AAAA,gBAAA;AAAA,kBACG,SAAQ;AAAA,kBACR,WAAW,sBAAAD,QAAO;AAAA,kBAClB,SAAS;AAAA,kBACT,UAAU;AAAA,kBAEV;AAAA,iEAAC,+BAAO,WAAW,sBAAAA,QAAO,gBAAgB;AAAA,oBACzC,gBAAgB,qBAAqB;AAAA;AAAA;AAAA,cAC1C;AAAA;AAAA,UAER;AAAA;AAAA;AAAA,IACJ;AAAA,EAER;AAGA,MAAI,SAAS,WAAW;AACpB,WACI;AAAA,MAAC,qBAAO;AAAA,MAAP;AAAA,QACG,SAAS,EAAE,SAAS,EAAE;AAAA,QACtB,SAAS,EAAE,SAAS,EAAE;AAAA,QACtB,MAAM,EAAE,SAAS,EAAE;AAAA,QACnB,YAAY,EAAE,UAAU,IAAI;AAAA,QAC5B,eAAW,kBAAK,sBAAAA,QAAO,gBAAgB,eAAe;AAAA,QACtD,cAAY;AAAA,QAGZ;AAAA,wDAAC,SAAI,WAAW,sBAAAA,QAAO,eACnB;AAAA;AAAA,cAACC;AAAA,cAAA;AAAA,gBACG,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,QAAQ,QAAQ;AAAA,gBAC/B,OAAO;AAAA,gBACP,WAAW,sBAAAD,QAAO;AAAA,gBAElB,uDAAC,oCAAY;AAAA;AAAA,YACjB;AAAA,YACA,6CAAC,UAAK,8BAAgB;AAAA,aAC1B;AAAA,UAGA;AAAA,YAAC;AAAA;AAAA,cACG,QAAQ,CAAC,EAAE,SAAS,UAAU,WAAW,MAAM;AAC3C,sBAAM,oBAAoB,mCAA6B,OAAM;AAC7D,uBACI,6CAAC,SAAI,WAAW,sBAAAA,QAAO,gBAClB,mBAAS,IAAI,CAAC,YAAY;AACvB,wBAAM,aAAa,qBAAqB,QAAQ;AAChD,yBACI;AAAA,oBAAC;AAAA;AAAA,sBAEG,MAAK;AAAA,sBACL,UAAU;AAAA,sBACV,SAAS,MAAM,WAAW,QAAQ,EAAE;AAAA,sBACpC,WAAW,OAAK;AACZ,4BAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACpC,4BAAE,eAAe;AACjB,qCAAW,QAAQ,EAAE;AAAA,wBACzB;AAAA,sBACJ;AAAA,sBACA,WAAW,sBAAAA,QAAO;AAAA,sBAElB;AAAA,sEAAC,SAAI,WAAW,sBAAAA,QAAO,aACnB;AAAA;AAAA,4BAAC;AAAA;AAAA,8BACG,WAAW,sBAAAA,QAAO;AAAA,8BAClB,OAAO,EAAE,YAAY,aAAa,QAAQ,EAAE,EAAE;AAAA;AAAA,0BAClD;AAAA,0BACA,6CAAC,UAAK,WAAW,sBAAAA,QAAO,cAAe,kBAAQ,OAAM;AAAA,2BACzD;AAAA,wBACA,6CAAC,SAAI,WAAW,sBAAAA,QAAO,WAAW,iBAAe,YAC5C,wBAAc,6CAAC,8BAAM,GAC1B;AAAA;AAAA;AAAA,oBArBK,QAAQ;AAAA,kBAsBjB;AAAA,gBAER,CAAC,GACL;AAAA,cAER;AAAA;AAAA,UACJ;AAAA;AAAA;AAAA,IACJ;AAAA,EAER;AACJ;AAEA,IAAO,yBAAQ;;;ADnVf,IAAOE,0BAAQ;","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"]}
|
package/dist/WalletDropdown.mjs
CHANGED
|
@@ -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
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@algobright/solana-connector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/algobright/solana-connector.git"
|
|
@@ -48,6 +48,8 @@
|
|
|
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
54
|
"clsx": "^2.1.1",
|
|
53
55
|
"esbuild-css-modules-plugin": "^3.1.5",
|
|
@@ -57,17 +59,18 @@
|
|
|
57
59
|
"react-icons": "^5.5.0"
|
|
58
60
|
},
|
|
59
61
|
"peerDependencies": {
|
|
60
|
-
"@solana-program/token": "^0.9.0",
|
|
61
|
-
"@solana-program/token-2022": "^0.6.1",
|
|
62
|
-
"@solana/connector": "^0.2.3",
|
|
63
|
-
"@solana/kit": "^5.4.0",
|
|
64
|
-
"@solana/web3.js": "^1.98.4",
|
|
65
62
|
"react": ">=18.0.0",
|
|
63
|
+
"@solana/web3.js": "^1.0.0",
|
|
66
64
|
"react-dom": ">=18.0.0"
|
|
67
65
|
},
|
|
66
|
+
"peerDependenciesMeta": {
|
|
67
|
+
"@solana/web3.js": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
68
71
|
"devDependencies": {
|
|
72
|
+
"@solana/kit": "^5.4.0",
|
|
69
73
|
"@solana/connector": "^0.2.4",
|
|
70
|
-
"@solana/web3.js": "^1.98.4",
|
|
71
74
|
"@types/qrcode": "^1.5.6",
|
|
72
75
|
"@types/react": "^19.2.13",
|
|
73
76
|
"@types/react-dom": "^19.2.3",
|