{"_id":"@armadura/connector","_rev":"7-c2953cebca3c4d7f5169572f587c391d","name":"@armadura/connector","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.0":{"name":"@armadura/connector","version":"0.1.0","license":"MIT","_id":"@armadura/connector@0.1.0","maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"dist":{"shasum":"db22c04f36d6ea14f65054177f5c8c2dd5db48c9","tarball":"https://registry.npmjs.org/@armadura/connector/-/connector-0.1.0.tgz","fileCount":5,"integrity":"sha512-utH5Id5W0r4mvw3UVxY+Ym5lLZyLuV29bfZYySYkCcwodqX+MS9ocYDeG46pTuyjLFFWJlkWX5j8fQJ9YOe5jw==","signatures":[{"sig":"MEQCIDjUNKDO626wulo9jVJEc22rz1hQzmrzYV2StQjTwFc2AiAD4LW7D63XIbvCXh96bbs1g6dvQ/keTAC5Oha38Mn3ug==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191431},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"5c8fb7cbb8ccdcae57cb99585f0573e9423b65df","scripts":{"lint":"biome check .","build":"tsup","clean":"rm -rf .turbo node_modules dist","format":"biome --write .","typecheck":"tsc --noEmit"},"_npmUser":{"name":"toxicmango","email":"sarmiento.steven@gmail.com"},"_npmVersion":"11.4.2","description":"Headless wallet connector client and React provider built on Wallet Standard","directories":{},"sideEffects":false,"_nodeVersion":"24.4.1","dependencies":{"motion":"^12.23.12","@radix-ui/react-slot":"^1.0.2","@wallet-standard/app":"^1.0.0","@wallet-standard/base":"^1.0.0","@radix-ui/react-dialog":"^1.0.5","@radix-ui/react-dropdown-menu":"^2.0.6","@solana-mobile/wallet-standard-mobile":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.6.3","@types/react":"^18.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/connector_0.1.0_1759287837671_0.6441671944452112","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@armadura/connector","version":"0.1.1","license":"MIT","_id":"@armadura/connector@0.1.1","maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"dist":{"shasum":"30689f202043a9f847e242fdda9552378e006841","tarball":"https://registry.npmjs.org/@armadura/connector/-/connector-0.1.1.tgz","fileCount":5,"integrity":"sha512-4IYyo0XKE6S2hh7XvATZdpKQn4c61dIatVz/cFGq4GmKLRXckD9bYZk7KZHjPMtNWGlLwFw2WuOWjJZTBcMIGQ==","signatures":[{"sig":"MEUCIQDakTNVd5ohj87Q4Ybuajg3zU1sWL+yQkUvSPEnLYlRTgIgVTBVOisYrmgtQc3aQ+7K4a+Y0O/DYq7O7CyKOzqO6rA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191431},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"5c8fb7cbb8ccdcae57cb99585f0573e9423b65df","scripts":{"lint":"biome check .","build":"tsup","clean":"rm -rf .turbo node_modules dist","format":"biome --write .","typecheck":"tsc --noEmit"},"_npmUser":{"name":"toxicmango","email":"sarmiento.steven@gmail.com"},"_npmVersion":"11.4.2","description":"Headless wallet connector client and React provider built on Wallet Standard","directories":{},"sideEffects":false,"_nodeVersion":"24.4.1","dependencies":{"motion":"^12.23.12","@radix-ui/react-slot":"^1.0.2","@wallet-standard/app":"^1.0.0","@wallet-standard/base":"^1.0.0","@radix-ui/react-dialog":"^1.0.5","@radix-ui/react-dropdown-menu":"^2.0.6","@solana-mobile/wallet-standard-mobile":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.6.3","@types/react":"^18.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/connector_0.1.1_1759290423337_0.15741090549022596","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@armadura/connector","version":"0.1.2","license":"MIT","_id":"@armadura/connector@0.1.2","maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"dist":{"shasum":"7289bd17fbe7f4aa275848ed84ada0dabe096067","tarball":"https://registry.npmjs.org/@armadura/connector/-/connector-0.1.2.tgz","fileCount":5,"integrity":"sha512-RSV/OcoO1rRsi171aTt7TzpaDDDyID3tkV7Wf1rhSLODG0A81DBrCLKA0kePCUkEY3L4wgFGt247yv1qZPvhiw==","signatures":[{"sig":"MEQCIB0a9Z9yPq+9nJ2ZIXdQacORl+JtCbHD5pa2ORc4O4JiAiBInyIm2AkxA5RpLhNnyDFDvHMacHqZb6O8W4QJdDEFDQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191432},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"5c8fb7cbb8ccdcae57cb99585f0573e9423b65df","scripts":{"lint":"biome check .","build":"tsup","clean":"rm -rf .turbo node_modules dist","format":"biome --write .","typecheck":"tsc --noEmit"},"_npmUser":{"name":"toxicmango","email":"sarmiento.steven@gmail.com"},"_npmVersion":"11.4.2","description":"Headless wallet connector client and React provider built on Wallet Standard","directories":{},"sideEffects":false,"_nodeVersion":"24.4.1","dependencies":{"motion":"^12.23.12","@radix-ui/react-slot":"^1.0.2","@wallet-standard/app":"^1.0.0","@wallet-standard/base":"^1.0.0","@radix-ui/react-dialog":"^1.0.5","@radix-ui/react-dropdown-menu":"^2.0.6","@solana-mobile/wallet-standard-mobile":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.6.3","@types/react":"^18.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/connector_0.1.2_1759292719449_0.16913488001521504","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@armadura/connector","version":"0.1.3","license":"MIT","_id":"@armadura/connector@0.1.3","maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"dist":{"shasum":"b00696dc5d27f5a26eff6a2069d81ad57a407839","tarball":"https://registry.npmjs.org/@armadura/connector/-/connector-0.1.3.tgz","fileCount":5,"integrity":"sha512-XJx9ogFSGbkojC455lI8R5VlmzSImd0Tw+r1dwmagO695OJHdwgSEK49iS1yfOLbxzuGmAv/A3jC5X1Ik/jcBA==","signatures":[{"sig":"MEUCIBYMVMkOI+w1Dtht8P+VhY7YdJaHiribXFaQ8skTQ6zEAiEA4nmhhObIwaGekoMTWNnZHWjUXoM4APtPW5I08DMu1GA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191432},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"9cd5bee677ffb1ffdb3ee72b2a3c332c52ca65c4","scripts":{"lint":"biome check .","build":"tsup","clean":"rm -rf .turbo node_modules dist","format":"biome --write .","typecheck":"tsc --noEmit"},"_npmUser":{"name":"toxicmango","email":"sarmiento.steven@gmail.com"},"_npmVersion":"11.4.2","description":"Headless wallet connector client and React provider built on Wallet Standard","directories":{},"sideEffects":false,"_nodeVersion":"24.4.1","dependencies":{"motion":"^12.23.12","@radix-ui/react-slot":"^1.0.2","@wallet-standard/app":"^1.0.0","@wallet-standard/base":"^1.0.0","@radix-ui/react-dialog":"^1.0.5","@radix-ui/react-dropdown-menu":"^2.0.6","@solana-mobile/wallet-standard-mobile":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.6.3","@types/react":"^18.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/connector_0.1.3_1759293384013_0.7125662276647886","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@armadura/connector","version":"0.1.4","license":"MIT","_id":"@armadura/connector@0.1.4","maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"dist":{"shasum":"374e51c320449b80d0b3e237d63bec32efcd8610","tarball":"https://registry.npmjs.org/@armadura/connector/-/connector-0.1.4.tgz","fileCount":5,"integrity":"sha512-++/jgfdwkJwGztF1NiHZrAuoNjmW8F5dD987Bbkf7aN6k6BpzjaUqy0v5tc1yDES+OS9djIamHejdaC2B3UcDA==","signatures":[{"sig":"MEQCIATeija+r+coBqBM4CEuOHGLtQ3VeAdCU5V/iWYpD9y3AiA4EMadptsXhoorqTdudGZvCy1IhHC+cMUlNs6KVg8jbg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191432},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"9cd5bee677ffb1ffdb3ee72b2a3c332c52ca65c4","scripts":{"lint":"biome check .","build":"tsup","clean":"rm -rf .turbo node_modules dist","format":"biome --write .","typecheck":"tsc --noEmit"},"_npmUser":{"name":"toxicmango","email":"sarmiento.steven@gmail.com"},"_npmVersion":"11.4.2","description":"Headless wallet connector client and React provider built on Wallet Standard","directories":{},"sideEffects":false,"_nodeVersion":"24.4.1","dependencies":{"motion":"^12.23.12","@radix-ui/react-slot":"^1.0.2","@wallet-standard/app":"^1.0.0","@wallet-standard/base":"^1.0.0","@radix-ui/react-dialog":"^1.0.5","@radix-ui/react-dropdown-menu":"^2.0.6","@solana-mobile/wallet-standard-mobile":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.6.3","@types/react":"^18.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/connector_0.1.4_1759293705817_0.016303784283385525","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@armadura/connector","version":"0.1.5","license":"MIT","_id":"@armadura/connector@0.1.5","maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"dist":{"shasum":"294b0cb3ed8323010f3c318254452baf6e92dcfa","tarball":"https://registry.npmjs.org/@armadura/connector/-/connector-0.1.5.tgz","fileCount":5,"integrity":"sha512-lDCG83ssyNJU5pKFQgXH1o1dRVbQCKo0WSf1ki1I+cOyiqhYuKrRHtkpJy8i5djRHwutcHXOJ32uCNHyITNjog==","signatures":[{"sig":"MEUCIQDTbhCLWTpG/kteGQ3PB+tegAP308IIg6TMYsOlSxAx6gIgJ9OzKh8CBzZ0HlmjvD5Dnq+AlAzGx7llb1PpnuxEfdQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191432},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"9cd5bee677ffb1ffdb3ee72b2a3c332c52ca65c4","scripts":{"lint":"biome check .","build":"tsup","clean":"rm -rf .turbo node_modules dist","format":"biome --write .","typecheck":"tsc --noEmit"},"_npmUser":{"name":"toxicmango","email":"sarmiento.steven@gmail.com"},"_npmVersion":"11.4.2","description":"Headless wallet connector client and React provider built on Wallet Standard","directories":{},"sideEffects":false,"_nodeVersion":"24.4.1","dependencies":{"motion":"^12.23.12","@radix-ui/react-slot":"^1.0.2","@wallet-standard/app":"^1.0.0","@wallet-standard/base":"^1.0.0","@radix-ui/react-dialog":"^1.0.5","@radix-ui/react-dropdown-menu":"^2.0.6","@solana-mobile/wallet-standard-mobile":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.6.3","@types/react":"^18.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/connector_0.1.5_1759294283570_0.36254935652594744","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@armadura/connector","version":"0.1.6","description":"Headless wallet connector client and React provider built on Wallet Standard","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","sideEffects":false,"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./headless":{"types":"./dist/headless.d.ts","import":"./dist/headless.mjs","require":"./dist/headless.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.js"},"./compat":{"types":"./dist/compat.d.ts","import":"./dist/compat.mjs","require":"./dist/compat.js"}},"scripts":{"build":"tsup","build:analyze":"npm run build && node scripts/analyze-bundle.js","dev":"tsup --watch","type-check":"tsc --noEmit","lint":"prettier --check src/","clean":"rm -rf dist","size":"size-limit","size:why":"size-limit --why","perf":"npm run build:analyze && npm run size","test":"vitest run","test:watch":"vitest","test:ui":"vitest --ui","test:coverage":"vitest run --coverage"},"peerDependencies":{"@solana/web3.js":"^1.0.0","react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true},"@solana/connector-debugger":{"optional":true},"@solana/web3.js":{"optional":true}},"dependencies":{"@nanostores/persistent":"^1.1.0","@solana-mobile/wallet-standard-mobile":"^0.4.3","@solana/webcrypto-ed25519-polyfill":"^4.0.0","@solana/addresses":"^5.0.0","@solana/codecs":"^5.0.0","@solana/keys":"^5.0.0","@solana/kit":"^5.0.0","@solana/signers":"^5.0.0","@solana/transaction-messages":"^5.0.0","@solana/transactions":"^5.0.0","@wallet-standard/app":"^1.1.0","@wallet-standard/base":"^1.1.0","@wallet-standard/features":"^1.1.0","@wallet-ui/core":"^2.0.0"},"devDependencies":{"@testing-library/jest-dom":"^6.9.1","@testing-library/react":"^16.3.0","@testing-library/user-event":"^14.6.1","@types/react":"^19.2.2","@vitest/coverage-v8":"^3.2.4","@vitest/ui":"^3.2.4","happy-dom":"^20.0.7","react":"19.2.0","react-dom":"19.2.0","tsup":"^8.5.0","typescript":"^5.9.3","vitest":"^3.2.4"},"license":"MIT","_id":"@armadura/connector@0.1.6","gitHead":"43ca1f7efb00fea4c6f88fcb83ab274adb3f6c6b","_nodeVersion":"24.4.1","_npmVersion":"11.4.2","dist":{"integrity":"sha512-5qjqmtu/t3l8yWho7fh9DQ3SWMqZdd1jE+vrErlJr4b4CdFx/qqzHGkCsIF7mn49jLqFm4zaZDg+oQEixNc5cA==","shasum":"b12fac488a9c289a47c4a734d2d62770d4625cc8","tarball":"https://registry.npmjs.org/@armadura/connector/-/connector-0.1.6.tgz","fileCount":47,"unpackedSize":2060869,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCQBqexcT+jeVdDISS56y7rVVSq/jhKBHTOS/lj0jPoyAIgLJnXFUp6OLJjuGZ2p8KFuAmOfYA7fZsWoAOTT20wmS0="}]},"_npmUser":{"name":"toxicmango","email":"sarmiento.steven@gmail.com"},"directories":{},"maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/connector_0.1.6_1764486509431_0.8506110905804767"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-01T03:03:57.575Z","modified":"2025-11-30T07:08:29.902Z","0.1.0":"2025-10-01T03:03:57.859Z","0.1.1":"2025-10-01T03:47:03.520Z","0.1.2":"2025-10-01T04:25:19.657Z","0.1.3":"2025-10-01T04:36:24.196Z","0.1.4":"2025-10-01T04:41:46.027Z","0.1.5":"2025-10-01T04:51:23.763Z","0.1.6":"2025-11-30T07:08:29.647Z"},"license":"MIT","description":"Headless wallet connector client and React provider built on Wallet Standard","maintainers":[{"name":"toxicmango","email":"sarmiento.steven@gmail.com"}],"readme":"---\ntitle: @solana/connector\ndescription: Production-ready wallet connector for Solana applications\n---\n\n**ConnectorKit is your Solana wallet infrastructure.** A headless, framework-agnostic wallet connector built on Wallet Standard that just work.\n\n![npm](https://img.shields.io/npm/v/@solana/connector)\n![Bundle Size](https://img.shields.io/badge/bundle-~45KB-gzip-green)\n![TypeScript](https://img.shields.io/badge/TypeScript-100%25-blue)\n\n### Why ConnectorKit?\n\n- **Wallet Standard First**: Built on the official Wallet Standard protocol for universal wallet compatibility\n- **Modern & Legacy Support**: Works with both `@solana/kit` (web3.js 2.0) and `@solana/web3.js` (legacy)\n- **Framework Agnostic**: React hooks + headless core for Vue, Svelte, or vanilla JavaScript\n- **Production Ready**: Event system for analytics, health checks for diagnostics, error boundaries for React apps\n- **Enhanced Storage**: Automatic validation, SSR fallback, and error handling out of the box\n- **Mobile Support**: Built-in Solana Mobile Wallet Adapter integration\n\n---\n\n## Quick Start\n\n### 1. Install\n\n```bash\nnpm install @solana/connector\n# or\npnpm add @solana/connector\n# or\nyarn add @solana/connector\n# or \nbun add @solana/connector\n```\n\n### 2. Setup Provider (once in your app root)\n\n```typescript\n'use client';\n\nimport { useMemo } from 'react';\nimport { AppProvider } from '@solana/connector/react';\nimport { getDefaultConfig, getDefaultMobileConfig } from '@solana/connector/headless';\n\nexport function Providers({ children }: { children: React.ReactNode }) {\n    const connectorConfig = useMemo(() => {\n        // Optional: Get custom RPC URL from environment variable\n        const customRpcUrl = process.env.SOLANA_RPC_URL;\n\n        // Optional: Create custom cluster configuration\n        const clusters = customRpcUrl\n            ? [\n                  {\n                      id: 'solana:mainnet' as const,\n                      label: 'Mainnet (Custom RPC)',\n                      name: 'mainnet-beta' as const,\n                      url: customRpcUrl,\n                  },\n                  {\n                      id: 'solana:devnet' as const,\n                      label: 'Devnet',\n                      name: 'devnet' as const,\n                      url: 'https://api.devnet.solana.com',\n                  },\n              ]\n            : undefined;\n\n        return getDefaultConfig({\n            appName: 'My App',\n            appUrl: 'https://myapp.com',\n            autoConnect: true,\n            enableMobile: true,\n            clusters,\n        });\n    }, []);\n\n    const mobile = useMemo(\n        () =>\n            getDefaultMobileConfig({\n                appName: 'My App',\n                appUrl: 'https://myapp.com',\n            }),\n        [],\n    );\n\n    return (\n        <AppProvider connectorConfig={connectorConfig} mobile={mobile}>\n            {children}\n        </AppProvider>\n    );\n}\n```\n\n### 3. Use Hooks (in any component)\n\n```typescript\n'use client';\n\nimport { useConnector, useAccount } from '@solana/connector';\n\nexport function ConnectButton() {\n    const { wallets, select, disconnect, connected, connecting, selectedWallet, selectedAccount } = useConnector();\n    const { address, formatted, copy } = useAccount();\n\n    if (connecting) {\n        return <button disabled>Connecting...</button>;\n    }\n\n    if (!connected) {\n        return (\n            <div>\n                {wallets.map(w => (\n                    <button key={w.wallet.name} onClick={() => select(w.wallet.name)}>\n                        Connect {w.wallet.name}\n                    </button>\n                ))}\n            </div>\n        );\n    }\n\n    return (\n        <div>\n            <button onClick={copy}>{formatted}</button>\n            <button onClick={disconnect}>Disconnect</button>\n        </div>\n    );\n}\n```\n\n**That's it!** You're ready to go. Everything else below is optional.\n\n---\n\n## Core Hooks\n\nThese are the main hooks you'll use in your components.\n\n### `useConnector()`\n\nMain hook for wallet connection and state.\n\n```typescript\nimport { useConnector } from '@solana/connector';\n\nfunction Component() {\n    const {\n        // State\n        wallets, // WalletInfo[] - All available wallets\n        selectedWallet, // Wallet | null - Currently connected wallet\n        selectedAccount, // string | null - Currently selected account address\n        accounts, // AccountInfo[] - Connected accounts\n        connected, // boolean - Connection status\n        connecting, // boolean - Connecting in progress\n\n        // Actions\n        select, // (walletName: string) => Promise<void>\n        disconnect, // () => Promise<void>\n    } = useConnector();\n}\n```\n\n**Real Example** - Connect Button with wallet selection:\n\n```typescript\n'use client';\n\nimport { useConnector } from '@solana/connector';\nimport { useState } from 'react';\n\nexport function ConnectButton() {\n    const [isModalOpen, setIsModalOpen] = useState(false);\n    const { connected, connecting, selectedWallet, selectedAccount, wallets, select } = useConnector();\n\n    if (connecting) {\n        return <button disabled>Connecting...</button>;\n    }\n\n    if (connected && selectedAccount && selectedWallet) {\n        const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;\n        return (\n            <div>\n                <span>{shortAddress}</span>\n                <button onClick={() => select(selectedWallet.name)}>Switch Wallet</button>\n            </div>\n        );\n    }\n\n    return (\n        <>\n            <button onClick={() => setIsModalOpen(true)}>Connect Wallet</button>\n            {/* Wallet selection modal */}\n        </>\n    );\n}\n```\n\n### `useAccount()`\n\nHook for working with the connected account.\n\n```typescript\nimport { useAccount } from '@solana/connector';\n\nfunction Component() {\n    const {\n        address, // string | null - Full wallet address\n        formatted, // string - Shortened address (e.g., \"5Gv8...x3kF\")\n        copy, // () => Promise<boolean> - Copy address to clipboard\n        copied, // boolean - True for 2s after copying\n        connected, // boolean - Connection status\n        accounts, // AccountInfo[] - All accounts\n        selectAccount, // (address: string) => Promise<void>\n    } = useAccount();\n}\n```\n\n**Real Example** - Account Switcher for multi-account wallets:\n\n```typescript\n'use client';\n\nimport { useAccount } from '@solana/connector';\n\nexport function AccountSwitcher() {\n    const { accounts, address, selectAccount, connected } = useAccount();\n\n    if (!connected || accounts.length <= 1) {\n        return null;\n    }\n\n    return (\n        <select\n            value={address || ''}\n            onChange={e => selectAccount(e.target.value)}\n        >\n            {accounts.map(account => (\n                <option key={account.address} value={account.address}>\n                    {account.address.slice(0, 6)}...{account.address.slice(-6)}\n                </option>\n            ))}\n        </select>\n    );\n}\n```\n\n### `useCluster()`\n\nHook for managing Solana network/cluster.\n\n```typescript\nimport { useCluster } from '@solana/connector';\n\nfunction Component() {\n    const {\n        cluster, // SolanaCluster | null - Active cluster\n        clusters, // SolanaCluster[] - Available clusters\n        setCluster, // (id: SolanaClusterId) => Promise<void>\n        isMainnet, // boolean - Convenience flags\n        isDevnet, // boolean\n        rpcUrl, // string - RPC endpoint URL\n        explorerUrl, // string - Solana Explorer base URL\n    } = useCluster();\n}\n```\n\n**Real Example** - Network Selector:\n\n```typescript\n'use client';\n\nimport { useCluster } from '@solana/connector';\n\nexport function ClusterSelector() {\n    const { cluster, clusters, setCluster } = useCluster();\n\n    return (\n        <select\n            value={cluster?.id || ''}\n            onChange={e => setCluster(e.target.value as SolanaClusterId)}\n        >\n            {clusters.map(c => (\n                <option key={c.id} value={c.id}>\n                    {c.label}\n                </option>\n            ))}\n        </select>\n    );\n}\n```\n\n### `useWalletInfo()`\n\nHook for accessing current wallet metadata.\n\n```typescript\nimport { useWalletInfo } from '@solana/connector';\n\nfunction Component() {\n    const {\n        name, // string | null - Wallet name\n        icon, // string | undefined - Wallet icon URL\n        wallet, // WalletInfo | null - Full wallet info\n        connecting, // boolean - Connection in progress\n    } = useWalletInfo();\n}\n```\n\n---\n\n## Transaction Signing\n\nConnectorKit provides powerful transaction signing capabilities with support for both legacy `@solana/web3.js` and modern `@solana/kit` APIs.\n\n### Modern API (`@solana/kit`)\n\nUse `useKitTransactionSigner()` for modern, type-safe transaction building:\n\n```typescript\n'use client';\n\nimport { useState } from 'react';\nimport {\n    address,\n    createSolanaRpc,\n    pipe,\n    createTransactionMessage,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    appendTransactionMessageInstructions,\n    sendAndConfirmTransactionFactory,\n    getSignatureFromTransaction,\n    signTransactionMessageWithSigners,\n    createSolanaRpcSubscriptions,\n    lamports,\n    assertIsTransactionWithBlockhashLifetime,\n} from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\nimport { useKitTransactionSigner, useCluster, useConnectorClient, LAMPORTS_PER_SOL } from '@solana/connector';\n\nexport function ModernSolTransfer() {\n    const { signer, ready } = useKitTransactionSigner();\n    const { cluster } = useCluster();\n    const client = useConnectorClient();\n    const [signature, setSignature] = useState<string | null>(null);\n\n    async function handleTransfer(recipientAddress: string, amount: number) {\n        if (!signer || !client) {\n            throw new Error('Wallet not connected');\n        }\n\n        // Get RPC URL from connector client\n        const rpcUrl = client.getRpcUrl();\n        if (!rpcUrl) {\n            throw new Error('No RPC endpoint configured');\n        }\n\n        // Create RPC client using web3.js 2.0\n        const rpc = createSolanaRpc(rpcUrl);\n        const rpcSubscriptions = createSolanaRpcSubscriptions(rpcUrl.replace('http', 'ws'));\n\n        // Get recent blockhash\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n\n        // Convert SOL to lamports\n        const amountInLamports = lamports(BigInt(Math.floor(amount * Number(LAMPORTS_PER_SOL))));\n\n        // Create transfer instruction\n        const transferInstruction = getTransferSolInstruction({\n            source: signer,\n            destination: address(recipientAddress),\n            amount: amountInLamports,\n        });\n\n        // Build transaction message\n        const transactionMessage = pipe(\n            createTransactionMessage({ version: 0 }),\n            tx => setTransactionMessageFeePayerSigner(signer, tx),\n            tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n            tx => appendTransactionMessageInstructions([transferInstruction], tx),\n        );\n\n        // Sign transaction\n        const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n\n        // Send and confirm\n        assertIsTransactionWithBlockhashLifetime(signedTransaction);\n        await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction, {\n            commitment: 'confirmed',\n        });\n\n        const transactionSignature = getSignatureFromTransaction(signedTransaction);\n        setSignature(transactionSignature);\n    }\n\n    return (\n        <div>\n            {/* Your form UI */}\n            <button onClick={() => handleTransfer('...', 0.1)} disabled={!ready}>\n                Send SOL\n            </button>\n            {signature && <div>Transaction: {signature}</div>}\n        </div>\n    );\n}\n```\n\n### Legacy API (`@solana/web3.js`)\n\nUse `useTransactionSigner()` for legacy web3.js compatibility:\n\n```typescript\nimport { useTransactionSigner } from '@solana/connector';\nimport { Transaction, SystemProgram } from '@solana/web3.js';\n\nfunction SendTransaction() {\n    const { signer, ready } = useTransactionSigner();\n\n    const handleSend = async () => {\n        if (!signer) return;\n\n        const transaction = new Transaction().add(\n            SystemProgram.transfer({\n                fromPubkey: signer.address,\n                toPubkey: recipientPubkey,\n                lamports: 1000000,\n            })\n        );\n\n        const signature = await signer.signAndSendTransaction(transaction);\n        console.log('Transaction sent:', signature);\n    };\n\n    return <button onClick={handleSend} disabled={!ready}>Send</button>;\n}\n```\n\n---\n\n## UI Elements\n\nConnectorKit provides composable UI elements that handle data fetching and state management for you. Use the render prop pattern to customize the UI.\n\n### Available Elements\n\n- `BalanceElement` - Display SOL balance with refresh\n- `ClusterElement` - Network/cluster selector\n- `TokenListElement` - List of SPL tokens\n- `TransactionHistoryElement` - Recent transaction history\n- `DisconnectElement` - Disconnect button\n- `AccountElement` - Account display and switcher\n- `WalletListElement` - List of available wallets\n\n### Example: Wallet Dropdown\n\n```typescript\n'use client';\n\nimport {\n    BalanceElement,\n    ClusterElement,\n    TokenListElement,\n    TransactionHistoryElement,\n    DisconnectElement,\n} from '@solana/connector/react';\n\nexport function WalletDropdown() {\n    return (\n        <div className=\"wallet-dropdown\">\n            {/* Balance */}\n            <BalanceElement\n                render={({ solBalance, isLoading, refetch }) => (\n                    <div>\n                        <div>Balance: {isLoading ? '...' : `${solBalance?.toFixed(4)} SOL`}</div>\n                        <button onClick={refetch}>Refresh</button>\n                    </div>\n                )}\n            />\n\n            {/* Network Selector */}\n            <ClusterElement\n                render={({ cluster, clusters, setCluster }) => (\n                    <select value={cluster?.id} onChange={e => setCluster(e.target.value)}>\n                        {clusters.map(c => (\n                            <option key={c.id} value={c.id}>\n                                {c.label}\n                            </option>\n                        ))}\n                    </select>\n                )}\n            />\n\n            {/* Tokens */}\n            <TokenListElement\n                limit={5}\n                render={({ tokens, isLoading }) => (\n                    <div>\n                        {isLoading ? (\n                            <div>Loading tokens...</div>\n                        ) : (\n                            tokens.map(token => (\n                                <div key={token.mint}>\n                                    {token.symbol}: {token.formatted}\n                                </div>\n                            ))\n                        )}\n                    </div>\n                )}\n            />\n\n            {/* Transaction History */}\n            <TransactionHistoryElement\n                limit={5}\n                render={({ transactions, isLoading }) => (\n                    <div>\n                        {isLoading ? (\n                            <div>Loading transactions...</div>\n                        ) : (\n                            transactions.map(tx => (\n                                <a key={tx.signature} href={tx.explorerUrl} target=\"_blank\">\n                                    {tx.type} - {tx.formattedTime}\n                                </a>\n                            ))\n                        )}\n                    </div>\n                )}\n            />\n\n            {/* Disconnect */}\n            <DisconnectElement\n                render={({ disconnect, disconnecting }) => (\n                    <button onClick={disconnect} disabled={disconnecting}>\n                        {disconnecting ? 'Disconnecting...' : 'Disconnect'}\n                    </button>\n                )}\n            />\n        </div>\n    );\n}\n```\n\n---\n\n## Configuration\n\n### Basic Configuration\n\n```typescript\nimport { getDefaultConfig } from '@solana/connector';\n\nconst config = getDefaultConfig({\n    appName: 'My App', // Required\n    appUrl: 'https://myapp.com', // Optional: for mobile wallet adapter\n    autoConnect: true, // Auto-reconnect (default: true)\n    network: 'mainnet-beta', // Initial network (default: 'mainnet-beta')\n    enableMobile: true, // Mobile Wallet Adapter (default: true)\n    debug: false, // Debug logging\n});\n```\n\n### Network Selection\n\n```typescript\nconst config = getDefaultConfig({\n    appName: 'My App',\n    network: 'devnet', // 'mainnet-beta' | 'devnet' | 'testnet' | 'localnet'\n});\n```\n\n### Custom RPC Endpoints\n\n```typescript\nimport { getDefaultConfig } from '@solana/connector';\n\nconst config = getDefaultConfig({\n    appName: 'My App',\n    clusters: [\n        {\n            id: 'solana:mainnet' as const,\n            label: 'Mainnet (Custom RPC)',\n            name: 'mainnet-beta' as const,\n            url: 'https://my-custom-rpc.com',\n        },\n        {\n            id: 'solana:devnet' as const,\n            label: 'Devnet',\n            name: 'devnet' as const,\n            url: 'https://api.devnet.solana.com',\n        },\n    ],\n});\n```\n\n### Mobile Wallet Adapter\n\n```typescript\nimport { getDefaultMobileConfig } from '@solana/connector/headless';\n\nconst mobile = getDefaultMobileConfig({\n    appName: 'My App',\n    appUrl: 'https://myapp.com',\n});\n\n<AppProvider connectorConfig={config} mobile={mobile}>\n    {children}\n</AppProvider>\n```\n\n---\n\n## Advanced Usage\n\n### Headless Client (Vue, Svelte, Vanilla JS)\n\nUse `ConnectorClient` for non-React frameworks:\n\n```typescript\nimport { ConnectorClient, getDefaultConfig } from '@solana/connector/headless';\n\n// Create client\nconst client = new ConnectorClient(getDefaultConfig({ appName: 'My App' }));\n\n// Get state\nconst state = client.getSnapshot();\nconsole.log('Wallets:', state.wallets);\n\n// Connect\nawait client.select('Phantom');\n\n// Subscribe to changes\nconst unsubscribe = client.subscribe(state => {\n    console.log('State updated:', state);\n});\n\n// Disconnect\nawait client.disconnect();\n\n// Cleanup\nclient.destroy();\n```\n\n### Custom Storage (React Native, SSR)\n\nStorage uses nanostores with built-in enhancements that are **automatically applied**:\n\n- Validation (Solana address format checking)\n- Error handling (catches localStorage quota errors, private browsing)\n- SSR fallback (uses memory storage when localStorage unavailable)\n\n**Most users don't need to configure storage.** Only customize for:\n\n- React Native (custom storage backend)\n- Additional validation rules\n- Custom error tracking\n\n```typescript\nimport { getDefaultConfig, createEnhancedStorageWallet, EnhancedStorageAdapter } from '@solana/connector';\n\nconst config = getDefaultConfig({\n    appName: 'My App',\n    storage: {\n        wallet: new EnhancedStorageAdapter(\n            createEnhancedStorageWallet({\n                validator: walletName => {\n                    // Custom validation\n                    return walletName !== null && walletName.length > 0;\n                },\n                onError: error => {\n                    // Custom error tracking\n                    Sentry.captureException(error);\n                },\n            }),\n        ),\n    },\n});\n```\n\n---\n\n## Package Exports\n\n### Main Export\n\n```typescript\n// Full library - includes React and headless\nimport { ConnectorProvider, useConnector, useAccount } from '@solana/connector';\n```\n\n### Headless Export (Framework Agnostic)\n\n```typescript\n// Headless core only - no React\nimport { ConnectorClient, getDefaultConfig } from '@solana/connector/headless';\n```\n\n### React Export\n\n```typescript\n// React-specific exports only\nimport { useConnector, useAccount } from '@solana/connector/react';\n```\n\n---\n\n## API Reference\n\n### Hooks\n\n| Hook | Description | Returns |\n|------|-------------|---------|\n| `useConnector()` | Main wallet connection hook | `{ wallets, selectedWallet, accounts, connected, connecting, select, disconnect }` |\n| `useAccount()` | Account management hook | `{ address, formatted, copy, copied, accounts, selectAccount }` |\n| `useCluster()` | Network/cluster management hook | `{ cluster, clusters, setCluster, isMainnet, isDevnet, rpcUrl }` |\n| `useWalletInfo()` | Wallet metadata hook | `{ name, icon, wallet, connecting }` |\n| `useTransactionSigner()` | Legacy transaction signer (web3.js) | `{ signer, ready, address, capabilities }` |\n| `useKitTransactionSigner()` | Modern transaction signer (@solana/kit) | `{ signer, ready, address }` |\n| `useBalance()` | SOL balance hook | `{ solBalance, isLoading, refetch }` |\n| `useTokens()` | SPL tokens hook | `{ tokens, isLoading, refetch }` |\n| `useTransactions()` | Transaction history hook | `{ transactions, isLoading, refetch }` |\n\n### Configuration Functions\n\n| Function | Description |\n|----------|-------------|\n| `getDefaultConfig(options)` | Create default connector configuration |\n| `getDefaultMobileConfig(options)` | Create mobile wallet adapter configuration |\n| `createConfig(options)` | Create unified config for ConnectorKit + Armadura |\n\n### Utility Functions\n\n| Function | Description |\n|----------|-------------|\n| `formatAddress(address, options?)` | Format Solana address |\n| `formatSOL(lamports, options?)` | Format SOL amount |\n| `copyAddressToClipboard(address)` | Copy address to clipboard |\n| `getTransactionUrl(cluster, signature)` | Get Solana Explorer transaction URL |\n| `getAddressUrl(cluster, address)` | Get Solana Explorer address URL |\n\n---\n\n## Types\n\n```typescript\nimport type {\n    // Configuration\n    ConnectorConfig,\n    DefaultConfigOptions,\n    UnifiedConfig,\n\n    // State & Info\n    ConnectorState,\n    ConnectorSnapshot,\n    WalletInfo,\n    AccountInfo,\n\n    // Wallet Standard\n    Wallet,\n    WalletAccount,\n\n    // Clusters\n    SolanaCluster,\n    SolanaClusterId,\n\n    // Hook Returns\n    UseClusterReturn,\n    UseAccountReturn,\n    UseWalletInfoReturn,\n    UseTransactionSignerReturn,\n    UseKitTransactionSignerReturn,\n} from '@solana/connector';\n```\n\n---\n\n## Development\n\n### Commands\n\n```bash\n# Install dependencies\npnpm install\n\n# Build package\npnpm build\n\n# Development mode with watch\npnpm dev\n\n# Type checking\npnpm type-check\n\n# Linting\npnpm lint\n\n# Run tests\npnpm test\n\n# Test in watch mode\npnpm test:watch\n\n# Coverage report\npnpm test:coverage\n\n# Check bundle size\npnpm size\n```\n\n---\n\n## Examples\n\nCheck out the [examples directory](../../examples/next-js) for complete working examples:\n\n- **Next.js Example** - Full-featured wallet connection UI with shadcn/ui\n- **Transaction Signing** - Modern and legacy transaction examples\n- **Network Switching** - Cluster/network management\n- **Account Management** - Multi-account support\n- **Mobile Support** - Solana Mobile Wallet Adapter\n\n---\n\n## Supported Wallets\n\nCompatible with all [Wallet Standard](https://github.com/wallet-standard/wallet-standard) compliant wallets:\n\n- **Phantom** - Browser extension and mobile\n- **Solflare** - Browser extension and mobile\n- **Backpack** - xNFT and wallet\n- **Glow** - Browser extension\n- **Brave Wallet** - Built-in browser wallet\n- **Solana Mobile** - All mobile wallet adapter compatible wallets\n- **Any Wallet Standard wallet** - Full compatibility\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}